From 6c588f189de5d97cd50eeb9f1bb586f3dc4baa0e Mon Sep 17 00:00:00 2001 From: Paul Hooijenga Date: Sat, 1 Apr 2017 20:29:31 +0200 Subject: [PATCH 1/2] Windows: enable ANSI escape support in console. --- pre_commit/color.py | 8 ++++++ pre_commit/color_windows.py | 49 +++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 pre_commit/color_windows.py diff --git a/pre_commit/color.py b/pre_commit/color.py index 686d85bf..25fbb256 100644 --- a/pre_commit/color.py +++ b/pre_commit/color.py @@ -1,7 +1,15 @@ from __future__ import unicode_literals +import os import sys +if os.name == 'nt': # pragma: no cover (windows) + from pre_commit.color_windows import enable_virtual_terminal_processing + try: + enable_virtual_terminal_processing() + except WindowsError: + pass + RED = '\033[41m' GREEN = '\033[42m' YELLOW = '\033[43;30m' diff --git a/pre_commit/color_windows.py b/pre_commit/color_windows.py new file mode 100644 index 00000000..d44e0b80 --- /dev/null +++ b/pre_commit/color_windows.py @@ -0,0 +1,49 @@ +from __future__ import unicode_literals + +from ctypes import POINTER +from ctypes import windll +from ctypes import WinError +from ctypes import WINFUNCTYPE +from ctypes.wintypes import BOOL +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE + +STD_OUTPUT_HANDLE = -11 +ENABLE_VIRTUAL_TERMINAL_PROCESSING = 4 + + +def bool_errcheck(result, func, args): + if not result: + raise WinError() + return args + + +GetStdHandle = WINFUNCTYPE(HANDLE, DWORD)( + ("GetStdHandle", windll.kernel32), + ((1, "nStdHandle"), ) +) + +GetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, POINTER(DWORD))( + ("GetConsoleMode", windll.kernel32), + ((1, "hConsoleHandle"), (2, "lpMode")) +) +GetConsoleMode.errcheck = bool_errcheck + +SetConsoleMode = WINFUNCTYPE(BOOL, HANDLE, DWORD)( + ("SetConsoleMode", windll.kernel32), + ((1, "hConsoleHandle"), (1, "dwMode")) +) +SetConsoleMode.errcheck = bool_errcheck + + +def enable_virtual_terminal_processing(): + """As of Windows 10, the Windows console supports (some) ANSI escape + sequences, but it needs to be enabled using `SetConsoleMode` first. + + More info on the escape sequences supported: + https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx + + """ + stdout = GetStdHandle(STD_OUTPUT_HANDLE) + flags = GetConsoleMode(stdout) + SetConsoleMode(stdout, flags | ENABLE_VIRTUAL_TERMINAL_PROCESSING) From 3c374802ec98834edefb87661cac3819fd9dd148 Mon Sep 17 00:00:00 2001 From: Paul Hooijenga Date: Fri, 7 Apr 2017 21:10:19 +0200 Subject: [PATCH 2/2] Omit Windows only file from coverage. --- .coveragerc | 1 + 1 file changed, 1 insertion(+) diff --git a/.coveragerc b/.coveragerc index f73b9e3d..a94ba5cd 100644 --- a/.coveragerc +++ b/.coveragerc @@ -8,6 +8,7 @@ omit = setup.py # Don't complain if non-runnable code isn't run */__main__.py + pre_commit/color_windows.py [report] show_missing = True