diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0ee24b4 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,7 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v2.3.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/README.md b/README.md index 0ddd817..d8d3185 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ For an outline of past/future changes refer to: [CHANGELOG](CHANGELOG.md) - [Configuration](#configuration) - [Style](#style) - [Commands](#commands) +- [Shell Completion](#shell-completion) - [License](#license) ## Requirements @@ -325,10 +326,70 @@ slobs-cli scenecollection load "ExistingCollection" slobs-cli scenecollection rename "ExistingCollection" "NewName" ``` +## Shell Completion + +Shell completion scripts are available for *bash*, *zsh*, and *fish*, you can find them in the [completions directory](./completions/). + +#### Bash + +Save the script in a completion directory of your choice. + +```console +cp -v ./completions/_slobs-cli.bash ~/.completions/_slobs-cli +``` + +Source the file in `~/.bashrc` + +```bash +. ~/.completions/_slobs-cli +``` + +Restart the shell + +```console +exec "$SHELL" +``` + +#### Fish + +Save the script to `~/.config/fish/completions` + +```fish +cp -v ./completions/_slobs-cli.fish ~/.config/fish/completions/_slobs-cli +``` + +Restart the shell + +```console +exec "$SHELL" +``` + +#### Zsh + +Save the script in a completion directory of your choice. + +```console +cp -v ./completions/_slobs-cli.zsh ~/.completions/_slobs-cli +``` + +Source the file in `~/.zshrc` + +```zsh +. ~/.completions/_slobs-cli +``` + +> Note: If you're using a framework like oh-my-zsh you can copy the completion script straight into $ZSH_CUSTOM/completions and skip modifying ~/.zshrc + +Restart the shell + +```console +exec "$SHELL" +``` + ## Special Thanks - [Julian-0](https://github.com/Julian-O) For writing the [PySLOBS wrapper](https://github.com/Julian-O/PySLOBS) on which this CLI depends. ## License -`slobs-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. \ No newline at end of file +`slobs-cli` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license. diff --git a/Taskfile.yaml b/Taskfile.yaml new file mode 100644 index 0000000..0dc9614 --- /dev/null +++ b/Taskfile.yaml @@ -0,0 +1,33 @@ +version: '3' + +tasks: + default: + desc: Generate completion scripts for supported shells + cmds: + - task: generate-completion-scripts + + generate-completion-scripts: + desc: Generate completion scripts for supported shells + cmds: + - for: + matrix: + SHELL: [bash, fish, zsh] + task: generate-completion-script-{{.ITEM.SHELL}} + + generate-completion-script-bash: + desc: Generate bash completion script + cmds: + - bash -c '_SLOBS_CLI_COMPLETE=bash_source slobs-cli > ./completions/_slobs-cli.bash' + internal: true + + generate-completion-script-fish: + desc: Generate fish completion script + cmds: + - fish -c '_SLOBS_CLI_COMPLETE=fish_source slobs-cli > ./completions/_slobs-cli.fish' + internal: true + + generate-completion-script-zsh: + desc: Generate zsh completion script + cmds: + - zsh -c '_SLOBS_CLI_COMPLETE=zsh_source slobs-cli > ./completions/_slobs-cli.zsh' + internal: true diff --git a/completions/_slobs-cli.bash b/completions/_slobs-cli.bash new file mode 100644 index 0000000..2c51b62 --- /dev/null +++ b/completions/_slobs-cli.bash @@ -0,0 +1,28 @@ +_slobs_cli_completion() { + local IFS=$'\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD _SLOBS_CLI_COMPLETE=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +_slobs_cli_completion_setup() { + complete -o nosort -F _slobs_cli_completion slobs-cli +} + +_slobs_cli_completion_setup; diff --git a/completions/_slobs-cli.fish b/completions/_slobs-cli.fish new file mode 100644 index 0000000..fb401fb --- /dev/null +++ b/completions/_slobs-cli.fish @@ -0,0 +1,17 @@ +function _slobs_cli_completion; + set -l response (env _SLOBS_CLI_COMPLETE=fish_complete COMP_WORDS=(commandline -cp) COMP_CWORD=(commandline -t) slobs-cli); + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command slobs-cli --arguments "(_slobs_cli_completion)"; diff --git a/completions/_slobs-cli.zsh b/completions/_slobs-cli.zsh new file mode 100644 index 0000000..ceba98d --- /dev/null +++ b/completions/_slobs-cli.zsh @@ -0,0 +1,40 @@ +#compdef slobs-cli + +_slobs_cli_completion() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[slobs-cli] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) _SLOBS_CLI_COMPLETE=zsh_complete slobs-cli)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + _slobs_cli_completion "$@" +else + # eval/source/. command, register function for later + compdef _slobs_cli_completion slobs-cli +fi diff --git a/pyproject.toml b/pyproject.toml index 8108eec..606ad4f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,12 @@ name = "slobs-cli" description = "A command line application for Streamlabs Desktop" authors = [{ name = "onyx-and-iris", email = "code@onyxandiris.online" }] -dependencies = ["pyslobs>=2.0.5", "asyncclick>=8.1.8", "rich>=14.0.0", "anyio>=4.12.0"] +dependencies = [ + "pyslobs>=2.0.5", + "asyncclick>=8.1.8", + "rich>=14.0.0", + "anyio>=4.12.0", +] requires-python = ">=3.11" readme = "README.md" license = { text = "MIT" } @@ -36,6 +41,8 @@ test.keep_going = true fmt.cmd = "ruff format {args}" post_fmt.cmd = "ruff check {args}" +completion.cmd = "task generate-completion-scripts" + [dependency-groups] dev = [ "tox-pdm>=0.7.2",