TL; DR: docopt lets you describe your program’s CLI by writing the help and then parsing it into a usable data structure.
This new feature for ralsina/docopt.cr a fork of the original docopt.cr gives you smart shell completion.
At least for bash, other shells to come.
Quoting the README:
Shell Completion Generation
docopt.cr can generate shell completion scripts for bash (other shells to come)
so that when you TAB
while writing a command it will show you the possible
options.
The code to create a bash completion looks like this for the classic
naval_fate
example:
bash_completion = Docopt.bash_completion("naval_fate", doc)
This will give you a reasonable bash completion. To make this available to the user
you could have something like a naval_fate --completion
in your usage instructions
and either tell the user to put this in their .bashrc
:
naval_fate --completion >> ~/.bashrc
Or write it to a file and put it in /etc/bash_completion.d/:
naval_fate --completion > /etc/bash_completion.d/naval_fate
Custom Completions
Usually the suggestions provided by the completions are limited to
flags options and files, which may not be the right thing.
Suppose you want the naval_fate ship new
command to be completed with
just the names from a list of famous ships. You can do that using the
custom_completions
argument:
bash_completion = Docopt.bash_completion(
"naval_fate",
doc,
{"naval_fate_ship_new" => %("Titanic 'Queen Mary' 'USS Enterprise')}
)
The key is the name of the command and any subcommands, joined by
_
(underscore). In this case, the command is naval_fate ship new
.
The completion should be provided as a list of space-separated strings,
and if any of them contain spaces, they should be single-quoted.
It can be made more dynamic by using instead the output of a command.
For example, if the command naval_fate ship list
existed, we could do this
using bash
ability to run commands inside other commands:
bash_completion = Docopt.bash_completion(
"naval_fate",
doc,
{"naval_fate_ship_new" => "$(naval_fate ship list)"}
)
And the completion for naval_fate ship new
would be the output of
naval_fate ship list
.