我真的很喜欢zsh的一般速度,但是有两件事使我烦恼。
- 我必须在点击逃脱和点击斜线之间稍等片刻才能进入历史记录搜索(如果搜索斜线的速度过快,它会说
zsh: do you wish to see all 514 possibilities (172 lines)
) - 由于按
a
或进入插入模式后A
,我不能退格到进入插入模式的位置。
我知道2就像经典vi,但我更喜欢vim样式。
我真的很喜欢zsh的一般速度,但是有两件事使我烦恼。
zsh: do you wish to see all 514 possibilities (172 lines)
)a
或进入插入模式后A
,我不能退格到进入插入模式的位置。我知道2就像经典vi,但我更喜欢vim样式。
Answers:
(1)。出于某种原因,bindkey在涉及“ /”时会表现出奇怪的现象:<esc>
快速后跟/
被解释为<esc-/>
。(前几天我观察到了此行为;不太清楚是什么原因造成的。)我不知道这是错误还是功能,是否可以禁用它是否是功能,但是您可以很轻松地解决它。
该组合键可能已绑定到_history-complete-older
,从而生成了不希望的结果–您可以bindkey -L
查看是否存在这种情况。
无论如何,如果您不介意牺牲实际 <esc-/>
(按在一起的和弦)绑定,则可以将其重新绑定到vi-mode历史搜索命令,以便键入<esc>
后跟/
键入在任何键入时都可以执行相同的操作速度。=)
由于这将被视为和弦,因此先进入vi命令模式不会产生效果,因此我们必须确保首先发生这种情况。首先,您需要定义一个函数;fpath
如果使用它,请将其放在您的某个位置,否则将其放在您的.zshrc中:
vi-search-fix() {
zle vi-cmd-mode
zle .vi-history-search-backward
}
其余的以两种方式进入您的.zshrc:
autoload vi-search-fix
zle -N vi-search-fix
bindkey -M viins '\e/' vi-search-fix
应该很好走。
(2)。您可以按以下方式修复退格键:
`bindkey "^?" backward-delete-char`
另外,如果您希望其他vi样式命令具有类似的行为:
bindkey "^W" backward-kill-word
bindkey "^H" backward-delete-char # Control-h also deletes the previous char
bindkey "^U" backward-kill-line
^[/
不是在之下\e/
,但这些都是说逃避的有效方法。所做的更改非常完美。现在,我正在更全面地使用它,与bash相比,zsh的vi模式看起来很烂(或者至少在默认情况下未完全配置)。一个例子是事实,它使您在搜索历史记录之后进入插入模式。我必须返回命令模式以按n查找下一个搜索项。
.vi-history-search-backward
。我将编写并编辑答案-今天晚些时候再回来查看。
bindkey | grep <searchterm>
为任何一个术语做时,它们都以前缀vi-
。我是否需要设置bindkey
没有前缀的命令vi-
?
我只想解决问题(1)。
您的问题是KEYTIMEOUT。我引用zshzle(1):
当ZLE从终端读取命令时,ZLE可能会读取绑定到某个命令的序列,该序列也是更长绑定字符串的前缀。在这种情况下,ZLE将等待一段时间以查看是否键入了更多的字符,如果没有键入(或它们不再与任何更长的字符串匹配),它将执行绑定。此超时是由KEYTIMEOUT参数定义的;其默认值为0.4秒。如果前缀字符串本身未绑定到命令,则没有超时。
0.4s是您按下ESC后所经历的延迟。解决方法是在其中一个外壳启动文件中将KEYTIMEOUT正确设置为0.01s:
export KEYTIMEOUT=1
不幸的是,这会产生连锁反应:其他事情开始出错…
首先,现在在vi命令模式下存在一个问题:键入ESC会使光标挂起,然后吞下下一个键入的字符。这是因为在vi命令模式下,默认情况下ESC没有绑定任何东西,但是有许多以ESC开头的多字符小部件(光标键!)。因此,当您按下ESC时,ZLE等待下一个字符…然后使用它。
解决方法是在命令模式下将ESC绑定到某事物,从而确保该事物在$ KEYTIMEOUT厘秒后传递到ZLE。现在,我们可以在命令模式下使绑定从ESC开始,而不会产生不良影响。我将ESC绑定到响铃字符,发现它比自动插入更具侵入性(并且我的外壳已静音):
bindkey -sM vicmd '^[' '^G'
2017年更新:
从那以后,我找到了绑定ESC的更好解决方案-
undefined-key
小部件。我不确定最初写此答案时此小部件是否在zsh中可用。
bindkey -M vicmd '^[' undefined-key
下一个问题:在vi插入模式下,默认情况下有一些以^ X开头的两键小部件;如果将$ KEYTIMEOUT设置为最低,则这些将变得不可用。我要做的是在vi插入模式下取消绑定^ X(默认情况下是自动插入);这使这些两键小部件可以继续工作。
bindkey -rM viins '^X'
您会失去自我插入的绑定,但是当然可以将其绑定到其他对象。(我没有,因为我没有用。)
最后一个问题(到目前为止,我已经找到了):由于将$ KEYTIMEOUT正确设置为负,因此我们遗失了一些默认的键绑定:在vi插入模式下以ESC开头的不是光标键。我个人将它们重新绑定为以^ X开头:
bindkey -M viins '^X,' _history-complete-newer \
'^X/' _history-complete-older \
'^X`' _bash_complete-word
更新2018:
事实证明,不一定需要上面的整个部分(“ Update 2017”之后)。可以使用以下命令在键盘映射中将META键设置为与ESC等效:
bindkey -mv
因此,可以不解除^ X的绑定,而可以通过按META键(而不是现代键盘上的ALT或OPT)来访问以ESC开始的键绑定。
如果您可以访问Kiddle等人的《从Bash到Z Shell》一书,则在第78-79页的第4章侧栏中将讨论键绑定中ESC和META的等效性。
i
两次才能回到插入模式,我强烈建议您修复此问题!