ChatGPT解决这个技术问题 Extra ChatGPT

如何使 bash 选项卡完成的行为类似于 vim 选项卡完成并循环匹配匹配项?

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

出于这个原因,在处理文件时,我在 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
默认使用 menu-complete
@D.BenKnoble Cn 和 Cp 对我无能为力...
@pixelearth 它可能仅处于 vi 编辑模式 (set -o vi)

s
sth

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

TAB: menu-complete

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


这完美地工作。一件事,有没有办法让它倒退?在vim中我使用shift+tab,如果我不小心走远了,我就回去,或者如果我想从列表的末尾开始。我整天在 vim 中做的事情......但似乎不适用于菜单完成。
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 之后应该有一个换行符。我无法在评论中正确设置样式。
j
joeytwiddle

对于 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 & 上的 this question 中提取了这些设置。 Linux 站点。

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

# 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 上在 stackoverflow.com/a/55011144/117471 上获取最新 bash(当前为 5.0.2)的答案
此配置需要在 .bashrc 中(其他一些答案提到 .inputrc)。
请注意,如果菜单不明确,则打开 show-all-if-ambiguous 将不允许菜单完成(这可能有用也可能没有用),除非它绑定到其他一些键。 // 另外,要找出发送的键码,请在键之前按
@xr280xr 我的一个假设是 .inputrc 是它们“应该”去的地方(并且可能会减少 bash 的解析)。但经过调查,我发现放入 .inputrc 的绑定不仅会被 bash 使用,而且会被所有使用 readline 的程序使用!
J
Johnny Baloney

在之上

# 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

PS 您可以从此The GNU Readline Library 网站获取最新的readline 库。


p
pixelearth

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

保持正常的 bash 选项卡完成,然后在需要时使用 ctl-f 循环使用 menu-complete

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

"\C-f": menu-complete

B
Bruno Bronosky

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

将 menu-complete 与 vi 键绑定结合使用时,我必须确保我的 ~/.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