An open API service indexing awesome lists of open source software.

https://github.com/integralist/zsh-cli-json-parser

Zsh script that uses jq to parse a JSON structure of a CLI
https://github.com/integralist/zsh-cli-json-parser

Last synced: over 1 year ago
JSON representation

Zsh script that uses jq to parse a JSON structure of a CLI

Awesome Lists containing this project

README

          

# zsh-cli-json-parser

## `get_cli_options`

The file [get_cli_options.zsh](get_cli_options.zsh) parses a JSON structure and
returns the relevant subcommands and flag options:

> \[!NOTE\]
> This isn't a recursive implementation.\
> We stop at 4 levels deep.

## Example JSON structure

The [example.json](example.json) file demonstrates what structure is required to
be passed to the `get_cli_options` shell function.

## Example Output

Using `example.json` as our example structure, we should see the following
output:

```zsh
# show the top-level commands
$ get_cli_options "example.json" ""
service
acl

# show the top-level/global flag options
$ get_cli_options "example.json" "--"
--help
--quiet
--verbose

# show subcommands and flags
$ get_cli_options "example.json" "acl"
--help-acl
create
list

# show command flags only
$ get_cli_options "example.json" "acl --"
--help-acl

# show subcommands and flags under a subcommand
$ get_cli_options "example.json" "acl list"
--json
third-level

# show subcommand flags only
$ get_cli_options "example.json" "acl list --"
--json

# show subcommands and flags under a third-level subcommand
$ get_cli_options "example.json" "acl list third-level"
--foo
--bar
fourth-level

# show third-level subcommand flags only
$ get_cli_options "example.json" "acl list third-level --"
--foo
--bar
```

## Zsh Autocomplete

You can plug this script into your zsh shell completion setup like so:

> \[!NOTE\]
> The following example is for setting up autocomplete for a binary called
> `example` (which uses the `example.json` from this repo as its structure). I
> typically store these files in `$HOME/.zsh/`, so in this case it would be
> stored as `$HOME/.zsh/_example`.

```zsh
#compdef fastly
autoload -U compinit && compinit
autoload -U bashcompinit && bashcompinit

_example_bash_autocomplete() {
local cur opts input_str
COMPREPLY=()

# Current word being completed
cur="${COMP_WORDS[COMP_CWORD]}"

# Reconstruct the input arguments excluding the binary name
local input=("${COMP_WORDS[@]:1}")

# Join the array into a single string, trimming excess whitespace
input_str=$(echo "${input[*]}" | sed 's/ *$//')

# Debugging: Log the exact call to get_cli_options
# echo "Calling get_cli_options with input_str: '$input_str'" >> /tmp/autocomplete-debug.log

# Pass the reconstructed input string to get_cli_options
opts=$(get_cli_options "$HOME/.zsh/example.json" "$input_str")

# Log the result of get_cli_options
# echo "opts: $opts" >> /tmp/autocomplete-debug.log

# Generate completions based on opts
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )

# Fall back to file completion if no matches are found
[[ $COMPREPLY ]] && return
compgen -f
return 0
}
complete -F _example_bash_autocomplete example
```

You'll then need to source the above `_example` script:

```zsh
dir_zsh="$HOME/.zsh"
path_example_completion="$dir_zsh/_example"
chmod +x $path_example_completion
source "$path_example_completion"
```

I'm not sure how you have your Zsh autocomplete setup, but I need to add this
custom directory to my `fpath`:

```zsh
fpath=($dir_zsh $fpath)
```

> \[!TIP\]
> If you're looking for an example autocomplete setup, then view my [dot
> files][1].

[1]: https://github.com/Integralist/dotfiles/blob/main/.config/zsh/autocomplete.zsh