diff --git a/docs/source/configuration.rst b/docs/source/configuration.rst index bbefffec..98111267 100644 --- a/docs/source/configuration.rst +++ b/docs/source/configuration.rst @@ -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 - `. + `. ``bg`` Background color. Must be defined in :ref:`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 `. + the value is the new color. Both the key and the value must be defined + in :ref:`colors `. ``groups`` Segment highlighting groups for this mode. Same syntax as the main diff --git a/powerline/__init__.py b/powerline/__init__.py index 5275a53c..5296cde9 100644 --- a/powerline/__init__.py +++ b/powerline/__init__.py @@ -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 {} diff --git a/powerline/colorscheme.py b/powerline/colorscheme.py index 335cc3b9..7fd85422 100644 --- a/powerline/colorscheme.py +++ b/powerline/colorscheme.py @@ -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, diff --git a/powerline/config_files/colors.json b/powerline/config_files/colors.json new file mode 100644 index 00000000..e4636a93 --- /dev/null +++ b/powerline/config_files/colors.json @@ -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"] + ] + } +} diff --git a/powerline/config_files/colorschemes/ipython/default.json b/powerline/config_files/colorschemes/ipython/default.json index 3a9f7355..b45bed45 100644 --- a/powerline/config_files/colorschemes/ipython/default.json +++ b/powerline/config_files/colorschemes/ipython/default.json @@ -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" } diff --git a/powerline/config_files/colorschemes/shell/default.json b/powerline/config_files/colorschemes/shell/default.json index 57cff291..0320d807 100644 --- a/powerline/config_files/colorschemes/shell/default.json +++ b/powerline/config_files/colorschemes/shell/default.json @@ -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"] }, diff --git a/powerline/config_files/colorschemes/shell/solarized.json b/powerline/config_files/colorschemes/shell/solarized.json index b850b34f..fe3216cd 100644 --- a/powerline/config_files/colorschemes/shell/solarized.json +++ b/powerline/config_files/colorschemes/shell/solarized.json @@ -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"] }, diff --git a/powerline/config_files/colorschemes/tmux/default.json b/powerline/config_files/colorschemes/tmux/default.json index d701c78a..37146011 100644 --- a/powerline/config_files/colorschemes/tmux/default.json +++ b/powerline/config_files/colorschemes/tmux/default.json @@ -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"] }, diff --git a/powerline/config_files/colorschemes/vim/default.json b/powerline/config_files/colorschemes/vim/default.json index 5e602bcb..42b69d6a 100644 --- a/powerline/config_files/colorschemes/vim/default.json +++ b/powerline/config_files/colorschemes/vim/default.json @@ -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"] }, diff --git a/powerline/config_files/colorschemes/vim/solarized.json b/powerline/config_files/colorschemes/vim/solarized.json index 2cad7df0..825a4272 100644 --- a/powerline/config_files/colorschemes/vim/solarized.json +++ b/powerline/config_files/colorschemes/vim/solarized.json @@ -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" }, diff --git a/powerline/config_files/colorschemes/wm/default.json b/powerline/config_files/colorschemes/wm/default.json index 412e5d5b..210b4e4b 100644 --- a/powerline/config_files/colorschemes/wm/default.json +++ b/powerline/config_files/colorschemes/wm/default.json @@ -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"] }, diff --git a/powerline/config_files/config.json b/powerline/config_files/config.json index e2ae7c13..4c8ad85f 100644 --- a/powerline/config_files/config.json +++ b/powerline/config_files/config.json @@ -11,7 +11,8 @@ "soft": " " } }, - "spaces": 1 + "spaces": 1, + "colors": "default" }, "ext": { "ipython": { diff --git a/powerline/renderer.py b/powerline/renderer.py index 684b702e..9fdb7015 100644 --- a/powerline/renderer.py +++ b/powerline/renderer.py @@ -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'): diff --git a/powerline/segment.py b/powerline/segment.py index 0175ff04..0efd3949 100644 --- a/powerline/segment.py +++ b/powerline/segment.py @@ -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, diff --git a/powerline/segments/vim.py b/powerline/segments/vim.py index 228e1ddc..91f80e25 100644 --- a/powerline/segments/vim.py +++ b/powerline/segments/vim.py @@ -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, }] diff --git a/powerline/theme.py b/powerline/theme.py index db503866..14a79021 100644 --- a/powerline/theme.py +++ b/powerline/theme.py @@ -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':