Skip to content

Instantly share code, notes, and snippets.

@mentalisttraceur
Last active March 19, 2023 05:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mentalisttraceur/5e9eb83b5ca8c743d12977617ec7865c to your computer and use it in GitHub Desktop.
Save mentalisttraceur/5e9eb83b5ca8c743d12977617ec7865c to your computer and use it in GitHub Desktop.
zsh vi-like PS1
function _vi_ps1_update
{
local mode_indicator=?
case "$KEYMAP" in
'vicmd')
mode_indicator=-
;;
'main')
case $(bindkey -lL main) in
'bindkey -A viins main')
mode_indicator=I
;;
'bindkey -A emacs main')
mode_indicator=E
esac
esac
PS1=$mode_indicator${PS1#?}
PS2=$mode_indicator${PS2#?}
PS3=$mode_indicator${PS3#?}
}
_vi_ps1_need_init=1
function zle-line-init
{
case $_vi_ps1_need_init in 1)
PS1=?$PS1
PS2=?$PS2
PS3=?$PS3
_vi_ps1_need_init=0
esac
_vi_ps1_update
zle reset-prompt
}
zle -N zle-line-init
function zle-keymap-select
{
_vi_ps1_update
zle reset-prompt
}
zle -N zle-keymap-select
function zle-line-finish
{
PS1=${PS1#?}
PS2=${PS2#?}
PS3=${PS3#?}
_vi_ps1_need_init=1
zle reset-prompt
}
zle -N zle-line-finish
@mentalisttraceur
Copy link
Author

mentalisttraceur commented Oct 22, 2022

.zsh-vi-ps1 adds a vi mode indicator to the shell prompt: - when in command mode and I when in insert mode.

Named after the main shell prompt variable (PS1) because that's the name most commonly associated with changing the shell prompt, but also works on continuation lines (PS2) and when getting select input (PS3).

The mode indicator automatically disappears from finished command lines unless they are aborted (such as with Ctrl+C), and disappears from the PS? shell variables while each command runs. This results in a cleaner terminal scrollback with a visible cue for which lines weren't actually ran, and avoids messy interactions with other shell prompt changes (such as virtualenv activation or manual fiddling).

If you sometimes switch back to zshell's "default" (Emacs) keymap, the mode indicator will show it as E. Any other keymap will show up as ?.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment