Support multiline prompt in zsh

Notes:

- Unlike fish zsh outputs right prompt shifted by one to the left. Which means
  I have to subtract 1 from computed width.
- PS2 and PS3 produce too lengthy prompts when fed with real width. Thus they
  are fed with PS1 prompt width like in ipython (out prompts).
This commit is contained in:
ZyX 2014-06-23 08:52:46 +04:00
parent eb014efddb
commit 3b4a2b3520
2 changed files with 29 additions and 13 deletions

View File

@ -1,4 +1,6 @@
# vim:fileencoding=utf-8:noet
from __future__ import absolute_import, unicode_literals, division, print_function
import zsh
import atexit
from powerline.shell import ShellPowerline
@ -89,21 +91,22 @@ class ZshPowerline(ShellPowerline):
def precmd(self):
self.args.last_pipe_status = zsh.pipestatus()
self.args.last_exit_code = zsh.last_exit_code()
zsh.eval('_POWERLINE_PARSER_STATE="${(%):-%_}"')
class Prompt(object):
__slots__ = ('powerline', 'side', 'savedpsvar', 'savedps', 'args', 'theme')
__slots__ = ('powerline', 'side', 'savedpsvar', 'savedps', 'args', 'theme', 'above')
def __init__(self, powerline, side, theme, savedpsvar=None, savedps=None):
def __init__(self, powerline, side, theme, savedpsvar=None, savedps=None, above=False):
self.powerline = powerline
self.side = side
self.above = above
self.savedpsvar = savedpsvar
self.savedps = savedps
self.args = powerline.args
self.theme = theme
def __str__(self):
zsh.eval('_POWERLINE_PARSER_STATE="${(%):-%_}"')
segment_info = {
'args': self.args,
'environ': environ,
@ -111,7 +114,14 @@ class Prompt(object):
'local_theme': self.theme,
'parser_state': zsh.getvalue('_POWERLINE_PARSER_STATE'),
}
r = self.powerline.render(
r = ''
if self.above:
for line in self.powerline.render_above_lines(
width=zsh.columns() - 1,
segment_info=segment_info,
):
r += line + '\n'
r += self.powerline.render(
width=zsh.columns(),
side=self.side,
segment_info=segment_info,
@ -131,13 +141,13 @@ class Prompt(object):
self.powerline.shutdown()
def set_prompt(powerline, psvar, side, theme):
def set_prompt(powerline, psvar, side, theme, above=False):
try:
savedps = zsh.getvalue(psvar)
except IndexError:
savedps = None
zpyvar = 'ZPYTHON_POWERLINE_' + psvar
prompt = Prompt(powerline, side, theme, psvar, savedps)
prompt = Prompt(powerline, side, theme, psvar, savedps, above)
zsh.set_special_string(zpyvar, prompt)
zsh.setvalue(psvar, '${' + zpyvar + '}')
@ -146,7 +156,7 @@ def setup():
powerline = ZshPowerline(Args())
used_powerlines.append(powerline)
used_powerlines.append(powerline)
set_prompt(powerline, 'PS1', 'left', None)
set_prompt(powerline, 'PS1', 'left', None, above=True)
set_prompt(powerline, 'RPS1', 'right', None)
set_prompt(powerline, 'PS2', 'left', 'continuation')
set_prompt(powerline, 'RPS2', 'right', 'continuation')

View File

@ -111,21 +111,27 @@ _powerline_setup_prompt() {
fi
done
precmd_functions+=( _powerline_set_jobnum )
if zmodload libzpython &>/dev/null || zmodload zsh/zpython &>/dev/null ; then
if test -z "${POWERLINE_NO_ZSH_ZPYTHON}" && { zmodload libzpython || zmodload zsh/zpython } &>/dev/null ; then
precmd_functions+=( _powerline_update_counter )
zpython 'from powerline.bindings.zsh import setup as _powerline_setup'
zpython '_powerline = _powerline_setup()'
zpython 'del _powerline_setup'
else
local add_args='--last_exit_code=$? --last_pipe_status="$pipestatus"'
local add_args='--last_exit_code=$?'
add_args+=' --last_pipe_status="$pipestatus"'
add_args+=' --renderer_arg="client_id=$$"'
add_args+=' --jobnum=$_POWERLINE_JOBNUM'
local add_args_2=$add_args' -R parser_state=${(%%):-%_} -R local_theme=continuation'
PS1='$($POWERLINE_COMMAND shell left -r zsh_prompt '$add_args')'
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 add_args_2=$add_args$new_args_2
add_args+=' --width=$(( COLUMNS - 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_2')'
PS3='$($POWERLINE_COMMAND shell left -r zsh_prompt -R local_theme=select '$add_args')'
RPS2='$($POWERLINE_COMMAND shell right -r zsh_prompt '$add_args_r2')'
PS3='$($POWERLINE_COMMAND shell left -r zsh_prompt '$add_args_3')'
fi
}