如何使bash制表符补全像vim制表符补全,并在匹配匹配之间循环?


73

我一直想为YEARS找到一个解决方案。

因此,在处理文件时,我在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可以执行此操作,我明天将切换。



1
bind TAB:menu-complete.bashrc
克劳迪奥(Claudio)

1
<Cn>和<Cp>默认情况下使用菜单完成
D. Ben Knoble

@ D.BenKnoble Cn和Cp对我没有任何帮助...
pixelearth

1
@pixelearth它可能只有在vi编辑模式(set -o vi
D.本Knoble

Answers:


89

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

TAB: menu-complete

有关更多详细信息,请参见中的READLINE部分man bash


1
这很完美。一件事,有没有办法让它倒退?在vim中,我使用shift + tab,如果不小心走了很远,我就回去,或者如果我想从列表的末尾开始。我整天都在vim中做某事...但是似乎不能与菜单完成一起使用。
pixelearth 2011年

8
menu-complete将自动替换您输入的内容,但不会显示候选列表。有办法做到这两者吗?
莱昂,

18
@pixelearth:还有menu-complete-backward,至少在我的终端机上Shift-Tab似乎发送了\e[Z转义序列。这为您提供了这个.inputrc条目:"\e[Z": menu-complete-backward
sth

2
如果您可以循环浏览各种可能性并查看各种可能性的清单(例如在vim中),那真是太酷了。遍历目录中每个可能的文件名只是为了查找完成命令后的内容,这是一个痛苦的过程。
James M. Lay 2015年

6
不知道如果这仍然是相关的,但我有同样的问题,因为詹姆斯·M·莱和通过将解决它 Tab:complete "\e[Z":menu-complete 在我的.inputrc。这样,Tab具有原始行为,并且Shift+Tab可让您循环浏览建议。编辑:应该在之后有一个换行符Tab:complete。我无法在评论中将其样式化。
karpfen '16

28

对于bash> = 4,您可能会喜欢这些设置。您可以直接在命令行上尝试使用它们,.bashrc如果愿意,可以将它们放入您的系统中。

# 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 completion on the first Tab press,
# only start cycling full results on the second Tab press

bind "set menu-complete-display-prefix on"

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

我从Unix&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上的这个问题中拉出了这些设置。


2
如果您使用的是Mac OS X,请检查您的bash --version。我的Mac仅具有bash版本3,很遗憾,这意味着最后两个绑定将无效。
joeytwiddle


2
此配置需要在.bashrc中(其他答案提到.inputrc)。
艾蒂安

请注意,如果模棱两可(如果可能是有用的或可能不是有用的),则打开显示所有模棱两可的内容将不允许菜单完成,除非将其绑定到其他某些键上。//同样,要找出发送的键控代码,请在键之前按<control + v>。
user202729 '20

14

在之上

# 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:您可以readline从此GNU Readline Library网站获取最新的库。


6

感谢@sth,我发现了最适合我的方法:

要保持正常的bash选项卡完成,然后在需要时使用ctl-f使用菜单完成来循环显示

将其放在您的.inputrc文件中:

"\C-f": menu-complete

0

根据我的经验,sth的答案中提供的解决方案从未完全适用于我。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命令
Mladen Petrovic

1
@MladenPetrovic-第一set...部分进入~/.bashrc,第二TAB:...部分进入~/.inputrcTAB command not found如果把那部分放进去,你会得到的~/.bashrc
特里·布朗
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.