From becc8ee59c3be3ab1165f963d13239af186d2fda Mon Sep 17 00:00:00 2001 From: ZyX Date: Sat, 22 Jun 2013 23:48:05 +0400 Subject: [PATCH 1/5] =?UTF-8?q?Support=20zsh=20=E2=80=9Cmodes=E2=80=9D=20(?= =?UTF-8?q?different=20keymaps=20like=20when=20using=20vicmd/viins=20pair)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #508 --- powerline/bindings/zsh/powerline.zsh | 41 +++++++++++++++++++ .../colorschemes/shell/default.json | 10 ++++- .../colorschemes/shell/solarized.json | 10 ++++- .../config_files/themes/shell/default.json | 4 ++ powerline/lint/__init__.py | 26 ++++++++++-- powerline/renderer.py | 5 ++- powerline/renderers/ipython.py | 2 +- powerline/renderers/tmux.py | 3 +- powerline/renderers/vim.py | 2 +- powerline/segments/shell.py | 28 +++++++++++++ scripts/powerline | 1 + 11 files changed, 122 insertions(+), 10 deletions(-) diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index 917f5a8b..34d0cfc6 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -59,6 +59,47 @@ _powerline_setup_prompt() { 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 + eval "${old_widget_command/$widget/$save_widget}" + zle -N $widget $function + export POWERLINE_SAVE_WIDGET="$save_widget" + fi +} + +_powerline_zle_keymap_select() { + export POWERLINE_MODE="${KEYMAP}" + zle reset-prompt + test -z "$POWERLINE_SAVE_WIDGET" || zle $POWERLINE_SAVE_WIDGET +} + +_powerline_set_mode() { + local keymap + if test -z "$(bindkey -lL main)" ; then + keymap=".safe" + else + keymap="main" + fi + export POWERLINE_MODE="${keymap}" +} + +_powerline_set_mode + +_powerline_add_widget zle-keymap-select _powerline_zle_keymap_select + trap "_powerline_tmux_set_columns" SIGWINCH _powerline_tmux_set_columns _powerline_tmux_set_pwd diff --git a/powerline/config_files/colorschemes/shell/default.json b/powerline/config_files/colorschemes/shell/default.json index 61fecdad..d4f5a6f2 100644 --- a/powerline/config_files/colorschemes/shell/default.json +++ b/powerline/config_files/colorschemes/shell/default.json @@ -14,6 +14,14 @@ "hostname": { "fg": "brightyellow", "bg": "mediumorange" }, "exit_fail": { "fg": "white", "bg": "darkestred" }, "exit_success": { "fg": "white", "bg": "darkestgreen" }, - "environment": { "fg": "white", "bg": "darkestgreen" } + "environment": { "fg": "white", "bg": "darkestgreen" }, + "mode": { "fg": "darkestgreen", "bg": "brightgreen", "attr": ["bold"] } + }, + "mode_translations": { + "vicmd": { + "groups": { + "mode": {"fg": "darkestcyan", "bg": "white", "attr": ["bold"]} + } + } } } diff --git a/powerline/config_files/colorschemes/shell/solarized.json b/powerline/config_files/colorschemes/shell/solarized.json index 121dd16b..e87abe8e 100644 --- a/powerline/config_files/colorschemes/shell/solarized.json +++ b/powerline/config_files/colorschemes/shell/solarized.json @@ -14,6 +14,14 @@ "hostname": { "fg": "oldlace", "bg": "darkgreencopper" }, "exit_fail": { "fg": "oldlace", "bg": "red" }, "exit_success": { "fg": "oldlace", "bg": "green" }, - "environment": { "fg": "oldlace", "bg": "green" } + "environment": { "fg": "oldlace", "bg": "green" }, + "mode": { "fg": "oldlace", "bg": "green", "attr": ["bold"] } + }, + "mode_translations": { + "vicmd": { + "groups": { + "mode": { "fg": "oldlace", "bg": "blue", "attr": ["bold"] } + } + } } } diff --git a/powerline/config_files/themes/shell/default.json b/powerline/config_files/themes/shell/default.json index 89dfa33a..35e8e18b 100644 --- a/powerline/config_files/themes/shell/default.json +++ b/powerline/config_files/themes/shell/default.json @@ -16,6 +16,10 @@ }, "segments": { "left": [ + { + "module": "powerline.segments.shell", + "name": "mode" + }, { "name": "hostname" }, diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 9d7a009b..6d778234 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -535,15 +535,15 @@ group_name_spec = Spec().re('^\w+(?::\w+)?$').copy groups_spec = Spec().unknown_spec( group_name_spec(), group_spec(), -).copy +).context_message('Error while loading groups (key {key})').copy colorscheme_spec = (Spec( name=name_spec(), - groups=groups_spec().context_message('Error while loading groups (key {key})'), + groups=groups_spec(), ).context_message('Error while loading coloscheme')) vim_mode_spec = Spec().oneof(set(list(vim_modes) + ['nc'])).copy vim_colorscheme_spec = (Spec( name=name_spec(), - groups=groups_spec().context_message('Error while loading groups (key {key})'), + groups=groups_spec(), mode_translations=Spec().unknown_spec( vim_mode_spec(), Spec( @@ -558,6 +558,24 @@ vim_colorscheme_spec = (Spec( ), ).context_message('Error while loading mode translations (key {key})'), ).context_message('Error while loading vim colorscheme')) +shell_mode_spec = Spec().re('^(?:[\w\-]+|\.safe)$').copy +shell_colorscheme_spec = (Spec( + name=name_spec(), + groups=groups_spec(), + mode_translations=Spec().unknown_spec( + shell_mode_spec(), + Spec( + colors=Spec().unknown_spec( + color_spec(), + color_spec(), + ).optional(), + groups=Spec().unknown_spec( + group_name_spec().func(check_translated_group_name), + group_spec(), + ).optional(), + ), + ).context_message('Error while loading mode translations (key {key})'), +).context_message('Error while loading shell colorscheme')) generic_keys = set(('exclude_modes', 'include_modes', 'width', 'align', 'name', 'draw_soft_divider', 'draw_hard_divider', 'priority', 'after', 'before')) @@ -1106,6 +1124,8 @@ def check(path=None, debug=False): colorscheme_configs[ext][colorscheme] = config if ext == 'vim': spec = vim_colorscheme_spec + elif ext == 'shell': + spec = shell_colorscheme_spec else: spec = colorscheme_spec if spec.match(config, context=(('', config),), data=data, echoerr=ee)[1]: diff --git a/powerline/renderer.py b/powerline/renderer.py index 0555caef..256d11f0 100644 --- a/powerline/renderer.py +++ b/powerline/renderer.py @@ -150,7 +150,7 @@ class Renderer(object): segment['divider_highlight'] = None return segment - def get_segment_info(self, segment_info): + def get_segment_info(self, segment_info, mode): '''Get segment information. Must return a dictionary containing at least ``home``, ``environ`` and @@ -167,6 +167,7 @@ class Renderer(object): :return: dict with segment information. ''' r = self.segment_info.copy() + r['mode'] = mode if segment_info: r.update(segment_info) if 'PWD' in r['environ']: @@ -201,7 +202,7 @@ class Renderer(object): Matcher information. Is processed in ``.get_theme()`` method. ''' theme = self.get_theme(matcher_info) - segments = theme.get_segments(side, self.get_segment_info(segment_info)) + segments = theme.get_segments(side, self.get_segment_info(segment_info, mode)) # Handle excluded/included segments for the current mode segments = [self._get_highlighting(segment, mode) for segment in segments diff --git a/powerline/renderers/ipython.py b/powerline/renderers/ipython.py index f5c2b24b..8de06dfe 100644 --- a/powerline/renderers/ipython.py +++ b/powerline/renderers/ipython.py @@ -9,7 +9,7 @@ class IpythonRenderer(ShellRenderer): escape_hl_start = '\x01' escape_hl_end = '\x02' - def get_segment_info(self, segment_info): + def get_segment_info(self, segment_info, mode): r = self.segment_info.copy() r['ipython'] = segment_info return r diff --git a/powerline/renderers/tmux.py b/powerline/renderers/tmux.py index c237ae1a..5daccbbb 100644 --- a/powerline/renderers/tmux.py +++ b/powerline/renderers/tmux.py @@ -46,7 +46,7 @@ class TmuxRenderer(Renderer): tmux_attr += ['nounderscore'] return '#[' + ','.join(tmux_attr) + ']' - def get_segment_info(self, segment_info): + def get_segment_info(self, segment_info, mode): r = self.segment_info.copy() if segment_info: r.update(segment_info) @@ -54,6 +54,7 @@ class TmuxRenderer(Renderer): varname = 'TMUX_PWD_' + r['pane_id'].lstrip('%') if varname in r['environ']: r['getcwd'] = lambda: r['environ'][varname] + r['mode'] = mode return r diff --git a/powerline/renderers/vim.py b/powerline/renderers/vim.py index 8ee1bf0b..6065dbbf 100644 --- a/powerline/renderers/vim.py +++ b/powerline/renderers/vim.py @@ -74,7 +74,7 @@ class VimRenderer(Renderer): def strwidth(string): return vim.strwidth(string) - def get_segment_info(self, segment_info): + def get_segment_info(self, segment_info, mode): return segment_info or self.segment_info def render(self, window, window_id, winnr): diff --git a/powerline/segments/shell.py b/powerline/segments/shell.py index 07212059..962a1a26 100644 --- a/powerline/segments/shell.py +++ b/powerline/segments/shell.py @@ -41,3 +41,31 @@ def last_pipe_status(pl, segment_info): for status in last_pipe_status] else: return None + + +@requires_segment_info +def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, default='main'): + '''Return the current mode. + + :param dict override: + dict for overriding mode strings. + :param str default: + If current mode is equal to this string then this segment will not get + displayed. + ''' + mode = segment_info['mode'] + if not mode: + pl.warn('No or empty POWERLINE_MODE variable') + return None + if mode == default: + return None + try: + return override[mode] + except KeyError: + # Note: with zsh line editor you can emulate as much modes as you wish. + # Thus having unknown mode is not an error: maybe just some developer + # added support for his own zle widgets. As there is no built-in mode() + # function like in VimL and POWERLINE_MODE is likely be defined by our + # code or by somebody knowing what he is doing there is absolutely no + # need in keeping translations dictionary. + return mode.upper() diff --git a/scripts/powerline b/scripts/powerline index e6517c7f..3192b4af 100755 --- a/scripts/powerline +++ b/scripts/powerline @@ -22,6 +22,7 @@ if __name__ == '__main__': width=args.width, side=args.side, segment_info=segment_info, + mode=os.environ.get('POWERLINE_MODE'), ) try: sys.stdout.write(rendered) From 34d4877abff71f09484938212ed38deab1fe4863 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 17 Nov 2013 00:12:40 +0400 Subject: [PATCH 2/5] Some fixes for powerline.zsh: - Replace main and other linked modes with modes they link to - Add proper keymap initialization Ref #508 --- powerline/bindings/zsh/powerline.zsh | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index 34d0cfc6..ec4ebab8 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -36,6 +36,7 @@ _powerline_precmd() { # wrong number of jobs. You need to filter the lines first. Or not use # jobs built-in at all. _POWERLINE_JOBNUM=${(%):-%j} + _powerline_set_true_keymap_name "${${(Q)${${(z)${"$(bindkey -lL main)"}}[3]}}:-.safe}" } _powerline_setup_prompt() { @@ -47,6 +48,7 @@ _powerline_setup_prompt() { done precmd_functions+=( _powerline_precmd ) chpwd_functions+=( _powerline_tmux_set_pwd ) + _powerline_set_true_keymap_name "${${(Q)${${(z)${"$(bindkey -lL main)"}}[3]}}:-.safe}" if zmodload zsh/zpython &>/dev/null ; then zpython 'from powerline.bindings.zsh import setup as powerline_setup' zpython 'powerline_setup()' @@ -80,25 +82,22 @@ _powerline_add_widget() { fi } +_powerline_set_true_keymap_name() { + export 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 +} + _powerline_zle_keymap_select() { - export POWERLINE_MODE="${KEYMAP}" + _powerline_set_true_keymap_name $KEYMAP zle reset-prompt test -z "$POWERLINE_SAVE_WIDGET" || zle $POWERLINE_SAVE_WIDGET } -_powerline_set_mode() { - local keymap - if test -z "$(bindkey -lL main)" ; then - keymap=".safe" - else - keymap="main" - fi - export POWERLINE_MODE="${keymap}" -} - -_powerline_set_mode - _powerline_add_widget zle-keymap-select _powerline_zle_keymap_select +_powerline_precmd trap "_powerline_tmux_set_columns" SIGWINCH _powerline_tmux_set_columns From 36c007058d418fdbcd530df30193a1ec1750ee00 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 17 Nov 2013 01:36:16 +0400 Subject: [PATCH 3/5] Omit any non-vi* mode by default --- powerline/bindings/zsh/powerline.zsh | 4 ++++ powerline/segments/shell.py | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/powerline/bindings/zsh/powerline.zsh b/powerline/bindings/zsh/powerline.zsh index ec4ebab8..6b55f1c3 100644 --- a/powerline/bindings/zsh/powerline.zsh +++ b/powerline/bindings/zsh/powerline.zsh @@ -99,6 +99,10 @@ _powerline_zle_keymap_select() { _powerline_add_widget zle-keymap-select _powerline_zle_keymap_select _powerline_precmd +if [[ "$POWERLINE_MODE" != vi* ]] ; then + export POWERLINE_DEFAULT_MODE="$POWERLINE_MODE" +fi + trap "_powerline_tmux_set_columns" SIGWINCH _powerline_tmux_set_columns _powerline_tmux_set_pwd diff --git a/powerline/segments/shell.py b/powerline/segments/shell.py index 962a1a26..1245d109 100644 --- a/powerline/segments/shell.py +++ b/powerline/segments/shell.py @@ -44,19 +44,22 @@ def last_pipe_status(pl, segment_info): @requires_segment_info -def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, default='main'): +def mode(pl, segment_info, override={'vicmd': 'COMMND', 'viins': 'INSERT'}, default=None): '''Return the current mode. :param dict override: dict for overriding mode strings. :param str default: If current mode is equal to this string then this segment will not get - displayed. + displayed. If not specified the value is taken from + ``$POWERLINE_DEFAULT_MODE`` variable. This variable is set by zsh + bindings for any mode that does not start from ``vi``. ''' mode = segment_info['mode'] if not mode: pl.warn('No or empty POWERLINE_MODE variable') return None + default = default or segment_info['environ'].get('POWERLINE_DEFAULT_MODE') if mode == default: return None try: From 8984647106c928f055c227b1c3c5b255653404e6 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 26 Jan 2014 22:26:29 +0400 Subject: [PATCH 4/5] Add tests --- tests/test_shells/input.zsh | 5 +++++ tests/test_shells/zsh.ok | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/test_shells/input.zsh b/tests/test_shells/input.zsh index b3b3ba59..20383310 100644 --- a/tests/test_shells/input.zsh +++ b/tests/test_shells/input.zsh @@ -19,6 +19,11 @@ cd ../'#[bold]' cd ../'(echo)' cd ../'$(echo)' cd ../'`echo`' +cd .. +POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,5] ) ; bindkey -v + + +echo abc false true is the last line exit diff --git a/tests/test_shells/zsh.ok b/tests/test_shells/zsh.ok index 9ebcfb60..bde41125 100644 --- a/tests/test_shells/zsh.ok +++ b/tests/test_shells/zsh.ok @@ -16,4 +16,10 @@   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  #[bold]  cd ../'(echo)'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`' -  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  false +  HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd .. +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,5] ) ; bindkey -v + INSERT  USER  ⋯  tests  shell  3rd   COMMND  USER  ⋯  tests  shell  3rd   + INSERT  USER  ⋯  tests  shell  3rd   + INSERT  USER  ⋯  tests  shell  3rd  echo abc +abc + INSERT  USER  ⋯  tests  shell  3rd  false From 6ba13c1d0f725521b6e8c42d6c5d6bb08ebb0271 Mon Sep 17 00:00:00 2001 From: ZyX Date: Sun, 26 Jan 2014 22:35:02 +0400 Subject: [PATCH 5/5] Modify appropriate theme --- tests/test_shells/input.zsh | 2 +- tests/test_shells/zsh.ok | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_shells/input.zsh b/tests/test_shells/input.zsh index 20383310..8cd28d54 100644 --- a/tests/test_shells/input.zsh +++ b/tests/test_shells/input.zsh @@ -20,7 +20,7 @@ cd ../'(echo)' cd ../'$(echo)' cd ../'`echo`' cd .. -POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,5] ) ; bindkey -v +POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,4] ${${POWERLINE_COMMAND[5]}/_leftonly} ) ; bindkey -v  echo abc diff --git a/tests/test_shells/zsh.ok b/tests/test_shells/zsh.ok index bde41125..dbc5e17b 100644 --- a/tests/test_shells/zsh.ok +++ b/tests/test_shells/zsh.ok @@ -17,9 +17,9 @@   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  (echo)  cd ../'$(echo)'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  $(echo)  cd ../'`echo`'   HOSTNAME  USER   BRANCH  ⋯  shell  3rd  `echo`  cd .. -  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,5] ) ; bindkey -v - INSERT  USER  ⋯  tests  shell  3rd   COMMND  USER  ⋯  tests  shell  3rd   - INSERT  USER  ⋯  tests  shell  3rd   - INSERT  USER  ⋯  tests  shell  3rd  echo abc +  HOSTNAME  USER   BRANCH  ⋯  tests  shell  3rd  POWERLINE_COMMAND=( $POWERLINE_COMMAND[1,4] ${${POWERLINE_COMMAND[5]}/_leftonly} ) ; bindkey -v + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   COMMND   HOSTNAME  USER  ⋯  tests  shell  3rd   + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd   + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  echo abc abc - INSERT  USER  ⋯  tests  shell  3rd  false + INSERT   HOSTNAME  USER  ⋯  tests  shell  3rd  false