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