In order to get easy bash completion for my scripts' command line switches, I have been exploring the _parse_help function in /etc/bash_completion (debian sid, bash v4.2-1, bash-completion v1:1.99-3).
My script generates a help message in what I believe to be standard GNU format:
MYSCRIPT [OPTIONS]
Usage:
-h, --help Show this help message
-o, --option Some option
I then activate completion via complete -F _parse_help ./myscript
.
Unfortunately this does not give the desired result. Upon first tab ./myscript <TAB>
(note, just a single keypress) an unformatted list appears containing --help and --option, not the shortened versions. Worse, completion of either option fails. In fact, just typing a dash causes _parse_help to completely stop generating output.
The whole thing feels very much broken, and I cannot find much reference of it online. Is this function perhaps considered obsolete? Is there another standard method of command line completion based on parsing --help output?
According to the bash reference manual the -F function
expects to read the word list from a variable COMPREPLY
It would appear that _parse_help
does not set this required variable and would therefor not be suited as a function for complete -F
. The output is obviously echo'd as is evident from executing the function.
$ _parse_help ./myscript
-h
--help
-o
--option
@gertjan What you were attempting can be accomplished using the -W wordlist
option instead.
$ complete -W "$(_parse_help ./myscript)" ./myscript
$ ./myscript -
--help --option -h -o
$ ./myscript --
--help --option
$ ./myscript --help
Completion works as expected and --h
will complete --help
or where there were multiple arguments like with "--" it will only list the appropriate options.
If we were trying to use a function however it is not sufficient alone to only set COMPREPLY
as you will see from the next example.
NOTE: COMPREPLY
is a bash array and requires the brackets ()
when set
$ function _myscript () {
> COMPREPLY=($(_parse_help ./myscript))
> }
$ complete -F _myscript ./myscript
$ ./myscript -
--help --option -h -o
$ ./myscript --
--help --option -h -o
$ ./myscript --help
--help --option -h -o
As you can see, even though the options are displayed, complete
now expects us to do the filtering. We can accomplish this with compgen
but first we need to determine what the current argument is to filter against. The function _get_comp_words_by_ref
can help with this by populating the $cur
variable, as per our final example.
The complete implementation using a function with _parse_help
for bash completion.
$ function _myscript () {
> _get_comp_words_by_ref cur
> COMPREPLY=($(compgen -W "$(_parse_help ./myscript)" -- "$cur"))
> }
$ complete -F _myscript ./myscript
$ ./myscript -
--help --option -h -o
$ ./myscript --
--help --option
$ ./myscript --help
nJoy!