diff options
Diffstat (limited to 'powerline/renderers/ipython')
-rw-r--r-- | powerline/renderers/ipython/__init__.py | 34 | ||||
-rw-r--r-- | powerline/renderers/ipython/pre_5.py | 56 | ||||
-rw-r--r-- | powerline/renderers/ipython/since_5.py | 130 | ||||
-rw-r--r-- | powerline/renderers/ipython/since_7.py | 91 |
4 files changed, 311 insertions, 0 deletions
diff --git a/powerline/renderers/ipython/__init__.py b/powerline/renderers/ipython/__init__.py new file mode 100644 index 0000000..8f463b5 --- /dev/null +++ b/powerline/renderers/ipython/__init__.py @@ -0,0 +1,34 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +from powerline.theme import Theme +from powerline.renderers.shell import PromptRenderer + + +class IPythonRenderer(PromptRenderer): + '''Powerline ipython segment renderer.''' + def get_segment_info(self, segment_info, mode): + r = self.segment_info.copy() + r['ipython'] = segment_info + return r + + def get_theme(self, matcher_info): + if matcher_info == 'in': + return self.theme + else: + match = self.local_themes[matcher_info] + try: + return match['theme'] + except KeyError: + match['theme'] = Theme( + theme_config=match['config'], + main_theme_config=self.theme_config, + **self.theme_kwargs + ) + return match['theme'] + + def shutdown(self): + self.theme.shutdown() + for match in self.local_themes.values(): + if 'theme' in match: + match['theme'].shutdown() diff --git a/powerline/renderers/ipython/pre_5.py b/powerline/renderers/ipython/pre_5.py new file mode 100644 index 0000000..9fc8c21 --- /dev/null +++ b/powerline/renderers/ipython/pre_5.py @@ -0,0 +1,56 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +from powerline.renderers.shell import ShellRenderer +from powerline.renderers.shell.readline import ReadlineRenderer +from powerline.renderers.ipython import IPythonRenderer + + +class IPythonPre50Renderer(IPythonRenderer, ShellRenderer): + '''Powerline ipython segment renderer for pre-5.0 IPython versions.''' + def render(self, **kwargs): + # XXX super(ShellRenderer), *not* super(IPythonPre50Renderer) + return super(ShellRenderer, self).render(**kwargs) + + def do_render(self, segment_info, **kwargs): + segment_info.update(client_id='ipython') + return super(IPythonPre50Renderer, self).do_render( + segment_info=segment_info, + **kwargs + ) + + +class IPythonPromptRenderer(IPythonPre50Renderer, ReadlineRenderer): + '''Powerline ipython prompt (in and in2) renderer''' + pass + + +class IPythonNonPromptRenderer(IPythonPre50Renderer): + '''Powerline ipython non-prompt (out and rewrite) renderer''' + pass + + +class RendererProxy(object): + '''Powerline IPython renderer proxy which chooses appropriate renderer + + Instantiates two renderer objects: one will be used for prompts and the + other for non-prompts. + ''' + def __init__(self, **kwargs): + old_widths = {} + self.non_prompt_renderer = IPythonNonPromptRenderer(old_widths=old_widths, **kwargs) + self.prompt_renderer = IPythonPromptRenderer(old_widths=old_widths, **kwargs) + + def render_above_lines(self, *args, **kwargs): + return self.non_prompt_renderer.render_above_lines(*args, **kwargs) + + def render(self, is_prompt, *args, **kwargs): + return (self.prompt_renderer if is_prompt else self.non_prompt_renderer).render( + *args, **kwargs) + + def shutdown(self, *args, **kwargs): + self.prompt_renderer.shutdown(*args, **kwargs) + self.non_prompt_renderer.shutdown(*args, **kwargs) + + +renderer = RendererProxy diff --git a/powerline/renderers/ipython/since_5.py b/powerline/renderers/ipython/since_5.py new file mode 100644 index 0000000..88c7625 --- /dev/null +++ b/powerline/renderers/ipython/since_5.py @@ -0,0 +1,130 @@ +# vim:fileencoding=utf-8:noet +from __future__ import (unicode_literals, division, absolute_import, print_function) + +import operator + +from collections import defaultdict + +try: + from __builtin__ import reduce +except ImportError: + from functools import reduce + +from pygments.token import Token +from prompt_toolkit.styles import DynamicStyle, Attrs + +from powerline.renderers.ipython import IPythonRenderer +from powerline.ipython import IPythonInfo +from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE + + +PowerlinePromptToken = Token.Generic.Prompt.Powerline + + +# Note: since 2.7 there is dict.__missing__ with same purpose. But in 2.6 one +# must use defaultdict to get __missing__ working. +class PowerlineStyleDict(defaultdict): + '''Dictionary used for getting pygments style for Powerline groups + ''' + def __new__(cls, missing_func): + return defaultdict.__new__(cls) + + def __init__(self, missing_func): + super(PowerlineStyleDict, self).__init__() + self.missing_func = missing_func + + def __missing__(self, key): + return self.missing_func(key) + + +class PowerlinePromptStyle(DynamicStyle): + def get_attrs_for_token(self, token): + if ( + token not in PowerlinePromptToken + or len(token) != len(PowerlinePromptToken) + 1 + or not token[-1].startswith('Pl') + or token[-1] == 'Pl' + ): + return super(PowerlinePromptStyle, self).get_attrs_for_token(token) + ret = { + 'color': None, + 'bgcolor': None, + 'bold': None, + 'underline': None, + 'italic': None, + 'reverse': False, + 'blink': False, + } + for prop in token[-1][3:].split('_'): + if prop[0] == 'a': + ret[prop[1:]] = True + elif prop[0] == 'f': + ret['color'] = prop[1:] + elif prop[0] == 'b': + ret['bgcolor'] = prop[1:] + return Attrs(**ret) + + def get_token_to_attributes_dict(self): + dct = super(PowerlinePromptStyle, self).get_token_to_attributes_dict() + + def fallback(key): + try: + return dct[key] + except KeyError: + return self.get_attrs_for_token(key) + + return PowerlineStyleDict(fallback) + + def invalidation_hash(self): + return super(PowerlinePromptStyle, self).invalidation_hash() + 1 + + +class IPythonPygmentsRenderer(IPythonRenderer): + reduce_initial = [] + + def get_segment_info(self, segment_info, mode): + return super(IPythonPygmentsRenderer, self).get_segment_info( + IPythonInfo(segment_info), mode) + + @staticmethod + def hl_join(segments): + return reduce(operator.iadd, segments, []) + + def hl(self, contents, fg=None, bg=None, attrs=None, **kwargs): + '''Output highlighted chunk. + + This implementation outputs a list containing a single pair + (:py:class:`pygments.token.Token`, + :py:class:`powerline.lib.unicode.unicode`). + ''' + guifg = None + guibg = None + attrs = [] + if fg is not None and fg is not False: + guifg = fg[1] + if bg is not None and bg is not False: + guibg = bg[1] + if attrs: + attrs = [] + if attrs & ATTR_BOLD: + attrs.append('bold') + if attrs & ATTR_ITALIC: + attrs.append('italic') + if attrs & ATTR_UNDERLINE: + attrs.append('underline') + name = ( + 'Pl' + + ''.join(('_a' + attr for attr in attrs)) + + (('_f%6x' % guifg) if guifg is not None else '') + + (('_b%6x' % guibg) if guibg is not None else '') + ) + return [(getattr(Token.Generic.Prompt.Powerline, name), contents)] + + def hlstyle(self, **kwargs): + return [] + + def get_client_id(self, segment_info): + return id(self) + + +renderer = IPythonPygmentsRenderer diff --git a/powerline/renderers/ipython/since_7.py b/powerline/renderers/ipython/since_7.py new file mode 100644 index 0000000..ca2ea0e --- /dev/null +++ b/powerline/renderers/ipython/since_7.py @@ -0,0 +1,91 @@ +# vim:fileencoding=utf-8:noet +import operator + +try: + from __builtin__ import reduce +except ImportError: + from functools import reduce + +from pygments.token import Token +from prompt_toolkit.styles import DynamicStyle + +from powerline.renderers.ipython import IPythonRenderer +from powerline.ipython import IPythonInfo +from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE + +used_styles = [] +seen = set() + +class PowerlinePromptStyle(DynamicStyle): + @property + def style_rules(self): + return (self.get_style() or self._dummy).style_rules + used_styles + + def invalidation_hash(self): + return (h + 1 for h in tuple(super(PowerlinePromptStyle, self).invalidation_hash())) + + +class IPythonPygmentsRenderer(IPythonRenderer): + reduce_initial = [] + + def __init__(self, **kwargs): + super(IPythonPygmentsRenderer, self).__init__(**kwargs) + self.character_translations[ord(' ')] = ' ' + + def get_segment_info(self, segment_info, mode): + return super(IPythonPygmentsRenderer, self).get_segment_info( + IPythonInfo(segment_info), mode) + + @staticmethod + def hl_join(segments): + return reduce(operator.iadd, segments, []) + + def hl(self, escaped_contents, fg=None, bg=None, attrs=None, *args, **kwargs): + '''Output highlighted chunk. + + This implementation outputs a list containing a single pair + (:py:class:`string`, + :py:class:`powerline.lib.unicode.unicode`). + ''' + guifg = None + guibg = None + att = [] + if fg is not None and fg is not False: + guifg = fg[1] + if bg is not None and bg is not False: + guibg = bg[1] + if attrs: + att = [] + if attrs & ATTR_BOLD: + att.append('bold') + if attrs & ATTR_ITALIC: + att.append('italic') + if attrs & ATTR_UNDERLINE: + att.append('underline') + + fg = (('%06x' % guifg) if guifg is not None else '') + bg = (('%06x' % guibg) if guibg is not None else '') + name = ( + 'pl' + + ''.join(('_a' + attr for attr in att)) + + '_f' + fg + '_b' + bg + ) + + global seen + if not (name in seen): + global used_styles + used_styles += [('pygments.' + name, + ''.join((' ' + attr for attr in att)) + + (' fg:#' + fg if fg != '' else ' fg:') + + (' bg:#' + bg if bg != '' else ' bg:'))] + seen.add(name) + return [((name,), escaped_contents)] + + def hlstyle(self, *args, **kwargs): + return [] + + def get_client_id(self, segment_info): + return id(self) + + +renderer = IPythonPygmentsRenderer |