Add cursor_space and cursor_columns configuration options

Fixes #815
This commit is contained in:
ZyX 2014-08-10 20:24:02 +04:00
parent c97ab8055a
commit 547306e746
11 changed files with 93 additions and 44 deletions

View File

@ -283,6 +283,16 @@ ascii Theme without any unicode characters at all
background colors, while the ``soft`` dividers are used to divide
segments with the same background color.
.. _config-themes-cursor_space:
``cursor_space``
Space reserved for user input in shell bindings. It is measured in per
cents.
``cursor_columns``
Space reserved for user input in shell bindings. Unlike :ref:`cursor_space
<config-themes-cursor_space>` it is measured in absolute amout of columns.
.. _config-themes-segment_data:
``segment_data``

View File

@ -42,7 +42,7 @@ _powerline_init_tmux_support() {
_powerline_prompt() {
# Arguments: side, last_exit_code, jobnum
$POWERLINE_COMMAND shell $1 \
-w "${COLUMNS:-$(_powerline_columns_fallback)}" \
--width="${COLUMNS:-$(_powerline_columns_fallback)}" \
-r bash_prompt \
--last_exit_code=$2 \
--jobnum=$3 \

View File

@ -22,15 +22,14 @@ class PowerlinePromptManager(PromptManager):
self.shell = shell
def render(self, name, color=True, *args, **kwargs):
width = None if name == 'in' else self.width
if name == 'out' or name == 'rewrite':
powerline = self.non_prompt_powerline
else:
powerline = self.prompt_powerline
res = powerline.render(
side='left',
output_width=True,
output_raw=not color,
width=width,
matcher_info=name,
segment_info=self.powerline_segment_info,
)
@ -44,12 +43,12 @@ class PowerlinePromptManager(PromptManager):
class ConfigurableIpythonPowerline(IpythonPowerline):
def __init__(self, ip, is_prompt):
def __init__(self, ip, is_prompt, old_widths):
config = ip.config.Powerline
self.config_overrides = config.get('config_overrides')
self.theme_overrides = config.get('theme_overrides', {})
self.paths = config.get('paths')
super(ConfigurableIpythonPowerline, self).__init__(is_prompt)
super(ConfigurableIpythonPowerline, self).__init__(is_prompt, old_widths)
old_prompt_manager = None
@ -59,8 +58,9 @@ def load_ipython_extension(ip):
global old_prompt_manager
old_prompt_manager = ip.prompt_manager
prompt_powerline = ConfigurableIpythonPowerline(ip, True)
non_prompt_powerline = ConfigurableIpythonPowerline(ip, False)
old_widths = {}
prompt_powerline = ConfigurableIpythonPowerline(ip, True, old_widths)
non_prompt_powerline = ConfigurableIpythonPowerline(ip, False, old_widths)
ip.prompt_manager = PowerlinePromptManager(
prompt_powerline=prompt_powerline,

View File

@ -32,14 +32,14 @@ class PowerlinePrompt(BasePrompt):
self.set_p_str()
return string(self.p_str)
def set_p_str(self, width=None):
def set_p_str(self):
self.p_str, self.p_str_nocolor, self.powerline_prompt_width = (
self.powerline.render(
side='left',
output_raw=True,
output_width=True,
segment_info=self.powerline_segment_info,
matcher_info=self.powerline_prompt_type,
width=width
)
)
@ -61,20 +61,21 @@ class PowerlinePrompt1(PowerlinePrompt):
def set_p_str(self):
super(PowerlinePrompt1, self).set_p_str()
self.nrspaces = len(self.rspace.search(self.p_str_nocolor).group())
self.prompt_text_len = self.powerline_prompt_width - self.nrspaces
self.powerline_last_in['nrspaces'] = self.nrspaces
self.powerline_last_in['prompt_text_len'] = self.prompt_text_len
def auto_rewrite(self):
return RewriteResult(self.other_powerline.render(matcher_info='rewrite', width=self.prompt_text_len, segment_info=self.powerline_segment_info)
+ (' ' * self.nrspaces))
return RewriteResult(self.other_powerline.render(
side='left',
matcher_info='rewrite',
segment_info=self.powerline_segment_info) + (' ' * self.nrspaces)
)
class PowerlinePromptOut(PowerlinePrompt):
powerline_prompt_type = 'out'
def set_p_str(self):
super(PowerlinePromptOut, self).set_p_str(width=self.powerline_last_in['prompt_text_len'])
super(PowerlinePromptOut, self).set_p_str()
spaces = ' ' * self.powerline_last_in['nrspaces']
self.p_str += spaces
self.p_str_nocolor += spaces
@ -85,21 +86,22 @@ class PowerlinePrompt2(PowerlinePromptOut):
class ConfigurableIpythonPowerline(IpythonPowerline):
def __init__(self, is_prompt, config_overrides=None, theme_overrides={}, paths=None):
def __init__(self, is_prompt, old_widths, config_overrides=None, theme_overrides={}, paths=None):
self.config_overrides = config_overrides
self.theme_overrides = theme_overrides
self.paths = paths
super(ConfigurableIpythonPowerline, self).__init__(is_prompt)
super(ConfigurableIpythonPowerline, self).__init__(is_prompt, old_widths)
def setup(**kwargs):
ip = get_ipython()
prompt_powerline = ConfigurableIpythonPowerline(True, **kwargs)
non_prompt_powerline = ConfigurableIpythonPowerline(False, **kwargs)
old_widths = {}
prompt_powerline = ConfigurableIpythonPowerline(True, old_widths, **kwargs)
non_prompt_powerline = ConfigurableIpythonPowerline(False, old_widths, **kwargs)
def late_startup_hook():
last_in = {'nrspaces': 0, 'prompt_text_len': None}
last_in = {'nrspaces': 0}
for attr, prompt_class, powerline, other_powerline in (
('prompt1', PowerlinePrompt1, prompt_powerline, non_prompt_powerline),
('prompt2', PowerlinePrompt2, prompt_powerline, None),

View File

@ -135,7 +135,7 @@ _powerline_prompt() {
# Arguments: side, exit_code
_powerline_set_jobs
$POWERLINE_COMMAND shell $1 \
-w "${COLUMNS:-$(_powerline_columns_fallback)}" \
--width="${COLUMNS:-$(_powerline_columns_fallback)}" \
$_POWERLINE_RENDERER_ARG \
--renderer_arg="client_id=$$" \
--last_exit_code=$2 \

View File

@ -133,9 +133,9 @@ _powerline_setup_prompt() {
add_args+=' --last_pipe_status="$pipestatus"'
add_args+=' --renderer_arg="client_id=$$"'
add_args+=' --jobnum=$_POWERLINE_JOBNUM'
local new_args_2=' -R parser_state=${(%%):-%_}'
new_args_2+=' -R local_theme=continuation'
local add_args_3=$add_args' -R local_theme=select'
local new_args_2=' --renderer_arg="parser_state=${(%%):-%_}"'
new_args_2+=' --renderer_arg="local_theme=continuation"'
local add_args_3=$add_args' --renderer_arg="local_theme=select"'
local add_args_2=$add_args$new_args_2
add_args+=' --width=$(( ${COLUMNS:-$(_powerline_columns_fallback)} - 1 ))'
local add_args_r2=$add_args$new_args_2

View File

@ -23,12 +23,17 @@ class RewriteResult(object):
class IpythonPowerline(Powerline):
def __init__(self, is_prompt):
def __init__(self, is_prompt, old_widths):
super(IpythonPowerline, self).__init__(
'ipython',
renderer_module=('ipython_prompt' if is_prompt else 'ipython'),
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):
if self.paths:

View File

@ -1279,6 +1279,8 @@ spaces_spec = Spec().unsigned().cmp(
).copy
common_theme_spec = Spec(
default_module=segment_module_spec().optional(),
cursor_space=Spec().type(int, float).cmp('le', 100).cmp('gt', 0).optional(),
cursor_columns=Spec().type(int).cmp('gt', 0).optional(),
).context_message('Error while loading theme').copy
top_theme_spec = common_theme_spec().update(
dividers=dividers_spec(),

View File

@ -1,6 +1,6 @@
# vim:fileencoding=utf-8:noet
from __future__ import absolute_import, unicode_literals
from __future__ import absolute_import, unicode_literals, division, print_function
from powerline.renderer import Renderer
from powerline.colorscheme import ATTR_BOLD, ATTR_ITALIC, ATTR_UNDERLINE
@ -27,31 +27,55 @@ class ShellRenderer(Renderer):
super(ShellRenderer, self).__init__(*args, **kwargs)
self.old_widths = {}
def render(self, segment_info, *args, **kwargs):
client_id = segment_info.get('client_id')
key = (client_id, kwargs.get('side'))
kwargs = kwargs.copy()
width = kwargs.pop('width', None)
def render(self, segment_info, **kwargs):
local_theme = segment_info.get('local_theme')
if client_id and local_theme:
output_width = False
return super(ShellRenderer, self).render(
matcher_info=local_theme,
segment_info=segment_info,
**kwargs
)
def do_render(self, output_width, segment_info, side, theme, width=None, **kwargs):
if isinstance(segment_info, dict):
client_id = segment_info.get('client_id')
else:
client_id = None
local_key = (client_id, side, None if theme is self.theme else id(theme))
key = (client_id, side, None)
did_width = False
if local_key[-1] != key[-1] and side == 'left':
try:
width = self.old_widths[key]
except KeyError:
pass
else:
output_width = True
ret = super(ShellRenderer, self).render(
output_width=output_width,
else:
did_width = True
if not did_width:
if width is not None:
if theme.cursor_space_multiplier is not None:
width = int(width * theme.cursor_space_multiplier)
elif theme.cursor_columns:
width -= theme.cursor_columns
if side == 'right':
try:
width -= self.old_widths[(client_id, 'left', local_key[-1])]
except KeyError:
pass
res = super(ShellRenderer, self).do_render(
output_width=True,
width=width,
matcher_info=local_theme,
theme=theme,
segment_info=segment_info,
*args, **kwargs
side=side,
**kwargs
)
if output_width:
self.old_widths[key] = ret[1]
ret = ret[0]
return ret
self.old_widths[local_key] = res[-1]
ret = res if output_width else res[:-1]
if len(ret) == 1:
return ret[0]
else:
return ret
def hlstyle(self, fg=None, bg=None, attr=None):
'''Highlight a segment.

View File

@ -1,4 +1,5 @@
# vim:fileencoding=utf-8:noet
from __future__ import division
from powerline.segment import gen_segment_getter, process_segment
from powerline.lib.unicode import u
@ -37,6 +38,11 @@ class Theme(object):
for k, v in val.items()))
for key, val in self.dividers.items()
))
try:
self.cursor_space_multiplier = 1 - (theme_config['cursor_space'] / 100)
except KeyError:
self.cursor_space_multiplier = None
self.cursor_columns = theme_config.get('cursor_columns')
self.spaces = theme_config['spaces']
self.segments = []
self.EMPTY_SEGMENT = {

View File

@ -118,11 +118,11 @@ class TestConfig(TestCase):
segment_info = Args(prompt_count=1)
with IpyPowerline(True) as powerline:
with IpyPowerline(True, {}) as powerline:
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)
with IpyPowerline(False) as powerline:
with IpyPowerline(False, {}) as powerline:
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)