summaryrefslogtreecommitdiffstats
path: root/powerline/bindings/zsh
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:40:16 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:40:16 +0000
commit3f25952c13d5847d510c0cae22a8ba876638d570 (patch)
tree02f505f016ed5a1029277dcae520d5e2a75906fb /powerline/bindings/zsh
parentInitial commit. (diff)
downloadpowerline-3f25952c13d5847d510c0cae22a8ba876638d570.tar.xz
powerline-3f25952c13d5847d510c0cae22a8ba876638d570.zip
Adding upstream version 2.8.3.upstream/2.8.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'powerline/bindings/zsh')
-rw-r--r--powerline/bindings/zsh/__init__.py225
-rw-r--r--powerline/bindings/zsh/powerline.zsh216
2 files changed, 441 insertions, 0 deletions
diff --git a/powerline/bindings/zsh/__init__.py b/powerline/bindings/zsh/__init__.py
new file mode 100644
index 0000000..44f5c69
--- /dev/null
+++ b/powerline/bindings/zsh/__init__.py
@@ -0,0 +1,225 @@
+# vim:fileencoding=utf-8:noet
+from __future__ import (unicode_literals, division, absolute_import, print_function)
+
+import atexit
+
+from weakref import WeakValueDictionary, ref
+
+import zsh
+
+from powerline.shell import ShellPowerline
+from powerline.lib.overrides import parsedotval, parse_override_var
+from powerline.lib.unicode import unicode, u
+from powerline.lib.encoding import (get_preferred_output_encoding,
+ get_preferred_environment_encoding)
+from powerline.lib.dict import mergeargs
+
+
+used_powerlines = WeakValueDictionary()
+
+
+def shutdown():
+ for powerline in tuple(used_powerlines.values()):
+ powerline.shutdown()
+
+
+def get_var_config(var):
+ try:
+ val = zsh.getvalue(var)
+ if isinstance(val, dict):
+ return mergeargs([parsedotval((u(k), u(v))) for k, v in val.items()])
+ elif isinstance(val, (unicode, str, bytes)):
+ return mergeargs(parse_override_var(u(val)))
+ else:
+ return None
+ except:
+ return None
+
+
+class Args(object):
+ __slots__ = ('last_pipe_status', 'last_exit_code')
+ ext = ['shell']
+ renderer_module = '.zsh'
+
+ @property
+ def config_override(self):
+ return get_var_config('POWERLINE_CONFIG_OVERRIDES')
+
+ @property
+ def theme_override(self):
+ return get_var_config('POWERLINE_THEME_OVERRIDES')
+
+ @property
+ def config_path(self):
+ try:
+ ret = zsh.getvalue('POWERLINE_CONFIG_PATHS')
+ except IndexError:
+ return None
+ else:
+ if isinstance(ret, (unicode, str, bytes)):
+ return [
+ path
+ for path in ret.split((b':' if isinstance(ret, bytes) else ':'))
+ if path
+ ]
+ else:
+ return ret
+
+ @property
+ def jobnum(self):
+ return zsh.getvalue('_POWERLINE_JOBNUM')
+
+
+def string(s):
+ if type(s) is bytes:
+ return s.decode(get_preferred_environment_encoding(), 'replace')
+ else:
+ return str(s)
+
+
+class Environment(object):
+ @staticmethod
+ def __getitem__(key):
+ try:
+ return string(zsh.getvalue(key))
+ except IndexError as e:
+ raise KeyError(*e.args)
+
+ @staticmethod
+ def get(key, default=None):
+ try:
+ return string(zsh.getvalue(key))
+ except IndexError:
+ return default
+
+ @staticmethod
+ def __contains__(key):
+ try:
+ zsh.getvalue(key)
+ return True
+ except IndexError:
+ return False
+
+
+environ = Environment()
+
+
+if hasattr(zsh, 'expand') and zsh.expand('${:-}') == '':
+ zsh_expand = zsh.expand
+else:
+ def zsh_expand(s):
+ zsh.eval('local _POWERLINE_REPLY="' + s + '"')
+ ret = zsh.getvalue('_POWERLINE_REPLY')
+ zsh.setvalue('_POWERLINE_REPLY', None)
+ return ret
+
+
+class ZshPowerline(ShellPowerline):
+ def init(self, **kwargs):
+ super(ZshPowerline, self).init(Args(), **kwargs)
+
+ def precmd(self):
+ self.args.last_pipe_status = zsh.pipestatus()
+ self.args.last_exit_code = zsh.last_exit_code()
+
+ def do_setup(self, zsh_globals):
+ set_prompt(self, 'PS1', 'left', None, above=True)
+ set_prompt(self, 'RPS1', 'right', None)
+ set_prompt(self, 'PS2', 'left', 'continuation')
+ set_prompt(self, 'RPS2', 'right', 'continuation')
+ set_prompt(self, 'PS3', 'left', 'select')
+ used_powerlines[id(self)] = self
+ zsh_globals['_powerline'] = self
+
+
+class Prompt(object):
+ __slots__ = ('powerline', 'side', 'savedpsvar', 'savedps', 'args', 'theme', 'above', '__weakref__')
+
+ 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):
+ parser_state = u(zsh_expand('${(%):-%_}'))
+ shortened_path = u(zsh_expand('${(%):-%~}'))
+ try:
+ mode = u(zsh.getvalue('_POWERLINE_MODE'))
+ except IndexError:
+ mode = None
+ try:
+ default_mode = u(zsh.getvalue('_POWERLINE_DEFAULT_MODE'))
+ except IndexError:
+ default_mode = None
+ segment_info = {
+ 'args': self.args,
+ 'environ': environ,
+ 'client_id': 1,
+ 'local_theme': self.theme,
+ 'parser_state': parser_state,
+ 'shortened_path': shortened_path,
+ 'mode': mode,
+ 'default_mode': default_mode,
+ }
+ try:
+ zle_rprompt_indent = zsh.getvalue('ZLE_RPROMPT_INDENT')
+ except IndexError:
+ zle_rprompt_indent = 1
+ r = ''
+ if self.above:
+ for line in self.powerline.render_above_lines(
+ width=zsh.columns() - zle_rprompt_indent,
+ segment_info=segment_info,
+ ):
+ if line:
+ r += line + '\n'
+ r += self.powerline.render(
+ width=zsh.columns(),
+ side=self.side,
+ segment_info=segment_info,
+ mode=mode,
+ )
+ if type(r) is not str:
+ if type(r) is bytes:
+ return r.decode(get_preferred_output_encoding(), 'replace')
+ else:
+ return r.encode(get_preferred_output_encoding(), 'replace')
+ return r
+
+ def __del__(self):
+ if self.savedps:
+ zsh.setvalue(self.savedpsvar, self.savedps)
+ self.powerline.shutdown()
+
+
+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, above)
+ zsh.setvalue(zpyvar, None)
+ zsh.set_special_string(zpyvar, prompt)
+ zsh.setvalue(psvar, '${' + zpyvar + '}')
+ return ref(prompt)
+
+
+def reload():
+ for powerline in tuple(used_powerlines.values()):
+ powerline.reload()
+
+
+def reload_config():
+ for powerline in used_powerlines.values():
+ powerline.create_renderer(load_main=True, load_colors=True, load_colorscheme=True, load_theme=True)
+
+
+def setup(zsh_globals):
+ powerline = ZshPowerline()
+ powerline.setup(zsh_globals)
+ atexit.register(shutdown)
diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh
new file mode 100644
index 0000000..ff46cb0
--- /dev/null
+++ b/powerline/bindings/zsh/powerline.zsh
@@ -0,0 +1,216 @@
+local _POWERLINE_SOURCED="$0:A"
+
+_powerline_columns_fallback() {
+ if which stty &>/dev/null ; then
+ local cols="$(stty size 2>/dev/null)"
+ if ! test -z "$cols" ; then
+ echo "${cols#* }"
+ return 0
+ fi
+ fi
+ echo 0
+ return 0
+}
+
+_powerline_append_precmd_function() {
+ if test -z "${precmd_functions[(re)$1]}" ; then
+ precmd_functions+=( $1 )
+ fi
+}
+
+integer -g _POWERLINE_JOBNUM=0
+
+_powerline_tmux_pane() {
+ local -x TMUX="$_POWERLINE_TMUX"
+ echo "${TMUX_PANE:-`tmux display -p "#D"`}" | tr -d ' %'
+}
+
+_powerline_tmux_pane() {
+ local -x TMUX="$_POWERLINE_TMUX"
+ echo "${TMUX_PANE:-`tmux display -p "#D"`}" | tr -d ' %'
+}
+
+_powerline_init_tmux_support() {
+ emulate -L zsh
+ if test -n "$TMUX" && tmux refresh -S &>/dev/null ; then
+ # TMUX variable may be unset to create new tmux session inside this one
+ typeset -g _POWERLINE_TMUX="$TMUX"
+
+ function -g _powerline_tmux_setenv() {
+ emulate -L zsh
+ local -x TMUX="$_POWERLINE_TMUX"
+ tmux setenv -g TMUX_"$1"_$(_powerline_tmux_pane) "$2"
+ tmux refresh -S
+ }
+
+ function -g _powerline_tmux_set_pwd() {
+ _powerline_tmux_setenv PWD "$PWD"
+ }
+
+ function -g _powerline_tmux_set_columns() {
+ _powerline_tmux_setenv COLUMNS "${COLUMNS:-$(_powerline_columns_fallback)}"
+ }
+
+ chpwd_functions+=( _powerline_tmux_set_pwd )
+ trap '_powerline_tmux_set_columns' SIGWINCH
+ _powerline_tmux_set_columns
+ _powerline_tmux_set_pwd
+ fi
+}
+
+_powerline_init_modes_support() {
+ emulate -L zsh
+
+ test -z "$ZSH_VERSION" && return 0
+
+ local -a vs
+ vs=( ${(s:.:)ZSH_VERSION} )
+
+ # Mode support requires >=zsh-4.3.11
+ if (( vs[1] < 4 || (vs[1] == 4 && (vs[2] < 3 || (vs[2] == 3 && vs[3] < 11))) )) ; then
+ return 0
+ fi
+
+ function -g _powerline_get_main_keymap_name() {
+ REPLY="${${(Q)${${(z)${"$(bindkey -lL main)"}}[3]}}:-.safe}"
+ }
+
+ function -g _powerline_set_true_keymap_name() {
+ typeset -g _POWERLINE_MODE="${1}"
+ local plm_bk="$(bindkey -lL ${_POWERLINE_MODE})"
+ if [[ $plm_bk = 'bindkey -A'* ]] ; then
+ _powerline_set_true_keymap_name ${(Q)${${(z)plm_bk}[3]}}
+ fi
+ }
+
+ function -g _powerline_zle_keymap_select() {
+ _powerline_set_true_keymap_name $KEYMAP
+ zle reset-prompt
+ test -z "$_POWERLINE_SAVE_WIDGET" || zle $_POWERLINE_SAVE_WIDGET
+ }
+
+ function -g _powerline_set_main_keymap_name() {
+ local REPLY
+ _powerline_get_main_keymap_name
+ _powerline_set_true_keymap_name "$REPLY"
+ }
+
+ _powerline_add_widget zle-keymap-select _powerline_zle_keymap_select
+ _powerline_set_main_keymap_name
+
+ if [[ "$_POWERLINE_MODE" != vi* ]] ; then
+ typeset -g _POWERLINE_DEFAULT_MODE="$_POWERLINE_MODE"
+ fi
+
+ _powerline_append_precmd_function _powerline_set_main_keymap_name
+}
+
+_powerline_set_jobnum() {
+ # If you are wondering why I am not using the same code as I use for bash
+ # ($(jobs|wc -l)): consider the following test:
+ # echo abc | less
+ # <C-z>
+ # . This way jobs will print
+ # [1] + done echo abc |
+ # suspended less -M
+ # ([ is in first column). You see: any line counting thingie will return
+ # wrong number of jobs. You need to filter the lines first. Or not use
+ # jobs built-in at all.
+ integer -g _POWERLINE_JOBNUM=${(%):-%j}
+}
+
+_powerline_update_counter() {
+ zpython '_powerline.precmd()'
+}
+
+_powerline_setup_prompt() {
+ emulate -L zsh
+
+ _powerline_append_precmd_function _powerline_set_jobnum
+
+ typeset -g VIRTUAL_ENV_DISABLE_PROMPT=1
+
+ if test -z "${POWERLINE_NO_ZSH_ZPYTHON}" && { zmodload libzpython || zmodload zsh/zpython } &>/dev/null ; then
+ _powerline_append_precmd_function _powerline_update_counter
+ zpython 'from powerline.bindings.zsh import setup as _powerline_setup'
+ zpython '_powerline_setup(globals())'
+ zpython 'del _powerline_setup'
+ powerline-reload() {
+ zpython 'from powerline.bindings.zsh import reload as _powerline_reload'
+ zpython '_powerline_reload()'
+ zpython 'del _powerline_reload'
+ }
+ powerline-reload-config() {
+ zpython 'from powerline.bindings.zsh import reload_config as _powerline_reload_config'
+ zpython '_powerline_reload_config()'
+ zpython 'del _powerline_reload_config'
+ }
+ else
+ if test -z "${POWERLINE_COMMAND}" ; then
+ typeset -g POWERLINE_COMMAND="$($POWERLINE_CONFIG_COMMAND shell command)"
+ fi
+
+ local add_args='-r .zsh'
+ add_args+=' --last-exit-code=$?'
+ add_args+=' --last-pipe-status="$pipestatus"'
+ add_args+=' --renderer-arg="client_id=$$"'
+ add_args+=' --renderer-arg="shortened_path=${(%):-%~}"'
+ add_args+=' --jobnum=$_POWERLINE_JOBNUM'
+ add_args+=' --renderer-arg="mode=$_POWERLINE_MODE"'
+ add_args+=' --renderer-arg="default_mode=$_POWERLINE_DEFAULT_MODE"'
+ 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)} - ${ZLE_RPROMPT_INDENT:-1} ))'
+ local add_args_r2=$add_args$new_args_2
+ typeset -g PS1='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell aboveleft '$add_args')'
+ typeset -g RPS1='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell right '$add_args')'
+ typeset -g PS2='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell left '$add_args_2')'
+ typeset -g RPS2='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell right '$add_args_r2')'
+ typeset -g PS3='$("$POWERLINE_COMMAND" $=POWERLINE_COMMAND_ARGS shell left '$add_args_3')'
+ fi
+}
+
+_powerline_add_widget() {
+ local widget="$1"
+ local function="$2"
+ local old_widget_command="$(zle -l -L $widget)"
+ if [[ "$old_widget_command" = "zle -N $widget $function" ]] ; then
+ return 0
+ elif [[ -z "$old_widget_command" ]] ; then
+ zle -N $widget $function
+ else
+ local save_widget="_powerline_save_$widget"
+ local -i i=0
+ while ! test -z "$(zle -l -L $save_widget)" ; do
+ save_widget="${save_widget}_$i"
+ (( i++ ))
+ done
+ # If widget was defined with `zle -N widget` (without `function`
+ # argument) then this function will be handy.
+ eval "function $save_widget() { emulate -L zsh; $widget \$@ }"
+ eval "${old_widget_command/$widget/$save_widget}"
+ zle -N $widget $function
+ typeset -g _POWERLINE_SAVE_WIDGET="$save_widget"
+ fi
+}
+
+if test -z "${POWERLINE_CONFIG_COMMAND}" ; then
+ if which powerline-config >/dev/null 2>/dev/null ; then
+ typeset -g POWERLINE_CONFIG_COMMAND=powerline-config
+ else
+ typeset -g POWERLINE_CONFIG_COMMAND="${_POWERLINE_SOURCED:h:h:h:h}/scripts/powerline-config"
+ fi
+fi
+
+setopt promptpercent
+setopt promptsubst
+
+if "${POWERLINE_CONFIG_COMMAND}" shell --shell=zsh uses prompt ; then
+ _powerline_setup_prompt
+ _powerline_init_modes_support
+fi
+if "${POWERLINE_CONFIG_COMMAND}" shell --shell=zsh uses tmux ; then
+ _powerline_init_tmux_support
+fi