Merge pull request #921 from ZyX-I/colorschemes-hierarchy

Implement colorschemes hierarchy

Fixes #770.
This commit is contained in:
Nikolai Aleksandrovich Pavlov 2014-07-12 14:35:49 +04:00
commit 12a93c57ad
21 changed files with 733 additions and 356 deletions

View File

@ -16,7 +16,9 @@ Powerline provides default configurations in the following locations:
`Main configuration`_ `Main configuration`_
:file:`powerline/config.json` :file:`powerline/config.json`
`Colorschemes`_ `Colorschemes`_
:file:`powerline/colorschemes/{extension}/default.json` :file:`powerline/colorschemes/{name}.json`,
:file:`powerline/colorscheme/__main__.json`,
:file:`powerline/colorschemes/{extension}/{name}.json`
`Themes`_ `Themes`_
:file:`powerline/themes/{extension}/default.json` :file:`powerline/themes/{extension}/default.json`
@ -248,7 +250,14 @@ Color definitions
Colorschemes Colorschemes
============ ============
:Location: :file:`powerline/colorschemes/{extension}/{name}.json` :Location: :file:`powerline/colorschemes/{name}.json`,
:file:`powerline/colorscheme/__main__.json`,
:file:`powerline/colorschemes/{extension}/{name}.json`
Colorscheme files are processed in order given: definitions from each next file
override those from each previous file. It is required that either
:file:`powerline/colorschemes/{name}.json`, or
:file:`powerline/colorschemes/{extension}/{name}.json` exists.
``name`` ``name``
Name of the colorscheme. Name of the colorscheme.
@ -258,21 +267,27 @@ Colorschemes
``groups`` ``groups``
Segment highlighting groups, consisting of a dict where the key is the Segment highlighting groups, consisting of a dict where the key is the
name of the highlighting group (usually the function name for function name of the highlighting group (usually the function name for function
segments), and the value is a dict that defines the foreground color, segments), and the value is either
background color and optional attributes:
``fg`` #) a dict that defines the foreground color, background color and
Foreground color. Must be defined in :ref:`colors attributes:
<config-colors-colors>`.
``bg`` ``fg``
Background color. Must be defined in :ref:`colors Foreground color. Must be defined in :ref:`colors
<config-colors-colors>`. <config-colors-colors>`.
``attr`` ``bg``
Optional list of attributes. Valid values are one or more of Background color. Must be defined in :ref:`colors
``bold``, ``italic`` and ``underline``. Note that some attributes <config-colors-colors>`.
may be unavailable in some applications or terminal emulators.
``attr``
List of attributes. Valid values are one or more of ``bold``,
``italic`` and ``underline``. Note that some attributes may be
unavailable in some applications or terminal emulators. If you do not
need any attributes leave this empty.
#) a string (an alias): a name of existing group. This groups definition
will be used when this color is requested.
``mode_translations`` ``mode_translations``
Mode-specific highlighting for extensions that support it (e.g. the vim Mode-specific highlighting for extensions that support it (e.g. the vim

View File

@ -9,6 +9,7 @@ from powerline.colorscheme import Colorscheme
from powerline.lib.config import ConfigLoader from powerline.lib.config import ConfigLoader
from powerline.lib.unicode import safe_unicode, FailedUnicode from powerline.lib.unicode import safe_unicode, FailedUnicode
from powerline.config import DEFAULT_SYSTEM_CONFIG_DIR from powerline.config import DEFAULT_SYSTEM_CONFIG_DIR
from powerline.lib import mergedicts
from threading import Lock, Event from threading import Lock, Event
@ -220,6 +221,22 @@ def finish_common_config(common_config):
return common_config return common_config
if sys.version_info < (3,):
# `raise exception[0], None, exception[1]` is a SyntaxError in python-3*
# Not using ('''…''') because this syntax does not work in python-2.6
exec(('def reraise(exception):\n'
' if type(exception) is tuple:\n'
' raise exception[0], None, exception[1]\n'
' else:\n'
' raise exception\n'))
else:
def reraise(exception):
if type(exception) is tuple:
raise exception[0].with_traceback(exception[1])
else:
raise exception
class Powerline(object): class Powerline(object):
'''Main powerline class, entrance point for all powerline uses. Sets '''Main powerline class, entrance point for all powerline uses. Sets
powerline up and loads the configuration. powerline up and loads the configuration.
@ -455,7 +472,40 @@ class Powerline(object):
:return: dictionary with :ref:`colorscheme configuration <config-colorschemes>`. :return: dictionary with :ref:`colorscheme configuration <config-colorschemes>`.
''' '''
return self._load_config(os.path.join('colorschemes', self.ext, name), 'colorscheme') # TODO Make sure no colorscheme name ends with __ (do it in
# powerline-lint)
levels = (
os.path.join('colorschemes', name),
os.path.join('colorschemes', self.ext, '__main__'),
os.path.join('colorschemes', self.ext, name),
)
config = {}
loaded = 0
exceptions = []
for cfg_path in levels:
try:
lvl_config = self._load_config(cfg_path, 'colorscheme')
except IOError as e:
if sys.version_info < (3,):
tb = sys.exc_info()[2]
exceptions.append((e, tb))
else:
exceptions.append(e)
else:
if not cfg_path.endswith('__'):
loaded += 1
# TODO Either make sure `attr` list is always present or make
# mergedicts not merge group definitions.
mergedicts(config, lvl_config)
if not loaded:
for exception in exceptions:
if type(exception) is tuple:
e = exception[0]
else:
e = exception
self.exception('Failed to load colorscheme: {0}', e, exception=exception)
raise e
return config
def load_colors_config(self): def load_colors_config(self):
'''Get colorscheme. '''Get colorscheme.
@ -562,5 +612,11 @@ class Powerline(object):
def exception(self, msg, *args, **kwargs): def exception(self, msg, *args, **kwargs):
if 'prefix' not in kwargs: if 'prefix' not in kwargs:
kwargs['prefix'] = 'powerline' kwargs['prefix'] = 'powerline'
exception = kwargs.pop('exception', None)
pl = getattr(self, 'pl', None) or get_fallback_logger() pl = getattr(self, 'pl', None) or get_fallback_logger()
if exception:
try:
reraise(exception)
except Exception:
return pl.exception(msg, *args, **kwargs)
return pl.exception(msg, *args, **kwargs) return pl.exception(msg, *args, **kwargs)

View File

@ -1,6 +1,10 @@
# vim:fileencoding=utf-8:noet # vim:fileencoding=utf-8:noet
from copy import copy from copy import copy
try:
from __builtin__ import unicode
except ImportError:
unicode = str
DEFAULT_MODE_KEY = None DEFAULT_MODE_KEY = None
@ -70,32 +74,41 @@ class Colorscheme(object):
else: else:
return self.colors[gradient] return self.colors[gradient]
def get_highlighting(self, groups, mode, gradient_level=None): def get_group_props(self, mode, trans, group, translate_colors=True):
trans = self.translations.get(mode, {}) if isinstance(group, (str, unicode)):
for group in hl_iter(groups): try:
if 'groups' in trans and group in trans['groups']: group_props = trans['groups'][group]
except KeyError:
try: try:
group_props = trans['groups'][group] group_props = self.groups[group]
except KeyError: except KeyError:
continue return None
break else:
return self.get_group_props(mode, trans, group_props, True)
else: else:
try: return self.get_group_props(mode, trans, group_props, False)
group_props = copy(self.groups[group]) else:
except KeyError: if translate_colors:
continue group_props = copy(group)
try: try:
ctrans = trans['colors'] ctrans = trans['colors']
except KeyError:
pass
else:
for key in ('fg', 'bg'): for key in ('fg', 'bg'):
try: try:
group_props[key] = ctrans[group_props[key]] group_props[key] = ctrans[group_props[key]]
except KeyError: except KeyError:
pass pass
except KeyError: return group_props
pass else:
return group
def get_highlighting(self, groups, mode, gradient_level=None):
trans = self.translations.get(mode, {})
for group in hl_iter(groups):
group_props = self.get_group_props(mode, trans, group)
if group_props:
break break
else: else:
raise KeyError('Highlighting groups not found in colorscheme: ' + ', '.join(hl_iter(groups))) raise KeyError('Highlighting groups not found in colorscheme: ' + ', '.join(hl_iter(groups)))

View File

@ -0,0 +1,42 @@
{
"name": "Default",
"groups": {
"background:divider": { "fg": "gray5", "bg": "gray0", "attr": [] },
"session": { "fg": "black", "bg": "gray10", "attr": ["bold"] },
"date": { "fg": "gray8", "bg": "gray2", "attr": [] },
"time": { "fg": "gray10", "bg": "gray2", "attr": ["bold"] },
"time:divider": { "fg": "gray5", "bg": "gray2", "attr": [] },
"email_alert": { "fg": "white", "bg": "brightred", "attr": ["bold"] },
"email_alert_gradient": { "fg": "white", "bg": "yellow_orange_red", "attr": ["bold"] },
"hostname": { "fg": "black", "bg": "gray10", "attr": ["bold"] },
"weather": { "fg": "gray8", "bg": "gray0", "attr": [] },
"weather_temp_gradient": { "fg": "blue_red", "bg": "gray0", "attr": [] },
"weather_condition_hot": { "fg": "khaki1", "bg": "gray0", "attr": [] },
"weather_condition_snowy": { "fg": "skyblue1", "bg": "gray0", "attr": [] },
"weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0", "attr": [] },
"uptime": { "fg": "gray8", "bg": "gray0", "attr": [] },
"external_ip": { "fg": "gray8", "bg": "gray0", "attr": [] },
"network_load": { "fg": "gray8", "bg": "gray0", "attr": [] },
"network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attr": [] },
"system_load": { "fg": "gray8", "bg": "gray0", "attr": [] },
"system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attr": [] },
"environment": { "fg": "gray8", "bg": "gray0", "attr": [] },
"cpu_load_percent": { "fg": "gray8", "bg": "gray0", "attr": [] },
"cpu_load_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0", "attr": [] },
"battery": { "fg": "gray8", "bg": "gray0", "attr": [] },
"battery_gradient": { "fg": "white_red", "bg": "gray0", "attr": [] },
"battery_full": { "fg": "red", "bg": "gray0", "attr": [] },
"battery_empty": { "fg": "white", "bg": "gray0", "attr": [] },
"now_playing": { "fg": "gray10", "bg": "black", "attr": [] },
"user": { "fg": "white", "bg": "darkblue", "attr": ["bold"] },
"superuser": { "fg": "white", "bg": "brightred", "attr": ["bold"] },
"branch": { "fg": "gray9", "bg": "gray2", "attr": [] },
"branch_dirty": { "fg": "brightyellow", "bg": "gray2", "attr": [] },
"branch_clean": { "fg": "gray9", "bg": "gray2", "attr": [] },
"branch:divider": { "fg": "gray7", "bg": "gray2", "attr": [] },
"cwd": { "fg": "gray9", "bg": "gray4", "attr": [] },
"cwd:current_folder": { "fg": "gray10", "bg": "gray4", "attr": ["bold"] },
"cwd:divider": { "fg": "gray7", "bg": "gray4", "attr": [] },
"virtualenv": { "fg": "white", "bg": "darkcyan", "attr": [] }
}
}

