summaryrefslogtreecommitdiffstats
path: root/powerline/renderers/ipython
diff options
context:
space:
mode:
Diffstat (limited to 'powerline/renderers/ipython')
-rw-r--r--powerline/renderers/ipython/__init__.py34
-rw-r--r--powerline/renderers/ipython/pre_5.py56
-rw-r--r--powerline/renderers/ipython/since_5.py130
-rw-r--r--powerline/renderers/ipython/since_7.py91
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