[ prev | next | top ]

## 12. Completion

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

`% comp` TAB

    % compress _

    % ls nicTAB
    % ls nicecolors _

    % ls /usr/prTAB
    % ls /usr/princeton/_

    % ls -l =comTAB
    % ls -l =compress _

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

    % setopt completeinword
    % ls /usr/p_onTAB
    % ls /usr/prince_on/
    % setopt alwaystoend
    % ls /usr/p_onTAB
    % ls /usr/princeton/_

You can list possible completions by pressing ˆD:

`% ls /vmu` TAB —beep—

    % ls /vmunix_
    % ls /vmunixˆD
    vmunix                    vmunix.old
    vmunix.new.kernelmap.old  vmunix.org

Or, you could just set the AUTOLIST option:

    % setopt autolist
    % ls /vmuTAB —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 LISTTYPES option. Together with AUTOLIST you can use LISTAMBIGUOUS. This will only list the possibilities if there is no unambiguous part to add:

    % setopt listambiguous
    % ls /vmuTAB —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 ALWAYSLASTPROMPT 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 MENUCOMPLETE. This affects the way TAB works. Let’s look at the `/vmunix` example again:

    % setopt menucomplete
    % ls /vmuTAB
    % ls /vmunixTAB
    % ls /vmunix.new.kernelmap.oldTAB
    % 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 AUTOMENU 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 RECEXACT, which causes exact matches to be accepted, even if there are other possible completions:

    % setopt recexact
    % ls /vmuTAB —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 AUTOREMOVESLASH 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.

`% ls foo` TAB —beep—

    foofile.c  foofile.o
    % fignore=( .o \˜ .bak .junk )
    % ls fooTAB
    % 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:

`% ls ˜pfal` TAB

    % ls ˜pfalstad/_

and parameter name completion:

`% echo $ORG` TAB

    % echo $ORGANIZATION _
    % echo ${ORGTAB
    % 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 AUTOPARAMKEYS option will automatically remove this space if you type a colon or closing brace after such a completion.

There is also option completion:

`% setopt nocl` TAB

    % setopt noclobber _

and binding completion:

`% 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`:

    % compctl -c man nohup
    % man uptTAB
    % 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.

    % compctl -cf echo
    % echo uptTAB
    % echo uptime _

    % echo foTAB
    % echo foo.c

Similarly, use `-o` to specify options, `-v` to specify variables, and `-b` to specify 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.

    % ftphosts=(ftp.uu.net wuarchive.wustl.edu)
    % compctl -k ftphosts ftp
    % ftp wuTAB
    % ftp wuarchive.wustl.edu _

    % compctl -k ’(cpirazzi subbarao sukthnkr)’ mail finger
    % finger cpTAB
    % 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.

    % ls
    letter.tex  letter.dvi  letter.aux  letter.log  letter.toc
    % compctl -g ’*.tex’ latex
    % compctl -g ’*.dvi’ xdvi dvips
    % latex lTAB
    % latex letter.tex _
    % xdvi lTAB
    % xdvi letter.dvi _

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

    % 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

    % compctl -g ’RCS/*(:t:s/\,v//)’ co rlog rcs
    % ls RCS
    builtin.c,v  lex.c,v      zle_main.c,v
    % rlog buTAB
    % 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.

    % 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.

    % compctl -l ’’ nohup exec
    % nohup compTAB
    % nohup compress _
    % nohup compress filTAB
    % 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:

    % 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.

    % compctl -P - -k signals kill
    % kill -HTAB
    % 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:

    % 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

    % 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

    % 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.

[ prev | next | top ]