Mercurial > hg-stable
changeset 31084:a0bde5ec3a46
color: move 'win32' declaration to the core module
This is another part of moving color implementation into core. before we can
move the advance logic, we need to move the basic definition and building
bricks. This is one more step on that road.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Thu, 22 Dec 2016 03:11:19 +0100 |
parents | c962bb6af909 |
children | 27d3bc0c9093 |
files | hgext/color.py mercurial/color.py |
diffstat | 2 files changed, 141 insertions(+), 140 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/color.py Tue Feb 21 16:29:31 2017 -0800 +++ b/hgext/color.py Thu Dec 22 03:11:19 2016 +0100 @@ -263,7 +263,7 @@ # gibberish, we error on the side of selecting "win32". However, if # w32effects is not defined, we almost certainly don't support # "win32", so don't even try. - if (term and 'xterm' in term) or not w32effects: + if (term and 'xterm' in term) or not color.w32effects: realmode = 'ansi' else: realmode = 'win32' @@ -278,10 +278,10 @@ if realmode == 'win32': color._terminfo_params.clear() - if not w32effects: + if not color.w32effects: modewarn() return None - color._effects.update(w32effects) + color._effects.update(color.w32effects) elif realmode == 'ansi': color._terminfo_params.clear() elif realmode == 'terminfo': @@ -311,7 +311,7 @@ self._buffers[-1].extend(args) elif self._colormode == 'win32': for a in args: - win32print(a, super(colorui, self).write, **opts) + color.win32print(a, super(colorui, self).write, **opts) else: return super(colorui, self).write( *[self.label(a, label) for a in args], **opts) @@ -325,7 +325,7 @@ return self.write(*args, **opts) if self._colormode == 'win32': for a in args: - win32print(a, super(colorui, self).write_err, **opts) + color.win32print(a, super(colorui, self).write_err, **opts) else: return super(colorui, self).write_err( *[self.label(a, label) for a in args], **opts) @@ -432,138 +432,3 @@ ui.write(' ' * (max(0, width - len(label)))) ui.write(', '.join(ui.label(e, e) for e in effects.split())) ui.write('\n') - -if pycompat.osname != 'nt': - w32effects = None -else: - import ctypes - import re - - _kernel32 = ctypes.windll.kernel32 - - _WORD = ctypes.c_ushort - - _INVALID_HANDLE_VALUE = -1 - - class _COORD(ctypes.Structure): - _fields_ = [('X', ctypes.c_short), - ('Y', ctypes.c_short)] - - class _SMALL_RECT(ctypes.Structure): - _fields_ = [('Left', ctypes.c_short), - ('Top', ctypes.c_short), - ('Right', ctypes.c_short), - ('Bottom', ctypes.c_short)] - - class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure): - _fields_ = [('dwSize', _COORD), - ('dwCursorPosition', _COORD), - ('wAttributes', _WORD), - ('srWindow', _SMALL_RECT), - ('dwMaximumWindowSize', _COORD)] - - _STD_OUTPUT_HANDLE = 0xfffffff5 # (DWORD)-11 - _STD_ERROR_HANDLE = 0xfffffff4 # (DWORD)-12 - - _FOREGROUND_BLUE = 0x0001 - _FOREGROUND_GREEN = 0x0002 - _FOREGROUND_RED = 0x0004 - _FOREGROUND_INTENSITY = 0x0008 - - _BACKGROUND_BLUE = 0x0010 - _BACKGROUND_GREEN = 0x0020 - _BACKGROUND_RED = 0x0040 - _BACKGROUND_INTENSITY = 0x0080 - - _COMMON_LVB_REVERSE_VIDEO = 0x4000 - _COMMON_LVB_UNDERSCORE = 0x8000 - - # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx - w32effects = { - 'none': -1, - 'black': 0, - 'red': _FOREGROUND_RED, - 'green': _FOREGROUND_GREEN, - 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN, - 'blue': _FOREGROUND_BLUE, - 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED, - 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN, - 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE, - 'bold': _FOREGROUND_INTENSITY, - 'black_background': 0x100, # unused value > 0x0f - 'red_background': _BACKGROUND_RED, - 'green_background': _BACKGROUND_GREEN, - 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN, - 'blue_background': _BACKGROUND_BLUE, - 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED, - 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN, - 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN | - _BACKGROUND_BLUE), - 'bold_background': _BACKGROUND_INTENSITY, - 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only - 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only - } - - passthrough = set([_FOREGROUND_INTENSITY, - _BACKGROUND_INTENSITY, - _COMMON_LVB_UNDERSCORE, - _COMMON_LVB_REVERSE_VIDEO]) - - stdout = _kernel32.GetStdHandle( - _STD_OUTPUT_HANDLE) # don't close the handle returned - if stdout is None or stdout == _INVALID_HANDLE_VALUE: - w32effects = None - else: - csbi = _CONSOLE_SCREEN_BUFFER_INFO() - if not _kernel32.GetConsoleScreenBufferInfo( - stdout, ctypes.byref(csbi)): - # stdout may not support GetConsoleScreenBufferInfo() - # when called from subprocess or redirected - w32effects = None - else: - origattr = csbi.wAttributes - ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', - re.MULTILINE | re.DOTALL) - - def win32print(text, orig, **opts): - label = opts.get('label', '') - attr = origattr - - def mapcolor(val, attr): - if val == -1: - return origattr - elif val in passthrough: - return attr | val - elif val > 0x0f: - return (val & 0x70) | (attr & 0x8f) - else: - return (val & 0x07) | (attr & 0xf8) - - # determine console attributes based on labels - for l in label.split(): - style = color._styles.get(l, '') - for effect in style.split(): - try: - attr = mapcolor(w32effects[effect], attr) - except KeyError: - # w32effects could not have certain attributes so we skip - # them if not found - pass - # hack to ensure regexp finds data - if not text.startswith('\033['): - text = '\033[m' + text - - # Look for ANSI-like codes embedded in text - m = re.match(ansire, text) - - try: - while m: - for sattr in m.group(1).split(';'): - if sattr: - attr = mapcolor(int(sattr), attr) - _kernel32.SetConsoleTextAttribute(stdout, attr) - orig(m.group(2), **opts) - m = re.match(ansire, m.group(3)) - finally: - # Explicitly reset original attributes - _kernel32.SetConsoleTextAttribute(stdout, origattr)
--- a/mercurial/color.py Tue Feb 21 16:29:31 2017 -0800 +++ b/mercurial/color.py Thu Dec 22 03:11:19 2016 +0100 @@ -9,6 +9,8 @@ from .i18n import _ +from . import pycompat + try: import curses # Mapping from effect name to terminfo attribute name (or raw code) or @@ -172,3 +174,137 @@ for effect in ['none'] + effects.split()) stop = _effect_str('none') return ''.join([start, text, stop]) + +w32effects = None +if pycompat.osname == 'nt': + import ctypes + import re + + _kernel32 = ctypes.windll.kernel32 + + _WORD = ctypes.c_ushort + + _INVALID_HANDLE_VALUE = -1 + + class _COORD(ctypes.Structure): + _fields_ = [('X', ctypes.c_short), + ('Y', ctypes.c_short)] + + class _SMALL_RECT(ctypes.Structure): + _fields_ = [('Left', ctypes.c_short), + ('Top', ctypes.c_short), + ('Right', ctypes.c_short), + ('Bottom', ctypes.c_short)] + + class _CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure): + _fields_ = [('dwSize', _COORD), + ('dwCursorPosition', _COORD), + ('wAttributes', _WORD), + ('srWindow', _SMALL_RECT), + ('dwMaximumWindowSize', _COORD)] + + _STD_OUTPUT_HANDLE = 0xfffffff5 # (DWORD)-11 + _STD_ERROR_HANDLE = 0xfffffff4 # (DWORD)-12 + + _FOREGROUND_BLUE = 0x0001 + _FOREGROUND_GREEN = 0x0002 + _FOREGROUND_RED = 0x0004 + _FOREGROUND_INTENSITY = 0x0008 + + _BACKGROUND_BLUE = 0x0010 + _BACKGROUND_GREEN = 0x0020 + _BACKGROUND_RED = 0x0040 + _BACKGROUND_INTENSITY = 0x0080 + + _COMMON_LVB_REVERSE_VIDEO = 0x4000 + _COMMON_LVB_UNDERSCORE = 0x8000 + + # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx + w32effects = { + 'none': -1, + 'black': 0, + 'red': _FOREGROUND_RED, + 'green': _FOREGROUND_GREEN, + 'yellow': _FOREGROUND_RED | _FOREGROUND_GREEN, + 'blue': _FOREGROUND_BLUE, + 'magenta': _FOREGROUND_BLUE | _FOREGROUND_RED, + 'cyan': _FOREGROUND_BLUE | _FOREGROUND_GREEN, + 'white': _FOREGROUND_RED | _FOREGROUND_GREEN | _FOREGROUND_BLUE, + 'bold': _FOREGROUND_INTENSITY, + 'black_background': 0x100, # unused value > 0x0f + 'red_background': _BACKGROUND_RED, + 'green_background': _BACKGROUND_GREEN, + 'yellow_background': _BACKGROUND_RED | _BACKGROUND_GREEN, + 'blue_background': _BACKGROUND_BLUE, + 'purple_background': _BACKGROUND_BLUE | _BACKGROUND_RED, + 'cyan_background': _BACKGROUND_BLUE | _BACKGROUND_GREEN, + 'white_background': (_BACKGROUND_RED | _BACKGROUND_GREEN | + _BACKGROUND_BLUE), + 'bold_background': _BACKGROUND_INTENSITY, + 'underline': _COMMON_LVB_UNDERSCORE, # double-byte charsets only + 'inverse': _COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only + } + + passthrough = set([_FOREGROUND_INTENSITY, + _BACKGROUND_INTENSITY, + _COMMON_LVB_UNDERSCORE, + _COMMON_LVB_REVERSE_VIDEO]) + + stdout = _kernel32.GetStdHandle( + _STD_OUTPUT_HANDLE) # don't close the handle returned + if stdout is None or stdout == _INVALID_HANDLE_VALUE: + w32effects = None + else: + csbi = _CONSOLE_SCREEN_BUFFER_INFO() + if not _kernel32.GetConsoleScreenBufferInfo( + stdout, ctypes.byref(csbi)): + # stdout may not support GetConsoleScreenBufferInfo() + # when called from subprocess or redirected + w32effects = None + else: + origattr = csbi.wAttributes + ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', + re.MULTILINE | re.DOTALL) + + def win32print(text, orig, **opts): + label = opts.get('label', '') + attr = origattr + + def mapcolor(val, attr): + if val == -1: + return origattr + elif val in passthrough: + return attr | val + elif val > 0x0f: + return (val & 0x70) | (attr & 0x8f) + else: + return (val & 0x07) | (attr & 0xf8) + + # determine console attributes based on labels + for l in label.split(): + style = _styles.get(l, '') + for effect in style.split(): + try: + attr = mapcolor(w32effects[effect], attr) + except KeyError: + # w32effects could not have certain attributes so we skip + # them if not found + pass + # hack to ensure regexp finds data + if not text.startswith('\033['): + text = '\033[m' + text + + # Look for ANSI-like codes embedded in text + m = re.match(ansire, text) + + try: + while m: + for sattr in m.group(1).split(';'): + if sattr: + attr = mapcolor(int(sattr), attr) + _kernel32.SetConsoleTextAttribute(stdout, attr) + orig(m.group(2), **opts) + m = re.match(ansire, m.group(3)) + finally: + # Explicitly reset original attributes + _kernel32.SetConsoleTextAttribute(stdout, origattr)