diff --git a/cmd/dbc/completions/dbc.bash b/cmd/dbc/completions/dbc.bash index 5b604ba9..a5faf992 100644 --- a/cmd/dbc/completions/dbc.bash +++ b/cmd/dbc/completions/dbc.bash @@ -7,14 +7,33 @@ _dbc() { local subcommands="install uninstall list init add sync search info docs remove completion auth" local global_opts="--help -h --version --quiet -q" - # If we're completing the first argument (subcommand) - if [[ $cword -eq 1 ]]; then + # Skip leading global options to find the subcommand. + local i=1 + while [[ $i -lt $COMP_CWORD ]]; do + case "${COMP_WORDS[i]}" in + -*) + ((i += 1)) + ;; + *) + break + ;; + esac + done + + # If we're completing the subcommand itself + if [[ $i -ge $COMP_CWORD ]]; then COMPREPLY=($(compgen -W "$subcommands $global_opts" -- "$cur")) return 0 fi - # Get the subcommand (first argument) - local subcommand="${words[1]}" + local subcommand="${COMP_WORDS[i]}" + + # The per-subcommand completers index COMP_WORDS positionally (subcommand + # at 1), so hand them a view with the global options removed. + local -a sub_words=("${COMP_WORDS[0]}" "${COMP_WORDS[@]:i}") + local sub_cword=$((COMP_CWORD - i + 1)) + local -a COMP_WORDS=("${sub_words[@]}") + local COMP_CWORD=$sub_cword case "$subcommand" in install) diff --git a/cmd/dbc/completions/dbc.fish b/cmd/dbc/completions/dbc.fish index 622d6f96..ef355dd0 100644 --- a/cmd/dbc/completions/dbc.fish +++ b/cmd/dbc/completions/dbc.fish @@ -1,8 +1,27 @@ # fish completion for dbc -*- shell-script -*- +# Tokens before the cursor with leading global options removed, so the +# subcommand is always at index 2. +function __fish_dbc_tokens + set -l tokens (commandline -opc) + printf '%s\n' $tokens[1] + set -l i 2 + while test $i -le (count $tokens) + switch $tokens[$i] + case '-*' + set i (math $i + 1) + case '*' + break + end + end + if test $i -le (count $tokens) + printf '%s\n' $tokens[$i..-1] + end +end + # Helper function to check if a subcommand has been given function __fish_dbc_needs_command - set -l cmd (commandline -opc) + set -l cmd (__fish_dbc_tokens) set -e cmd[1] if test (count $cmd) -eq 0 return 0 @@ -12,7 +31,7 @@ end # Helper function to check if we're using a specific subcommand function __fish_dbc_using_subcommand - set -l cmd (commandline -opc) + set -l cmd (__fish_dbc_tokens) if test (count $cmd) -gt 1 if test $argv[1] = $cmd[2] return 0 @@ -111,7 +130,7 @@ complete -f -c dbc -n '__fish_dbc_using_subcommand completion' -a 'fish' -d 'Gen # Helper function to check if we're using auth subcommand and need a nested subcommand function __fish_dbc_auth_needs_subcommand - set -l cmd (commandline -opc) + set -l cmd (__fish_dbc_tokens) if test (count $cmd) -eq 2 if test $cmd[2] = "auth" return 0 @@ -122,7 +141,7 @@ end # Helper function to check if we're using a specific auth subcommand function __fish_dbc_auth_using_subcommand - set -l cmd (commandline -opc) + set -l cmd (__fish_dbc_tokens) if test (count $cmd) -gt 2 if test $cmd[2] = "auth" -a $argv[1] = $cmd[3] return 0 @@ -150,7 +169,7 @@ complete -f -c dbc -n '__fish_dbc_auth_using_subcommand logout' -l purge -d 'Rem # Helper function to check if we need a license subcommand function __fish_dbc_auth_license_needs_subcommand - set -l cmd (commandline -opc) + set -l cmd (__fish_dbc_tokens) if test (count $cmd) -eq 3 if test $cmd[2] = "auth" -a $cmd[3] = "license" return 0 @@ -161,7 +180,7 @@ end # Helper function to check if we're using a specific auth license subcommand function __fish_dbc_auth_license_using_subcommand - set -l cmd (commandline -opc) + set -l cmd (__fish_dbc_tokens) if test (count $cmd) -gt 3 if test $cmd[2] = "auth" -a $cmd[3] = "license" -a $argv[1] = $cmd[4] return 0 diff --git a/cmd/dbc/completions/dbc.zsh b/cmd/dbc/completions/dbc.zsh index c6db9d2c..34d493dd 100644 --- a/cmd/dbc/completions/dbc.zsh +++ b/cmd/dbc/completions/dbc.zsh @@ -6,7 +6,13 @@ compdef _dbc dbc function _dbc { local line state + # Global options are declared as _arguments specs (not listed as values + # below) so _arguments offers them and skips them when locating the + # subcommand. _arguments -C \ + '(-h --help)'{-h,--help}'[Show help]' \ + '--version[Show version]' \ + '(-q --quiet)'{-q,--quiet}'[Suppress all output]' \ "1: :->subcommand" \ "*::arg:->args" @@ -24,12 +30,7 @@ function _dbc { 'docs[Open driver documentation in a web browser]' \ 'remove[Remove a driver from the driver list]' \ 'completion[Generate shell completions]' \ - 'auth[Authenticate with a driver registry]' \ - '--help[Show help]' \ - '-h[Show help]' \ - '--version[Show version]' \ - '--quiet[Suppress all output]' \ - '-q[Suppress all output]' + 'auth[Authenticate with a driver registry]' ;; args) case $line[1] in