In a simple world, it is quite straightforward to perform tab-completion for Bash aliases. Suppose we want to create the alias
/etc/bash_completion.d/docker is the completion script for Docker. It is sourced when the shell starts, loading a
_docker function into the shell’s namespace. It executes
complete -F _docker docker and thus
docker has tab-completion. Bestowing the alias
docker’s tab-completion is as simple as:
complete -F _docker d
Now upon entering
d Tab, we see a pretty list of Docker commands.
Of course the world is rarely so simple. Loading hundreds or thousands of completion scripts for every new interactive shell is quite slow. So starting with version 1.90, Bash supports dynamically loaded completions.
Let us suppose that we’d like to create the alias
git and enable tab-completion. Where to start?
We need to source
git’s completion script so that it’s completion function is in the shell’s namespace and available to us. We can go about this a couple of different ways.
We can source it ourselves, but where is the file? Try
dpkg -L git | grep bash-completion. We git lucky and see that it’s located at /usr/share/bash-completion/completions/git. So we can run
. /usr/share/bash-completion/completions/git. But we may not always be so lucky, so this isn’t a great option.
Another option is to have it loaded dynamically. Simply enter
git Tab. But we’d like to be able to do this programmatically.
To do so programmatically, we have
_completion_loader, a function included in the
bash-completion package. As you might expect, it loads the completions for a given command.
It will return an exit status of 124, disregard it. You can read more about programmable completion and
_completion_loader in Bash’s manual.
git’s completion script has been loaded, we need to figure out exactly what was loaded and how.
complete -p git
complete -o bashdefault -o default -o nospace -F __git_wrap__git_main git. Great, now we know how to bestow
complete -o bashdefault -o default -o nospace -F __git_wrap__git_main g
F.Y.I. the aforementioned command is equivalent to the following:
complete -o bashdefault -o default -o nospace -F _git g
This is what all of this would look like in a .bashrc or .bash_aliases.
Note: Ensure programmable completion is sourced before the following code. If you see an error like _completion_loader: command not found, you’ll want to move the programmable completion portion of .bashrc above the alias definitions. Alternatively you can manually source it by running
alias g=git _completion_loader git complete -o bashdefault -o default -o nospace -F _git g
Just out of curiosity, let’s see how we could do this a bit more programmatically.
Note that all of the aforementioned code is only useful for simple aliases like
alias g=git. Completion for subcommands requires a different approach. Luckily
git makes this pretty easy. For example, providing completion for something like
git diff entails the following:
alias gd="git diff" _completion_loader git __git_complete gd _git_diff
More complex aliases involving option flags or pipes require wrapper functions and are beyond the scope of this article. For more information on setting up programmable completion for these sorts of aliases, see: