diff --git a/powerline/__init__.py b/powerline/__init__.py index 935190ac..dc1f30ea 100644 --- a/powerline/__init__.py +++ b/powerline/__init__.py @@ -6,19 +6,18 @@ import os import sys from powerline.colorscheme import Colorscheme -from powerline.lib import underscore_to_camelcase def open_file(path): return open(path, 'r') -def load_json_config(search_paths, config_file, load=json.load, open=open_file): +def load_json_config(search_paths, config_file, load=json.load, open_file=open_file): config_file += '.json' for path in search_paths: config_file_path = os.path.join(path, config_file) if os.path.isfile(config_file_path): - with open(config_file_path) as config_file_fp: + with open_file(config_file_path) as config_file_fp: return load(config_file_fp) raise IOError('Config file not found in search path: {0}'.format(config_file)) @@ -65,9 +64,8 @@ class Powerline(object): # Load and initialize extension renderer renderer_module_name = renderer_module or ext renderer_module_import = 'powerline.renderers.{0}'.format(renderer_module_name) - renderer_class_name = '{0}Renderer'.format(underscore_to_camelcase(renderer_module_name)) try: - Renderer = getattr(__import__(renderer_module_import, fromlist=[renderer_class_name]), renderer_class_name) + Renderer = __import__(renderer_module_import, fromlist=['renderer']).renderer except ImportError as e: sys.stderr.write('Error while importing renderer module: {0}\n'.format(e)) sys.exit(1) diff --git a/powerline/lib/__init__.py b/powerline/lib/__init__.py index 549d7455..fc97407d 100644 --- a/powerline/lib/__init__.py +++ b/powerline/lib/__init__.py @@ -7,11 +7,6 @@ from powerline.lib.humanize_bytes import humanize_bytes # NOQA from powerline.lib.url import urllib_read, urllib_urlencode # NOQA -def underscore_to_camelcase(string): - '''Return a underscore_separated_string as CamelCase.''' - return ''.join(word.capitalize() or '_' for word in string.split('_')) - - def mergedicts(d1, d2): '''Recursively merge two dictionaries. First dictionary is modified in-place. ''' diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 05108d57..6267e2f9 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -604,7 +604,7 @@ def check_segment_name(name, data, context, echoerr): except AttributeError: echoerr(context='Error while loading segment function (key {key})'.format(key=context_key(context)), problem='failed to load function {0} from module {1}'.format(name, module), - problem_mark=match_name.mark) + problem_mark=name.mark) return True, False, True if not callable(func): @@ -875,7 +875,7 @@ def check(path=None): hadproblem = False try: - main_config = load_json_config(search_paths, 'config', load=load_config, open=open_file) + main_config = load_json_config(search_paths, 'config', load=load_config, open_file=open_file) except IOError: main_config = {} sys.stderr.write('\nConfiguration file not found: config.json\n') @@ -891,7 +891,7 @@ def check(path=None): import_paths = [os.path.expanduser(path) for path in main_config.get('common', {}).get('paths', [])] try: - colors_config = load_json_config(search_paths, 'colors', load=load_config, open=open_file) + colors_config = load_json_config(search_paths, 'colors', load=load_config, open_file=open_file) except IOError: colors_config = {} sys.stderr.write('\nConfiguration file not found: colors.json\n') diff --git a/powerline/lint/markedjson/reader.py b/powerline/lint/markedjson/reader.py index 47b99362..f59605ee 100644 --- a/powerline/lint/markedjson/reader.py +++ b/powerline/lint/markedjson/reader.py @@ -88,7 +88,6 @@ class Reader(object): def check_printable(self, data): match = NON_PRINTABLE.search(data) if match: - character = match.group() self.update_pointer(match.start()) raise ReaderError('while reading from stream', None, 'found special characters which are not allowed', diff --git a/powerline/renderer.py b/powerline/renderer.py index bdd995b9..a9c3a175 100644 --- a/powerline/renderer.py +++ b/powerline/renderer.py @@ -10,6 +10,13 @@ except NameError: NBSP = ' ' +def construct_returned_value(rendered_highlighted, segments, output_raw): + if output_raw: + return rendered_highlighted, ''.join((segment['_rendered_raw'] for segment in segments)) + else: + return rendered_highlighted + + class Renderer(object): def __init__(self, theme_config, local_themes, theme_kwargs, colorscheme, **options): self.__dict__.update(options) @@ -64,7 +71,7 @@ class Renderer(object): if not width: # No width specified, so we don't need to crop or pad anything - return self._returned_value(''.join([segment['_rendered_hl'] for segment in segments]) + self.hlstyle(), segments, output_raw) + return construct_returned_value(''.join([segment['_rendered_hl'] for segment in segments]) + self.hlstyle(), segments, output_raw) # Create an ordered list of segments that can be dropped segments_priority = [segment for segment in sorted(segments, key=lambda segment: segment['priority'], reverse=True) if segment['priority'] > 0] @@ -89,7 +96,7 @@ class Renderer(object): rendered_highlighted = ''.join([segment['_rendered_hl'] for segment in self._render_segments(theme, segments)]) + self.hlstyle() - return self._returned_value(rendered_highlighted, segments, output_raw) + return construct_returned_value(rendered_highlighted, segments, output_raw) def _render_segments(self, theme, segments, render_highlighted=True): '''Internal segment rendering method. @@ -166,24 +173,10 @@ class Renderer(object): segment['_len'] = self.strwidth(segment['_rendered_raw']) yield segment - @staticmethod - def _returned_value(rendered_highlighted, segments, output_raw): - if output_raw: - return rendered_highlighted, ''.join((segment['_rendered_raw'] for segment in segments)) - else: - return rendered_highlighted - @staticmethod def escape(string): return string - @staticmethod - def _int_to_rgb(int): - r = (int >> 16) & 0xff - g = (int >> 8) & 0xff - b = int & 0xff - return r, g, b - def hlstyle(fg=None, bg=None, attr=None): raise NotImplementedError diff --git a/powerline/renderers/bash_prompt.py b/powerline/renderers/bash_prompt.py index b9f911ad..01f42f74 100644 --- a/powerline/renderers/bash_prompt.py +++ b/powerline/renderers/bash_prompt.py @@ -11,3 +11,6 @@ class BashPromptRenderer(ShellRenderer): @staticmethod def escape(string): return string.replace('\\', '\\\\').replace('$', '\\$').replace('`', '\\`') + + +renderer = BashPromptRenderer diff --git a/powerline/renderers/ipython.py b/powerline/renderers/ipython.py index d1e4c7bd..2fa63acd 100644 --- a/powerline/renderers/ipython.py +++ b/powerline/renderers/ipython.py @@ -7,3 +7,6 @@ class IpythonRenderer(ShellRenderer): '''Powerline ipython segment renderer.''' escape_hl_start = '\x01' escape_hl_end = '\x02' + + +renderer = IpythonRenderer diff --git a/powerline/renderers/pango_markup.py b/powerline/renderers/pango_markup.py index 54e78868..f5e85b6a 100644 --- a/powerline/renderers/pango_markup.py +++ b/powerline/renderers/pango_markup.py @@ -29,3 +29,6 @@ class PangoMarkupRenderer(Renderer): if attr & ATTR_UNDERLINE: awesome_attr += ['underline="single"'] return '' + contents + '' + + +renderer = PangoMarkupRenderer diff --git a/powerline/renderers/shell.py b/powerline/renderers/shell.py index b2ad0197..40777c46 100644 --- a/powerline/renderers/shell.py +++ b/powerline/renderers/shell.py @@ -4,6 +4,13 @@ from powerline.renderer import Renderer from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE +def int_to_rgb(num): + r = (num >> 16) & 0xff + g = (num >> 8) & 0xff + b = num & 0xff + return r, g, b + + class ShellRenderer(Renderer): '''Powerline shell segment renderer.''' escape_hl_start = '' @@ -25,7 +32,7 @@ class ShellRenderer(Renderer): ansi += [39] else: if self.term_truecolor: - ansi += [38, 2] + list(self._int_to_rgb(fg[1])) + ansi += [38, 2] + list(int_to_rgb(fg[1])) else: ansi += [38, 5, fg[0]] if bg is not None: @@ -33,7 +40,7 @@ class ShellRenderer(Renderer): ansi += [49] else: if self.term_truecolor: - ansi += [48, 2] + list(self._int_to_rgb(bg[1])) + ansi += [48, 2] + list(int_to_rgb(bg[1])) else: ansi += [48, 5, bg[0]] if attr is not None: @@ -58,3 +65,6 @@ class ShellRenderer(Renderer): @staticmethod def escape(string): return string.replace('\\', '\\\\') + + +renderer = ShellRenderer diff --git a/powerline/renderers/tmux.py b/powerline/renderers/tmux.py index 57dd3cd8..34e4329e 100644 --- a/powerline/renderers/tmux.py +++ b/powerline/renderers/tmux.py @@ -39,3 +39,6 @@ class TmuxRenderer(Renderer): else: tmux_attr += ['nounderscore'] return '#[' + ','.join(tmux_attr) + ']' + + +renderer = TmuxRenderer diff --git a/powerline/renderers/vim.py b/powerline/renderers/vim.py index 245d7293..bec4548a 100644 --- a/powerline/renderers/vim.py +++ b/powerline/renderers/vim.py @@ -9,6 +9,7 @@ from powerline.theme import Theme import vim + vim_mode = vim_get_func('mode') vim_getwinvar = vim_get_func('getwinvar') vim_setwinvar = vim_get_func('setwinvar') @@ -132,3 +133,6 @@ class VimRenderer(Renderer): attr=','.join(hl_group['attr']), )) return '%#' + self.hl_groups[(fg, bg, attr)]['name'] + '#' + + +renderer = VimRenderer diff --git a/powerline/renderers/zsh_prompt.py b/powerline/renderers/zsh_prompt.py index f66f7359..2e6e5e77 100644 --- a/powerline/renderers/zsh_prompt.py +++ b/powerline/renderers/zsh_prompt.py @@ -11,3 +11,6 @@ class ZshPromptRenderer(ShellRenderer): @staticmethod def escape(string): return string.replace('%', '%%').replace('\\', '\\\\') + + +renderer = ZshPromptRenderer diff --git a/powerline/segments/vim.py b/powerline/segments/vim.py index 54dbad92..772d356f 100644 --- a/powerline/segments/vim.py +++ b/powerline/segments/vim.py @@ -151,16 +151,23 @@ def readonly_indicator(segment_info, text=''): @requires_segment_info -def file_directory(segment_info, shorten_home=False): +def file_directory(segment_info, shorten_user=True, shorten_cwd=True, shorten_home=False): '''Return file directory (head component of the file path). + :param bool shorten_user: + shorten ``$HOME`` directory to :file:`~/` + + :param bool shorten_cwd: + shorten current directory to :file:`./` + :param bool shorten_home: shorten all directories in :file:`/home/` to :file:`~user/` instead of :file:`/home/user/`. ''' name = segment_info['buffer'].name if not name: return None - file_directory = vim_funcs['fnamemodify'](name, ':~:.:h') + file_directory = vim_funcs['fnamemodify'](name, (':~' if shorten_user else '') + + (':.' if shorten_home else '') + ':h') if shorten_home and file_directory.startswith('/home/'): file_directory = '~' + file_directory[6:] return file_directory + os.sep if file_directory else None diff --git a/tests/test_configuration.py b/tests/test_configuration.py index 5851ec3f..bd5f9e89 100644 --- a/tests/test_configuration.py +++ b/tests/test_configuration.py @@ -57,6 +57,34 @@ class TestConfig(TestCase): from powerline.shell import ShellPowerline with replace_module_attr(common, 'urllib_read', urllib_read): ShellPowerline(Args(ext=['tmux'])).renderer.render() + reload(common) + + def test_zsh(self): + from powerline.shell import ShellPowerline + ShellPowerline(Args(last_pipe_status=[1, 0], ext=['shell'], renderer_module='zsh_prompt')).renderer.render() + + def test_bash(self): + from powerline.shell import ShellPowerline + ShellPowerline(Args(last_exit_code=1, ext=['shell'], renderer_module='bash_prompt', config=[('ext', {'shell': {'theme': 'default_leftonly'}})])).renderer.render() + + def test_ipython(self): + from powerline.ipython import IpythonPowerline + + class IpyPowerline(IpythonPowerline): + path = None + config_overrides = None + theme_overrides = {} + + IpyPowerline().renderer.render() + + def test_wm(self): + from powerline.segments import common + from imp import reload + reload(common) + from powerline import Powerline + with replace_module_attr(common, 'urllib_read', urllib_read): + Powerline(ext='wm', renderer_module='pango_markup').renderer.render() + reload(common) old_cwd = None diff --git a/tests/test_lib.py b/tests/test_lib.py index e48730d1..5b3e2192 100644 --- a/tests/test_lib.py +++ b/tests/test_lib.py @@ -1,5 +1,5 @@ # vim:fileencoding=utf-8:noet -from powerline.lib import mergedicts, underscore_to_camelcase, add_divider_highlight_group, humanize_bytes +from powerline.lib import mergedicts, add_divider_highlight_group, humanize_bytes from powerline.lib.vcs import guess from subprocess import call, PIPE import os @@ -8,10 +8,6 @@ from tests import TestCase class TestLib(TestCase): - def test_underscore_to_camelcase(self): - self.assertEqual(underscore_to_camelcase('abc_def_ghi'), 'AbcDefGhi') - self.assertEqual(underscore_to_camelcase('abc_def__ghi'), 'AbcDef_Ghi') - def test_mergedicts(self): d = {} mergedicts(d, {'abc': {'def': 'ghi'}})