diff --git a/command/completions/_zsh_completions_generator.ts b/command/completions/_zsh_completions_generator.ts index 2200f40b..a0bca054 100644 --- a/command/completions/_zsh_completions_generator.ts +++ b/command/completions/_zsh_completions_generator.ts @@ -110,7 +110,7 @@ function _${replaceSpecialChars(path)}() {` + let completions: string = commands .map((subCommand: Command) => - `'${subCommand.getName()}:${ + `'${subCommand.getName().replace(/:/g, "\\:")}:${ subCommand.getShortDescription() // escape single quotes .replace(/'/g, "'\"'\"'") diff --git a/command/test/integration/__snapshots__/test.ts.snap b/command/test/integration/__snapshots__/test.ts.snap index d2cf209c..5cc4b7a1 100644 --- a/command/test/integration/__snapshots__/test.ts.snap +++ b/command/test/integration/__snapshots__/test.ts.snap @@ -28,6 +28,7 @@ snapshot[`command integration > should complete available commands for help comm stdout: "foo bar +foo:bar validation-error help completions" @@ -102,7 +103,7 @@ _completions_test() { } __completions_test() { - opts=(-h --help -V --version -g --global -m --main --color -C --colors foo bar validation-error help completions) + opts=(-h --help -V --version -g --global -m --main --color -C --colors foo bar foo:bar validation-error help completions) _completions_test_complete color if [[ \${cur} == -* || \${COMP_CWORD} -eq 1 ]] ; then return 0 @@ -166,7 +167,7 @@ _completions_test() { } __completions_test_bar() { - opts=(-h --help -g --global -f --file help) + opts=(-h --help -g --global help) if [[ \${cur} == -* || \${COMP_CWORD} -eq 2 ]] ; then return 0 @@ -174,7 +175,6 @@ _completions_test() { case "\${prev}" in -h|--help) opts=() ;; -g|--global) opts=(); _completions_test_complete boolean bar ;; - -f|--file) opts=(); _completions_test_complete string bar ;; esac } @@ -189,6 +189,30 @@ _completions_test() { esac } + __completions_test_foo_bar() { + opts=(-h --help -g --global -f --file help) + + if [[ \${cur} == -* || \${COMP_CWORD} -eq 2 ]] ; then + return 0 + fi + case "\${prev}" in + -h|--help) opts=() ;; + -g|--global) opts=(); _completions_test_complete boolean foo:bar ;; + -f|--file) opts=(); _completions_test_complete string foo:bar ;; + esac + } + + __completions_test_foo_bar_help() { + opts=(-h --help) + _completions_test_complete command foo:bar help + if [[ \${cur} == -* || \${COMP_CWORD} -eq 3 ]] ; then + return 0 + fi + case "\${prev}" in + -h|--help) opts=() ;; + esac + } + __completions_test_validation_error() { opts=(-h --help -g --global help) @@ -417,7 +441,7 @@ _foo_command() { } __foo_command() { - opts=(-h --help -V --version -g --global -m --main --color -C --colors foo bar validation-error help completions) + opts=(-h --help -V --version -g --global -m --main --color -C --colors foo bar foo:bar validation-error help completions) _foo_command_complete color if [[ \${cur} == -* || \${COMP_CWORD} -eq 1 ]] ; then return 0 @@ -481,7 +505,7 @@ _foo_command() { } __foo_command_bar() { - opts=(-h --help -g --global -f --file help) + opts=(-h --help -g --global help) if [[ \${cur} == -* || \${COMP_CWORD} -eq 2 ]] ; then return 0 @@ -489,7 +513,6 @@ _foo_command() { case "\${prev}" in -h|--help) opts=() ;; -g|--global) opts=(); _foo_command_complete boolean bar ;; - -f|--file) opts=(); _foo_command_complete string bar ;; esac } @@ -504,6 +527,30 @@ _foo_command() { esac } + __foo_command_foo_bar() { + opts=(-h --help -g --global -f --file help) + + if [[ \${cur} == -* || \${COMP_CWORD} -eq 2 ]] ; then + return 0 + fi + case "\${prev}" in + -h|--help) opts=() ;; + -g|--global) opts=(); _foo_command_complete boolean foo:bar ;; + -f|--file) opts=(); _foo_command_complete string foo:bar ;; + esac + } + + __foo_command_foo_bar_help() { + opts=(-h --help) + _foo_command_complete command foo:bar help + if [[ \${cur} == -* || \${COMP_CWORD} -eq 3 ]] ; then + return 0 + fi + case "\${prev}" in + -h|--help) opts=() ;; + esac + } + __foo_command_validation_error() { opts=(-h --help -g --global help) @@ -680,7 +727,7 @@ stdout: # fish completion support for completions-test v1.0.0 function __fish_completions_test_using_command - set -l cmds __completions_test __completions_test_foo __completions_test_help __completions_test_foo_bar __completions_test_help __completions_test_bar __completions_test_help __completions_test_validation_error __completions_test_help __completions_test_help __completions_test_completions __completions_test_help __completions_test_completions_bash __completions_test_help __completions_test_completions_fish __completions_test_help __completions_test_completions_zsh __completions_test_help + set -l cmds __completions_test __completions_test_foo __completions_test_help __completions_test_foo_bar __completions_test_help __completions_test_bar __completions_test_help __completions_test_foo_bar __completions_test_help __completions_test_validation_error __completions_test_help __completions_test_help __completions_test_completions __completions_test_help __completions_test_completions_bash __completions_test_help __completions_test_completions_fish __completions_test_help __completions_test_completions_zsh __completions_test_help set -l words (commandline -opc) set -l cmd "_" for word in \$words @@ -725,7 +772,13 @@ complete -c completions-test -n '__fish_completions_test_using_command __complet complete -c completions-test -n '__fish_completions_test_using_command __completions_test' -k -f -a bar complete -c completions-test -n '__fish_completions_test_using_command __completions_test_bar' -s h -l help -x -k -f -d 'Show this help.' complete -c completions-test -n '__fish_completions_test_using_command __completions_test_bar' -s g -l global -k -f -r -a '(completions-test completions complete boolean bar)' -d 'Foo option.' -complete -c completions-test -n '__fish_completions_test_using_command __completions_test_bar' -s f -l file -k -f -r -a '(completions-test completions complete string bar)' -d '...' +complete -c completions-test -n '__fish_completions_test_using_command __completions_test' -k -f -a help -d 'Show this help or the help of a sub-command.' +complete -c completions-test -n '__fish_completions_test_using_command __completions_test_help' -k -f -a '(completions-test completions complete command help)' +complete -c completions-test -n '__fish_completions_test_using_command __completions_test_help' -s h -l help -x -k -f -d 'Show this help.' +complete -c completions-test -n '__fish_completions_test_using_command __completions_test' -k -f -a foo:bar +complete -c completions-test -n '__fish_completions_test_using_command __completions_test_foo_bar' -s h -l help -x -k -f -d 'Show this help.' +complete -c completions-test -n '__fish_completions_test_using_command __completions_test_foo_bar' -s g -l global -k -f -r -a '(completions-test completions complete boolean foo:bar)' -d 'Foo option.' +complete -c completions-test -n '__fish_completions_test_using_command __completions_test_foo_bar' -s f -l file -k -f -r -a '(completions-test completions complete string foo:bar)' -d '...' complete -c completions-test -n '__fish_completions_test_using_command __completions_test' -k -f -a help -d 'Show this help or the help of a sub-command.' complete -c completions-test -n '__fish_completions_test_using_command __completions_test_help' -k -f -a '(completions-test completions complete command help)' complete -c completions-test -n '__fish_completions_test_using_command __completions_test_help' -s h -l help -x -k -f -d 'Show this help.' @@ -772,7 +825,7 @@ stdout: # fish completion support for foo-command v1.0.0 function __fish_foo_command_using_command - set -l cmds __foo_command __foo_command_foo __foo_command_help __foo_command_foo_bar __foo_command_help __foo_command_bar __foo_command_help __foo_command_validation_error __foo_command_help __foo_command_help __foo_command_completions __foo_command_help __foo_command_completions_bash __foo_command_help __foo_command_completions_fish __foo_command_help __foo_command_completions_zsh __foo_command_help + set -l cmds __foo_command __foo_command_foo __foo_command_help __foo_command_foo_bar __foo_command_help __foo_command_bar __foo_command_help __foo_command_foo_bar __foo_command_help __foo_command_validation_error __foo_command_help __foo_command_help __foo_command_completions __foo_command_help __foo_command_completions_bash __foo_command_help __foo_command_completions_fish __foo_command_help __foo_command_completions_zsh __foo_command_help set -l words (commandline -opc) set -l cmd "_" for word in \$words @@ -817,7 +870,13 @@ complete -c foo-command -n '__fish_foo_command_using_command __foo_command_help' complete -c foo-command -n '__fish_foo_command_using_command __foo_command' -k -f -a bar complete -c foo-command -n '__fish_foo_command_using_command __foo_command_bar' -s h -l help -x -k -f -d 'Show this help.' complete -c foo-command -n '__fish_foo_command_using_command __foo_command_bar' -s g -l global -k -f -r -a '(foo-command completions complete boolean bar)' -d 'Foo option.' -complete -c foo-command -n '__fish_foo_command_using_command __foo_command_bar' -s f -l file -k -f -r -a '(foo-command completions complete string bar)' -d '...' +complete -c foo-command -n '__fish_foo_command_using_command __foo_command' -k -f -a help -d 'Show this help or the help of a sub-command.' +complete -c foo-command -n '__fish_foo_command_using_command __foo_command_help' -k -f -a '(foo-command completions complete command help)' +complete -c foo-command -n '__fish_foo_command_using_command __foo_command_help' -s h -l help -x -k -f -d 'Show this help.' +complete -c foo-command -n '__fish_foo_command_using_command __foo_command' -k -f -a foo:bar +complete -c foo-command -n '__fish_foo_command_using_command __foo_command_foo_bar' -s h -l help -x -k -f -d 'Show this help.' +complete -c foo-command -n '__fish_foo_command_using_command __foo_command_foo_bar' -s g -l global -k -f -r -a '(foo-command completions complete boolean foo:bar)' -d 'Foo option.' +complete -c foo-command -n '__fish_foo_command_using_command __foo_command_foo_bar' -s f -l file -k -f -r -a '(foo-command completions complete string foo:bar)' -d '...' complete -c foo-command -n '__fish_foo_command_using_command __foo_command' -k -f -a help -d 'Show this help or the help of a sub-command.' complete -c foo-command -n '__fish_foo_command_using_command __foo_command_help' -k -f -a '(foo-command completions complete command help)' complete -c foo-command -n '__fish_foo_command_using_command __foo_command_help' -s h -l help -x -k -f -d 'Show this help.' @@ -899,6 +958,7 @@ function _completions_test() { commands=( 'foo:Foo command with "'"'"'quotes'"'"'" and ([{brackets}])' 'bar:' + 'foo\\\\:bar:' 'validation-error:' 'help:Show this help or the help of a sub-command.' 'completions:Generate shell completions.' @@ -911,6 +971,7 @@ function _completions_test() { case "\${words[1]}" in foo) _completions_test_foo ;; bar) _completions_test_bar ;; + foo:bar) _completions_test_foo_bar ;; validation-error) _completions_test_validation_error ;; help) _completions_test_help ;; completions) _completions_test_completions ;; @@ -1053,14 +1114,12 @@ function _completions_test_bar() { _arguments -w -s -S -C \\\\ '(- *)'{-h,--help}'[Show this help.]' \\\\ '(-h --help -g --global)'{-g,--global}'[Foo option.]:val:->val-boolean' \\\\ - '(-h --help -f --file)'{-f,--file}'[...]:path:->path-string' \\\\ '1:command:_commands' \\\\ '*::sub command:->command_args' case "\$state" in command_args) _command_args ;; val-boolean) __completions_test_complete val boolean bar ;; - path-string) __completions_test_complete path string bar ;; esac } @@ -1077,6 +1136,52 @@ function _completions_test_bar_help() { '1:command:_commands' } +# shellcheck disable=SC2154 +(( \$+functions[_completions_test_foo_bar] )) || +function _completions_test_foo_bar() { + + function _commands() { + local -a commands + # shellcheck disable=SC2034 + commands=( + 'help:Show this help or the help of a sub-command.' + ) + _describe 'command' commands + } + + function _command_args() { + case "\${words[1]}" in + help) _completions_test_foo_bar_help ;; + esac + } + + _arguments -w -s -S -C \\\\ + '(- *)'{-h,--help}'[Show this help.]' \\\\ + '(-h --help -g --global)'{-g,--global}'[Foo option.]:val:->val-boolean' \\\\ + '(-h --help -f --file)'{-f,--file}'[...]:path:->path-string' \\\\ + '1:command:_commands' \\\\ + '*::sub command:->command_args' + + case "\$state" in + command_args) _command_args ;; + val-boolean) __completions_test_complete val boolean foo:bar ;; + path-string) __completions_test_complete path string foo:bar ;; + esac +} + +# shellcheck disable=SC2154 +(( \$+functions[_completions_test_foo_bar_help] )) || +function _completions_test_foo_bar_help() { + + function _commands() { + __completions_test_complete command command foo:bar help + } + + _arguments -w -s -S -C \\\\ + '(- *)'{-h,--help}'[Show this help.]' \\\\ + '1:command:_commands' +} + # shellcheck disable=SC2154 (( \$+functions[_completions_test_validation_error] )) || function _completions_test_validation_error() { @@ -1363,6 +1468,7 @@ function _foo_command() { commands=( 'foo:Foo command with "'"'"'quotes'"'"'" and ([{brackets}])' 'bar:' + 'foo\\\\:bar:' 'validation-error:' 'help:Show this help or the help of a sub-command.' 'completions:Generate shell completions.' @@ -1375,6 +1481,7 @@ function _foo_command() { case "\${words[1]}" in foo) _foo_command_foo ;; bar) _foo_command_bar ;; + foo:bar) _foo_command_foo_bar ;; validation-error) _foo_command_validation_error ;; help) _foo_command_help ;; completions) _foo_command_completions ;; @@ -1517,14 +1624,12 @@ function _foo_command_bar() { _arguments -w -s -S -C \\\\ '(- *)'{-h,--help}'[Show this help.]' \\\\ '(-h --help -g --global)'{-g,--global}'[Foo option.]:val:->val-boolean' \\\\ - '(-h --help -f --file)'{-f,--file}'[...]:path:->path-string' \\\\ '1:command:_commands' \\\\ '*::sub command:->command_args' case "\$state" in command_args) _command_args ;; val-boolean) __foo_command_complete val boolean bar ;; - path-string) __foo_command_complete path string bar ;; esac } @@ -1541,6 +1646,52 @@ function _foo_command_bar_help() { '1:command:_commands' } +# shellcheck disable=SC2154 +(( \$+functions[_foo_command_foo_bar] )) || +function _foo_command_foo_bar() { + + function _commands() { + local -a commands + # shellcheck disable=SC2034 + commands=( + 'help:Show this help or the help of a sub-command.' + ) + _describe 'command' commands + } + + function _command_args() { + case "\${words[1]}" in + help) _foo_command_foo_bar_help ;; + esac + } + + _arguments -w -s -S -C \\\\ + '(- *)'{-h,--help}'[Show this help.]' \\\\ + '(-h --help -g --global)'{-g,--global}'[Foo option.]:val:->val-boolean' \\\\ + '(-h --help -f --file)'{-f,--file}'[...]:path:->path-string' \\\\ + '1:command:_commands' \\\\ + '*::sub command:->command_args' + + case "\$state" in + command_args) _command_args ;; + val-boolean) __foo_command_complete val boolean foo:bar ;; + path-string) __foo_command_complete path string foo:bar ;; + esac +} + +# shellcheck disable=SC2154 +(( \$+functions[_foo_command_foo_bar_help] )) || +function _foo_command_foo_bar_help() { + + function _commands() { + __foo_command_complete command command foo:bar help + } + + _arguments -w -s -S -C \\\\ + '(- *)'{-h,--help}'[Show this help.]' \\\\ + '1:command:_commands' +} + # shellcheck disable=SC2154 (( \$+functions[_foo_command_validation_error] )) || function _foo_command_validation_error() { @@ -1816,6 +1967,7 @@ stdout: \\x1b[94mfoo\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Foo command with "'quotes'" and ([{brackets}]) \\x1b[94mbar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m + \\x1b[94mfoo:bar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mvalidation-error\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mhelp\\x1b[39m \\x1b[33m[\\x1b[39m\\x1b[95mcommand\\x1b[39m\\x1b[33m]\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Show this help or the help of a sub-command. \\x1b[94mcompletions\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Generate shell completions. @@ -1882,6 +2034,7 @@ stdout: \\x1b[94mfoo\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Foo command with "'quotes'" and ([{brackets}]) \\x1b[94mbar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m + \\x1b[94mfoo:bar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mvalidation-error\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mhelp\\x1b[39m \\x1b[33m[\\x1b[39m\\x1b[95mcommand\\x1b[39m\\x1b[33m]\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Show this help or the help of a sub-command. \\x1b[94mcompletions\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Generate shell completions. @@ -1926,6 +2079,7 @@ stdout: \\x1b[94mfoo\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Foo command with "'quotes'" and ([{brackets}]) \\x1b[94mbar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m + \\x1b[94mfoo:bar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mvalidation-error\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mhelp\\x1b[39m \\x1b[33m[\\x1b[39m\\x1b[95mcommand\\x1b[39m\\x1b[33m]\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Show this help or the help of a sub-command. \\x1b[94mcompletions\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Generate shell completions. @@ -1956,25 +2110,9 @@ stderr: snapshot[`command integration > should print the help of sub-command on validation error 1`] = ` stdout: -" -\\x1b[1mUsage:\\x1b[22m \\x1b[95mcompletions-test bar --file \\x1b[33m<\\x1b[95m\\x1b[95mpath\\x1b[95m\\x1b[33m>\\x1b[95m\\x1b[39m -\\x1b[1mVersion:\\x1b[22m \\x1b[33m1.0.0\\x1b[39m - -\\x1b[1mOptions:\\x1b[22m - - \\x1b[94m-h\\x1b[39m, \\x1b[94m--help\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Show this help. - \\x1b[94m-g\\x1b[39m, \\x1b[94m--global\\x1b[39m \\x1b[33m<\\x1b[39m\\x1b[95mval\\x1b[39m\\x1b[33m>\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Foo option. - \\x1b[94m-f\\x1b[39m, \\x1b[94m--file\\x1b[39m \\x1b[33m<\\x1b[39m\\x1b[95mpath\\x1b[39m\\x1b[33m>\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m ... (\\x1b[33mrequired\\x1b[39m) - -\\x1b[1mCommands:\\x1b[22m - - \\x1b[94mhelp\\x1b[39m \\x1b[33m[\\x1b[39m\\x1b[95mcommand\\x1b[39m\\x1b[33m]\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Show this help or the help of a sub-command. - -" +"" stderr: -'\\x1b[31m \\x1b[1merror\\x1b[22m: Missing required option "--file". -\\x1b[39m -' +"" `; snapshot[`command integration > should print error message for unknown option with suggestion 1`] = ` @@ -2007,6 +2145,7 @@ stdout: \\x1b[94mfoo\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Foo command with "'quotes'" and ([{brackets}]) \\x1b[94mbar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m + \\x1b[94mfoo:bar\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mvalidation-error\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m \\x1b[94mhelp\\x1b[39m \\x1b[33m[\\x1b[39m\\x1b[95mcommand\\x1b[39m\\x1b[33m]\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Show this help or the help of a sub-command. \\x1b[94mcompletions\\x1b[39m \\x1b[31m\\x1b[1m-\\x1b[22m\\x1b[39m Generate shell completions. diff --git a/command/test/integration/command.ts b/command/test/integration/command.ts index bd78e2fd..d04c60ac 100644 --- a/command/test/integration/command.ts +++ b/command/test/integration/command.ts @@ -51,6 +51,7 @@ const cmd = new Command() .reset(), ) .command("bar") + .command("foo:bar") .option("-f, --file ", "...", { required: true }) .command("validation-error") .action(() => { diff --git a/command/test/integration/test.ts b/command/test/integration/test.ts index e6891a47..80310d43 100644 --- a/command/test/integration/test.ts +++ b/command/test/integration/test.ts @@ -104,6 +104,7 @@ await snapshotTest({ .reset(), ) .command("bar") + .command("foo:bar") .option("-f, --file ", "...", { required: true }) .command("validation-error") .action(() => {