Split colorschemes and add better gradient support

- Splitted colorschemes into colors definitions file (TODO: remove non-colors
  definitions like weather_condition_hot and base00) and actual colorscheme.
- Removed dictionary containing groups definitions for all groups for all modes,
  now colorscheme is queried for this each time.
- Moved determination of colors from theme to renderer.
- Added gradients definitions (actually, only one) to new colors file.
- Made line_percent with gradient=True use new gradients.
This commit is contained in:
ZyX 2013-02-23 01:05:18 +04:00 committed by Kim Silkebækken
parent b8b0518e9b
commit 01b34a7893
16 changed files with 229 additions and 359 deletions

View File

@ -155,15 +155,12 @@ Common configuration is a subdictionary that is a value of ``ext`` key in
Defines themes used when certain conditions are met, e.g. for
buffer-specific statuslines in vim. Requires a custom matcher and theme.
Colorschemes
============
Color definitions
=================
:Location: :file:`powerline/colorschemes/{extension}/{name}.json`
:Location: :file:`powerline/colors.json`
``name``
Name of the colorscheme.
.. _config-colorscheme-colors:
.. _config-colors-colors:
``colors``
Color definitions, consisting of a dict where the key is the name of the
@ -174,6 +171,22 @@ Colorschemes
"aabbcc"]``). This is useful for colorschemes that use colors that
aren't available in color terminals.
``gradients``
Gradient definitions, consisting of a dict where the key is the name of the
gradient, and the value is a list containing one or two items, second item
is optional:
* A list of cterm color indicies.
* A list of hex color strings.
Colorschemes
============
:Location: :file:`powerline/colorschemes/{extension}/{name}.json`
``name``
Name of the colorscheme.
.. _config-colorscheme-groups:
``groups``
@ -184,11 +197,11 @@ Colorschemes
``fg``
Foreground color. Must be defined in :ref:`colors
<config-colorscheme-colors>`.
<config-colors-colors>`.
``bg``
Background color. Must be defined in :ref:`colors
<config-colorscheme-colors>`.
<config-colors-colors>`.
``attr``
Optional list of attributes. Valid values are one or more of
@ -203,8 +216,8 @@ Colorschemes
``colors``
A dict where the key is the color to be translated in this mode, and
the value is the new color. Both the key and the value must be
defined in :ref:`colors <config-colorscheme-colors>`.
the value is the new color. Both the key and the value must be defined
in :ref:`colors <config-colors-colors>`.
``groups``
Segment highlighting groups for this mode. Same syntax as the main

View File

@ -31,7 +31,8 @@ class Powerline(object):
# Load and initialize colorscheme
colorscheme_config = self.load_colorscheme_config(ext_config['colorscheme'])
colorscheme = Colorscheme(colorscheme_config)
colors_config = self.load_colors_config()
colorscheme = Colorscheme(colorscheme_config, colors_config)
# Load and initialize extension theme
theme_config = self.load_theme_config(ext_config.get('theme', 'default'))
@ -39,7 +40,6 @@ class Powerline(object):
self.import_paths = common_config['paths']
theme_kwargs = {
'ext': ext,
'colorscheme': colorscheme,
'common_config': common_config,
'segment_info': self.get_segment_info(),
}
@ -55,7 +55,7 @@ class Powerline(object):
sys.stderr.write('Error while importing renderer module: {0}\n'.format(e))
sys.exit(1)
options = {'term_truecolor': common_config.get('term_24bit_colors', False)}
self.renderer = Renderer(theme_config, local_themes, theme_kwargs, **options)
self.renderer = Renderer(theme_config, local_themes, theme_kwargs, colorscheme, **options)
def get_config_paths(self):
config_home = os.environ.get('XDG_CONFIG_HOME', os.path.join(os.path.expanduser('~'), '.config'))
@ -72,6 +72,9 @@ class Powerline(object):
def load_colorscheme_config(self, name):
return load_json_config(self.config_paths, os.path.join('colorschemes', self.ext, name))
def load_colors_config(self):
return load_json_config(self.config_paths, 'colors')
@staticmethod
def get_local_themes(local_themes):
return {}

