Merge pull request #630 from BYK/colors

Fix background colors for PTK
This commit is contained in:
Morten Enemark Lund 2016-01-23 21:25:43 +01:00
commit 4e4cfda9f0
5 changed files with 89 additions and 58 deletions

View file

@ -11,15 +11,15 @@ from xonsh.tools import TERM_COLORS
from xonsh.environ import format_prompt, Env
builtins.__xonsh_env__ = Env()
builtins.__xonsh_env__['PROMPT_TOOLKIT_COLORS'] = {'WHITE': '#ffffff'}
builtins.__xonsh_env__['PROMPT_TOOLKIT_COLORS'] = {'WHITE': '#f0f0f0'}
def test_format_prompt_for_prompt_toolkit():
templ = ('>>> {BOLD_BLUE}~/xonsh {WHITE} (main){NO_COLOR}')
templ = ('>>> {BOLD_INTENSE_BLUE}~/xonsh {WHITE} {BACKGROUND_RED} {INTENSE_RED}(main){NO_COLOR}')
prompt = format_prompt(templ, TERM_COLORS)
token_names, color_styles, strings = format_prompt_for_prompt_toolkit(prompt)
assert_equal(token_names, ['NO_COLOR', 'BOLD_BLUE', 'WHITE', 'NO_COLOR'])
assert_equal(color_styles, ['', 'bold #0000D2', '#ffffff', ''])
assert_equal(strings, ['>>> ', '~/xonsh ', ' (main)', ''])
assert_equal(token_names, ['NO_COLOR', 'BOLD_INTENSE_BLUE', 'WHITE', 'BACKGROUND_RED', 'INTENSE_RED', 'NO_COLOR'])
assert_equal(color_styles, ['noinherit', 'bold #0000d2', '#f0f0f0', 'bg:#800000', 'bg:#800000 #ff1010', 'noinherit'])
assert_equal(strings, ['>>> ', '~/xonsh ', ' ', ' ', '(main)', ''])
if __name__ == '__main__':

View file

@ -99,12 +99,12 @@ def is_callable_default(x):
"""Checks if a value is a callable default."""
return callable(x) and getattr(x, '_xonsh_callable_default', False)
if ON_WINDOWS:
DEFAULT_PROMPT = ('{BOLD_GREEN}{user}@{hostname}{BOLD_CYAN} '
'{cwd}{branch_color}{curr_branch} '
DEFAULT_PROMPT = ('{BOLD_INTENSE_GREEN}{user}@{hostname}{BOLD_INTENSE_CYAN} '
'{cwd}{branch_color}{curr_branch}{NO_COLOR} '
'{BOLD_WHITE}{prompt_end}{NO_COLOR} ')
else:
DEFAULT_PROMPT = ('{BOLD_GREEN}{user}@{hostname}{BOLD_BLUE} '
'{cwd}{branch_color}{curr_branch} '
'{cwd}{branch_color}{curr_branch}{NO_COLOR} '
'{BOLD_BLUE}{prompt_end}{NO_COLOR} ')
DEFAULT_TITLE = '{current_job}{user}@{hostname}: {cwd} | xonsh'
@ -809,8 +809,14 @@ def dirty_working_directory(cwd=None):
def branch_color():
"""Return red if the current branch is dirty, otherwise green"""
return (TERM_COLORS['BOLD_RED'] if dirty_working_directory() else
TERM_COLORS['BOLD_GREEN'])
return (TERM_COLORS['BOLD_INTENSE_RED'] if dirty_working_directory() else
TERM_COLORS['BOLD_INTENSE_GREEN'])
def branch_bg_color():
"""Return red if the current branch is dirty, otherwise green"""
return (TERM_COLORS['BACKGROUND_RED'] if dirty_working_directory() else
TERM_COLORS['BACKGROUND_GREEN'])
def _replace_home(x):
@ -870,6 +876,7 @@ FORMATTER_DICT = dict(
short_cwd=_collapsed_pwd,
curr_branch=current_branch,
branch_color=branch_color,
branch_bg_color=branch_bg_color,
current_job=_current_job,
**TERM_COLORS)
DEFAULT_VALUES['FORMATTER_DICT'] = dict(FORMATTER_DICT)

View file

@ -179,7 +179,7 @@ def _xonsh_style(tokens=tuple(), cstyles=tuple()):
Token.Aborted: '#888888',
})
# update with the prompt styles
styles.update({t: s for (t, s) in zip(tokens, cstyles)})
styles.update(dict(zip(tokens, cstyles)))
# Update with with any user styles
userstyle = builtins.__xonsh_env__.get('PROMPT_TOOLKIT_STYLES')
if userstyle is not None:

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Hooks for pygments syntax highlighting."""
from pygments.lexer import inherit, bygroups, using, this
from pygments.token import Name, Generic, Keyword, Text, String
from pygments.token import Name, Generic, Keyword, String
from pygments.lexers.shell import BashLexer
from pygments.lexers.agile import PythonLexer
@ -61,7 +61,7 @@ class XonshConsoleLexer(PythonLexer):
'subproc': SUBPROC_TOKENS,
}
# XonshLexer & XonshSubprocLexer have to refernce each other
# XonshLexer & XonshSubprocLexer have to reference each other
XonshSubprocLexer.tokens['root'] = [
(r'(\$\{)(.*)(\})', bygroups(Keyword, using(XonshLexer), Keyword)),
(r'(@\()(.+)(\))', bygroups(Keyword, using(XonshLexer), Keyword)),

View file

@ -53,6 +53,7 @@ VER_FULL = sys.version_info[:3]
VER_MAJOR_MINOR = sys.version_info[:2]
V_MAJOR_MINOR = 'v{0}{1}'.format(*sys.version_info[:2])
def docstring_by_version(**kwargs):
"""Sets a docstring by the python version."""
doc = kwargs.get(V_MAJOR_MINOR, None)
@ -764,71 +765,94 @@ class FakeChar(str):
return iter(self.char)
RE_HIDDEN_MAX = re.compile('(\001.*?\002)+')
COLOR_CODE_SPLIT_RE = re.compile(r'(\001\033\[[\d;m]+\002)')
TERM_COLORS_REVERSED = {v: k for k, v in TERM_COLORS.items()}
COLOR_NAME_REGEX = re.compile(r'(?:(\w+)_)?(\w+)')
_PT_COLORS = {
'BLACK': '#000000',
'RED': '#800000',
'GREEN': '#008000',
'YELLOW': '#808000',
'BLUE': '#000080',
'PURPLE': '#800080',
'CYAN': '#008080',
'WHITE': '#ffffff',
'GRAY': '#008080',
'INTENSE_RED': '#ff1010',
'INTENSE_GREEN': '#00ff18',
'INTENSE_YELLOW': '#ffff00',
'INTENSE_BLUE': '#0000d2',
'INTENSE_PURPLE': '#ff00ff',
'INTENSE_CYAN': '#00ffff',
'INTENSE_GRAY': '#c0c0c0',
None: '',
}
_PT_COLORS_DARK = {'BLACK': '#000000',
'RED': '#ff1010',
'GREEN': '#00FF18',
'YELLOW': '#FFFF00',
'BLUE': '#0000D2',
'PURPLE': '#FF00FF',
'CYAN': '#00FFFF',
'WHITE': '#FFFFFF',
'GRAY': '#c0c0c0'}
_PT_STYLE = {
'BOLD': 'bold',
'UNDERLINE': 'underline',
}
_PT_COLORS_LIGHT = {'BLACK': '#000000',
'RED': '#800000',
'GREEN': '#008000',
'YELLOW': '#808000',
'BLUE': '#000080',
'PURPLE': '#800080',
'CYAN': '#008080',
'WHITE': '#FFFFFF',
'GRAY': '#008080'}
_PT_STYLE = {'BOLD': 'bold',
'UNDERLINE': 'underline',
'INTENSE': 'italic'}
_LAST_BG_COLOR = None
def _make_style(color_name):
""" Convert color names to pygments styles codes """
global _LAST_BG_COLOR
colors = _PT_COLORS.copy()
# Extend with custom colors
colors.update(builtins.__xonsh_env__.get('PROMPT_TOOLKIT_COLORS'))
if color_name == 'NO_COLOR':
_LAST_BG_COLOR = None
return 'noinherit'
qualifiers, name = COLOR_NAME_REGEX.match(color_name).groups()
if name not in colors:
qualifiers = name
name = None
qualifiers = qualifiers.split('_') if qualifiers else []
is_bg_color = False
style = []
for k, v in _PT_STYLE.items():
if k in color_name:
style.append(v)
_custom_colors = builtins.__xonsh_env__.get('PROMPT_TOOLKIT_COLORS')
for k, v in _custom_colors.items():
if k in color_name:
style.append(v)
for k, v in _PT_COLORS_DARK.items():
if k not in _custom_colors and k in color_name:
style.append(v)
for qualifier in qualifiers:
if qualifier == 'INTENSE' and name is not None:
name = 'INTENSE_' + name
elif qualifier == 'BACKGROUND':
is_bg_color = True
elif qualifier in _PT_STYLE:
style.append(_PT_STYLE[qualifier])
color = colors[name]
if is_bg_color:
_LAST_BG_COLOR = color = 'bg:' + color
elif _LAST_BG_COLOR:
style.append(_LAST_BG_COLOR)
style.append(color)
return ' '.join(style)
def get_xonsh_color_names(color_code):
""" Makes a reverse lookup in TERM_COLORS """
try:
return next(k for k, v in TERM_COLORS.items() if v == color_code)
except StopIteration:
return 'NO_COLOR'
def format_prompt_for_prompt_toolkit(prompt):
"""Converts a prompt with color codes to a pygments style and tokens
"""
parts = RE_HIDDEN_MAX.split(prompt)
parts = COLOR_CODE_SPLIT_RE.split(prompt)
# ensure that parts is [colorcode, string, colorcode, string,...]
if parts and len(parts[0]) == 0:
if len(parts[0]) == 0:
parts = parts[1:]
else:
parts.insert(0, '')
if len(parts) % 2 != 0:
parts.append()
parts.append('')
strings = parts[1::2]
token_names = [get_xonsh_color_names(c) for c in parts[::2]]
token_names = [TERM_COLORS_REVERSED.get(c, 'NO_COLOR') for c in parts[::2]]
cstyles = [_make_style(c) for c in token_names]
return token_names, cstyles, strings