Add ability to specify some segment keys once in top theme

This commit is contained in:
ZyX 2013-02-18 09:23:40 +04:00 committed by Kim Silkebækken
parent 186ad2d423
commit c86b047ed4
6 changed files with 77 additions and 21 deletions

View File

@ -145,9 +145,13 @@ Common configuration is a subdictionary that is a value of ``ext`` key in
Defines the colorscheme used for this extension.
``theme``
.. _config-ext-theme:
Defines the theme used for this extension.
``local_themes``
.. _config-ext-local_themes:
Defines themes used when certain conditions are met, e.g. for
buffer-specific statuslines in vim. Requires a custom matcher and theme.
@ -219,6 +223,21 @@ Themes
``default_module``
Python module where segments will be looked by default.
.. _config-themes-segment_data:
``segment_data``
A dict where keys are segment names or strings ``{module}.{name}``. Used to
specify default values for various keys:
:ref:`after <config-theme-seg-after>`,
:ref:`before <config-theme-seg-before>`,
:ref:`contents <config-theme-seg-contents>` (only for string segments
if :ref:`name <config-themes-seg-name>` is defined),
:ref:`args <config-themes-seg-args>` (only for function segments). When
using :ref:`local themes <config-ext-local_themes>` values of these keys are
first searched in the segment description, then in ``segment_data`` key of
a local theme, then in ``segment_data`` key of a :ref:`default theme
<config-ext-theme>`.
``segments``
A dict with a ``left`` and a ``right`` list, consisting of segment
dicts. Each segment has the following options:
@ -257,9 +276,13 @@ Themes
available in the colorscheme is used.
``before``
.. _config-themes-seg-before:
A string which will be prepended to the segment contents.
``after``
.. _config-themes-seg-after:
A string which will be appended to the segment contents.
``contents``
@ -268,6 +291,8 @@ Themes
Segment contents, only required for ``string`` segments.
``args``
.. _config-themes-seg-args:
A dict of arguments to be passed to a ``function`` segment.
``align``

View File

@ -1,4 +1,19 @@
{
"segment_data": {
"branch": {
"before": " "
},
"modified_indicator": {
"args": { "text": "+" }
},
"line_percent": {
"args": { "gradient": true },
"after": "%"
},
"line_current_symbol": {
"contents": " "
}
},
"segments": {
"left": [
{
@ -14,7 +29,6 @@
"name": "branch",
"exclude_modes": ["nc"],
"priority": 60,
"before": " ",
"divider_highlight_group": "branch:divider"
},
{
@ -38,7 +52,6 @@
},
{
"name": "modified_indicator",
"args": { "text": "+" },
"before": " "
},
{
@ -70,15 +83,13 @@
},
{
"name": "line_percent",
"args": { "gradient": true },
"priority": 30,
"after": "%",
"width": 4,
"align": "r"
},
{
"type": "string",
"contents": " ",
"name": "line_current_symbol",
"highlight_group": ["line_current_symbol", "line_current"]
},
{

View File

@ -15,15 +15,13 @@
"right": [
{
"name": "line_percent",
"args": { "gradient": true },
"priority": 30,
"after": "%",
"width": 4,
"align": "r"
},
{
"type": "string",
"contents": " ",
"name": "line_current_symbol",
"highlight_group": ["line_current_symbol", "line_current"]
},
{

View File

@ -7,6 +7,7 @@ from powerline.theme import Theme
class Renderer(object):
def __init__(self, theme_config, local_themes, theme_kwargs, **options):
self.__dict__.update(options)
self.theme_config = theme_config
self.theme = Theme(theme_config=theme_config, **theme_kwargs)
self.local_themes = local_themes
self.theme_kwargs = theme_kwargs
@ -21,7 +22,7 @@ class Renderer(object):
if matcher(matcher_info):
match = self.local_themes[matcher]
if 'config' in match:
match['theme'] = Theme(theme_config=match.pop('config'), **self.theme_kwargs)
match['theme'] = Theme(theme_config=match.pop('config'), top_theme_config=self.theme_config, **self.theme_kwargs)
return match['theme']
else:
return self.theme

View File

@ -4,18 +4,34 @@ from importlib import import_module
import sys
def get_segment_key(segment, theme_configs, key, module=None, default=None):
try:
return segment[key]
except KeyError:
if 'name' in segment:
name = segment['name']
for theme_config in theme_configs:
if 'segment_data' in theme_config:
for segment_key in ((module+'.'+name, name) if module else (name,)):
try:
return theme_config['segment_data'][segment_key][key]
except KeyError:
pass
return default
def get_function(data, segment):
oldpath = sys.path
sys.path = data['path'] + sys.path
segment_module = str(segment.get('module', data['default_module']))
try:
return None, getattr(import_module(segment_module), segment['name']), '{0}.{1}'.format(segment_module, segment['name'])
return None, getattr(import_module(segment_module), segment['name']), segment_module
finally:
sys.path = oldpath
def get_string(data, segment):
return segment.get('contents'), None, None
return data['get_key'](segment, None, 'contents'), None, None
def get_filler(data, segment):
@ -29,11 +45,14 @@ segment_getters = {
}
def gen_segment_getter(ext, path, default_module=None):
def gen_segment_getter(ext, path, theme_configs, default_module=None):
data = {
"default_module": default_module or 'powerline.segments.'+ext,
"path": path
'default_module': default_module or 'powerline.segments.'+ext,
'path': path,
}
def get_key(segment, module, key, default=None):
return get_segment_key(segment, theme_configs, key, module, default)
data['get_key'] = get_key
def get(segment, side):
segment_type = segment.get('type', 'function')
@ -41,19 +60,18 @@ def gen_segment_getter(ext, path, default_module=None):
get_segment_info = segment_getters[segment_type]
except KeyError:
raise TypeError('Unknown segment type: {0}'.format(segment_type))
contents, contents_func, key = get_segment_info(data, segment)
contents, contents_func, module = get_segment_info(data, segment)
highlight_group = segment.get('highlight_group', segment.get('name'))
divider_highlight_group = segment.get('divider_highlight_group')
return {
'key': key,
'type': segment_type,
'highlight_group': highlight_group,
'divider_highlight_group': divider_highlight_group,
'before': segment.get('before', ''),
'after': segment.get('after', ''),
'before': get_key(segment, module, 'before', ''),
'after': get_key(segment, module, 'after', ''),
'contents_func': contents_func,
'contents': contents,
'args': segment.get('args', {}),
'args': get_key(segment, module, 'args', {}) if segment_type == 'function' else {},
'priority': segment.get('priority', -1),
'draw_divider': segment.get('draw_divider', True),
'side': side,

View File

@ -18,7 +18,7 @@ def requires_segment_info(func):
class Theme(object):
def __init__(self, ext, colorscheme, theme_config, common_config, segment_info=None):
def __init__(self, ext, colorscheme, theme_config, common_config, top_theme_config=None, segment_info=None):
self.colorscheme = colorscheme
self.dividers = theme_config.get('dividers', common_config['dividers'])
self.spaces = theme_config.get('spaces', common_config['spaces'])
@ -31,7 +31,10 @@ class Theme(object):
'highlight': defaultdict(lambda: {'fg': False, 'bg': False, 'attr': 0})
}
self.segment_info = segment_info
get_segment = gen_segment_getter(ext, common_config['paths'], theme_config.get('default_module'))
theme_configs = [theme_config]
if top_theme_config:
theme_configs.append(top_theme_config)
get_segment = gen_segment_getter(ext, common_config['paths'], theme_configs, theme_config.get('default_module'))
for side in ['left', 'right']:
self.segments[side].extend((get_segment(segment, side) for segment in theme_config['segments'].get(side, [])))