12. Completion

Another great zsh feature is completion. If you hit Tab, zsh will complete all kinds of stuff. Like commands or filenames:

Example 12.1: Complete commands and filenames
% comp«Tab»
% compress _

% ls nic«Tab»
% ls nicecolors _

% ls /usr/pr«Tab»
% ls /usr/princeton/_

% ls -l =com«Tab»
% ls -l =compress _

If the completion is ambiguous, the editor will beep. If you find this annoying, you can set the NO_LIST_BEEP option. Completion can even be done in the middle of words. To use this, you will have to set the COMPLETE_IN_WORD option:

Example 12.2: Complete in middle of word
% setopt completeinword
% ls /usr/p_on«Tab»
% ls /usr/prince_on/
% setopt alwaystoend
% ls /usr/p_on«Tab»
% ls /usr/princeton/_

You can list possible completions by pressing Ctrl+D:

Example 12.3: List completions with Ctrl+D
% ls /vmu«Tab» —beep—
% ls /vmunix_
% ls /vmunix«Ctrl+D»
vmunix                    vmunix.old
vmunix.new.kernelmap.old  vmunix.org

Or, you could just set the AUTO_LIST option:

Example 12.4: AUTO_LIST completion listing
% setopt autolist
% ls /vmu«Tab» —beep—
vmunix                    vmunix.old
vmunix.new.kernelmap.old  vmunix.org
% ls /vmunix_

If you like to see the types of the files in these lists, like in ls -F, you can set the LIST_TYPES option. Together with AUTO_LIST you can use LIST_AMBIGUOUS. This will only list the possibilities if there is no unambiguous part to add:

Example 12.5: LIST_AMBIGUOUS with Tab
% setopt listambiguous
% ls /vmu«Tab» —beep—
% ls /vmunix_«Tab» —beep—
vmunix                    vmunix.old
vmunix.new.kernelmap.old  vmunix.org

If you don’t want several of these listings to scroll the screen so much, the ALWAYS_LAST_PROMPT option is useful. If set, you can continue to edit the line you were editing, with the completion listing appearing beneath it.

Another interesting option is MENU_COMPLETE. This affects the way Tab works. Let’s look at the /vmunix example again:

Example 12.6: Menu completion with Tab
% setopt menucomplete
% ls /vmu«Tab»
% ls /vmunix«Tab»
% ls /vmunix.new.kernelmap.old«Tab»
% ls /vmunix.old_

Each time you press Tab, it displays the next possible completion. In this way, you can cycle through the possible completions until you find the one you want.

The AUTO_MENU option makes a nice compromise between this method of completion and the regular method. If you set this option, pressing Tab once completes the unambiguous part normally, pressing the Tab key repeatedly after an ambiguous completion will cycle through the possible completions.

Another option you could set is REC_EXACT, which causes exact matches to be accepted, even if there are other possible completions:

Example 12.7: Accept exact matches
% setopt recexact
% ls /vmu«Tab» —beep—
vmunix                    vmunix.old
vmunix.new.kernelmap.old  vmunix.org
% ls /vmunix_«Tab»
% ls /vmunix _

To facilitate the typing of pathnames, a slash will be added whenever a directory is completed. Some computers don’t like the spurious slashes at the end of directory names. In that case, the AUTO_REMOVE_SLASH option comes to rescue. It will remove these slashes when you type a space or return after them.

The fignore variable lists suffixes of files to ignore during completion.

Example 12.8: Ignore suffixes with fignore
% ls foo«Tab» —beep—
foofile.c  foofile.o
% fignore=( .o \~ .bak .junk )
% ls foo«Tab»
% ls foofile.c _

Since foofile.o has a suffix that is in the fignore list, it was not considered a possible completion of foo.

Username completion is also supported:

Example 12.9: Complete tilde usernames
% ls ~pfal«Tab»
% ls ~pfalstad/_

and parameter name completion:

