16

Is there a way in zsh or bash to have a status line? e.g. in VI it will let you know that you are in insert mode with -- INSERT --

Is there an eqivalent for the command line?

ui_90jax
  • 759
  • 2
  • 6
  • 17

2 Answers2

21

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-init
zle -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]; }
Community
  • 1
  • 1
Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
  • 1
    hmmmm... Now I want to make it so that ctrl+c while in -- INSERT -- doesn't quit the command, but exits to NORMAL mode, then finally ctrl-c in NORMAL mode to exit the command. – trusktr Nov 09 '13 at 22:44
  • 1
    You can set different bindings for Ctrl+C in insert and normal mode, just pass the right option to `bindkey`. – Gilles 'SO- stop being evil' Nov 10 '13 at 17:43
  • Sweeet. I can't wait to do this. – trusktr Nov 11 '13 at 08:30
  • How can I use the second one (where the indicator is below) with a prompt that I already have? Where would I put my existing $PROMPT variable? I've tried it but then the label doesn't update between INSERT and NORMAL when switching modes. – user779159 Jan 13 '14 at 21:08
  • @user779159 Put your stuff in `PS1`. You need to use either `PROMPT` or `PS1`, they're aliases. – Gilles 'SO- stop being evil' Jan 13 '14 at 21:30
  • I am using a ZSH theme that has already generated a nice looking prompt. But when I try adding that $PROMPT variable to the PS1= assignment, it doesn't work properly to update the NORMAL/INSERT values. I can't tell what part of '%~ %# ' at the end to replace with $PROMPT, I've tried several combinations and they don't work. Could you tell me where I could put $PROMPT in that second line? Thanks – user779159 Jan 14 '14 at 09:27
  • @user779159 That depends on what your theme is doing. Try using `PROMPT` instead of `PS1`, maybe `PROMPT="%{$terminfo_down_sc$PS1_2$terminfo[rc]%}$PROMPT"`. Depending on the theme, you may have to add that bit somewhere else. If you can't figure it out, ask on [unix.se]. – Gilles 'SO- stop being evil' Jan 14 '14 at 10:50
2

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_NORMAL
ZVM_MODE_INSERT
ZVM_MODE_VISUAL
ZVM_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` function
function 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:

demo

J.T.
  • 864
  • 9
  • 17