Reputation: 2240
I have a script that requires as an argument the name of command and arguments of that command.
So I want to write a completion function that would complete the name of the command and would complete the arguments for that command.
So I can complete the name of the command like this
if [[ "$COMP_CWORD" == 1 ]]; then
COMPREPLY=( $( compgen -c ${COMP_WORDS[COMP_CWORD]} ))
else
#Don't know what to write here
fi
So this will complete the first argument to list of shell commands that are available to run. And on second and other arguments I need a completion for
${COMP_WORDS[COMP_CWORD]}
command.
I thought about removing first element from COMP_WORDS
, decreasing COMP_CWORD
by one and call a function _${COMP_WORDS[0]}
with name that prefixes "_" to the command, because in many examples the function that completes a command has such name, but when I executed complete -p
in bash I found that many commands are completed with functions that has different names. And as for me, such solution looks really bad.
I'm not a bash scripting guru so I just don't know where to start searching the solution.
Upvotes: 8
Views: 2923
Reputation: 545508
I’ve had a similar issue but my command has subcommands and global options. For example, I needed to be able to complete the following:
mycmd -o foo run ls ./Tab
To make this work, _command
is insufficient. But _command_offset
works well. This is also what e.g. the sudo
completion uses. Here’s an example, from my implementation, which supports both short and long options with arguments:
_mycmd_completion() {
local cur prev words cword
_init_completion || return
local i
for ((i = 1; i < cword; i++)); do
case ${words[$i]} in
-o|--option) ((i++)) ;; # Skip option value
-o*|--option=*) ;;
*) break ;; # end of options
esac
done
case ${words[$i]} in
run)
_command_offset "$((i + 1))"
return
;;
…other commands…) … ;;
esac
COMPREPLY=($(compgen -W '--option -o run …other commands…' -- "$cur"))
}
complete -F _mycmd_completion mycmd
Upvotes: 2
Reputation: 20970
Your requirement is similar to the command completion for exec
or time
or xargs
. These commands also take a command & that command's arguments as completion options.
Checking the bash_completion option for exec
:
$ complete -p exec
complete -F _command exec
You can re-use the same function _command
as your completion function..
Usage:
complete -F _command your-script.sh
Upvotes: 6