I have a command line tool which takes arguments in an three-part form:
$ t first_second_third
I have a set of valid values for first
, a set of valid values for second
, and a set of valid values for third
. I want to use Bash complete functionality to complete each part of the option value, as in this example:
$ t [tab][tab] # shows options for first part
walk run skip bike
$ t w[tab] # completes first part and appends delimiter
$ t walk_[tab][tab] # shows options for second part
home work park
$ t walk_h[tab] # completes second part and appends delimiter
$ t walk_home_[tab][tab] # shows options for second part
morning afternoon evening
$ t walk_home_a[tab] # completes second part and appends space
$ t walk_home_afternoon
I have this code:
_tool () {
local cur="${COMP_WORDS[COMP_CWORD]}"
local first="walk run skip bike"
local second="home work park"
local third="morning afternoon evening"
case "${cur}" in
*_*_*)
COMPREPLY=( $(compgen -W "${third}" -- "") ); return 0;;
*_*)
COMPREPLY=( $(compgen -W "${second}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
*)
COMPREPLY=( $(compgen -W "${first}" -S "_" -- ${cur}) ); compopt -o nospace; return 0;;
esac
}
complete -F _tool t
The first clause works great; nothing special there. But the second clause gives me no options or completions.
$ t [tab][tab]
bike_ run_ skip_ walk_
$ t b[tab]
$ t bike_[tab][tab] # nothing but bells
I replaced the second clause with the following (i.e. I replaced ${cur}
with an empty string in the COMPREPLY
call):
COMPREPLY=( $(compgen -W "${second}" -S "_" -- "") ); compopt -o nospace; return 0;;
I get a list of all options on the command line, but no completions.
$ t bike_[tab][tab]
home_ park_ work_
$ t bike_h[tab][tab]
home_ park_ work_
$ t bike_ho[tab][tab]
home_ park_ work_
I thought there might be some bad interaction with ${cur}
and the COMPREPLY
word list, so I changed the second clause again, adding a prefix which matches the first part of the current word:
local prefix=( $(expr "${cur}" : '\(.*_\)') )
COMPREPLY=( $(compgen -W "${second}" -P "${prefix}" -S "_" -- "") ); compopt -o nospace; return 0;;
This did not help much. With ${cur}
still in the COMPREPLY
command, I got no options or completions again. With an empty string instead, I got the full option (not just the curent part). But, pressing tab would erase what is typed.
$ t bike_[tab][tab]
bike_home_ bike_park_ bike_work_
$ t bike_ho[tab]
$ t bike_ # "ho" was erased
Of course, I have the same problem with the third part, too.
- How can I get Bash to complete the current word, part by part?
- How can I get Bash to not append the delimiter until an option has been selected?
This is similar to another Bash complete question, but I do not want to list every possible permutation of the values and they are not formatted as filenames (not sure if the filename pattern makes a difference).
Thanks for the help!
--ap
$IFS
variable to include the_
character? I will need to give that a try. – Optime