在 zsh 的 vi 模拟中,转义不是幂等的吗?

在 zsh 的 vi 模拟中,转义不是幂等的吗?

我已将 zsh 配置为使用 vi 键绑定。我注意到“escape”出现了一些意外行为。在 vim 中(我尚未测试 vanilla vi),如果我按两次 escape,我可以按一次“i”返回到插入模式。在 zsh 中,如果我碰巧按了两次 escape,按“i”不会让我返回到插入模式,我必须按两次。另一个例子出现在导航中。如果我按了一次 escape,我可以按预期使用“^”和“$”。但是,如果我不小心按了两次 escape(或更多),它们将无法工作,直到我返回到插入模式并再次按 escape。

我是否以某种方式错误地配置了 zsh,或者这只是 zsh 的 vi 仿真中的一个已知差异?

答案1

我也遇到过这种情况。之前没有注意到,因为我通常在 shell 中使用 emacs 绑定。似乎使用默认绑定时,在 vicmd 模式下使用 Esc 键会吃掉下一个字符。这似乎是处理未定义键时的一个错误。

我可以通过在 vicmd 模式下为退出键定义一个 noop 绑定来解决此问题:

noop () { }
zle -N noop
bindkey -M vicmd '\e' noop

答案2

我在这里没有足够的声誉来回复 qqx 的回答,所以我只需要提交一个单独的答案:

这不是一个错误;实际发生的情况如下:当你第一次按下 ESC 时,你会从 vi 插入模式切换到 vi 命令模式(显然)。然后你在 vi 命令模式下再次按下 ESC。问题是,默认情况下,ESC 在命令模式下不与任何东西绑定,然而,有以 ESC 开头的多键小部件,绑定——值得注意的是箭头键发送的控制序列。

因此,如果您在 vi 命令模式下按下 ESC,ZLE 会等待小部件的第二次击键。这就是为什么如果您按下“i”(或任何字符),它会被 ZLE 默默地占用。

答案是在 vi 命令模式下将 ESC 绑定到某个东西(任何东西),正如 qqx 在他的回答中所说的那样。

答案3

这似乎不是 zsh 5.6.2 的问题。

需要考虑的事项是KEYTIMEOUT=1在您的 中进行设置~/.zshrc

按键超时

当读取绑定的多字符序列时,shell 等待另一个键被按下的时间(以百分之一秒为单位)。

查看zsh 参数文档

相关内容