From 1e4c3612ee8f105da5bba5c315e3450a7aa298f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kim=20Silkeb=C3=A6kken?= Date: Mon, 28 Jan 2013 11:51:26 +0100 Subject: [PATCH] Pass segment contents to renderer hl() methods This allows the hl() methods to wrap highlighting code *around* the segment contents, this is required for e.g. Pango markup in Awesome statuslines (segments must be wrapped in ... tags). --- powerline/renderer.py | 58 +++++++++++++++++++++---------- powerline/renderers/shell.py | 4 +-- powerline/renderers/tmux.py | 4 +-- powerline/renderers/vim.py | 4 +-- powerline/renderers/zsh_prompt.py | 4 +-- 5 files changed, 47 insertions(+), 27 deletions(-) diff --git a/powerline/renderer.py b/powerline/renderer.py index 2d630b45..63702d60 100644 --- a/powerline/renderer.py +++ b/powerline/renderer.py @@ -105,39 +105,59 @@ class Renderer(object): segment['rendered_raw'] = u'' 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 = theme.get_divider(segment['side'], divider_type) - divider_hl = '' - segment_hl = '' + divider_raw = theme.get_divider(segment['side'], divider_type) + divider_highlighted = '' + contents_raw = segment['contents'] + contents_highlighted = '' + + # Pad segments first + if segment['type'] == 'filler': + pass + elif segment['draw_divider'] or divider_type == 'hard': + if segment['side'] == 'left': + contents_raw = outer_padding + contents_raw + ' ' + divider_raw = divider_raw + ' ' + else: + contents_raw = ' ' + contents_raw + outer_padding + divider_raw = ' ' + divider_raw + elif contents_raw: + if segment['side'] == 'left': + contents_raw = outer_padding + contents_raw + else: + contents_raw = contents_raw + outer_padding + else: + raise ValueError('Unknown segment type') + + # Apply highlighting to padded dividers and contents if render_highlighted: if divider_type == 'soft' and segment['divider_highlight_group'] is not None: - divider_hl = self.hl(segment['divider_highlight'][mode]['fg'], segment['divider_highlight'][mode]['bg'], False) + divider_highlighted = self.hl(divider_raw, segment['divider_highlight'][mode]['fg'], segment['divider_highlight'][mode]['bg'], False) elif divider_type == 'hard': - divider_hl = self.hl(segment['highlight'][mode]['bg'], compare_segment['highlight'][mode]['bg'], False) - segment_hl = self.hl(**segment['highlight'][mode]) + divider_highlighted = self.hl(divider_raw, segment['highlight'][mode]['bg'], compare_segment['highlight'][mode]['bg'], False) + contents_highlighted = self.hl(self.escape(contents_raw), **segment['highlight'][mode]) + # Append padded raw and highlighted segments to the rendered segment variables if segment['type'] == 'filler': - rendered_highlighted += self.escape(segment['contents'] or '') + rendered_highlighted += contents_highlighted if contents_raw else '' elif segment['draw_divider'] or divider_type == 'hard': # Draw divider if specified, or if it's a hard divider # Note: Hard dividers are always drawn, regardless of # the draw_divider option if segment['side'] == 'left': - segment['rendered_raw'] += outer_padding + segment['contents'] + ' ' + divider + ' ' - rendered_highlighted += segment_hl + self.escape(outer_padding + segment['contents'] + ' ') + divider_hl + self.escape(divider + ' ') + segment['rendered_raw'] += contents_raw + divider_raw + rendered_highlighted += contents_highlighted + divider_highlighted else: - segment['rendered_raw'] += ' ' + divider + ' ' + segment['contents'] + outer_padding - rendered_highlighted += self.escape(' ') + divider_hl + self.escape(divider) + segment_hl + self.escape(' ' + segment['contents'] + outer_padding) - elif segment['contents']: + segment['rendered_raw'] += divider_raw + contents_raw + rendered_highlighted += divider_highlighted + contents_highlighted + elif contents_raw: # Segments without divider if segment['side'] == 'left': - segment['rendered_raw'] += outer_padding + segment['contents'] - rendered_highlighted += segment_hl + self.escape(outer_padding + segment['contents']) + segment['rendered_raw'] += contents_raw + rendered_highlighted += contents_highlighted else: - segment['rendered_raw'] += segment['contents'] + outer_padding - rendered_highlighted += segment_hl + self.escape(segment['contents'] + outer_padding) - else: - raise ValueError('Unknown segment type') + segment['rendered_raw'] += contents_raw + rendered_highlighted += contents_highlighted rendered_highlighted += self.hl() return rendered_highlighted @@ -161,5 +181,5 @@ class Renderer(object): b = int & 0xff return r, g, b - def hl(self, fg=None, bg=None, attr=None): + def hl(self, contents=None, fg=None, bg=None, attr=None): raise NotImplementedError diff --git a/powerline/renderers/shell.py b/powerline/renderers/shell.py index 3797429f..d4708b34 100644 --- a/powerline/renderers/shell.py +++ b/powerline/renderers/shell.py @@ -5,7 +5,7 @@ from powerline.renderer import Renderer class ShellRenderer(Renderer): '''Powerline shell segment renderer.''' - def hl(self, fg=None, bg=None, attr=None): + def hl(self, contents=None, fg=None, bg=None, attr=None): '''Highlight a segment. If an argument is None, the argument is ignored. If an argument is @@ -35,7 +35,7 @@ class ShellRenderer(Renderer): else: if attr & Renderer.ATTR_BOLD: ansi += [1] - return '[{0}m'.format(';'.join(str(attr) for attr in ansi)) + return '[{0}m'.format(';'.join(str(attr) for attr in ansi)) + (contents or u'') @staticmethod def escape(string): diff --git a/powerline/renderers/tmux.py b/powerline/renderers/tmux.py index 1b2a93a2..df232a15 100644 --- a/powerline/renderers/tmux.py +++ b/powerline/renderers/tmux.py @@ -5,7 +5,7 @@ from powerline.renderer import Renderer class TmuxRenderer(Renderer): '''Powerline tmux segment renderer.''' - def hl(self, fg=None, bg=None, attr=None): + def hl(self, contents=None, fg=None, bg=None, attr=None): '''Highlight a segment.''' # We don't need to explicitly reset attributes, so skip those calls if not attr and not bg and not fg: @@ -37,4 +37,4 @@ class TmuxRenderer(Renderer): tmux_attr += ['underscore'] else: tmux_attr += ['nounderscore'] - return '#[' + ','.join(tmux_attr) + ']' + return '#[' + ','.join(tmux_attr) + ']' + (contents or u'') diff --git a/powerline/renderers/vim.py b/powerline/renderers/vim.py index 18a0d709..9d33ca73 100644 --- a/powerline/renderers/vim.py +++ b/powerline/renderers/vim.py @@ -45,7 +45,7 @@ class VimRenderer(Renderer): def escape(string): return string.replace('%', '%%') - def hl(self, fg=None, bg=None, attr=None): + def hl(self, contents=None, fg=None, bg=None, attr=None): '''Highlight a segment. If an argument is None, the argument is ignored. If an argument is @@ -94,4 +94,4 @@ class VimRenderer(Renderer): guibg='#{0:06x}'.format(hl_group['guibg']) if hl_group['guibg'] != 'NONE' else 'NONE', attr=','.join(hl_group['attr']), )) - return '%#' + self.hl_groups[(fg, bg, attr)]['name'] + '#' + return '%#' + self.hl_groups[(fg, bg, attr)]['name'] + '#' + (contents or u'') diff --git a/powerline/renderers/zsh_prompt.py b/powerline/renderers/zsh_prompt.py index f0d0e533..6d292ccd 100644 --- a/powerline/renderers/zsh_prompt.py +++ b/powerline/renderers/zsh_prompt.py @@ -5,13 +5,13 @@ from powerline.renderers.shell import ShellRenderer class ZshPromptRenderer(ShellRenderer): '''Powerline zsh prompt segment renderer.''' - def hl(self, *args, **kwargs): + def hl(self, contents=None, fg=None, bg=None, attr=None): '''Highlight a segment. Returns the default ShellRenderer escape sequence with %{...%} wrapped around it (required in zsh prompts). ''' - return '%{' + super(ZshPromptRenderer, self).hl(*args, **kwargs) + '%}' + return '%{' + super(ZshPromptRenderer, self).hl(None, fg, bg, attr) + '%}' + (contents or u'') @staticmethod def escape(string):