Switch how IPython is configured
Now user is expected to use from powerline.bindings.ipython.since_5 import PowerlinePrompts c.TerminalInteractiveShell.prompts_class = PowerlinePrompts Note: still using hacks, now different ones. Main problem is that I cannot just register a powerline pygments style, user needs to specify his own style in order to change highlighting of non-powerline tokens (i.e. of everything, but prompt).
This commit is contained in:
parent
2954c83330
commit
5b16efa6ec
|
@ -2,12 +2,12 @@
|
|||
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||
|
||||
from weakref import ref
|
||||
from warnings import warn
|
||||
|
||||
try:
|
||||
from IPython.core.prompts import PromptManager
|
||||
has_prompt_manager = True
|
||||
except ImportError:
|
||||
from IPython.terminal.interactiveshell import TerminalInteractiveShell
|
||||
has_prompt_manager = False
|
||||
from IPython.core.magic import Magics, magics_class, line_magic
|
||||
|
||||
|
@ -15,8 +15,6 @@ from powerline.ipython import IPythonPowerline, IPythonInfo
|
|||
|
||||
if has_prompt_manager:
|
||||
from powerline.ipython import RewriteResult
|
||||
else:
|
||||
from powerline.renderers.ipython.since_5 import PowerlinePromptStyle, PowerlinePrompts
|
||||
|
||||
|
||||
@magics_class
|
||||
|
@ -33,6 +31,22 @@ class PowerlineMagics(Magics):
|
|||
raise ValueError('Expected `reload`, but got {0}'.format(line))
|
||||
|
||||
|
||||
old_prompt_manager = None
|
||||
|
||||
|
||||
class ShutdownHook(object):
|
||||
def __init__(self, ip):
|
||||
self.powerline = lambda: None
|
||||
ip.hooks.shutdown_hook.add(self)
|
||||
|
||||
def __call__(self):
|
||||
from IPython.core.hooks import TryNext
|
||||
powerline = self.powerline()
|
||||
if powerline is not None:
|
||||
powerline.shutdown()
|
||||
raise TryNext()
|
||||
|
||||
|
||||
if has_prompt_manager:
|
||||
class PowerlinePromptManager(PromptManager):
|
||||
def __init__(self, powerline, shell):
|
||||
|
@ -57,23 +71,6 @@ if has_prompt_manager:
|
|||
else:
|
||||
return ret
|
||||
|
||||
|
||||
class ShutdownHook(object):
|
||||
powerline = lambda: None
|
||||
|
||||
def __call__(self):
|
||||
from IPython.core.hooks import TryNext
|
||||
powerline = self.powerline()
|
||||
if powerline is not None:
|
||||
powerline.shutdown()
|
||||
raise TryNext()
|
||||
|
||||
|
||||
old_prompt_manager = None
|
||||
old_style = None
|
||||
old_prompts = None
|
||||
|
||||
|
||||
class ConfigurableIPythonPowerline(IPythonPowerline):
|
||||
def init(self, ip):
|
||||
config = ip.config.Powerline
|
||||
|
@ -87,13 +84,9 @@ class ConfigurableIPythonPowerline(IPythonPowerline):
|
|||
super(ConfigurableIPythonPowerline, self).init(
|
||||
renderer_module=renderer_module)
|
||||
|
||||
|
||||
def do_setup(self, ip, shutdown_hook):
|
||||
global old_prompt_manager
|
||||
global old_style
|
||||
global old_prompts
|
||||
|
||||
if has_prompt_manager:
|
||||
if old_prompt_manager is None:
|
||||
old_prompt_manager = ip.prompt_manager
|
||||
prompt_manager = PowerlinePromptManager(
|
||||
|
@ -101,20 +94,6 @@ class ConfigurableIPythonPowerline(IPythonPowerline):
|
|||
shell=ip.prompt_manager.shell,
|
||||
)
|
||||
ip.prompt_manager = prompt_manager
|
||||
else:
|
||||
if ip.pt_cli is not None:
|
||||
if old_style is None:
|
||||
old_style = ip.pt_cli.application.style
|
||||
prev_style = ip.pt_cli.application.style
|
||||
while isinstance(prev_style, PowerlinePromptStyle):
|
||||
prev_style = prev_style.get_style()
|
||||
new_style = PowerlinePromptStyle(lambda: prev_style)
|
||||
ip.pt_cli.application.style = new_style
|
||||
ip.pt_cli.renderer.style = new_style
|
||||
|
||||
if old_prompts is None:
|
||||
old_prompts = ip.prompts
|
||||
ip.prompts = PowerlinePrompts(ip.prompts, self)
|
||||
|
||||
magics = PowerlineMagics(ip, self)
|
||||
shutdown_hook.powerline = ref(self)
|
||||
|
@ -122,20 +101,23 @@ class ConfigurableIPythonPowerline(IPythonPowerline):
|
|||
|
||||
|
||||
def load_ipython_extension(ip):
|
||||
if has_prompt_manager:
|
||||
shutdown_hook = ShutdownHook(ip)
|
||||
powerline = ConfigurableIPythonPowerline(ip)
|
||||
shutdown_hook = ShutdownHook()
|
||||
|
||||
powerline.setup(ip, shutdown_hook)
|
||||
|
||||
ip.hooks.shutdown_hook.add(shutdown_hook)
|
||||
else:
|
||||
from powerline.bindings.ipython.since_5 import PowerlinePrompts
|
||||
ip.prompts_class = PowerlinePrompts
|
||||
ip.prompts = PowerlinePrompts(ip)
|
||||
warn(DeprecationWarning(
|
||||
'post_0_11 extension is deprecated since IPython 5, use\n'
|
||||
' from powerline.bindings.ipython.since_5 import PowerlinePrompts\n'
|
||||
' c.TerminalInteractiveShell.prompts_class = PowerlinePrompts\n'
|
||||
))
|
||||
|
||||
|
||||
def unload_ipython_extension(ip):
|
||||
global old_prompt_manager
|
||||
if old_prompt_manager is not None:
|
||||
ip.prompt_manager = old_prompt_manager
|
||||
if old_style is not None:
|
||||
ip.pt_cli.application.style = old_style
|
||||
ip.pt_cli.renderer.style = old_style
|
||||
ip.prompts = old_prompts
|
||||
old_prompt_manager = None
|
||||
old_style = None
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
# 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_5 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_5')
|
||||
|
||||
def do_setup(self, ip, prompts, shutdown_hook):
|
||||
prompts.powerline = self
|
||||
|
||||
saved_msfn = ip._make_style_from_name
|
||||
|
||||
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)
|
||||
|
||||
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))
|
|
@ -12,10 +12,10 @@ except ImportError:
|
|||
|
||||
from pygments.token import Token
|
||||
from prompt_toolkit.styles import DynamicStyle, Attrs
|
||||
from IPython.terminal.prompts import Prompts
|
||||
|
||||
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
|
||||
|
@ -30,39 +30,13 @@ class PowerlineStyleDict(defaultdict):
|
|||
return defaultdict.__new__(cls)
|
||||
|
||||
def __init__(self, missing_func):
|
||||
super(IPythonPygmentsStyle, self).__init__()
|
||||
super(PowerlineStyleDict, self).__init__()
|
||||
self.missing_func = missing_func
|
||||
|
||||
def __missing__(self, key):
|
||||
return self.missing_func(key)
|
||||
|
||||
|
||||
class PowerlinePrompts(Prompts):
|
||||
'''Class that returns powerline prompts
|
||||
'''
|
||||
def __init__(self, old_prompts, powerline):
|
||||
self.old_prompts = old_prompts
|
||||
self.shell = old_prompts.shell
|
||||
self.powerline = powerline
|
||||
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=IPythonInfo(self.shell),'
|
||||
' ) + [(Token.Generic.Prompt, " ")]\n'
|
||||
' return self.last_output["{0}"]'
|
||||
).format(prompt, 'in2' if prompt == 'continuation' else prompt))
|
||||
|
||||
|
||||
class PowerlinePromptStyle(DynamicStyle):
|
||||
def get_attrs_for_token(self, token):
|
||||
if (
|
||||
|
@ -108,6 +82,10 @@ class PowerlinePromptStyle(DynamicStyle):
|
|||
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, [])
|
||||
|
|
Loading…
Reference in New Issue