mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00
Merge pull request #749 from scopatz/fix_colors_for_cmd_exe
Fix colors for cmd exe
This commit is contained in:
commit
58e5ff61d5
5 changed files with 112 additions and 20 deletions
|
@ -9,7 +9,11 @@ Current Developments
|
|||
* Added a new shell type ``'none'``, used to avoid importing ``readline`` or
|
||||
``prompt_toolkit`` when running scripts or running a single command.
|
||||
* New: `sudo` functionality on Windows through an alias
|
||||
|
||||
* Automatically enhance colors for readability in the default terminal (cmd.exe)
|
||||
on Windows. This functionality can be enabled/disabled with the
|
||||
$INTENSIFY_COLORS_ON_WIN environment variable.
|
||||
|
||||
|
||||
**Changed:**
|
||||
|
||||
* Running scripts through xonsh (or running a single command with ``-c``) no
|
||||
|
|
|
@ -25,7 +25,8 @@ from xonsh.tools import (
|
|||
history_tuple_to_str, is_float, string_types, is_string, DEFAULT_ENCODING,
|
||||
is_completions_display_value, to_completions_display_value, is_string_set,
|
||||
csv_to_set, set_to_csv, get_sep, is_int, is_bool_seq, csv_to_bool_seq,
|
||||
bool_seq_to_csv, DefaultNotGiven, setup_win_unicode_console
|
||||
bool_seq_to_csv, DefaultNotGiven, setup_win_unicode_console,
|
||||
intensify_colors_on_win_setter
|
||||
)
|
||||
from xonsh.dirstack import _get_cwd
|
||||
from xonsh.foreign_shells import DEFAULT_SHELLS, load_foreign_envs
|
||||
|
@ -69,6 +70,7 @@ DEFAULT_ENSURERS = {
|
|||
'FORCE_POSIX_PATHS': (is_bool, to_bool, bool_to_str),
|
||||
'HISTCONTROL': (is_string_set, csv_to_set, set_to_csv),
|
||||
'IGNOREEOF': (is_bool, to_bool, bool_to_str),
|
||||
'INTENSIFY_COLORS_ON_WIN':(always_false, intensify_colors_on_win_setter, bool_to_str),
|
||||
'LC_COLLATE': (always_false, locale_convert('LC_COLLATE'), ensure_string),
|
||||
'LC_CTYPE': (always_false, locale_convert('LC_CTYPE'), ensure_string),
|
||||
'LC_MESSAGES': (always_false, locale_convert('LC_MESSAGES'), ensure_string),
|
||||
|
@ -169,6 +171,7 @@ DEFAULT_VALUES = {
|
|||
'HISTCONTROL': set(),
|
||||
'IGNOREEOF': False,
|
||||
'INDENT': ' ',
|
||||
'INTENSIFY_COLORS_ON_WIN': True,
|
||||
'LC_CTYPE': locale.setlocale(locale.LC_CTYPE),
|
||||
'LC_COLLATE': locale.setlocale(locale.LC_COLLATE),
|
||||
'LC_TIME': locale.setlocale(locale.LC_TIME),
|
||||
|
@ -181,8 +184,6 @@ DEFAULT_VALUES = {
|
|||
'PATH': (),
|
||||
'PATHEXT': (),
|
||||
'PROMPT': DEFAULT_PROMPT,
|
||||
'PROMPT_TOOLKIT_COLORS': {},
|
||||
'PROMPT_TOOLKIT_STYLES': None,
|
||||
'PUSHD_MINUS': False,
|
||||
'PUSHD_SILENT': False,
|
||||
'RAISE_SUBPROC_ERROR': False,
|
||||
|
@ -309,6 +310,10 @@ DEFAULT_DOCS = {
|
|||
"exit status) to not be added to the history list."),
|
||||
'IGNOREEOF': VarDocs('Prevents Ctrl-D from exiting the shell.'),
|
||||
'INDENT': VarDocs('Indentation string for multiline input'),
|
||||
'INTENSIFY_COLORS_ON_WIN': VarDocs('Enhance style colors for readability '
|
||||
'when using the default terminal (cmd.exe) on winodws. Blue colors, '
|
||||
'which are hard to read, are replaced with cyan. Other colors are '
|
||||
'generally replaced by their bright counter parts.'),
|
||||
'LOADED_CONFIG': VarDocs('Whether or not the xonsh config file was loaded',
|
||||
configurable=False),
|
||||
'LOADED_RC_FILES': VarDocs(
|
||||
|
@ -335,17 +340,6 @@ DEFAULT_DOCS = {
|
|||
"auto-formatted, see 'Customizing the Prompt' at "
|
||||
'http://xon.sh/tutorial.html#customizing-the-prompt.',
|
||||
default='xonsh.environ.DEFAULT_PROMPT'),
|
||||
'PROMPT_TOOLKIT_COLORS': VarDocs(
|
||||
'This is a mapping of from color names to HTML color codes. Whenever '
|
||||
'prompt-toolkit would color a word a particular color (in the prompt, '
|
||||
'or in syntax highlighting), it will use the value specified here to '
|
||||
'represent that color, instead of its default. If a color is not '
|
||||
'specified here, prompt-toolkit uses the colors from '
|
||||
"'xonsh.tools._PT_COLORS'.", configurable=False),
|
||||
'PROMPT_TOOLKIT_STYLES': VarDocs(
|
||||
'This is a mapping of pygments tokens to user-specified styles for '
|
||||
'prompt-toolkit. See the prompt-toolkit and pygments documentation '
|
||||
'for more details. If None, this is skipped.', configurable=False),
|
||||
'PUSHD_MINUS': VarDocs(
|
||||
'Flag for directory pushing functionality. False is the normal '
|
||||
'behavior.'),
|
||||
|
|
|
@ -16,6 +16,8 @@ from pygments.style import Style
|
|||
from pygments.styles import get_style_by_name
|
||||
import pygments.util
|
||||
|
||||
from xonsh.tools import (ON_WINDOWS, intensify_colors_for_cmd_exe,
|
||||
expand_gray_colors_for_cmd_exe)
|
||||
|
||||
class XonshSubprocLexer(BashLexer):
|
||||
"""Lexer for xonsh subproc mode."""
|
||||
|
@ -281,7 +283,8 @@ class XonshStyle(Style):
|
|||
style_name : str, optional
|
||||
The style name to initialize with.
|
||||
"""
|
||||
self.trap = {} # for custom colors
|
||||
self.trap = {} # for traping custom colors set by user
|
||||
self._smap = {}
|
||||
self._style_name = ''
|
||||
self.style_name = style_name
|
||||
super().__init__()
|
||||
|
@ -301,17 +304,34 @@ class XonshStyle(Style):
|
|||
RuntimeWarning)
|
||||
cmap = DEFAULT_STYLE
|
||||
try:
|
||||
smap = get_style_by_name(value)().styles
|
||||
self._smap = get_style_by_name(value)().styles.copy()
|
||||
except (ImportError, pygments.util.ClassNotFound):
|
||||
smap = XONSH_BASE_STYLE
|
||||
compound = CompoundColorMap(ChainMap(self.trap, cmap, PTK_STYLE, smap))
|
||||
self.styles = ChainMap(self.trap, cmap, PTK_STYLE, smap, compound)
|
||||
self._smap = XONSH_BASE_STYLE.copy()
|
||||
compound = CompoundColorMap(ChainMap(self.trap, cmap, PTK_STYLE, self._smap))
|
||||
self.styles = ChainMap(self.trap, cmap, PTK_STYLE, self._smap, compound)
|
||||
self._style_name = value
|
||||
if ON_WINDOWS:
|
||||
self.enhance_colors_for_cmd_exe()
|
||||
|
||||
@style_name.deleter
|
||||
def style_name(self):
|
||||
self._style_name = ''
|
||||
|
||||
def enhance_colors_for_cmd_exe(self):
|
||||
""" Enhance colors when using cmd.exe on windows.
|
||||
When using the default style all blue and dark red colors
|
||||
are changed to CYAN and intence red.
|
||||
"""
|
||||
env = builtins.__xonsh_env__
|
||||
# Ensure we are not using ConEmu
|
||||
if 'CONEMUANSI' not in env:
|
||||
# Auto suggest needs to be a darker shade to be distinguishable
|
||||
# from the default color
|
||||
self.styles[Token.AutoSuggestion] = '#444444'
|
||||
if env.get('INTENSIFY_COLORS_ON_WIN', False):
|
||||
self._smap.update(expand_gray_colors_for_cmd_exe(self._smap))
|
||||
self._smap.update(intensify_colors_for_cmd_exe(self._smap))
|
||||
|
||||
|
||||
def xonsh_style_proxy(styler):
|
||||
"""Factory for a proxy class to a xonsh style."""
|
||||
|
|
|
@ -733,6 +733,78 @@ def color_style():
|
|||
return builtins.__xonsh_shell__.shell.color_style()
|
||||
|
||||
|
||||
try:
|
||||
import prompt_toolkit
|
||||
except ImportError:
|
||||
prompt_toolkit = None
|
||||
|
||||
|
||||
def _get_color_indexes(style_map):
|
||||
""" Generates the color and windows color index for a style """
|
||||
table = prompt_toolkit.terminal.win32_output.ColorLookupTable()
|
||||
pt_style = prompt_toolkit.styles.style_from_dict(style_map)
|
||||
for token in style_map:
|
||||
attr = pt_style.token_to_attrs[token]
|
||||
if attr.color is not None:
|
||||
index = table.lookup_color(attr.color, attr.bgcolor)
|
||||
try:
|
||||
rgb = (int(attr.color[0:2], 16),
|
||||
int(attr.color[2:4], 16),
|
||||
int(attr.color[4:6], 16))
|
||||
except:
|
||||
rgb = None
|
||||
yield token, index, rgb
|
||||
|
||||
|
||||
def intensify_colors_for_cmd_exe(style_map, replace_colors=None):
|
||||
"""Returns a modified style to where colors that maps to dark
|
||||
colors are replaced with brighter versions. Also expands the
|
||||
range used by the gray colors
|
||||
"""
|
||||
modified_style = {}
|
||||
if not ON_WINDOWS or prompt_toolkit is None:
|
||||
return modified_style
|
||||
if replace_colors is None:
|
||||
replace_colors = {1: '#44ffff', # subst blue with bright cyan
|
||||
2: '#44ff44', # subst green with bright green
|
||||
4: '#ff4444', # subst red with bright red
|
||||
5: '#ff44ff', # subst magenta with bright magenta
|
||||
6: '#ffff44', # subst yellow with bright yellow
|
||||
9: '#00aaaa', # subst intense blue (hard to read)
|
||||
# with dark cyan (which is readable)
|
||||
}
|
||||
for token, idx, _ in _get_color_indexes(style_map):
|
||||
if idx in replace_colors:
|
||||
modified_style[token] = replace_colors[idx]
|
||||
return modified_style
|
||||
|
||||
|
||||
def expand_gray_colors_for_cmd_exe(style_map):
|
||||
""" Expand the style's gray scale color range.
|
||||
All gray scale colors has a tendency to map to the same default GRAY
|
||||
in cmd.exe.
|
||||
"""
|
||||
modified_style = {}
|
||||
if not ON_WINDOWS or prompt_toolkit is None:
|
||||
return modified_style
|
||||
for token, idx, rgb in _get_color_indexes(style_map):
|
||||
if idx == 7 and rgb:
|
||||
if sum(rgb) <= 306:
|
||||
# Equal and below '#666666 is reset to dark gray
|
||||
modified_style[token] = '#444444'
|
||||
elif sum(rgb) >= 408:
|
||||
# Equal and above 0x888888 is reset to white
|
||||
modified_style[token] = '#ffffff'
|
||||
return modified_style
|
||||
|
||||
|
||||
def intensify_colors_on_win_setter(enable):
|
||||
""" Resets the style when setting the INTENSIFY_COLORS_ON_WIN
|
||||
environment variable. """
|
||||
enable = to_bool(enable)
|
||||
delattr(builtins.__xonsh_shell__.shell.styler, 'style_name')
|
||||
return enable
|
||||
|
||||
|
||||
_RE_STRING_START = "[bBrRuU]*"
|
||||
_RE_STRING_TRIPLE_DOUBLE = '"""'
|
||||
|
|
|
@ -324,6 +324,8 @@ def _tok_colors(cmap, cols):
|
|||
|
||||
def _colors(ns):
|
||||
cols, _ = shutil.get_terminal_size()
|
||||
if tools.ON_WINDOWS:
|
||||
cols -= 1
|
||||
cmap = tools.color_style()
|
||||
akey = next(iter(cmap))
|
||||
if isinstance(akey, str):
|
||||
|
|
Loading…
Add table
Reference in a new issue