[PATCH 1 of 3] windows: add a method to enable ANSI color code processing on Windows 10

Matt Harbison mharbison72 at gmail.com
Tue May 23 02:57:39 UTC 2017


# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1495504856 14400
#      Mon May 22 22:00:56 2017 -0400
# Node ID 58dbbf67bd726092374403b2805d9ef9f5118ebe
# Parent  8db2feb04cebc1878c6232dd2650f2c5468d350e
windows: add a method to enable ANSI color code processing on Windows 10

SetConsoleMode() fails with an invalid parameter error if given this option
prior to Windows 10, so indicate that to the caller instead of doing explicit
version checks.

diff --git a/mercurial/posix.py b/mercurial/posix.py
--- a/mercurial/posix.py
+++ b/mercurial/posix.py
@@ -557,6 +557,14 @@
     """
     pass
 
+def enablevtmode():
+    """Enable virtual terminal mode for the associated console.  Return True if
+    enabled, else False.
+
+    Used to enable ANSI color support on Windows 10.
+    """
+    return True
+
 class cachestat(object):
     def __init__(self, path):
         self.stat = os.stat(path)
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -96,6 +96,7 @@
 checkexec = platform.checkexec
 checklink = platform.checklink
 copymode = platform.copymode
+enablevtmode = platform.enablevtmode
 executablepath = platform.executablepath
 expandglobs = platform.expandglobs
 explainexit = platform.explainexit
diff --git a/mercurial/win32.py b/mercurial/win32.py
--- a/mercurial/win32.py
+++ b/mercurial/win32.py
@@ -202,6 +202,12 @@
 _kernel32.SetConsoleCtrlHandler.argtypes = [_SIGNAL_HANDLER, _BOOL]
 _kernel32.SetConsoleCtrlHandler.restype = _BOOL
 
+_kernel32.SetConsoleMode.argtypes = [_HANDLE, _DWORD]
+_kernel32.SetConsoleMode.restype = _BOOL
+
+_kernel32.GetConsoleMode.argtypes = [_HANDLE, ctypes.c_void_p]
+_kernel32.GetConsoleMode.restype = _BOOL
+
 _kernel32.GetStdHandle.argtypes = [_DWORD]
 _kernel32.GetStdHandle.restype = _HANDLE
 
@@ -372,6 +378,30 @@
     height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1
     return width, height
 
+def enablevtmode():
+    '''Enable virtual terminal mode for the associated console.  Return True if
+    enabled, else False.'''
+
+    ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4
+
+    # Query stderr, like termsize().  Either stdout or stderr will work.
+    handle = _kernel32.GetStdHandle(_STD_ERROR_HANDLE) # don't close the handle
+    if handle == _INVALID_HANDLE_VALUE:
+        return False
+
+    mode = _DWORD(0)
+
+    if not _kernel32.GetConsoleMode(handle, ctypes.byref(mode)):
+        return False
+
+    if (mode.value & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == 0:
+        mode.value |= ENABLE_VIRTUAL_TERMINAL_PROCESSING
+
+        if not _kernel32.SetConsoleMode(handle, mode):
+            return False
+
+    return True
+
 def _1stchild(pid):
     '''return the 1st found child of the given pid
 
diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -30,6 +30,7 @@
 
 osutil = policy.importmod(r'osutil')
 
+enablevtmode = win32.enablevtmode
 executablepath = win32.executablepath
 getuser = win32.getuser
 hidewindow = win32.hidewindow


More information about the Mercurial mailing list