As an example, say that I type part of a name:
$ vi partn <= here I press <tab><tab>
partname partnook partnum <= these are the results
This is standard behaviour in bash
and that is fine, but I've been working a lot on PowerShell lately where the default behaviour is that if you press tab, it cycles through the names, completing each name and then pressing tab again will go to the next file, so if I pressed tab one time, I see vi ./partname
, then press tab again, I see vi ./partnook
, then tab again I see vi ./partnum
. I tend to prefer this behaviour as it's less typing (you just hit tab to cycle through until you get the filename or command that you want).
Everything is customisable in Linux of course, so can someone advise how I might change the default bash
behaviour to follow the above by default?
To persistently make tab-completion not require two Tab keypresses whenever there are multiple matching completions and to instead cycle through them, in-line:
Option A: If you either already have:
/etc/inputrc
file (applies system-wide, modification requires sudo
)~/.inputrc
file (user-specific)and/or
you're planning to customize the Readline library extensively and/or want to make customizations effective for scripts too when they call read -e
:
Add line:
"\C-i": menu-complete
to either file, depending on whether you want the setting to be effective for all users or the current user (create the file, if necessary).
Note: Alternatively, you can simply turn off the need to press Tab twice and exhibit the standard behavior instantly, which means showing a multi-column list of all possible completions, and then redisplaying the input line, to allow you to type additional characters to either fully complete the argument or to type enough of it so that the next Tab keypress unambiguously completes:
set show-all-if-ambiguous on
Option B: Alternatively, you may add Readline commands to your user-specific initialization file (~/.bash_profile
on macOS, ~/.bashrc
on Linux and other Unix-like platforms), by passing them as a single argument to the bind
builtin:
bind '"\C-i": menu-complete'
If you prefer the show-all-matches behavior:
bind 'set show-all-if-ambiguous on'
Note that bind
commands in ~/.bash_profile
/ ~/.bashrc
take precedence over equivalent commands in either /etc/inputrc
or ~/.inputrc
.
As implied above, configuring Readline this way will not take effect in scripts that call read -e
in order to activate Readline support for reading user input.