From 3b4a2b3520fbf1acfd3538635f76e7bcd04428c3 Mon Sep 17 00:00:00 2001 From: ZyX Date: Mon, 23 Jun 2014 08:52:46 +0400 Subject: [PATCH] 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). --- powerline/bindings/zsh/__init__.py | 24 +++++++++++++++++------- powerline/bindings/zsh/powerline.zsh | 18 ++++++++++++------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/powerline/bindings/zsh/__init__.py b/powerline/bindings/zsh/__init__.py index 0ffdee19..2bbf3184 100644 --- a/powerline/bindings/zsh/__init__.py +++ b/powerline/bindings/zsh/__init__.py @@ -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') diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index 1f358b36..797c216f 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -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 }