mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-04-14 17:41:45 +04:00
Make the foreground (text) color be the usual background color, when highlighting text. This is done by setting the foreground color instead of the background color, then inverting (code 7) to swap the foreground and background colors. Previously, with some color schemes there was not enough contrast between the text and highlight color. Based on the assumption that there should be contrast between terminal colors and the background, this should make the text readable with a wider set of color schemes.
109 lines
3.1 KiB
Python
109 lines
3.1 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import os
|
|
import sys
|
|
|
|
if sys.platform == 'win32': # pragma: no cover (windows)
|
|
def _enable() -> None:
|
|
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_ERROR_HANDLE = -12
|
|
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
|
|
|
|
# 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
|
|
stderr = GetStdHandle(STD_ERROR_HANDLE)
|
|
flags = GetConsoleMode(stderr)
|
|
SetConsoleMode(stderr, flags | ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
|
|
|
try:
|
|
_enable()
|
|
except OSError:
|
|
terminal_supports_color = False
|
|
else:
|
|
terminal_supports_color = True
|
|
else: # pragma: win32 no cover
|
|
terminal_supports_color = True
|
|
|
|
RED = '\033[31;7m'
|
|
GREEN = '\033[32;7m'
|
|
YELLOW = '\033[33;7m'
|
|
TURQUOISE = '\033[36;7m'
|
|
SUBTLE = '\033[2m'
|
|
NORMAL = '\033[m'
|
|
|
|
|
|
def format_color(text: str, color: str, use_color_setting: bool) -> str:
|
|
"""Format text with color.
|
|
|
|
Args:
|
|
text - Text to be formatted with color if `use_color`
|
|
color - The color start string
|
|
use_color_setting - Whether or not to color
|
|
"""
|
|
if use_color_setting:
|
|
return f'{color}{text}{NORMAL}'
|
|
else:
|
|
return text
|
|
|
|
|
|
COLOR_CHOICES = ('auto', 'always', 'never')
|
|
|
|
|
|
def use_color(setting: str) -> bool:
|
|
"""Choose whether to use color based on the command argument.
|
|
|
|
Args:
|
|
setting - Either `auto`, `always`, or `never`
|
|
"""
|
|
if setting not in COLOR_CHOICES:
|
|
raise ValueError(setting)
|
|
|
|
return (
|
|
setting == 'always' or (
|
|
setting == 'auto' and
|
|
sys.stderr.isatty() and
|
|
terminal_supports_color and
|
|
os.getenv('TERM') != 'dumb'
|
|
)
|
|
)
|
|
|
|
|
|
def add_color_option(parser: argparse.ArgumentParser) -> None:
|
|
parser.add_argument(
|
|
'--color', default=os.environ.get('PRE_COMMIT_COLOR', 'auto'),
|
|
type=use_color,
|
|
metavar='{' + ','.join(COLOR_CHOICES) + '}',
|
|
help='Whether to use color in output. Defaults to `%(default)s`.',
|
|
)
|