Refactor IPython bindings
- Replaced two powerline objects with one powerline object utilizing RendererProxy proxy class that holds two Renderer instances. - Made .setup() functions do something more meaningful.
This commit is contained in:
parent
b93f8d9b7b
commit
06175dcd74
|
@ -1,4 +1,7 @@
|
||||||
# vim:fileencoding=utf-8:noet
|
# vim:fileencoding=utf-8:noet
|
||||||
|
|
||||||
|
from weakref import ref
|
||||||
|
|
||||||
from powerline.ipython import IPythonPowerline, RewriteResult
|
from powerline.ipython import IPythonPowerline, RewriteResult
|
||||||
|
|
||||||
from IPython.core.prompts import PromptManager
|
from IPython.core.prompts import PromptManager
|
||||||
|
@ -15,18 +18,13 @@ class IPythonInfo(object):
|
||||||
|
|
||||||
|
|
||||||
class PowerlinePromptManager(PromptManager):
|
class PowerlinePromptManager(PromptManager):
|
||||||
def __init__(self, prompt_powerline, non_prompt_powerline, shell):
|
def __init__(self, powerline, shell):
|
||||||
prompt_powerline.setup('prompt_powerline', self)
|
|
||||||
non_prompt_powerline.setup('non_prompt_powerline', self)
|
|
||||||
self.powerline_segment_info = IPythonInfo(shell)
|
self.powerline_segment_info = IPythonInfo(shell)
|
||||||
self.shell = shell
|
self.shell = shell
|
||||||
|
|
||||||
def render(self, name, color=True, *args, **kwargs):
|
def render(self, name, color=True, *args, **kwargs):
|
||||||
if name == 'out' or name == 'rewrite':
|
res = self.powerline.render(
|
||||||
powerline = self.non_prompt_powerline
|
is_prompt=name.startswith('in'),
|
||||||
else:
|
|
||||||
powerline = self.prompt_powerline
|
|
||||||
res = powerline.render(
|
|
||||||
side='left',
|
side='left',
|
||||||
output_width=True,
|
output_width=True,
|
||||||
output_raw=not color,
|
output_raw=not color,
|
||||||
|
@ -43,12 +41,12 @@ class PowerlinePromptManager(PromptManager):
|
||||||
|
|
||||||
|
|
||||||
class ConfigurableIPythonPowerline(IPythonPowerline):
|
class ConfigurableIPythonPowerline(IPythonPowerline):
|
||||||
def init(self, ip, is_prompt, old_widths):
|
def init(self, ip):
|
||||||
config = ip.config.Powerline
|
config = ip.config.Powerline
|
||||||
self.config_overrides = config.get('config_overrides')
|
self.config_overrides = config.get('config_overrides')
|
||||||
self.theme_overrides = config.get('theme_overrides', {})
|
self.theme_overrides = config.get('theme_overrides', {})
|
||||||
self.paths = config.get('paths')
|
self.paths = config.get('paths')
|
||||||
super(ConfigurableIPythonPowerline, self).init(is_prompt, old_widths)
|
super(ConfigurableIPythonPowerline, self).init()
|
||||||
|
|
||||||
|
|
||||||
old_prompt_manager = None
|
old_prompt_manager = None
|
||||||
|
@ -58,19 +56,16 @@ def load_ipython_extension(ip):
|
||||||
global old_prompt_manager
|
global old_prompt_manager
|
||||||
|
|
||||||
old_prompt_manager = ip.prompt_manager
|
old_prompt_manager = ip.prompt_manager
|
||||||
old_widths = {}
|
powerline = ConfigurableIPythonPowerline(ip)
|
||||||
prompt_powerline = ConfigurableIPythonPowerline(ip, True, old_widths)
|
|
||||||
non_prompt_powerline = ConfigurableIPythonPowerline(ip, False, old_widths)
|
|
||||||
|
|
||||||
ip.prompt_manager = PowerlinePromptManager(
|
ip.prompt_manager = PowerlinePromptManager(
|
||||||
prompt_powerline=prompt_powerline,
|
powerline=powerline,
|
||||||
non_prompt_powerline=non_prompt_powerline,
|
shell=ip.prompt_manager.shell,
|
||||||
shell=ip.prompt_manager.shell
|
|
||||||
)
|
)
|
||||||
|
powerline.setup(ref(ip.prompt_manager))
|
||||||
|
|
||||||
def shutdown_hook():
|
def shutdown_hook():
|
||||||
prompt_powerline.shutdown()
|
powerline.shutdown()
|
||||||
non_prompt_powerline.shutdown()
|
|
||||||
raise TryNext()
|
raise TryNext()
|
||||||
|
|
||||||
ip.hooks.shutdown_hook.add(shutdown_hook)
|
ip.hooks.shutdown_hook.add(shutdown_hook)
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
# vim:fileencoding=utf-8:noet
|
# vim:fileencoding=utf-8:noet
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from weakref import ref
|
||||||
|
|
||||||
from powerline.ipython import IPythonPowerline, RewriteResult
|
from powerline.ipython import IPythonPowerline, RewriteResult
|
||||||
from powerline.lib.unicode import string
|
from powerline.lib.unicode import string
|
||||||
|
|
||||||
from IPython.Prompts import BasePrompt
|
from IPython.Prompts import BasePrompt
|
||||||
from IPython.ipapi import get as get_ipython
|
from IPython.ipapi import get as get_ipython
|
||||||
from IPython.ipapi import TryNext
|
from IPython.ipapi import TryNext
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
class IPythonInfo(object):
|
class IPythonInfo(object):
|
||||||
def __init__(self, cache):
|
def __init__(self, cache):
|
||||||
|
@ -18,9 +22,7 @@ class IPythonInfo(object):
|
||||||
|
|
||||||
|
|
||||||
class PowerlinePrompt(BasePrompt):
|
class PowerlinePrompt(BasePrompt):
|
||||||
def __init__(self, powerline, other_powerline, powerline_last_in, old_prompt):
|
def __init__(self, powerline, powerline_last_in, old_prompt):
|
||||||
powerline.setup('powerline', self)
|
|
||||||
other_powerline.setup('other_powerline', self)
|
|
||||||
self.powerline_last_in = powerline_last_in
|
self.powerline_last_in = powerline_last_in
|
||||||
self.powerline_segment_info = IPythonInfo(old_prompt.cache)
|
self.powerline_segment_info = IPythonInfo(old_prompt.cache)
|
||||||
self.cache = old_prompt.cache
|
self.cache = old_prompt.cache
|
||||||
|
@ -35,6 +37,7 @@ class PowerlinePrompt(BasePrompt):
|
||||||
def set_p_str(self):
|
def set_p_str(self):
|
||||||
self.p_str, self.p_str_nocolor, self.powerline_prompt_width = (
|
self.p_str, self.p_str_nocolor, self.powerline_prompt_width = (
|
||||||
self.powerline.render(
|
self.powerline.render(
|
||||||
|
is_prompt=self.powerline_is_prompt,
|
||||||
side='left',
|
side='left',
|
||||||
output_raw=True,
|
output_raw=True,
|
||||||
output_width=True,
|
output_width=True,
|
||||||
|
@ -50,6 +53,7 @@ class PowerlinePrompt(BasePrompt):
|
||||||
|
|
||||||
class PowerlinePrompt1(PowerlinePrompt):
|
class PowerlinePrompt1(PowerlinePrompt):
|
||||||
powerline_prompt_type = 'in'
|
powerline_prompt_type = 'in'
|
||||||
|
powerline_is_prompt = True
|
||||||
rspace = re.compile(r'(\s*)$')
|
rspace = re.compile(r'(\s*)$')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -64,7 +68,8 @@ class PowerlinePrompt1(PowerlinePrompt):
|
||||||
self.powerline_last_in['nrspaces'] = self.nrspaces
|
self.powerline_last_in['nrspaces'] = self.nrspaces
|
||||||
|
|
||||||
def auto_rewrite(self):
|
def auto_rewrite(self):
|
||||||
return RewriteResult(self.other_powerline.render(
|
return RewriteResult(self.powerline.render(
|
||||||
|
is_prompt=False,
|
||||||
side='left',
|
side='left',
|
||||||
matcher_info='rewrite',
|
matcher_info='rewrite',
|
||||||
segment_info=self.powerline_segment_info) + (' ' * self.nrspaces)
|
segment_info=self.powerline_segment_info) + (' ' * self.nrspaces)
|
||||||
|
@ -73,6 +78,7 @@ class PowerlinePrompt1(PowerlinePrompt):
|
||||||
|
|
||||||
class PowerlinePromptOut(PowerlinePrompt):
|
class PowerlinePromptOut(PowerlinePrompt):
|
||||||
powerline_prompt_type = 'out'
|
powerline_prompt_type = 'out'
|
||||||
|
powerline_is_prompt = False
|
||||||
|
|
||||||
def set_p_str(self):
|
def set_p_str(self):
|
||||||
super(PowerlinePromptOut, self).set_p_str()
|
super(PowerlinePromptOut, self).set_p_str()
|
||||||
|
@ -83,37 +89,46 @@ class PowerlinePromptOut(PowerlinePrompt):
|
||||||
|
|
||||||
class PowerlinePrompt2(PowerlinePromptOut):
|
class PowerlinePrompt2(PowerlinePromptOut):
|
||||||
powerline_prompt_type = 'in2'
|
powerline_prompt_type = 'in2'
|
||||||
|
powerline_is_prompt = True
|
||||||
|
|
||||||
|
|
||||||
class ConfigurableIPythonPowerline(IPythonPowerline):
|
class ConfigurableIPythonPowerline(IPythonPowerline):
|
||||||
def init(self, is_prompt, old_widths, config_overrides=None, theme_overrides={}, paths=None):
|
def init(self, config_overrides=None, theme_overrides={}, paths=None):
|
||||||
self.config_overrides = config_overrides
|
self.config_overrides = config_overrides
|
||||||
self.theme_overrides = theme_overrides
|
self.theme_overrides = theme_overrides
|
||||||
self.paths = paths
|
self.paths = paths
|
||||||
super(ConfigurableIPythonPowerline, self).init(is_prompt, old_widths)
|
super(ConfigurableIPythonPowerline, self).init()
|
||||||
|
|
||||||
|
def do_setup(self, wrefs):
|
||||||
|
for wref in wrefs:
|
||||||
|
obj = wref()
|
||||||
|
if obj is not None:
|
||||||
|
setattr(obj, 'powerline', self)
|
||||||
|
|
||||||
|
|
||||||
def setup(**kwargs):
|
def setup(**kwargs):
|
||||||
ip = get_ipython()
|
ip = get_ipython()
|
||||||
|
|
||||||
old_widths = {}
|
old_widths = {}
|
||||||
prompt_powerline = ConfigurableIPythonPowerline(True, old_widths, **kwargs)
|
powerline = ConfigurableIPythonPowerline(**kwargs)
|
||||||
non_prompt_powerline = ConfigurableIPythonPowerline(False, old_widths, **kwargs)
|
|
||||||
|
|
||||||
def late_startup_hook():
|
def late_startup_hook():
|
||||||
last_in = {'nrspaces': 0}
|
last_in = {'nrspaces': 0}
|
||||||
for attr, prompt_class, powerline, other_powerline in (
|
prompts = []
|
||||||
('prompt1', PowerlinePrompt1, prompt_powerline, non_prompt_powerline),
|
for attr, prompt_class in (
|
||||||
('prompt2', PowerlinePrompt2, prompt_powerline, None),
|
('prompt1', PowerlinePrompt1),
|
||||||
('prompt_out', PowerlinePromptOut, non_prompt_powerline, None)
|
('prompt2', PowerlinePrompt2),
|
||||||
|
('prompt_out', PowerlinePromptOut)
|
||||||
):
|
):
|
||||||
old_prompt = getattr(ip.IP.outputcache, attr)
|
old_prompt = getattr(ip.IP.outputcache, attr)
|
||||||
setattr(ip.IP.outputcache, attr, prompt_class(powerline, other_powerline, last_in, old_prompt))
|
prompt = prompt_class(powerline, last_in, old_prompt)
|
||||||
|
setattr(ip.IP.outputcache, attr, prompt)
|
||||||
|
prompts.append(ref(prompt))
|
||||||
|
powerline.setup(prompts)
|
||||||
raise TryNext()
|
raise TryNext()
|
||||||
|
|
||||||
def shutdown_hook():
|
def shutdown_hook():
|
||||||
prompt_powerline.shutdown()
|
powerline.shutdown()
|
||||||
non_prompt_powerline.shutdown()
|
|
||||||
raise TryNext()
|
raise TryNext()
|
||||||
|
|
||||||
ip.IP.hooks.late_startup_hook.add(late_startup_hook)
|
ip.IP.hooks.late_startup_hook.add(late_startup_hook)
|
||||||
|
|
|
@ -23,17 +23,11 @@ class RewriteResult(object):
|
||||||
|
|
||||||
|
|
||||||
class IPythonPowerline(Powerline):
|
class IPythonPowerline(Powerline):
|
||||||
def init(self, is_prompt, old_widths):
|
def init(self):
|
||||||
super(IPythonPowerline, self).init(
|
super(IPythonPowerline, self).init(
|
||||||
'ipython',
|
'ipython',
|
||||||
renderer_module=('.prompt' if is_prompt else None),
|
|
||||||
use_daemon_threads=True
|
use_daemon_threads=True
|
||||||
)
|
)
|
||||||
self.old_widths = old_widths
|
|
||||||
|
|
||||||
def create_renderer(self, *args, **kwargs):
|
|
||||||
super(IPythonPowerline, self).create_renderer(*args, **kwargs)
|
|
||||||
self.renderer.old_widths = self.old_widths
|
|
||||||
|
|
||||||
def get_config_paths(self):
|
def get_config_paths(self):
|
||||||
if self.paths:
|
if self.paths:
|
||||||
|
@ -56,5 +50,7 @@ class IPythonPowerline(Powerline):
|
||||||
mergedicts(r, self.theme_overrides[name])
|
mergedicts(r, self.theme_overrides[name])
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def do_setup(self, attr, obj):
|
def do_setup(self, wref):
|
||||||
setattr(obj, attr, self)
|
obj = wref()
|
||||||
|
if obj:
|
||||||
|
setattr(obj, 'powerline', self)
|
||||||
|
|
|
@ -37,4 +37,38 @@ class IPythonRenderer(ShellRenderer):
|
||||||
return super(ShellRenderer, self).render(*args, **kwargs)
|
return super(ShellRenderer, self).render(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
renderer = IPythonRenderer
|
class IPythonPromptRenderer(IPythonRenderer):
|
||||||
|
'''Powerline ipython prompt (in and in2) renderer'''
|
||||||
|
escape_hl_start = '\x01'
|
||||||
|
escape_hl_end = '\x02'
|
||||||
|
|
||||||
|
|
||||||
|
class IPythonNonPromptRenderer(IPythonRenderer):
|
||||||
|
'''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
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
# vim:fileencoding=utf-8:noet
|
|
||||||
|
|
||||||
from powerline.renderers.ipython import IPythonRenderer
|
|
||||||
|
|
||||||
|
|
||||||
class IPythonPromptRenderer(IPythonRenderer):
|
|
||||||
'''Powerline ipython prompt renderer'''
|
|
||||||
escape_hl_start = '\x01'
|
|
||||||
escape_hl_end = '\x02'
|
|
||||||
|
|
||||||
|
|
||||||
renderer = IPythonPromptRenderer
|
|
|
@ -24,9 +24,9 @@ class ShellRenderer(Renderer):
|
||||||
|
|
||||||
character_translations = Renderer.character_translations.copy()
|
character_translations = Renderer.character_translations.copy()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, old_widths=None, **kwargs):
|
||||||
super(ShellRenderer, self).__init__(*args, **kwargs)
|
super(ShellRenderer, self).__init__(**kwargs)
|
||||||
self.old_widths = {}
|
self.old_widths = old_widths if old_widths is not None else {}
|
||||||
|
|
||||||
def render(self, segment_info, **kwargs):
|
def render(self, segment_info, **kwargs):
|
||||||
local_theme = segment_info.get('local_theme')
|
local_theme = segment_info.get('local_theme')
|
||||||
|
|
|
@ -118,11 +118,11 @@ class TestConfig(TestCase):
|
||||||
|
|
||||||
segment_info = Args(prompt_count=1)
|
segment_info = Args(prompt_count=1)
|
||||||
|
|
||||||
with IpyPowerline(True, {}) as powerline:
|
with IpyPowerline() as powerline:
|
||||||
for prompt_type in ['in', 'in2']:
|
for prompt_type in ['in', 'in2']:
|
||||||
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
||||||
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
||||||
with IpyPowerline(False, {}) as powerline:
|
with IpyPowerline() as powerline:
|
||||||
for prompt_type in ['out', 'rewrite']:
|
for prompt_type in ['out', 'rewrite']:
|
||||||
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
||||||
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
powerline.render(matcher_info=prompt_type, segment_info=segment_info)
|
||||||
|
|
Loading…
Reference in New Issue