View File

@ -1,95 +1,108 @@
# -*- coding: utf-8 -*-
from copy import copy
DEFAULT_MODE_KEY = None
ATTR_BOLD = 1
ATTR_ITALIC = 2
ATTR_UNDERLINE = 4
def get_attr_flag(attributes):
'''Convert an attribute array to a renderer flag.'''
attr_flag = 0
if 'bold' in attributes:
attr_flag |= ATTR_BOLD
if 'italic' in attributes:
attr_flag |= ATTR_ITALIC
if 'underline' in attributes:
attr_flag |= ATTR_UNDERLINE
return attr_flag
def pick_gradient_value(grad_list, gradient_level):
'''Given a list of colors and gradient percent, return a color that should be used.
Note: gradient level is not checked for being inside [0, 100] interval.
'''
return grad_list[int(round(gradient_level * (len(grad_list) - 1) / 100))]
class Colorscheme(object):
def __init__(self, colorscheme_config):
def __init__(self, colorscheme_config, colors_config):
'''Initialize a colorscheme.'''
self.colors = {}
self.modes_groups = {DEFAULT_MODE_KEY: {}}
self.gradients = {}
self.groups = colorscheme_config['groups']
self.translations = colorscheme_config.get('mode_translations', {})
# Create a dict of color tuples with both a cterm and hex value
for color_name, color in colorscheme_config['colors'].items():
for color_name, color in colors_config['colors'].items():
try:
self.colors[color_name] = (color[0], int(color[1], 16))
except TypeError:
self.colors[color_name] = (color, cterm_to_hex[color])
# Create highlighting groups for all modes
for group_name, group_props in colorscheme_config['groups'].items():
group_attr_flag = self._get_attr_flag(group_props.get('attr', []))
self.modes_groups[DEFAULT_MODE_KEY][group_name] = {
'fg': self.colors[group_props['fg']],
'bg': self.colors[group_props['bg']],
'attr': group_attr_flag,
}
# Create a dict of gradient names with two lists: for cterm and hex
# values. Two lists in place of one list of pairs were chosen because
# true colors allow more precise gradients.
for gradient_name, gradient in colors_config['gradients'].items():
if len(gradient) == 2:
self.gradients[gradient_name] = (
(gradient[0], [int(color, 16) for color in gradient[1]]))
else:
self.gradients[gradient_name] = (
(gradient[0], [cterm_to_hex[color] for color in gradient[0]]))
# Create mode-specific highlighting for this group
for mode, translations in colorscheme_config.get('mode_translations', {}).items():
if not mode in self.modes_groups:
self.modes_groups[mode] = {}
if group_name in translations.get('groups', {}):
# Override entire group if present in the translations group dict
self.modes_groups[mode][group_name] = {
'fg': self.colors[translations['groups'][group_name]['fg']],
'bg': self.colors[translations['groups'][group_name]['bg']],
'attr': self._get_attr_flag(translations['groups'][group_name].get('attr', [])),
}
else:
# Fallback to color translations from the translations colors dict
self.modes_groups[mode][group_name] = {
'fg': self.colors[translations.get('colors', {}).get(group_props['fg'], group_props['fg'])],
'bg': self.colors[translations.get('colors', {}).get(group_props['bg'], group_props['bg'])],
'attr': group_attr_flag,
}
def get_gradient(self, gradient, gradient_level):
if gradient in self.gradients:
return tuple((pick_gradient_value(grad_list, gradient_level) for grad_list in self.gradients[gradient]))
else:
return self.colors[gradient]
def get_group_highlighting(self, group):
'''Return highlighting information for all modes of a highlighting group.'''
group_highlighting = {}
for mode, mode_group in self.modes_groups.items():
try:
group_highlighting[mode] = mode_group[group]
except TypeError:
for try_group in group:
if try_group in self.modes_groups[mode]:
group_highlighting[mode] = mode_group[try_group]
break
finally:
if mode not in group_highlighting:
raise KeyError('Highlighting groups not found in colorscheme: {0}'.format(group))
return group_highlighting
def get_highlighting(self, groups, mode, gradient_level=None):
trans = self.translations.get(mode, {})
for group in groups:
if 'groups' in trans and group in trans['groups']:
try:
group_props = trans['groups'][group]
except KeyError:
continue
break
def get_highlighting(self, group, mode=None):
'''Return highlighting information for a highlighting group and mode.
else:
try:
group_props = copy(self.groups[group])
except KeyError:
continue
If no mode is specified, or the mode doesn't exist, highlighting for
the default mode is returned.
'''
if not mode or mode not in self.modes_groups:
mode = DEFAULT_MODE_KEY
try:
return self.modes_groups[mode][group]
except TypeError:
for try_group in group:
if try_group in self.modes_groups[mode]:
return self.modes_groups[mode][try_group]
raise KeyError('Highlighting groups not found in colorscheme: {0}'.format(group))
return self.modes_groups[mode][group]
try:
ctrans = trans['colors']
for key in ('fg', 'bg'):
try:
group_props[key] = ctrans[group_props[key]]
except KeyError:
pass
except KeyError:
pass
break
else:
raise KeyError('Highlighting groups not found in colorscheme: ' + ', '.join(groups))
if gradient_level is None:
pick_color = self.colors.__getitem__
else:
pick_color = lambda gradient : self.get_gradient(gradient, gradient_level)
return {
'fg': pick_color(group_props['fg']),
'bg': pick_color(group_props['bg']),
'attr': get_attr_flag(group_props.get('attr', [])),
}
def _get_attr_flag(self, attributes):
'''Convert an attribute array to a renderer flag.'''
attr_flag = 0
if 'bold' in attributes:
attr_flag |= ATTR_BOLD
if 'italic' in attributes:
attr_flag |= ATTR_ITALIC
if 'underline' in attributes:
attr_flag |= ATTR_UNDERLINE
return attr_flag
cterm_to_hex = {
16: 0x000000, 17: 0x00005f, 18: 0x000087, 19: 0x0000af, 20: 0x0000d7, 21: 0x0000ff,

View File

@ -0,0 +1,82 @@
{
"colors": {
"black": 16,
"white": 231,
"green": [2, "719e07"],
"darkestgreen": 22,
"darkgreen": 28,
"mediumgreen": 70,
"brightgreen": 148,
"cyan": [6, "2aa198"],
"darkestcyan": 23,
"darkcyan": 74,
"mediumcyan": 117,
"brightcyan": 159,
"blue": [4, "268bd2"],
"darkestblue": 24,
"darkblue": 31,
"red": [1, "dc322f"],
"darkestred": 52,
"darkred": 88,
"mediumred": 124,
"brightred": 160,
"brightestred": 196,
"magenta": [5, "d33682"],
"darkestpurple": 55,
"mediumpurple": 98,
"brightpurple": 189,
"violet": [13, "6c71c4"],
"orange": [9, "cb4b16"],
"darkorange": 94,
"mediumorange": 166,
"brightorange": 208,
"brightestorange": 214,
"yellow": [3, "b58900"],
"brightyellow": 220,
"gray0": 233,
"gray1": 235,
"gray2": 236,
"gray3": 239,
"gray4": 240,
"gray5": 241,
"gray6": 244,
"gray7": 245,
"gray8": 247,
"gray9": 250,
"gray10": 252,
"base03": [8, "002b36"],
"base02": [0, "073642"],
"base01": [10, "586e75"],
"base00": [11, "657b83"],
"base0": [12, "839496"],
"base1": [14, "93a1a1"],
"base2": [7, "eee8d5"],
"base3": [15, "fdf6e3"],
"system_load_good": 106,
"system_load_bad": 178,
"system_load_ugly": 202,
"weather_temp_cold": 67,
"weather_temp_hot": 166,
"weather_condition_cold": 117,
"weather_condition_hot": 228
},
"gradients": {
"green_yellow_red": [
[190, 184, 178, 172, 166, 160],
["8ae71c", "c2e821", "e9d926", "eaa72b", "eb7830", "ec4b35"]
]
}
}

View File

@ -1,23 +1,5 @@
{
"name": "Default color scheme for IPython prompt",
"colors": {
"black": 16,
"white": 231,
"darkcyan": 74,
"gray0": 233,
"gray1": 235,
"gray2": 236,
"gray3": 239,
"gray4": 240,
"gray5": 241,
"gray6": 244,
"gray7": 245,
"gray8": 247,
"gray9": 250,
"gray10": 252
},
"groups": {
"virtualenv": { "fg": "white", "bg": "darkcyan" },
"prompt": { "fg": "gray9", "bg": "gray4" }

View File

@ -1,58 +1,5 @@
{
"name": "Default color scheme for shell prompts",
"colors": {
"black": 16,
"white": 231,
"darkestgreen": 22,
"darkgreen": 28,
"mediumgreen": 70,
"brightgreen": 148,
"darkestcyan": 23,
"darkcyan": 74,
"mediumcyan": 117,
"brightcyan": 159,
"darkestblue": 24,
"darkblue": 31,
"darkestred": 52,
"darkred": 88,
"mediumred": 124,
"brightred": 160,
"brightestred": 196,
"darkestpurple": 55,
"mediumpurple": 98,
"brightpurple": 189,
"darkorange": 94,
"mediumorange": 166,
"brightorange": 208,
"brightestorange": 214,
"brightyellow": 220,
"gray0": 233,
"gray1": 235,
"gray2": 236,
"gray3": 239,
"gray4": 240,
"gray5": 241,
"gray6": 244,
"gray7": 245,
"gray8": 247,
"gray9": 250,
"gray10": 252,
"gradient1": 190,
"gradient2": 184,
"gradient3": 178,
"gradient4": 172,
"gradient5": 166,
"gradient6": 160
},
"groups": {
"user": { "fg": "white", "bg": "darkblue", "attr": ["bold"] },
"superuser": { "fg": "white", "bg": "brightred", "attr": ["bold"] },

View File

@ -1,23 +1,5 @@
{
"name": "Solarized Dark",
"colors": {
"base03": [8, "002b36"],
"base02": [0, "073642"],
"base01": [10, "586e75"],
"base00": [11, "657b83"],
"base0": [12, "839496"],
"base1": [14, "93a1a1"],
"base2": [7, "eee8d5"],
"base3": [15, "fdf6e3"],
"yellow": [3, "b58900"],
"orange": [9, "cb4b16"],
"red": [1, "dc322f"],
"magenta": [5, "d33682"],
"violet": [13, "6c71c4"],
"blue": [4, "268bd2"],
"cyan": [6, "2aa198"],
"green": [2, "719e07"]
},
"groups": {
"user": { "fg": "base3", "bg": "blue", "attr": ["bold"] },
"superuser": { "fg": "base3", "bg": "red", "attr": ["bold"] },

View File

@ -1,38 +1,5 @@
{
"name": "Default color scheme for terminal prompts",
"colors": {
"black": 16,
"white": 231,
"brightred": 160,
"darkestblue": 24,
"darkblue": 31,
"mediumblue": 38,
"brightblue": 117,
"brightestblue": 153,
"gray0": 234,
"gray1": 235,
"gray2": 236,
"gray3": 239,
"gray4": 240,
"gray5": 241,
"gray6": 244,
"gray7": 245,
"gray8": 247,
"gray9": 250,
"gray10": 254,
"system_load_good": 106,
"system_load_bad": 178,
"system_load_ugly": 202,
"weather_temp_cold": 67,
"weather_temp_hot": 166,
"weather_condition_cold": 117,
"weather_condition_hot": 228
},
"groups": {
"background:divider": { "fg": "gray5", "bg": "gray0" },
"session": { "fg": "black", "bg": "gray10", "attr": ["bold"] },

View File

@ -1,58 +1,5 @@
{
"name": "Default color scheme",
"colors": {
"black": 16,
"white": 231,
"darkestgreen": 22,
"darkgreen": 28,
"mediumgreen": 70,
"brightgreen": 148,
"darkestcyan": 23,
"darkcyan": 74,
"mediumcyan": 117,
"brightcyan": 159,
"darkestblue": 24,
"darkblue": 31,
"darkestred": 52,
"darkred": 88,
"mediumred": 124,
"brightred": 160,
"brightestred": 196,
"darkestpurple": 55,
"mediumpurple": 98,
"brightpurple": 189,
"darkorange": 94,
"mediumorange": 166,
"brightorange": 208,
"brightestorange": 214,
"brightyellow": 220,
"gray0": 233,
"gray1": 235,
"gray2": 236,
"gray3": 239,
"gray4": 240,
"gray5": 241,
"gray6": 244,
"gray7": 245,
"gray8": 247,
"gray9": 250,
"gray10": 252,
"gradient1": [190, "8ae71c"],
"gradient2": [184, "c2e821"],
"gradient3": [178, "e9d926"],
"gradient4": [172, "eaa72b"],
"gradient5": [166, "eb7830"],
"gradient6": [160, "ec4b35"]
},
"groups": {
"background": { "fg": "white", "bg": "gray2" },
"background:divider": { "fg": "gray6", "bg": "gray2" },
@ -74,12 +21,7 @@
"file_vcs_status_M": { "fg": "brightyellow", "bg": "gray4" },
"file_vcs_status_A": { "fg": "brightgreen", "bg": "gray4" },
"line_percent": { "fg": "gray9", "bg": "gray4" },
"line_percent_gradient1": { "fg": "gradient1", "bg": "gray4" },
"line_percent_gradient2": { "fg": "gradient2", "bg": "gray4" },
"line_percent_gradient3": { "fg": "gradient3", "bg": "gray4" },
"line_percent_gradient4": { "fg": "gradient4", "bg": "gray4" },
"line_percent_gradient5": { "fg": "gradient5", "bg": "gray4" },
"line_percent_gradient6": { "fg": "gradient6", "bg": "gray4" },
"line_percent_gradient": { "fg": "green_yellow_red", "bg": "gray4" },
"line_current": { "fg": "gray1", "bg": "gray10", "attr": ["bold"] },
"line_current_symbol": { "fg": "gray1", "bg": "gray10" },
"col_current": { "fg": "gray6", "bg": "gray10" },
@ -102,12 +44,7 @@
"gray9": "gray4",
"gray10": "gray5",
"white": "gray6",
"gradient1": "gray5",
"gradient2": "gray5",
"gradient3": "gray5",
"gradient4": "gray5",
"gradient5": "gray5",
"gradient6": "gray5"
"green_yellow_red": "gray5"
}
},
"i": {
@ -123,12 +60,7 @@
"gray8": "mediumcyan",
"gray9": "mediumcyan",
"gray10": "mediumcyan",
"gradient1": "mediumcyan",
"gradient2": "mediumcyan",
"gradient3": "mediumcyan",
"gradient4": "mediumcyan",
"gradient5": "mediumcyan",
"gradient6": "mediumcyan"
"green_yellow_red": "gray5"
},
"groups": {
"mode": { "fg": "darkestcyan", "bg": "white", "attr": ["bold"] },

View File

@ -1,23 +1,5 @@
{
"name": "Solarized Dark",
"colors": {
"base03": [8, "002b36"],
"base02": [0, "073642"],
"base01": [10, "586e75"],
"base00": [11, "657b83"],
"base0": [12, "839496"],
"base1": [14, "93a1a1"],
"base2": [7, "eee8d5"],
"base3": [15, "fdf6e3"],
"yellow": [3, "b58900"],
"orange": [9, "cb4b16"],
"red": [1, "dc322f"],
"magenta": [5, "d33682"],
"violet": [13, "6c71c4"],
"blue": [4, "268bd2"],
"cyan": [6, "2aa198"],
"green": [2, "719e07"]
},
"groups": {
"background": { "fg": "base3", "bg": "base02" },
"background:divider": { "fg": "base00", "bg": "base02" },

View File

@ -1,38 +1,5 @@
{
"name": "Default color scheme for window managers",
"colors": {
"black": 16,
"white": 231,
"brightred": 160,
"darkestblue": 24,
"darkblue": 31,
"mediumblue": 38,
"brightblue": 117,
"brightestblue": 153,
"gray0": 234,
"gray1": 235,
"gray2": 236,
"gray3": 239,
"gray4": 240,
"gray5": 241,
"gray6": 244,
"gray7": 245,
"gray8": 247,
"gray9": 250,
"gray10": 254,
"system_load_good": 106,
"system_load_bad": 178,
"system_load_ugly": 202,
"weather_temp_cold": 67,
"weather_temp_hot": 166,
"weather_condition_cold": 117,
"weather_condition_hot": 228
},
"groups": {
"background:divider": { "fg": "gray5", "bg": "gray0" },
"session": { "fg": "black", "bg": "gray10", "attr": ["bold"] },

View File

@ -11,7 +11,8 @@
"soft": " "
}
},
"spaces": 1
"spaces": 1,
"colors": "default"
},
"ext": {
"ipython": {

View File

@ -1,16 +1,16 @@
# -*- coding: utf-8 -*-
from powerline.colorscheme import DEFAULT_MODE_KEY
from powerline.theme import Theme
class Renderer(object):
def __init__(self, theme_config, local_themes, theme_kwargs, **options):
def __init__(self, theme_config, local_themes, theme_kwargs, colorscheme, **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
self.colorscheme = colorscheme
def add_local_theme(self, matcher, theme):
if matcher in self.local_themes:
@ -27,6 +27,14 @@ class Renderer(object):
else:
return self.theme
def get_highlighting(self, segment, mode):
segment['highlight'] = self.colorscheme.get_highlighting(segment['highlight_group'], mode, segment.get('gradient_level'))
if segment['divider_highlight_group']:
segment['divider_highlight'] = self.colorscheme.get_highlighting(segment['divider_highlight_group'], mode)
else:
segment['divider_highlight'] = None
return segment
def render(self, mode=None, width=None, side=None, output_raw=False, segment_info=None, matcher_info=None):
'''Render all segments.
@ -43,10 +51,10 @@ class Renderer(object):
theme.segment_info.update(segment_info)
# Handle excluded/included segments for the current mode
segments = [segment for segment in segments
segments = [self.get_highlighting(segment, mode) for segment in segments
if mode not in segment['exclude_modes'] or (segment['include_modes'] and segment in segment['include_modes'])]
segments = [segment for segment in self._render_segments(mode, theme, segments)]
segments = [segment for segment in self._render_segments(theme, segments)]
if not width:
# No width specified, so we don't need to crop or pad anything
@ -73,11 +81,11 @@ class Renderer(object):
segment['_space_right'] += space_side
segments_spacers[0]['_space_right'] += distribute_len_remainder
rendered_highlighted = u''.join([segment['_rendered_hl'] for segment in self._render_segments(mode, theme, segments)]) + self.hlstyle()
rendered_highlighted = u''.join([segment['_rendered_hl'] for segment in self._render_segments(theme, segments)]) + self.hlstyle()
return self._returned_value(rendered_highlighted, segments, output_raw)
def _render_segments(self, mode, theme, segments, render_highlighted=True):
def _render_segments(self, theme, segments, render_highlighted=True):
'''Internal segment rendering method.
This method loops through the segment array and compares the
@ -89,10 +97,6 @@ class Renderer(object):
statusline if render_highlighted is True.
'''
segments_len = len(segments)
try:
mode = mode if mode in segments[0]['highlight'] else DEFAULT_MODE_KEY
except IndexError:
pass
for index, segment in enumerate(segments):
segment['_rendered_raw'] = u''
@ -102,7 +106,7 @@ class Renderer(object):
next_segment = segments[index + 1] if index < segments_len - 1 else theme.EMPTY_SEGMENT
compare_segment = next_segment if segment['side'] == 'left' else prev_segment
outer_padding = ' ' if (index == 0 and segment['side'] == 'left') or (index == segments_len - 1 and segment['side'] == 'right') else ''
divider_type = 'soft' if compare_segment['highlight'][mode]['bg'] == segment['highlight'][mode]['bg'] else 'hard'
divider_type = 'soft' if compare_segment['highlight']['bg'] == segment['highlight']['bg'] else 'hard'
divider_raw = theme.get_divider(segment['side'], divider_type)
divider_spaces = theme.get_spaces()
@ -130,13 +134,13 @@ class Renderer(object):
if render_highlighted:
if divider_type == 'soft':
divider_highlight_group_key = 'highlight' if segment['divider_highlight_group'] is None else 'divider_highlight'
divider_fg = segment[divider_highlight_group_key][mode]['fg']
divider_bg = segment[divider_highlight_group_key][mode]['bg']
divider_fg = segment[divider_highlight_group_key]['fg']
divider_bg = segment[divider_highlight_group_key]['bg']
else:
divider_fg = segment['highlight'][mode]['bg']
divider_bg = compare_segment['highlight'][mode]['bg']
divider_fg = segment['highlight']['bg']
divider_bg = compare_segment['highlight']['bg']
divider_highlighted = self.hl(divider_raw, divider_fg, divider_bg, False)
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'][mode])
contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'])
# Append padded raw and highlighted segments to the rendered segment variables
if segment['draw_divider'] or (divider_type == 'hard' and segment['width'] != 'auto'):

View File

@ -45,6 +45,10 @@ segment_getters = {
}
def scalar_to_list(value):
return value if type(value) is list else [value]
def gen_segment_getter(ext, path, theme_configs, default_module=None):
data = {
'default_module': default_module or 'powerline.segments.' + ext,
@ -66,8 +70,8 @@ def gen_segment_getter(ext, path, theme_configs, default_module=None):
divider_highlight_group = segment.get('divider_highlight_group')
return {
'type': segment_type,
'highlight_group': highlight_group,
'divider_highlight_group': divider_highlight_group,
'highlight_group': scalar_to_list(highlight_group),
'divider_highlight_group': scalar_to_list(divider_highlight_group) if divider_highlight_group else None,
'before': get_key(segment, module, 'before', ''),
'after': get_key(segment, module, 'after', ''),
'contents_func': contents_func,

View File

@ -241,7 +241,8 @@ def line_percent(segment_info, gradient=False):
return percentage
return [{
'contents': percentage,
'highlight_group': ['line_percent_gradient' + str(int(5 * percentage // 100) + 1), 'line_percent'],
'highlight_group': ['line_percent_gradient', 'line_percent'],
'gradient_level': percentage,
}]

View File

@ -18,8 +18,7 @@ def requires_segment_info(func):
class Theme(object):
def __init__(self, ext, colorscheme, theme_config, common_config, top_theme_config=None, segment_info=None):
self.colorscheme = colorscheme
def __init__(self, ext, theme_config, common_config, top_theme_config=None, segment_info=None):
self.dividers = theme_config.get('dividers', common_config['dividers'])
self.spaces = theme_config.get('spaces', common_config['spaces'])
self.segments = {
@ -28,7 +27,7 @@ class Theme(object):
}
self.EMPTY_SEGMENT = {
'contents': None,
'highlight': defaultdict(lambda: {'fg': False, 'bg': False, 'attr': 0})
'highlight': {'fg': False, 'bg': False, 'attr': 0}
}
self.segment_info = segment_info
theme_configs = [theme_config]
@ -45,14 +44,6 @@ class Theme(object):
def get_spaces(self):
return self.spaces
def add_highlight(self, segment):
segment['highlight'] = self.colorscheme.get_group_highlighting(segment['highlight_group'])
if segment['divider_highlight_group']:
segment['divider_highlight'] = self.colorscheme.get_group_highlighting(segment['divider_highlight_group'])
else:
segment['divider_highlight'] = None
return segment
def get_segments(self, side=None):
'''Return all segments.
@ -92,7 +83,6 @@ class Theme(object):
else:
continue
for segment in parsed_segments:
segment = self.add_highlight(segment)
segment['contents'] = segment['before'] + unicode(segment['contents'] if segment['contents'] is not None else '') + segment['after']
# Align segment contents
if segment['width'] and segment['width'] != 'auto':