# HG changeset patch # User Matt Mackall # Date 1300136384 18000 # Node ID d943efb9701f088313de17f6c32cad22928b96c7 # Parent c0c59970984693d7fcd5b37e2a36d95e5c3a71eb# Parent 994510694b1d12f121dce2e5a585abaf13514259 merge with stable diff -r c0c599709846 -r d943efb9701f hgext/color.py --- a/hgext/color.py Mon Mar 14 09:36:17 2011 +0100 +++ b/hgext/color.py Mon Mar 14 15:59:44 2011 -0500 @@ -203,7 +203,7 @@ if mode == 'win32': if w32effects is None: # only warn if color.mode is explicitly set to win32 - ui.warn(_('win32console not found, please install pywin32\n')) + ui.warn(_('warning: failed to set color mode to %s\n') % mode) return _effects.update(w32effects) elif mode != 'ansi': @@ -231,52 +231,96 @@ _("when to colorize (boolean, always, auto, or never)"), _('TYPE'))) -try: - import re, pywintypes, win32console as win32c +if os.name != 'nt': + w32effects = None +else: + import re, ctypes + + _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 = 0xfffffff5L # (DWORD)-11 + _STD_ERROR_HANDLE = 0xfffffff4L # (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': win32c.FOREGROUND_RED, - 'green': win32c.FOREGROUND_GREEN, - 'yellow': win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN, - 'blue': win32c.FOREGROUND_BLUE, - 'magenta': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_RED, - 'cyan': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_GREEN, - 'white': (win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN | - win32c.FOREGROUND_BLUE), - 'bold': win32c.FOREGROUND_INTENSITY, + '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': win32c.BACKGROUND_RED, - 'green_background': win32c.BACKGROUND_GREEN, - 'yellow_background': win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN, - 'blue_background': win32c.BACKGROUND_BLUE, - 'purple_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_RED, - 'cyan_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_GREEN, - 'white_background': (win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN | - win32c.BACKGROUND_BLUE), - 'bold_background': win32c.BACKGROUND_INTENSITY, - 'underline': win32c.COMMON_LVB_UNDERSCORE, # double-byte charsets only - 'inverse': win32c.COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only + '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([win32c.FOREGROUND_INTENSITY, - win32c.BACKGROUND_INTENSITY, - win32c.COMMON_LVB_UNDERSCORE, - win32c.COMMON_LVB_REVERSE_VIDEO]) + passthrough = set([_FOREGROUND_INTENSITY, + _BACKGROUND_INTENSITY, + _COMMON_LVB_UNDERSCORE, + _COMMON_LVB_REVERSE_VIDEO]) - try: - stdout = win32c.GetStdHandle(win32c.STD_OUTPUT_HANDLE) - if stdout is None: - raise ImportError() - origattr = stdout.GetConsoleScreenBufferInfo()['Attributes'] - except pywintypes.error: - # stdout may be defined but not support - # GetConsoleScreenBufferInfo(), when called from subprocess or - # redirected. - raise ImportError() - ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE | re.DOTALL) + 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', '') @@ -308,12 +352,9 @@ for sattr in m.group(1).split(';'): if sattr: attr = mapcolor(int(sattr), attr) - stdout.SetConsoleTextAttribute(attr) + _kernel32.SetConsoleTextAttribute(stdout, attr) orig(m.group(2), **opts) m = re.match(ansire, m.group(3)) # Explicity reset original attributes - stdout.SetConsoleTextAttribute(origattr) - -except ImportError: - w32effects = None + _kernel32.SetConsoleTextAttribute(stdout, origattr) diff -r c0c599709846 -r d943efb9701f hgext/pager.py --- a/hgext/pager.py Mon Mar 14 09:36:17 2011 +0100 +++ b/hgext/pager.py Mon Mar 14 15:59:44 2011 -0500 @@ -59,14 +59,17 @@ def _runpager(p): if not hasattr(os, 'fork'): - sys.stderr = sys.stdout = util.popen(p, 'wb') + sys.stdout = util.popen(p, 'wb') + if sys.stderr.isatty(): + sys.stderr = sys.stdout return fdin, fdout = os.pipe() pid = os.fork() if pid == 0: os.close(fdin) os.dup2(fdout, sys.stdout.fileno()) - os.dup2(fdout, sys.stderr.fileno()) + if sys.stderr.isatty(): + os.dup2(fdout, sys.stderr.fileno()) os.close(fdout) return os.dup2(fdin, sys.stdin.fileno())