I love Bash tab completion, and I want it for the command I am writing, so it can automatically complete parts of the command line when I run my program.
Code
Here is the script (install-bash-completion) I wrote to set it up (no need to be root – it installs in ~/.local):
#!/bin/bash
set -u
set -e
DIR=${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions
mkdir -p ${DIR}
cp _myprogram ${DIR}
The actual completion script (_myprogram) it installs looks like this:
_myprogram_commands()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
opts=$(bash -c "./myprogram --commands")
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
}
complete -F _myprogram_commands ./myprogram
Installing
To install it, run:
./install-bash-completion
Then log out and log in again.
Now when you type ./myprogram and press TAB a couple of times, you should see the possible completions listed.
Notes
The completion script must be named to match the program name, with a leading underscore.
If I wanted it to work when it was installed in my PATH, I would need to change ./myprogram to just myprogram in 2 places.
Notice the line opts=$(bash -c "./myprogram --commands") – it actually runs my program to get the list of completions. This means my program needs to accept a --commands option which prints the valid commands. Alternatively, I could have hard-coded it by replacing that line with just:
opts="cmd1 cmd2 --help --etc"
More info: