【问题标题】:How can I make bash tab completion behave like vim tab completion and cycle through matching matches?如何使 bash 选项卡完成的行为类似于 vim 选项卡完成并循环匹配匹配项?
【发布时间】:2011-11-03 00:36:22
【问题描述】:

多年来,我一直想为此找到解决方案。

由于这个原因,我在处理文件时使用 vim 比使用 bash 更有效率。

如果我有

file_12390983421
file_12391983421
file_12340983421
file_12390986421

在 bash 中并输入 file_1->tab ,它显然列出了:

file_12390983421 file_12391983421 file_12340983421 file_12390986421

这是一个可怕的无聊和痛苦的工作。

vim 中的相同序列将一次循环一个文件。

请有人告诉我如何在 bash 中执行此操作,或者如果有另一个 shell 可以执行此操作,我将在明天切换。

【问题讨论】:

  • bind TAB:menu-complete 放入.bashrc
  • 默认使用菜单完成
  • @D.BenKnoble C-n 和 C-p 对我没有任何作用...
  • @pixelearth 可能只在vi编辑模式下(set -o vi)

标签: bash shell vim


【解决方案1】:

对于 bash >= 4,您可能会喜欢这些设置。您可以直接在命令行上试用它们,如果您喜欢它们,可以将它们放入您的~/.bash_profile

# If there are multiple matches for completion, Tab should cycle through them
bind 'TAB:menu-complete'

# Display a list of the matching files
bind "set show-all-if-ambiguous on"

# Perform partial (common) completion on the first Tab press, only start
# cycling full results on the second Tab press (from bash version 5)
bind "set menu-complete-display-prefix on"

这个设置类似于 Vim 的set wildmode=longest:full:list,full

我从 Unix & Linux 网站上的 this question 中提取了这些设置。


顺便说一句,既然你在这里,这是另一对不错的绑定:

# Cycle through history based on characters already typed on the line
bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'

这意味着,如果您输入 ssh<Up>,它将循环遍历您之前运行 ssh 的行

如果你不喜欢你得到的东西,你可以用 Ctrl-K Ctrl-U

清除该行

我从 AskUbuntu 上的 this question 中提取了这些设置。

【讨论】:

  • 如果您使用的是 Mac OS X,请查看您的 bash --version。我的 Mac 只有 bash 版本 3,不幸的是,这意味着最后两个绑定将无效。
  • 我有一个关于在 macOS 上获取最新的bash(当前为 5.0.2)stackoverflow.com/a/55011144/117471 的答案
  • 此配置需要在 .bashrc 中(其他一些答案提到 .inputrc)。
  • 请注意,如果它不明确(这可能有用也可能没用),除非它绑定到其他一些键,否则打开 show-all-if-ambiguous 将不允许菜单完成。 // 同样,要找出发送的键码,请在键之前按
  • @Étienne .bashrc 似乎适用于别名。但是,在使用 rsync 时绑定会引发错误(“警告:未启用行编辑”)。所以我建议将这些绑定放入.bash_profile。更好的是,它们可以放入.inputrc,但需要适当格式化(删除bind 命令和引号)。
【解决方案2】:

根据我的经验,某事的答案中提供的解决方案从未完全适合我。 TL;DR:将set -o vi 添加到您的~/.bashrc

当结合 vi 键绑定使用 menu-complete 时,我必须确保我的 ~/.bashrc 具有:

set -o vi

我的~/.inputrc 仅仅拥有:

TAB: menu-complete

set editing-mode vi
set keymap vi

我的猜测是 set editing-modeset keymap 以某种方式破坏了 TAB: ... 设置,但我还没有彻底查看文档以弄清楚为什么会这样。

【讨论】:

  • 我找不到 TAB 命令。我尝试将编辑模式和键盘映射设置为 vi 但仍然没有,在 macOS 上的 inputrc 中找不到 bash 命令
  • @MladenPetrovic - 第一个set... 部分进入~/.bashrc,第二个TAB:... 部分进入~/.inputrc。如果你把那部分放在~/.bashrc中,你会得到TAB command not found
【解决方案3】:

在上面

# cycle forward
Control-k: menu-complete
# cycle backward
Control-j: menu-complete-backward

你也可以考虑添加

# display one column with matches
set completion-display-width 1

这样您将保留当前的 ​​Tab 功能并使 bash 在一列中显示可能性。所以不是

file_12340983421 file_12390983421 file_12390986421 file_12391983421

你会得到

file_12340983421
file_12390983421
file_12390986421
file_12391983421

附:您可以从这个The GNU Readline Library 网站获取最新的readline 库。

【讨论】:

    【解决方案4】:

    感谢@sth,我找到了最适合我的方法:

    保持正常的 bash tab 补全,然后在需要的时候使用 menu-complete 使用 ctl-f 循环浏览

    把它放在你的 .inputrc 文件中:

    "\C-f": menu-complete
    

    【讨论】:

      【解决方案5】:

      默认情况下TAB 绑定到complete readline 命令。您想要的行为将是menu-complete。您可以通过编辑 ~/.inputrc 来更改您的 readlines 设置。要重新绑定TAB,请添加以下行:

      TAB: menu-complete
      

      有关详细信息,请参阅man bash 中的READLINE 部分。

      【讨论】:

      • 这非常有效。一件事,有没有办法让它倒退?在vim中我使用shift+tab,如果我不小心走远了,我就回去,或者如果我想从列表的末尾开始。我整天在 vim 中做的事情......但似乎不适用于 menu-complete。
      • menu-complete 将自动替换您的输入,但不会显示候选列表。有没有办法做到这两点?
      • @pixelearth: 还有menu-complete-backward,至少在我的终端Shift-Tab 似乎发送\e[Z 转义序列。这会给你这个 .inputrc 条目:"\e[Z": menu-complete-backward
      • 如果您可以循环浏览各种可能性并查看可能性列表,就像在 vim 中一样,那将是非常酷的。循环遍历目录中每个可能的文件名只是为了在完成命令时找出其中的内容是很痛苦的。
      • 不确定这是否仍然相关,但我遇到了与 James M. Lay 相同的问题,并通过将 Tab:complete "\e[Z":menu-complete 放入我的 .inputrc 来解决它。这样,Tab 具有原始行为,Shift + Tab 允许您循环浏览建议。编辑:Tab:complete 之后应该有一个换行符。我无法在 cmets 中正确设置它的样式。
      猜你喜欢
      • 2013-11-18
      • 2012-06-12
      • 1970-01-01
      • 2011-07-31
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      相关资源
      最近更新 更多