mirror of
https://github.com/powerline/powerline.git
synced 2025-07-26 23:35:04 +02:00
Merge pull request #975 from ZyX-I/min_cursor_columns
Add cursor_space and cursor_columns options
This commit is contained in:
commit
1abe0ac194
@ -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``
|
||||
|
@ -41,7 +41,12 @@ _powerline_init_tmux_support() {
|
||||
|
||||
_powerline_prompt() {
|
||||
# Arguments: side, last_exit_code, jobnum
|
||||
$POWERLINE_COMMAND shell $1 -w "${COLUMNS:-$(_powerline_columns_fallback)}" -r bash_prompt --last_exit_code=$2 --jobnum=$3
|
||||
$POWERLINE_COMMAND shell $1 \
|
||||
--width="${COLUMNS:-$(_powerline_columns_fallback)}" \
|
||||
-r bash_prompt \
|
||||
--last_exit_code=$2 \
|
||||
--jobnum=$3 \
|
||||
--renderer_arg="client_id=$$"
|
||||
}
|
||||
|
||||
_powerline_set_prompt() {
|
||||
|
@ -34,6 +34,9 @@ function powerline-setup
|
||||
set -l addargs "--last_exit_code=\$status"
|
||||
set -l addargs "$addargs --last_pipe_status=\$status"
|
||||
set -l addargs "$addargs --jobnum=(jobs -p | wc -l)"
|
||||
# One random value has an 1/32767 = 0.0031% probability of having
|
||||
# the same value in two shells
|
||||
set -l addargs "$addargs --renderer_arg=client_id="(random)
|
||||
set -l addargs "$addargs --width=\$_POWERLINE_COLUMNS"
|
||||
set -l promptside
|
||||
set -l rpromptpast
|
||||
|
@ -22,20 +22,20 @@ 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, res_nocolor = powerline.render(
|
||||
output_raw=True,
|
||||
width=width,
|
||||
res = powerline.render(
|
||||
side='left',
|
||||
output_width=True,
|
||||
output_raw=not color,
|
||||
matcher_info=name,
|
||||
segment_info=self.powerline_segment_info,
|
||||
)
|
||||
self.txtwidth = len(res_nocolor)
|
||||
self.width = self.txtwidth
|
||||
ret = res if color else res_nocolor
|
||||
self.txtwidth = res[-1]
|
||||
self.width = res[-1]
|
||||
ret = res[0] if color else res[1]
|
||||
if name == 'rewrite':
|
||||
return RewriteResult(ret)
|
||||
else:
|
||||
@ -43,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
|
||||
@ -58,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,
|
||||
|
@ -32,12 +32,15 @@ class PowerlinePrompt(BasePrompt):
|
||||
self.set_p_str()
|
||||
return string(self.p_str)
|
||||
|
||||
def set_p_str(self, width=None):
|
||||
self.p_str, self.p_str_nocolor = (
|
||||
self.powerline.render(output_raw=True,
|
||||
segment_info=self.powerline_segment_info,
|
||||
matcher_info=self.powerline_prompt_type,
|
||||
width=width)
|
||||
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,
|
||||
)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
@ -58,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 = len(self.p_str_nocolor) - 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
|
||||
@ -82,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),
|
||||
|
@ -134,7 +134,12 @@ _powerline_set_jobs() {
|
||||
_powerline_prompt() {
|
||||
# Arguments: side, exit_code
|
||||
_powerline_set_jobs
|
||||
$POWERLINE_COMMAND shell $1 -w "${COLUMNS:-$(_powerline_columns_fallback)}" $_POWERLINE_RENDERER_ARG --last_exit_code=$2 --jobnum=$_POWERLINE_JOBS
|
||||
$POWERLINE_COMMAND shell $1 \
|
||||
--width="${COLUMNS:-$(_powerline_columns_fallback)}" \
|
||||
$_POWERLINE_RENDERER_ARG \
|
||||
--renderer_arg="client_id=$$" \
|
||||
--last_exit_code=$2 \
|
||||
--jobnum=$_POWERLINE_JOBS
|
||||
}
|
||||
|
||||
_powerline_setup_prompt() {
|
||||
|
@ -24,11 +24,11 @@ if ( { $POWERLINE_CONFIG shell --shell=tcsh uses prompt } ) then
|
||||
if ( $?POWERLINE_NO_TCSH_ABOVE || $?POWERLINE_NO_SHELL_ABOVE ) then
|
||||
alias _powerline_above true
|
||||
else
|
||||
alias _powerline_above '$POWERLINE_COMMAND shell above --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS'
|
||||
alias _powerline_above '$POWERLINE_COMMAND shell above --renderer_arg=client_id=$$ --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS'
|
||||
endif
|
||||
|
||||
alias _powerline_set_prompt 'set prompt="`$POWERLINE_COMMAND shell left -r tcsh_prompt --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS`"'
|
||||
alias _powerline_set_rprompt 'set rprompt="`$POWERLINE_COMMAND shell right -r tcsh_prompt --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS` "'
|
||||
alias _powerline_set_prompt 'set prompt="`$POWERLINE_COMMAND shell left -r tcsh_prompt --renderer_arg=client_id=$$ --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS`"'
|
||||
alias _powerline_set_rprompt 'set rprompt="`$POWERLINE_COMMAND shell right -r tcsh_prompt --renderer_arg=client_id=$$ --last_exit_code=$POWERLINE_STATUS --width=$POWERLINE_COLUMNS` "'
|
||||
alias _powerline_set_columns 'set POWERLINE_COLUMNS=`stty size|cut -d" " -f2` ; set POWERLINE_COLUMNS=`expr $POWERLINE_COLUMNS - 2`'
|
||||
|
||||
alias precmd 'set POWERLINE_STATUS=$? ; '"`alias precmd`"' ; _powerline_set_columns ; _powerline_above ; _powerline_set_prompt ; _powerline_set_rprompt'
|
||||
|
@ -129,21 +129,22 @@ _powerline_setup_prompt() {
|
||||
POWERLINE_COMMAND=( "$($POWERLINE_CONFIG shell command)" )
|
||||
fi
|
||||
|
||||
local add_args='--last_exit_code=$?'
|
||||
local add_args='-r zsh_prompt'
|
||||
add_args+=' --last_exit_code=$?'
|
||||
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
|
||||
PS1='$($POWERLINE_COMMAND shell aboveleft -r zsh_prompt '$add_args')'
|
||||
RPS1='$($POWERLINE_COMMAND shell right -r zsh_prompt '$add_args')'
|
||||
PS2='$($POWERLINE_COMMAND shell left -r zsh_prompt '$add_args_2')'
|
||||
RPS2='$($POWERLINE_COMMAND shell right -r zsh_prompt '$add_args_r2')'
|
||||
PS3='$($POWERLINE_COMMAND shell left -r zsh_prompt '$add_args_3')'
|
||||
PS1='$($POWERLINE_COMMAND shell aboveleft '$add_args')'
|
||||
RPS1='$($POWERLINE_COMMAND shell right '$add_args')'
|
||||
PS2='$($POWERLINE_COMMAND shell left '$add_args_2')'
|
||||
RPS2='$($POWERLINE_COMMAND shell right '$add_args_r2')'
|
||||
PS3='$($POWERLINE_COMMAND shell left '$add_args_3')'
|
||||
fi
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
"segments": {
|
||||
"left": [
|
||||
{
|
||||
"name": "virtualenv"
|
||||
"name": "virtualenv",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
|
@ -7,29 +7,36 @@
|
||||
"name": "mode"
|
||||
},
|
||||
{
|
||||
"name": "hostname"
|
||||
"name": "hostname",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"name": "user"
|
||||
"name": "user",
|
||||
"priority": 30
|
||||
},
|
||||
{
|
||||
"name": "virtualenv"
|
||||
"name": "virtualenv",
|
||||
"priority": 50
|
||||
},
|
||||
{
|
||||
"name": "cwd"
|
||||
"name": "cwd",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"module": "powerline.segments.shell",
|
||||
"name": "jobnum"
|
||||
"name": "jobnum",
|
||||
"priority": 20
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{
|
||||
"module": "powerline.segments.shell",
|
||||
"name": "last_pipe_status"
|
||||
"name": "last_pipe_status",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"name": "branch"
|
||||
"name": "branch",
|
||||
"priority": 40
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -3,27 +3,34 @@
|
||||
"segments": {
|
||||
"left": [
|
||||
{
|
||||
"name": "hostname"
|
||||
"name": "hostname",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"name": "user"
|
||||
"name": "user",
|
||||
"priority": 30
|
||||
},
|
||||
{
|
||||
"name": "virtualenv"
|
||||
"name": "virtualenv",
|
||||
"priority": 50
|
||||
},
|
||||
{
|
||||
"name": "branch"
|
||||
"name": "branch",
|
||||
"priority": 40
|
||||
},
|
||||
{
|
||||
"name": "cwd"
|
||||
"name": "cwd",
|
||||
"priority": 10
|
||||
},
|
||||
{
|
||||
"module": "powerline.segments.shell",
|
||||
"name": "jobnum"
|
||||
"name": "jobnum",
|
||||
"priority": 20
|
||||
},
|
||||
{
|
||||
"module": "powerline.segments.shell",
|
||||
"name": "last_status",
|
||||
"module": "powerline.segments.shell"
|
||||
"priority": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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(),
|
||||
|
@ -15,11 +15,15 @@ except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
def construct_returned_value(rendered_highlighted, segments, output_raw):
|
||||
if output_raw:
|
||||
return rendered_highlighted, ''.join((segment['_rendered_raw'] for segment in segments))
|
||||
else:
|
||||
def construct_returned_value(rendered_highlighted, segments, width, output_raw, output_width):
|
||||
if not (output_raw or output_width):
|
||||
return rendered_highlighted
|
||||
else:
|
||||
return (
|
||||
(rendered_highlighted,)
|
||||
+ ((''.join((segment['_rendered_raw'] for segment in segments)),) if output_raw else ())
|
||||
+ ((width,) if output_width else ())
|
||||
)
|
||||
|
||||
|
||||
class Renderer(object):
|
||||
@ -188,7 +192,7 @@ class Renderer(object):
|
||||
for line in range(theme.get_line_number() - 1, 0, -1):
|
||||
yield self.render(side=None, line=line, **kwargs)
|
||||
|
||||
def render(self, mode=None, width=None, side=None, line=0, output_raw=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.
|
||||
|
||||
When a width is provided, low-priority segments are dropped one at
|
||||
@ -213,14 +217,44 @@ class Renderer(object):
|
||||
Changes the output: if this parameter is ``True`` then in place of
|
||||
one string this method outputs a pair ``(colored_string,
|
||||
colorless_string)``.
|
||||
:param bool output_width:
|
||||
Changes the output: if this parameter is ``True`` then in place of
|
||||
one string this method outputs a pair ``(colored_string,
|
||||
string_width)``. Returns a three-tuple if ``output_raw`` is also
|
||||
``True``: ``(colored_string, colorless_string, string_width)``.
|
||||
:param dict segment_info:
|
||||
Segment information. See also ``.get_segment_info()`` method.
|
||||
:param matcher_info:
|
||||
Matcher information. Is processed in ``.get_theme()`` method.
|
||||
'''
|
||||
theme = self.get_theme(matcher_info)
|
||||
segments = theme.get_segments(side, line, self.get_segment_info(segment_info, mode))
|
||||
return self.do_render(
|
||||
mode=mode,
|
||||
width=width,
|
||||
side=side,
|
||||
line=line,
|
||||
output_raw=output_raw,
|
||||
output_width=output_width,
|
||||
segment_info=segment_info,
|
||||
theme=theme,
|
||||
)
|
||||
|
||||
def compute_divider_widths(self, theme):
|
||||
return {
|
||||
'left': {
|
||||
'hard': self.strwidth(theme.get_divider('left', 'hard')),
|
||||
'soft': self.strwidth(theme.get_divider('left', 'soft')),
|
||||
},
|
||||
'right': {
|
||||
'hard': self.strwidth(theme.get_divider('right', 'hard')),
|
||||
'soft': self.strwidth(theme.get_divider('right', 'soft')),
|
||||
},
|
||||
}
|
||||
|
||||
def do_render(self, mode, width, side, line, output_raw, output_width, segment_info, theme):
|
||||
'''Like Renderer.render(), but accept theme in place of matcher_info
|
||||
'''
|
||||
segments = theme.get_segments(side, line, self.get_segment_info(segment_info, mode))
|
||||
# Handle excluded/included segments for the current mode
|
||||
segments = [
|
||||
self._get_highlighting(segment, segment['mode'] or mode)
|
||||
@ -234,37 +268,36 @@ class Renderer(object):
|
||||
)
|
||||
]
|
||||
|
||||
current_width = 0
|
||||
|
||||
if not width:
|
||||
# No width specified, so we don't need to crop or pad anything
|
||||
if output_width:
|
||||
current_width = self._render_length(theme, segments, self.compute_divider_widths(theme))
|
||||
return construct_returned_value(''.join([
|
||||
segment['_rendered_hl']
|
||||
for segment in self._render_segments(theme, segments)
|
||||
]) + self.hlstyle(), segments, output_raw)
|
||||
]) + self.hlstyle(), segments, current_width, output_raw, output_width)
|
||||
|
||||
divider_lengths = {
|
||||
'left': {
|
||||
'hard': self.strwidth(theme.get_divider('left', 'hard')),
|
||||
'soft': self.strwidth(theme.get_divider('left', 'soft')),
|
||||
},
|
||||
'right': {
|
||||
'hard': self.strwidth(theme.get_divider('right', 'hard')),
|
||||
'soft': self.strwidth(theme.get_divider('right', 'soft')),
|
||||
},
|
||||
}
|
||||
|
||||
length = self._render_length(theme, segments, divider_lengths)
|
||||
divider_widths = self.compute_divider_widths(theme)
|
||||
|
||||
# Create an ordered list of segments that can be dropped
|
||||
segments_priority = sorted((segment for segment in segments if segment['priority'] is not None), key=lambda segment: segment['priority'], reverse=True)
|
||||
for segment in segments_priority:
|
||||
if self._render_length(theme, segments, divider_lengths) <= width:
|
||||
current_width = self._render_length(theme, segments, divider_widths)
|
||||
if current_width <= width:
|
||||
break
|
||||
segments.remove(segment)
|
||||
|
||||
# Distribute the remaining space on spacer segments
|
||||
segments_spacers = [segment for segment in segments if segment['width'] == 'auto']
|
||||
if segments_spacers:
|
||||
distribute_len, distribute_len_remainder = divmod(width - sum([segment['_len'] for segment in segments]), len(segments_spacers))
|
||||
if not segments_priority:
|
||||
# Update segment['_len'] and current_width if not already done
|
||||
# (is not done in shells where there is nothing to remove
|
||||
# because “priority” key is not specified)
|
||||
current_width = self._render_length(theme, segments, divider_widths)
|
||||
distribute_len, distribute_len_remainder = divmod(width - current_width, len(segments_spacers))
|
||||
for segment in segments_spacers:
|
||||
if segment['align'] == 'l':
|
||||
segment['_space_right'] += distribute_len
|
||||
@ -275,12 +308,17 @@ class Renderer(object):
|
||||
segment['_space_left'] += space_side + space_side_remainder
|
||||
segment['_space_right'] += space_side
|
||||
segments_spacers[0]['_space_right'] += distribute_len_remainder
|
||||
# `_len` key is not needed anymore, but current_width should have an
|
||||
# actual value for various bindings.
|
||||
current_width = width
|
||||
elif output_width:
|
||||
current_width = self._render_length(theme, segments, divider_widths)
|
||||
|
||||
rendered_highlighted = ''.join([segment['_rendered_hl'] for segment in self._render_segments(theme, segments)]) + self.hlstyle()
|
||||
|
||||
return construct_returned_value(rendered_highlighted, segments, output_raw)
|
||||
return construct_returned_value(rendered_highlighted, segments, current_width, output_raw, output_width)
|
||||
|
||||
def _render_length(self, theme, segments, divider_lengths):
|
||||
def _render_length(self, theme, segments, divider_widths):
|
||||
'''Update segments lengths and return them
|
||||
'''
|
||||
segments_len = len(segments)
|
||||
@ -306,7 +344,7 @@ class Renderer(object):
|
||||
draw_divider = segment['draw_' + divider_type + '_divider']
|
||||
segment_len += segment['_space_left'] + segment['_space_right'] + outer_padding
|
||||
if draw_divider:
|
||||
segment_len += divider_lengths[side][divider_type] + divider_spaces
|
||||
segment_len += divider_widths[side][divider_type] + divider_spaces
|
||||
|
||||
segment['_len'] = segment_len
|
||||
ret += segment_len
|
||||
|
@ -21,7 +21,7 @@ class IpythonRenderer(ShellRenderer):
|
||||
except KeyError:
|
||||
match['theme'] = Theme(
|
||||
theme_config=match['config'],
|
||||
top_theme_config=self.theme_config,
|
||||
main_theme_config=self.theme_config,
|
||||
**self.theme_kwargs
|
||||
)
|
||||
return match['theme']
|
||||
@ -32,5 +32,9 @@ class IpythonRenderer(ShellRenderer):
|
||||
if 'theme' in match:
|
||||
match['theme'].shutdown()
|
||||
|
||||
def render(self, *args, **kwargs):
|
||||
# XXX super(ShellRenderer), *not* super(IpythonRenderer)
|
||||
return super(ShellRenderer, self).render(*args, **kwargs)
|
||||
|
||||
|
||||
renderer = IpythonRenderer
|
||||
|
@ -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
|
||||
@ -23,6 +23,60 @@ class ShellRenderer(Renderer):
|
||||
|
||||
character_translations = Renderer.character_translations.copy()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ShellRenderer, self).__init__(*args, **kwargs)
|
||||
self.old_widths = {}
|
||||
|
||||
def render(self, segment_info, **kwargs):
|
||||
local_theme = segment_info.get('local_theme')
|
||||
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:
|
||||
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,
|
||||
theme=theme,
|
||||
segment_info=segment_info,
|
||||
side=side,
|
||||
**kwargs
|
||||
)
|
||||
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.
|
||||
|
||||
|
@ -57,7 +57,7 @@ class VimRenderer(Renderer):
|
||||
try:
|
||||
return match['theme']
|
||||
except KeyError:
|
||||
match['theme'] = Theme(theme_config=match['config'], top_theme_config=self.theme_config, **self.theme_kwargs)
|
||||
match['theme'] = Theme(theme_config=match['config'], main_theme_config=self.theme_config, **self.theme_kwargs)
|
||||
return match['theme']
|
||||
|
||||
def get_theme(self, matcher_info):
|
||||
|
@ -14,34 +14,6 @@ class ZshPromptRenderer(ShellRenderer):
|
||||
character_translations = ShellRenderer.character_translations.copy()
|
||||
character_translations[ord('%')] = '%%'
|
||||
|
||||
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)
|
||||
local_theme = segment_info.get('local_theme')
|
||||
if client_id and local_theme:
|
||||
output_raw = False
|
||||
try:
|
||||
width = self.old_widths[key]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
output_raw = True
|
||||
ret = super(ShellRenderer, self).render(
|
||||
output_raw=output_raw,
|
||||
width=width,
|
||||
matcher_info=local_theme,
|
||||
segment_info=segment_info,
|
||||
*args, **kwargs
|
||||
)
|
||||
if output_raw:
|
||||
self.old_widths[key] = len(ret[1])
|
||||
ret = ret[0]
|
||||
return ret
|
||||
|
||||
def get_theme(self, matcher_info):
|
||||
if not matcher_info:
|
||||
return self.theme
|
||||
@ -51,7 +23,7 @@ class ZshPromptRenderer(ShellRenderer):
|
||||
except KeyError:
|
||||
match['theme'] = Theme(
|
||||
theme_config=match['config'],
|
||||
top_theme_config=self.theme_config,
|
||||
main_theme_config=self.theme_config,
|
||||
**self.theme_kwargs
|
||||
)
|
||||
return match['theme']
|
||||
|
@ -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
|
||||
@ -28,7 +29,7 @@ class Theme(object):
|
||||
theme_config,
|
||||
common_config,
|
||||
pl,
|
||||
top_theme_config=None,
|
||||
main_theme_config=None,
|
||||
run_once=False,
|
||||
shutdown_event=None):
|
||||
self.dividers = theme_config['dividers']
|
||||
@ -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 = {
|
||||
@ -45,8 +51,8 @@ class Theme(object):
|
||||
}
|
||||
self.pl = pl
|
||||
theme_configs = [theme_config]
|
||||
if top_theme_config:
|
||||
theme_configs.append(top_theme_config)
|
||||
if main_theme_config:
|
||||
theme_configs.append(main_theme_config)
|
||||
get_segment = gen_segment_getter(pl, ext, common_config, theme_configs, theme_config.get('default_module'))
|
||||
for segdict in itertools.chain((theme_config['segments'],),
|
||||
theme_config['segments'].get('above', ())):
|
||||
|
@ -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)
|
||||
|
@ -54,10 +54,14 @@ run_test() {
|
||||
|
||||
run screen -L -c tests/test_shells/screenrc -d -m -S "$SESNAME" \
|
||||
env LANG=en_US.UTF-8 BINDFILE="$BINDFILE" "${ARGS[@]}"
|
||||
screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH
|
||||
while ! screen -S "$SESNAME" -X readreg a tests/test_shells/input.$SH ; do
|
||||
sleep 0.1s
|
||||
done
|
||||
# Wait for screen to initialize
|
||||
sleep 1
|
||||
screen -S "$SESNAME" -p 0 -X width 300 1
|
||||
while ! screen -S "$SESNAME" -p 0 -X width 300 1 ; do
|
||||
sleep 0.1s
|
||||
done
|
||||
if test "x${SH}" = "xdash" ; then
|
||||
# If I do not use this hack for dash then output will look like
|
||||
#
|
||||
|
Loading…
x
Reference in New Issue
Block a user