Shell Completion¶
Click provides tab completion support for Bash (version 4.4 and up), Zsh, and Fish. It is possible to add support forother shells too, and suggestions can be customized at multiple levels.
Shell completion suggests command names, option names, and values for choice, file, and path parameter types. Optionsare only listed if at least a dash has been entered. Hidden commands and options are not shown.
$repo<TAB><TAB>clone commit copy delete setuser$repoclone-<TAB><TAB>--deep --help --rev --shallow -r
Enabling Completion¶
Completion is only available if a script is installed and invoked through an entry point, not through thepythoncommand. SeePackaging Entry Points. Once the executable is installed, calling it with a special environment variable willput Click in completion mode.
To enable shell completion, the user needs to register a special function with their shell. The exact script variesdepending on the shell you are using. Click will output it when called with_{FOO_BAR}_COMPLETE set to{shell}_source.{FOO_BAR} is the executable name in uppercase with dashes replaced by underscores. It isconventional but not strictly required for environment variable names to be in upper case. This convention helpsdistinguish environment variables from regular shell variables and commands, making scripts and configuration files morereadable and easier to maintain. The built-in shells arebash,zsh, andfish.
Provide your users with the following instructions customized to your program name. This usesfoo-bar as an example.
Add this to~/.bashrc:
eval"$(_FOO_BAR_COMPLETE=bash_sourcefoo-bar)"
Add this to~/.zshrc:
eval"$(_FOO_BAR_COMPLETE=zsh_sourcefoo-bar)"
Add this to~/.config/fish/completions/foo-bar.fish:
_FOO_BAR_COMPLETE=fish_source foo-bar|source
This is the same file used for the activation script methodbelow. For Fish it’s probably always easier to use that method.
Usingeval means that the command is invoked and evaluated every time a shell is started, which can delay shellresponsiveness. To speed it up, write the generated script to a file, then source that. You can generate the files aheadof time and distribute them with your program to save your users a step.
Save the script somewhere.
_FOO_BAR_COMPLETE=bash_sourcefoo-bar>~/.foo-bar-complete.bash
Source the file in~/.bashrc.
.~/.foo-bar-complete.bash
Save the script somewhere.
_FOO_BAR_COMPLETE=zsh_sourcefoo-bar>~/.foo-bar-complete.zsh
Source the file in~/.zshrc.
.~/.foo-bar-complete.zsh
Save the script to~/.config/fish/completions/foo-bar.fish:
_FOO_BAR_COMPLETE=fish_source foo-bar> ~/.config/fish/completions/foo-bar.fish
After modifying the shell config, you need to start a new shell in order for the changes to be loaded.
Custom Type Completion¶
When creating a customParamType, override itsshell_complete() method to provideshell completion for parameters with the type. The method must return a list ofCompletionItem objects.Besides the value, these objects hold metadata that shell support might use. The built-in implementations usetype toindicate special handling for paths, andhelp for shells that support showing a help string next to a suggestion.
In this example, the type will suggest environment variables that start with the incomplete value.
classEnvVarType(ParamType):name="envvar"defshell_complete(self,ctx,param,incomplete):return[CompletionItem(name)fornameinos.environifname.startswith(incomplete)]@click.command()@click.option("--ev",type=EnvVarType())defcli(ev):click.echo(os.environ[ev])
Overriding Value Completion¶
Value completions for a parameter can be customized without a custom type by providing ashell_complete function. Thefunction is used instead of any completion provided by the type. It is passed 3 positional arguments:
ctx- The current command context.param- The current parameter requesting completion.incomplete- The partial word that is being completed. May be an empty string if no characters have been enteredyet.
It must return a list ofCompletionItem objects, or as a shortcut it can return a list of strings.
In this example, the command will suggest environment variables that start with the incomplete value.
defcomplete_env_vars(ctx,param,incomplete):return[kforkinos.environifk.startswith(incomplete)]@click.command()@click.argument("name",shell_complete=complete_env_vars)defcli(name):click.echo(f"Name:{name}")click.echo(f"Value:{os.environ[name]}")
Adding Support for a Shell¶
Support can be added for shells that do not come built in. Be sure to check PyPI to see if there’s already a packagethat adds support for your shell. This topic is very technical, you’ll want to look at Click’s source to study thebuilt-in implementations.
Shell support is provided by subclasses ofShellComplete registered withadd_completion_class(). WhenClick is invoked in completion mode, it callssource() to output the completion script, orcomplete() to output completions. The base class provides default implementations that requireimplementing some smaller parts.
First, you’ll need to figure out how your shell’s completion system works and write a script to integrate it with Click.It must invoke your program with the environment variable_{FOO_BAR}_COMPLETE set to{shell}_complete and pass thecomplete args and incomplete value. How it passes those values, and the format of the completion response from Click isup to you.
In your subclass, setShellComplete.source_template to the completion script. The default implementation willperform% formatting with the following variables:
complete_func- A safe name for the completion function defined in the script.complete_var- The environment variable name for passing the{shell}_completeinstruction.foo_bar- The name of the executable being completed.
The example code is for a made up shell “My Shell” or “mysh” for short.
fromclick.shell_completionimportadd_completion_classfromclick.shell_completionimportShellComplete_mysh_source="""\%(complete_func)s { response=$(%(complete_var)s=mysh_complete%(foo_bar)s) # parse response and set completions somehow}call-on-complete%(foo_bar)s%(complete_func)s"""@add_completion_classclassMyshComplete(ShellComplete):name="mysh"source_template=_mysh_source
Next, implementget_completion_args(). This must get, parse, and return the complete args andincomplete value from the completion script. For example, for the Bash implementation theCOMP_WORDS env var containsthe command line args as a string, and theCOMP_CWORD env var contains the index of the incomplete arg. The methodmust return a(args,incomplete) tuple.
importosfromclick.parserimportsplit_arg_stringclassMyshComplete(ShellComplete):...defget_completion_args(self):args=split_arg_string(os.environ["COMP_WORDS"])ifos.environ["COMP_PARTIAL"]=="1":incomplete=args.pop()returnargs,incompletereturnargs,""
Finally, implementformat_completion(). This is called to format eachCompletionItem into a string. For example, the Bash implementation returnsf"{item.type},{item.value} (it doesn’t support help strings), and the Zsh implementation returns each part separated by a newline, replacing empty help with a_ placeholder. This format is entirely up to what you parse with your completion script.
Thetype value is usuallyplain, but it can be another value that the completion script can switch on. For example,file ordir can tell the shell to handle path completion, since the shell is better at that than Click.
classMyshComplete(ShellComplete):...defformat_completion(self,item):returnf"{item.type}\t{item.value}"
With those three things implemented, the new shell support is ready. In case those weren’t sufficient, there are moreparts that can be overridden, but that probably isn’t necessary.
The activation instructions will again depend on how your shell works. Use the following to generate the completionscript, then load it into the shell somehow.
_FOO_BAR_COMPLETE=mysh_source foo-bar