* ipython fix * ipython fix * ipython fix * fix ipython startup * better fix for nbsp * ipython7: fix attributes * Change ipythen tests to use new binding * ipython test: use proper config
This commit is contained in:
parent
bc33b1ce31
commit
f9ce8201c4
|
@ -0,0 +1,81 @@
|
||||||
|
# vim:fileencoding=utf-8:noet
|
||||||
|
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||||
|
|
||||||
|
from weakref import ref
|
||||||
|
|
||||||
|
from IPython.terminal.prompts import Prompts
|
||||||
|
from pygments.token import Token # NOQA
|
||||||
|
|
||||||
|
from powerline.ipython import IPythonPowerline
|
||||||
|
from powerline.renderers.ipython.since_7 import PowerlinePromptStyle
|
||||||
|
from powerline.bindings.ipython.post_0_11 import PowerlineMagics, ShutdownHook
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurableIPythonPowerline(IPythonPowerline):
|
||||||
|
def init(self, ip):
|
||||||
|
config = ip.config.Powerline
|
||||||
|
self.config_overrides = config.get('config_overrides')
|
||||||
|
self.theme_overrides = config.get('theme_overrides', {})
|
||||||
|
self.config_paths = config.get('config_paths')
|
||||||
|
super(ConfigurableIPythonPowerline, self).init(
|
||||||
|
renderer_module='.since_7')
|
||||||
|
|
||||||
|
def do_setup(self, ip, prompts, shutdown_hook):
|
||||||
|
prompts.powerline = self
|
||||||
|
|
||||||
|
msfn_missing = ()
|
||||||
|
saved_msfn = getattr(ip, '_make_style_from_name', msfn_missing)
|
||||||
|
|
||||||
|
if hasattr(saved_msfn, 'powerline_original'):
|
||||||
|
saved_msfn = saved_msfn.powerline_original
|
||||||
|
|
||||||
|
def _make_style_from_name(ip, name):
|
||||||
|
prev_style = saved_msfn(name)
|
||||||
|
new_style = PowerlinePromptStyle(lambda: prev_style)
|
||||||
|
return new_style
|
||||||
|
|
||||||
|
_make_style_from_name.powerline_original = saved_msfn
|
||||||
|
|
||||||
|
if not isinstance(ip._style, PowerlinePromptStyle):
|
||||||
|
prev_style = ip._style
|
||||||
|
ip._style = PowerlinePromptStyle(lambda: prev_style)
|
||||||
|
|
||||||
|
if not isinstance(saved_msfn, type(self.init)):
|
||||||
|
_saved_msfn = saved_msfn
|
||||||
|
saved_msfn = lambda: _saved_msfn(ip)
|
||||||
|
|
||||||
|
if saved_msfn is not msfn_missing:
|
||||||
|
ip._make_style_from_name = _make_style_from_name
|
||||||
|
|
||||||
|
magics = PowerlineMagics(ip, self)
|
||||||
|
ip.register_magics(magics)
|
||||||
|
|
||||||
|
if shutdown_hook:
|
||||||
|
shutdown_hook.powerline = ref(self)
|
||||||
|
|
||||||
|
|
||||||
|
class PowerlinePrompts(Prompts):
|
||||||
|
'''Class that returns powerline prompts
|
||||||
|
'''
|
||||||
|
def __init__(self, shell):
|
||||||
|
shutdown_hook = ShutdownHook(shell)
|
||||||
|
powerline = ConfigurableIPythonPowerline(shell)
|
||||||
|
self.shell = shell
|
||||||
|
powerline.do_setup(shell, self, shutdown_hook)
|
||||||
|
self.last_output_count = None
|
||||||
|
self.last_output = {}
|
||||||
|
|
||||||
|
for prompt in ('in', 'continuation', 'rewrite', 'out'):
|
||||||
|
exec((
|
||||||
|
'def {0}_prompt_tokens(self, *args, **kwargs):\n'
|
||||||
|
' if self.last_output_count != self.shell.execution_count:\n'
|
||||||
|
' self.last_output.clear()\n'
|
||||||
|
' self.last_output_count = self.shell.execution_count\n'
|
||||||
|
' if "{0}" not in self.last_output:\n'
|
||||||
|
' self.last_output["{0}"] = self.powerline.render('
|
||||||
|
' side="left",'
|
||||||
|
' matcher_info="{1}",'
|
||||||
|
' segment_info=self.shell,'
|
||||||
|
' ) + [(Token.Generic.Prompt, " ")]\n'
|
||||||
|
' return self.last_output["{0}"]'
|
||||||
|
).format(prompt, 'in2' if prompt == 'continuation' else prompt))
|
|
@ -21,25 +21,25 @@ np_control_character_translations = dict((
|
||||||
))
|
))
|
||||||
'''Control character translations
|
'''Control character translations
|
||||||
|
|
||||||
Dictionary that maps characters in range 0x00–0x1F (inclusive) to strings
|
Dictionary that maps characters in range 0x00–0x1F (inclusive) to strings
|
||||||
``'^@'``, ``'^A'`` and so on.
|
``'^@'``, ``'^A'`` and so on.
|
||||||
|
|
||||||
.. note: maps tab to ``^I`` and newline to ``^J``.
|
.. note: maps tab to ``^I`` and newline to ``^J``.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
np_invalid_character_translations = dict((
|
np_invalid_character_translations = dict((
|
||||||
# Invalid unicode characters obtained using 'surrogateescape' error
|
# Invalid unicode characters obtained using 'surrogateescape' error
|
||||||
# handler.
|
# handler.
|
||||||
(i2, '<{0:02x}>'.format(i2 - 0xDC00)) for i2 in range(0xDC80, 0xDD00)
|
(i2, '<{0:02x}>'.format(i2 - 0xDC00)) for i2 in range(0xDC80, 0xDD00)
|
||||||
))
|
))
|
||||||
'''Invalid unicode character translations
|
'''Invalid unicode character translations
|
||||||
|
|
||||||
When using ``surrogateescape`` encoding error handling method characters in
|
When using ``surrogateescape`` encoding error handling method characters in
|
||||||
range 0x80–0xFF (inclusive) are transformed into unpaired surrogate escape
|
range 0x80–0xFF (inclusive) are transformed into unpaired surrogate escape
|
||||||
unicode codepoints 0xDC80–0xDD00. This dictionary maps such characters to
|
unicode codepoints 0xDC80–0xDD00. This dictionary maps such characters to
|
||||||
``<80>``, ``<81>``, and so on: in Python-3 they cannot be printed or
|
``<80>``, ``<81>``, and so on: in Python-3 they cannot be printed or
|
||||||
converted to UTF-8 because UTF-8 standard does not allow surrogate escape
|
converted to UTF-8 because UTF-8 standard does not allow surrogate escape
|
||||||
characters, not even paired ones. Python-2 contains a bug that allows such
|
characters, not even paired ones. Python-2 contains a bug that allows such
|
||||||
action, but printing them in any case makes no sense.
|
action, but printing them in any case makes no sense.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -47,20 +47,20 @@ action, but printing them in any case makes no sense.
|
||||||
np_invalid_character_re = re.compile('(?<![\uD800-\uDBFF])[\uDC80-\uDD00]')
|
np_invalid_character_re = re.compile('(?<![\uD800-\uDBFF])[\uDC80-\uDD00]')
|
||||||
'''Regex that finds unpaired surrogate escape characters
|
'''Regex that finds unpaired surrogate escape characters
|
||||||
|
|
||||||
Search is only limited to the ones obtained from ``surrogateescape`` error
|
Search is only limited to the ones obtained from ``surrogateescape`` error
|
||||||
handling method. This regex is only used for UCS-2 Python variants because
|
handling method. This regex is only used for UCS-2 Python variants because
|
||||||
in this case characters above 0xFFFF are represented as surrogate escapes
|
in this case characters above 0xFFFF are represented as surrogate escapes
|
||||||
characters and are thus subject to partial transformation if
|
characters and are thus subject to partial transformation if
|
||||||
``np_invalid_character_translations`` translation table is used.
|
``np_invalid_character_translations`` translation table is used.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
np_character_translations = np_control_character_translations.copy()
|
np_character_translations = np_control_character_translations.copy()
|
||||||
'''Dictionary that contains non-printable character translations
|
'''Dictionary that contains non-printable character translations
|
||||||
|
|
||||||
In UCS-4 versions of Python this is a union of
|
In UCS-4 versions of Python this is a union of
|
||||||
``np_invalid_character_translations`` and ``np_control_character_translations``
|
``np_invalid_character_translations`` and ``np_control_character_translations``
|
||||||
dictionaries. In UCS-2 for technical reasons ``np_invalid_character_re`` is used
|
dictionaries. In UCS-2 for technical reasons ``np_invalid_character_re`` is used
|
||||||
instead and this dictionary only contains items from
|
instead and this dictionary only contains items from
|
||||||
``np_control_character_translations``.
|
``np_control_character_translations``.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -81,10 +81,10 @@ translate_np = (
|
||||||
)
|
)
|
||||||
'''Function that translates non-printable characters into printable strings
|
'''Function that translates non-printable characters into printable strings
|
||||||
|
|
||||||
Is used to translate control characters and surrogate escape characters
|
Is used to translate control characters and surrogate escape characters
|
||||||
obtained from ``surrogateescape`` encoding errors handling method into some
|
obtained from ``surrogateescape`` encoding errors handling method into some
|
||||||
printable sequences. See documentation for
|
printable sequences. See documentation for
|
||||||
``np_invalid_character_translations`` and
|
``np_invalid_character_translations`` and
|
||||||
``np_control_character_translations`` for more details.
|
``np_control_character_translations`` for more details.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -106,17 +106,17 @@ class Renderer(object):
|
||||||
:param dict theme_config:
|
:param dict theme_config:
|
||||||
Main theme configuration.
|
Main theme configuration.
|
||||||
:param local_themes:
|
:param local_themes:
|
||||||
Local themes. Is to be used by subclasses from ``.get_theme()`` method,
|
Local themes. Is to be used by subclasses from ``.get_theme()`` method,
|
||||||
base class only records this parameter to a ``.local_themes`` attribute.
|
base class only records this parameter to a ``.local_themes`` attribute.
|
||||||
:param dict theme_kwargs:
|
:param dict theme_kwargs:
|
||||||
Keyword arguments for ``Theme`` class constructor.
|
Keyword arguments for ``Theme`` class constructor.
|
||||||
:param PowerlineLogger pl:
|
:param PowerlineLogger pl:
|
||||||
Object used for logging.
|
Object used for logging.
|
||||||
:param int ambiwidth:
|
:param int ambiwidth:
|
||||||
Width of the characters with east asian width unicode attribute equal to
|
Width of the characters with east asian width unicode attribute equal to
|
||||||
``A`` (Ambigious).
|
``A`` (Ambigious).
|
||||||
:param dict options:
|
:param dict options:
|
||||||
Various options. Are normally not used by base renderer, but all options
|
Various options. Are normally not used by base renderer, but all options
|
||||||
are recorded as attributes.
|
are recorded as attributes.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -127,23 +127,23 @@ class Renderer(object):
|
||||||
}
|
}
|
||||||
'''Basic segment info
|
'''Basic segment info
|
||||||
|
|
||||||
Is merged with local segment information by :py:meth:`get_segment_info`
|
Is merged with local segment information by :py:meth:`get_segment_info`
|
||||||
method. Keys:
|
method. Keys:
|
||||||
|
|
||||||
``environ``
|
``environ``
|
||||||
Object containing environment variables. Must define at least the
|
Object containing environment variables. Must define at least the
|
||||||
following methods: ``.__getitem__(var)`` that raises ``KeyError`` in
|
following methods: ``.__getitem__(var)`` that raises ``KeyError`` in
|
||||||
case requested environment variable is not present, ``.get(var,
|
case requested environment variable is not present, ``.get(var,
|
||||||
default=None)`` that works like ``dict.get`` and be able to be passed to
|
default=None)`` that works like ``dict.get`` and be able to be passed to
|
||||||
``Popen``.
|
``Popen``.
|
||||||
|
|
||||||
``getcwd``
|
``getcwd``
|
||||||
Function that returns current working directory. Will be called without
|
Function that returns current working directory. Will be called without
|
||||||
any arguments, should return ``unicode`` or (in python-2) regular
|
any arguments, should return ``unicode`` or (in python-2) regular
|
||||||
string.
|
string.
|
||||||
|
|
||||||
``home``
|
``home``
|
||||||
String containing path to home directory. Should be ``unicode`` or (in
|
String containing path to home directory. Should be ``unicode`` or (in
|
||||||
python-2) regular string or ``None``.
|
python-2) regular string or ``None``.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -185,8 +185,8 @@ class Renderer(object):
|
||||||
)
|
)
|
||||||
'''Function that returns string width.
|
'''Function that returns string width.
|
||||||
|
|
||||||
Is used to calculate the place given string occupies when handling
|
Is used to calculate the place given string occupies when handling
|
||||||
``width`` argument to ``.render()`` method. Must take east asian width
|
``width`` argument to ``.render()`` method. Must take east asian width
|
||||||
into account.
|
into account.
|
||||||
|
|
||||||
:param unicode string:
|
:param unicode string:
|
||||||
|
@ -198,18 +198,18 @@ class Renderer(object):
|
||||||
def get_theme(self, matcher_info):
|
def get_theme(self, matcher_info):
|
||||||
'''Get Theme object.
|
'''Get Theme object.
|
||||||
|
|
||||||
Is to be overridden by subclasses to support local themes, this variant
|
Is to be overridden by subclasses to support local themes, this variant
|
||||||
only returns ``.theme`` attribute.
|
only returns ``.theme`` attribute.
|
||||||
|
|
||||||
:param matcher_info:
|
:param matcher_info:
|
||||||
Parameter ``matcher_info`` that ``.render()`` method received.
|
Parameter ``matcher_info`` that ``.render()`` method received.
|
||||||
Unused.
|
Unused.
|
||||||
'''
|
'''
|
||||||
return self.theme
|
return self.theme
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
'''Prepare for interpreter shutdown. The only job it is supposed to do
|
'''Prepare for interpreter shutdown. The only job it is supposed to do
|
||||||
is calling ``.shutdown()`` method for all theme objects. Should be
|
is calling ``.shutdown()`` method for all theme objects. Should be
|
||||||
overridden by subclasses in case they support local themes.
|
overridden by subclasses in case they support local themes.
|
||||||
'''
|
'''
|
||||||
self.theme.shutdown()
|
self.theme.shutdown()
|
||||||
|
@ -217,12 +217,12 @@ class Renderer(object):
|
||||||
def get_segment_info(self, segment_info, mode):
|
def get_segment_info(self, segment_info, mode):
|
||||||
'''Get segment information.
|
'''Get segment information.
|
||||||
|
|
||||||
Must return a dictionary containing at least ``home``, ``environ`` and
|
Must return a dictionary containing at least ``home``, ``environ`` and
|
||||||
``getcwd`` keys (see documentation for ``segment_info`` attribute). This
|
``getcwd`` keys (see documentation for ``segment_info`` attribute). This
|
||||||
implementation merges ``segment_info`` dictionary passed to
|
implementation merges ``segment_info`` dictionary passed to
|
||||||
``.render()`` method with ``.segment_info`` attribute, preferring keys
|
``.render()`` method with ``.segment_info`` attribute, preferring keys
|
||||||
from the former. It also replaces ``getcwd`` key with function returning
|
from the former. It also replaces ``getcwd`` key with function returning
|
||||||
``segment_info['environ']['PWD']`` in case ``PWD`` variable is
|
``segment_info['environ']['PWD']`` in case ``PWD`` variable is
|
||||||
available.
|
available.
|
||||||
|
|
||||||
:param dict segment_info:
|
:param dict segment_info:
|
||||||
|
@ -241,7 +241,7 @@ class Renderer(object):
|
||||||
def render_above_lines(self, **kwargs):
|
def render_above_lines(self, **kwargs):
|
||||||
'''Render all segments in the {theme}/segments/above list
|
'''Render all segments in the {theme}/segments/above list
|
||||||
|
|
||||||
Rendering happens in the reversed order. Parameters are the same as in
|
Rendering happens in the reversed order. Parameters are the same as in
|
||||||
.render() method.
|
.render() method.
|
||||||
|
|
||||||
:yield: rendered line.
|
:yield: rendered line.
|
||||||
|
@ -254,37 +254,37 @@ class Renderer(object):
|
||||||
def render(self, mode=None, width=None, side=None, line=0, output_raw=False, output_width=False, segment_info=None, matcher_info=None):
|
def render(self, mode=None, width=None, side=None, line=0, output_raw=False, output_width=False, segment_info=None, matcher_info=None):
|
||||||
'''Render all segments.
|
'''Render all segments.
|
||||||
|
|
||||||
When a width is provided, low-priority segments are dropped one at
|
When a width is provided, low-priority segments are dropped one at
|
||||||
a time until the line is shorter than the width, or only segments
|
a time until the line is shorter than the width, or only segments
|
||||||
with a negative priority are left. If one or more segments with
|
with a negative priority are left. If one or more segments with
|
||||||
``"width": "auto"`` are provided they will fill the remaining space
|
``"width": "auto"`` are provided they will fill the remaining space
|
||||||
until the desired width is reached.
|
until the desired width is reached.
|
||||||
|
|
||||||
:param str mode:
|
:param str mode:
|
||||||
Mode string. Affects contents (colors and the set of segments) of
|
Mode string. Affects contents (colors and the set of segments) of
|
||||||
rendered string.
|
rendered string.
|
||||||
:param int width:
|
:param int width:
|
||||||
Maximum width text can occupy. May be exceeded if there are too much
|
Maximum width text can occupy. May be exceeded if there are too much
|
||||||
non-removable segments.
|
non-removable segments.
|
||||||
:param str side:
|
:param str side:
|
||||||
One of ``left``, ``right``. Determines which side will be rendered.
|
One of ``left``, ``right``. Determines which side will be rendered.
|
||||||
If not present all sides are rendered.
|
If not present all sides are rendered.
|
||||||
:param int line:
|
:param int line:
|
||||||
Line number for which segments should be obtained. Is counted from
|
Line number for which segments should be obtained. Is counted from
|
||||||
zero (botmost line).
|
zero (botmost line).
|
||||||
:param bool output_raw:
|
:param bool output_raw:
|
||||||
Changes the output: if this parameter is ``True`` then in place of
|
Changes the output: if this parameter is ``True`` then in place of
|
||||||
one string this method outputs a pair ``(colored_string,
|
one string this method outputs a pair ``(colored_string,
|
||||||
colorless_string)``.
|
colorless_string)``.
|
||||||
:param bool output_width:
|
:param bool output_width:
|
||||||
Changes the output: if this parameter is ``True`` then in place of
|
Changes the output: if this parameter is ``True`` then in place of
|
||||||
one string this method outputs a pair ``(colored_string,
|
one string this method outputs a pair ``(colored_string,
|
||||||
string_width)``. Returns a three-tuple if ``output_raw`` is also
|
string_width)``. Returns a three-tuple if ``output_raw`` is also
|
||||||
``True``: ``(colored_string, colorless_string, string_width)``.
|
``True``: ``(colored_string, colorless_string, string_width)``.
|
||||||
:param dict segment_info:
|
:param dict segment_info:
|
||||||
Segment information. See also :py:meth:`get_segment_info` method.
|
Segment information. See also :py:meth:`get_segment_info` method.
|
||||||
:param matcher_info:
|
:param matcher_info:
|
||||||
Matcher information. Is processed in :py:meth:`get_segment_info`
|
Matcher information. Is processed in :py:meth:`get_segment_info`
|
||||||
method.
|
method.
|
||||||
'''
|
'''
|
||||||
theme = self.get_theme(matcher_info)
|
theme = self.get_theme(matcher_info)
|
||||||
|
@ -314,11 +314,11 @@ class Renderer(object):
|
||||||
hl_join = staticmethod(''.join)
|
hl_join = staticmethod(''.join)
|
||||||
'''Join a list of rendered segments into a resulting string
|
'''Join a list of rendered segments into a resulting string
|
||||||
|
|
||||||
This method exists to deal with non-string render outputs, so `segments`
|
This method exists to deal with non-string render outputs, so `segments`
|
||||||
may actually be not an iterable with strings.
|
may actually be not an iterable with strings.
|
||||||
|
|
||||||
:param list segments:
|
:param list segments:
|
||||||
Iterable containing rendered segments. By “rendered segments”
|
Iterable containing rendered segments. By “rendered segments”
|
||||||
:py:meth:`Renderer.hl` output is meant.
|
:py:meth:`Renderer.hl` output is meant.
|
||||||
|
|
||||||
:return: Results of joining these segments.
|
:return: Results of joining these segments.
|
||||||
|
@ -355,7 +355,7 @@ class Renderer(object):
|
||||||
|
|
||||||
segments_priority = iter(segments_priority)
|
segments_priority = iter(segments_priority)
|
||||||
if current_width > width and len(segments) > 100:
|
if current_width > width and len(segments) > 100:
|
||||||
# When there are too many segments use faster, but less correct
|
# When there are too many segments use faster, but less correct
|
||||||
# algorythm for width computation
|
# algorythm for width computation
|
||||||
diff = current_width - width
|
diff = current_width - width
|
||||||
for segment in segments_priority:
|
for segment in segments_priority:
|
||||||
|
@ -365,8 +365,8 @@ class Renderer(object):
|
||||||
break
|
break
|
||||||
current_width = self._render_length(theme, segments, divider_widths)
|
current_width = self._render_length(theme, segments, divider_widths)
|
||||||
if current_width > width:
|
if current_width > width:
|
||||||
# When there are not too much use more precise, but much slower
|
# When there are not too much use more precise, but much slower
|
||||||
# width computation. It also finishes computations in case
|
# width computation. It also finishes computations in case
|
||||||
# previous variant did not free enough space.
|
# previous variant did not free enough space.
|
||||||
for segment in segments_priority:
|
for segment in segments_priority:
|
||||||
segments.remove(segment)
|
segments.remove(segment)
|
||||||
|
@ -386,7 +386,7 @@ class Renderer(object):
|
||||||
distribute_len + (1 if distribute_len_remainder > 0 else 0),
|
distribute_len + (1 if distribute_len_remainder > 0 else 0),
|
||||||
segment))
|
segment))
|
||||||
distribute_len_remainder -= 1
|
distribute_len_remainder -= 1
|
||||||
# `_len` key is not needed anymore, but current_width should have an
|
# `_len` key is not needed anymore, but current_width should have an
|
||||||
# actual value for various bindings.
|
# actual value for various bindings.
|
||||||
current_width = width
|
current_width = width
|
||||||
elif output_width:
|
elif output_width:
|
||||||
|
@ -527,7 +527,7 @@ class Renderer(object):
|
||||||
contents_highlighted = ''
|
contents_highlighted = ''
|
||||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||||
|
|
||||||
# XXX Make sure self.hl() calls are called in the same order
|
# XXX Make sure self.hl() calls are called in the same order
|
||||||
# segments are displayed. This is needed for Vim renderer to work.
|
# segments are displayed. This is needed for Vim renderer to work.
|
||||||
if draw_divider:
|
if draw_divider:
|
||||||
divider_raw = self.escape(theme.get_divider(side, divider_type))
|
divider_raw = self.escape(theme.get_divider(side, divider_type))
|
||||||
|
@ -579,8 +579,8 @@ class Renderer(object):
|
||||||
def hlstyle(fg=None, bg=None, attrs=None):
|
def hlstyle(fg=None, bg=None, attrs=None):
|
||||||
'''Output highlight style string.
|
'''Output highlight style string.
|
||||||
|
|
||||||
Assuming highlighted string looks like ``{style}{contents}`` this method
|
Assuming highlighted string looks like ``{style}{contents}`` this method
|
||||||
should output ``{style}``. If it is called without arguments this method
|
should output ``{style}``. If it is called without arguments this method
|
||||||
is supposed to reset style to its default.
|
is supposed to reset style to its default.
|
||||||
'''
|
'''
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -588,7 +588,7 @@ class Renderer(object):
|
||||||
def hl(self, contents, fg=None, bg=None, attrs=None):
|
def hl(self, contents, fg=None, bg=None, attrs=None):
|
||||||
'''Output highlighted chunk.
|
'''Output highlighted chunk.
|
||||||
|
|
||||||
This implementation just outputs :py:meth:`hlstyle` joined with
|
This implementation just outputs :py:meth:`hlstyle` joined with
|
||||||
``contents``.
|
``contents``.
|
||||||
'''
|
'''
|
||||||
return self.hlstyle(fg, bg, attrs) + (contents or '')
|
return self.hlstyle(fg, bg, attrs) + (contents or '')
|
||||||
|
|
|
@ -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
|
8
setup.py
8
setup.py
|
@ -95,11 +95,11 @@ setup(
|
||||||
author_email='kim.silkebaekken+vim@gmail.com',
|
author_email='kim.silkebaekken+vim@gmail.com',
|
||||||
url='https://github.com/powerline/powerline',
|
url='https://github.com/powerline/powerline',
|
||||||
license='MIT',
|
license='MIT',
|
||||||
# XXX Python 3 doesn’t allow compiled C files to be included in the scripts
|
# XXX Python 3 doesn’t allow compiled C files to be included in the scripts
|
||||||
# list below. This is because Python 3 distutils tries to decode the file to
|
# list below. This is because Python 3 distutils tries to decode the file to
|
||||||
# ASCII, and fails when powerline-client is a binary.
|
# ASCII, and fails when powerline-client is a binary.
|
||||||
#
|
#
|
||||||
# XXX Python 2 fucks up script contents*. Not using it to install scripts
|
# XXX Python 2 fucks up script contents*. Not using it to install scripts
|
||||||
# any longer.
|
# any longer.
|
||||||
# * Consider the following input:
|
# * Consider the following input:
|
||||||
# % alias hex1=$'hexdump -e \'"" 1/1 "%02X\n"\''
|
# % alias hex1=$'hexdump -e \'"" 1/1 "%02X\n"\''
|
||||||
|
@ -111,7 +111,7 @@ setup(
|
||||||
# > 0A
|
# > 0A
|
||||||
# (repeated, with diff segment header numbers growing up).
|
# (repeated, with diff segment header numbers growing up).
|
||||||
#
|
#
|
||||||
# FIXME Current solution does not work with `pip install -e`. Still better
|
# FIXME Current solution does not work with `pip install -e`. Still better
|
||||||
# then solution that is not working at all.
|
# then solution that is not working at all.
|
||||||
scripts=[
|
scripts=[
|
||||||
'scripts/powerline-lint',
|
'scripts/powerline-lint',
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
from powerline.bindings.ipython.since_7 import PowerlinePrompts
|
||||||
import os
|
import os
|
||||||
c = get_config()
|
c = get_config()
|
||||||
c.InteractiveShellApp.extensions = ['powerline.bindings.ipython.post_0_11']
|
c.TerminalInteractiveShell.simple_prompt = False
|
||||||
|
c.TerminalIPythonApp.display_banner = False
|
||||||
|
c.TerminalInteractiveShell.prompts_class = PowerlinePrompts
|
||||||
c.TerminalInteractiveShell.autocall = 1
|
c.TerminalInteractiveShell.autocall = 1
|
||||||
c.Powerline.config_paths = [os.path.abspath('powerline/config_files')]
|
c.Powerline.config_paths = [os.path.abspath('powerline/config_files')]
|
||||||
c.Powerline.theme_overrides = {
|
c.Powerline.theme_overrides = {
|
||||||
|
|
Loading…
Reference in New Issue