From 8df5a2e76209c44cc535caa5d241b22437c71624 Mon Sep 17 00:00:00 2001 From: Jamy Date: Mon, 29 Apr 2024 19:30:58 +0200 Subject: [PATCH] Convert `--generate-completion` flag to subcommand and add docs/tests (#22) - Add documention - Add tests - Fix github action --- .github/workflows/release.yml | 6 +- CHANGELOG.md | 7 + README.md | 1 + USAGE.md | 18 ++ contrib/completion/README.md | 12 ++ contrib/completion/tinty.bash | 58 ++++++- contrib/completion/tinty.elvish | 134 +++++++++++++++ contrib/completion/tinty.fish | 22 ++- .../{tinty.ps1 => tinty.powershell} | 15 +- contrib/completion/tinty.zsh | 28 +++- scripts/package_build | 2 +- src/cli.rs | 15 +- src/main.rs | 16 +- ...cli_generatecompletion_subcommand_tests.rs | 158 ++++++++++++++++++ 14 files changed, 454 insertions(+), 38 deletions(-) create mode 100644 contrib/completion/README.md create mode 100644 contrib/completion/tinty.elvish rename contrib/completion/{tinty.ps1 => tinty.powershell} (89%) create mode 100644 tests/cli_generatecompletion_subcommand_tests.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25bf7ed..c9c08e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -178,11 +178,7 @@ jobs: run: | files="example.toml THIRD_PARTY_LICENSES.md LICENSE README.md" $GITHUB_WORKSPACE/scripts/package_build \ - "example.toml THIRD_PARTY_LICENSES.md LICENSE README.md" \ - "contrib/completion/tinty.bash" \ - "contrib/completion/tinty.zsh" \ - "contrib/completion/tinty.fish" \ - "contrib/completion/tinty.ps1" \ + "example.toml THIRD_PARTY_LICENSES.md LICENSE README.md contrib/completion/tinty.bash contrib/completion/tinty.elvish contrib/completion/tinty.fish contrib/completion/tinty.powershell contrib/completion/tinty.zsh" \ "${{ matrix.target }}" \ "$GITHUB_WORKSPACE" \ "${{ steps.cargo_version.outputs.value }}" diff --git a/CHANGELOG.md b/CHANGELOG.md index e3378c5..980223c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [Unreleased] + +### Added + +- Add shell completions functionality with `generate-completion` + subcommand + ## [0.11.0] - 2024-03-10 ### Added diff --git a/README.md b/README.md index 3d306a6..9e80dd5 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ The following is a table of the available subcommands for the CLI tool (Tinty), | `init` | Initializes the tool with the last applied theme otherwise `default-scheme` from `config.toml`. | - | `tinty init` | | `current` | Displays the currently applied theme. | - | `tinty current` | | `info` | Provides information about themes. | `[-]`: Optional argument to specify a theme for detailed info. | `tinty info base16-mocha` | +| `generate-completion` | Generates a shell completion file to source in your shell startup file (`*rc`). | ``: Name of the shell to generate a completion script for. Supports `bash`, `elvish`, `fish`, `powershell`, `zsh` | `tinty generate-completion bash` | Some subcommands support additional flags and options to modify their behavior: diff --git a/USAGE.md b/USAGE.md index 31bd79b..09ef6f6 100644 --- a/USAGE.md +++ b/USAGE.md @@ -5,6 +5,7 @@ For more general usage, look at the [Usage section] in [README.md]. ## Table of contents +- [Shell completions](#shell-completions) - [How it works](#how-it-works) - [Sourcing scripts that set environment variables](#sourcing-scripts-that-set-environment-variables) - [shell](#shell) @@ -13,6 +14,21 @@ For more general usage, look at the [Usage section] in [README.md]. - [fzf](#fzf) - [bat](#bat) +## Shell completions + +You can generate shell completions with the `generate-completion` +subcommand, source the generated file in your shell startup file (`*rc`) +and completions will exist for `tinty`. Have a look at the [README CLI +section] for more information about the command usage. + +A shell completion generation via `tinty` doesn't include any dynamic +values, meaning scheme names (such as `base16-ocean`) won't be completed +typing `tinty apply base`. We've created modified completion script +files for this reason so it can also generate the scheme names. +Currently this is only supported for the `bash` completion file, but we +plan to include the other shells too. You can find these completion +files in [contrib/completion]. + ## How it works There are some concepts which some of the following instructions will @@ -371,3 +387,5 @@ alias bat="bat --theme='base16-256'" [tmux tpm]: https://github.com/tmux-plugins/tpm [XDG Base Directory specification]: https://wiki.archlinux.org/title/XDG_Base_Directory [Sourcing scripts that set environment variables]: #sourcing-scripts-that-set-environment-variables +[README CLI section]: README.md#cli +[contrib/completion]: contrib/completion diff --git a/contrib/completion/README.md b/contrib/completion/README.md new file mode 100644 index 0000000..7941d28 --- /dev/null +++ b/contrib/completion/README.md @@ -0,0 +1,12 @@ +# Shell Completions + +Run `tinty generate-completion ` to +generate a shell completion script for your shell of choice. Make sure +to source the generated script in your shell startup file (`*rc`). + +The files in this directory are custom completion scripts which has been +optimised further than the standard completions `tinty` generates. These +scripts complete dynamic values (scheme names) as well as the standard +subcommands and flags. Currently `bash` is the completion which has been +optimised this way, the rest are the default completions generated by +`tinty generate-completion `. diff --git a/contrib/completion/tinty.bash b/contrib/completion/tinty.bash index c01d180..925f655 100644 --- a/contrib/completion/tinty.bash +++ b/contrib/completion/tinty.bash @@ -18,6 +18,9 @@ _tinty() { tinty,current) cmd="tinty__current" ;; + tinty,generate-completion) + cmd="tinty__generate__completion" + ;; tinty,help) cmd="tinty__help" ;; @@ -42,6 +45,9 @@ _tinty() { tinty__help,current) cmd="tinty__help__current" ;; + tinty__help,generate-completion) + cmd="tinty__help__generate__completion" + ;; tinty__help,help) cmd="tinty__help__help" ;; @@ -67,7 +73,7 @@ _tinty() { case "${cmd}" in tinty) - opts="-c -d -h -V --config --data-dir --generate-completion --help --version current info init list apply install update help" + opts="-c -d -h -V --config --data-dir --help --version current generate-completion info init list apply install update help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -89,10 +95,6 @@ _tinty() { COMPREPLY=($(compgen -f "${cur}")) return 0 ;; - --generate-completion) - COMPREPLY=($(compgen -W "bash elvish fish powershell zsh" -- "${cur}")) - return 0 - ;; *) COMPREPLY=() ;; @@ -164,8 +166,38 @@ _tinty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + tinty__generate__completion) + opts="-c -d -h --config --data-dir --help bash elvish fish powershell zsh" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + --config) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -c) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + --data-dir) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + -d) + COMPREPLY=($(compgen -f "${cur}")) + return 0 + ;; + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; tinty__help) - opts="current info init list apply install update help" + opts="current generate-completion info init list apply install update help" if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -206,6 +238,20 @@ _tinty() { COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 ;; + tinty__help__generate__completion) + opts="" + if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + fi + case "${prev}" in + *) + COMPREPLY=() + ;; + esac + COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) + return 0 + ;; tinty__help__help) opts="" if [[ ${cur} == -* || ${COMP_CWORD} -eq 3 ]] ; then diff --git a/contrib/completion/tinty.elvish b/contrib/completion/tinty.elvish new file mode 100644 index 0000000..813f0ba --- /dev/null +++ b/contrib/completion/tinty.elvish @@ -0,0 +1,134 @@ + +use builtin; +use str; + +set edit:completion:arg-completer[tinty] = {|@words| + fn spaces {|n| + builtin:repeat $n ' ' | str:join '' + } + fn cand {|text desc| + edit:complex-candidate $text &display=$text' '(spaces (- 14 (wcswidth $text)))$desc + } + var command = 'tinty' + for word $words[1..-1] { + if (str:has-prefix $word '-') { + break + } + set command = $command';'$word + } + var completions = [ + &'tinty'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + cand -V 'Print version' + cand --version 'Print version' + cand current 'Prints the last scheme name applied' + cand generate-completion 'Generates a shell completion script' + cand info 'Shows scheme colors for all schemes matching - (Eg: tinty info base16-mocha)' + cand init 'Initializes with the exising config. Used to Initialize exising theme for when your shell starts up' + cand list 'Lists available schemes' + cand apply 'Applies a theme based on the chosen scheme' + cand install 'Install the environment needed for tinty' + cand update 'Update to the latest themes' + cand help 'Print this message or the help of the given subcommand(s)' + } + &'tinty;current'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;generate-completion'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;info'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;init'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;list'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;apply'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;install'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;update'= { + cand -c 'Optional path to the tinty config.toml file' + cand --config 'Optional path to the tinty config.toml file' + cand -d 'Optional path to the tinty data directory' + cand --data-dir 'Optional path to the tinty data directory' + cand -h 'Print help' + cand --help 'Print help' + } + &'tinty;help'= { + cand current 'Prints the last scheme name applied' + cand generate-completion 'Generates a shell completion script' + cand info 'Shows scheme colors for all schemes matching - (Eg: tinty info base16-mocha)' + cand init 'Initializes with the exising config. Used to Initialize exising theme for when your shell starts up' + cand list 'Lists available schemes' + cand apply 'Applies a theme based on the chosen scheme' + cand install 'Install the environment needed for tinty' + cand update 'Update to the latest themes' + cand help 'Print this message or the help of the given subcommand(s)' + } + &'tinty;help;current'= { + } + &'tinty;help;generate-completion'= { + } + &'tinty;help;info'= { + } + &'tinty;help;init'= { + } + &'tinty;help;list'= { + } + &'tinty;help;apply'= { + } + &'tinty;help;install'= { + } + &'tinty;help;update'= { + } + &'tinty;help;help'= { + } + ] + $completions[$command] +} diff --git a/contrib/completion/tinty.fish b/contrib/completion/tinty.fish index 6e556ec..71671ca 100644 --- a/contrib/completion/tinty.fish +++ b/contrib/completion/tinty.fish @@ -1,9 +1,9 @@ complete -c tinty -n "__fish_use_subcommand" -s c -l config -d 'Optional path to the tinty config.toml file' -r complete -c tinty -n "__fish_use_subcommand" -s d -l data-dir -d 'Optional path to the tinty data directory' -r -complete -c tinty -n "__fish_use_subcommand" -l generate-completion -d 'Generate completion scripts' -r -f -a "{bash '',elvish '',fish '',powershell '',zsh ''}" complete -c tinty -n "__fish_use_subcommand" -s h -l help -d 'Print help' complete -c tinty -n "__fish_use_subcommand" -s V -l version -d 'Print version' complete -c tinty -n "__fish_use_subcommand" -f -a "current" -d 'Prints the last scheme name applied' +complete -c tinty -n "__fish_use_subcommand" -f -a "generate-completion" -d 'Generates a shell completion script' complete -c tinty -n "__fish_use_subcommand" -f -a "info" -d 'Shows scheme colors for all schemes matching - (Eg: tinty info base16-mocha)' complete -c tinty -n "__fish_use_subcommand" -f -a "init" -d 'Initializes with the exising config. Used to Initialize exising theme for when your shell starts up' complete -c tinty -n "__fish_use_subcommand" -f -a "list" -d 'Lists available schemes' @@ -14,6 +14,9 @@ complete -c tinty -n "__fish_use_subcommand" -f -a "help" -d 'Print this message complete -c tinty -n "__fish_seen_subcommand_from current" -s c -l config -d 'Optional path to the tinty config.toml file' -r complete -c tinty -n "__fish_seen_subcommand_from current" -s d -l data-dir -d 'Optional path to the tinty data directory' -r complete -c tinty -n "__fish_seen_subcommand_from current" -s h -l help -d 'Print help' +complete -c tinty -n "__fish_seen_subcommand_from generate-completion" -s c -l config -d 'Optional path to the tinty config.toml file' -r +complete -c tinty -n "__fish_seen_subcommand_from generate-completion" -s d -l data-dir -d 'Optional path to the tinty data directory' -r +complete -c tinty -n "__fish_seen_subcommand_from generate-completion" -s h -l help -d 'Print help' complete -c tinty -n "__fish_seen_subcommand_from info" -s c -l config -d 'Optional path to the tinty config.toml file' -r complete -c tinty -n "__fish_seen_subcommand_from info" -s d -l data-dir -d 'Optional path to the tinty data directory' -r complete -c tinty -n "__fish_seen_subcommand_from info" -s h -l help -d 'Print help' @@ -32,11 +35,12 @@ complete -c tinty -n "__fish_seen_subcommand_from install" -s h -l help -d 'Prin complete -c tinty -n "__fish_seen_subcommand_from update" -s c -l config -d 'Optional path to the tinty config.toml file' -r complete -c tinty -n "__fish_seen_subcommand_from update" -s d -l data-dir -d 'Optional path to the tinty data directory' -r complete -c tinty -n "__fish_seen_subcommand_from update" -s h -l help -d 'Print help' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "current" -d 'Prints the last scheme name applied' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "info" -d 'Shows scheme colors for all schemes matching - (Eg: tinty info base16-mocha)' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "init" -d 'Initializes with the exising config. Used to Initialize exising theme for when your shell starts up' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "list" -d 'Lists available schemes' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "apply" -d 'Applies a theme based on the chosen scheme' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "install" -d 'Install the environment needed for tinty' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "update" -d 'Update to the latest themes' -complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "current" -d 'Prints the last scheme name applied' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "generate-completion" -d 'Generates a shell completion script' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "info" -d 'Shows scheme colors for all schemes matching - (Eg: tinty info base16-mocha)' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "init" -d 'Initializes with the exising config. Used to Initialize exising theme for when your shell starts up' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "list" -d 'Lists available schemes' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "apply" -d 'Applies a theme based on the chosen scheme' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "install" -d 'Install the environment needed for tinty' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "update" -d 'Update to the latest themes' +complete -c tinty -n "__fish_seen_subcommand_from help; and not __fish_seen_subcommand_from current; and not __fish_seen_subcommand_from generate-completion; and not __fish_seen_subcommand_from info; and not __fish_seen_subcommand_from init; and not __fish_seen_subcommand_from list; and not __fish_seen_subcommand_from apply; and not __fish_seen_subcommand_from install; and not __fish_seen_subcommand_from update; and not __fish_seen_subcommand_from help" -f -a "help" -d 'Print this message or the help of the given subcommand(s)' diff --git a/contrib/completion/tinty.ps1 b/contrib/completion/tinty.powershell similarity index 89% rename from contrib/completion/tinty.ps1 rename to contrib/completion/tinty.powershell index 5183e1d..8a8c15a 100644 --- a/contrib/completion/tinty.ps1 +++ b/contrib/completion/tinty.powershell @@ -25,12 +25,12 @@ Register-ArgumentCompleter -Native -CommandName 'tinty' -ScriptBlock { [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'Optional path to the tinty config.toml file') [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Optional path to the tinty data directory') [CompletionResult]::new('--data-dir', 'data-dir', [CompletionResultType]::ParameterName, 'Optional path to the tinty data directory') - [CompletionResult]::new('--generate-completion', 'generate-completion', [CompletionResultType]::ParameterName, 'Generate completion scripts') [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') [CompletionResult]::new('-V', 'V ', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('--version', 'version', [CompletionResultType]::ParameterName, 'Print version') [CompletionResult]::new('current', 'current', [CompletionResultType]::ParameterValue, 'Prints the last scheme name applied') + [CompletionResult]::new('generate-completion', 'generate-completion', [CompletionResultType]::ParameterValue, 'Generates a shell completion script') [CompletionResult]::new('info', 'info', [CompletionResultType]::ParameterValue, 'Shows scheme colors for all schemes matching - (Eg: tinty info base16-mocha)') [CompletionResult]::new('init', 'init', [CompletionResultType]::ParameterValue, 'Initializes with the exising config. Used to Initialize exising theme for when your shell starts up') [CompletionResult]::new('list', 'list', [CompletionResultType]::ParameterValue, 'Lists available schemes') @@ -49,6 +49,15 @@ Register-ArgumentCompleter -Native -CommandName 'tinty' -ScriptBlock { [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') break } + 'tinty;generate-completion' { + [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Optional path to the tinty config.toml file') + [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'Optional path to the tinty config.toml file') + [CompletionResult]::new('-d', 'd', [CompletionResultType]::ParameterName, 'Optional path to the tinty data directory') + [CompletionResult]::new('--data-dir', 'data-dir', [CompletionResultType]::ParameterName, 'Optional path to the tinty data directory') + [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help') + [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help') + break + } 'tinty;info' { [CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, 'Optional path to the tinty config.toml file') [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'Optional path to the tinty config.toml file') @@ -105,6 +114,7 @@ Register-ArgumentCompleter -Native -CommandName 'tinty' -ScriptBlock { } 'tinty;help' { [CompletionResult]::new('current', 'current', [CompletionResultType]::ParameterValue, 'Prints the last scheme name applied') + [CompletionResult]::new('generate-completion', 'generate-completion', [CompletionResultType]::ParameterValue, 'Generates a shell completion script') [CompletionResult]::new('info', 'info', [CompletionResultType]::ParameterValue, 'Shows scheme colors for all schemes matching - (Eg: tinty info base16-mocha)') [CompletionResult]::new('init', 'init', [CompletionResultType]::ParameterValue, 'Initializes with the exising config. Used to Initialize exising theme for when your shell starts up') [CompletionResult]::new('list', 'list', [CompletionResultType]::ParameterValue, 'Lists available schemes') @@ -117,6 +127,9 @@ Register-ArgumentCompleter -Native -CommandName 'tinty' -ScriptBlock { 'tinty;help;current' { break } + 'tinty;help;generate-completion' { + break + } 'tinty;help;info' { break } diff --git a/contrib/completion/tinty.zsh b/contrib/completion/tinty.zsh index 7d3b199..35e63b4 100644 --- a/contrib/completion/tinty.zsh +++ b/contrib/completion/tinty.zsh @@ -19,7 +19,6 @@ _tinty() { '--config=[Optional path to the tinty config.toml file]:FILE: ' \ '-d+[Optional path to the tinty data directory]:DIRECTORY: ' \ '--data-dir=[Optional path to the tinty data directory]:DIRECTORY: ' \ -'--generate-completion=[Generate completion scripts]:SHELL:(bash elvish fish powershell zsh)' \ '-h[Print help]' \ '--help[Print help]' \ '-V[Print version]' \ @@ -43,6 +42,17 @@ _arguments "${_arguments_options[@]}" \ '--help[Print help]' \ && ret=0 ;; +(generate-completion) +_arguments "${_arguments_options[@]}" \ +'-c+[Optional path to the tinty config.toml file]:FILE: ' \ +'--config=[Optional path to the tinty config.toml file]:FILE: ' \ +'-d+[Optional path to the tinty data directory]:DIRECTORY: ' \ +'--data-dir=[Optional path to the tinty data directory]:DIRECTORY: ' \ +'-h[Print help]' \ +'--help[Print help]' \ +':shell_name -- The name of the shell you want to generate a completion script for:(bash elvish fish powershell zsh)' \ +&& ret=0 +;; (info) _arguments "${_arguments_options[@]}" \ '-c+[Optional path to the tinty config.toml file]:FILE: ' \ @@ -121,6 +131,10 @@ _arguments "${_arguments_options[@]}" \ _arguments "${_arguments_options[@]}" \ && ret=0 ;; +(generate-completion) +_arguments "${_arguments_options[@]}" \ +&& ret=0 +;; (info) _arguments "${_arguments_options[@]}" \ && ret=0 @@ -162,6 +176,7 @@ esac _tinty_commands() { local commands; commands=( 'current:Prints the last scheme name applied' \ +'generate-completion:Generates a shell completion script' \ 'info:Shows scheme colors for all schemes matching - (Eg\: tinty info base16-mocha)' \ 'init:Initializes with the exising config. Used to Initialize exising theme for when your shell starts up' \ 'list:Lists available schemes' \ @@ -192,10 +207,21 @@ _tinty__help__current_commands() { local commands; commands=() _describe -t commands 'tinty help current commands' commands "$@" } +(( $+functions[_tinty__generate-completion_commands] )) || +_tinty__generate-completion_commands() { + local commands; commands=() + _describe -t commands 'tinty generate-completion commands' commands "$@" +} +(( $+functions[_tinty__help__generate-completion_commands] )) || +_tinty__help__generate-completion_commands() { + local commands; commands=() + _describe -t commands 'tinty help generate-completion commands' commands "$@" +} (( $+functions[_tinty__help_commands] )) || _tinty__help_commands() { local commands; commands=( 'current:Prints the last scheme name applied' \ +'generate-completion:Generates a shell completion script' \ 'info:Shows scheme colors for all schemes matching - (Eg\: tinty info base16-mocha)' \ 'init:Initializes with the exising config. Used to Initialize exising theme for when your shell starts up' \ 'list:Lists available schemes' \ diff --git a/scripts/package_build b/scripts/package_build index 0d68ade..133ba77 100755 --- a/scripts/package_build +++ b/scripts/package_build @@ -20,7 +20,7 @@ package_build() { continue fi - cp "$file" "$release_dir/$file" + cp --parents "$file" "$release_dir/" files_to_include+="$file " done diff --git a/src/cli.rs b/src/cli.rs index 0bc81d6..2385621 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -27,16 +27,17 @@ pub fn build_cli() -> Command { .global(true) .action(ArgAction::Set) ) - .arg( - Arg::new("generate-completion") - .long("generate-completion") - .value_name("SHELL") - .value_parser(clap::value_parser!(Shell)) - .help("Generate completion scripts") - ) .subcommand( Command::new("current").about("Prints the last scheme name applied") ) + .subcommand( + Command::new("generate-completion").about("Generates a shell completion script").arg( + Arg::new("shell_name") + .value_parser(clap::value_parser!(Shell)) + .help("The name of the shell you want to generate a completion script for") + .required(true), + ), + ) .subcommand( Command::new("info").about(format!("Shows scheme colors for all schemes matching - (Eg: {} info base16-mocha)", REPO_NAME)).arg( Arg::new("scheme_name") diff --git a/src/main.rs b/src/main.rs index 2171d61..211bf89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,14 +18,6 @@ fn main() -> Result<()> { // Parse the command line arguments let matches = get_matches(); - // Generate completion scripts - if let Some(generator) = matches.get_one::("generate-completion") { - let mut cmd = build_cli(); - eprintln!("Generating completion file for {generator}..."); - print_completions(*generator, &mut cmd); - return Ok(()); - }; - // Other configuration paths let config_path_result: Result = if let Some(config_file_path) = matches.get_one::("config") { @@ -63,6 +55,14 @@ fn main() -> Result<()> { Some(("current", _)) => { operations::current::current(&data_path)?; } + Some(("generate-completion", sub_matches)) => { + if let Some(generator) = sub_matches.get_one::("shell_name") { + let mut cmd = build_cli(); + eprintln!("Generating completion file for {generator}..."); + print_completions(*generator, &mut cmd); + return Ok(()); + }; + } Some(("info", sub_matches)) => { let scheme_name_option = sub_matches.get_one::("scheme_name"); diff --git a/tests/cli_generatecompletion_subcommand_tests.rs b/tests/cli_generatecompletion_subcommand_tests.rs new file mode 100644 index 0000000..fb0c444 --- /dev/null +++ b/tests/cli_generatecompletion_subcommand_tests.rs @@ -0,0 +1,158 @@ +mod common; + +use crate::common::setup; +use anyhow::Result; + +fn generate_shell_completion_test(shell_name: &str) -> Result { + // ------- + // Arrange + // ------- + let (_, _, command_vec, cleanup) = setup( + "test_cli_generatecompletion_subcommand", + format!("generate-completion {shell_name}").as_str(), + )?; + + // --- + // Act + // --- + let (stdout, stderr) = common::run_command(command_vec).unwrap(); + + // Ok((stdout, stderr, cleanup)) + + // ------ + // Assert + // ------ + assert!( + stderr.contains(format!("Generating completion file for {shell_name}...").as_str()), + "stderr does not contain the expected output" + ); + + cleanup()?; + Ok(stdout) +} + +#[test] +fn test_cli_generatecompletion_subcommand_bash() -> Result<()> { + // --- + // Act + // --- + let shell_name = "bash"; + let stdout = generate_shell_completion_test(shell_name)?; + + // ------ + // Assert + // ------ + assert!( + stdout.contains( + r##"_tinty() { + local i cur prev opts cmd + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + cmd="" + opts="" + + for i in ${COMP_WORDS[@]}"## + ), + "stdout does not contain the expected output" + ); + + Ok(()) +} + +#[test] +fn test_cli_generatecompletion_subcommand_elvish() -> Result<()> { + // --- + // Act + // --- + let shell_name = "elvish"; + let stdout = generate_shell_completion_test(shell_name)?; + + // ------ + // Assert + // ------ + assert!( + stdout.contains( + r##"use builtin; +use str; + +set edit:completion:arg-completer[tinty] = {|@words|"## + ), + "stdout does not contain the expected output" + ); + + Ok(()) +} + +#[test] +fn test_cli_generatecompletion_subcommand_fish() -> Result<()> { + // --- + // Act + // --- + let shell_name = "fish"; + let stdout = generate_shell_completion_test(shell_name)?; + + // ------ + // Assert + // ------ + assert!( + stdout.contains(r##"complete -c tinty -n "__fish_use_subcommand" -s c -l config -d 'Optional path to the tinty config.toml file' -r +complete -c tinty -n "__fish_use_subcommand" -s d -l data-dir -d 'Optional path to the tinty data directory' -r +complete -c tinty -n "__fish_use_subcommand" -s h -l help -d 'Print help'"##), + "stdout does not contain the expected output" + ); + + Ok(()) +} + +#[test] +fn test_cli_generatecompletion_subcommand_powershell() -> Result<()> { + // --- + // Act + // --- + let shell_name = "powershell"; + let stdout = generate_shell_completion_test(shell_name)?; + + // ------ + // Assert + // ------ + assert!( + stdout.contains( + r##"using namespace System.Management.Automation +using namespace System.Management.Automation.Language + +Register-ArgumentCompleter -Native -CommandName 'tinty' -ScriptBlock {"## + ), + "stdout does not contain the expected output" + ); + + Ok(()) +} + +#[test] +fn test_cli_generatecompletion_subcommand_zsh() -> Result<()> { + // --- + // Act + // --- + let shell_name = "zsh"; + let stdout = generate_shell_completion_test(shell_name)?; + + // ------ + // Assert + // ------ + assert!( + stdout.contains( + r##"#compdef tinty + +autoload -U is-at-least + +_tinty() { + typeset -A opt_args + typeset -a _arguments_options + local ret=1"## + ), + "stdout does not contain the expected output" + ); + + Ok(()) +}