![zsh:使选项卡退出菜单完成并在最后一个条目上执行完成](https://linux22.com/image/174044/zsh%EF%BC%9A%E4%BD%BF%E9%80%89%E9%A1%B9%E5%8D%A1%E9%80%80%E5%87%BA%E8%8F%9C%E5%8D%95%E5%AE%8C%E6%88%90%E5%B9%B6%E5%9C%A8%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E6%9D%A1%E7%9B%AE%E4%B8%8A%E6%89%A7%E8%A1%8C%E5%AE%8C%E6%88%90.png)
我正在尝试从 bash 切换到 zsh,但我发现 zsh 有一个主要的不方便之处。我已取消menucomplete
设置选项,绑定tab
到expand-or-complete-prefix
,并绑定alt-s
到menu-complete
。
但是,一旦我通过按 调用菜单完成alt-s
,随后点击tab
将继续循环浏览菜单完成条目,而不是像 bash 那样退出菜单完成并在最后显示的条目上执行完成。我想要这个的主要原因是,如果我想要cd
/ls
进入多个嵌套目录,我可以快速“进入”最后显示的目录。
我使用的是 zsh 版本 5.8,并且在我的 ~/.zshrc 中有以下内容:
setopt autolist
unsetopt automenu autoremoveslash listambiguous menucomplete
bindkey '^i' expand-or-complete-prefix # Bind tab
bindkey '^[s' menu-complete # Bind alt-s to menu-complete
这是一个工作示例:
$ mkdir dir dir/a dir/b dir/b/d dir/c
$ ls dir/ <alt-s>
$ ls dir/a/ <alt-s>
$ ls dir/b/ <tab>
$ ls dir/c/ <tab>
$ ls dir/a/ <tab>
$ ls dir/b/ <tab>
$ ls dir/c/
...etc.
相反,我想像bash 一样tab
“进入” :dir/b/
$ ls dir/ <alt-s>
$ ls dir/a/ <alt-s>
$ ls dir/b/ <tab>
$ ls dir/b/d/ <-- Pressing tab exits menu-complete and immediately goes into the currently displayed directory.
有谁知道我如何才能获得这种行为?非常感谢你的帮助!
编辑:
我通过将以下内容添加到 ~/.zshrcmenuselect
找到了一个稍微缓解的解决方案:zsh/complist
zmodload -i zsh/complist
bindkey -M menuselect '^i' accept-line
zstyle ':completion:*' menu select=1
现在,tab
在menu-complete
操作过程中按退出menu-complete
。但是,它不会“进入”最后显示的目录,我必须tab
再次按才能在最后显示的目录中执行自动完成。因此,tab
在 zsh 中按两次而不是在 bash 中按一次即可获得相同的功能。
请注意,有一个不同的menuselect
选项:
bindkey -M menuselect '^i' accept-and-infer-next-history
只需按一下即可“进入”最后显示的目录tab
,但menu-select
在该目录中执行,而不是tab
像我想要的那样正常完成。
如果有人知道我如何只需按一下按键即可获得此功能tab
,我将不胜感激。是否可以为 编写自定义 zle 命令menuselect
,例如accept-and-complete-next-history
?
答案1
配置 Zsh 的完成系统来完成您在这里所要求的操作需要相当多的代码行,尽管它实际上能够做到这一点。我建议使用我的,而不是自己做zsh-autocomplete
插入反而。它为您提供以下内容:
- 输入任何内容,就会自动列出补全内容。
- 无需按⇥ Tab。
- 输入更多内容以缩小选择范围。
- 这支持模糊的提前输入完成,这意味着您可以输入您要查找的单词的任何部分,只要您接下来输入的内容位于目标单词的右侧即可。
- 按⇥ Tab插入顶部补全。
- 如果这是一个目录,则会自动列出子目录。
- 冲洗、起泡沫并重复。
- 如果您无法在顶部获得所需的完成信息,则可以使用↓ Down(加上其他箭头键)导航到它。
- 如果您根本没有看到所需的完成情况,请尝试按⌃ Ctrl␣ Space。这将导致显示额外的完成情况(如果有)。
答案2
嗯,你的zsh-autocomplete
插件看起来很有趣,马龙先生,必须检查一下。
无论如何,我找到了解决原始问题的方法。基本上,我只是创建了一个简单的小部件来执行我想要的操作。在~/.zshrc中:
zmodload -i zsh/complist
accept-and-complete-next-history() {
zle expand-or-complete-prefix
}
zle -N accept-and-complete-next-history
bindkey -M menuselect '^i' accept-and-complete-next-history
zstyle ':completion:*' menu select=1
或者等价地:
zmodload -i zsh/complist
bindkey -M menuselect '^i' .expand-or-complete-prefix
zstyle ':completion:*' menu select=1