diff --git a/powerline/renderer.py b/powerline/renderer.py index 2117eeee..0555caef 100644 --- a/powerline/renderer.py +++ b/powerline/renderer.py @@ -4,12 +4,15 @@ from powerline.theme import Theme from unicodedata import east_asian_width, combining import os - try: NBSP = unicode(' ', 'utf-8') except NameError: NBSP = ' ' +try: + from __builtin__ import unichr as chr +except ImportError: + pass def construct_returned_value(rendered_highlighted, segments, output_raw): if output_raw: @@ -65,6 +68,22 @@ class Renderer(object): python-2) regular string or ``None``. ''' + character_translations = {ord(' '): NBSP} + '''Character translations for use in escape() function. + + See documentation of ``unicode.translate`` for details. + ''' + + np_character_translations = dict(((i, '^' + chr(i + 0x40)) for i in range(0x20))) + '''Non-printable character translations + + These are used to transform characters in range 0x00—0x1F into ``^@``, + ``^A`` and so on. Unilke with ``.escape()`` method (and + ``character_translations``) result is passed to ``.strwidth()`` method. + + Note: transforms tab into ``^I``. + ''' + def __init__(self, theme_config, local_themes, @@ -262,8 +281,8 @@ class Renderer(object): contents_raw = (segment['_space_left'] * ' ') + contents_raw + (segment['_space_right'] * ' ') + outer_padding # Replace spaces with no-break spaces - contents_raw = contents_raw.replace(' ', NBSP) divider_raw = divider_raw.replace(' ', NBSP) + contents_raw = contents_raw.translate(self.np_character_translations) # Apply highlighting to padded dividers and contents if render_highlighted: @@ -295,11 +314,11 @@ class Renderer(object): segment['_len'] = self.strwidth(segment['_rendered_raw']) yield segment - @staticmethod - def escape(string): + @classmethod + def escape(cls, string): '''Method that escapes segment contents. ''' - return string + return string.translate(cls.character_translations) def hlstyle(fg=None, bg=None, attr=None): '''Output highlight style string. diff --git a/powerline/renderers/bash_prompt.py b/powerline/renderers/bash_prompt.py index 01f42f74..58cf36d9 100644 --- a/powerline/renderers/bash_prompt.py +++ b/powerline/renderers/bash_prompt.py @@ -1,5 +1,7 @@ # vim:fileencoding=utf-8:noet +from __future__ import absolute_import, unicode_literals + from powerline.renderers.shell import ShellRenderer @@ -8,9 +10,9 @@ class BashPromptRenderer(ShellRenderer): escape_hl_start = '\[' escape_hl_end = '\]' - @staticmethod - def escape(string): - return string.replace('\\', '\\\\').replace('$', '\\$').replace('`', '\\`') + character_translations = ShellRenderer.character_translations + character_translations[ord('$')] = '\\$' + character_translations[ord('`')] = '\\`' renderer = BashPromptRenderer diff --git a/powerline/renderers/shell.py b/powerline/renderers/shell.py index 945dc765..e261bb28 100644 --- a/powerline/renderers/shell.py +++ b/powerline/renderers/shell.py @@ -1,5 +1,7 @@ # vim:fileencoding=utf-8:noet +from __future__ import absolute_import, unicode_literals + from powerline.renderer import Renderer from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE @@ -19,6 +21,9 @@ class ShellRenderer(Renderer): tmux_escape = False screen_escape = False + character_translations = Renderer.character_translations + character_translations[ord('\\')] = '\\\\' + def hlstyle(self, fg=None, bg=None, attr=None): '''Highlight a segment. @@ -62,9 +67,5 @@ class ShellRenderer(Renderer): r = '\033P' + r.replace('\033', '\033\033') + '\033\\' return self.escape_hl_start + r + self.escape_hl_end - @staticmethod - def escape(string): - return string.replace('\\', '\\\\') - renderer = ShellRenderer diff --git a/powerline/renderers/tmux.py b/powerline/renderers/tmux.py index 655c1a6b..e8ab17f1 100644 --- a/powerline/renderers/tmux.py +++ b/powerline/renderers/tmux.py @@ -1,11 +1,17 @@ # vim:fileencoding=utf-8:noet +from __future__ import absolute_import, unicode_literals + from powerline.renderer import Renderer from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE class TmuxRenderer(Renderer): '''Powerline tmux segment renderer.''' + + character_translations = Renderer.character_translations + character_translations[ord('#')] = '##[]' + def hlstyle(self, fg=None, bg=None, attr=None): '''Highlight a segment.''' # We don't need to explicitly reset attributes, so skip those calls diff --git a/powerline/renderers/vim.py b/powerline/renderers/vim.py index 8e8fb0e9..f2e17c32 100644 --- a/powerline/renderers/vim.py +++ b/powerline/renderers/vim.py @@ -1,6 +1,6 @@ # vim:fileencoding=utf-8:noet -from __future__ import absolute_import +from __future__ import absolute_import, unicode_literals from powerline.bindings.vim import vim_get_func, environ from powerline.renderer import Renderer @@ -11,6 +11,12 @@ import vim import sys +try: + from __builtin__ import unichr as chr +except ImportError: + pass + + vim_mode = vim_get_func('mode', rettype=str) mode_translations = { chr(ord('V') - 0x40): '^V', @@ -21,6 +27,9 @@ mode_translations = { class VimRenderer(Renderer): '''Powerline vim segment renderer.''' + character_translations = Renderer.character_translations + character_translations[ord('%')] = '%%' + def __init__(self, *args, **kwargs): if not hasattr(vim, 'strwidth'): # Hope nobody want to change this at runtime @@ -97,10 +106,6 @@ class VimRenderer(Renderer): def reset_highlight(self): self.hl_groups.clear() - @staticmethod - def escape(string): - return string.replace('%', '%%') - def hlstyle(self, fg=None, bg=None, attr=None): '''Highlight a segment. diff --git a/powerline/renderers/zsh_prompt.py b/powerline/renderers/zsh_prompt.py index 2e6e5e77..e30ac061 100644 --- a/powerline/renderers/zsh_prompt.py +++ b/powerline/renderers/zsh_prompt.py @@ -1,5 +1,7 @@ # vim:fileencoding=utf-8:noet +from __future__ import absolute_import, unicode_literals + from powerline.renderers.shell import ShellRenderer @@ -8,9 +10,8 @@ class ZshPromptRenderer(ShellRenderer): escape_hl_start = '%{' escape_hl_end = '%}' - @staticmethod - def escape(string): - return string.replace('%', '%%').replace('\\', '\\\\') + character_translations = ShellRenderer.character_translations + character_translations[ord('%')] = '%%' renderer = ZshPromptRenderer