zsh-completions/zsh-completions-howto.org

251 lines
18 KiB
Org Mode

* Intro
The official documentation for writing zsh completion functions is difficult to understand, and doesn't give many examples.
At the time of writing this document I was able to find a few other tutorials on the web, however those tutorials only
explain a small portion of the capabilities of the completion system. This document aims to cover areas not explained elsewhere,
with examples, so that you can learn how to write more advanced completion functions. I do not go into all the details, but will
give enough information and examples to get you up and running. If you need more details you can look it up for yourself in the
[[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][official documentation]].
Please make any scripts that you create publically available for others (e.g. by forking this repo and making a [[id:64bcd501-b0f0-48c7-b8e2-07af708b95ec][pull request]]).
* Getting started
** Telling zsh which function to use for completing a command
Completion functions for commands are stored in files with names beginning with an underscore _, and these files should
be placed in a directory listed in the $fpath variable.
You can add a directory to $fpath by adding a line like this to your ~/.zshrc file:
#+BEGIN_SRC sh
fpath=(~/newdir $fpath)
#+END_SRC
The first line of a completion function file can look something like this:
#+BEGIN_SRC sh
#compdef foobar
#+END_SRC
This tells zsh that the file contains code for completing the foobar command.
This is the format that you will use most often for the first line, but you can also use the same file for completing
several different functions if you want. See [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Autoloaded-files][here]] for more details.
You can also use the compdef command directly (e.g. in your ~/.zshrc file) to tell zsh which function to use for completing
a command like this:
#+BEGIN_SRC sh
> compdef _function foobar
#+END_SRC
or to use the same completions for several commands:
#+BEGIN_SRC sh
> compdef _function foobar goocar hoodar
#+END_SRC
or if you want to supply arguments:
#+BEGIN_SRC sh
> compdef '_function arg1 arg2' foobar
#+END_SRC
See [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Functions-4][here]] for more details.
** Completing generic gnu commands
Many [[http://www.gnu.org/][gnu]] commands have a standardized way of listing option descriptions (when the --help option is used).
For these commands you can use the _gnu_generic function for automatically creating completions, like this:
#+BEGIN_SRC sh
> compdef _gnu_generic foobar
#+END_SRC
or to use _gnu_generic with several different commands:
#+BEGIN_SRC sh
> compdef _gnu_generic foobar goocar hoodar
#+END_SRC
This line can be placed in your ~/.zshrc file.
** Copying completions from another command
If you want a command, say cmd1, to have the same completions as another, say cmd2, which has already had
completions defined for it, you can do this:
#+BEGIN_SRC sh
> compdef cmd1=cmd2
#+END_SRC
This can be useful for example if you have created an alias for a command to help you remember it.
* Writing your own completion functions
A good way to get started is to look at some already defined completion functions.
On my linux installation these are found in /usr/share/zsh/functions/Completion/Unix
and /usr/share/zsh/functions/Completion/Linux and a few other subdirs.
You will notice that the _arguments function is used a lot in these files.
This is a utility function that makes it easy to write simple completion functions.
The _arguments function is a wrapper around the compadd builtin function.
The compadd builtin is the core function used to add completion words to the command line, and control its behaviour.
However, most of the time you will not need to use compadd, since there are many utility functions such as _arguments
and _describe which are easier to use.
** Utility functions
Here is a list of some of the utility functions that may be of use.
The full list of utility functions, with full explanations, is available [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions][here]].
Examples of how to use these functions are given in the next section.
*** main utility functions for overall completion
| _alternative | Loop over tag labels and perform actions based on matching tag label. |
| _arguments | Used to specify how to complete individual options & arguments for a command with unix style options. |
| _describe | Used for creating simple completions consisting of single words with descriptions (but no actions). Easier to use than _arguments |
| _gnu_generic | Can be used to complete options for commands that understand the `--help' option. |
| _regex_arguments | Creates a function for matching commandline arguments with regular expressions, and then performing actions/completions. |
*** functions for performing complex individual completions
| _values | Used for completing arbitrary keywords (values) and their arguments, or comma separated lists of such combinations. |
| _combination | Used to complete combinations of values, for example pairs of hostnames and usernames. |
| _multi_parts | Used for completing multiple parts of words separately where each part is separated by some char, e.g. for completing partial filepaths: /u/i/sy -> /usr/include/sys |
| _sep_parts | Like _multi_parts but allows different separators at different parts of the completion. |
*** functions for completing specific types of objects
| _path_files | Used to complete filepaths. Take several options to control behaviour. |
| _files | Calls _path_files with all options except -g and -/. These options depend on file-patterns style setting. |
| _net_interfaces | Used for completing network interface names |
| _users | Used for completing user names |
| _groups | Used for completing group names |
| _options | Used for completing the names of shell options. |
| _parameters | Used for completing the names of shell parameters/variables (can restrict to those matching a pattern). |
*** functions for handling cached completions
If you have a very large number of completions you can save them in a cache file so that the completions load quickly.
| _cache_invalid | indicates whether the completions cache corresponding to a given cache identifier needs rebuilding |
| _retrieve_cache | retrieves completion information from a cache file |
| _store_cache | store completions corresponding to a given cache identifier in a cache file |
*** other functions
| _message | Used for displaying help messages in places where no completions can be generated. |
| _regex_words | Can be used to generate arguments for the _regex_arguments command. This is easier than writing the arguments manually. |
| _guard | Can be used in the ACTION of specifications for _arguments and similar functions to check the word being completed. |
*** Actions
Many of the utility functions such as _arguments, _regex_arguments, _alternative and _values may include an action
at the end of an option/argument specification. This action indicates how to complete the corresponding argument.
The actions can take one of the following forms:
| ( ) | Argument is required but no matches are generated for it. |
| (ITEM1 ITEM2) | List of possible matches |
| ((ITEM1\:'DESC1' ITEM2\:'DESC2')) | List of possible matches, with descriptions. Make sure to use different quotes than those around the whole specification. |
| ->STRING | Set $state to STRING and continue ($state can be checked in a case statement after the utility function call) |
| FUNCTION | Name of a function to call for generating matches or performing some other action, e.g. _files or _message |
| {EVAL-STRING} | Evaluate string as shell code to generate matches. This can be used to call a utility function with arguments, e.g. _values or _describe |
| =ACTION | Inserts a dummy word into completion command line without changing the point at which completion takes place. |
Not all action types are available for all utility functions that use them. For example the ->STRING type is not available in the
_regex_arguments or _alternative functions.
** Writing simple completion functions using _describe
The _describe function can be used for simple completions where the order and position of the options/arguments is
not important. You just need to create an array parameter to hold the options & their descriptions, and then pass
the parameter name as an argument to _describe. The following example creates completion candidates -c and -d, with
the descriptions.
#+BEGIN_SRC sh
local -a options
options=('-c:description for -c opt' '-d:description for -d opt')
_describe 'values' options
#+END_SRC
You can use several different lists separated by a double hyphen e.g. like this:
#+BEGIN_SRC sh
local -a options arguments
options=('-c:description for -c opt' '-d:description for -d opt')
arguments=('e:description for e arg' 'f:description for f arg')
_describe 'values' options -- arguments
#+END_SRC
The _describe function can be used in an ACTION as part of a specification for _alternative, _arguments or _regex_arguments.
In this case you will have to put it in braces with its arguments, e.g. 'TAG:DESCRIPTION:{_describe 'values' options}'
** Writing completion functions using _alternative
Like _describe, this function performs simple completions where the order and position of options/arguments is not important.
However, unlike _describe, you can call execute shell code or call functions to obtain the completion candidates.
As arguments it takes a list of specifications each in the form `TAG:DESCRIPTION:ACTION' where TAG is a tag name,
DESCRIPTION is a description, and ACTION is one of the action types listed previously (apart from the ->STRING and =ACTION forms).
For example:
#+BEGIN_SRC sh
_alternative 'args:custom args:(a b c)' 'files:filenames:_files'
#+END_SRC
The first specification adds completion candidates a, b & c, and the second specification calls the _files function
for completing filepaths.
We could split the specifications over several lines with \ and add descriptions to each of the custom args like this:
#+BEGIN_SRC sh
_alternative 'args:custom args:((a\:"description a" b\:"description b" c\:"description c"))'\
'files:filenames:_files'
#+END_SRC
If we want to call _files with arguments we can put it in braces, like this:
#+BEGIN_SRC sh
_alternative 'args:custom args:((a\:"description a" b\:"description b" c\:"description c"))'\
'files:filenames:{_files -/}'
#+END_SRC
To use parameter expansion to create our list of completions we must use double quotes to quote the specifications,
e.g:
#+BEGIN_SRC sh
_alternative "dirs:user directories:($userdirs)"\
"pids:process IDs:($(ps -A o pid=))"
#+END_SRC
In this case the first specification adds the words stored in the $userdirs variable, and the second specification
evaluates 'ps -A o pid=' to get a list of pids to use as completion candidates.
We can use other utility functions such as _values in the ACTION to perform more complex completions, e.g:
#+BEGIN_SRC sh
_alternative "dirs:user directories:($userdirs)"\
'opts:comma separated opts:{_values -s , a b c}'
#+END_SRC
this will complete the items in $userdirs, aswell as a comma separated list containing a, b &/or c.
As with _describe, the _alternative function can itself be used in an ACTION as part of a specification for _arguments
or _regex_arguments.
** Writing completion functions using _arguments
With the _arguments function you can create much more sophisticated completion functions.
Like the _alternative function, _arguments takes a list of specification strings as arguments.
These specification strings can be for specifying options and any corresponding option arguments (e.g. -f filename),
or command arguments.
Basic option specifications take the form '-OPT[DESCRIPTION]', e.g. like this:
#+BEGIN_SRC sh
_arguments '-s[sort output]' '--l[long output]' '-l[long output]'
#+END_SRC
Arguments for the option can be specified after the option description in this form '-OPT[DESCRIPTION]:MESSAGE:ACTION',
where MESSAGE is a message to display and ACTION can be any of the forms mentioned in the ACTIONS section above.
For example:
#+BEGIN_SRC sh
_arguments '-f[input file]:filename:_files'
#+END_SRC
| -OPT | single option |
| +OPT | single option beginning with + |
| -+OPT | single option beginning with + or - |
| +-OPT | single option beginning with + or - |
| {-OPT1,--OPT2} | list of alternatives for an option (e.g. short & long forms). This is not a different specification but a trick that relies on braces expansion. |
| -OPT- | indicates the argument of the option must come directly after the option name, e.g. -optARG |
| -OPT+ | indicates the argument of the option may come directly after the option or as a separate word, e.g. -optARG or -opt ARG |
| -OPT= | indicates the argument of the option may come as a separate word, or separated from the option with an = sign, e.g. -opt=ARG or -opt ARG |
| -OPT=- | indicates the argument of the option must appear after an = sign, not as a separate word |
| OPTSPEC[explanation] | the explanation string will be displayed along with the option (OPTSPEC is any of the previously mentioned option specifications) |
| *OPTSPEC | indicates that the option may be repeated (OPTSPEC is any of the previously mentioned option specifications) |
| OPTSPEC:ARG1:ARG2:etc | for specifying options that take arguments (see below for option argument specification) |
As arguments it takes special strings specifying the options & arguments to the function being completed,
e.g. like this:
#+BEGIN_SRC sh
_arguments '--help[show help]' '-?[show help]' '1:First arg:_files'
#+END_SRC
This example completes the options --help & -? when trying to complete a hyphen, which will both be listed together
with the same description in this case. The first non-option argument is completed using the _files function which
completes file/directories.
There are a couple of tutorials on how to use _arguments [[http://www.linux-mag.com/id/1106/][here]] and [[http://wikimatze.de/writing-zsh-completion-for-padrino.html][here]], so I won't cover any more here.
Also have a look at the many completion functions listed [[https://github.com/vapniks/zsh-completions/tree/master/src][here]] many of which use _arguments.
The full documentation for _arguments is available [[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-Functions][here]].
** Writing completion functions using _regex_arguments and _regex_words
*** Patterns
* Testing & debugging
To reload a completion function:
#+BEGIN_SRC sh
> unfunction _func
> autoload -U _func
#+END_SRC
The following functions can be called to obtain useful information.
If the default keybindings don't work you can try pressing Alt+x and then enter the command name.
| Function | Default keybinding | Description |
|-----------------+--------------------+--------------------------------------------------------------------------------------------------------------------------------|
| _complete_help | Ctrl+x h | displays information about context names, tags, and completion functions used when completing at the current cursor position |
| _complete_help | Alt+2 Ctrl+x h | as above but displays even more information |
| _complete_debug | Ctrl+x ? | performs ordinary completion, but captures in a temporary file a trace of the shell commands executed by the completion system |
* Gotchas (things to watch out for)
Take care to use the correct type of quoting for specifications to _arguments or _regex_arguments:
use double quotes if there is a parameter that needs to be expanded in the specification, single quotes otherwise,
and make sure to use different quotes around item descriptions.
* Putting it all together
* Other resources
[[http://wikimatze.de/writing-zsh-completion-for-padrino.html][Here]] is a nicely formatted short tutorial showing basic usage of the _arguments function,
and [[http://www.linux-mag.com/id/1106/][here]] is a slightly more advanced tutorial using the _arguments function.
[[http://zsh.sourceforge.net/Doc/Release/Completion-System.html#Completion-System][Here]] is the zshcompsys man page.