r/zsh•
bshacklett

Unpredictable VI mode behavior on prompt return

I’ve been having some difficulties with VI mode exiting insert mode, seemingly at random, after the prompt returns. Worse, it takes about half a second for it to happen, so my inputs are often dropped. I’m sure there’s some logic to it, but I haven’t been able to isolate what causes the behavior.

Can anyone help me understand what might cause ZSH to switch to Normal mode without the escape key being pressed? Is there a non-hack-ish way to make the mode for the next prompt more consistent?

Edit: I use the Starship prompt.

Posted Dec 13, 2021, 4:59 PM UTC

16
romkatv•

I’ve been having some difficulties with VI mode exiting insert mode, seemingly at random, after the prompt returns.

What do you mean by "after the prompt returns"?

Can anyone help me understand what might cause ZSH to switch to Normal mode without the escape key being pressed?

With the default bindings, the current keymap changes from vicmd (a.k.a. vi command mode, a.k.a. vi normal mode) to viins (a.k.a. vi insert mode) when you press i, RETURN or ENTER.

If it changes for you when you press some other key, this is most likely caused by your configuration files.

1
bshacklettOP•

What do you mean by "after the prompt returns"?

I mean when the next prompt is displayed after a program terminates, after pressing ^(C,) ^C, etc.

1
okapi-a•

Do you have a zle-line-init hook defined? I.e. what does which zle-line-init output. Also check for zle-keymap-select and zle-line-pre-redraw hooks. Have you got any setup to display vi mode in the prompt because a bug in that is a likely culprit.

Can you elaborate on what you mean by "after pressing C,". Is the comma part of your key press? Did you actually mean Ctrl-C. I'm puzzled by Reddit's rendering of your C in superscript.

Also what is the value of $KEYTIMEOUT. The default of 20 can be somewhat too high on modern systems which has caused recommendations of 0 to circulate but 0 is really quite a bad idea. 5 may be a better choice. Many other keys generate a sequence that starts with an escape and could be being interpreted as an actual escape key press.

2
bshacklettOP•

Indeed, I did mean ^C. Now I know that Reddit enables superscript with ^.

I think you're onto something with the "setup to display vi mode in the prompt" note. I definitely do have something in place for that, which I'll take a look at shortly. I'll look for zle-line-init, et. al., as well.

Thanks!

Edit: Also, here's my vi-mode config: https://github.com/bgshacklett/dotzsh/blob/master/conf.d/00-vi-mode.zsh

I see that I'm pulling in a plug-in there. I'm going to see if an update helps, or if there are any known issues, there.

1
okapi-a•

The zle-line-init part of that plugin does:

[[ $VIM_MODE_KEYMAP = vicmd ]] && zle && zle vi-cmd-mode

To be sure I'd need to read through the whole plugin but at a guess, what it is trying to do is select normal mode if you were in normal mode for the previous command-line. That might explain why it appears to only happen randomly.

Does it help if, after setting up the plugin, you do:

add-zle-hook-widget -d zle-line-init vim-mode-line-init
1