I am aware how to set ZSH's default line editor to use vi-like keybindings...

bindkeys -v

...and even to default each new prompt to be in command mode instead of insert mod by default...

zle-line-init() { zle -K vicmd; }
zle -N zle-line-init

...and most of the time I prefer this behavior. However, it makes a few things very awkward. For example pasting multi-line commands into a terminal for immediate execution becomes nearly impossible.

How can I configure it so that the mode is persistent? I would like whatever mode it was when I executed one line should be the default mode for the next line.

1 Answer 1


Maybe like:

vicmd-accept() { prev_mode=vicmd; zle .accept-line }
viins-accept() { prev_mode=viins; zle .accept-line }
zle-line-init() { zle -K ${prev_mode:-viins} }
zle -N viins-accept
zle -N vicmd-accept
zle -N zle-line-init
bindkey -M viins \\r viins-accept
bindkey -M vicmd \\r vicmd-accept

Or even simpler:

accept-line() { prev_mode=$KEYMAP; zle .accept-line }
zle-line-init() { zle -K ${prev_mode:-viins} }
zle -N accept-line
zle -N zle-line-init
  • I see what you did there. Subtle ;-)
    – Caleb
    Jan 25, 2014 at 14:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.