automagical shell alias completion;
-
works with all common aliases, even self-aliases;
-
one completion function, for all aliases;
-
alias completion as easy as type-and-tab;
-
install dependency bash-completion;
-
linux:
install
bash-completion
using system package manager:dnf install bash-completion ## fedora apt install bash-completion ## debian
for other linux distros, see faq;
-
macos (experimental):
install
bash-completion
homebrew formulae version 2:brew install bash-completion@2
-
windows (experimental):
see faq;
-
-
source
complete_alias
in~/.bash_completion
:. {complete_alias}
where
{complete_alias}
is the path ofcomplete_alias
;
-
edit aliases to complete in
complete_alias
:for example, to complete aliases
foo
,bar
andbaz
:complete -F _complete_alias foo complete -F _complete_alias bar complete -F _complete_alias baz
-
to complete an alias, type it and press
<tab>
;
to complete alias sctl
aliased to systemctl
:
$ alias sctl='systemctl'
$ cp complete_alias ~/.complete_alias
$ echo ". ~/.complete_alias" >> ~/.bash_completion
$ echo "complete -F _complete_alias sctl" >> ~/.complete_alias
$ sctl <tab>
add-requires
add-wants
cancel
cat
condreload
...
to config complete-alias
, set these envars before sourcing the main script:
-
COMPAL_AUTO_UNMASK
this is a bool; default is
0
; when set to1
, enables auto unmask; when set to0
, uses manual unmask;auto unmask automatically manages non-alias command completions, but incurs a small overhead on source; manual unmask is the traditional way of setting non-alias command completions, which is static and faster but requires user intervention if the preset is not satisfying;
-
support for gnu bash(>=4.4) on linux is aimed;
-
support for older versions of bash is uncertain;
-
support for other shells is possible but unlikely;
-
support for other operating systems is experimental;
-
how to install it on windows?
support for windows is limited to msys2 and git for windows:
-
msys2:
msys2 features pacman so you can install like linux:
pacman -S bash-completion cat complete_alias >> ~/.bash_completion
-
git for windows:
tldr: steal
bash_completion
and source it beforecomplete_alias
;git for windows provides git bash, which is a minimal environment based on msys2; for what matters here, git bash does not have package manager; so the above install procedure does not apply;
the idea is, you must somehow get
bash-completion
and load it beforecomplete-alias
in a shell environment; for example, you can downloadbash-completion
package from a msys2 mirror; however, the easiest solution i found to make things work is to simply download the main scriptbash_completion
from its git repo; this does not give you its entirety, but is good enough to work;now you have 2 files:
bash_completion
andcomplete_alias
; you need to source them in this order in~/.bashrc
:. ~/.bash_completion.sh . ~/.complete_alias.sh
attention: here we renamed the files; we cannot use
~/.bash_completion
because this is the very filename sourced by the very script; using this filename will cause an infinite loop;now install is complete; add your own aliases in
~/.complete_alias.sh
;
-
-
how to install
bash-completion
on other linux distros?these commands are sourced from wikis and users:
pacman -S bash-completion ## arch yum install bash-completion ## centos emerge --ask app-shells/bash-completion ## gentoo zypper install bash-completion ## suse apt install bash-completion ## ubuntu
these commands are not tested; open a ticket if you find them not working;
-
how to complete all my aliases?
run this one-liner after all aliases have been defined:
complete -F _complete_alias "${!BASH_ALIASES[@]}"
it works like this:
complete -F _complete_alias foo complete -F _complete_alias bar complete -F _complete_alias baz ...
note that if you simply put this one-liner in
complete_alias
code, things may not work, depending on the order of file sourcing, which in turn varies across user configurations; the correct way to use this one-liner is to put it in the same file where aliases are defined; for example, if your aliases are defined in~/.bashrc
, then that file should look like this:alias foo='...' alias bar='...' alias baz='...' ... complete -F _complete_alias "${!BASH_ALIASES[@]}"
-
what are special characters in alias body?
these characters have special meanings and may cause errors when used in alias body (this is not a complete list):
-
newline (
\n
):we do not allow alias body to contain the newline character; this limits the cases to consider and makes smaller, faster code; we treat a newline as a word breaker in the outmost scope, but you better not rely on this;
-
backquote (
`
):avoid the old-style backquote form
`command`
of command substitution as much as possible; instead, use the$(command)
form; the backquote form is more tricky and less legible when nested in quotes or another command substitution; we do not intend to fully support backquotes; -
backslash (
\
):avoid backslashes unless you absolutely have to use them; they are mostly used to escape a character; we have double quotes that can do the same; the bash manual is not complete on where a backslash is special and where it is literal; and we may make mistakes on its interpretation;
-
colon (
:
):a colon seems innocent but is special to word completion code: it is one of the characters that breaks words for the completer; you can read more about it at this link; however, we do not guarantee the same treatment of colons here as there; we treat a colon as a word breaker in the outmost scope and a literal otherwise; if you always want it to be a literal, just quote it;
-
-
why is
sudo
completion not working correctly?there is a known case with
sudo
that can go wrong; for example:$ unalias sudo $ complete -r sudo $ alias ls='ping' $ complete -F _complete_alias ls $ sudo ls <tab> {ip} {ip} {ip} ...
here we are expecting a list of files, but the completion reply is a list of ip addrs; the reason is, the completion function for
sudo
is almost always_sudo
, which is provided bybash-completion
; this function stripssudo
then meta-completes the remaining command line; in our case, this isls
to be completed by_complete_alias
; but there is no way for_complete_alias
to see the original command line, and so it cannot tellls
fromsudo ls
; as a result,ls
andsudo ls
are always completed the same even when they should not; unfortunately, there is nothing_complete_alias
can do here;the easiest solution is to make
sudo
a self-alias:$ alias sudo='sudo' $ complete -F _complete_alias sudo $ alias ls='ping' $ complete -F _complete_alias ls $ sudo ls <tab> {file} {file} {file} ...
this gives
_complete_alias
a chance to see the original command line, then decide what is the right thing to do; you may add a trailing space tosudo
alias body if you like it that way, and things still work correctly (listing ip addrs is correct in this case):$ alias sudo='sudo ' $ complete -F _complete_alias sudo $ alias ls='ping' $ complete -F _complete_alias ls $ sudo ls <tab> {ip} {ip} {ip} ...
The source code is licensed under the GNU General Public License v3.0.
Copyright (C) 2016-2021 Cyker Way
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.