zsh:使选项卡退出菜单完成并在最后一个条目上执行完成

zsh:使选项卡退出菜单完成并在最后一个条目上执行完成

我正在尝试从 bash 切换到 zsh,但我发现 zsh 有一个主要的不方便之处。我已取消menucomplete设置选项,绑定tabexpand-or-complete-prefix,并绑定alt-smenu-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

现在,tabmenu-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插入反而。它为您提供以下内容:

  1. 输入任何内容,就会自动列出补全内容。
    • 无需按⇥ Tab
    • 输入更多内容以缩小选择范围。
    • 这支持模糊的提前输入完成,这意味着您可以输入您要查找的单词的任何部分,只要您接下来输入的内容位于目标单词的右侧即可。
  2. ⇥ Tab插入顶部补全。
    • 如果这是一个目录,则会自动列出子目录。
    • 冲洗、起泡沫并重复。
  3. 如果您无法在顶部获得所需的完成信息,则可以使用↓ 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

相关内容