I am attempting to write a shell script utility that wraps other shell utilities into a single CLI and am trying to get shell completion to work in zsh and bash.
For example, let's say the CLI is named util
:
util aws [...args] #=> runs aws
util docker [...args] #=> runs docker
util terraform [...args] #=> runs terraform
What I would like, ideally, is a way in zsh and bash completion to be able to say "complete this subcommand X like other command Y" independently from the implementation of the completion for the wrapped scripts.
Something like:
compdef 'util aws'='aws'
compdef 'util docker'='docker'
compdef 'util terraform'='terraform'
A stretch goal would be to allow for completion of an arbitrary sub-command to a subcommand in another binary:
util aws [...args] #=> completes against `aws`
util ecr [...args] #=> completes against `aws ecr`
Is any of this possible? I've been attempting to emulate the completion scripts of the individual binaries, however there is significant variation in how other completion scripts are written.
I know nothing about zsh, but I can offer a solution for bash. It delegates using the _complete
function (which I found following muru's suggestion - good call!).
The second section of the function provides completions for the util
command itself, which I assume here will just be a list of subcommands. You can tailor that to your needs, of course.
The first section handles the delegation in the case where a full subcommand has been typed, and optionally a target for completion according to the subcommand's completion.
_delegate() {
local cur subs
cur="${COMP_WORDS[COMP_CWORD]}" # partial word, if any
subs="ssh aws docker terraform"
if [[ $COMP_CWORD == 2 ]]; then
# Two whole words before the cursor - delegate to the second arg
_command $2
else
# complete with the list of subcommands
COMPREPLY=( $(compgen -W "${subs}" -- ${cur}) )
fi
}
njv@pandion:~$ complete -F _delegate util
1d [njv@eidolon:~] $ util
aws docker ssh terraform
1d [njv@eidolon:~] $ util ssh
::1 gh ip6-localhost ubuntu.members.linode.com
eidolon github.com ip6-loopback
ff02::1 ip6-allnodes localhost
ff02::2 ip6-allrouters ubuntu
1d [njv@eidolon:~] $ util ssh ip6-
ip6-allnodes ip6-allrouters ip6-localhost ip6-loopback
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With