zsh vi mode status line
This has already been answered at Super User and Unix Stack Exchange. For the completeness of Stack Overflow:
function zle-line-init zle-keymap-select { RPS1="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}" RPS2=$RPS1 zle reset-prompt}zle -N zle-line-initzle -N zle-keymap-select
And if you want the indicator below the current line rather than to the right, from Unix Stack Exchange:
terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]function zle-line-init zle-keymap-select { PS1_2="${${KEYMAP/vicmd/-- NORMAL --}/(main|viins)/-- INSERT --}" PS1="%{$terminfo_down_sc$PS1_2$terminfo[rc]%}%~ %# " zle reset-prompt}preexec () { print -rn -- $terminfo[el]; }
Exactly, I can understand your concern and if you don't mind using a plugin, I think the below one can help you show the vi mode status perfectly, also the additional bonus of better experience on vi mode and so on.
zsh-vi-mode: A better and friendly vi(vim) mode plugin for ZSH.
https://github.com/jeffreytse/zsh-vi-mode
This plugin has provided a ZVM_MODE
variable for you to retrieve current vi mode and better show the indicator.
And currently the below modes are supported:
ZVM_MODE_NORMALZVM_MODE_INSERTZVM_MODE_VISUALZVM_MODE_VISUAL_LINE
For updating the vi mode indicator, we should add our commands to zvm_after_select_vi_mode_commands
. For example:
After you install this plugin
# The plugin will auto execute this `zvm_after_select_vi_mode` functionfunction zvm_after_select_vi_mode() { case $ZVM_MODE in $ZVM_MODE_NORMAL) # Something you want to do... ;; $ZVM_MODE_INSERT) # Something you want to do... ;; $ZVM_MODE_VISUAL) # Something you want to do... ;; $ZVM_MODE_VISUAL_LINE) # Something you want to do... ;; esac}
Here is an example: