<navid="sidebar"class="sidebar"aria-label="Table of contents">
<divclass="sidebar-scrollbox">
<olclass="chapter"><liclass="chapter-item expanded affix "><ahref="zshguide.html">A User's Guide to the Z-Shell</a></li><liclass="chapter-item expanded "><ahref="zshguide01.html"><strongaria-hidden="true">1.</strong> A short introduction</a></li><liclass="chapter-item expanded "><ahref="zshguide02.html"><strongaria-hidden="true">2.</strong> What to put in your startup files</a></li><liclass="chapter-item expanded "><ahref="zshguide03.html"><strongaria-hidden="true">3.</strong> Dealing with basic shell syntax</a></li><liclass="chapter-item expanded "><ahref="zshguide04.html"><strongaria-hidden="true">4.</strong> The Z-Shell Line Editor</a></li><liclass="chapter-item expanded "><ahref="zshguide05.html"><strongaria-hidden="true">5.</strong> Substitutions</a></li><liclass="chapter-item expanded "><ahref="zshguide06.html"class="active"><strongaria-hidden="true">6.</strong> Completion, old and new</a></li><liclass="chapter-item expanded "><ahref="zshguide07.html"><strongaria-hidden="true">7.</strong> Modules and other bits and pieces Not written</a></li></ol>
<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p>The option <code>ALWAYS_LAST_PROMPT</code> is set by default, and has been since an
earlier 3.1 release of zsh; after listing a completion, the cursor is
taken back to the line it was on before, instead of reprinting it
underneath. The downside of this is that the listing will be obscured
when you execute the command or produce a different listing, so you may
want to unset the option. <code>ALWAYS_LAST_PROMPT</code> behaviour is required for
menu selection to work, which is why I mention it now instead of in the
ragbag below.</p>
<p>When you're writing your own editor functions which invoke completion,
you can actually cancel the effect of this with the widget
<code>end-of-list</code>, which you would call as <code>zle end-of-list</code> (it's a normal
editing function, not a completion function). You can also bind it to a
key to use to preserve the existing completion list. On the other hand,
if you want to control the behaviour within a completion function, i.e.
to decide whether completion will try to return to the prompt above the
list, you can manipulate it with the <code>last_prompt</code> element of the
<code>$compstate</code> associative array, so for example:</p>
<pre><code> compstate[last_prompt]=''
</code></pre>
<p>will turn off the behaviour for the completion in progress. <code>$compstate</code>
is the place to turn if you find yourself wanting to control completion
behaviour in this much detail; see the <code>zshcompwid</code> manual page.</p>
<p><spanid="l149"></span></p>
<h3id="623-menu-completion-and-menu-selection"><aclass="header"href="#623-menu-completion-and-menu-selection">6.2.3: Menu completion and menu selection</a></h3>
<p>The most significant matter decided by the options above is whether or
not you are using menu completion. If you are not, you will need to type
the next character explicitly when completion is ambiguous; if you are,
you just need to keep hitting tab until the completion you want appears.
In the second case, of course, this works best if there are not too many
possibilities. Use of <code>AUTO_MENU</code> or binding the <code>menu-complete</code> widget
to a separate key-stroke gives you something of both worlds.</p>
<p>A new variant of menu completion appeared in 3.1.6; in fact, it deserves
the name menu completion rather more than the original form, but since
that name was taken it is called `menu selection'. This allows you to
move the cursor around the list of completions to select one. It is
implemented by a separate module, <code>zsh/complist</code>; you can make sure this
is loaded by putting `<code>zmodload -i zsh/complist</code>' in <code>.zshrc</code>, although
it should be loaded automatically when the style <code>menu</code> is set as below.
For it to be useful, you need two other things. The first is
<code>ALWAYS_LAST_PROMPT</code> behaviour; this is suppressed if the whole
completion list won't appear on the screen, since there's no line on the
screen to go back to. However, menu selection does still work, by
allowing you to scroll the list up and down. The second thing is that
you need to start menu completion in any of the usual ways; menu
selection is an addition to menu completion, not a replacement.</p>
<p>Now you should set the following style:</p>
<pre><code> zstyle ':completion:*' menu select=<NUM>
</code></pre>
<p>If an ambiguous completion produces at least <code><NUM></code> possibilities, menu
selection is started. You can understand this best by trying it. One of
the completions in the list, initially the top-leftmost, is highlighted
and inserted into the line. By moving the cursor in the obvious
directions (with wraparound at the edges), you change both the value
highlighted and the value inserted into the line. When you have the
value you want, hit return, which removes the list and leaves the
inserted value. Hitting <code>^G</code> (the editor function <code>send-break</code>) aborts
menu selection, removes the list and restores the command line.</p>
<p>Internally, zsh actually uses the parameter <code>$MENUSELECT</code> to supply the
number and hence start menu selection. However, this is always
initialised from the style as defined above, so you shouldn't set
<code>$MENUSELECT</code> directly (unless you are using <code>compctl</code>, which will
happily use menu selection). As with other styles, you can specify
different values for different contexts; the <code>default</code> tag is checked if
the current context does not produce a value for the style with whatever
the current tag is. Note that the <code>menu</code> style also allows you to
control whether menu completion is started at all, with or without
selection; in other words, it is a style corresponding to the
<code>MENU_COMPLETE</code> option.</p>
<p>There is one other additional feature when using menu selection. The zle
command <code>accept-and-infer-next-history</code> has a different meaning here; it
accepts a completion, and then tries to complete again using menu
selection. This is very useful with directory hierarchies, and in
combination with <code>undo</code> gives you a simple file browser. You need to
bind it in the special keymap <code>menuselect</code>; for example, I use</p>
<p>because the behaviour reminds me of what is usually bound to <code>^O</code> in
emacs modes, namely <code>accept-line-and-down-history</code>. Binding it like this
has no effect on <code>^O</code> in the normal keymaps. Try it out by entering menu
selection on a set of files including directories, and typing <code>^O</code> on
one of the directories. You should immediately have the contents of that
directory presented for the next selection, while <code>undo</code> is smart enough
not only to remove that selection but return to completion on the parent
directory.</p>
<p>You can choose the manner in which the currently selected value in the
completion list is highlighted using exactly the same mechanism as for
specifying colours for particular types of matches; see the description
of the <code>list-colors</code> style below.</p>
<p><spanid="l150"></span></p>
<h3id="624-other-ways-of-changing-completion-behaviour"><aclass="header"href="#624-other-ways-of-changing-completion-behaviour">6.2.4: Other ways of changing completion behaviour</a></h3>
<p>If this is set, the cursor is always moved to the end of the word after
it is completed, even if completion took place in the middle. This also
happens with menu completion.</p>
<p><spanid="l151"></span></p>
<h3id="625-changing-the-way-completions-are-displayed"><aclass="header"href="#625-changing-the-way-completions-are-displayed">6.2.5: Changing the way completions are displayed</a></h3>
<p><strong><code>LIST_TYPES</code></strong></p>
<p>This is like the <code>-F</code> option to <code>ls</code>; files which appear in the
completion listing have a trailing `<code>/</code>' for a directory, `<code>*</code>' for a
regular file executable by the current process, `<code>@</code>' for a link,
`<code>|</code>' for a named pipe, `<code>%</code>' for a character device and `<code>#</code>' for a
block device. This option is on by default.</p>
<p>Note that the identifiers only appear if the completion system knows
that the item is supposed to be a file. This is automatic if the usual
filename completion commands are used. There is also an option <code>-f</code> to
the builtin <code>compadd</code> if you write your own completion function and want
to tell the shell that the values may be existing files to apply
<code>LIST_TYPES</code> to (though no harm is caused if no such files exist).</p>
<p>These affect the arrangement of the completion listing. With
<code>LIST_PACKED</code>, completion lists are made as compact as possible by
varying the widths of the columns, instead of formatting them into a
completely regular grid. With <code>LIST_ROWS_FIRST</code>, the listing order is
changed so that adjacent items appear along rows instead of down
columns, rather like <code>ls</code>'s <code>-x</code> option.</p>
<p>It is possible to alter both these for particular contexts using the
styles <code>list-packed</code> and <code>list-rows-first</code>. The styles in such cases
always override the option; the option setting is used if no
corresponding style is found.</p>
<p>Note also the discussion of completion groups later on: it is possible
to have different types of completion appear in separate lists, which
may then be formatted differently using these tag-sensitive styles.</p>
<p><spanid="l152"></span></p>
<h2id="63-getting-started-with-new-completion"><aclass="header"href="#63-getting-started-with-new-completion">6.3: Getting started with new completion</a></h2>
<p>Before I go into any detail about new completion, here's how to set it
up so that you can try it out. As I said above, the basic objects that
do completions are shell functions. These are all autoloaded, so the
shell needs to know where to find them via the <code>$fpath</code> array. If the
shell was installed properly, and nothing in the initialization files
has removed the required bits from <code>$fpath</code>, this should happen
automatically. It's even possible your system sets up completion for you
(Mandrake Linux 6.1 is the first system known to do this out of the
box), in which case type `<code>which compdef</code>' and you should see a
complete shell function --- actually the one which allows you to define
additional completion functions. Then you can skip the next paragraph.</p>
<p>If you want to load completion, try this at the command line:</p>
<pre><code> autoload -U compinit
compinit
</code></pre>
<p>which should work silently. If not, you need to ask your system
administrator what has happened to the completion functions or find them
yourself, and then add all the required directories to your <code>$fpath</code>.
Either they will all be in one big directory, or in a set of
subdirectories with the names <code>AIX</code>, <code>BSD</code>, <code>Base</code>, <code>Debian</code>, <code>Redhat</code>,
<code>Unix</code>, <code>X</code> and <code>Zsh</code>; in the second case, all the directories need to
be in <code>$fpath</code>. When this works, you can add the same lines, including
any modification of <code>$fpath</code> you needed, to your <code>.zshrc</code>.</p>
<p>You can now see if it's actually working. Type `<code>cd </code>', then <code>^D</code>,
and you should be presented with a list of directories only, no regular
files. If you have <code>$cdpath</code> set, you may see directories that don't
appear with <code>ls</code>. As this suggests, the completion system is supplied
with completions for many common (and some quite abstruse) commands.
Indeed, the idea is that for most users completion just works without
intervention most of the time. If you think it should when it doesn't,
it may be a bug or an oversight, and you should report it.</p>
<p>Another example on the theme of `it just works':</p>
<pre><code> tar xzf archive.tar.gz ^D
</code></pre>
<p>will look inside the gzipped tar archive --- assuming the GNU version of
<code>tar</code>, for which the `<code>z</code>' in the first set of arguments reports that
the archive has been compressed with gzip --- and give you a list of
files or directories you can extract. This is done in a very similar way
to normal file completion; although there are differences, you can do
completion down to any directory depth within the archive. (At this
point, you're supposed to be impressed.)</p>
<p>The completion system knows about more than just commands and their
arguments, it also understands some of the shell syntax. For example,
there's an associative array called <code>$_comps</code> which stores the names of
commands as keys and the names of completion functions as the
corresponding values. Try typing:</p>
<pre><code> print ${_comps[
</code></pre>
<p>and then <code>^D</code>. You'll probably get a message asking if you really want
to see all the possible completions, i.e. the keys for <code>$_comps</code>; if you
say `<code>y</code>' you'll see a list. If you insert any of those keys, then
close the braces so you have e.g. `<code>${_comps[mozilla]}</code>' and hit
return, you'll see the completion function which handles that command;
in this case (at the time of writing) it's <code>_webbrowser</code>. This is one
way of finding out what function is handling a particular command. If
there is no entry --- i.e. the `<code>print ${_comps[mycmd]}</code>' gives you a
blank line --- then the command is not handled specially and will simply
use whatever function is defined for the `<code>-default-</code>' context, usually
<code>_default</code>. Usually this will just try to complete file names. You can
customize <code>_default</code>, if you like.</p>
<p>Apart from <code>-default-</code>, some other of those keys for <code>_comps</code> also look
like <code>-this-</code>: they are special contexts, places other than the
arguments of a command. We were using the context called <code>-subscript-</code>;
you'll find that the function in this case is called <code>_subscript</code>. Many
completion functions have names which are simply an underscore followed
by the command or context name, minus any hyphens. If you want a taster
of how a completion function looks, try `<code>which _subscript</code>'; you may
well find there are a lot of other commands in there that you don't know
yet.</p>
<p>It's important to remember that the function found in this way is at the
root of how a completion is performed. No amount of fiddling with
options or styles --- the stuff I'm going to be talking about for the
next few sections --- will change that; if you want to change the basic
completion, you will just have to write your own function.</p>
<p>By the way, you may have old-style completions you want to mix-in --- or
maybe you specifically don't want to mix them in so that you can make
sure everything is working with the new format. By default, the new
completion system will first try to find a specific new-style
completion, and if it can't it will try to find a <code>compctl</code>-defined
completion for the command in question. If all that fails, it will try
the usual new-style default completion, probably just filename
completion. Note that specific new-style completions take precedence,
which is fair enough, since if you've added them you almost certainly
don't want to go back and use the old form. However, if you don't ever
want to try old-style completion, you can put the following incantation
<p>For now, that's just black magic, but later I will explain the `style'
mechanism in more detail and you will see that this fits in with the
normal way of turning things off in new-style completion.</p>
<p><spanid="l153"></span></p>
<h2id="64-how-the-shell-finds-the-right-completions"><aclass="header"href="#64-how-the-shell-finds-the-right-completions">6.4: How the shell finds the right completions</a></h2>
<p>From the discussion of contexts above, the pattern will match any time
an argument to the <code>cd</code> command is being completed. The style being set
is called <code>tag-order</code>, and the values are the two tags valid for
directories in <code>cd</code>.</p>
<p>The <code>tag-order</code> style determines the order in which tags are tried. The
value given above means that first <code>local-directories</code> will be
completed; only if none can be completed will <code>path-directories</code> be
tried. You can enter the command and try this; if you don't have
<code>$cdpath</code> set up you can assign `<code>cdpath=(~)</code>', which will allow `<code>cd foo</code>' to change to a directory `<code>~/foo</code>' and allow completion of
directories accordingly. Go to a directory other than <code>~</code>; completion
for <code>cd</code> will only show subdirectories of where you are, not those of
<code>~</code>, unless you type a string which is the prefix of a directory under
<code>~</code> but not your current directory. For example,</p>
<pre><code> % cdpath=(~)
% ls -F ~
foo/ bar/
% ls -F
rod/ stick/
# Without that tag-order zstyle command, you would get...
# now you just get the local directories, if there are any...
% cd ^D
rod/ stick/
</code></pre>
<p>There's more you can do with the <code>tag-order</code> style: if you put the tags
into the same word by quoting, for example <code>"local-directories path-directories"</code>, then they would be tried at the same time, which in
this case gives you the effect of the default. In fact, since it's too
much work to know what tags are going to be available for every single
possible completion, the default when there is no appropriate
<code>tag-order</code> is simply to try all the tags available in the context at
once; this was of course what was originally happening for completion
after <code>cd</code>.</p>
<p>Even if there is a <code>tag-order</code> specification, any tags not specified
will usually be tried all together at the end, so you could actually
have missed out <code>path-directories</code> from the end of the original example
and the effect would have been the same. If you don't want that to
happen, you can specify a `<code>-</code>' somewhere in the list of tags, which is
not used as a tag but tells completion that only the tags in the list
should be tried, not any others that may be available. Also, if you
don't want a particular tag to be shown you can include `<code>!tagname</code>' in
the values, and all the others but this will be included. For example,
you may have noticed that when completing in command position you are
offered parameters to set as well as commands etc.:</p>
<pre><code> Completing external command
tex texhash texi2pdf text2sf
texconfig texi2dvi texindex textmode
texdoc texi2dvi4a2ps texlinks texutil
texexec texi2html texshow texview
Completing parameter
TEXINPUTS texinputs
</code></pre>
<p>(I haven't told you how to produce those descriptions, or how to make
the completions for different tags appear separately, but I will --- see
the descriptions of the `<code>format</code>' and `<code>group-name</code>' styles below.)
<p>which is used when you're completing for the command <code>aliens</code>, which
presumably has completions tagged as `<code>frooble</code>' (if not, you're very
weird). Then completion will first look up styles for that tag under the
name <code>frooble-funny</code>, and if it finds completions using those styles it
will list them with a description (if you are using <code>format</code>) of `funny
frooble'. Otherwise, it will look up the styles for the tag under its
usual name and try completion again. It's presumably obvious that if you
don't have different styles for the two labels of the tag, you get the
same completions each time.</p>
<p>Rather than overload you with information on tags by giving examples of
how to use tag labels now, I'll reserve this for the description of the
<code>ignored-patterns</code> style below, which is one neat use for labels. In
fact, it's the one for which it was invented; there are probably lots of
other ones we haven't thought of yet.</p>
<p>One important note about <code>tag-order</code> which I may not have made as
explicit as I should have: <em>it doesn't change which tags are actually
valid in that completion</em>. Just putting a tag name into the list doesn't
mean that tag name will be used; that's determined entirely by the
completion functions for a particular context. The <code>tag-order</code> style
simply alters the order in which the tags which <em>are</em> valid are
examined. Come back and read this paragraph again when you can't work
out why <code>tag-order</code> isn't doing what you want.</p>
<p>Note that the rule for testing patterns means that you can always
specify a catch-all worst case by `<code>zstyle "*" style ...</code>', which will
always be tried last --- not just in completion, in fact, since other
parts of the shell use the styles mechanism, and without the
`<code>:completion:</code>' at the start of the context this style definition will
be picked up there, too.</p>
<p>Styles like <code>tag-order</code> are the most important case where tags are used
on their own. In other cases, they can be added to the end of the
context; this is useful for styles which can give different results for
different sets of completions, in particular styles that determine how
the list of completions is displayed, or how a completion is to be
inserted into the command line. The tag is the final element, so is not
followed by a colon. A full context then looks something like
`<code>:completion::complete:cd::path-directories</code>'. Later, you'll see some
styles which can usefully be different for different tag contexts.
Remember, however, that the tags part of the context, like other parts,
may be empty if the completion system hasn't figured out what it should
be yet.</p>
<p><spanid="l156"></span></p>
<h2id="65-configuring-completion-using-styles"><aclass="header"href="#65-configuring-completion-using-styles">6.5: Configuring completion using styles</a></h2>
<p>You now know how to define a style for a particular context, using</p>
<p>--- note that although the first argument is a pattern, in this case it
is treated exactly, so if you give the pattern `<code>:completion:*:cd:*</code>',
only values given with <em>exactly</em> that pattern will be deleted, not other
values whose context begins with `<code>:completion:</code>' and contains
`<code>:cd:</code>'. The pattern and the style are optional when deleting; if
omitted, all styles for the context, or all styles of any sort, are
deleted. The completion system has its own defaults, but these are
builtin, so anything you specify takes precedence.</p>
<p>By the way, I did mention in passing in <ahref="zshguide04.html#zle">chapter 4</a>
that you could use styles in just the same way in ordinary zle widgets
(the ones created with `<code>zle -N</code>'), but you probably forgot about that
straight away. All the instructions about defining styles and using them
in your own functions from this chapter apply to zle functions. The only
difference is that in that case the convention for contexts is that the
context is set to `<code>:zle:</code><em>widget-name</em>' for executing the widget
<em>widget-name</em>.</p>
<p>The rest of this section describes some useful styles. It's up to you to
experiment with contexts if you want the style's values to be different
in different places, or just use `<code>*</code>' if you don't care.</p>
<p><spanid="l157"></span></p>
<h3id="651-specifying-completers-and-their-options"><aclass="header"href="#651-specifying-completers-and-their-options">6.5.1: Specifying completers and their options</a></h3>
<p>`Completers' are the behind-the-scenes functions that decide what sort
of completion is being done. You set what completers to use with the
`<code>completer</code>' style, which takes an array of completers to try in
<p>Actually, it's not bogus at all, since I just created one. First try
`<code>echo foo<TAB></code>'; no surprise, you get `<code>foobar</code>'. Now try completing
with `<code>fo-b<TAB></code>' after the `<code>echo</code>': basic completion fails, it gets
to `_approximate:-one' and finds that it's allowed one error, so
accepts the completion `<code>foobar</code>' again. Now try `<code>fort-ba<TAB></code>'.
This time nothing kicks in until the third completion, which effectively
allows it to match `<code>fort*-ba*<TAB></code>', so you see `<code>fortified-badger</code>'
(no, I've never seen one myself, but they're nocturnal, you know).
Finally, try `<code>fortfully-ba<TAB></code>'; the last entry, which allows up to
four errors, thoughtfully corrects `<code>or</code>' to `<code>righ</code>', and you get
`<code>frightfully-barbaric</code>'. All right, the example is somewhat unhinged,
but I think you can see the features are useful. If it makes you feel
better, it took me four or five attempts to get the styles right for
this.</p>
<p><spanid="l158"></span></p>
<h3id="652-changing-the-format-of-listings-groups-etc"><aclass="header"href="#652-changing-the-format-of-listings-groups-etc">6.5.2: Changing the format of listings: groups etc.</a></h3>
<p><strong><code>format</code></strong></p>
<p>You can use this style if you want to find out where the completions in
a completion listing come from. The most basic use is to set it for the
<code>descriptions</code> tag in any completion context. It takes a string value in
which `<code>%d</code>' should appear; this will be replaced by a description of
whatever is being completed. For example, I use:</p>
<pre><code> zstyle ':completion:*:descriptions' format 'Completing %d'
</code></pre>
<p>and if I type <code>cd^D</code>, I see a listing like this (until I define the
<code>group-name</code> style, that is):</p>
<pre><code> Completing external command
Completing builtin command
Completing shell function
cd cddbsubmit cdp cdrecord
cdctrl cdecl cdparanoia cdswap
cdda2wav cdmatch cdparanoia-yaf
cddaslave cdmatch.newer cdplay
cddbslave cdot cdplayer_applet
</code></pre>
<p>The descriptions at the top are related to the tag names --- usually
there's a unique correspondence --- but are in a more readable form; to
get the tag names, you need to use <code>^Xh</code>. You will no doubt see
something different, but the point is that the completions listed are a
mixture of external commands (e.g. <code>cdplay</code>), builtin commands (<code>cd</code>)
and shell functions (<code>cdmatch</code>, which happens to be a leftover from
old-style completion, showing you how often I clean out my function
directory), and it's often quite handy to know what you have.</p>
<p>You can use some prompt escapes in the description, specifically those
that turn on or off standout mode (`<code>%S</code>', `<code>%s</code>'), bold text
(`<code>%B</code>', `<code>%b</code>'), and underlined text (`<code>%U</code>', `<code>%u</code>'), to make the
descriptions stand out from the completion lists.</p>
<p>You can set this for some other tag than <code>descriptions</code> and the format
thus defined will be used only for completions of that tag.</p>
<p>These are not really complete commands at all in the strict sense, they
are normal editing commands which happen to have the effect of
completion. This means that they are not part of the completion system,
and though they are installed with other shell functions they will not
automatically be loaded. You will therefore need an explicit `<code>autoload -U predict-on</code>', etc. --- remember that the `<code>-U</code>' prevents the
functions from expanding any of your own aliases when they are read in
--- as well as an explicit `<code>bindkey</code>' command to bind each function,
and a `<code>zle -N</code>' statement to tell the line editor that the function is
to be regarded as an editing widget. The <code>predict-on</code> file, when loaded,
actually defines two functions, <code>predict-on</code> and <code>predict-off</code>, both of
which need to be defined and bound for them to work. So to use all of
<p>`Prediction' is a sort of dynamic history completion. With <code>predict-on</code>
in effect, the line editor will try to retrieve a line back in the
history which matches what you type. If it does, it will show the line,
extending past the current cursor position. You can then edit the line;
characters which do not insert anything mostly behave as normal. If you
continue to type, and what you type does not match the line which was
found, the line editor will look further back for another line; if no
line matches, editing is essentially as normal. Often this is flexible
enough that you can leave <code>predict-on</code> in effect, but you can return to
basic editing with <code>predict-off</code>.</p>
<p>Note that, with prediction turned on, deleting characters reverses the
direction of the history search, so that you go back to previous lines,
like an ordinary incremental search; unfortunately the previous line
found could be one you've already half-edited, because they don't
disappear from the list until you finally hit `return' on an edited
line to accept it. There's another problem with moving around the line
and inserting characters somewhere else: history searching will resume
as soon as you try to insert the new characters, which means everything
on the right of the cursor is liable to disappear again. So in that case
you need to turn prediction off explicitly. A final problem: prediction
is bad with multi-line buffers.</p>
<p>If prediction fails with <code>predict-on</code> active, completion is
automatically tried. The context for this looks like
`<code>:completion:predict::::</code>'. Various styles are useful at this point:
`<code>list</code>' could be set to <code>always</code>, which will show a possible
completion even if there is only one, for example. The style `<code>cursor</code>'
may have the values `<code>complete</code>' to move to the end of the word
completed, `<code>key</code>' to move past the rightmost occurrence of the
character just typed, allowing you just to keep typing, or anything else
not to move the cursor which is the default behaviour.</p>
<p>The <code>incremental-complete-word</code> function allows you to see a list of
possible completions as you type them character by character after the
first. The function is quite basic; it is really just an example of
using various line editor facilities, and needs some work to make a
useful system. It will understand <code>DEL</code> to delete the previous
character, return to accept, <code>^G</code> to abort, <code>TAB</code> to complete the word
as normal and <code>^D</code> to list possibilities; otherwise, keys which do not
insert are unlikely to have a useful effect. The completion is done
behind the scenes by the standard function <code>complete-word</code>.</p>
<p><spanid="l170"></span></p>
<h2id="67-matching-control-and-controlling-where-things-are-inserted"><aclass="header"href="#67-matching-control-and-controlling-where-things-are-inserted">6.7: Matching control and controlling where things are inserted</a></h2>
<p>The final matter before I delve into the system for writing new
completion functions is matching control; the name refers in this case
to how the matching between characters already typed on the command line
and characters in a trial completion is performed. This can be done in
two ways: by setting the <code>matcher-list</code> style, which applies to all
completions, or by using an argument (<code>-M</code>) to the low-level completion
functions. Mostly we will be concerned with the first. All this is best
illustrated by examples, which are taken from the section `<strong>Matching
Control</strong>' in the <code>zshcompwid</code> manual page; in the printed manual and
the `info' pages this occurs within the section `<code>Completion Widgets</code>'.</p>
<p>The <code>matcher-list</code> style takes an array value. The values will be tried
<p>This already looks a bit horrific, but it breaks down quite easily. We
test the <code>$CURRENT</code> parameter, which is a special parameter in the
completion system giving the word on the command line we are on. This is
the syntactic word --- the completion system has already done the hard
job (and that's not an overstatement, I can tell you) of deciding what
makes up a word on the command line, taking into account quoting and
special characters. The array of words is stored, unsurprisingly, in the
array <code>$words</code>. So word 1 will be `<code>p4</code>' and word 2 the subcommand.</p>
<p>Hence if we are past word 2, we look at <code>${words[2]}</code> to get the
subcommand, and use that to decide what to do next. The change to
<code>$curcontext</code> is a bit of cleverness to make it easy for the user to
defined styles for particular subcommands; refresh your mind by looking
at the discussion of styles and contexts above if you need to. For
example, if you are completing after `<code>p4 diff</code>', the context will look
something like
`<code>:completion::complete:p4-diff:argument-1:opened-files</code>' where the
remainder says you are on the first argument and are complete the tag
`<code>opened-files</code>', We'll see down below how we tell the system to use
that tag; the `<code>argument-1</code>' is handled by the <code>_arguments</code> utility
function, which takes away a lot of the load of handling options and
arguments in a standard UNIX format.</p>
<p>Next, we pretend that the `<code>p4</code>' at the start wasn't there by removing
the front of <code>$words</code> and decrementing <code>$CURRENT</code> so as to reflect its
new position in <code>$words</code>. The reason for doing this is that we are going
to use <code>_arguments</code> for handling the subcommand. As is only sensible,
this function looks at the first element of <code>$words</code> to find the command
word, and treats the rest as options or arguments to the command.</p>
<p>We then dispatch the right function for the command simply by
constructing the name of the function on the fly. Of course it's a
little neater to check the function exists first;
<code>$+functions[_perforce_cmd_$cmd]</code> would come to our aid again.</p>
<p>However, if we're still on the second (original) word, we have to
generate a list of functions to complete. We will do this by asking
Perforce's help system to list them, and store the results in the array
<code>$cmdlist</code>. The loop has a couple of checks to remove blank lines and
the title line at the start. The remaining lines have a command and a
description. We take the command, but also tack the description on after
a colon --- we can then show the user the description, too, as a bit of
extra help.</p>
<p>Actually, the Perforce command that generates the list of subcommands is
simply `<code>p4 help command</code>'. (That's really all you need to know; skip
the rest of the paragraph if you just want the basics.) The
`<code>_call_program help-commands</code>' was stuck in front for the name of
configurability. Before executing the command, the system checks in the
current context with the given tag <code>help-commands</code> for the style
<code>command</code>. If it finds a value for that style, it will use that as the
command to execute in the place of the remaining arguments. If the style
it read began with <code>-</code>, then the command it was going to execute ---
i.e. `<code>p4 help commands</code>' is appended to the end of the command read
from the style, so that the user's command can process the original
command if it needs to. This is really extreme sophistication; you will
rarely actually need the <code>command</code> style, but if you are writing a
completion for others to use it's polite to give them a chance to
intercept calls in this way.</p>
<p>The <code>_describe</code> command then does the work for us. The `<code>-t p4-commands</code>' gives the tag we are going to use; the convention is that
tag names are plural, though there's nothing to enforce this. Then we
give an overall description --- this is what appears after
`<code>Completing </code>' in the examples of the <code>format</code> style above; if you
don't have that set, you won't see it. Finally, we give the array name
--- note it is the <em>name</em>, not the substituted value. This is more
efficient because the shell doesn't need to extract the values until the
last minute; until then it can pass around just the single word. The
<code>_description</code> function knows about the `<code>completion:description</code>'
syntax; reread what I said about the <code>verbose</code> style for what the system
does with the descriptions for the completion.</p>
<p>The <code>_describe</code> function is one level above the completion system's
basic builtin command, <code>compadd</code>; it just knows about a single tag, with
a little icing sugar to display verbose descriptions. Later, we'll see
ways of building up alternatives where different types of completion can
be completed at the same point. There are lots of ways of doing this;
some of the more complicated are relegated to the detailed descriptions
<p>The function <code>_alternative</code> is a little bit like <code>_arguments</code>, but
thankfully much simpler. It's name gives away its purpose; every
argument specifies one of a set of possible alternatives, all of which
are valid at that point --- so the user is offered anything which
matches out of the choices, unlike <code>_arguments</code>, which has to decide
between the various possibilities. It's a sort of glorified loop around
`<code>_describe</code>', with <code>_arguments</code>'s conventions on the action for
generating completions (up to a point --- <code>_alternative</code> doesn't have
all the whackier ones, though it does have the ones I've been talking
about so far).</p>
<p>Each set of possibilities consists of the name of a tag, a description,
and an argument. The tag isn't present in <code>_arguments</code>. If you use <code>^xh</code>
to tell you about valid tags, you'll see <code>_arguments</code> has its own
generic tag, <code>argument-rest</code>; this isn't usually all that useful, so we
are going to supply more specific ones.</p>
<p>In the first possibility, it's the standard one for files, `<code>files</code>.
The function is the basic low-level one for completing files, too; it's
described below, but you already know a lot about the effect since it's
the completion system's workhorse which you use it all the time without
realising. Actually, it will supply its own tags, but that doesn't
matter since they will silently override what we say.</p>
<p>The second possibility is the new one we're adding. I've therefore
invented a suitable tag `<code>subdirs</code>', a description, `<code>subdirectory search</code>', and the name of the function I'm going to supply to do the
completion. This is quite simple:</p>
<pre><code> _perforce_subdir_search() {
compset -P '*/'
compadd "$@" '...'
}
</code></pre>
<p>The first line tells the completion system to ignore anything up to the
last `<code>/</code>'. That's so we can append a `<code>...</code>' to any directory which
already exists on the command line. The builtin <code>compset</code> does various
low-level transformations of this time. Note that the <code>-P</code> is `greedy'
--- it looks for the longest possible pattern match, which is the usual
default in zsh and other UNIX pattern matchers.</p>
<p>The second line actually adds the `<code>...</code>' as a completion; <code>compadd</code> is
the key builtin for the whole completion system. I've actually passed
some on the arguments which we got to `<code>_perforce_subdir_search</code>' via
`<code>"$@"</code>'. In fact, looking back it seems as if there weren't any!
However, <code>_alternative</code> actually passed some behind my back --- and it's
a good thing, too, since it's exactly those arguments that give the tag
`<code>subdirs</code>' and the description `<code>subdirectory search</code>'. So that extra
`<code>"$@"</code>' is actually quite important. The buck stops here; there's
nothing below <code>compadd</code>. A function of this simplest only works well
when the handling of tags and contexts has already been done; but we
just saw that <code>_alternative</code> did that, so as long as we always call
<code>_perforce_subdir_search</code> suitably, we're in the clear.</p>
<p><strong>Different types of file, part 2</strong></p>
<p>Furthermore, a Perforce file specification can look like a normal UNIX
file path, or it can look like:</p>
<pre><code> //depot/dirs/moredirs/file
</code></pre>
<p>(don't get confused with paths to network resources, which also use the
doubled slash or backslash on some systems, notably Cygwin). We could
use <code>_alternative</code> to handle this, too, and if I was writing <code>_perforce</code>
again I probably would for simplicity. However, I decided to do it just
by testing for the `<code>//</code>' in <code>_perforce_files</code>. This means that the
structure of <code>p4_files</code> so far looks like:</p>
<pre><code> if [[ $PREFIX = //* ]]; then
# ask Perforce for files that match
local -a altfiles
altfiles=(
'depot-files:file in depot:_perforce_depot_files'
depot-dirs:directory in depot:_perforce_depot_dirs'
<p>where we are still to write the functions for the first two alternatives
in the first branch; the `<code>...</code>' is still valid for that branch, so
I've added that as the third alternative. I've used the array
<code>$altfiles</code> because, actually, the structure is more complicated than
I've shown; doing it this way makes it easier to add different sets of
alternatives.</p>
<p>The choice of which branch is made by examining the <code>$PREFIX</code> special
variable, which contains everything (well, everything interesting) that
comes before the cursor position in the word being completed. There is a
counterpart <code>$SUFFIX</code> which we will see in a moment. The `almost
everything' comes because sometimes we definitely don't want to see the
whole <code>$PREFIX</code>. Completing the three dots was such as case --- we
didn't want to see anything up to the last <code>/</code>. What that `<code>compset -P '*/'</code>' actually did was move the matched pattern from the front of
<code>$PREFIX</code> to the end of <code>$IPREFIX</code>, another special parameter which
contains parts of the completion we aren't currently interested in, but
which are still there. This allows us to concentrate on a particular
part of the completion. However you do that --- whether by <code>compset</code> or
directly manipulating <code>$PREFIX</code> and friends --- the completion system
usually restores the parameters when you exit the function where you
altered them. This fits in nicely with what we're doing here with
<code>_alternative</code> --- if we handle adding `<code>...</code>' by ignoring everything
up to the last slash, for example, we don't want the next completion we
try to continue to ignore that; other file completions will want to look
at the directory path.</p>
<p>`Depot' is Perforce's name for what CVS calls a repository --- the
central location where all versions of all files are stored, and from
where they are retrieved when you ask to look at one. I've separated out
`<code>depot-dirs</code>' and `<code>depot-files</code>' for various reasons. First, the
commands to examine files and directories are different, so the
completion function is different. Second, we can offer different tags
for files and directories --- this is what <code>_path_files</code> does for normal
UNIX files. Third, it will later allow us more control --- some commands
only operate on directories. Here's <code>_perforce_depot_files</code>;
<code>_perforce_depot_dirs</code> is extremely similar:</p>
<p>A little messy (and still not quite the full horror). I've split the key
line in the middle which fetches the list from Perforce to make it fit.
If you ploughed through chapter 5, you'll recognised what's going on
here --- we're reading a list of files, one per line, from the command
`<code>p4 files</code>', and we're stripping off the directory at the front, and
everything from a `<code>#</code>' on at the end. The latter is a revision number;
we're not handling those at this point, though we will later.</p>
<p>Notice the way I remembered <code>$PREFIX</code> before I told the system to ignore
it for the word we're now completing. I remembered it as
`<code>${(Q)PREFIX}</code>' in order to remove any quotes from the name. For
example, if the name on the line so far had a space, <code>$PREFIX</code> (which
comes from what is on the command line without any quotes being
stripped) would have the space quoted somehow, e.g. `<code>name\ with\ space</code>'. We arrange for <code>$pfx</code> to contain `<code>name with space</code>', which is
how Perforce knows the file, using the <code>(Q)</code> parameter flag. We then
pass the argument <code>"$pfx*${(Q)SUFFIX}"</code> to `<code>p4 files</code>'; this generates
matching files internally. The extra layer of backslash-quoting is for
the benefit of <code>_call_program</code>, which re-evaluates its arguments; this
ensures the argument is expanded at the point it gets passed to <code>p4 files</code>. All this goes to show just how difficult getting the quoting
right can be.</p>
<p>Once we've got the list of bare filenames, we check to see if the list
is just one element with no length. That's an artefact of the the
<code>"$(cmd)"</code> syntax; if the output is empty, because its quoted you still
get one zero-length string output, which we don't want.</p>
<p>Finally, we pass the result to <code>compadd</code> as before. Again, tags and the
description have already been handled and we just need to make sure the
appropriate options get passed in with <code>"$@"</code>. This time we use the
`<code>-a</code>' option which tells <code>compadd</code> that any arguments are array name,
not a list of completions. This is more efficient; compadd only needs to
expand the array internally instead of the shell passing a potentially
huge list to the builtin.</p>
<p><strong>Handling extra bits on a completion</strong></p>
<p>`Extra bits' on a completion could be anything; common examples include
an extra value for a comma-separated list (the <code>_values</code> functions is
for this), or some kind of modifier applied to the completion you have
already. We've already seen an example, in fact, since the principle of
handling the directory and basename parts of a file is very similar. The
phrase `extra bits' may already alert you to the fact that we are
heading towards the deeper recesses of completion.</p>
<p>Anyway, here's how we tack a revision or change number onto the end of a
file.</p>
<p>I'll stick with revisions: `<em>filename</em><code>#</code><em>revision</em>', where <em>revision</em>
is a number. For the full sophistication, there are three steps to this.
First, make it easy for the user to add `<code>#</code>' to an existing filename;
second, recognise that a `<code>#</code>' is already there so that revisions need
to be completed; third, find out the actual revisions which can be
completed. As a revision is just a number, you might think completing it
was a bit pointless. However, given the sophistication of zsh's
completion system there's actually one very good reason --- we can
supply a description with the revisions, so that the user is given
information about the revisions and can pick the right one without
running some external command to find out. There was the same sort of
rationale behind the `<code>-d</code>' option to <code>p4 diff</code>; there was just one
letter to type, but zsh was able to generate extra information to
describe the possibilities, so it wasn't just laziness.</p>
<p>First part: make it easy for the user to add the `<code>#</code>'. This actually
depends on a new feature in version 4.1 of zsh; in 4.0 you couldn't play
the trick we need or grabbing the keyboard input after a completion was
finished unless you specified a particular suffix to add to the
completion (such as the `<code>/</code>' after a directory --- this is
historically where this feature came from).</p>
<p>The method is to add an extra argument everywhere we complete a file
name. For example, change the <code>compadd</code> in <code>_perforce_depot_files</code> to:</p>
<pre><code> compadd "$@" -R _perforce_file_suffix -a files
</code></pre>
<p>where the option argument specifies a function:</p>
<pre><code> _perforce_file_suffix() {
[[ $1 = 1 ]] || return
if [[ $LBUFFER[-1] = ' ' ]]; then
if [[ $KEYS = '#' ]]; then
# Suffix removal with an added backslash
LBUFFER="$LBUFFER[1,-2]\\"
elif [[ $KEYS = (*[^[:print:]]*|[[:blank:]\;\&\|@]) ]]; then
# Normal suffix removal
LBUFFER="$LBUFFER[1,-2]"
fi
fi
}
</code></pre>
<p>This has been simplified, too; I've ignored revision ranges in the form
<em>file</em><code>#</code><em>rev1</em><code>,</code><em>rev2</em>. However, I've handled changes (`<code>@</code>'
following a filename) as well as revisions. You'll see this function
looks much more like a zle widget rather than a completion widget ---
which is exactly what it is; it's not called as part of the completion
system at all. After the specified completion, zle reads in the next
keystroke, which is stored in <code>$KEYS</code>, and calls this function as a zle
widget. This means it can manipulate the line buffer; we only need to
look at what is at the left of the cursor, stored in <code>$LBUFFER</code>.</p>
<p>The function is called with the length of the suffix added to the
function. In this case, it's just a space --- we've finished a normal
completion, so the system has automatically added a space to what's on
the command line. We therefore check we've just got one single character
in the suffix, to avoid getting confused.</p>
<p>Next, we look at what's immediately left of the cursor, which is the
last character in <code>$LBUFFER</code>, i.e. <code>$LBUFFER[-1]</code>, to make sure this is
a space.</p>
<p>If everything looks OK, we consider the keys typed and decide whether to
modify the line. You may already have noticed that in some cases zsh
automatically removes that space by itself; for example, if you hit
return --- or any other non-printing character --- or if it's a
character that terminates a command such as `<code>&</code>' or `<code>;</code>'. We emulate
that behaviour --- most of the second test is simply to do that. The
only differences from normal are if the key typed was `<code>@</code>' or `<code>#</code>'.</p>
<p>The `<code>@</code>' is simple --- we just remove the last character, the same as
we do for the other characters. For `<code>#</code>', however, we also add a
backslash to the command line before the `<code>#</code>'. That's because `<code>#</code>'
is a special character with extended globbing, and the completion system
generally runs with extended globbing switched on. Adding the backslash
means the user doesn't have to; it's never harmful.</p>
<p>To show the next effect, suppose we complete a file name:</p>
<pre><code> p4 diff fil<TAB>
</code></pre>
<p>to get:</p>
<pre><code> p4 diff filename _
</code></pre>
<p>where `<code>_</code>' shows the cursor position, and then typed `<code>#</code>'; we would
get:</p>
<pre><code> p4 diff filename\#
</code></pre>
<p>with the cursor right at the end.</p>
<p>So far so good. For the second step, we need to modify <code>_perforce_files</code>
to spot that there is a `<code>#</code>' on the line before the cursor, and to
call the revision code. To do this we add an extra branch at the start
of the `<code>if</code>' in <code>_perforce_files</code> --- at the start, because any `<code>#</code>'
before the cursor forces us to look at revisions, so this takes
precedence over the other choices. When this is added, the code will
look like:</p>
<pre><code> if [[ -prefix *\# ]]; then
_perforce_revisions
elif [[ $PREFIX = //* ]]; then
# as before.
</code></pre>
<p>In fact, that <code>-prefix</code> test is just a fancy way of saying the same
thing as the `<code>[[ $PREFIX = *\# ]]</code>' and if I wasn't so hopelessly
inconsistent I would have written both tests the same.</p>
<p>So now the third step: write <code>_perforce_revisions</code> to complete revisions
<p>Thankfully, a lot of the structure of this is already familiar. We
extract the existing prefix before the `<code>#</code>', being careful about
quoting --- this is the filename for which we want a list of revisions.
We ignore everything in the command argument before the `<code>#</code>'. After
generating the completions, we use the <code>_describe</code> function to add them
with the tag `<code>revisions</code>' and the description `<code>revision</code>'.</p>
<p>The main new part is the loop over output from `<code>p4 filelog</code>', which is
the Perforce command that tells us about the revisions of a file. We
extract the revision number and the comment from the line using
backreferences (see previous chapter) and weld them together with a
colon so that <code>_describe</code> will be able to separate the completion from
its description. Then we add a few special non-numerical revisions which
Perforce allows, and pass this list down to <code>_describe</code>. The extra
<code>if</code>'s are a very minor optimization to check if we are completing a
numerical or non-numerical revision.</p>
<p><spanid="l181"></span></p>
<h3id="684-the-rest"><aclass="header"href="#684-the-rest">6.8.4: The rest</a></h3>
<p>It's obvious that this tutorial could expand in any number of
directions, but as it's really just to point out some possibilities and
directions, that would would miss the point. So the rest of this chapter
takes the completion system apart and looks at the individual
components. It should at least now be a bit more obvious where each
component fits.</p>
<p><spanid="l182"></span></p>
<h2id="69-writing-new-completion-functions-and-widgets"><aclass="header"href="#69-writing-new-completion-functions-and-widgets">6.9: Writing new completion functions and widgets</a></h2>
<p>Now down to the nitty gritty. When I first talked about new completion,
I explained that the functions beginning `<code>_</code>' were the core of the
system. For the remainder of the chapter, I'll explain what goes in them
in more detail than I did in the tutorial. However, I'll try to do it in
such a way that you don't need to know every single detail. The trade
off is that if you just use the simplest way of writing functions, many
of the mechanisms I told you about above, particularly those involving
styles and tags, won't work. For example, much of the code that helps
with smart formatting of completion listings is buried in the function
`<code>_description</code>'; if you don't know how to call that --- which is often
done indirectly --- then your own completions won't appear in the same
format as the pre-defined ones.</p>
<p>The easiest way of getting round that is to take a dual approach: read
the following as far as you need, but also try to find the existing
completion that comes nearest to meeting your needs, then copy that and
change it. For example, here's a function that completes files ending in
<code>.gz</code> (the supplied function which does this has now changed), which are
files compressed by the <code>gzip</code> program, for use by the corresponding
program that does decompression, <code>gunzip</code> --- hence the file and
function are called <code>_gunzip</code>:</p>
<pre><code> #compdef gunzip zcat
local expl
_description files expl 'compressed file'
_files "$expl[@]" -g '*.[gG][zZ]'
</code></pre>
<p>You can probably see straight away that if you want to design your own
completion function for a command which takes, say, files ending in
<code>.exe</code>, you need to change three things: the line at the top, which
gives the names of programmes whose arguments are to be completed here,
the description `<code>compressed file</code>' to some appropriate string, and the
argument following the <code>-g</code> to something like <code>'*.exe'</code> --- any globbing
pattern should work, just remember to quote it, since it shouldn't be
expanded until the inside of the function <code>_files</code>. Once you've
installed that somewhere in your <code>$fpath</code> and restarted the shell,
everything should work, probably following a longer pause than usual as
the completion system has to rescan every completion function when it
finds there is a new one.</p>
<p>What you might miss is that the first argument to <code>_description</code>,
`<code>files</code>', is the all-important mystical tag for the type of
completion. In this case, you would probably want to keep it. Indeed,
the <code>_files</code> function is used for all file completions of any type, and
knows all about the other tags --- <code>globbed-files</code>, <code>directories</code>,
<code>all-files</code> --- so virtually all your work's done for you here.</p>
<p>If you're adding your own functions, you will need your own functions
directory. This was described earlier in this guide, but just to remind
you: all you need to do is create a directory and add it to <code>$fpath</code> in
either <code>.zshenv</code> (which a lot of people use) or <code>.zshrc</code> (which some
sticklers insist on, since it doesn't affect non-interactive shells):</p>
<pre><code> fpath=(~/funcs $fpath)
</code></pre>
<p>It's best to put it before the standard completion directories, since
then you can override a standard completion function simply by copying
it into your own directory; that copy will then be found first and used.
This is a perfectly reasonable thing to do with any completion function
--- although if you find you need to tweak one of the larger standard
functions, that's probably better done with styles, and you should
<p>The first thing to understand is that top line of <code>_gunzip</code>. The
`<code>#compdef</code>' tag is what tells the system when it checks through all
files beginning with `<code>_</code>' that this is a function implementing a
completion. Files which don't directly implement completions, but are
needed by the system, instead have the single word `<code>#autoload</code>' at
that point. All files are only loaded when needed, using the usual
autoloading system, to keep memory usage down.</p>
<p>You can supply various options to the `<code>#compdef</code>' tag; these are
listed in the `<code>Initialization</code>' section of the <code>zshcompsys(1)</code> manual
page or `<strong>Completion System</strong>' info node. The most useful are <code>-k</code> and
<code>-K</code>, which allow you to define a completion command and binding rather
than a function used in a particular context. There are also <code>-p</code> and
<code>-P</code> which tell the system that what follows is a pattern rather than a
literal command name; any command matching the pattern will use that
completion function, unless you used <code>-P</code> and a normal (non-pattern)
completion function for the name was found first.</p>
<p>For normal <code>#compdef</code> entries, however, what comes next is a list of
command names --- or rather a list of contexts, since the form
`<code>-context-</code>' can be used here. For example, the function <code>_default</code>
has the line `<code>#compdef -default-</code>'. You can give as many words as you
like and that completion will be used for each. Note that contexts in
the colon-separated form can't appear here, just command names or the
special contexts named with hyphens.</p>
<p>The system does its work by using a function <code>compdef</code>; it gets as
arguments more or less what you see, except that the function name is
passed as the first argument. Thus the <code>_gunzip</code> completion is loaded by
`<code>compdef _gunzip gunzip zcat</code>', <code>_default</code> by `<code>compdef _default -default-</code>', and so on. This simply records the name of the function
handling the context in the <code>$_comps</code> associative array which you've
already met. You can make extra commands/contexts be handled by an
existing completion function in this way, too; this is generally more
convenient than copying and modifying the function. Just add `<code>compdef <_function><command-to-handle></code>' to <code>.zshrc</code> after the call to
<code>compinit</code>.</p>
<p>It's also high time I mentioned an easy way of using the completion
already defined for an existing function: `<code>compdef newcmd=oldcmd</code>'
tells the completion system that the completion arguments for
`<code>newcmd</code>' are to be the same as the ones already defined for
`<code>oldcmd</code>'; it will complain if nothing is known about completing for
<code>oldcmd</code>. This works recursively; you can now define completions in
terms of that for <code>newcmd</code>. If you happen to know the name of the
completion function called, you can use that; the following three lines
are broadly equivalent:</p>
<pre><code> compdef $_comps[typeset] foo
compdef _vars_eq foo
compdef foo=typeset
</code></pre>
<p>since the completion for <code>typeset</code> is stored in <code>$_comps</code> along with all
the others, and this happens to resolve to <code>_vars_eq</code>; but the last
example is easier and safer and the intention more obvious. The manual
refers to <code>typeset</code> here as a `service' for <code>foo</code> (guess what the shell
stores in the associative array element <code>$_services[foo]</code>).</p>
<p>There's actually more to services: when a function is called, the
parameter <code>$service</code> is set. Usually this will just be the name of the
command being completed for, or one of the special contexts like
`<code>-math-</code>'. However, in a case like the last <code>compdef</code> in the list
above, the service will be <code>typeset</code> even though the command name may be
`<code>foo</code>'.</p>
<p>This is also used in `<code>#compdef</code>' lines. The top of `<code>_gzip</code>'
contains:</p>
<pre><code> #compdef gzip gunzip gzcat=gunzip
</code></pre>
<p>which says that the file provides two services, for <code>gzip</code> and <code>gunzip</code>,
and also handles completion for <code>gzcat</code>, but with the service name
<code>gunzip</code>. Only a few of the completion functions actually care what
service they provide (you can check, obviously, by looking to see if
they refer to <code>$service</code>); but you may have uses for this. Note that if
you define services with a <code>compdef</code> command, <em>all</em> the arguments must
be in the <em>foo</em><code>=</code><em>bar</em> form; the mixed form is only useful after a
<h3id="692-adding-a-set-of-completions-compadd"><aclass="header"href="#692-adding-a-set-of-completions-compadd">6.9.2: Adding a set of completions: <code>compadd</code></a></h3>
<p>Once you know how to make a new completion function, there is only one
other basic command you need to know before you can create your own
completions yourself. This is the builtin <code>compadd</code>. It is at the heart
of the completions system; all its arguments, after the options, are
taken as possible completions. This is the list from which the system
selects the possibilities that match what you have already typed. Here's
a very basic example which you can type or paste at the command line:</p>
<pre><code> _foo() { compadd Yan Tan Tethera; }
compdef _foo foo
</code></pre>
<p>Now type `<code>foo </code>' and experiment with completions after it. If only
it were all that simple.</p>
<p>There are a whole list of options to <code>compadd</code>, and you will have to
look in the <code>zshcompwid(1)</code> manual page or the `<strong>Completion Widgets</strong>'
info node for all of them. I've already mentioned <code>-M</code> and (long ago)
<code>-f</code>. Here are other interesting ones. <code>-X <description></code> provides a
description --- this is used by the <code>format</code> style to pass descriptions,
and if you use the normal tags system you shouldn't pass it directly;
I'll explain this later.</p>
<p><code>-P <prefix></code> and <code>-S <suffix></code> allow you to specify bits which are not
treated as part of the completion, but appear on the line none the less.
In fact, they do two different things: if the prefix or suffix is
already there, it is ignored, and if it isn't, it is inserted. There are
also corresponding hidden and ignored prefixes, necessary for the full
power of the completion system, but you will need to read the manual for
the full story. The <code>-q</code> option is useful with <code>-S</code>; it enables
auto-remove behaviour for the suffix you gave, just like <code>/</code> with the
<code>AUTO_REMOVE_SLASH</code> option when completing filenames.</p>
<p><code>-J <group></code> is the way group names are specified, used by the
<code>group-name</code> tag; there is also <code>-V <group></code>, but the group here is not
sorted (and is distinct from any group of the same name passed to <code>-J</code>).
<code>-Q</code> tells the completion code not to quote the words --- this is useful
where you need to have unquoted metacharacters in the final completion.
It is also useful when you are completion something where the result
isn't going to be expanded by the shell.</p>
<p><code>-U</code> tells <code>compadd</code> to use the list of completions even if they don't
match what's on the command line; you will need this if your completion
function modifies the prefix or suffix so that they no longer fit what's
already there. If you use this, you might consider turning on menu
completion (using <code>compstate[insert]=menu</code>), since it might otherwise be
difficult to select the appropriate completion.</p>
<p>Finally, note the <code>-F</code> and <code>-W</code> options which I describe below for
<code>_files</code> actually are options to <code>compadd</code> too.</p>
<p><spanid="l185"></span></p>
<h3id="693-functions-for-generating-filenames-etc"><aclass="header"href="#693-functions-for-generating-filenames-etc">6.9.3: Functions for generating filenames, etc.</a></h3>
<p>However, for most types of completion the possibilities will not be a
simple list of things you already know, so that you need to have some
way of generating the required values. In this section, I will describe
some of the existing functions you can call to do the hard work. In the
next section I will show how to retrieve information from some special
parameters made available by the <code>zsh/parameter</code> module.</p>
<p><strong>Files etc.: the function <code>_files</code></strong></p>
<p>You have already seen <code>_files</code> in action. Calling this with no arguments
simply adds all possible files as completions, taking account of the
word on the command line to establish directories and so on.</p>
<p>For more specific use, you can give it various options: `<code>-/</code>' means
complete directories, and, as you saw, `<code>-g "<pattern>"</code>' gives a
filename generation pattern to produce matching files.</p>
<p>A couple of other options, which can be combined with the ones above,
are worthy of mention. If you use `<code>-W <dir></code>', then completion takes
place under directory <code><dir</code>> rather than in the current directory ---
it has no effect if you are using an absolute path. Here, `<code><dir></code>' can
also be a set of directories separated by spaces or, most usefully since
it avoids any problems with quoting, the name of an array variable which
contains the list of possible directories. This is essentially how
completion for <code>cd</code> with the <code>$cdpath</code> array works. So if you have a
program that looks for files with the suffix `<code>.mph</code>', first in the
current directory, then in a standard directory, say,
<code>/usr/local/oomph</code>', you can do this:</p>
<pre><code> local oomph_dirs
oomph_dirs=(. /usr/local/oomph)
_files -W oomph_dirs -g '*.mph'
</code></pre>
<p>--- note there is no `<code>$</code>' before the variable <code>$oomph_dirs</code> here,
since it should only be expanded deep inside <code>_files</code>.</p>
<p>The system that implements <code>$fignore</code> and the <code>ignored-patterns</code> style
can be intercepted, if you need to, with the option `<code>-F "<pat>"</code>';
`<code><pat></code>' is an array of patterns to ignore, in the usual completion
format, in other words the name of a real shell array, or a list of
values inside parentheses. If you make sure all the tags stuff is
handled properly, <code>ignored-patterns</code> will work automatically, however,
and in addition extended globbing allows you to specify patterns with
exclusion directly, so you probably won't use this feature directly
unless you're in one of your superhero moods.</p>
<p>In addition, <code>_files</code> also takes many of the standard completion options
which apply to <code>compadd</code>, for convenience.</p>
<p>Actually, the function <code>_path_files</code> is the real engine room of the
system. The advantage of using <code>_files</code> is that it prepares all the tags
for you, deciding whether you want directories to be completed as well
as the globbed files, and so on. If you have particularly specific needs
you can use <code>_path_files</code> directly, but you won't get the automatic
fallback one <code>directories</code> and <code>all-files</code>. Because it doesn't handle
the tags, <code>_path_files</code> is too lowly to do the usual tricks with label
loops, i.e. pretending `<code>dog:-setter</code>' is a tag `<code>dog-setter</code>' with
the usual completions for `<code>dog</code>'; likewise, it doesn't implement the
<code>file-patterns</code> style. So you need to know what you're doing when you
use it directly.</p>
<p><strong>Parameters and options</strong></p>
<p>These can be completed by calls to the <code>_parameters</code> and <code>_options</code>
functions, respectively. Both set up their own tags, and <code>_options</code> uses
the matching control mechanism described above to allow options to be
given in all the available forms. As with <code>_files</code>, they will also pass
standard <code>compadd</code> options down to that function. Furthermore, they are
all at a high enough level to handle tags with labels: to translate that
into English, you can use them directly without any of the preprocessing
described later on which are necessary to make sure the styles dealing
with tags are respected.</p>
<p>For more detailed control with options, the functions <code>_set_options</code> and
<code>_unset_options</code> behave like <code>_options</code>, but the possible completions
are limited to options which are set or unset, respectively. However,
it's not that simple: the completion system itself alters the options,
and you need to enable some code near the top of <code>_main_complete</code> (it's
clearly marked) to remember the options which were set or unset when
completion started. A straw poll based on a sample of two zsh developers
revealed that in any case many people don't like the completion system
to second guess the options they want to set or unset in this way, so
it's probably better just to stick to <code>_options</code>.</p>
<p><strong>Miscellaneous</strong></p>
<p>There are also many other completion functions adding matches of a
certain type. These can be used in the same way as <code>_parameters</code> and
<code>_options</code>; in other words they do all the work needed for tags
themselves and can be given options for <code>compadd</code> as arguments.
Normally, these functions are named directly after the type of matches
they generate, like <code>_users</code>, <code>_groups</code>, <code>_hosts</code>, <code>_pids</code>, <code>_jobs</code>,
etc.</p>
<p><spanid="l186"></span></p>
<h3id="694-the-zshparameter-module"><aclass="header"href="#694-the-zshparameter-module">6.9.4: The <code>zsh/parameter</code> module</a></h3>
<p>The new completion system automatically makes the <code>zsh/parameter</code> module
available for use. This provides an easy way of generating arguments for
<code>compadd</code>. To get the maximum use out of this, you should be familiar
with zsh's rather self-willed syntax for extracting bits out of
associative arrays. Note in particular <code>${(k)assoc}</code>, which expands to a
list of the keys of the associative array <code>$assoc</code>, <code>${(v)assoc}</code>, which
expands to just its values (actually, so does <code>$assoc</code> on its own), and
<code>${(kv)assoc}</code> which produces key/value pairs. For all intents and
purposes, the keys and values, or the pairs of them, are in a random
order, but as the completion system does it's own sorting that shouldn't
be a problem. Mostly, the important parts for completion are in the
keys, i.e. to add all aliases as possible completions, you need
`<code>compadd ${(k)aliases}</code>'.</p>
<p>Here's a list of associative and ordinary arrays provided; for more
information on the values of the associative arrays, which could be
useful in some cases, consult the section <strong>The zsh/parameter Module</strong>
in the <code>zshmodules(1)</code> manual page or the corresponding info node.
<p>which you can test does the right thing. Here's a translation:
<code>"$(limit)"</code> calls the command in a quoted context, which means you get
the output as if it were a single file (just type `<code>limit</code>' to see what
that is). <code>${(f)...}</code> splits this into an array (it is now outside
quotes, so splitting will generate an array) with one element per line.
Finally, <code>${...%% *}</code> removes the trailing end of each array element
from the first piece of whitespace on, so that `<code>cputime unlimited</code>' is
reduced to `<code>cputime</code>', and so on. Type `<code>limit ^D</code>', and you will see
the practical upshot of this.</p>
<p>That's by no means the most complicated example. The nested expansion
facility is used throughout the completion functions, which adds to
brevity but subtracts considerably from readability. It will repay
further study, however.</p>
<p><spanid="l187"></span></p>
<h3id="695-special-completion-parameters-and-compset"><aclass="header"href="#695-special-completion-parameters-and-compset">6.9.5: Special completion parameters and <code>compset</code></a></h3>
<p>Up to now, I've assumed that at the start of your completion function
you already know what to complete. In more complicated cases that won't
be the case: different things may need completing in different arguments
of a command, or even some part of a word may need to be handled
differently from another part, or you need to look for a word following
a particular option. I will first describe some of the lower level
facilities which allow you to manipulate this; see the manual page
<code>zshcompwid(1)</code> or the info node <strong>Completion Widgets</strong> for the details
of these. Later, I will show how you can actually skip a lot of this for
ordinary commands with options and arguments by using such functions as
<code>_arguments</code>, where you simply specify what arguments and options the
function takes and what sort of completion they need.</p>
<p>The heart of this is the special parameters made available in completion
for testing what has already been typed. It doesn't matter if there are
parameters of that name outside the completion system; they will be
safely hidden, the special values used, and the original values restored
when completion is over.</p>
<p><code>$words</code> is an array corresponding to the words on the command line ---
where by a `word' I mean as always a single argument to the command,
which may include quoted whitespace. <code>$CURRENT</code> is the index into that
array of the current word. Note that to avoid confusion the ksh-like
array behaviour is explicitly turned off in <code>_main_complete</code>, so the
command itself is <code>$words[1]</code>, and so on.</p>
<p>The word being completed is treated specially. The reason is that you
may only want to complete some of it. An obvious example is a file with
a path: if you are completing at `<code>foo/bar</code>', you don't want to have to
check the entire file system; you want the directory <code>foo</code> to be fixed,
and completion just for files in that. There are actually two parts to
this. First, when completion is entered, <code>$PREFIX</code> and <code>$SUFFIX</code> give
you the part of the current word before the cursor, and the remainder,
respectively. It's done like this to make it possible to write functions
for completing inside a word, not just at the end. The simplest possible
way of completing a file is then to find everything that matches
<code>$PREFIX*$SUFFIX</code>.</p>
<p>But there's more to it than that: you need to separate off the
directory, hence the second part. The parameters <code>$IPREFIX</code> and
<code>$ISUFFIX</code> contain a part of the string which will be ignored for
completion. It's up to you to decide what that is, then to move the bit
you want to be ignored from <code>$PREFIX</code> to <code>$IPREFIX</code> (that's the usual
case) or from <code>$SUFFIX</code> to <code>$ISUFFIX</code>, making sure that the word so far
typed is still given by <code>$IPREFIX$PREFIX$SUFFIX$ISUFFIX</code>. Thus in
completing <code>foo/bar</code>, you would strip <code>foo/</code> from the start of <code>$PREFIX</code>
and tack it onto the end of <code>$IPREFIX</code> --- after recording the fact that
you need to move to directory <code>foo</code>, of course. Then you generate files
in <code>foo</code>, and the completion system will happily accept <code>barrack</code> or
<code>barbarous</code> as completions because it doesn't care about the <code>foo</code> any
more.</p>
<p>Actually, this is already done by the the <code>_files</code> and <code>_path_files</code>
functions for filename completion. Also, you can get some help using the
<code>compset</code> builtin command. In this case, the incantation is</p>
<pre><code> if compset -P "*/"; then
# do whatever you need to with the leading
# string up to / stripped off
else
# no prefix stripped, do whatever's necessary in this case
fi
</code></pre>
<p>In other words, any initial match of the pattern `<code>*/</code>' in <code>$PREFIX</code> is
removed and transferred to the end of <code>$IPREFIX</code>; the command status
tells you whether this was done. Note that it is the longest possible
such match, so if there were multiple slashes, all will be moved into
<code>$IPREFIX</code>. You can control this by putting a number <code><N></code> between the
<code>-P</code> and the pattern, which says to move only up to the <code><N></code>th such
match; here, that would be a pattern with exactly <code><N></code> slashes. Note
that <code>-P</code> stands for prefix, not pattern; there is a corresponding <code>-S</code>
option for the suffix. See the manual for other uses of <code>compset</code>; these
are probably the most frequent.</p>
<p>If you want to make the test made by <code>compset</code>, but without the side
effect of changing the prefixes and suffixes, there are tests like this:</p>
<pre><code> if [[ -prefix */ ]]; then
# same as with `compset -P "*/"', except prefixes were left alone.
fi
</code></pre>
<p>These have the advantage of looking like all the standard tests
understood by the shell.</p>
<p>There are three other parameters special to completion. The <code>$QIPREFIX</code>
and <code>$QISUFFIX</code> are a special prefix and suffix used when you are
dividing up a quoted word --- for example, in `<code>zsh -c "echo hi"</code>', the
word <code>"echo hi"</code> is going to be used as a command line in its own right,
so if you want to do completion there, you need to have it split up. You
can use `<code>compset -q</code>' to split a word in this fashion.</p>
<p>There is also an associative array <code>$compstate</code>, which allows you to
inspect and change the state of many internal aspects of completion,
such as use of menus, context, number of matches, and so on. Again,
consult the manual for more detail. Many of the standard styles work by
altering elements of <code>$compstate</code>.</p>
<p>Finally, in addition to the parameters special to completion, you can
examine (but not alter) any of the parameters which appear in all
editing widgets: <code>$BUFFER</code>, the contents of the current editing line;
<code>$LBUFFER</code>, the part of that before the cursor; <code>$RBUFFER</code>, the rest;
<code>$CURSOR</code>, the index of the cursor into <code>$BUFFER</code> (with the first
character at zero, in this case --- or you can think of the zero as
being the point before the first character, which is where insertion
would take place with the cursor on the first character); <code>$WIDGET</code> and
<code>$LASTWIDGET</code>, the names of the current and last editing or completion
widget; <code>$KEYS</code>, the keys typed to invoke the current widget;
<code>$NUMERIC</code>, any numeric prefix given, unset if there is none, and a few
other probably less useful values. These are described in the
<code>zshzle(1)</code> manual page and the <strong>Zsh Line Editor</strong> info node. In
particular, I already mentioned <code>$NUMERIC</code> as of possible use in various
styles, and it is used by the completers which understand a `<code>numeric</code>'
value in their relevant styles; the <code>$WIDGET</code> and <code>$KEYS</code> parameters are
useful for deciding between different behaviours based on what the
widget is called (as in <code>_history_complete_word</code>), or which keys are
used to invoke it (as in <code>_bash_completions</code>).</p>
<p>Here are a few examples of using special parameters and <code>compset</code>.</p>
<p>One of the shortest standard completions is this, <code>_precommand</code>:</p>
<p>Instead of doing it with mirrors, this uses globbing qualifiers to
extract the required file; <code>om</code> specifies ordering by modification time,
and the expression in square brackets selects the single match we're
after. The <code>N</code> turns on <code>NULL_GLOB</code>, so <code>$file</code> is empty if there are no
matches, and the parameter expansions with `<code>$~</code>' force patterns in
<code>$PREFIX</code> and <code>$SUFFIX</code> to be available for expansion (a little extra
feature I use, although ordinary completion would work without).</p>
<p>Most of the <code>compadd</code> command is bookkeeping to make sure the parts of
the prefix and suffix we've already removed, if there are any, get
passed on, but the reason for that deserves a mention, since normally
this is handled automatically. The difference here is that <code>-U</code> usually
replaces absolutely everything that was in the word before, so if you
need to keep it you have to pass it back to <code>compadd</code>. For example,
suppose you were in a context where you were completing after
`<code>file=...</code> and you had told the completion system that everything up
to `<code>file=</code>' was not to count and not to be shown as part of the
completion. You would want to keep that when the word was put back on
the command line. However, `<code>-U</code>' would delete that too. Hence the
`<code>-i "$IPREFIX"</code>' to make sure it's retained. The same argument goes
for the ignored suffix. However, there's currently no way of getting
<code>_most_recent_file</code> to work on only a part of a string, so this
explanation really only applies when you call it from another completion
function, not directly from the command line.</p>
<p><spanid="l188"></span></p>
<h3id="696-fancier-completion-using-the-tags-and-styles-mechanism"><aclass="header"href="#696-fancier-completion-using-the-tags-and-styles-mechanism">6.9.6: Fancier completion: using the tags and styles mechanism</a></h3>
<p>At this point, you should be in a position to construct, although maybe
not in the best possible way, pretty much any completion list you want.
Now I need to explain how you make sure it all fits in with the usual
tags and styles system. You will need to pick appropriate tags for your
completions. Although there is no real restriction, it's probably best
to pick one of the standard tags, some of which are suitably general to
cover just about anything: <code>files</code>, <code>options</code>, <code>values</code>, etc. There is a
list in the completion system manual entry. Remember that the main use
for tags is to choose what happens when more than one tag can be
completed in the same place. Finding such things that can't be separated
using the standard tag names is a good reason for inventing some new
ones; you don't have to do anything special if the tag names are new,
just make sure they're documented for anyone using the completion
function.</p>
<p><strong>How to call functions so that `It Just Works'</strong></p>
<p>The simplest way of making your own completion function recognize tags
is to use the <code>_description</code> function, which is usually called with
three arguments: the name of the tag you're completing for, the name of
a variable which will become an array containing arguments to pass to
<code>compadd</code>, and the full description. Then you have to make sure that
array gets passed down to <code>compadd</code>, or to any of the higher-level
completion functions which will pass the arguments on to <code>compadd</code>. For
example,</p>
<pre><code> local expl
_description files expl 'my special files'
_files "$expl[@]"
</code></pre>
<p>This sets the files tag; <code>_description</code> sets <code>$expl</code> to pass on the
description, and maybe other things such as a group name for the tag, in
the appropriate format; we pass this down to <code>_files</code> which will use it
for calling <code>compadd</code>. Generally, you will call <code>_description</code> for each
time you call <code>compadd</code> or something that in turn calls <code>compadd</code>.</p>
<p>The <code>_description</code> function calls another function <code>_setup</code> to do much
of the setting up of styles for the particular tag. Mostly, <code>_setup</code> is
buried deeply enough that you don't need to worry about it yourself.
Sometimes you can't do completion, and just want to print a message
unconditionally to say so, irrespective of tags etc.; the function
<code>_message</code> does this, taking the message as its sole argument.</p>
<p>There are two levels above that; these implement the tags mechanism in
full. In <code>_description</code>, all that happens is that the user is informed
what tag is coming up; there's no check what preferences the user has
for tags (the first level), nor whether he wants tags to be split up
using the labelling mechanism, e.g. picking out certain sorts of files
using the labelled tag `<code>file:-myfiles</code>' to get the final tag
`<code>file-myfiles</code>' (the second level).</p>
<p>To get this for simple cases you use the function <code>_wanted</code>. Unlike
<code>_description</code>, it's an interface to the function that generates
completion as well as a handler for tags --- that's so it can loop over
the generated tags, checking the labels. The call above would now look
like this:</p>
<pre><code> _wanted files expl 'my special files' _files
</code></pre>
<p>Note that you now don't pass the <code>"$expl[@]"</code>, which hasn't even been
set yet; <code>_wanted</code> will generate the string using the parameter name you
say (here `<code>expl</code>', as usual), and assume that the function generating
the completions can use the result passed down to it. This is true of
pretty much anything you are likely to want to use.</p>
<p>Note also the fact you need to pass `<code>_files</code>', i.e. the function
generating the completion. You can put pretty much any command line
which generates completions here, down to a simple `<code>compadd</code>'
expression. The reason it has to be here is the tag labelling business:
<code>_wanted</code> could check whether the tag you specify, `<code>files</code>', is wanted
by the user and then return control to you, but it wouldn't be able to
split up and loop over labelled tags set in this case for the
<code>file-patterns</code> style and in other case by the <code>tag-order</code> style.</p>
<p>Unless you're really going into the bowels, <code>_wanted</code> is probably the
lowest level you will want to use. I'd suggest you remember that one,
and only go back and look at the other stuff if you need to do something
more complicated.</p>
<p>If your function handles multiple tags, you need to loop over the
different tags to find out which sort the tag order wants next. For
this, you first need to tell the system which tags are coming up, using
the <code>_tags</code> function with a list. Then you need to to test whether each
tag in turn actually needs to be completed, and go on doing this until
you run out of tags which need completions performing; the <code>_tags</code>
function without arguments does this. Finally, you need to use
<code>_requested</code>, which works a bit like <code>_wanted</code> but is made to fit inside
the loop we are using. The end result looks like this:</p>
<pre><code> local expl ret=1
_tags foo bar rod
while _tags; do
_requested foo expl "This is the description for tag foo" \
compadd all foos completions && ret=0
_requested bar expl "This is the description for tag bar" \
compadd all bars completions && ret=0
_requested rod expl "This is the description for tag rod" \
compadd all rods completions && ret=0
(( ret )) || return 0 # leave if matches were generated
done
</code></pre>
<p>If you do include the completion function line as arguments, the loop
over labels for the tag you specify is automatically handled as with
<code>_wanted</code>. It may be a little confusing that both <code>_requested</code> and
<code>_wanted</code> exist: the specific difference is that with <code>_requested</code> you
call the <code>_tags</code> function yourself, whereas <code>_wanted</code> assumes the only
valid tag is its argument and acts accordingly, and can be used only for
simple, `one-shot' completions.</p>
<p>With <code>_requested</code>, unlike <code>_wanted</code>, you can separate out the arguments
to the completion generator itself --- here <code>compadd</code> --- into a
different statement, remembering the <code>"$expl[@]"</code> argument in that case.
You can miss out the second and third arguments for <code>_requested</code> in this
way. This time the loop which generates labels for tags is not
performed, and you have to arrange it yourself, with the usual trade off
of greater complexity for greater flexibility. To do this, there are two
other functions: <code>_all_labels</code> and <code>_next_label</code>. The simpler case is
with <code>_all_labels</code>, which just implements the loop over the labels using
the same arguments as <code>_wanted</code>:</p>
<pre><code> _requested values &&
_all_labels values expl 'values for my special things' \
compadd alpha bravo charlie delta echo foxtrot.
</code></pre>
<p>In case you haven't understood (and it's quite complicated, I'm afraid):
the <code>_requested</code> looks at whether the tag you use has been asked for by
the user. Having found out that it is, the <code>_all_labels</code> function calls
the command <code>compadd</code> which actually adds the completions, but it does
it in such a way as to take account of labelled tags --- you might have
both a plain `<code>values</code>' tag and `<code>values:-special</code>' labelled tag, and
<code>_all_labels</code> is needed to decide which is being used here. This last
example is actually exactly what <code>_requested</code> does when given the
<code>compadd</code> as argument, so it's only really useful when there is some
code between the <code>_requested</code> and the <code>_all_labels</code>, for example to
compute the strings to complete.</p>
<p>The most complicated case you are likely to come across is when inside
the part of the tags loop which handles a particular tag (i.e. the
<code>_requested</code> lines in the example above), you actually want to add more
than one possible sort of completion. Then <code>_all_labels</code> is no longer
enough, because completion needs to sort out the different things which
are being added. This can also happen when there is only one valid tag,
but that has multiple completions so that <code>_wanted</code> isn't any use. In
this case you need to use <code>_next_label</code> inside a loop, which, as its
names suggests, fixes up labels for the current tag and stops when it's
found the right one. Here's a stripped down example which handles
completion of messages from the <code>MH</code> mail handling system; you'll find
it complete inside the function <code>_mh</code>.</p>
<p>which tries <code>sequences</code> under the labels <code>sequences-name</code> and
<code>sequences-num</code>; which ignore completions which are all digits, and
those which are not all digits, respectively. The slight twiddle in the
pattern for <code>sequences-name</code> ignores messages marked for deletion as
well, which have a comma stuck in front of the number (this is
configurable, so your version of MH may be different).</p>
<p>All of <code>_description</code>, <code>_wanted</code>, <code>_requested</code>, <code>_all_labels</code> and
<code>_next_label</code> take the options <code>-J</code> and <code>-V</code> to specify sorted or
unsorted listings and menus, and the options <code>-1</code> and <code>-2</code> for removing
consecutive duplicates or all duplicates. These are also options to
<code>compadd</code>; the reason for handling them here is that they can be
different for each tag, and the function called will set <code>expl</code>
appropriately.</p>
<p>If your requirements are simple enough, you can replace that <code>_tags</code>
loop above with a single function, <code>_alternative</code>. This takes a series
of arguments each in the form `<tag>:<description>:<action>',
with the first two in the form you now know, and the third an action.
These are essentially the same as actions for the <code>_arguments</code> function,
described below, except that the form `<code>->state</code>', which says that the
calling function will handle the action itself by using the value of the
parameter <code>$state</code>, is not available. The most common forms of action
here will be a call to another completion function, maybe with arguments
(e.g. `<code>_files -/</code>'), or a simple list in parentheses (e.g. `<code>(see saw margery daw)</code>'). Here, for example, is how the <code>_cd</code> function handles
the two cases of local directories (under the current directory) and
directories reached via the <code>$cdpath</code> parameter:</p>
<p>If the tag is irrelevant, you can leave it empty, but you still need the
final colon since there should always be six in total. In some cases
where multiple tags apply it's useful to have a <code>:default</code> tag context
as a fall back if none of the actual tags yield styles for that context;
hence you should test the style first for the specific tag, then with
the <code>default</code>.</p>
<p>Style lookups all have the form just shown; the result for looking up
<code>style-name</code> in the given context will be saved in the <code>parameter</code>
(which you should make local, obviously). In addition, <code>zstyle</code> returns
a zero status if the lookup succeeded and non-zero if it failed. The
<code>-t</code> lookup is different from the rest as it only returns a status for a
boolean, i.e. returns status 0 if the value is <code>true</code>, <code>yes</code>, <code>1</code> or
<code>on</code>, and doesn't require a parameter name. There is also a <code>-T</code>, which
is identical except that it returns status 0 if the style doesn't exist,
i.e. the style is taken to default to true.</p>
<p>The other lookup options return the style as a particular type in the
parameter with exit status zero if the lookup succeeded, i.e. a value
was found, and non-zero otherwise; <code>-b</code>, <code>-s</code>, and <code>-a</code> specify boolean
(<code>parameter</code> is either <code>yes</code> or <code>no</code>), scalar (<code>parameter</code> is a scalar),
and array (<code>parameter</code> is an array, which may still be a single word, of
course), You can retrieve an associative array with <code>-a</code> as long as the
parameter has already been declared as one.</p>
<p>There's also a convenience option for matching, <code>-m</code>; instead of a
<code>parameter</code> this takes a <code>pattern</code> as the final argument, and returns
status zero if and only if the <code>pattern</code> matches one of the values
stored in the style for the given context.</p>
<p>Typical usages are thus:</p>
<pre><code> if zstyle -t ":completion:${curcontext}:" foo; then
# do things in a fooish way
else
# do things in an unfooish way
fi
</code></pre>
<p>or to use the value:</p>
<pre><code> local val
if zstyle -s ":completion:${curcontext}:" foo val; then
# use $val to establish how fooish to be
else
# be defaultly fooish
fi
</code></pre>
<p><spanid="l189"></span></p>
<h3id="697-getting-the-work-done-for-you-handling-arguments-etc"><aclass="header"href="#697-getting-the-work-done-for-you-handling-arguments-etc">6.9.7: Getting the work done for you: handling arguments etc.</a></h3>
<p>The last piece of unfinished completion business is to explain the
higher level functions which can save you time writing completions for
commands which behave in a standard way, with arguments and options. The
good news is that all the higher functions here handle tags and labels
internally, so you don't need to worry about <code>_tags</code>, <code>_wanted</code>,
<code>_requested</code>, etc. There's one exception: the `state' mechanism to be
described, where a function signals you that you're in a given state
using the parameter <code>$state</code>, expects you to handle tag labels yourself
--- pretty reasonable, as you have requested that the function return
control to you to generate the completions. I've mentioned that here so
that I don't have to gum up the description of the functions in this
<p>The most useful function is <code>_arguments</code>. There are many examples of
this in the completion functions for external commands, since so many
external commands take the standard format of a command with options,
some taking their own arguments, plus command arguments.</p>
<p>The basic usage is to call it with a series of arguments (which I'll
call `specifications') like:</p>
<pre><code><where I am>:<description>:<what action to take>
</code></pre>
<p>although there are a whole series of more complicated possibilities.</p>
<p>The initial `<code><where I am></code>' part tells the function whether the
specification applies to an argument in a particular position, or to an
option and possibly any arguments for that option. Let's start with
ordinary arguments, since these are simpler. In this case `<code><where I am></code>' will be either a number, giving the number of the argument, or a
`<code>*</code>', saying that this applies to all remaining arguments (or all
arguments, if you haven't used any of the other form). You can simplify
the first form, by just missing out the number; then the function will
assume it applies to the first argument not yet specified. Hence the
standard way of handling arguments is with a series of specifications
just beginning `<code>:</code>' for arguments that need to be handled their own
way, if any, then one beginning `<code>*:</code> for all remaining arguments, if
any.</p>
<p>The message that follows is a description to be passed on down to
<code>_description</code>. You don't specify the tags at this point; that comes
with the action.</p>
<p>The action can have various forms, chosen to be easily distinguishable
from one another.</p>
<ol>
<li>
<p>A list of strings in parentheses, such as `<code>(red blue green)</code>'.
These are the possible completions, passed straight down to
<code>compadd</code>.</p>
</li>
<li>
<p>The same, but with double parentheses; the list in this case
consists of the completion, a backslashed colon, and a description.
So an extended version of the previous action is `<code>((red\:The\ colour\ red blue:The\ colour\ blue))</code>' and so on. You can escape
other colons inside the specifications in this way, too.</p>
</li>
<li>
<p>A completion function to call, with any arguments, such as `<code>_files -/</code>' to complete directories. Usually this does the business with
<code>$expl</code> which should be familiar from the section on basic tag
handling, however you can put an extra space in front of the action
to have it called exactly as is, after word splitting.</p>
</li>
<li>
<p>A word preceded by `<code>-></code>' for example `<code>->state</code>'. This specifies
that <code>_arguments</code> should return and allow the calling function to
process the argument. To signal back to the calling function, the
parameter <code>$state</code> will be set to what follows the `<code>-></code>'. It's up
to the calling function to make <code>$state</code> a local parameter ---
<code>_arguments</code> can't do that, since then it couldn't return a value.</p>
<p>You should also make the parameters <code>$context</code> and <code>$line</code> local;
the former is set to the new part to be added to <code>$curcontext</code>,
which, as you can find out from <code>^Xh</code>, is <code>option-<option>-<arg></code>,
for example <code>option-file-1</code> for the first argument of the
<code>option-file</code> option, or <code>argument-N</code>, for example <code>argument-2</code> for
the second argument of the command.</p>
<p>In simple cases, you will just test the parameter <code>$state</code> after
<code>_arguments</code> has returned to see what to do: the return value is 300
to distinguish it from other returns where <code>_arguments</code> itself
performed the completion.</p>
</li>
<li>
<p>A chunk of code to evaluate, given in braces, which removes the need
for a special function or processing states. Obviously this is best
used for the simplest cases.</p>
</li>
</ol>
<p>These are the main possibilities, but I have not described every
variation. As always, you should see the manual for all the detail.</p>
<p>Here's a concocted example for that `<code>->state</code>' action specifier, in
case it's confusing you. It's for a command that takes arguments
`<code>alpha</code>', `<code>beta</code>' and `<code>gamma</code>', and takes a single option
`<code>-type</code>' which takes one argument, either `<code>normal</code>' or `<code>unusual</code>'.</p>
<p>If you run `<code>gdb --help</code>', you'll see where these come from:
`<code>--core=COREFILE</code>', `<code>--exec=EXECFILE</code>' and `<code>--tty=TTY</code>' are all
listed as possible option/argument pairs. Doing it this way neatly
allows the argument completions to work whatever the names of the
options --- though of course it's possible for the rest of the pattern
to change, too, and the commands, being written by lots of different
people, are not necessarily completely consistent in the way their help
text is presented.</p>
<p><spanid="l190"></span></p>
<h3id="698-more-completion-utility-functions"><aclass="header"href="#698-more-completion-utility-functions">6.9.8: More completion utility functions</a></h3>
<p>This is now just a ragbag of other functions which might prove useful in
your own completion functions, and which haven't been mentioned before,
with some examples; once again, consult the manual for more detail. Note
that many of these functions can take the most useful arguments to
<code>compadd</code> and pass them on, even where I haven't explicitly said so.</p>