Example 12.10: Parameter name completion
% echo $ORG«Tab»
% echo $ORGANIZATION _
% echo ${ORG«Tab»
% echo ${ORGANIZATION _

Note that in the last example a space is added after the completion as usual. But if you want to add a colon or closing brace, you probably don’t want this extra space. Setting the AUTO_PARAM_KEYS option will automatically remove this space if you type a colon or closing brace after such a completion.

There is also option completion:

Example 12.11: Option name completion
% setopt nocl«Tab»
% setopt noclobber _

and binding completion:

Example 12.12: Completing bindkey arguments
% bindkey '^X^X' pu«Tab»
% bindkey '^X^X' push-line _

The compctl command is used to control completion of the arguments of specific commands. For example, to specify that certain commands take other commands as arguments, you use compctl -c:

Example 12.13: compctl commands for man
% compctl -c man nohup
% man upt«Tab»
% man uptime _

To specify that a command should complete filenames, you should use compctl -f. This is the default. It can be combined with -c, as well.

Example 12.14: compctl commands and files
% compctl -cf echo
% echo upt«Tab»
% echo uptime _

% echo fo«Tab»
% echo foo.c

Similarly, use -o to specify options, -v to specify variables, and -b to specify bindings.

Example 12.15: compctl options variables bindings
% compctl -o setopt unsetopt
% compctl -v typeset vared unset export
% compctl -b bindkey

You can also use -k to specify a custom list of keywords to use in completion. After the -k comes either the name of an array or a literal array to take completions from.

Example 12.16: compctl custom keyword lists
% ftphosts=(ftp.uu.net wuarchive.wustl.edu)
% compctl -k ftphosts ftp
% ftp wu«Tab»
% ftp wuarchive.wustl.edu _

% compctl -k '(cpirazzi subbarao sukthnkr)' mail finger
% finger cp«Tab»
% finger cpirazzi _

To better specify the files to complete for a command, use the -g option which takes any glob pattern as an argument. Be sure to quote the glob patterns as otherwise they will be expanded when the compctl command is run.

Example 12.17: compctl globs for TeX tools
% ls
letter.tex  letter.dvi  letter.aux  letter.log  letter.toc
% compctl -g '*.tex' latex
% compctl -g '*.dvi' xdvi dvips
% latex l«Tab»
% latex letter.tex _
% xdvi l«Tab»
% xdvi letter.dvi _

Glob patterns can include qualifiers within parentheses. To rmdir only directories and cd to directories and symbolic links pointing to them:

Example 12.18: compctl directory-only globs
% compctl -g '*(-/)' cd
% compctl -g '*(/)' rmdir

RCS users like to run commands on files which are not in the current directory, but in the RCS subdirectory where they all get ,v suffixes. They might like to use

Example 12.19: compctl RCS ,v files
% compctl -g 'RCS/*(:t:s/\,v//)' co rlog rcs
% ls RCS
builtin.c,v  lex.c,v      zle_main.c,v
% rlog bu«Tab»
% rlog builtin.c _

The :t modifier keeps only the last part of the pathname and the :s/\,v// will replace any ,v by nothing.

The -s flag is similar to -g, but it uses all expansions, instead of just globbing, like brace expansion, parameter substitution and command substitution.

Example 12.20: compctl -s substitutions
% compctl -s '$(setopt)' unsetopt

will only complete options which are actually set to be arguments to unsetopt.

Sometimes a command takes another command as its argument. You can tell zsh to complete commands as the first argument to such a command and then use the completion method of the second command. The -l flag with a null-string argument is used for this.

Example 12.21: compctl follow command args
% compctl -l '' nohup exec
% nohup comp«Tab»
% nohup compress _
% nohup compress fil«Tab»
% nohup compress filename _

Sometimes you would like to run really complicated commands to find out what the possible completions are. To do this, you can specify a shell function to be called that will assign the possible completions to a variable called reply. Note that this variable must be an array. Here’s another (much slower) way to get the completions for co and friends:

Example 12.22: compctl via reply function
% function getrcs {
> reply=()
> for i in RCS/*
>   do
>   reply=($reply[*] $(basename $i ,v))
>   done
> }
% compctl -K getrcs co rlog rcs

Some command arguments use a prefix that is not a part of the things to complete. The kill builtin command takes a signal name after a -. To make such a prefix be ignored in the completion process, you can use the -P flag.

Example 12.23: compctl kill signal prefix
% compctl -P - -k signals kill
% kill -H«Tab»
% kill -HUP _

TeX is usually run on files ending in .tex, but also sometimes on other files. It is somewhat annoying to specify that the arguments of TeX should end in .tex and then not be able to complete these other files. Therefore you can specify things like “Complete to files ending in .tex if available, otherwise complete to any filename.”. This is done with xored completion:

Example 12.24: Xor completion for tex
% compctl -g '*.tex' + -f tex

The + tells the editor to only take the next thing into account if the current one doesn’t generate any matches. If you have not changed the default completion, the above example is in fact equivalent to

Example 12.25: Xor with default completion
% compctl -g '*.tex' + tex

as a lone + at the end is equivalent to specifying the default completion after the +. This form of completion is also frequently used if you want to run some command only on a certain type of files, but not necessarily in the current directory. In this case you will want to complete both files of this type and directories. Depending on your preferences you can use either of

Example 12.26: Xor files and directories
% compctl -g '*.ps' + -g '*(-/)' ghostview
% compctl -g '*.ps *(-/)' ghostview

where the first one will only complete directories (and symbolic links pointing to directories) if no postscript file matches the already typed part of the argument.