Here is my take on VI mode indicator in zsh’s prompt. This is useful only for people who use the vi mode (bindkey -v
) in ZSH.
vim_ins_mode="%{$fg[cyan]%}[INS]%{$reset_color%}"
vim_cmd_mode="%{$fg[green]%}[CMD]%{$reset_color%}"
vim_mode=$vim_ins_mode
function zle-keymap-select {
vim_mode="${${KEYMAP/vicmd/${vim_cmd_mode}}/(main|viins)/${vim_ins_mode}}"
zle reset-prompt
}
zle -N zle-keymap-select
function zle-line-finish {
vim_mode=$vim_ins_mode
}
zle -N zle-line-finish
# Fix a bug when you C-c in CMD mode and you'd be prompted with CMD mode indicator, while in fact you would be in INS mode
# Fixed by catching SIGINT (C-c), set vim_mode to INS and then repropagate the SIGINT, so if anything else depends on it, we will not break it
# Thanks Ron! (see comments)
function TRAPINT() {
vim_mode=$vim_ins_mode
return $(( 128 + $1 ))
}
And then it’s a matter of adding ${vim_mode}
somewhere in your prompt. For example like this:
RPROMPT='${vim_mode}'
Other examples on the web use zle reset-prompt
in the zle-line-init
, which has a very nasty side effect of deleting last couple of lines on mode change (when going from ins
to cmd
mode) when using multi-line prompt. Using zle-line-finish
works around that.
Also see my current ~/.zshrc, which includes those tweaks (and many others!).