Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have zsh configured to use vi keybindings. I've noticed some unexpected behavior with "escape". In vim (I haven't tested vanilla vi) if I hit escape twice, I can hit 'i' once to return to insert mode. In zsh if I happen to hit escape twice, hitting 'i' won't return me to insert mode, I have to hit it twice. Another example of this comes up in navigation. If I hit escape once, I can use '^' and '$' as expected. But if I've accidentally hit escape twice (or more) they fail to work until I return to insert mode and escape again.

Do I somehow have zsh configured incorrectly, or is this just a known difference in zsh's vi emulation?

share|improve this question

I get that as well. Hadn't noticed it before, since I generally use emacs bindings in my shell. It seems that with the default bindings, using the escape key in vicmd mode eats the next character. This seems like it may be a bug in handling of undefined keys.

I was able to work around this issue by defining a noop binding for the escape key in vicmd mode using:

noop () { }
zle -N noop
bindkey -M vicmd '\e' noop
share|improve this answer
Thanks! I had kind of expected that I could perhaps do something by binding escape in vicmd mode, but wasn't sure if there was something more going on here. I'm surprised other users haven't made an issue of it. Maybe I'm just too absent minded of a vi user, hitting escape all the time. – user1063042 Dec 8 '12 at 4:00
This has been plaguing me for days, thank you! – cchamberlain Jul 24 '15 at 2:51

I don't have enough reputation here to reply to qqx's answer, so I'll just have to file a separate answer:

It's not a bug; what happens is the following: When you hit ESC the first time, you switch from vi insert mode to vi command mode (obviously). Then you hit ESC again in vi command mode. The problem is that, by default, ESC is not bound to anything in command mode, however, there are multi-key widgets starting with ESC which are bound — notably, the control sequences sent by the arrow keys.

Hence, if you hit ESC in vi command mode, ZLE sits there waiting for the second keystroke of the widget. That is why, if you hit 'i' (or any character), it gets silently consumed by ZLE.

The answer is to bind ESC to something — anything — in vi command mode, exactly as qqx stated in his answer.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .