我真的很喜欢 zsh 的一般速度,但是有两件事让我很恼火。
zsh: do you wish to see all 514 possibilities (172 lines))a或进入插入模式后A,我无法退格超过进入插入模式的点。我知道 2 就像经典的 vi,但我更喜欢 vim 风格。
Mar*_*nks 26
(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
}
Run Code Online (Sandbox Code Playgroud)
其余的都在你的 .zshrc 中:
autoload vi-search-fix
zle -N vi-search-fix
bindkey -M viins '\e/' vi-search-fix
Run Code Online (Sandbox Code Playgroud)
去应该不错。
(2). 您可以按如下方式修复退格键:
`bindkey "^?" backward-delete-char`
Run Code Online (Sandbox Code Playgroud)
此外,如果您希望其他 vi 样式命令具有类似的行为:
bindkey "^W" backward-kill-word
bindkey "^H" backward-delete-char # Control-h also deletes the previous char
bindkey "^U" backward-kill-line
Run Code Online (Sandbox Code Playgroud)
wjv*_*wjv 13
我只打算解决问题(1)。
您的问题是 KEYTIMEOUT。我引自 zshzle(1):
当 ZLE 从终端读取命令时,它可能会读取一个绑定到某个命令的序列,并且也是一个较长绑定字符串的前缀。在这种情况下,ZLE 将等待一段时间来查看是否输入了更多字符,如果没有(或者它们不再匹配任何更长的字符串),它将执行绑定。此超时由 KEYTIMEOUT 参数定义;它的默认值为 0.4 秒。如果前缀字符串本身未绑定到命令,则不会超时。
0.4 秒是您按下 ESC 后遇到的延迟。解决方法是在 shell 启动文件之一中将 KEYTIMEOUT 设置为 0.01 秒:
export KEYTIMEOUT=1
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会产生连锁反应:其他事情开始出错……
首先,现在 vi 命令模式存在一个问题:输入 ESC 会导致光标挂起,然后您接下来输入的任何字符都会被吞下。这是因为 ESC 在 vi 命令模式下默认没有绑定到任何东西,但有以 ESC 开头的多字符小部件(光标键!)。因此,当您按下 ESC 时,ZLE 会等待下一个字符……然后将其消耗掉。
修复方法是在命令模式下将 ESC 绑定到某些内容,从而确保在 $KEYTIMEOUT 厘秒后将某些内容传递给 ZLE。现在我们可以在命令模式下保持以 ESC 开头的绑定,而不会产生这些不良影响。我将 ESC 绑定到钟形字符,我发现它比自插入更不具有侵入性(并且我的外壳被静音):
bindkey -sM vicmd '^[' '^G'
Run Code Online (Sandbox Code Playgroud)
2017 年更新:
从那以后,我找到了一个更好的绑定 ESC 的解决方案——
undefined-key小部件。当我最初写这个答案时,我不确定这个小部件是否在 zsh 中可用。
bindkey -M vicmd '^[' undefined-key
下一个问题:在 vi 插入模式下,默认有一些以 ^X 开头的双键小部件;如果 $KEYTIMEOUT 一直设置为向下,这些将变得不可用。我所做的是在 vi 插入模式下解除 ^X 的绑定(默认情况下它是自插入的);这允许那些两键小部件继续工作。
bindkey -rM viins '^X'
Run Code Online (Sandbox Code Playgroud)
你失去了自我插入的绑定,但你当然可以将它绑定到其他东西。(我没有,因为我没有用它。)
最后一个问题(到目前为止我已经找到了):由于将 $KEYTIMEOUT 设置为正确,我们“丢失”了一些剩余的默认键绑定,即:那些在 vi 插入模式下以 ESC 开头的不是光标键。我个人重新绑定它们以 ^X 开头:
bindkey -M viins '^X,' _history-complete-newer \
'^X/' _history-complete-older \
'^X`' _bash_complete-word
Run Code Online (Sandbox Code Playgroud)
2018 年更新:
事实证明,不一定需要上面的整个部分(在“2017 年更新”之后)。可以使用以下方法将 META 键设置为与键盘映射中的 ESC 等效:
bindkey -mv因此,可以不解除 ^X 绑定,并通过按 META 作为引导键(现代键盘上的 ALT 或 OPT)来访问在 ESC 中开始的键绑定。
如果您可以阅读Kiddle 等人的《从 Bash 到 Z Shell》一书,则第 78-79 页的第 4 章侧边栏中讨论了键绑定中 ESC 和 META 的等效性。
| 归档时间: |
|
| 查看次数: |
10857 次 |
| 最近记录: |