##// END OF EJS Templates
color: move 'win32' declaration to the core module...
Pierre-Yves David -
r31067:a0bde5ec default
parent child Browse files
Show More
@@ -263,7 +263,7 b' def _modesetup(ui, coloropt):'
263 # gibberish, we error on the side of selecting "win32". However, if
263 # gibberish, we error on the side of selecting "win32". However, if
264 # w32effects is not defined, we almost certainly don't support
264 # w32effects is not defined, we almost certainly don't support
265 # "win32", so don't even try.
265 # "win32", so don't even try.
266 if (term and 'xterm' in term) or not w32effects:
266 if (term and 'xterm' in term) or not color.w32effects:
267 realmode = 'ansi'
267 realmode = 'ansi'
268 else:
268 else:
269 realmode = 'win32'
269 realmode = 'win32'
@@ -278,10 +278,10 b' def _modesetup(ui, coloropt):'
278
278
279 if realmode == 'win32':
279 if realmode == 'win32':
280 color._terminfo_params.clear()
280 color._terminfo_params.clear()
281 if not w32effects:
281 if not color.w32effects:
282 modewarn()
282 modewarn()
283 return None
283 return None
284 color._effects.update(w32effects)
284 color._effects.update(color.w32effects)
285 elif realmode == 'ansi':
285 elif realmode == 'ansi':
286 color._terminfo_params.clear()
286 color._terminfo_params.clear()
287 elif realmode == 'terminfo':
287 elif realmode == 'terminfo':
@@ -311,7 +311,7 b' class colorui(uimod.ui):'
311 self._buffers[-1].extend(args)
311 self._buffers[-1].extend(args)
312 elif self._colormode == 'win32':
312 elif self._colormode == 'win32':
313 for a in args:
313 for a in args:
314 win32print(a, super(colorui, self).write, **opts)
314 color.win32print(a, super(colorui, self).write, **opts)
315 else:
315 else:
316 return super(colorui, self).write(
316 return super(colorui, self).write(
317 *[self.label(a, label) for a in args], **opts)
317 *[self.label(a, label) for a in args], **opts)
@@ -325,7 +325,7 b' class colorui(uimod.ui):'
325 return self.write(*args, **opts)
325 return self.write(*args, **opts)
326 if self._colormode == 'win32':
326 if self._colormode == 'win32':
327 for a in args:
327 for a in args:
328 win32print(a, super(colorui, self).write_err, **opts)
328 color.win32print(a, super(colorui, self).write_err, **opts)
329 else:
329 else:
330 return super(colorui, self).write_err(
330 return super(colorui, self).write_err(
331 *[self.label(a, label) for a in args], **opts)
331 *[self.label(a, label) for a in args], **opts)
@@ -432,138 +432,3 b' def _debugdisplaystyle(ui):'
432 ui.write(' ' * (max(0, width - len(label))))
432 ui.write(' ' * (max(0, width - len(label))))
433 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
433 ui.write(', '.join(ui.label(e, e) for e in effects.split()))
434 ui.write('\n')
434 ui.write('\n')
435
436 if pycompat.osname != 'nt':
437 w32effects = None
438 else:
439 import ctypes
440 import re
441
442 _kernel32 = ctypes.windll.kernel32
443
444 _WORD = ctypes.c_ushort
445
446 _INVALID_HANDLE_VALUE = -1
447
448 class _COORD(ctypes.Structure):
449 _fields_ = [('X', ctypes.c_short),
450 ('Y', ctypes.c_short)]
451
452 class _SMALL_RECT(ctypes.Structure):
453 _fields_ = [('Left', ctypes.c_short),
454 ('Top', ctypes.c_short),
455 ('Right', ctypes.c_short),
456 ('Bottom', ctypes.c_short)]
457
458 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
459 _fields_ = [('dwSize', _COORD),
460 ('dwCursorPosition', _COORD),
461 ('wAttributes', _WORD),
462 ('srWindow', _SMALL_RECT),
463 ('dwMaximumWindowSize', _COORD)]
464
465 _STD_OUTPUT_HANDLE = 0xfffffff5 # (DWORD)-11
466 _STD_ERROR_HANDLE = 0xfffffff4 # (DWORD)-12
467
468 _FOREGROUND_BLUE = 0x0001
469 _FOREGROUND_GREEN = 0x0002
470 _FOREGROUND_RED = 0x0004
471 _FOREGROUND_INTENSITY = 0x0008
472
473 _BACKGROUND_BLUE = 0x0010
474 _BACKGROUND_GREEN = 0x0020
475 _BACKGROUND_RED = 0x0040
476 _BACKGROUND_INTENSITY = 0x0080
477
478 _COMMON_LVB_REVERSE_VIDEO = 0x4000
479 _COMMON_LVB_UNDERSCORE = 0x8000
480
481 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
482 w32effects = {
483 'none': -1,
484 'black': 0,
485 'red': _FOREGROUND_RED,
486 'green': _FOREGROUND_GREEN,
487 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
488 'blue': _FOREGROUND_BLUE,
489 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
490 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
491 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
492 'bold': _FOREGROUND_INTENSITY,
493 'black_background': 0x100, # unused value > 0x0f
494 'red_background': _BACKGROUND_RED,
495 'green_background': _BACKGROUND_GREEN,
496 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
497 'blue_background': _BACKGROUND_BLUE,
498 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
499 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
500 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
501 _BACKGROUND_BLUE),
502 'bold_background': _BACKGROUND_INTENSITY,
503 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only
504 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
505 }
506
507 passthrough = set([_FOREGROUND_INTENSITY,
508 _BACKGROUND_INTENSITY,
509 _COMMON_LVB_UNDERSCORE,
510 _COMMON_LVB_REVERSE_VIDEO])
511
512 stdout = _kernel32.GetStdHandle(
513 _STD_OUTPUT_HANDLE) # don't close the handle returned
514 if stdout is None or stdout == _INVALID_HANDLE_VALUE:
515 w32effects = None
516 else:
517 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
518 if not _kernel32.GetConsoleScreenBufferInfo(
519 stdout, ctypes.byref(csbi)):
520 # stdout may not support GetConsoleScreenBufferInfo()
521 # when called from subprocess or redirected
522 w32effects = None
523 else:
524 origattr = csbi.wAttributes
525 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
526 re.MULTILINE | re.DOTALL)
527
528 def win32print(text, orig, **opts):
529 label = opts.get('label', '')
530 attr = origattr
531
532 def mapcolor(val, attr):
533 if val == -1:
534 return origattr
535 elif val in passthrough:
536 return attr | val
537 elif val > 0x0f:
538 return (val & 0x70) | (attr & 0x8f)
539 else:
540 return (val & 0x07) | (attr & 0xf8)
541
542 # determine console attributes based on labels
543 for l in label.split():
544 style = color._styles.get(l, '')
545 for effect in style.split():
546 try:
547 attr = mapcolor(w32effects[effect], attr)
548 except KeyError:
549 # w32effects could not have certain attributes so we skip
550 # them if not found
551 pass
552 # hack to ensure regexp finds data
553 if not text.startswith('\033['):
554 text = '\033[m' + text
555
556 # Look for ANSI-like codes embedded in text
557 m = re.match(ansire, text)
558
559 try:
560 while m:
561 for sattr in m.group(1).split(';'):
562 if sattr:
563 attr = mapcolor(int(sattr), attr)
564 _kernel32.SetConsoleTextAttribute(stdout, attr)
565 orig(m.group(2), **opts)
566 m = re.match(ansire, m.group(3))
567 finally:
568 # Explicitly reset original attributes
569 _kernel32.SetConsoleTextAttribute(stdout, origattr)
@@ -9,6 +9,8 b' from __future__ import absolute_import'
9
9
10 from .i18n import _
10 from .i18n import _
11
11
12 from . import pycompat
13
12 try:
14 try:
13 import curses
15 import curses
14 # Mapping from effect name to terminfo attribute name (or raw code) or
16 # Mapping from effect name to terminfo attribute name (or raw code) or
@@ -172,3 +174,137 b' def _render_effects(text, effects):'
172 for effect in ['none'] + effects.split())
174 for effect in ['none'] + effects.split())
173 stop = _effect_str('none')
175 stop = _effect_str('none')
174 return ''.join([start, text, stop])
176 return ''.join([start, text, stop])
177
178 w32effects = None
179 if pycompat.osname == 'nt':
180 import ctypes
181 import re
182
183 _kernel32 = ctypes.windll.kernel32
184
185 _WORD = ctypes.c_ushort
186
187 _INVALID_HANDLE_VALUE = -1
188
189 class _COORD(ctypes.Structure):
190 _fields_ = [('X', ctypes.c_short),
191 ('Y', ctypes.c_short)]
192
193 class _SMALL_RECT(ctypes.Structure):
194 _fields_ = [('Left', ctypes.c_short),
195 ('Top', ctypes.c_short),
196 ('Right', ctypes.c_short),
197 ('Bottom', ctypes.c_short)]
198
199 class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
200 _fields_ = [('dwSize', _COORD),
201 ('dwCursorPosition', _COORD),
202 ('wAttributes', _WORD),
203 ('srWindow', _SMALL_RECT),
204 ('dwMaximumWindowSize', _COORD)]
205
206 _STD_OUTPUT_HANDLE = 0xfffffff5 # (DWORD)-11
207 _STD_ERROR_HANDLE = 0xfffffff4 # (DWORD)-12
208
209 _FOREGROUND_BLUE = 0x0001
210 _FOREGROUND_GREEN = 0x0002
211 _FOREGROUND_RED = 0x0004
212 _FOREGROUND_INTENSITY = 0x0008
213
214 _BACKGROUND_BLUE = 0x0010
215 _BACKGROUND_GREEN = 0x0020
216 _BACKGROUND_RED = 0x0040
217 _BACKGROUND_INTENSITY = 0x0080
218
219 _COMMON_LVB_REVERSE_VIDEO = 0x4000
220 _COMMON_LVB_UNDERSCORE = 0x8000
221
222 # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
223 w32effects = {
224 'none': -1,
225 'black': 0,
226 'red': _FOREGROUND_RED,
227 'green': _FOREGROUND_GREEN,
228 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN,
229 'blue': _FOREGROUND_BLUE,
230 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED,
231 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN,
232 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE,
233 'bold': _FOREGROUND_INTENSITY,
234 'black_background': 0x100, # unused value > 0x0f
235 'red_background': _BACKGROUND_RED,
236 'green_background': _BACKGROUND_GREEN,
237 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN,
238 'blue_background': _BACKGROUND_BLUE,
239 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED,
240 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN,
241 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN |
242 _BACKGROUND_BLUE),
243 'bold_background': _BACKGROUND_INTENSITY,
244 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only
245 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
246 }
247
248 passthrough = set([_FOREGROUND_INTENSITY,
249 _BACKGROUND_INTENSITY,
250 _COMMON_LVB_UNDERSCORE,
251 _COMMON_LVB_REVERSE_VIDEO])
252
253 stdout = _kernel32.GetStdHandle(
254 _STD_OUTPUT_HANDLE) # don't close the handle returned
255 if stdout is None or stdout == _INVALID_HANDLE_VALUE:
256 w32effects = None
257 else:
258 csbi = _CONSOLE_SCREEN_BUFFER_INFO()
259 if not _kernel32.GetConsoleScreenBufferInfo(
260 stdout, ctypes.byref(csbi)):
261 # stdout may not support GetConsoleScreenBufferInfo()
262 # when called from subprocess or redirected
263 w32effects = None
264 else:
265 origattr = csbi.wAttributes
266 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)',
267 re.MULTILINE | re.DOTALL)
268
269 def win32print(text, orig, **opts):
270 label = opts.get('label', '')
271 attr = origattr
272
273 def mapcolor(val, attr):
274 if val == -1:
275 return origattr
276 elif val in passthrough:
277 return attr | val
278 elif val > 0x0f:
279 return (val & 0x70) | (attr & 0x8f)
280 else:
281 return (val & 0x07) | (attr & 0xf8)
282
283 # determine console attributes based on labels
284 for l in label.split():
285 style = _styles.get(l, '')
286 for effect in style.split():
287 try:
288 attr = mapcolor(w32effects[effect], attr)
289 except KeyError:
290 # w32effects could not have certain attributes so we skip
291 # them if not found
292 pass
293 # hack to ensure regexp finds data
294 if not text.startswith('\033['):
295 text = '\033[m' + text
296
297 # Look for ANSI-like codes embedded in text
298 m = re.match(ansire, text)
299
300 try:
301 while m:
302 for sattr in m.group(1).split(';'):
303 if sattr:
304 attr = mapcolor(int(sattr), attr)
305 _kernel32.SetConsoleTextAttribute(stdout, attr)
306 orig(m.group(2), **opts)
307 m = re.match(ansire, m.group(3))
308 finally:
309 # Explicitly reset original attributes
310 _kernel32.SetConsoleTextAttribute(stdout, origattr)
General Comments 0
You need to be logged in to leave comments. Login now