(Even More) Advanced Bash Completion

In my previous post, I described how to set up tab completion for many common commands using these Bash completion files. This works well for established commands, but it doesn’t work so well for commands that I have written myself.

I use a command called “hc12-console” to connect to 68HC12 microcontrollers over a serial port. The command takes two arguments: the name of a microcontroller to connect to and a file to load. I only have two microcontrollers called “dragon1” and “dragon2”. Therefore, I want to be able to tab complete the first argument to one of those values only. The second argument should be the name of a file that ends in “.load”.

I do this with a function that checks the argument number and then completes it based on a specified list or by limiting the types of files that will be listed.

_hc12console ()
{
	local cur

	COMPREPLY=()
	cur=${COMP_WORDS[COMP_CWORD]}

	# First argument completes with either dragon1 or dragon2
	if [[ $COMP_CWORD -eq 1 ]] ; then
		COMPREPLY=( $( compgen -W "dragon1 dragon2" -- $cur ) )
		return 0
	fi

	# Second argument completes with only files matching *.load
	if [[ $COMP_CWORD -eq 2 ]] ; then
		COMPREPLY=( $( compgen -f -X '!*.load' -- $cur ) )
		return 0
	fi

	# All other arguments will not auto-complete
	return 0
}
complete -F _hc12console hc12-console

I added the script above to a file that my bashrc sources. It associates the function with the shell command, and then instead of manually typing out:

hc12-console dragon1 file.load <enter>

I can type:

hc12<tab> <tab>1 <tab> <enter>