View File

@ -1,8 +1,7 @@
{ {
"name": "Default color scheme for IPython prompt", "name": "Default color scheme for IPython prompt",
"groups": { "groups": {
"virtualenv": { "fg": "white", "bg": "darkcyan" }, "prompt": { "fg": "gray9", "bg": "gray4", "attr": [] },
"prompt": { "fg": "gray9", "bg": "gray4" }, "prompt_count": { "fg": "white", "bg": "gray4", "attr": [] }
"prompt_count": { "fg": "white", "bg": "gray4" }
} }
} }

View File

@ -0,0 +1,6 @@
{
"groups": {
"continuation": "cwd",
"continuation:current": "cwd:current_folder"
}
}

View File

@ -1,23 +1,12 @@
{ {
"name": "Default color scheme for shell prompts", "name": "Default color scheme for shell prompts",
"groups": { "groups": {
"jobnum": { "fg": "brightyellow", "bg": "mediumorange" }, "hostname": { "fg": "brightyellow", "bg": "mediumorange", "attr": [] },
"user": { "fg": "white", "bg": "darkblue", "attr": ["bold"] }, "jobnum": { "fg": "brightyellow", "bg": "mediumorange", "attr": [] },
"superuser": { "fg": "white", "bg": "brightred", "attr": ["bold"] }, "exit_fail": { "fg": "white", "bg": "darkestred", "attr": [] },
"virtualenv": { "fg": "white", "bg": "darkcyan" }, "exit_success": { "fg": "white", "bg": "darkestgreen", "attr": [] },
"branch": { "fg": "gray9", "bg": "gray2" }, "environment": { "fg": "white", "bg": "darkestgreen", "attr": [] },
"branch_dirty": { "fg": "brightyellow", "bg": "gray2" }, "mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] }
"branch_clean": { "fg": "gray9", "bg": "gray2" },
"continuation": { "fg": "gray9", "bg": "gray4" },
"continuation:current": { "fg": "gray10", "bg": "gray4", "attr": ["bold"] },
"cwd": { "fg": "gray9", "bg": "gray4" },
"cwd:current_folder": { "fg": "gray10", "bg": "gray4", "attr": ["bold"] },
"cwd:divider": { "fg": "gray7", "bg": "gray4" },
"hostname": { "fg": "brightyellow", "bg": "mediumorange" },
"exit_fail": { "fg": "white", "bg": "darkestred" },
"exit_success": { "fg": "white", "bg": "darkestgreen" },
"environment": { "fg": "white", "bg": "darkestgreen" },
"mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] }
}, },
"mode_translations": { "mode_translations": {
"vicmd": { "vicmd": {

View File

@ -1,23 +1,10 @@
{ {
"name": "Solarized Dark", "name": "Solarized dark for shell",
"groups": { "groups": {
"jobnum": { "fg": "oldlace", "bg": "darkgreencopper" }, "jobnum": { "fg": "oldlace", "bg": "darkgreencopper", "attr": [] },
"user": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] }, "exit_fail": { "fg": "oldlace", "bg": "red", "attr": [] },
"superuser": { "fg": "oldlace", "bg": "red", "attr": ["bold"] }, "exit_success": { "fg": "oldlace", "bg": "green", "attr": [] },
"virtualenv": { "fg": "oldlace", "bg": "green" }, "mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] }
"branch": { "fg": "gray61", "bg": "royalblue5" },
"branch_dirty": { "fg": "yellow", "bg": "royalblue5" },
"branch_clean": { "fg": "gray61", "bg": "royalblue5" },
"continuation": { "fg": "lightyellow", "bg": "darkgreencopper" },
"continuation:current": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
"cwd": { "fg": "lightyellow", "bg": "darkgreencopper" },
"cwd:current_folder": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
"cwd:divider": { "fg": "gray61", "bg": "darkgreencopper" },
"hostname": { "fg": "oldlace", "bg": "darkgreencopper" },
"exit_fail": { "fg": "oldlace", "bg": "red" },
"exit_success": { "fg": "oldlace", "bg": "green" },
"environment": { "fg": "oldlace", "bg": "green" },
"mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] }
}, },
"mode_translations": { "mode_translations": {
"vicmd": { "vicmd": {

View File

@ -0,0 +1,17 @@
{
"name": "Solarized dark",
"groups": {
"background": { "fg": "oldlace", "bg": "royalblue5", "attr": [] },
"user": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] },
"superuser": { "fg": "oldlace", "bg": "red", "attr": ["bold"] },
"virtualenv": { "fg": "oldlace", "bg": "green", "attr": [] },
"branch": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
"branch_dirty": { "fg": "yellow", "bg": "royalblue5", "attr": [] },
"branch_clean": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
"cwd": { "fg": "lightyellow", "bg": "darkgreencopper", "attr": [] },
"cwd:current_folder": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
"cwd:divider": { "fg": "gray61", "bg": "darkgreencopper", "attr": [] },
"hostname": { "fg": "oldlace", "bg": "darkgreencopper", "attr": [] },
"environment": { "fg": "oldlace", "bg": "green", "attr": [] }
}
}

View File

@ -1,32 +0,0 @@
{
"name": "Default color scheme for terminal prompts",
"groups": {
"background:divider": { "fg": "gray5", "bg": "gray0" },
"session": { "fg": "black", "bg": "gray10", "attr": ["bold"] },
"date": { "fg": "gray8", "bg": "gray2" },
"time": { "fg": "gray10", "bg": "gray2", "attr": ["bold"] },
"time:divider": { "fg": "gray5", "bg": "gray2" },
"email_alert": { "fg": "white", "bg": "brightred", "attr": ["bold"] },
"email_alert_gradient": { "fg": "white", "bg": "yellow_orange_red", "attr": ["bold"] },
"hostname": { "fg": "black", "bg": "gray10", "attr": ["bold"] },
"weather": { "fg": "gray8", "bg": "gray0" },
"weather_temp_gradient": { "fg": "blue_red", "bg": "gray0" },
"weather_condition_hot": { "fg": "khaki1", "bg": "gray0" },
"weather_condition_snowy": { "fg": "skyblue1", "bg": "gray0" },
"weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0" },
"uptime": { "fg": "gray8", "bg": "gray0" },
"external_ip": { "fg": "gray8", "bg": "gray0" },
"network_load": { "fg": "gray8", "bg": "gray0" },
"network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" },
"system_load": { "fg": "gray8", "bg": "gray0" },
"system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" },
"cpu_load_percent": { "fg": "gray8", "bg": "gray0" },
"cpu_load_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" },
"environment": { "fg": "gray8", "bg": "gray0" },
"battery": { "fg": "gray8", "bg": "gray0" },
"battery_gradient": { "fg": "white_red", "bg": "gray0" },
"battery_full": { "fg": "red", "bg": "gray0" },
"battery_empty": { "fg": "white", "bg": "gray0" },
"now_playing": { "fg": "gray10", "bg": "black" }
}
}

View File

@ -0,0 +1,15 @@
{
"groups": {
"branch_clean": "branch",
"environment": "information:unimportant",
"file_size": "information:unimportant",
"file_format": "information:unimportant",
"file_encoding": "file_format",
"file_type": "file_format",
"branch": "information:additional",
"file_directory": "information:additional",
"file_name_empty": "file_directory",
"line_percent": "information:additional",
"position": "information:additional"
}
}

View File

@ -1,42 +1,35 @@
{ {
"name": "Default color scheme", "name": "Default color scheme",
"groups": { "groups": {
"background": { "fg": "white", "bg": "gray2" }, "information:unimportant": { "fg": "gray8", "bg": "gray2", "attr": [] },
"background:divider": { "fg": "gray6", "bg": "gray2" }, "information:additional": { "fg": "gray9", "bg": "gray4", "attr": [] },
"background": { "fg": "white", "bg": "gray2", "attr": [] },
"background:divider": { "fg": "gray6", "bg": "gray2", "attr": [] },
"mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] }, "mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] },
"visual_range": { "fg": "brightestorange", "bg": "darkorange", "attr": ["bold"] }, "visual_range": { "fg": "brightestorange", "bg": "darkorange", "attr": ["bold"] },
"modified_indicator": { "fg": "brightyellow", "bg": "gray4", "attr": ["bold"] }, "modified_indicator": { "fg": "brightyellow", "bg": "gray4", "attr": ["bold"] },
"paste_indicator": { "fg": "white", "bg": "mediumorange", "attr": ["bold"] }, "paste_indicator": { "fg": "white", "bg": "mediumorange", "attr": ["bold"] },
"readonly_indicator": { "fg": "brightestred", "bg": "gray4" }, "readonly_indicator": { "fg": "brightestred", "bg": "gray4", "attr": [] },
"branch": { "fg": "gray9", "bg": "gray4" }, "branch_dirty": { "fg": "brightyellow", "bg": "gray4", "attr": [] },
"branch_dirty": { "fg": "brightyellow", "bg": "gray4" }, "branch:divider": { "fg": "gray7", "bg": "gray4", "attr": [] },
"branch_clean": { "fg": "gray9", "bg": "gray4" },
"branch:divider": { "fg": "gray7", "bg": "gray4" },
"file_directory": { "fg": "gray9", "bg": "gray4" },
"file_name": { "fg": "white", "bg": "gray4", "attr": ["bold"] }, "file_name": { "fg": "white", "bg": "gray4", "attr": ["bold"] },
"window_title": { "fg": "white", "bg": "gray4" }, "window_title": { "fg": "white", "bg": "gray4", "attr": [] },
"file_size": { "fg": "gray8", "bg": "gray2" },
"file_name_no_file": { "fg": "gray9", "bg": "gray4", "attr": ["bold"] }, "file_name_no_file": { "fg": "gray9", "bg": "gray4", "attr": ["bold"] },
"file_name_empty": { "fg": "gray9", "bg": "gray4" }, "file_vcs_status": { "fg": "brightestred", "bg": "gray4", "attr": [] },
"file_format": { "fg": "gray8", "bg": "gray2" }, "file_vcs_status_M": { "fg": "brightyellow", "bg": "gray4", "attr": [] },
"file_encoding": { "fg": "gray8", "bg": "gray2" }, "file_vcs_status_A": { "fg": "brightgreen", "bg": "gray4", "attr": [] },
"file_type": { "fg": "gray8", "bg": "gray2" }, "line_percent": { "fg": "gray9", "bg": "gray4", "attr": [] },
"file_vcs_status": { "fg": "brightestred", "bg": "gray4" }, "line_percent_gradient": { "fg": "dark_green_gray", "bg": "gray4", "attr": [] },
"file_vcs_status_M": { "fg": "brightyellow", "bg": "gray4" }, "position": { "fg": "gray9", "bg": "gray4", "attr": [] },
"file_vcs_status_A": { "fg": "brightgreen", "bg": "gray4" }, "position_gradient": { "fg": "green_yellow_red", "bg": "gray4", "attr": [] },
"line_percent": { "fg": "gray9", "bg": "gray4" },
"line_percent_gradient": { "fg": "dark_green_gray", "bg": "gray4" },
"position": { "fg": "gray9", "bg": "gray4" },
"position_gradient": { "fg": "green_yellow_red", "bg": "gray4" },
"line_current": { "fg": "gray1", "bg": "gray10", "attr": ["bold"] }, "line_current": { "fg": "gray1", "bg": "gray10", "attr": ["bold"] },
"line_current_symbol": { "fg": "gray1", "bg": "gray10" }, "line_current_symbol": { "fg": "gray1", "bg": "gray10", "attr": [] },
"virtcol_current_gradient": { "fg": "dark_GREEN_Orange_red", "bg": "gray10" }, "virtcol_current_gradient": { "fg": "dark_GREEN_Orange_red", "bg": "gray10", "attr": [] },
"col_current": { "fg": "gray6", "bg": "gray10" }, "col_current": { "fg": "gray6", "bg": "gray10", "attr": [] },
"modified_buffers": { "fg": "brightyellow", "bg": "gray2" }, "modified_buffers": { "fg": "brightyellow", "bg": "gray2", "attr": [] },
"environment": { "fg": "gray8", "bg": "gray2" },
"error": { "fg": "brightestred", "bg": "darkred", "attr": ["bold"] }, "error": { "fg": "brightestred", "bg": "darkred", "attr": ["bold"] },
"warning": { "fg": "brightyellow", "bg": "darkorange", "attr": ["bold"] }, "warning": { "fg": "brightyellow", "bg": "darkorange", "attr": ["bold"] },
"current_tag": { "fg": "gray9", "bg": "gray2" } "current_tag": { "fg": "gray9", "bg": "gray2", "attr": [] }
}, },
"mode_translations": { "mode_translations": {
"nc": { "nc": {
@ -76,8 +69,8 @@
}, },
"groups": { "groups": {
"mode": { "fg": "darkestcyan", "bg": "white", "attr": ["bold"] }, "mode": { "fg": "darkestcyan", "bg": "white", "attr": ["bold"] },
"background:divider": { "fg": "darkcyan", "bg": "darkestblue" }, "background:divider": { "fg": "darkcyan", "bg": "darkestblue", "attr": [] },
"branch:divider": { "fg": "darkcyan", "bg": "darkblue" } "branch:divider": { "fg": "darkcyan", "bg": "darkblue", "attr": [] }
} }
}, },
"v": { "v": {

View File

@ -1,38 +1,33 @@
{ {
"name": "Solarized Dark", "name": "Solarized dark for vim",
"groups": { "groups": {
"background": { "fg": "oldlace", "bg": "royalblue5" }, "information:additional": { "fg": "lightyellow", "bg": "darkgreencopper", "attr": [] },
"background:divider": { "fg": "lightskyblue4", "bg": "royalblue5" }, "information:unimportant": { "fg": "oldlace", "bg": "darkgreencopper", "attr": [] },
"background": { "fg": "oldlace", "bg": "royalblue5", "attr": [] },
"background:divider": { "fg": "lightskyblue4", "bg": "royalblue5", "attr": [] },
"mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] }, "mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] },
"visual_range": { "fg": "green", "bg": "oldlace", "attr": ["bold"] }, "visual_range": { "fg": "green", "bg": "oldlace", "attr": ["bold"] },
"modified_indicator": { "fg": "yellow", "bg": "darkgreencopper", "attr": ["bold"] }, "modified_indicator": { "fg": "yellow", "bg": "darkgreencopper", "attr": ["bold"] },
"paste_indicator": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] }, "paste_indicator": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] },
"readonly_indicator": { "fg": "red", "bg": "darkgreencopper" }, "readonly_indicator": { "fg": "red", "bg": "darkgreencopper", "attr": [] },
"branch": { "fg": "lightyellow", "bg": "darkgreencopper" }, "branch_dirty": { "fg": "yellow", "bg": "darkgreencopper", "attr": [] },
"branch_dirty": { "fg": "yellow", "bg": "darkgreencopper" }, "branch:divider": { "fg": "gray61", "bg": "darkgreencopper", "attr": [] },
"branch_clean": { "fg": "lightyellow", "bg": "darkgreencopper" },
"branch:divider": { "fg": "gray61", "bg": "darkgreencopper" },
"file_directory": { "fg": "lightyellow", "bg": "darkgreencopper" },
"file_name": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] }, "file_name": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
"window_title": { "fg": "oldlace", "bg": "darkgreencopper" }, "window_title": { "fg": "oldlace", "bg": "darkgreencopper", "attr": [] },
"file_size": { "fg": "oldlace", "bg": "darkgreencopper" },
"file_name_no_file": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] }, "file_name_no_file": { "fg": "oldlace", "bg": "darkgreencopper", "attr": ["bold"] },
"file_name_empty": { "fg": "oldlace", "bg": "darkgreencopper" }, "file_format": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
"file_format": { "fg": "gray61", "bg": "royalblue5" }, "file_vcs_status": { "fg": "red", "bg": "darkgreencopper", "attr": [] },
"file_encoding": { "fg": "gray61", "bg": "royalblue5" }, "file_vcs_status_M": { "fg": "yellow", "bg": "darkgreencopper", "attr": [] },
"file_type": { "fg": "gray61", "bg": "royalblue5" }, "file_vcs_status_A": { "fg": "green", "bg": "darkgreencopper", "attr": [] },
"file_vcs_status": { "fg": "red", "bg": "darkgreencopper" }, "line_percent": { "fg": "oldlace", "bg": "lightskyblue4", "attr": [] },
"file_vcs_status_M": { "fg": "yellow", "bg": "darkgreencopper" }, "line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "lightskyblue4", "attr": [] },
"file_vcs_status_A": { "fg": "green", "bg": "darkgreencopper" }, "position": { "fg": "oldlace", "bg": "lightskyblue4", "attr": [] },
"line_percent": { "fg": "oldlace", "bg": "lightskyblue4" }, "position_gradient": { "fg": "green_yellow_orange_red", "bg": "lightskyblue4", "attr": [] },
"line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "lightskyblue4" },
"position": { "fg": "oldlace", "bg": "lightskyblue4" },
"position_gradient": { "fg": "green_yellow_orange_red", "bg": "lightskyblue4" },
"line_current": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] }, "line_current": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] },
"line_current_symbol": { "fg": "gray13", "bg": "lightyellow" }, "line_current_symbol": { "fg": "gray13", "bg": "lightyellow", "attr": [] },
"virtcol_current_gradient": { "fg": "GREEN_Orange_red", "bg": "lightyellow" }, "virtcol_current_gradient": { "fg": "GREEN_Orange_red", "bg": "lightyellow", "attr": [] },
"col_current": { "fg": "azure4", "bg": "lightyellow" }, "col_current": { "fg": "azure4", "bg": "lightyellow", "attr": [] },
"environment": { "fg": "gray61", "bg": "royalblue5" }, "environment": { "fg": "gray61", "bg": "royalblue5", "attr": [] },
"error": { "fg": "oldlace", "bg": "red", "attr": ["bold"] }, "error": { "fg": "oldlace", "bg": "red", "attr": ["bold"] },
"warning": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] }, "warning": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] },
"current_tag": { "fg": "oldlace", "bg": "royalblue5", "attr": ["bold"] } "current_tag": { "fg": "oldlace", "bg": "royalblue5", "attr": ["bold"] }
@ -50,32 +45,30 @@
}, },
"i": { "i": {
"groups": { "groups": {
"background": { "fg": "oldlace", "bg": "darkgreencopper" }, "background": { "fg": "oldlace", "bg": "darkgreencopper", "attr": [] },
"background:divider": { "fg": "lightyellow", "bg": "darkgreencopper" }, "background:divider": { "fg": "lightyellow", "bg": "darkgreencopper", "attr": [] },
"mode": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] }, "mode": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] },
"modified_indicator": { "fg": "yellow", "bg": "lightyellow", "attr": ["bold"] }, "modified_indicator": { "fg": "yellow", "bg": "lightyellow", "attr": ["bold"] },
"paste_indicator": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] }, "paste_indicator": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] },
"readonly_indicator": { "fg": "red", "bg": "lightyellow" }, "readonly_indicator": { "fg": "red", "bg": "lightyellow", "attr": [] },
"branch": { "fg": "darkgreencopper", "bg": "lightyellow" }, "branch": { "fg": "darkgreencopper", "bg": "lightyellow", "attr": [] },
"branch:divider": { "fg": "lightskyblue4", "bg": "lightyellow" }, "branch:divider": { "fg": "lightskyblue4", "bg": "lightyellow", "attr": [] },
"file_directory": { "fg": "darkgreencopper", "bg": "lightyellow" }, "file_directory": { "fg": "darkgreencopper", "bg": "lightyellow", "attr": [] },
"file_name": { "fg": "royalblue5", "bg": "lightyellow", "attr": ["bold"] }, "file_name": { "fg": "royalblue5", "bg": "lightyellow", "attr": ["bold"] },
"file_size": { "fg": "royalblue5", "bg": "lightyellow" }, "file_size": { "fg": "royalblue5", "bg": "lightyellow", "attr": [] },
"file_name_no_file": { "fg": "royalblue5", "bg": "lightyellow", "attr": ["bold"] }, "file_name_no_file": { "fg": "royalblue5", "bg": "lightyellow", "attr": ["bold"] },
"file_name_empty": { "fg": "royalblue5", "bg": "lightyellow" }, "file_name_empty": { "fg": "royalblue5", "bg": "lightyellow", "attr": [] },
"file_format": { "fg": "lightyellow", "bg": "darkgreencopper" }, "file_format": { "fg": "lightyellow", "bg": "darkgreencopper", "attr": [] },
"file_encoding": { "fg": "lightyellow", "bg": "darkgreencopper" }, "file_vcs_status": { "fg": "red", "bg": "lightyellow", "attr": [] },
"file_type": { "fg": "lightyellow", "bg": "darkgreencopper" }, "file_vcs_status_M": { "fg": "yellow", "bg": "lightyellow", "attr": [] },
"file_vcs_status": { "fg": "red", "bg": "lightyellow" }, "file_vcs_status_A": { "fg": "green", "bg": "lightyellow", "attr": [] },
"file_vcs_status_M": { "fg": "yellow", "bg": "lightyellow" }, "line_percent": { "fg": "oldlace", "bg": "gray61", "attr": [] },
"file_vcs_status_A": { "fg": "green", "bg": "lightyellow" }, "line_percent_gradient": { "fg": "oldlace", "bg": "gray61", "attr": [] },
"line_percent": { "fg": "oldlace", "bg": "gray61" }, "position": { "fg": "oldlace", "bg": "gray61", "attr": [] },
"line_percent_gradient": { "fg": "oldlace", "bg": "gray61" }, "position_gradient": { "fg": "oldlace", "bg": "gray61", "attr": [] },
"position": { "fg": "oldlace", "bg": "gray61" },
"position_gradient": { "fg": "oldlace", "bg": "gray61" },
"line_current": { "fg": "gray13", "bg": "oldlace", "attr": ["bold"] }, "line_current": { "fg": "gray13", "bg": "oldlace", "attr": ["bold"] },
"line_current_symbol": { "fg": "gray13", "bg": "oldlace" }, "line_current_symbol": { "fg": "gray13", "bg": "oldlace", "attr": [] },
"col_current": { "fg": "azure4", "bg": "oldlace" } "col_current": { "fg": "azure4", "bg": "oldlace", "attr": [] }
} }
}, },
"v": { "v": {

View File

@ -1,38 +1,33 @@
{ {
"name": "Solarized Light", "name": "Solarized light for vim",
"groups": { "groups": {
"background": { "fg": "gray13", "bg": "darkgreencopper" }, "information:additional": { "fg": "royalblue5", "bg": "lightyellow", "attr": [] },
"background:divider": { "fg": "azure4", "bg": "darkgreencopper" }, "information:unimportant": { "fg": "gray61", "bg": "darkgreencopper", "attr": [] },
"background": { "fg": "gray13", "bg": "darkgreencopper", "attr": [] },
"background:divider": { "fg": "azure4", "bg": "darkgreencopper", "attr": [] },
"mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] }, "mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] },
"visual_range": { "fg": "green", "bg": "oldlace", "attr": ["bold"] }, "visual_range": { "fg": "green", "bg": "oldlace", "attr": ["bold"] },
"modified_indicator": { "fg": "yellow", "bg": "lightyellow", "attr": ["bold"] }, "modified_indicator": { "fg": "yellow", "bg": "lightyellow", "attr": ["bold"] },
"paste_indicator": { "fg": "red", "bg": "lightyellow", "attr": ["bold"] }, "paste_indicator": { "fg": "red", "bg": "lightyellow", "attr": ["bold"] },
"readonly_indicator": { "fg": "red", "bg": "lightyellow" }, "readonly_indicator": { "fg": "red", "bg": "lightyellow", "attr": [] },
"branch": { "fg": "royalblue5", "bg": "lightyellow" }, "branch_dirty": { "fg": "yellow", "bg": "lightyellow", "attr": [] },
"branch_dirty": { "fg": "yellow", "bg": "lightyellow" }, "branch:divider": { "fg": "gray61", "bg": "lightyellow", "attr": [] },
"branch_clean": { "fg": "royalblue5", "bg": "lightyellow" },
"branch:divider": { "fg": "gray61", "bg": "lightyellow" },
"file_directory": { "fg": "royalblue5", "bg": "lightyellow" },
"file_name": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] }, "file_name": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] },
"window_title": { "fg": "gray13", "bg": "lightyellow" }, "window_title": { "fg": "gray13", "bg": "lightyellow", "attr": [] },
"file_size": { "fg": "gray13", "bg": "lightyellow" }, "file_size": { "fg": "gray13", "bg": "lightyellow", "attr": [] },
"file_name_no_file": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] }, "file_name_no_file": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] },
"file_name_empty": { "fg": "gray13", "bg": "lightyellow" }, "file_name_empty": { "fg": "gray13", "bg": "lightyellow", "attr": [] },
"file_format": { "fg": "gray61", "bg": "darkgreencopper" }, "file_vcs_status": { "fg": "red", "bg": "lightyellow", "attr": [] },
"file_encoding": { "fg": "gray61", "bg": "darkgreencopper" }, "file_vcs_status_M": { "fg": "yellow", "bg": "lightyellow", "attr": [] },
"file_type": { "fg": "gray61", "bg": "darkgreencopper" }, "file_vcs_status_A": { "fg": "green", "bg": "lightyellow", "attr": [] },
"file_vcs_status": { "fg": "red", "bg": "lightyellow" }, "line_percent": { "fg": "gray13", "bg": "lightyellow", "attr": [] },
"file_vcs_status_M": { "fg": "yellow", "bg": "lightyellow" }, "line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "lightyellow", "attr": [] },
"file_vcs_status_A": { "fg": "green", "bg": "lightyellow" }, "position": { "fg": "gray13", "bg": "lightyellow", "attr": [] },
"line_percent": { "fg": "gray13", "bg": "lightyellow" }, "position_gradient": { "fg": "green_yellow_orange_red", "bg": "lightyellow", "attr": [] },
"line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "lightyellow" },
"position": { "fg": "gray13", "bg": "lightyellow" },
"position_gradient": { "fg": "green_yellow_orange_red", "bg": "lightyellow" },
"line_current": { "fg": "oldlace", "bg": "royalblue5", "attr": ["bold"] }, "line_current": { "fg": "oldlace", "bg": "royalblue5", "attr": ["bold"] },
"line_current_symbol": { "fg": "oldlace", "bg": "royalblue5" }, "line_current_symbol": { "fg": "oldlace", "bg": "royalblue5", "attr": [] },
"virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "royalblue5" }, "virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "royalblue5", "attr": [] },
"col_current": { "fg": "lightskyblue4", "bg": "royalblue5" }, "col_current": { "fg": "lightskyblue4", "bg": "royalblue5", "attr": [] },
"environment": { "fg": "gray61", "bg": "darkgreencopper" },
"error": { "fg": "gray13", "bg": "red", "attr": ["bold"] }, "error": { "fg": "gray13", "bg": "red", "attr": ["bold"] },
"warning": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] }, "warning": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] },
"current_tag": { "fg": "gray13", "bg": "darkgreencopper", "attr": ["bold"] } "current_tag": { "fg": "gray13", "bg": "darkgreencopper", "attr": ["bold"] }
@ -50,33 +45,31 @@
}, },
"i": { "i": {
"groups": { "groups": {
"background": { "fg": "gray13", "bg": "lightyellow" }, "background": { "fg": "gray13", "bg": "lightyellow", "attr": [] },
"background:divider": { "fg": "royalblue5", "bg": "lightyellow" }, "background:divider": { "fg": "royalblue5", "bg": "lightyellow", "attr": [] },
"mode": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] }, "mode": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] },
"modified_indicator": { "fg": "yellow", "bg": "royalblue5", "attr": ["bold"] }, "modified_indicator": { "fg": "yellow", "bg": "royalblue5", "attr": ["bold"] },
"paste_indicator": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] }, "paste_indicator": { "fg": "oldlace", "bg": "orange", "attr": ["bold"] },
"readonly_indicator": { "fg": "red", "bg": "royalblue5" }, "readonly_indicator": { "fg": "red", "bg": "royalblue5", "attr": [] },
"branch": { "fg": "lightyellow", "bg": "royalblue5" }, "branch": { "fg": "lightyellow", "bg": "royalblue5", "attr": [] },
"branch:divider": { "fg": "azure4", "bg": "royalblue5" }, "branch:divider": { "fg": "azure4", "bg": "royalblue5", "attr": [] },
"file_directory": { "fg": "lightyellow", "bg": "royalblue5" }, "file_directory": { "fg": "lightyellow", "bg": "royalblue5", "attr": [] },
"file_name": { "fg": "darkgreencopper", "bg": "royalblue5", "attr": ["bold"] }, "file_name": { "fg": "darkgreencopper", "bg": "royalblue5", "attr": ["bold"] },
"file_size": { "fg": "darkgreencopper", "bg": "royalblue5" }, "file_size": { "fg": "darkgreencopper", "bg": "royalblue5", "attr": [] },
"file_name_no_file": { "fg": "darkgreencopper", "bg": "royalblue5", "attr": ["bold"] }, "file_name_no_file": { "fg": "darkgreencopper", "bg": "royalblue5", "attr": ["bold"] },
"file_name_empty": { "fg": "darkgreencopper", "bg": "royalblue5" }, "file_name_empty": { "fg": "darkgreencopper", "bg": "royalblue5", "attr": [] },
"file_format": { "fg": "royalblue5", "bg": "lightyellow" }, "file_format": { "fg": "royalblue5", "bg": "lightyellow", "attr": [] },
"file_encoding": { "fg": "royalblue5", "bg": "lightyellow" }, "file_vcs_status": { "fg": "red", "bg": "royalblue5", "attr": [] },
"file_type": { "fg": "royalblue5", "bg": "lightyellow" }, "file_vcs_status_M": { "fg": "yellow", "bg": "royalblue5", "attr": [] },
"file_vcs_status": { "fg": "red", "bg": "royalblue5" }, "file_vcs_status_A": { "fg": "green", "bg": "royalblue5", "attr": [] },
"file_vcs_status_M": { "fg": "yellow", "bg": "royalblue5" }, "line_percent": { "fg": "gray13", "bg": "gray61", "attr": [] },
"file_vcs_status_A": { "fg": "green", "bg": "royalblue5" }, "line_percent_gradient": { "fg": "gray13", "bg": "gray61", "attr": [] },
"line_percent": { "fg": "gray13", "bg": "gray61" }, "position": { "fg": "gray13", "bg": "gray61", "attr": [] },
"line_percent_gradient": { "fg": "gray13", "bg": "gray61" }, "position_gradient": { "fg": "gray13", "bg": "gray61", "attr": [] },
"position": { "fg": "gray13", "bg": "gray61" },
"position_gradient": { "fg": "gray13", "bg": "gray61" },
"line_current": { "fg": "oldlace", "bg": "gray13", "attr": ["bold"] }, "line_current": { "fg": "oldlace", "bg": "gray13", "attr": ["bold"] },
"line_current_symbol": { "fg": "oldlace", "bg": "gray13" }, "line_current_symbol": { "fg": "oldlace", "bg": "gray13", "attr": [] },
"virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "gray13" }, "virtcol_current_gradient": { "fg": "yellow_orange_red", "bg": "gray13", "attr": [] },
"col_current": { "fg": "lightskyblue4", "bg": "gray13" } "col_current": { "fg": "lightskyblue4", "bg": "gray13", "attr": [] }
} }
}, },
"v": { "v": {

View File

@ -1,26 +0,0 @@
{
"name": "Default color scheme for window managers",
"groups": {
"background:divider": { "fg": "gray5", "bg": "gray0" },
"session": { "fg": "black", "bg": "gray10", "attr": ["bold"] },
"date": { "fg": "gray8", "bg": "gray2" },
"time": { "fg": "gray10", "bg": "gray2", "attr": ["bold"] },
"time:divider": { "fg": "gray5", "bg": "gray2" },
"email_alert": { "fg": "white", "bg": "brightred", "attr": ["bold"] },
"email_alert_gradient": { "fg": "white", "bg": "yellow_orange_red", "attr": ["bold"] },
"hostname": { "fg": "black", "bg": "gray10", "attr": ["bold"] },
"weather": { "fg": "gray8", "bg": "gray0" },
"weather_temp_gradient": { "fg": "blue_red", "bg": "gray0" },
"weather_condition_hot": { "fg": "khaki1", "bg": "gray0" },
"weather_condition_snowy": { "fg": "skyblue1", "bg": "gray0" },
"weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0" },
"uptime": { "fg": "gray8", "bg": "gray0" },
"external_ip": { "fg": "gray8", "bg": "gray0" },
"network_load": { "fg": "gray8", "bg": "gray0" },
"system_load": { "fg": "gray8", "bg": "gray0" },
"system_load_good": { "fg": "lightyellowgreen", "bg": "gray0" },
"system_load_bad": { "fg": "gold3", "bg": "gray0" },
"system_load_ugly": { "fg": "orangered", "bg": "gray0" },
"environment": { "fg": "gray8", "bg": "gray0" }
}
}

View File

@ -18,7 +18,7 @@ def mergedicts(d1, d2):
'''Recursively merge two dictionaries. First dictionary is modified in-place. '''Recursively merge two dictionaries. First dictionary is modified in-place.
''' '''
for k in d2: for k in d2:
if k in d1 and type(d1[k]) is dict and type(d2[k]) is dict: if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
mergedicts(d1[k], d2[k]) mergedicts(d1[k], d2[k])
elif d2[k] is REMOVE_THIS_KEY: elif d2[k] is REMOVE_THIS_KEY:
d1.pop(k, None) d1.pop(k, None)
@ -26,6 +26,21 @@ def mergedicts(d1, d2):
d1[k] = d2[k] d1[k] = d2[k]
def mergedicts_copy(d1, d2):
'''Recursively merge two dictionaries.
Dictionaries are not modified. Copying happens only if necessary. Assumes
that first dictionary support .copy() method.
'''
ret = d1.copy()
for k in d2:
if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
ret[k] = mergedicts_copy(d1[k], d2[k])
else:
ret[k] = d2[k]
return ret
def add_divider_highlight_group(highlight_group): def add_divider_highlight_group(highlight_group):
def dec(func): def dec(func):
@wraps_saveargs(func) @wraps_saveargs(func)

View File

@ -7,6 +7,7 @@ from powerline.lint.markedjson.error import echoerr, MarkedError
from powerline.segments.vim import vim_modes from powerline.segments.vim import vim_modes
from powerline.lint.inspect import getconfigargspec from powerline.lint.inspect import getconfigargspec
from powerline.lib.threaded import ThreadedSegment from powerline.lib.threaded import ThreadedSegment
from powerline.lib import mergedicts_copy
import itertools import itertools
import sys import sys
import os import os
@ -414,14 +415,20 @@ def check_matcher_func(ext, match_name, data, context, echoerr):
def check_ext(ext, data, context, echoerr): def check_ext(ext, data, context, echoerr):
hadsomedirs = False hadsomedirs = False
hadproblem = False hadproblem = False
for subdir in ('themes', 'colorschemes'): if ext not in data['lists']['exts']:
if ext not in data['configs'][subdir]: hadproblem = True
hadproblem = True echoerr(context='Error while loading {0} extension configuration'.format(ext),
echoerr(context='Error while loading {0} extension configuration'.format(ext), context_mark=ext.mark,
context_mark=ext.mark, problem='extension configuration does not exist')
problem='{0} configuration does not exist'.format(subdir)) else:
else: for typ in ('themes', 'colorschemes'):
hadsomedirs = True if ext not in data['configs'][typ] and not data['configs']['top_' + typ]:
hadproblem = True
echoerr(context='Error while loading {0} extension configuration'.format(ext),
context_mark=ext.mark,
problem='{0} configuration does not exist'.format(typ))
else:
hadsomedirs = True
return hadsomedirs, hadproblem return hadsomedirs, hadproblem
@ -431,7 +438,13 @@ def check_config(d, theme, data, context, echoerr):
else: else:
# local_themes # local_themes
ext = context[-3][0] ext = context[-3][0]
if ext not in data['configs'][d] or theme not in data['configs'][d][ext]: if ext not in data['lists']['exts']:
echoerr(context='Error while loading {0} extension configuration'.format(ext),
context_mark=ext.mark,
problem='extension configuration does not exist')
return True, False, True
if ((ext not in data['configs'][d] or theme not in data['configs'][d][ext])
and theme not in data['configs']['top_' + d]):
echoerr(context='Error while loading {0} from {1} extension configuration'.format(d[:-1], ext), echoerr(context='Error while loading {0} from {1} extension configuration'.format(d[:-1], ext),
problem='failed to find configuration file {0}/{1}/{2}.json'.format(d, ext, theme), problem='failed to find configuration file {0}/{1}/{2}.json'.format(d, ext, theme),
problem_mark=theme.mark) problem_mark=theme.mark)
@ -531,22 +544,84 @@ def check_color(color, data, context, echoerr):
def check_translated_group_name(group, data, context, echoerr): def check_translated_group_name(group, data, context, echoerr):
if group not in context[0][1].get('groups', {}): return check_group(group, data, context, echoerr)
echoerr(context='Error while checking translated group in colorscheme (key {key})'.format(key=context_key(context)),
problem='translated group {0} is not in main groups dictionary'.format(group),
problem_mark=group.mark) def check_group(group, data, context, echoerr):
return True, False, True if not isinstance(group, unicode):
return True, False, False return True, False, False
colorscheme = data['colorscheme']
ext = data['ext']
configs = []
if ext:
if colorscheme == '__main__':
configs.append([config for config in data['ext_colorscheme_configs'][ext].items()])
configs.append([config for config in data['top_colorscheme_configs'].items()])
else:
try:
configs.append([data['ext_colorscheme_configs'][ext][colorscheme]])
except KeyError:
pass
try:
configs.append([data['ext_colorscheme_configs'][ext]['__main__']])
except KeyError:
pass
try:
configs.append([data['top_colorscheme_configs'][colorscheme]])
except KeyError:
pass
else:
try:
configs.append([data['top_colorscheme_configs'][colorscheme]])
except KeyError:
pass
new_echoerr = DelayedEchoErr(echoerr)
hadproblem = False
for config_lst in configs:
tofind = len(config_lst)
not_found = []
for config in config_lst:
if isinstance(config, tuple):
new_colorscheme, config = config
new_data = data.copy()
new_data['colorscheme'] = new_colorscheme
else:
new_data = data
try:
group_data = config['groups'][group]
except KeyError:
not_found.append(config.mark.name)
else:
proceed, echo, chadproblem = check_group(
group_data,
new_data,
context,
echoerr,
)
if chadproblem:
hadproblem = True
else:
tofind -= 1
if not tofind:
return proceed, echo, hadproblem
if not proceed:
break
if not_found:
new_echoerr(context='Error while checking group definition in colorscheme (key {key})'.format(key=context_key(context)),
problem='name {0} is not present in {1} {2} colorschemes: {3}'.format(group, tofind, ext, ', '.join(not_found)),
problem_mark=group.mark)
new_echoerr.echo_all()
return True, False, hadproblem
color_spec = Spec().type(unicode).func(check_color).copy color_spec = Spec().type(unicode).func(check_color).copy
name_spec = Spec().type(unicode).len('gt', 0).optional().copy name_spec = Spec().type(unicode).len('gt', 0).optional().copy
group_spec = Spec( group_name_spec = Spec().re('^\w+(?::\w+)?$').copy
group_spec = Spec().either(Spec(
fg=color_spec(), fg=color_spec(),
bg=color_spec(), bg=color_spec(),
attr=Spec().list(Spec().type(unicode).oneof(set(('bold', 'italic', 'underline')))).optional(), attr=Spec().list(Spec().type(unicode).oneof(set(('bold', 'italic', 'underline')))),
).copy ), group_name_spec().func(check_group)).copy
group_name_spec = Spec().re('^\w+(?::\w+)?$').copy
groups_spec = Spec().unknown_spec( groups_spec = Spec().unknown_spec(
group_name_spec(), group_name_spec(),
group_spec(), group_spec(),
@ -555,23 +630,32 @@ colorscheme_spec = (Spec(
name=name_spec(), name=name_spec(),
groups=groups_spec(), groups=groups_spec(),
).context_message('Error while loading coloscheme')) ).context_message('Error while loading coloscheme'))
mode_translations_value_spec = Spec(
colors=Spec().unknown_spec(
color_spec(),
color_spec(),
).optional(),
groups=Spec().unknown_spec(
group_name_spec().func(check_translated_group_name),
group_spec(),
).optional(),
).copy
top_colorscheme_spec = (Spec(
name=name_spec(),
groups=groups_spec(),
mode_translations=Spec().unknown_spec(
Spec().type(unicode),
mode_translations_value_spec(),
).optional().context_message('Error while loading mode translations (key {key})').optional(),
).context_message('Error while loading top-level coloscheme'))
vim_mode_spec = Spec().oneof(set(list(vim_modes) + ['nc'])).copy vim_mode_spec = Spec().oneof(set(list(vim_modes) + ['nc'])).copy
vim_colorscheme_spec = (Spec( vim_colorscheme_spec = (Spec(
name=name_spec(), name=name_spec(),
groups=groups_spec(), groups=groups_spec(),
mode_translations=Spec().unknown_spec( mode_translations=Spec().unknown_spec(
vim_mode_spec(), vim_mode_spec(),
Spec( mode_translations_value_spec(),
colors=Spec().unknown_spec( ).optional().context_message('Error while loading mode translations (key {key})'),
color_spec(),
color_spec(),
).optional(),
groups=Spec().unknown_spec(
group_name_spec().func(check_translated_group_name),
group_spec(),
).optional(),
),
).context_message('Error while loading mode translations (key {key})'),
).context_message('Error while loading vim colorscheme')) ).context_message('Error while loading vim colorscheme'))
shell_mode_spec = Spec().re('^(?:[\w\-]+|\.safe)$').copy shell_mode_spec = Spec().re('^(?:[\w\-]+|\.safe)$').copy
shell_colorscheme_spec = (Spec( shell_colorscheme_spec = (Spec(
@ -579,17 +663,8 @@ shell_colorscheme_spec = (Spec(
groups=groups_spec(), groups=groups_spec(),
mode_translations=Spec().unknown_spec( mode_translations=Spec().unknown_spec(
shell_mode_spec(), shell_mode_spec(),
Spec( mode_translations_value_spec(),
colors=Spec().unknown_spec( ).optional().context_message('Error while loading mode translations (key {key})'),
color_spec(),
color_spec(),
).optional(),
groups=Spec().unknown_spec(
group_name_spec().func(check_translated_group_name),
group_spec(),
).optional(),
),
).context_message('Error while loading mode translations (key {key})'),
).context_message('Error while loading shell colorscheme')) ).context_message('Error while loading shell colorscheme'))
@ -1044,44 +1119,60 @@ def check(path=None, debug=False):
ee = EchoErr(echoerr, logger) ee = EchoErr(echoerr, logger)
dirs = { paths = {
'themes': defaultdict(lambda: []), 'themes': defaultdict(lambda: []),
'colorschemes': defaultdict(lambda: []) 'colorschemes': defaultdict(lambda: []),
'top_colorschemes': [],
'top_themes': [],
}
lists = {
'colorschemes': set(),
'themes': set(),
'exts': set(),
} }
for path in reversed(search_paths): for path in reversed(search_paths):
for subdir in ('themes', 'colorschemes'): for typ in ('themes', 'colorschemes'):
d = os.path.join(path, subdir) d = os.path.join(path, typ)
if os.path.isdir(d): if os.path.isdir(d):
for ext in os.listdir(d): for subp in os.listdir(d):
extd = os.path.join(d, ext) extpath = os.path.join(d, subp)
if os.path.isdir(extd): if os.path.isdir(extpath):
dirs[subdir][ext].append(extd) lists['exts'].add(subp)
elif os.path.exists(d): paths[typ][subp].append(extpath)
elif extpath.endswith('.json'):
name = subp[:-5]
if name != '__main__':
lists[typ].add(name)
paths['top_' + typ].append(extpath)
else:
hadproblem = True hadproblem = True
sys.stderr.write('Path {0} is supposed to be a directory, but it is not\n'.format(d)) sys.stderr.write('Path {0} is supposed to be a directory, but it is not\n'.format(d))
configs = { configs = defaultdict(lambda: defaultdict(lambda: {}))
'themes': defaultdict(lambda: {}), for typ in ('themes', 'colorschemes'):
'colorschemes': defaultdict(lambda: {}) for ext in paths[typ]:
} for d in paths[typ][ext]:
for subdir in ('themes', 'colorschemes'): for subp in os.listdir(d):
for ext in dirs[subdir]: if subp.endswith('.json'):
for d in dirs[subdir][ext]: name = subp[:-5]
for config in os.listdir(d): if name != '__main__':
if os.path.isdir(os.path.join(d, config)): lists[typ].add(name)
dirs[subdir][ext].append(os.path.join(d, config)) configs[typ][ext][name] = os.path.join(d, subp)
elif config.endswith('.json'): for path in paths['top_' + typ]:
configs[subdir][ext][config[:-5]] = os.path.join(d, config) name = os.path.basename(path)[:-5]
configs['top_' + typ][name] = path
diff = set(configs['themes']) ^ set(configs['colorschemes']) diff = set(configs['themes']) ^ set(configs['colorschemes'])
if diff: if diff:
hadproblem = True hadproblem = True
for ext in diff: for ext in diff:
sys.stderr.write('{0} extension {1} present only in {2}\n'.format( typ = 'colorschemes' if ext in configs['themes'] else 'themes'
ext, if not configs['top_' + typ] or typ == 'themes':
'configuration' if (ext in dirs['themes'] and ext in dirs['colorschemes']) else 'directory', sys.stderr.write('{0} extension {1} not present in {2}\n'.format(
'themes' if ext in configs['themes'] else 'colorschemes', ext,
)) 'configuration' if (ext in paths['themes'] and ext in paths['colorschemes']) else 'directory',
typ,
))
lhadproblem = [False] lhadproblem = [False]
@ -1103,7 +1194,7 @@ def check(path=None, debug=False):
sys.stderr.write(str(e) + '\n') sys.stderr.write(str(e) + '\n')
hadproblem = True hadproblem = True
else: else:
if main_spec.match(main_config, data={'configs': configs}, context=(('', main_config),), echoerr=ee)[1]: if main_spec.match(main_config, data={'configs': configs, 'lists': lists}, context=(('', main_config),), echoerr=ee)[1]:
hadproblem = True hadproblem = True
import_paths = [os.path.expanduser(path) for path in main_config.get('common', {}).get('paths', [])] import_paths = [os.path.expanduser(path) for path in main_config.get('common', {}).get('paths', [])]
@ -1125,9 +1216,30 @@ def check(path=None, debug=False):
if lhadproblem[0]: if lhadproblem[0]:
hadproblem = True hadproblem = True
colorscheme_configs = defaultdict(lambda: {}) top_colorscheme_configs = {}
data = {
'ext': None,
'top_colorscheme_configs': top_colorscheme_configs,
'ext_colorscheme_configs': {},
'colors_config': colors_config
}
for colorscheme, cfile in configs['top_colorschemes'].items():
with open_file(cfile) as config_file_fp:
try:
config, lhadproblem = load(config_file_fp)
except MarkedError as e:
sys.stderr.write(str(e) + '\n')
hadproblem = True
continue
if lhadproblem:
hadproblem = True
top_colorscheme_configs[colorscheme] = config
data['colorscheme'] = colorscheme
if top_colorscheme_spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]:
hadproblem = True
ext_colorscheme_configs = defaultdict(lambda: {})
for ext in configs['colorschemes']: for ext in configs['colorschemes']:
data = {'ext': ext, 'colors_config': colors_config}
for colorscheme, cfile in configs['colorschemes'][ext].items(): for colorscheme, cfile in configs['colorschemes'][ext].items():
with open_file(cfile) as config_file_fp: with open_file(cfile) as config_file_fp:
try: try:
@ -1138,7 +1250,17 @@ def check(path=None, debug=False):
continue continue
if lhadproblem: if lhadproblem:
hadproblem = True hadproblem = True
colorscheme_configs[ext][colorscheme] = config ext_colorscheme_configs[ext][colorscheme] = config
for ext, econfigs in ext_colorscheme_configs.items():
data = {
'ext': ext,
'top_colorscheme_configs': top_colorscheme_configs,
'ext_colorscheme_configs': ext_colorscheme_configs,
'colors_config': colors_config,
}
for colorscheme, config in econfigs.items():
data['colorscheme'] = colorscheme
if ext == 'vim': if ext == 'vim':
spec = vim_colorscheme_spec spec = vim_colorscheme_spec
elif ext == 'shell': elif ext == 'shell':
@ -1148,6 +1270,27 @@ def check(path=None, debug=False):
if spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]: if spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]:
hadproblem = True hadproblem = True
colorscheme_configs = {}
for ext in lists['exts']:
colorscheme_configs[ext] = {}
for colorscheme in lists['colorschemes']:
econfigs = ext_colorscheme_configs[ext]
ecconfigs = econfigs.get(colorscheme)
mconfigs = (
top_colorscheme_configs.get(colorscheme),
econfigs.get('__main__'),
ecconfigs,
)
config = None
for mconfig in mconfigs:
if not mconfig:
continue
if config:
config = mergedicts_copy(config, mconfig)
else:
config = mconfig
colorscheme_configs[colorscheme] = config
theme_configs = defaultdict(lambda: {}) theme_configs = defaultdict(lambda: {})
for ext in configs['themes']: for ext in configs['themes']:
for theme, sfile in configs['themes'][ext].items(): for theme, sfile in configs['themes'][ext].items():
@ -1161,6 +1304,7 @@ def check(path=None, debug=False):
if lhadproblem: if lhadproblem:
hadproblem = True hadproblem = True
theme_configs[ext][theme] = config theme_configs[ext][theme] = config
for ext, configs in theme_configs.items(): for ext, configs in theme_configs.items():
data = {'ext': ext, 'colorscheme_configs': colorscheme_configs, 'import_paths': import_paths, data = {'ext': ext, 'colorscheme_configs': colorscheme_configs, 'import_paths': import_paths,
'main_config': main_config, 'ext_theme_configs': configs, 'colors_config': colors_config} 'main_config': main_config, 'ext_theme_configs': configs, 'colors_config': colors_config}

View File

@ -47,6 +47,16 @@ class MarkedFloat(float):
__new__ = gen_new(float) __new__ = gen_new(float)
class MarkedDict(dict):
__new__ = gen_new(dict)
def __init__(self, value, mark):
super(MarkedDict, self).__init__(value)
def copy(self):
return MarkedDict(super(MarkedDict, self).copy(), self.mark)
class MarkedValue: class MarkedValue:
def __init__(self, value, mark): def __init__(self, value, mark):
self.mark = mark self.mark = mark
@ -57,6 +67,7 @@ specialclasses = {
unicode: MarkedUnicode, unicode: MarkedUnicode,
int: MarkedInt, int: MarkedInt,
float: MarkedFloat, float: MarkedFloat,
dict: MarkedDict,
} }
classcache = {} classcache = {}
@ -70,7 +81,10 @@ def gen_marked_value(value, mark, use_special_classes=True):
else: else:
class Marked(MarkedValue): class Marked(MarkedValue):
for func in value.__class__.__dict__: for func in value.__class__.__dict__:
if func not in set(('__init__', '__new__', '__getattribute__')): if func == 'copy':
def copy(self):
return self.__class__(self.value.copy(), self.mark)
elif func not in set(('__init__', '__new__', '__getattribute__')):
if func in set(('__eq__',)): if func in set(('__eq__',)):
# HACK to make marked dictionaries always work # HACK to make marked dictionaries always work
exec (('def {0}(self, *args):\n' exec (('def {0}(self, *args):\n'

View File

@ -22,6 +22,8 @@ for script in tests/*.vim ; do
done done
if ! sh tests/test_shells/test.sh ; then if ! sh tests/test_shells/test.sh ; then
echo "Failed shells" echo "Failed shells"
FAILED=1 if ${PYTHON} -c 'import platform, sys; sys.exit(1 * (platform.python_implementation() == "PyPy"))' ; then
FAILED=1
fi
fi fi
exit $FAILED exit $FAILED

View File

@ -101,7 +101,7 @@ class TestConfigReload(TestCase):
with get_powerline(run_once=True) as p: with get_powerline(run_once=True) as p:
with replace_item(globals(), 'config', deepcopy(config)): with replace_item(globals(), 'config', deepcopy(config)):
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['config']['common']['spaces'] = 1 config['config']['common']['spaces'] = 1
add_watcher_events(p, 'config', wait=False, interval=0.05) add_watcher_events(p, 'config', wait=False, interval=0.05)
# When running once thread should not start # When running once thread should not start
@ -117,7 +117,7 @@ class TestConfigReload(TestCase):
with get_powerline(run_once=False) as p: with get_powerline(run_once=False) as p:
with replace_item(globals(), 'config', deepcopy(config)): with replace_item(globals(), 'config', deepcopy(config)):
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['config']['common']['spaces'] = 1 config['config']['common']['spaces'] = 1
add_watcher_events(p, 'config') add_watcher_events(p, 'config')
@ -141,14 +141,19 @@ class TestConfigReload(TestCase):
config['config']['ext']['test']['colorscheme'] = 'nonexistent' config['config']['ext']['test']['colorscheme'] = 'nonexistent'
add_watcher_events(p, 'config') add_watcher_events(p, 'config')
self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s <2 4 False>>><3 4 4>g <4 False False>>><None None None>')
self.assertAccessEvents('config', 'colorschemes/test/nonexistent') self.assertAccessEvents('config', 'colorschemes/nonexistent', 'colorschemes/test/__main__', 'colorschemes/test/nonexistent')
# It should normally handle file missing error # It should normally handle file missing error
self.assertEqual(p.logger._pop_msgs(), ['exception:test:powerline:Failed to create renderer: colorschemes/test/nonexistent']) self.assertEqual(p.logger._pop_msgs(), [
'exception:test:powerline:Failed to load colorscheme: colorschemes/nonexistent',
'exception:test:powerline:Failed to load colorscheme: colorschemes/test/__main__',
'exception:test:powerline:Failed to load colorscheme: colorschemes/test/nonexistent',
'exception:test:powerline:Failed to create renderer: colorschemes/test/nonexistent'
])
config['config']['ext']['test']['colorscheme'] = '2' config['config']['ext']['test']['colorscheme'] = '2'
add_watcher_events(p, 'config') add_watcher_events(p, 'config')
self.assertEqual(p.render(), '<2 3 1> s <3 4 False>>><1 4 4>g <4 False False>>><None None None>') self.assertEqual(p.render(), '<2 3 1> s <3 4 False>>><1 4 4>g <4 False False>>><None None None>')
self.assertAccessEvents('config', 'colorschemes/test/2') self.assertAccessEvents('config', 'colorschemes/2', 'colorschemes/test/__main__', 'colorschemes/test/2')
self.assertEqual(p.logger._pop_msgs(), []) self.assertEqual(p.logger._pop_msgs(), [])
config['config']['ext']['test']['theme'] = '2' config['config']['ext']['test']['theme'] = '2'
@ -170,7 +175,7 @@ class TestConfigReload(TestCase):
with get_powerline(run_once=False) as p: with get_powerline(run_once=False) as p:
with replace_item(globals(), 'config', deepcopy(config)): with replace_item(globals(), 'config', deepcopy(config)):
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['config']['ext']['test']['colorscheme'] = 'nonexistentraise' config['config']['ext']['test']['colorscheme'] = 'nonexistentraise'
add_watcher_events(p, 'config') add_watcher_events(p, 'config')
@ -182,9 +187,14 @@ class TestConfigReload(TestCase):
# fcf:colorschemes/test/nonexistentraise”). # fcf:colorschemes/test/nonexistentraise”).
# sleep(0.1) # sleep(0.1)
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config') # For colorschemes/{test/,}*raise find_config_file raises
# IOError, but it does not do so for colorschemes/test/__main__,
# so powerline is trying to load this, but not other
# colorschemes/*
self.assertAccessEvents('config', 'colorschemes/test/__main__')
self.assertIn('exception:test:powerline:Failed to create renderer: fcf:colorschemes/test/nonexistentraise', p.logger._pop_msgs()) self.assertIn('exception:test:powerline:Failed to create renderer: fcf:colorschemes/test/nonexistentraise', p.logger._pop_msgs())
config['colorschemes/nonexistentraise'] = {}
config['colorschemes/test/nonexistentraise'] = { config['colorschemes/test/nonexistentraise'] = {
'groups': { 'groups': {
"str1": {"fg": "col1", "bg": "col3", "attr": ["bold"]}, "str1": {"fg": "col1", "bg": "col3", "attr": ["bold"]},
@ -192,9 +202,10 @@ class TestConfigReload(TestCase):
}, },
} }
while not p._will_create_renderer(): while not p._will_create_renderer():
sleep(0.000001) sleep(0.1)
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><2 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><2 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('colorschemes/test/nonexistentraise') # Same as above
self.assertAccessEvents('colorschemes/nonexistentraise', 'colorschemes/test/nonexistentraise', 'colorschemes/test/__main__')
self.assertEqual(p.logger._pop_msgs(), []) self.assertEqual(p.logger._pop_msgs(), [])
pop_events() pop_events()
@ -202,7 +213,7 @@ class TestConfigReload(TestCase):
with get_powerline(run_once=False) as p: with get_powerline(run_once=False) as p:
with replace_item(globals(), 'config', deepcopy(config)): with replace_item(globals(), 'config', deepcopy(config)):
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['colors']['colors']['col1'] = 5 config['colors']['colors']['col1'] = 5
add_watcher_events(p, 'colors') add_watcher_events(p, 'colors')
@ -215,12 +226,12 @@ class TestConfigReload(TestCase):
with get_powerline(run_once=False) as p: with get_powerline(run_once=False) as p:
with replace_item(globals(), 'config', deepcopy(config)): with replace_item(globals(), 'config', deepcopy(config)):
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['colorschemes/test/default']['groups']['str1']['bg'] = 'col3' config['colorschemes/test/default']['groups']['str1']['bg'] = 'col3'
add_watcher_events(p, 'colorschemes/test/default') add_watcher_events(p, 'colorschemes/test/default')
self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 3 1> s<3 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('colorschemes/test/default') self.assertAccessEvents('colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default')
self.assertEqual(p.logger._pop_msgs(), []) self.assertEqual(p.logger._pop_msgs(), [])
pop_events() pop_events()
@ -228,7 +239,7 @@ class TestConfigReload(TestCase):
with get_powerline(run_once=False) as p: with get_powerline(run_once=False) as p:
with replace_item(globals(), 'config', deepcopy(config)): with replace_item(globals(), 'config', deepcopy(config)):
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3' config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
add_watcher_events(p, 'themes/test/default') add_watcher_events(p, 'themes/test/default')
@ -242,7 +253,7 @@ class TestConfigReload(TestCase):
config['config']['common']['interval'] = None config['config']['common']['interval'] = None
with get_powerline(run_once=False) as p: with get_powerline(run_once=False) as p:
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3' config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
add_watcher_events(p, 'themes/test/default', wait=False) add_watcher_events(p, 'themes/test/default', wait=False)
@ -257,7 +268,7 @@ class TestConfigReload(TestCase):
config['config']['common']['interval'] = None config['config']['common']['interval'] = None
with get_powerline(run_once=True) as p: with get_powerline(run_once=True) as p:
self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>') self.assertEqual(p.render(), '<1 2 1> s<2 4 False>>><3 4 4>g<4 False False>>><None None None>')
self.assertAccessEvents('config', 'colors', 'colorschemes/test/default', 'themes/test/default') self.assertAccessEvents('config', 'colors', 'colorschemes/default', 'colorschemes/test/__main__', 'colorschemes/test/default', 'themes/test/default')
config['themes/test/default']['segments']['left'][0]['contents'] = 'col3' config['themes/test/default']['segments']['left'][0]['contents'] = 'col3'
add_watcher_events(p, 'themes/test/default', wait=False) add_watcher_events(p, 'themes/test/default', wait=False)

View File

@ -12,6 +12,16 @@ import sys
import os import os
def highlighted_string(s, group, **kwargs):
ret = {
'type': 'string',
'contents': s,
'highlight_group': [group],
}
ret.update(kwargs)
return ret
config = { config = {
'config': { 'config': {
'common': { 'common': {
@ -46,14 +56,39 @@ config = {
'col2': 2, 'col2': 2,
'col3': 3, 'col3': 3,
'col4': 4, 'col4': 4,
'col5': 5,
'col6': 6,
'col7': 7,
'col8': 8,
'col9': 9,
'col10': 10,
'col11': 11,
'col12': 12,
}, },
'gradients': { 'gradients': {
}, },
}, },
'colorschemes/test/__main__': {
'groups': {
'm1': 'g1',
'm2': 'g3',
'm3': {'fg': 'col11', 'bg': 'col12', 'attr': []},
}
},
'colorschemes/default': {
'groups': {
'g1': {'fg': 'col5', 'bg': 'col6', 'attr': []},
'g2': {'fg': 'col7', 'bg': 'col8', 'attr': []},
'g3': {'fg': 'col9', 'bg': 'col10', 'attr': []},
}
},
'colorschemes/test/default': { 'colorschemes/test/default': {
'groups': { 'groups': {
'str1': {'fg': 'col1', 'bg': 'col2', 'attr': ['bold']}, 'str1': {'fg': 'col1', 'bg': 'col2', 'attr': ['bold']},
'str2': {'fg': 'col3', 'bg': 'col4', 'attr': ['underline']}, 'str2': {'fg': 'col3', 'bg': 'col4', 'attr': ['underline']},
'd1': 'g2',
'd2': 'm2',
'd3': 'm3',
}, },
}, },
'colorschemes/vim/default': { 'colorschemes/vim/default': {
@ -64,26 +99,11 @@ config = {
'themes/test/default': { 'themes/test/default': {
'segments': { 'segments': {
'left': [ 'left': [
{ highlighted_string('s', 'str1', width='auto'),
'type': 'string', highlighted_string('g', 'str2'),
'contents': 's',
'width': 'auto',
'highlight_group': ['str1'],
},
{
'type': 'string',
'contents': 'g',
'highlight_group': ['str2'],
},
], ],
'right': [ 'right': [
{ highlighted_string('f', 'str2', width='auto', align='right'),
'type': 'string',
'contents': 'f',
'width': 'auto',
'align': 'right',
'highlight_group': ['str2'],
},
], ],
}, },
}, },
@ -111,13 +131,15 @@ def add_p_arg(func):
return f return f
class TestSingleLine(TestCase): class TestRender(TestCase):
def assertRenderEqual(self, p, output, **kwargs): def assertRenderEqual(self, p, output, **kwargs):
self.assertEqual(p.render(**kwargs).replace(' ', ' '), output) self.assertEqual(p.render(**kwargs).replace(' ', ' '), output)
def assertRenderLinesEqual(self, p, output, **kwargs): def assertRenderLinesEqual(self, p, output, **kwargs):
self.assertEqual([l.replace(' ', ' ') for l in p.render_above_lines(**kwargs)], output) self.assertEqual([l.replace(' ', ' ') for l in p.render_above_lines(**kwargs)], output)
class TestLines(TestRender):
@add_p_arg @add_p_arg
def test_without_above(self, p): def test_without_above(self, p):
self.assertRenderEqual(p, '{121} s{24}>>{344}g{34}>{34}<{344}f {--}') self.assertRenderEqual(p, '{121} s{24}>>{344}g{34}>{34}<{344}f {--}')
@ -149,6 +171,115 @@ class TestSingleLine(TestCase):
], width=10) ], width=10)
class TestColorschemesHierarchy(TestRender):
@add_p_arg
def test_group_redirects(self, p):
with replace_item(globals(), 'config', deepcopy(config)):
config['themes/test/default']['segments'] = {
'left': [
highlighted_string('a', 'd1', draw_hard_divider=False),
highlighted_string('b', 'd2', draw_hard_divider=False),
highlighted_string('c', 'd3', draw_hard_divider=False),
highlighted_string('A', 'm1', draw_hard_divider=False),
highlighted_string('B', 'm2', draw_hard_divider=False),
highlighted_string('C', 'm3', draw_hard_divider=False),
highlighted_string('1', 'g1', draw_hard_divider=False),
highlighted_string('2', 'g2', draw_hard_divider=False),
highlighted_string('3', 'g3', draw_hard_divider=False),
],
'right': [],
}
self.assertRenderEqual(p, '{78} a{910}b{1112}c{56}A{910}B{1112}C{56}1{78}2{910}3{--}')
@add_p_arg
def test_group_redirects_no_main(self, p):
with replace_item(globals(), 'config', deepcopy(config)):
del config['colorschemes/test/__main__']
config['themes/test/default']['segments'] = {
'left': [
highlighted_string('a', 'd1', draw_hard_divider=False),
highlighted_string('1', 'g1', draw_hard_divider=False),
highlighted_string('2', 'g2', draw_hard_divider=False),
highlighted_string('3', 'g3', draw_hard_divider=False),
],
'right': [],
}
self.assertRenderEqual(p, '{78} a{56}1{78}2{910}3{--}')
@add_p_arg
def test_group_redirects_no_top_default(self, p):
with replace_item(globals(), 'config', deepcopy(config)):
del config['colorschemes/default']
config['themes/test/default']['segments'] = {
'left': [
highlighted_string('c', 'd3', draw_soft_divider=False),
highlighted_string('C', 'm3', draw_hard_divider=False),
],
'right': [],
}
self.assertRenderEqual(p, '{1112} c{1112}C{--}')
@add_p_arg
def test_group_redirects_no_test_default(self, p):
with replace_item(globals(), 'config', deepcopy(config)):
del config['colorschemes/test/default']
config['themes/test/default']['segments'] = {
'left': [
highlighted_string('A', 'm1', draw_hard_divider=False),
highlighted_string('B', 'm2', draw_hard_divider=False),
highlighted_string('C', 'm3', draw_hard_divider=False),
highlighted_string('1', 'g1', draw_hard_divider=False),
highlighted_string('2', 'g2', draw_hard_divider=False),
highlighted_string('3', 'g3', draw_hard_divider=False),
],
'right': [],
}
self.assertRenderEqual(p, '{56} A{910}B{1112}C{56}1{78}2{910}3{--}')
@add_p_arg
def test_group_redirects_only_main(self, p):
with replace_item(globals(), 'config', deepcopy(config)):
del config['colorschemes/default']
del config['colorschemes/test/default']
config['themes/test/default']['segments'] = {
'left': [
highlighted_string('C', 'm3', draw_hard_divider=False),
],
'right': [],
}
# Powerline is not able to work without default colorscheme
# somewhere, thus it will output error string
self.assertRenderEqual(p, 'colorschemes/test/default')
@add_p_arg
def test_group_redirects_only_top_default(self, p):
with replace_item(globals(), 'config', deepcopy(config)):
del config['colorschemes/test/__main__']
del config['colorschemes/test/default']
config['themes/test/default']['segments'] = {
'left': [
highlighted_string('1', 'g1', draw_hard_divider=False),
highlighted_string('2', 'g2', draw_hard_divider=False),
highlighted_string('3', 'g3', draw_hard_divider=False),
],
'right': [],
}
self.assertRenderEqual(p, '{56} 1{78}2{910}3{--}')
@add_p_arg
def test_group_redirects_only_test_default(self, p):
with replace_item(globals(), 'config', deepcopy(config)):
del config['colorschemes/default']
del config['colorschemes/test/__main__']
config['themes/test/default']['segments'] = {
'left': [
highlighted_string('s', 'str1', draw_hard_divider=False),
],
'right': [],
}
self.assertRenderEqual(p, '{121} s{--}')
class TestVim(TestCase): class TestVim(TestCase):
def test_environ_update(self): def test_environ_update(self):
# Regression test: test that segment obtains environment from vim, not # Regression test: test that segment obtains environment from vim, not