4959 lines
316 KiB
HTML
4959 lines
316 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="sidebar-visible no-js light">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>Completion, old and new - Zsh User's Guide</title>
|
|
|
|
|
|
<!-- Custom HTML head -->
|
|
|
|
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
|
|
<meta name="description" content="">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="theme-color" content="#ffffff" />
|
|
|
|
<link rel="icon" href="favicon.svg">
|
|
<link rel="shortcut icon" href="favicon.png">
|
|
<link rel="stylesheet" href="css/variables.css">
|
|
<link rel="stylesheet" href="css/general.css">
|
|
<link rel="stylesheet" href="css/chrome.css">
|
|
<link rel="stylesheet" href="css/print.css" media="print">
|
|
|
|
<!-- Fonts -->
|
|
<link rel="stylesheet" href="FontAwesome/css/font-awesome.css">
|
|
<link rel="stylesheet" href="fonts/fonts.css">
|
|
|
|
<!-- Highlight.js Stylesheets -->
|
|
<link rel="stylesheet" href="highlight.css">
|
|
<link rel="stylesheet" href="tomorrow-night.css">
|
|
<link rel="stylesheet" href="ayu-highlight.css">
|
|
|
|
<!-- Custom theme stylesheets -->
|
|
<link rel="stylesheet" href="./theme/catppuccin.css">
|
|
<link rel="stylesheet" href="./theme/catppuccin-highlight.css">
|
|
|
|
</head>
|
|
<body>
|
|
<!-- Provide site root to javascript -->
|
|
<script type="text/javascript">
|
|
var path_to_root = "";
|
|
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
|
|
</script>
|
|
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
|
<script type="text/javascript">
|
|
try {
|
|
var theme = localStorage.getItem('mdbook-theme');
|
|
var sidebar = localStorage.getItem('mdbook-sidebar');
|
|
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
|
}
|
|
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
|
}
|
|
} catch (e) { }
|
|
</script>
|
|
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
|
<script type="text/javascript">
|
|
var theme;
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
|
var html = document.querySelector('html');
|
|
html.classList.remove('no-js')
|
|
html.classList.remove('light')
|
|
html.classList.add(theme);
|
|
html.classList.add('js');
|
|
</script>
|
|
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
|
<script type="text/javascript">
|
|
var html = document.querySelector('html');
|
|
var sidebar = 'hidden';
|
|
if (document.body.clientWidth >= 1080) {
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
|
sidebar = sidebar || 'visible';
|
|
}
|
|
html.classList.remove('sidebar-visible');
|
|
html.classList.add("sidebar-" + sidebar);
|
|
</script>
|
|
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
|
<div class="sidebar-scrollbox">
|
|
<ol class="chapter"><li class="chapter-item expanded affix "><a href="zshguide.html">A User's Guide to the Z-Shell</a></li><li class="chapter-item expanded "><a href="zshguide01.html"><strong aria-hidden="true">1.</strong> A short introduction</a></li><li class="chapter-item expanded "><a href="zshguide02.html"><strong aria-hidden="true">2.</strong> What to put in your startup files</a></li><li class="chapter-item expanded "><a href="zshguide03.html"><strong aria-hidden="true">3.</strong> Dealing with basic shell syntax</a></li><li class="chapter-item expanded "><a href="zshguide04.html"><strong aria-hidden="true">4.</strong> The Z-Shell Line Editor</a></li><li class="chapter-item expanded "><a href="zshguide05.html"><strong aria-hidden="true">5.</strong> Substitutions</a></li><li class="chapter-item expanded "><a href="zshguide06.html" class="active"><strong aria-hidden="true">6.</strong> Completion, old and new</a></li><li class="chapter-item expanded "><a href="zshguide07.html"><strong aria-hidden="true">7.</strong> Modules and other bits and pieces Not written</a></li></ol>
|
|
</div>
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
|
|
</nav>
|
|
|
|
<div id="page-wrapper" class="page-wrapper">
|
|
|
|
<div class="page">
|
|
<div id="menu-bar-hover-placeholder"></div>
|
|
<div id="menu-bar" class="menu-bar sticky bordered">
|
|
<div class="left-buttons">
|
|
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
|
<i class="fa fa-bars"></i>
|
|
</button>
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
|
<i class="fa fa-paint-brush"></i>
|
|
</button>
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="latte">Latte</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="frappe">Frappé</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="macchiato">Macchiato</button></li>
|
|
<li role="none"><button role="menuitem" class="theme" id="mocha">Mocha</button></li>
|
|
</ul>
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
|
<i class="fa fa-search"></i>
|
|
</button>
|
|
</div>
|
|
|
|
<h1 class="menu-title">Zsh User's Guide</h1>
|
|
|
|
<div class="right-buttons">
|
|
<a href="print.html" title="Print this book" aria-label="Print this book">
|
|
<i id="print-button" class="fa fa-print"></i>
|
|
</a>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div id="search-wrapper" class="hidden">
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
|
</form>
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
|
<ul id="searchresults">
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
|
<script type="text/javascript">
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
|
});
|
|
</script>
|
|
|
|
<div id="content" class="content">
|
|
<main>
|
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
|
<p><strong>Table of Contents</strong> <em>generated with <a href="https://github.com/thlorenz/doctoc">DocToc</a></em></p>
|
|
<ul>
|
|
<li><a href="#chapter-6-completion-old-and-new">Chapter 6: Completion, old and new</a>
|
|
<ul>
|
|
<li><a href="#61-completion-and-expansion">6.1: Completion and expansion</a></li>
|
|
<li><a href="#62-configuring-completion-using-shell-options">6.2: Configuring completion using shell options</a>
|
|
<ul>
|
|
<li><a href="#621-ambiguous-completions">6.2.1: Ambiguous completions</a></li>
|
|
<li><a href="#622-always_last_prompt">6.2.2: <code>ALWAYS_LAST_PROMPT</code></a></li>
|
|
<li><a href="#623-menu-completion-and-menu-selection">6.2.3: Menu completion and menu selection</a></li>
|
|
<li><a href="#624-other-ways-of-changing-completion-behaviour">6.2.4: Other ways of changing completion behaviour</a></li>
|
|
<li><a href="#625-changing-the-way-completions-are-displayed">6.2.5: Changing the way completions are displayed</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#63-getting-started-with-new-completion">6.3: Getting started with new completion</a></li>
|
|
<li><a href="#64-how-the-shell-finds-the-right-completions">6.4: How the shell finds the right completions</a>
|
|
<ul>
|
|
<li><a href="#641-contexts">6.4.1: Contexts</a></li>
|
|
<li><a href="#642-tags">6.4.2: Tags</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#65-configuring-completion-using-styles">6.5: Configuring completion using styles</a>
|
|
<ul>
|
|
<li><a href="#651-specifying-completers-and-their-options">6.5.1: Specifying completers and their options</a></li>
|
|
<li><a href="#652-changing-the-format-of-listings-groups-etc">6.5.2: Changing the format of listings: groups etc.</a></li>
|
|
<li><a href="#653-styles-affecting-particular-completions">6.5.3: Styles affecting particular completions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#66-command-widgets">6.6: Command widgets</a>
|
|
<ul>
|
|
<li><a href="#661-_complete_help">6.6.1: <code>_complete_help</code></a></li>
|
|
<li><a href="#662-_correct_word-_correct_filename-_expand_word">6.6.2: <code>_correct_word</code>, <code>_correct_filename</code>, <code>_expand_word</code></a></li>
|
|
<li><a href="#663-_history_complete_word">6.6.3: <code>_history_complete_word</code></a></li>
|
|
<li><a href="#664-_most_recent_file">6.6.4: <code>_most_recent_file</code></a></li>
|
|
<li><a href="#665-_next_tags">6.6.5: <code>_next_tags</code></a></li>
|
|
<li><a href="#666-_bash_completions">6.6.6: <code>_bash_completions</code></a></li>
|
|
<li><a href="#667-_read_comp">6.6.7: <code>_read_comp</code></a></li>
|
|
<li><a href="#668-_generic">6.6.8: <code>_generic</code></a></li>
|
|
<li><a href="#669-predict-on-incremental-complete-word">6.6.9: <code>predict-on</code>, <code>incremental-complete-word</code></a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#67-matching-control-and-controlling-where-things-are-inserted">6.7: Matching control and controlling where things are inserted</a>
|
|
<ul>
|
|
<li><a href="#671-case-insensitive-matching">6.7.1: Case-insensitive matching</a></li>
|
|
<li><a href="#672-matching-option-names">6.7.2: Matching option names</a></li>
|
|
<li><a href="#673-partial-word-completion">6.7.3: Partial word completion</a></li>
|
|
<li><a href="#674-substring-completion">6.7.4: Substring completion</a></li>
|
|
<li><a href="#675-partial-words-with-capitals">6.7.5: Partial words with capitals</a></li>
|
|
<li><a href="#676-final-notes">6.7.6: Final notes</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#68-tutorial">6.8: Tutorial</a>
|
|
<ul>
|
|
<li><a href="#681-the-dispatcher">6.8.1: The dispatcher</a></li>
|
|
<li><a href="#682-subcommand-completion-_arguments">6.8.2: Subcommand completion: <code>_arguments</code></a></li>
|
|
<li><a href="#683-completing-particular-argument-types">6.8.3: Completing particular argument types</a></li>
|
|
<li><a href="#684-the-rest">6.8.4: The rest</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#69-writing-new-completion-functions-and-widgets">6.9: Writing new completion functions and widgets</a>
|
|
<ul>
|
|
<li><a href="#691-loading-completion-functions-compdef">6.9.1: Loading completion functions: <code>compdef</code></a></li>
|
|
<li><a href="#692-adding-a-set-of-completions-compadd">6.9.2: Adding a set of completions: <code>compadd</code></a></li>
|
|
<li><a href="#693-functions-for-generating-filenames-etc">6.9.3: Functions for generating filenames, etc.</a></li>
|
|
<li><a href="#694-the-zshparameter-module">6.9.4: The <code>zsh/parameter</code> module</a></li>
|
|
<li><a href="#695-special-completion-parameters-and-compset">6.9.5: Special completion parameters and <code>compset</code></a></li>
|
|
<li><a href="#696-fancier-completion-using-the-tags-and-styles-mechanism">6.9.6: Fancier completion: using the tags and styles mechanism</a></li>
|
|
<li><a href="#697-getting-the-work-done-for-you-handling-arguments-etc">6.9.7: Getting the work done for you: handling arguments etc.</a></li>
|
|
<li><a href="#698-more-completion-utility-functions">6.9.8: More completion utility functions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#610-finally">6.10: Finally</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
<p><span id="comp"></span><span id="l144"></span></p>
|
|
<h1 id="chapter-6-completion-old-and-new"><a class="header" href="#chapter-6-completion-old-and-new">Chapter 6: Completion, old and new</a></h1>
|
|
<p>Completion of command arguments is something zsh is particularly good
|
|
at. The simplest case is that you hit <code><TAB></code>, and the shell guesses
|
|
what has to go there and fills it in for you:</p>
|
|
<pre><code> % ls
|
|
myfile theirfile yourfile
|
|
% cat t<TAB>
|
|
</code></pre>
|
|
<p>expands the command line to</p>
|
|
<pre><code> % cat theirfile
|
|
</code></pre>
|
|
<p>and you only had to type the initial letter, then <code>TAB</code>.</p>
|
|
<p>In the early days when this feature appeared in the C shell, only
|
|
filenames could be completed; there were no clever tricks to help you if
|
|
the name was ambiguous, it simply printed the unambiguous part and
|
|
beeped so that you had to decide what to do next. You could also list
|
|
possible completions; for some reason this became attached to the <code>^D</code>
|
|
key in csh, which in later shells with Emacs-like bindings also deletes
|
|
the next character, so that history has endowed zsh, like other shells,
|
|
with the slightly odd combined behaviour:</p>
|
|
<pre><code> % cat yx
|
|
</code></pre>
|
|
<p>Now move the cursor back one character onto the x and hit ^D twice and
|
|
you see: <code>yourfile</code>. That doesn't work if you use vi-like bindings, or,
|
|
obviously, if you've rebound <code>^D</code>.</p>
|
|
<p>Next, it became possible to complete other items such as names of users,
|
|
commands or hosts. Then zsh weighed in with menu completion, so you
|
|
could keep on blindly hitting <code><TAB></code> until the right answer appeared,
|
|
and never had to type an extra character yourself.</p>
|
|
<p>The next development was tcsh's, and then zsh's, programmable completion
|
|
system; you could give instructions to the shell that in certain
|
|
contexts, only certain items should be completed; for example, after
|
|
<code>cd</code>, you would only want directories. In tcsh, there was a command
|
|
called <code>complete</code>; each `<code>complete ...</code>' statement defined the
|
|
completion for the arguments of a particular command, such as <code>cd</code>; the
|
|
equivalent in zsh is <code>compctl</code>, which was inspired by <code>complete</code> but is
|
|
different in virtually every significant detail. There is a perl script
|
|
<code>lete2ctl</code> in the <code>Misc</code> directory of the shell distribution to help you
|
|
convert from the tcsh to the zsh formats. You put a whole series of
|
|
<code>compctl</code> commands into <code>.zshrc</code>, and everything else is done by the
|
|
shell.</p>
|
|
<p>Zsh's system has become more and more sophisticated, and in version
|
|
3.1.6 a new completion system appeared which is supposed to do
|
|
everything for you: you simply call a function, <code>compinit</code>, from an
|
|
initialization file, after which zsh knows, for example, that <code>gunzip</code>
|
|
should be followed by files ending in <code>.gz</code>. The new system is based on
|
|
shell functions, an added bonus since they are extremely flexible and
|
|
you already know the syntax. However, given the complexity it's quite
|
|
difficult to get started writing your own completions now, and hard
|
|
enough to know what to do to change the settings the way you like. The
|
|
rest of the chapter should help.</p>
|
|
<p>I shall concentrate on the new completion system, which seems destined
|
|
to take over completely from the old one eventually, now that the 3.1
|
|
release series has become the 4.0 production release. The old
|
|
<strong>compctl</strong> command is still available, and old completion definitions
|
|
will remain working in future versions of zsh --- in fact, on most
|
|
operating systems which support dynamically linked libraries the old
|
|
completion system is in a different file, which the shell loads when
|
|
necessary, so there's very little overhead for this.</p>
|
|
<p>The big difference in the new system is that, instead of everything
|
|
being set up once and for all when the shell starts, various bits of
|
|
shell code are called after you hit <code><TAB></code>, to generate the completions
|
|
there and then. There's enough new in the shell that all those
|
|
unmemorable options to <code>compctl</code> (`<code>-f</code>' for files `<code>-v</code>' for
|
|
variables and so on) can be replaced by commands that produce the list
|
|
of completions directly; the key command in this case is called
|
|
`<code>compadd</code>', which is passed this list and decides what to use to
|
|
complete the word on the command line. So the simplest possible form of
|
|
new completion looks roughly like this:</p>
|
|
<pre><code> # tell the shell that the function mycompletion can do completion
|
|
# when called by the widget name my-completion-widget, and that
|
|
# it behaves like the existing widget complete-word
|
|
zle -C my-completion-widget .complete-word mycompletion
|
|
|
|
# define a key that calls the completion widget
|
|
bindkey '^x^i' my-completion-widget
|
|
|
|
# define the function that will be called
|
|
mycompletion() {
|
|
# add a list of completions
|
|
compadd alpha bravo charlie delta
|
|
}
|
|
</code></pre>
|
|
<p>That's very roughly what the completion system is doing, except that the
|
|
function is called <code>_main_complete</code> and calls a lot of other functions
|
|
to do its dirty work based on the context where completion was called
|
|
(all the things that <code>compctl</code> used to do), and the widgets are just the
|
|
old completion widgets (`<code>expand-or-complete</code>' etc.) redefined and
|
|
still bound to all the original keys. But, in case you hadn't guessed,
|
|
there's more to it than that.</p>
|
|
<p>Here's a plan for the sections of this chapter.</p>
|
|
<ol>
|
|
<li>A broad description of completion and expansion, applying equally to
|
|
old and new completion.</li>
|
|
<li>How to configure completion using shell options. Most of this
|
|
section applies to old completion, too, although I won't explicitly
|
|
flag up any differences. After this, I shall leave the <code>compctl</code>
|
|
world behind.</li>
|
|
<li>How to start up new completion.</li>
|
|
<li>The basics of how the new completion system works.</li>
|
|
<li>How to configure it using the new `<code>zstyle</code>' builtin.</li>
|
|
<li>Separate commands which do something other than the usual completion
|
|
system, as well as some other editing widgets that have to do with
|
|
completion.</li>
|
|
<li>Matching control, a powerful way of deciding such things as whether
|
|
to complete case-insensitively, to allow insertion of extra parts of
|
|
words before punctuation characters, or to ignore certain characters
|
|
in the word on the command line.</li>
|
|
<li>How to write your own completion functions; you won't need to have
|
|
too solid an understanding of all the foregoing just to do simple
|
|
completions, but I will gradually introduce the full baroque
|
|
splendour of how to make tags and styles work in your own functions,
|
|
and how to make completion do the work of handling command arguments
|
|
and options.</li>
|
|
<li>Ends the chapter gracefully, on the old `beginning, middle, end'
|
|
principle.</li>
|
|
</ol>
|
|
<p><span id="l145"></span></p>
|
|
<h2 id="61-completion-and-expansion"><a class="header" href="#61-completion-and-expansion">6.1: Completion and expansion</a></h2>
|
|
<p>More things than just completion happen when you hit tab. The first
|
|
thing that zsh tries to do is expand the line. Expansion was covered in
|
|
a previous chapter: basically all the things described there are
|
|
possible candidates for expanding in-line by the editor. In other words,
|
|
history substitutions with bangs, the various expansions using `<code>$</code>' or
|
|
backquote, and filename generation (globbing) can all take place, with
|
|
the result replacing what was there on the command line:</p>
|
|
<pre><code> % echo $PWD<TAB>
|
|
-> echo /home/pws/zsh/projects/zshguide
|
|
% echo `print $ZSH_VERSION`<TAB>
|
|
-> echo 3.1.7
|
|
% echo !!<TAB>
|
|
-> echo echo 3.1.7
|
|
% echo ~/.z*<TAB>
|
|
-> echo /home/pws/.zcompdump /home/pws/.zlogout
|
|
/home/pws/.zshenv /home/pws/.zshrc
|
|
</code></pre>
|
|
<p>Note that the `<code>~</code>' also gets expanded in this case.</p>
|
|
<p>This is often a good time to remember the `undo' key, `<code>^_</code>' or
|
|
`<code>^Xu</code>'; typing this will restore what was there before the expansion
|
|
if you don't like the result. Many keyboards have a quirk that what's
|
|
described as `<code>^_</code>' should be typed as control with slash, which you'd
|
|
write `<code>^/</code>' except unfortunately that does something else; this is not
|
|
zsh's fault. There's another half-exception, namely filename generation:
|
|
paths like `<code>~/file</code>' don't get expanded, because you usually know what
|
|
they refer to and it's usually convenient to leave them for use in
|
|
completion. However, the `<code>=cmdname</code>' form does get expanded, unless
|
|
you have <code>NO_EQUALS</code> set.</p>
|
|
<p>In fact, deciding whether expansion or completion takes place can
|
|
sometimes be tricky, since things that would be expanded if they were
|
|
complete, may need to be completed first; for example <code>$PAT</code> should
|
|
probably be completed to <code>$PATH</code>, but it's quite possible there is a
|
|
parameter <code>$PAT</code> too. You can decide which, if you prefer. First, the
|
|
commands <code>expand-word</code>, bound to `<code>^X*</code>', and the corresponding command
|
|
for listing what would be expanded, <code>list-expand</code>, bound to `<code>^Xg</code>', do
|
|
expansion only --- all possible forms except alias expansion, including
|
|
turning `<code>~/file</code>' into a full path.</p>
|
|
<p>From the other point of view, you can use commands other than
|
|
<code>expand-or-complete</code>, the one bound by default to <code><TAB></code>, to perform
|
|
only completion. The basic command for this is <code>complete-word</code>, which is
|
|
not bound by default. It is quite sensible to bind this to `<code>^I</code>' (i.e.
|
|
<code><TAB></code>) if you are happy to use the separate commands for expansion,
|
|
i.e.</p>
|
|
<pre><code> # Now tab does only completion, not expansion
|
|
bindkey '^i' complete-word
|
|
</code></pre>
|
|
<p>Furthermore, if you do this and use the new completion system, then as
|
|
we shall see there is a way of making the completion system perform
|
|
expansion --- see the description of the <code>_expand</code> completer below. In
|
|
this case you have much more control over what forms of expansion are
|
|
tried, and at what point, but you have to make sure you use
|
|
<code>complete-word</code>, not <code>expand-or-complete</code>, else the standard expansion
|
|
system will take over.</p>
|
|
<p>There's a close relative of <code>expand-or-complete</code>,
|
|
<code>expand-or-complete-prefix</code>, not bound by default. The only difference
|
|
is that it will ignore everything under and to the right of the cursor
|
|
when completing. It's as if there was a space where the cursor was, with
|
|
everything to be ignored shifted to the right (guess how it's
|
|
implemented). Use this if you habitually type new words in the line
|
|
before other words, and expect them to complete or expand on their own
|
|
even before you've typed the space after them. Some other shells work
|
|
this way all the time. To be more explicit:</p>
|
|
<pre><code> % ls
|
|
filename1
|
|
% ls filex
|
|
</code></pre>
|
|
<p>Move the cursor to the <code>x</code> and hit tab. With <code>expand-or-complete</code>
|
|
nothing happens; it's trying to complete a file called `<code>filex</code>' ---
|
|
or, with the option <code>COMPLETE_IN_WORD</code> set, it's trying to find a file
|
|
whose name starts with `<code>file</code>' and ends with `<code>x</code>'. If you do</p>
|
|
<pre><code> bindkey '^i' expand-or-complete-prefix
|
|
</code></pre>
|
|
<p>and try the same experiment, you will find the whole thing is completed
|
|
to `<code>filename1x</code>', so that the `<code>x</code>' was ignored, but not removed.</p>
|
|
<p>One possible trap is that the listing commands, both
|
|
<code>delete-char-or-list</code>, bound by default to `<code>^D</code>' in emacs mode, and
|
|
<code>list-options</code>, bound by default to `<code>^D</code>' in vi insert mode and the
|
|
basic command for listing completions as it doesn't have the
|
|
delete-character behaviour, do not show possible expansions, so with the
|
|
default bindings you can use `<code>^D</code>' to list, then hit <code><TAB></code> and find
|
|
that the line has been completely rewritten by some expansion. Using
|
|
<code>complete-word</code> instead of <code>expand-or-complete</code> will of course fix this.
|
|
If you know how to write new editor widgets (<a href="zshguide04.html#zle">chapter
|
|
4</a>), you can make up a function which tries
|
|
<code>list-expand</code>, and if that fails tries <code>list-options</code>.</p>
|
|
<p>There are four completion commands I haven't mentioned yet: three are
|
|
<code>menu-complete</code>, <code>menu-expand-or-complete</code> and <code>reverse-menu-complete</code>,
|
|
which perform menu completion, where you can cycle through all possible
|
|
completions by hitting the same key. The first two correspond to
|
|
<code>complete-word</code> and <code>expand-or-complete</code> respectively, while the third
|
|
has no real equivalent as it takes you backwards through a completion
|
|
list. The effect of the third can't be reached just by setting options
|
|
for menu completion, so it's a useful one to bind separately. I have it
|
|
bound to `<code>\M-\C-i</code>', i.e. tab with the Meta key pressed down, but it's
|
|
not bound by default.</p>
|
|
<p>The fourth is <code>menu-select</code>, which performs an enhanced form of menu
|
|
completion called `menu selection' which I'll describe below when I
|
|
talk about options. You have to make sure the <code>zsh/complist</code> module is
|
|
loaded to use this zle command. If you use the style, zsh should be able
|
|
to load this automatically when needed, as long as you have dynamic
|
|
loading, which you probably do these days. <span id="l146"></span></p>
|
|
<h2 id="62-configuring-completion-using-shell-options"><a class="header" href="#62-configuring-completion-using-shell-options">6.2: Configuring completion using shell options</a></h2>
|
|
<p>There are two main ways of altering the behaviour of completion without
|
|
writing or rewriting shell functions: shell options, as introduced in
|
|
<a href="zshguide02.html#init">chapter 2</a>, and styles, as introduced above. I
|
|
shall first discuss the shell options, although as you will see some of
|
|
these refer to the styles mechanism. Setting shell options affects every
|
|
single completion, unless special care has been taken (using a
|
|
corresponding style for the context, or setting an option locally) to
|
|
avoid that.</p>
|
|
<p>In addition to the options which directly affect the completion system,
|
|
completion is sensitive to various other options which describe shell
|
|
behaviour. For example, if the option <code>MAGIC_EQUAL_SUBST</code> is set, so
|
|
that arguments of all commands looking like `<code>foo=~/file</code>' have the
|
|
`<code>~</code>' expanded as if it was at the start of an argument, then the
|
|
default completion for arguments of commands not specially handled will
|
|
try to complete filenames after the `<code>=</code>'.</p>
|
|
<p>Needless to say, if you write completion functions you will need to
|
|
worry about a lot of other options which can affect shell syntax. The
|
|
main starting point for completion chosen by context (everything except
|
|
the commands for particular completions bound separately to keystrokes)
|
|
is the function <code>_main_complete</code>, which includes the effect of the
|
|
following lines to make sure that at least the basic options are set up
|
|
within completion functions:</p>
|
|
<pre><code> setopt glob bareglobqual nullglob rcexpandparam extendedglob unset
|
|
unsetopt markdirs globsubst shwordsplit shglob ksharrays cshnullglob
|
|
unsetopt allexport aliases errexit octalzeroes
|
|
</code></pre>
|
|
<p>but that by no means exhausts the possibilities. Actually, it doesn't
|
|
include those lines: the options to set are stored in the array
|
|
<code>$_comp_options</code>, with <code>NO_</code> in front if they are to be turned off. You
|
|
can modify this if you find you need to (and maybe tell the maintainers,
|
|
too).</p>
|
|
<p>By the way, if you are wondering whether you can re-use the function
|
|
<code>_main_complete</code>, by binding it to a different key with slightly
|
|
different completion definitions, look instead at the description of the
|
|
<code>_generic</code> command widget below. It's just a front-end to
|
|
<code>_main_complete</code> which allows you to have a different set of styles in
|
|
effect.</p>
|
|
<p><span id="l147"></span></p>
|
|
<h3 id="621-ambiguous-completions"><a class="header" href="#621-ambiguous-completions">6.2.1: Ambiguous completions</a></h3>
|
|
<p>The largest group of options deals with what happens when a completion
|
|
is ambiguous, in other words there is more than one possible completion.
|
|
The seven relevant options are as follows, as copied from the FAQ; many
|
|
different combinations are possible:</p>
|
|
<ul>
|
|
<li>with <code>NO_BEEP</code> set, that annoying beep goes away,</li>
|
|
<li>with <code>NO_LIST_BEEP</code>, beeping is only turned off for ambiguous
|
|
completions,</li>
|
|
<li>with <code>AUTO_LIST</code> set, when the completion is ambiguous you get a
|
|
list without having to type <code>^D</code>,</li>
|
|
<li>with <code>BASH_AUTO_LIST</code> set, the list only happens the second time you
|
|
hit tab on an ambiguous completion,</li>
|
|
<li>with <code>LIST_AMBIGUOUS</code>, this is modified so that nothing is listed if
|
|
there is an unambiguous prefix or suffix to be inserted --- this can
|
|
be combined with <code>BASH_AUTO_LIST</code>, so that where both are applicable
|
|
you need to hit tab three times for a listing,</li>
|
|
<li>with <code>REC_EXACT</code>, if the string on the command line exactly matches
|
|
one of the possible completions, it is accepted, even if there is
|
|
another completion (i.e. that string with something else added) that
|
|
also matches,</li>
|
|
<li>with <code>MENU_COMPLETE</code> set, one completion is always inserted
|
|
completely, then when you hit TAB it changes to the next, and so on
|
|
until you get back to where you started,</li>
|
|
<li>with <code>AUTO_MENU</code>, you only get the menu behaviour when you hit TAB
|
|
again on the ambiguous completion.</li>
|
|
</ul>
|
|
<p><span id="l148"></span></p>
|
|
<h3 id="622-always_last_prompt"><a class="header" href="#622-always_last_prompt">6.2.2: <code>ALWAYS_LAST_PROMPT</code></a></h3>
|
|
<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><span id="l149"></span></p>
|
|
<h3 id="623-menu-completion-and-menu-selection"><a class="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>
|
|
<pre><code> bindkey -M menuselect '^o' accept-and-infer-next-history
|
|
</code></pre>
|
|
<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><span id="l150"></span></p>
|
|
<h3 id="624-other-ways-of-changing-completion-behaviour"><a class="header" href="#624-other-ways-of-changing-completion-behaviour">6.2.4: Other ways of changing completion behaviour</a></h3>
|
|
<p><strong><code>COMPLETE_ALIASES</code></strong></p>
|
|
<p>If you set an alias such as</p>
|
|
<pre><code> alias pu=pushd
|
|
</code></pre>
|
|
<p>then the alias `<code>pu</code>' will be expanded when the completion system is
|
|
looking for the name of the command, so that it will instead find the
|
|
command name `<code>pushd</code>'. This is quite useful to avoid having to define
|
|
extra completions for all your aliases. However, it's possible you may
|
|
want to define something different for the alias than for the command it
|
|
expands to. In that case, you will need to set <code>COMPLETE_ALIASES</code>, and
|
|
to make arrangements for completing after every alias which does not
|
|
already match the name of a command. Hence `<code>alias zcat="myzcat -dc"</code>'
|
|
will work with the option set, even if you haven't told the system about
|
|
`<code>myzcat</code>', while `<code>alias myzcat="gzip -dc"</code>' will not work unless you
|
|
do define a completion for myzcat: here `<code>compdef _gzip myzcat</code>' would
|
|
probably be good enough. Without the option set, it would be the other
|
|
way around: the first alias would not work without the extra <code>compdef</code>,
|
|
but the second would.</p>
|
|
<p><strong><code>AUTO_REMOVE_SLASH</code></strong></p>
|
|
<p>This option is turned on by default. If you complete a directory name
|
|
and a slash is added --- which it usually is, both to tell you that you
|
|
have completed a directory and to allow you to complete files inside it
|
|
without adding a `<code>/</code>' by hand --- and the next thing you type is <em>not</em>
|
|
something which would insert or complete part of a file in that
|
|
directory, then the slash is removed. Hence:</p>
|
|
<pre><code> % rmdir my<TAB>
|
|
-> rmdir mydir/
|
|
% rmdir mydir/<RETURN>
|
|
-> `rmdir mydir' executed
|
|
|
|
</code></pre>
|
|
<p>This example shows why this behaviour was added: some versions of
|
|
`<code>rmdir</code>' baulk at having the slash after the directory name. On the
|
|
other hand, if you continued typing after the slash, or hit tab again to
|
|
complete inside <code>mydir</code>, then the slash would remain.</p>
|
|
<p>This is at worst harmless under most circumstances. However, you can
|
|
unset the option <code>AUTO_REMOVE_SLASH</code> if you don't like that behaviour.
|
|
One thing that may cause slight confusion, although it is the same as
|
|
with other suffixes (i.e. bits which get added automatically but aren't
|
|
part of the value being completed), is that the slash is added straight
|
|
away if the value is being inserted by menu completion. This might cause
|
|
you to think wrongly that the completion is finished, and hence is
|
|
unique when in fact it isn't.</p>
|
|
<p>Note that some forms of completion have this type of behaviour built in,
|
|
not necessarily with a slash, when completing lists of arguments. For
|
|
example, enter `<code>typeset ZSH_V<TAB></code>' and you will see
|
|
`<code>ZSH_VERSION=</code>' appear, in case you want to assign something to the
|
|
parameter; hitting space, which is not a possible value, makes the
|
|
`<code>=</code>' disappear. This is not controlled by the <code>AUTO_REMOVE_SLASH</code>
|
|
option, which applies only to directories inserted by the standard
|
|
filename completion system.</p>
|
|
<p><strong><code>AUTO_PARAM_SLASH</code>, <code>AUTO_PARAM_KEYS</code></strong></p>
|
|
<p>These options come into effect when completing expressions with
|
|
parameter substitutions. If <code>AUTO_PARAM_SLASH</code> is set, then any
|
|
parameter expression whose value is the name of a directory will have a
|
|
slash appended when completed, just as if the value itself had been
|
|
inserted by the completion system.</p>
|
|
<p>The behaviour for <code>AUTO_PARAM_KEYS</code> is a bit more complicated. Try this:</p>
|
|
<pre><code> print ${ZSH_V<TAB>
|
|
</code></pre>
|
|
<p>You will find that you get the complete word `<code>${ZSH_VERSION}</code>', with
|
|
the closing brace and (assuming there are no other matching parameters)
|
|
a space afterwards. However, often after you have completed a parameter
|
|
in this fashion you want to type something immediately after it, such as
|
|
a subscript. With <code>AUTO_PARAM_KEYS</code>, if you type something at this point
|
|
which seems likely to have to go after the parameter name, it will
|
|
immediately be put there without you having to delete the intervening
|
|
characters --- try it with `<code>[</code>', for example. Note that this only
|
|
happens if the parameter name and any extra bits were added by
|
|
completion; if you type everything by hand, typing `<code>[</code>' will not have
|
|
this magic effect.</p>
|
|
<p><strong><code>COMPLETE_IN_WORD</code></strong></p>
|
|
<p>If this is set, completion always takes place at the cursor position in
|
|
the word. For example if you typed `<code>Mafile</code>', went back over the
|
|
`<code>f</code>', and hit tab, the shell would complete `<code>Makefile</code>', instead of
|
|
its usual behaviour of going to the end of the word and trying to find a
|
|
completion there, i.e. something matching `<code>Mafile*</code>'. Some sorts of
|
|
new completion (such as filename completion) seem to implement this
|
|
behaviour regardless of the option setting; some other features (such as
|
|
the `<code>_prefix</code>' completer described below) require it, so it's a good
|
|
thing to set and get used to, unless you really need to complete only at
|
|
the end of the word.</p>
|
|
<p><strong><code>ALWAYS_TO_END</code></strong></p>
|
|
<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><span id="l151"></span></p>
|
|
<h3 id="625-changing-the-way-completions-are-displayed"><a class="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><strong><code>LIST_PACKED</code>, <code>LIST_ROWS_FIRST</code></strong></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><span id="l152"></span></p>
|
|
<h2 id="63-getting-started-with-new-completion"><a class="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
|
|
in your <code>.zshrc</code>:</p>
|
|
<pre><code> zstyle ':completion:*' use-compctl false
|
|
</code></pre>
|
|
<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><span id="l153"></span></p>
|
|
<h2 id="64-how-the-shell-finds-the-right-completions"><a class="header" href="#64-how-the-shell-finds-the-right-completions">6.4: How the shell finds the right completions</a></h2>
|
|
<p><span id="l154"></span></p>
|
|
<h3 id="641-contexts"><a class="header" href="#641-contexts">6.4.1: Contexts</a></h3>
|
|
<p>The examples above show that the completion system is highly
|
|
context-sensitive, so it's important to know how these contexts are
|
|
described. This system evolved gradually, but everything I say applies
|
|
to all versions of zsh with the major version 4.</p>
|
|
<p>state we are at in completion, and is given as a sort of colon-separated
|
|
path, starting with the least specific part. There's an easy way of
|
|
finding out what context you are in: at the point where you want to
|
|
complete something, instead type `<code>^Xh</code>', and it will tell you. In the
|
|
case of the <code>$_comps</code> example, you will find,</p>
|
|
<pre><code> :completion::complete:-subscript-::
|
|
</code></pre>
|
|
<p>plus a list of so-called `tags' and completion functions, which I'll
|
|
talk about later. The full form is:</p>
|
|
<pre><code> :completion:<func>:<completer>:<command>:<argument>:<tag>
|
|
</code></pre>
|
|
<p>where the elements may be missing if they are not set, but the colons
|
|
will always be there to make pattern matching easier. Here's what the
|
|
bits of the context mean after the <code>:completion:</code> part, which is common
|
|
to the whole completion system.</p>
|
|
<ul>
|
|
<li><em><strong><func></strong></em><br />
|
|
is the name of a function from which completion is called --- this
|
|
is blank if it was started from the standard completion system, and
|
|
only appears in a few special cases, listed in section six of this
|
|
chapter.</li>
|
|
<li><em><strong><completer></strong></em><br />
|
|
is called `<code>complete</code>' in this case: this refers to the fact that
|
|
the completion system can do more than just simple completion; for
|
|
example, it can do a more controlled form of expansion (as I
|
|
mentioned), spelling correction, and completing words with spelling
|
|
mistakes. I'll introduce the other completers later; `<code>complete</code>'
|
|
is the simplest one, which just does basic completion.</li>
|
|
<li><em><strong><command></strong></em><br />
|
|
is the name of a command or other similar context as described
|
|
above, here `<code>-subscript-</code>'.</li>
|
|
<li><em><strong><argument></strong></em><br />
|
|
is most useful when <code><command></code> is the name of a real command; it
|
|
describes where in the arguments to that command we are. You'll see
|
|
how it works in a moment. Many of the simpler completions don't use
|
|
this; only the ones with complicated option and argument
|
|
combinations. You just have to find out with <code>^Xh</code> if you need to
|
|
know.</li>
|
|
<li><em><strong><tag></strong></em><br />
|
|
describes the type of a completion, essentially a way of
|
|
discriminating between the different things which can be completed
|
|
at the same point on the command line.</li>
|
|
</ul>
|
|
<p>Now look at the context for a more normal command-argument completion,
|
|
e.g. after <code>cd</code>; here you'll see the context
|
|
`<code>:completion::complete:cd::</code>'. Here the command-name part of the
|
|
context is a real command.</p>
|
|
<p>For something more complicated, try after `<code>cvs add</code>' (it doesn't
|
|
matter for this if you don't have the <code>cvs</code> command). You'll see a long
|
|
and repetitive list of tags, for two possible contexts,</p>
|
|
<pre><code> :completion::complete:cvs:argument-rest:
|
|
:completion::complete:cvs-add:argument-rest:
|
|
</code></pre>
|
|
<p>The reason you have both is that the `<code>add</code>' is not only an argument to
|
|
<code>cvs</code>, as the first context would suggest, it's also a subcommand in its
|
|
own right, with its own arguments, and that's what the second context is
|
|
for. The first context implies there might be more subcommands after
|
|
`<code>add</code>' and its arguments which are completely separate from them ---
|
|
though in fact CVS doesn't work that way, so that form won't give you
|
|
any completions here.</p>
|
|
<p>In both, `<code>argument-rest</code>' shows that completion is looking for another
|
|
argument, the `<code>rest</code>' indicating that it is the list of arguments at
|
|
the end of the line; if position were important (see `<code>cvs import</code>' for
|
|
an example), the context would contain `<code>argument-1</code>', or whatever. The
|
|
`<code>cvs-add</code>' shows how subcommands are handled, by separating with a
|
|
hyphen instead of a colon, so as not to confuse the different bits of
|
|
the context.</p>
|
|
<p>Apart from arguments to commands and subcommands, arguments to options
|
|
are another frequent possibility; for an example of this, try typing
|
|
<code>^Xh</code> after `<code>dvips -o</code>' and you will see the context
|
|
`<code>:completion::complete:dvips:option-o-1:</code>'; this shows you are
|
|
completing the first argument to <code>dvips</code>'s <code>-o</code> option, (it only takes
|
|
one argument) which happens to be the name of a file for output.</p>
|
|
<p><span id="l155"></span></p>
|
|
<h3 id="642-tags"><a class="header" href="#642-tags">6.4.2: Tags</a></h3>
|
|
<p>Now on to the other matter to do with contexts, tags. Let's go back and
|
|
look at the output from the <code>^Xh</code> help test after the <code>cd</code> command in
|
|
full:</p>
|
|
<pre><code> tags in context :completion::complete:cd::
|
|
local-directories path-directories (_alternative _cd)
|
|
</code></pre>
|
|
<p>Unlike the contexts considered so far, which tell you how completion
|
|
arrived at the point it did, the tags describe the things it can
|
|
complete here. In this case, there are three: <code>directory-stack</code> refers
|
|
to entries such as `<code>+1</code>'; the directory stack is the set of
|
|
directories defined by using the <code>pushd</code> command, which you can see by
|
|
using the <code>dirs</code> command. Next, <code>local-directories</code> refers to
|
|
subdirectories of the current working directory, while
|
|
<code>path-directories</code> refers to any directories found by searching the
|
|
<code>$cdpath</code> array. Each of the possible completions which the system
|
|
offers belongs to one of those classes.</p>
|
|
<p>In parentheses, you see the names of the functions which were called to
|
|
generate the completions; these are what you need to change or replace
|
|
if you want to alter the basic completion behaviour. Calling functions
|
|
appear on the right and called functions on the left, so that in this
|
|
case the function `<code>_cd</code>' was the function first called to handle
|
|
arguments for the <code>cd</code> command, fitting the usual convention. Some
|
|
standard completion functions have been filtered out of this list --- it
|
|
wouldn't help you to know it had been through <code>_main_complete</code> and
|
|
<code>_complete</code>, for example.</p>
|
|
<p>Maybe it's already obvious that having the system treat different types
|
|
of completion in different ways is useful, but here's an example, which
|
|
gives you a preview of the `styles' mechanism, discussed later. Styles
|
|
are a sort of glorified shell parameter; they are defined with the
|
|
<code>zstyle</code> command, using a style name and possible values which may be an
|
|
array; you can always define a style as an array, but some styles may
|
|
simply use it as a string, joining together the arguments you gave it
|
|
with spaces. You can also use the <code>zstyle</code> command, with different
|
|
arguments, to retrieve their value, which is what the completion system
|
|
itself does; there's no actual overlap with parameters and their values,
|
|
so they don't get in the way of normal shell programming.</p>
|
|
<p>Where styles differ from parameters is that they can take different
|
|
values in different contexts. The first argument to the <code>zstyle</code> command
|
|
gives a context; when you define a style, this argument is actually a
|
|
pattern which will be matched against the current context to see if the
|
|
style applies. The rule for finding out what applies is: exact string
|
|
matches are preferred before patterns, and longer patterns are preferred
|
|
before shorter patterns. Here's that example:</p>
|
|
<pre><code> zstyle ':completion:*:cd:*' tag-order local-directories \
|
|
path-directories
|
|
</code></pre>
|
|
<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...
|
|
% cd ^D
|
|
bar/ foo/ rod/ stick/
|
|
% zstyle ':completion:*:cd:*' tag-order local-directories \
|
|
path-directories
|
|
# 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.)
|
|
If you set</p>
|
|
<pre><code> zstyle ':completion:*:-command-:*' tag-order '!parameters'
|
|
</code></pre>
|
|
<p>then the last two lines will disappear from the completion. Of course,
|
|
your completion list probably looks completely different from mine
|
|
anyway. By the way, one good thing about styles is that it doesn't
|
|
matter whether they're defined before or after completion is loaded,
|
|
since styles are stored and retrieved by another part of the shell.</p>
|
|
<p>To exclude more than one tag name, you need to include the names in the
|
|
same word. For example, to exclude both parameters and reserved words
|
|
the value would be <code>'!parameters reserved-words'</code>, and <em>not</em>
|
|
<code>'!parameters' '!reserved-words'</code>, which would try completion once with
|
|
parameters excluded, then again with reserved words excluded.
|
|
Furthermore, tags can actually be patterns, or more precisely any word
|
|
in one of the arguments to <code>tag-order</code> may contain a pattern, which will
|
|
then be tried against all the valid tags to see if it matches. It's
|
|
sometimes even useful to use `<code>*</code>' to match all tags, if you are
|
|
specifying a special form of one of the tags --- maybe using a label, as
|
|
described next --- in the same word. See the manual for all the tag
|
|
names understood by the supplied functions.</p>
|
|
<p>The <code>tag-order</code> style allows you to give tags `labels', which are a
|
|
sort of alias, instructing the completion system to use a tag under a
|
|
different name. You arrange this by giving the tag followed by a colon,
|
|
followed by the label. The label can also have a hyphen in front, which
|
|
means that the original tag name should be put in front when the label
|
|
is looked up; this is really just a way of making the names look neater.
|
|
The upshot is that by using contexts with the label name in, rather than
|
|
the tag name, you can arrange for special behaviour. Furthermore, you
|
|
can give an alternative description for the labelled tag; these show up
|
|
with the <code>format</code> style which I'll describe below (and which I
|
|
personally find very useful). You put the description after another
|
|
colon, with any spaces quoted. It would look like this:</p>
|
|
<pre><code> zstyle ':completion:*:aliens:*' tag-order \
|
|
'frooble:-funny:funny\ frooble' frooble
|
|
</code></pre>
|
|
<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><span id="l156"></span></p>
|
|
<h2 id="65-configuring-completion-using-styles"><a class="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>
|
|
<pre><code> zstyle <context> <style> <value...>
|
|
</code></pre>
|
|
<p>and some of the cases where it's useful. Before introducing other
|
|
styles, here's some more detailed information. I already said that
|
|
styles could take an array value, i.e. a set of values at the end of the
|
|
<code>zstyle</code> command corresponding to the array elements, and you've already
|
|
seen one case (<code>tag-order</code>) where that is useful. Many styles only use
|
|
one value, however. There is a particularly common case, where you
|
|
simply want to turn a value on or off, i.e. a boolean value. In this
|
|
case, you can use any of `<code>true</code>', `<code>yes</code>', `<code>on</code>' or `<code>1</code>' for on
|
|
and `<code>false</code>', `<code>no</code>', `<code>off</code>' or `<code>0</code>' for off. You define all
|
|
styles the same way; only when they're used is it decided whether they
|
|
should be a scalar, an array, or a boolean, nor is the name of a style
|
|
checked to see if it is valid, since the shell doesn't know what styles
|
|
might later be looked up. The same obviously goes for contexts.</p>
|
|
<p>You can list existing styles (not individually, only as a complete list)
|
|
using either `<code>zstyle</code>' or `<code>zstyle -L</code>'. In the second case, they are
|
|
output as the set of <code>zstyle</code> commands which would regenerate the styles
|
|
currently defined. This is also useful with <code>grep</code>, since you can easily
|
|
check all possible contexts for a particular style.</p>
|
|
<p>The most powerful way of using <code>zstyle</code> is with the option <code>-e</code>. This
|
|
says that the words you supply are to be evaluated as if as arguments to
|
|
<code>eval</code>. This should set the array <code>$reply</code> to the words to be used. So</p>
|
|
<pre><code> zstyle '*' days 'Monday Tuesday'
|
|
</code></pre>
|
|
<p>and</p>
|
|
<pre><code> zstyle -e '*' days 'reply=(Monday Tuesday)'
|
|
</code></pre>
|
|
<p>are equivalent --- but the intention, of course, is that in the second
|
|
case the argument can return a different value each time so that the
|
|
style can vary. It will usually be evaluated in the heat of completion,
|
|
hence picking up all the editing parameters; so for example</p>
|
|
<pre><code> zstyle -e ':completion:*' mystyles 'reply=(${NUMERIC:-0})'
|
|
</code></pre>
|
|
<p>will make the style return a non-zero integer (possibly indicating
|
|
<code>true</code>) if you entered a non-zero prefix argument to the command, as
|
|
described in <a href="zshguide04.html#zle">chapter 4</a>. However, the argument can
|
|
contain any zsh code whatsoever, not just a simple assignment. Remember
|
|
to quote it to prevent it from being turned into something else when the
|
|
<code>zstyle</code> command line is run.</p>
|
|
<p>Finally, you can delete a context for a style or a list of styles by</p>
|
|
<pre><code> zstyle -d [ <context-pattern> [ <style> ] ] ...
|
|
</code></pre>
|
|
<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 <a href="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><span id="l157"></span></p>
|
|
<h3 id="651-specifying-completers-and-their-options"><a class="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
|
|
order. For example,</p>
|
|
<pre><code> zstyle ':completion:*' completer _complete _correct _approximate
|
|
</code></pre>
|
|
<p>specifies that first normal completion will be tried (`<code>_complete</code>'),
|
|
then spelling correction (`<code>_correct</code>'), and finally approximate
|
|
completion (`<code>_approximate</code>'), which is essentially the combined effect
|
|
of the previous two, i.e. complete the word typed but allow for spelling
|
|
mistakes. All completers set the context, so inside <code>_complete</code> you will
|
|
usually find `<code>:completion::complete:...</code>', inside correction
|
|
`<code>:completion::correct:..</code>', and so on.</p>
|
|
<p>There's a labelling feature for completers, rather like the one for tags
|
|
described, but not illustrated in detail, above. You can put a completer
|
|
in a list like this:</p>
|
|
<pre><code> zstyle ':completion:*' completer ... _complete:comp-label ...
|
|
</code></pre>
|
|
<p>which calls the completer <code>_complete</code>, but pretends its name is
|
|
<code>comp-label</code> when looking things up in styles, so you can try completers
|
|
more than once with different features enabled. As with tags, you can
|
|
write it like `<code>_complete:-label</code>', and the normal name will be
|
|
prepended to get the name `<code>complete-label</code>' --- just a shortcut, it
|
|
doesn't introduce anything new. I'll defer an example until you know
|
|
what the completers do.</p>
|
|
<p>Here is a more detailed description of the existing completers; they are
|
|
all functions, so you can simply copy and modify one to make your own
|
|
completer.</p>
|
|
<p><strong><code>_complete</code></strong></p>
|
|
<p>This is the basic completion behaviour, which we've been assuming up to
|
|
now. Its major use is simply to check the context --- here meaning
|
|
whether we are completing a normal command argument or one of the
|
|
special `<code>-context-</code>' places --- and call the appropriate completion
|
|
function. It's possible to trick it by setting the parameter
|
|
`<code>compcontext</code>' which will be used instead of the one generated
|
|
automatically; this can be useful if you write your own completion
|
|
commands for special cases. If you do this, you should make the
|
|
parameter local to your function.</p>
|
|
<p><strong><code>_approximate</code></strong></p>
|
|
<p>This does approximate completion: it's actually written as a wrapper for
|
|
the <code>_complete</code> completer, so it does all the things that does, but it
|
|
also sets up the system to allow completions with misspellings.
|
|
Typically, you would want to try to complete without misspellings first,
|
|
so this completer usually appears after <code>_complete</code> in the <code>completers</code>
|
|
style.</p>
|
|
<p>The main means of control is via the <code>max-errors</code> style. You can set
|
|
this to the maximum number of errors to allow. An error is defined as
|
|
described in the manual for approximate pattern matching: a character
|
|
missing such as `<code>rhythm</code>' / `<code>rhytm</code>', an extra character such as
|
|
`<code>rhythm</code>' / `<code>rhythms</code>', an incorrect character such as `<code>rhythm</code>' /
|
|
`<code>rhxthm</code>', or a pair of characters transposed such as `<code>rhythm</code>'
|
|
`<code>rhyhtm</code>' each count as one error. Approximation will first try to
|
|
find a match or matches with one error, then two errors, and so on, up
|
|
to and including the value of <code>max-errors</code>; the set of matches with the
|
|
lowest number of errors is chosen, so that even if you set <code>max-errors</code>
|
|
large, matches with a lower number of errors will always be preferred.
|
|
The real problems with setting a large <code>max-errors</code> are that it will be
|
|
slower, and is more likely to generate matches completely unlike what
|
|
you want --- with typing errors, two or three are probably the most you
|
|
need. Otherwise, there's always Mavis Beacon. Hence:</p>
|
|
<pre><code> % zstyle ':completion:*' max-errors 2
|
|
# just for the sake of example...
|
|
% zstyle ':completion:*' completer _approximate
|
|
% ls
|
|
ashes sackcloth
|
|
% echo siccl<TAB>
|
|
-> echo sackcloth
|
|
% echo zicc<TAB>
|
|
<Beep.>
|
|
</code></pre>
|
|
<p>because `<code>s[i/a]c[k]cloth</code>' is only two errors, while
|
|
`<code>[z/s][i/a]c[k]cloth</code>' would be three, so doesn't complete.</p>
|
|
<p>There's another way to give a maximum number of errors, using the
|
|
numeric prefix specified with <code>ESC-<digit></code> in Emacs mode, directly with
|
|
number keys in vi command mode, or with <code>universal-argument</code>. To enable
|
|
this, you have to include the string <code>numeric</code> as one of the values for
|
|
<code>max-errors</code> --- hence this can actually be an array, e.g.</p>
|
|
<pre><code> zstyle ':completion:*:approximate:*' max-errors 2 numeric
|
|
</code></pre>
|
|
<p>allows up to two errors automatically, but you can specify a higher
|
|
maximum by giving a prefix to the completion command. So to continue the
|
|
example above, enter the new <code>zstyle</code> and:</p>
|
|
<pre><code> % echo zicc<ESC-3><TAB>
|
|
-> echo sackcloth
|
|
</code></pre>
|
|
<p>because we've allowed three errors. You can start to see the problems
|
|
with allowing too many errors: if you had the file `<code>zucchini</code>', that
|
|
would be only one error away, and would be found and inserted before
|
|
`<code>sackcloth</code>' was even considered.</p>
|
|
<p>Note that the context is examined straightaway in the completer, so at
|
|
this stage it is simply `<code>:completion::approximate:::</code>'; no more
|
|
detailed contextual information is available, so it is not possible to
|
|
specify different <code>max-errors</code> for different commands or tags.</p>
|
|
<p>The final possibility as a value for the style is `<code>not-numeric</code>': that
|
|
means if any numeric prefix is given, approximation will not be done at
|
|
all. In the last example, completion would have to find a file beginning
|
|
`<code>zicc</code>'.</p>
|
|
<p>Other minor styles also control approximation. The style <code>original</code>, if
|
|
true means the original value is always treated as a possible
|
|
completion, even if it doesn't match anything and even if nothing else
|
|
matched. Completing the original and the corrections use different tags,
|
|
unimaginatively called <code>original</code> and <code>corrections</code>, so you can organise
|
|
this with the <code>tag-order</code> style.</p>
|
|
<p>Because the completions in this case usually don't match what's already
|
|
on the command line, and may well not match each other, menu completion
|
|
is entered straight away for you to pick a completion. You can arrange
|
|
that this doesn't happen if there is an unambiguous piece at the start
|
|
to insert first by setting the boolean style <code>insert-unambiguous</code>.</p>
|
|
<p>Those last two styles (<code>original</code> and <code>insert-unambiguous</code>) are looked
|
|
up quite early on, when the context for generating corrections is being
|
|
set up, so that only the context up to the completer name is available.
|
|
The completer name will be followed by a hyphen and the number of errors
|
|
currently being accepted. So for trying approximation with one error the
|
|
context is `<code>:completion::approximate-1:::</code>'; if that fails and the
|
|
system needs to look for completion with two errors, the context will be
|
|
`<code>:completion::approximate-2:::</code>', and so on; the same happens with
|
|
correction and `<code>correct-1</code>', etc., for the completer described next.</p>
|
|
<p><strong><code>_correct</code></strong></p>
|
|
<p>This is very similar to <code>_approximate</code>, except that the context is
|
|
`<code>:completion::correct:*</code>' (or `<code>:completion::correct-<num>:*</code>' when
|
|
generating corrections, as described immediately above) and it won't
|
|
perform completion, just spelling correction, so extra characters which
|
|
the completer has to add at the end of the word on the line now count as
|
|
extra errors instead of completing in the ordinary way: <code>zicc</code> is
|
|
woefully far from <code>sackcloth</code>, seven errors, but <code>ziccloth</code> only counts
|
|
three again. The <code>_correct</code> completer is controlled in just the same way
|
|
as <code>_approximate</code>.</p>
|
|
<p>There is a separate command which only does correction and nothing else,
|
|
usually bound to `<code>^Xc</code>', so if you are happy using that you don't need
|
|
to include <code>_correct</code> in the list of completers. If you do include it,
|
|
and you also have <code>_approximate</code>, <code>_correct</code> should come earlier;
|
|
<code>_approximate</code> is bound to generate all the matches <code>_correct</code> does, and
|
|
probably more. Like other separate completion commands, it has its own
|
|
context, here beginning `<code>:completion:correct-word:</code>', so it's easy to
|
|
make this command behave differently from the normal completers.</p>
|
|
<p>Old-timers will remember that there is another form of spelling
|
|
correction built into the shell, called with `<code>ESC-$</code>' or `<code>ESC-s</code>'.
|
|
This only corrects filenames and doesn't understand anything about the
|
|
new completion mechanism; the only reason for using it is that it may
|
|
well be faster. However, if you use the <code>CORRECT</code> or <code>CORRECT_ALL</code> shell
|
|
options, you will be using the old filename correction mechanism; it's
|
|
not yet possible to alter this.</p>
|
|
<p><strong><code>_expand</code></strong></p>
|
|
<p>This actually performs expansion, not completion; the difference was
|
|
explained at the start of the chapter. If you use it, you should bind
|
|
tab to <code>complete-word</code>, not <code>expand-or-complete</code>, since otherwise
|
|
expansion will be performed before the completion mechanism is started
|
|
up. As expansion should still usually be attempted before completion,
|
|
this completer should appear before <code>_complete</code> and its relatives in the
|
|
list of values for the <code>completers</code> style.</p>
|
|
<p>The reason for using this completer instead of normal expansion is that
|
|
you can control which expansions are performed using styles in the
|
|
`<code>:completion:*:expand:*</code>' context. Here are the relevant styles:</p>
|
|
<ul>
|
|
<li><strong><code>glob</code></strong><br />
|
|
expands glob expressions, in other words does filename generation
|
|
using wildcards.</li>
|
|
<li><strong><code>substitute</code></strong><br />
|
|
expands expressions including and active `<code>$</code>' or backquotes.</li>
|
|
</ul>
|
|
<p>But remember that you need</p>
|
|
<pre><code> bindkey '^i' complete-word
|
|
</code></pre>
|
|
<p>when using this completer as otherwise the built-in expansion mechanism
|
|
which is run by the normal binding <code>expand-or-complete</code> will take over.</p>
|
|
<p>You can also control how expansions are inserted. The tags for adding
|
|
expansions are <code>original</code> (presumably self-explanatory),
|
|
<code>all-expansions</code>, which refers to adding a single string containing all
|
|
the possible expansions (the default, just like the editor function
|
|
<code>expand-word</code>), and <code>expansions</code>, which refers to the results added one
|
|
by one. By changing the order in which the tags are tried, as described
|
|
for the <code>tag-order</code> style above, you can decide how this happens. For
|
|
example,</p>
|
|
<pre><code> zstyle ':completion:*' completer _expand _complete
|
|
zstyle ':completion::expand:*' tag-order expansions
|
|
</code></pre>
|
|
<p>sets up for performing glob expansion via completion, with the
|
|
expansions being presented one by one (usually via menu completion,
|
|
since there is no common prefix). Altering <code>expansions</code> to
|
|
<code>all-expansions</code> would insert the list, as done by the normal expansion
|
|
mechanism, while altering it to `<code>expansions original</code>' would keep the
|
|
one-at-a-time entry but also present the original string as a
|
|
possibility. You can even have all three, i.e. the entire list as a
|
|
single string becomes just one of the set of possibilities.</p>
|
|
<p>There is also a <code>sort</code> style, which determines whether the expansions
|
|
generated will be sorted in the way completions usually are, or left
|
|
just as the shell produced them from the expansion (for example,
|
|
expansion of an array parameter would produce the elements in order). If
|
|
it is <code>true</code>, they will always be sorted, if <code>false</code> or unset never, and
|
|
if it is <code>menu</code> they will be sorted for the <code>expansions</code> tag, but not
|
|
for the <code>all-expansions</code> tag which will be a single string of the values
|
|
in the original order.</p>
|
|
<p>There is a slight problem when you try just to generate <code>glob</code>
|
|
expansions, without <code>substitute</code>. In fact, it doesn't take much thought
|
|
to see that an expression like `<code>$PWD/*.c</code>' doesn't mean anything if
|
|
<code>substitute</code> is inactive; it must be active to make sense of such
|
|
expressions. However, this is annoying if there are no matches: you end
|
|
up being offered a completion with the expanded <code>$PWD</code>, but `<code>*.c</code>'
|
|
still tacked on the end, which isn't what you want. If you use <code>_expand</code>
|
|
mainly for globbing, you might therefore want to set the style
|
|
<code>subst-globs-only</code> to true: if a completion just expands the parameters,
|
|
and globbing does nothing, then the expansion is rejected and the line
|
|
left untouched.</p>
|
|
<p>The <code>_expand</code> completer will also use the styles</p>
|
|
<ul>
|
|
<li><strong><code>accept-exact</code></strong><br />
|
|
applies to words beginning with a `<code>$</code>' or `<code>~</code>'. Suppose there is
|
|
a parameter `<code>$foo</code>' and a parameter `<code>$foobar</code>' and you have
|
|
`<code>$foo</code>' on the line. Normally the completion system will perform
|
|
completion at this point. However, with <code>accept-exact</code> set,
|
|
`<code>$foo</code>' will be expanded since it matches a parameter.</li>
|
|
<li><strong><code>add-space</code></strong><br />
|
|
means add a space after the expansion, as with a successful
|
|
completion --- although directories are given a `<code>/</code>' instead. For
|
|
finer control, it can be set to the word <code>file</code>, which means the
|
|
space is only added if the expanded word matches a file that already
|
|
exists (the idea being that, if it doesn't, you may want to complete
|
|
further). Both <code>true</code> and <code>file</code> may be combined with <code>subst</code>, which
|
|
prevents the adding of a space after expanding a substitution of the
|
|
form `<code>${...}</code>' or `<code>$(...)</code>'.</li>
|
|
<li><strong><code>keep_prefix</code></strong><br />
|
|
also addresses the question of whether a `<code>~</code>' or `<code>$</code>' should be
|
|
expanded. If set, the prefix will be retained, so expanding
|
|
`<code>~/f*</code>' to `<code>~/foo</code>' doesn't turn the `<code>~</code>' into `<code>/home/pws</code>'.
|
|
The default is the value `<code>changed</code>', which is a half-way house
|
|
been <code>false</code> and <code>true</code>: it means that if there was no other change
|
|
in the word, i.e. no other possible expansion was found, the `<code>~</code>'
|
|
or `<code>$</code>' will be expanded. If the effect of this style is that the
|
|
expansion is the same as the unexpanded word, the next completer in
|
|
the list after <code>_expand</code> will be tried.</li>
|
|
<li><strong><code>suffix</code></strong><br />
|
|
is similar to <code>keep_prefix</code>. The `suffix' referred to is something
|
|
after an expression beginning `<code>~</code>' or `<code>$</code>' that wouldn't be part
|
|
of that expansion. If this style is set, and such a suffix exists,
|
|
the expansion is not performed. So, for example, `<code>~pw<TAB></code>' can
|
|
be expanded to `<code>~pws</code>', but `<code>~pw/</code>' is not eligible for
|
|
expansion; likewise `<code>$fo</code>' and `<code>$fo/</code>'. This style defaults to
|
|
<code>true</code> --- so if you want <code>_expand</code> always to expand such
|
|
expressions, you will need to set it to <code>false</code> yourself.</li>
|
|
</ul>
|
|
<p>An easier way of getting the sort of control over expansion which the
|
|
<code>_expand</code> completer provides is with the <code>_expand_word</code> function,
|
|
usually bound to <code>\C-xe</code>, which does all the things described above
|
|
without getting mixed up with the other completers. In this case the
|
|
context string starts `<code>:completion:expand-word</code>', so you can have
|
|
different styles for this than for the <code>_expand</code> completer.</p>
|
|
<p>Setting different priorities for expansion is one good use for completer
|
|
labels, for example</p>
|
|
<pre><code> zstyle ':completion:*' completer _expand:-glob _expand:-subst
|
|
zstyle ':completion:*:expand-glob:*' glob yes
|
|
zstyle ':completion:*:expand-subst:*' substitute yes
|
|
</code></pre>
|
|
<p>is the basic set up to make <code>_expand</code> try glob completions and failing
|
|
that do substitutions, presenting the results as an expansion. You would
|
|
almost certainly want to add details to help this along.</p>
|
|
<p><strong><code>_history</code></strong></p>
|
|
<p>This completes words from the shell's history, in other words everything
|
|
you typed or had completed or expanded on previous lines. There are
|
|
three styles that affect it, <code>sort</code> and <code>remove-all-dups</code>; they are
|
|
described for the command widget <code>_history_complete_word</code> below. That
|
|
widget essentially performs the work of this completer as a special
|
|
keystroke.</p>
|
|
<p><strong><code>_prefix</code></strong></p>
|
|
<p>Strictly, this completer doesn't do completion itself, and should hence
|
|
be in the group below starting with <code>_match</code>. However, it <em>seems</em> to do
|
|
completion... Let me explain.</p>
|
|
<p>Many shells including zsh have the facility to complete only the word
|
|
before the cursor, which zsh completion jargon refers to as the
|
|
`prefix'. I explained this above when I talked about
|
|
<code>expand-or-complete-prefix</code>; when you use that instead of the normal
|
|
completion functions, the word as it's finally completed looks like
|
|
`<code><prefix><completion><suffix></code>' where the completion has changed
|
|
`<code><prefix></code>' to `<code><prefix><completion></code>', ignoring <code><suffix></code>
|
|
throughout.</p>
|
|
<p>The <code>_prefix</code> completer lets you do this as part of normal completion.
|
|
What happens is that the completers are evaluated as normal, from left
|
|
to right, until a completion is found. If <code>_prefix</code> is reached,
|
|
completion is then attempted just on the prefix. So if your completers
|
|
are `<code>_complete _prefix</code>', the shell will first try completion on the
|
|
whole word, prefix and suffix, then just on the prefix. Only the first
|
|
`real' completer (<code>_complete</code>, <code>_approximate</code>, <code>_correct</code>, <code>_expand</code>,
|
|
<code>_history</code>) is used.</p>
|
|
<p>You can try prefix completion more than once simply by including
|
|
<code>_prefix</code> more than once in the list of completers; the second time, it
|
|
will try the second `real' completer in the list; so if they are
|
|
`<code>_complete _prefix _correct _prefix</code>', you will get first ordinary
|
|
completion, then the same for the prefix only, then ordinary correction,
|
|
then the same for the prefix only. You can move either of the <code>_prefix</code>
|
|
completers to the point in the sequence where you want the prefix-only
|
|
version to be tried.</p>
|
|
<p>The <code>_prefix</code> completer will re-look up the <code>completer</code> style. This
|
|
means that you can use a non-default set of completers for use just with
|
|
<code>_prefix</code>. Here, as described in the manual, is how to force <code>_prefix</code>
|
|
only to be used as a last resort, and only with normal completion:</p>
|
|
<pre><code> zstyle ':completion:::::' completer _complete \
|
|
<other-completers> _prefix
|
|
zstyle ':completion::prefix:::' completer _complete
|
|
</code></pre>
|
|
<p>The full contexts are shown, just to emphasise the form; as always, you
|
|
can use wildcards if you don't care. In a case like this, you can use
|
|
<em>only</em> <code>_prefix</code> as the completer, and completion including the suffix
|
|
would never be tried; you then have to make sure you have the
|
|
<code>completer</code> style for the <code>prefix</code> context, however, or no completion at
|
|
all will be done.</p>
|
|
<p>The completer labelling trick is again useful here: you can call
|
|
<code>_prefix</code> more than once, wherever you choose in your list of
|
|
completers, and force it to look up in a different context each time.</p>
|
|
<pre><code> zstyle ':completion:*' completer _complete _prefix:-complete \
|
|
_approximate _prefix:-approximate
|
|
zstyle ':completion:*:prefix-complete:*' completer _complete
|
|
zstyle ':completion:*:prefix-approximate:*' completer _approximate
|
|
</code></pre>
|
|
<p>This tries ordinary completion, then the same for the prefix only, then
|
|
approximation, then the same for the prefix only. As mentioned in the
|
|
previous paragraph, it is perfectly legitimate to leave out the raw
|
|
<code>_complete</code> and <code>_approximate</code> completers and just use the forms with
|
|
the <code>_prefix</code> prefix.</p>
|
|
<p>One gotcha with the <code>_prefix</code> completer: you have to make sure the
|
|
option <code>COMPLETE_IN_WORD</code> is set. That may sound counter-intuitive:
|
|
after all, <code>_prefix</code> forces completion <em>not</em> to complete inside a word.
|
|
The point is that without that option, completion is only ever tried at
|
|
the end of the word, so when you type <code><TAB></code> in the middle of
|
|
<code><prefix><suffix></code>, the cursor is moved to after the end of the suffix
|
|
before the completion system has a chance to see what's there, and hence
|
|
the whole thing is regarded as a prefix, with no suffix.</p>
|
|
<p>There's one more style used with <code>_prefix</code>: `<code>add-space</code>'. This makes
|
|
<code>_prefix</code> add a real, live space when it completes the prefix, instead
|
|
of just pretending there was one there, hence separating the completed
|
|
word from the original suffix; otherwise it would simply leave the
|
|
resulting word all joined together, as <code>expand-or-complete-prefix</code>
|
|
usually does.</p>
|
|
<p><strong><code>_ignored</code></strong></p>
|
|
<p>Like <code>_prefix</code> this is a bit of a hybrid, mopping up after completions
|
|
which have already been generated. It allows you to have completions
|
|
which have already been rejected by the style `<code>ignored-patterns</code>'.
|
|
I'll describe that below, but it's effect is very simple: for the
|
|
context given, the list of patterns you specify are matched against
|
|
possible completions, and any that match are removed from the list. The
|
|
<code>_ignored</code> completer allows you to retrieve those removed completions
|
|
later in your completer list, in case nothing else matched.</p>
|
|
<p>This is used by the <code>$fignore</code> mechanism --- a list of suffixes of files
|
|
not normally to be completed --- which is actually built on top of
|
|
<code>ignored-patterns</code>, so if you use that in the way familiar to current
|
|
zsh users, where the ignored matches are shown if there are no unignored
|
|
matches, you need the <code>_ignored</code> completer in your completer list.</p>
|
|
<p>One slightly annoying feature with <code>_ignored</code> is if there is only a
|
|
single possible completion, since it will then be unconditionally
|
|
inserted. Hardly a surprise, but it can be annoying if you really don't
|
|
want that choice. There is a style <code>single-ignored</code> which you can set to
|
|
<code>show</code> --- just show the single ignored match, don't insert it --- or to
|
|
<code>menu</code> --- go to menu completion so that TAB cycles you between the
|
|
completion which <code>_ignored</code> produced and what you originally typed. The
|
|
latter gives a very natural way of handling ignored files; it's sort of
|
|
saying `well, I found this but you might not like it, so hit tab again
|
|
if you want to go back to what you had before'.</p>
|
|
<p>I said this was like <code>_prefix</code>, and indeed you can specify which
|
|
completers are called for the <code>_ignored</code> completer in just the same way,
|
|
by giving the <code>completer</code> style in the context
|
|
`<code>:completion:*:ignored:*</code>'. That means my description has been a
|
|
little over-simplified: <code>_ignored</code> doesn't really use the completions
|
|
which were ignored before; rather, when it's called it generates a list
|
|
of possibilities where the choices matched by <code>ignore-patterns</code> --- or
|
|
internally using <code>$fignore</code> --- are not ignored. So it should really be
|
|
called `<code>_not_ignored</code>', but it isn't.</p>
|
|
<p><strong><code>_match</code></strong></p>
|
|
<p>This and the remaining completers are utilities, which affect the main
|
|
completers given above when put into the completion list rather than
|
|
doing completion themselves.</p>
|
|
<p>The <code>_match</code> completer should appear <em>after</em> <code>_complete</code>; it is a more
|
|
flexible form of the <code>GLOB_COMPLETE</code> option. In other words, if
|
|
<code>_complete</code> didn't succeed, it will try to match the word on the line as
|
|
a pattern, not just a fixed string, against the possible completions. To
|
|
make it work like normal completion, it usually acts as if a `<code>*</code>' was
|
|
inserted at the cursor position, even if the word already contains
|
|
wildcards.</p>
|
|
<p>You can control the addition of `<code>*</code>' with the `<code>match-original</code>'
|
|
style; the normal behaviour occurs if this is unset. If it is set to
|
|
`<code>only</code>', the `<code>*</code>' is not inserted, and if it is `<code>true</code>', or
|
|
actually any other string, it will try first without the `<code>*</code>', then
|
|
with. For example, consider typing `<code>setopt c*ect<TAB></code>' with the
|
|
<code>_match</code> completer in use. Normally this will produce two possibilities,
|
|
`<code>correct</code>' and `<code>correctall</code>'. After setting the style,</p>
|
|
<pre><code> zstyle ':completion::match:*' original only
|
|
</code></pre>
|
|
<p>no `<code>*</code>' would be inserted at the place where you hit `<code>TAB</code>', so that
|
|
`<code>correct</code>' is the only possible match.</p>
|
|
<p>The <code>_match</code> completer uses the style <code>insert-unambiguous</code> in just the
|
|
same way as does <code>_approximate</code>.</p>
|
|
<p><strong><code>_all_matches</code></strong></p>
|
|
<p>This has a similar effect to performing expansion instead of completion:
|
|
all the possible completions are inserted onto the command line.
|
|
However, it uses the results of ordinary contextual completion to
|
|
achieve this. The normal way that the completion system achieves this is
|
|
by influencing the behaviour of any subsequent completers which are
|
|
called --- hence you will need to put <code>_all_matches</code> in the list of
|
|
completers before any which you would like to have this behaviour.</p>
|
|
<p>You're unlikely to want to do this with every type of completion, so
|
|
there are two ways of limiting its effect. First, there is the
|
|
<code>avoid-completer</code> style: you can set this to a list of completers which
|
|
should <em>not</em> insert all matches, and they will be handled normally.</p>
|
|
<p>Then there is the style <code>old-matches</code>. This forces <code>_all_matches</code> to use
|
|
an existing list of matches, if it exists, rather than what would be
|
|
generated this time round. You can set the style to <code>only</code> instead of
|
|
true; in this case <code>_all_matches</code> will never apply to the completions
|
|
which would be generated this time round, it will only use whatever list
|
|
of completions already exists.</p>
|
|
<p>This can be a nuisance if applied to normal completion generation ---
|
|
the usual list would never be generated, since <code>_all_matches</code> would just
|
|
insert the non-existent list from last time --- so the manual recommends
|
|
two other ways of using the completer with this style. First, you can
|
|
add a condition to the use of the style:</p>
|
|
<pre><code> zstyle -e ':completion:*' old-matches 'reply=(${NUMERIC:-false})'
|
|
</code></pre>
|
|
<p>This returns false unless there is a non-zero numeric argument; if you
|
|
type <code><ESC>1</code> in emacs mode, or just <code>1</code> in vi mode, before completion,
|
|
it will insert all the values generated by the immediately preceding
|
|
completion.</p>
|
|
<p>Otherwise, you can bind <code>_all_matches</code> separately. This is probably the
|
|
more useful; copying the manual entry:</p>
|
|
<pre><code> zle -C all-matches complete-word _generic
|
|
bindkey '^Xa' all-matches
|
|
zstyle ':completion:all-matches:*' completer _all_matches
|
|
zstyle ':completion:all-matches:*' old-matches only
|
|
</code></pre>
|
|
<p>Here we generate ourselves a new completion based on the <code>complete-word</code>
|
|
widget, called <code>all-matches</code> --- this name is arbitrary but convenient.
|
|
We bind that to the keystroke <code>^Xa</code>, and give it two special styles
|
|
which normal completion won't see. For the <code>completer</code> we set just
|
|
<code>_all_matches</code>, and for <code>old-matches</code> we set <code>only</code>; the effect is that
|
|
<code>^Xa</code> will only ever have the effect of inserting all the completions
|
|
which were generated by the last completion, whatever that was --- it
|
|
does not have to be an ordinary contextual completion, it may be the
|
|
result of any completion widget.</p>
|
|
<p><strong><code>_list</code></strong></p>
|
|
<p>If you have this in the list of completers (at the beginning is as good
|
|
as anything), then the first time you try completion, you only get a
|
|
list; nothing changes, not even a common prefix is inserted. The second
|
|
time, completion continues as normal. This is like typing <code>^D</code>, then
|
|
tab, but using just the one key. This differs from the usual <code>AUTO_LIST</code>
|
|
behaviour in that is entirely irrespective of whether the completion is
|
|
ambiguous; you always get the list the first time, and it always does
|
|
completion in the usual way the second time.</p>
|
|
<p>The <code>_list</code> completer also uses the <code>condition</code> style, which works a bit
|
|
like the styles for the <code>_expand</code> completer: it must be set to one of
|
|
the values corresponding to `true' for the <code>_list</code> delaying behaviour
|
|
to take effect. You can test for a particular value of <code>$NUMERIC</code> or any
|
|
other condition by using the <code>-e</code> option of <code>zstyle</code> when defining the
|
|
style.</p>
|
|
<p>Finally, the boolean style <code>word</code> is also relevant. If false or unset,
|
|
<code>_list</code> examines the whole line when deciding if it has changed, and
|
|
hence completion should be delayed until the next keypress. If true, it
|
|
just examines the current word. Note that <code>_list</code> has no knowledge of
|
|
what happens between those completion calls; looking at the command line
|
|
is its only resource.</p>
|
|
<p><strong><code>_menu</code></strong></p>
|
|
<p>This just implements menu completion in shell code; it should come
|
|
before the `real' completion generators in the <code>completers</code> style. It
|
|
ignores the <code>MENU_COMPLETION</code> option and other related options and the
|
|
normal menu-completion widgets don't work well with it. However, you can
|
|
copy it and write your own completers.</p>
|
|
<p><strong><code>_oldlist</code></strong></p>
|
|
<p>This completer is most useful when you are in the habit of using special
|
|
completion functions, i.e. commands other than the standard completion
|
|
system. It is able to hang onto an old completion list which would
|
|
otherwise be replaced with a newly generated one. There are two aspects
|
|
to this.</p>
|
|
<p>First, listing. Suppose you try to complete something from the shell
|
|
history, using the command bound to `<code>ESC-/</code>'. For example, I typed
|
|
`<code>echo ma<ESC-/></code>' and got `<code>max-errors</code>'. At this point you might
|
|
want to list the possible completions. Unfortunately, if you type <code>^D</code>,
|
|
it will simply list all the usual contextual completions --- for the
|
|
<code>echo</code> command, which is not handled specially, these are simply files.
|
|
So it doesn't work. By putting the <code>_oldlist</code> completer into the
|
|
<code>completers</code> style <em>before</em> <code>_complete</code>, it does work, because the old
|
|
list of matches is kept for <code>^D</code> to use.</p>
|
|
<p>In this case, you can force old-listing on or off by setting the
|
|
<code>old-list</code> style to <code>always</code> or <code>never</code>; usually it shows the listing
|
|
for the current set of completions if that isn't already displayed, and
|
|
otherwise generates the standard listing. You can even set the value of
|
|
<code>old-list</code> to a list of completers which will always have their list
|
|
kept in this way.</p>
|
|
<p>The other place where <code>_oldlist</code> is useful is in menu completion, where
|
|
exactly the same problem occurs: if you generate a menu from a special
|
|
command, then try to cycle through by hitting tab, completion will look
|
|
for normal contextual matches instead. There's a way round this time ---
|
|
use the special command key repeatedly instead of tab. This is rather
|
|
tedious with multiple key sequences. Again, <code>_oldlist</code> cures this, and
|
|
again you can control the behaviour with a style, <code>old-menu</code>, which
|
|
takes a boolean value (it is on by default). As Orwell put it,
|
|
oldlisters unbellyfeel menucomp.</p>
|
|
<p><strong>Ordering completers</strong></p>
|
|
<p>I've given various suggestions about the order in which completers
|
|
should come in, which might be confusing. Here, therefore, is a
|
|
suggested order; just miss out any completers you don't want to use:</p>
|
|
<pre><code> _all_matches _list _oldlist _menu _expand _complete _match
|
|
_ignored _correct _approximate _prefix
|
|
</code></pre>
|
|
<p>Other orders are certainly possible and maybe even useful: for example,
|
|
the <code>_all_matches</code> completer applies to all the completers following not
|
|
listed in the <code>avoid-completer</code> style, so you might have good reason to
|
|
shift it further down the list.</p>
|
|
<p>Here's my example of labels for completers, which I mentioned just above
|
|
the list of different completers, whereby completers can be looked up
|
|
under different names.</p>
|
|
<pre><code> zstyle ':completion:*' completer _complete _approximate:-one \
|
|
_complete:-extended _approximate:-four
|
|
zstyle ':completion:*:approximate-one:*' max-errors 1
|
|
zstyle ':completion:*:complete-extended:*' \
|
|
matcher 'r:|[.,_-]=* r:|=*'
|
|
zstyle ':completion:*:approximate-four:*' max-errors 4
|
|
</code></pre>
|
|
<p>This tries the following in order.</p>
|
|
<ol>
|
|
<li>Ordinary, no-frills completion.</li>
|
|
<li>Approximation with one error, as given by the second style.</li>
|
|
<li>Ordinary completion with extended completion turned on, as given by
|
|
the third style. Sorry, this will be a black box until I talk about
|
|
the <code>matcher</code> style later on; for now, you'll just have to take my
|
|
word for it that this style allows the characters in the square
|
|
brackets to have a wildcard in front, so `<code>a-b</code>' can complete to
|
|
`<code>able-baker</code>', and so on.</li>
|
|
<li>Approximation with up to four errors, as given by the final style.</li>
|
|
</ol>
|
|
<p>Here's a rather bogus example. You have a directory containing:</p>
|
|
<pre><code> foobar fortified-badger frightfully-barbaric
|
|
</code></pre>
|
|
<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><span id="l158"></span></p>
|
|
<h3 id="652-changing-the-format-of-listings-groups-etc"><a class="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><strong><code>group-name</code>, <code>group-order</code></strong></p>
|
|
<p>In the <code>format</code> example just above, you may have wondered if it is
|
|
possible to make the different types of completion appear separately,
|
|
together with the description. You can do this using <em>groups</em>. They are
|
|
also related to tags, although as you can define group names via the
|
|
<code>group-name</code> style it is possible to give different names for completion
|
|
in any context. However, to start off with it is easiest to give the
|
|
value of the style an empty string, which means that group names are
|
|
just the names of the tags. In other words,</p>
|
|
<pre><code> zstyle ':completion:*' group-name ''
|
|
</code></pre>
|
|
<p>assigns a different group name for each tag. Later, you can fine-tune
|
|
this with more specific patterns, if you decide you want various tags to
|
|
have the same group name. If no group name is defined, the group used is
|
|
called `<code>-default-</code>', so this is what was happening before you issued
|
|
the <code>zstyle</code> command above; all matches were in that group.</p>
|
|
<p>The reason for groups is this: matches in the same group are shown
|
|
together, matches in different groups are shown separately. So the
|
|
completion list from the previous example, with both the <code>format</code> and
|
|
<code>group-name</code> styles set, becomes:</p>
|
|
<pre><code> Completing external command
|
|
cdctrl cddbsubmit cdparanoia cdrecord
|
|
cdda2wav cdecl cdparanoia-yaf
|
|
cddaslave cdot cdplay
|
|
cddbslave cdp cdplayer_applet
|
|
Completing builtin command
|
|
cd
|
|
Completing shell function
|
|
cdmatch cdmatch.newer cdswap
|
|
</code></pre>
|
|
<p>which you may find more helpful, or you may find messier, depending on
|
|
deep psychological factors outside my control.</p>
|
|
<p>If (and only if) you are using <code>group-name</code>, you can also use
|
|
<code>group-order</code>. As its name suggests, it determines the order in which
|
|
the different completion groups are displayed. It's a little like
|
|
<code>tag-order</code>, which I described when tags were first introduced: the
|
|
value is just a set of names of groups, in the order you want to see
|
|
them. The example from the manual is relevant to the listing I just
|
|
showed:</p>
|
|
<pre><code> zstyle ':completion:*:-command-' group-order \
|
|
builtins functions commands
|
|
</code></pre>
|
|
<p>--- remember that the `<code>-command-</code>' context is used when the names of
|
|
commands, rather than their arguments, are being completed. Not
|
|
surprisingly, that listing now becomes:</p>
|
|
<pre><code> Completing builtin command
|
|
cd
|
|
Completing shell function
|
|
cdmatch cdmatch.newer cdswap
|
|
Completing external command
|
|
cdctrl cddbsubmit cdparanoia cdrecord
|
|
cdda2wav cdecl cdparanoia-yaf
|
|
cddaslave cdot cdplay
|
|
cddbslave cdp cdplayer_applet
|
|
</code></pre>
|
|
<p>and if you investigate the tags available by using <code>^Xh</code>, you'll see
|
|
that there are others such as aliases whose order we haven't defined.
|
|
These appear after the ones for which you have defined the order and in
|
|
some order decided by the function which generated the matches.</p>
|
|
<p><strong><code>tag-order</code></strong></p>
|
|
<p>As I already said, I've already described this, but it's here again for
|
|
completeness.</p>
|
|
<p><strong><code>verbose</code>, <code>auto-description</code></strong></p>
|
|
<p>These are relatives of <code>format</code> as they add helpful messages to the
|
|
listing. If <code>verbose</code> is true, the function generating the matches may,
|
|
at its discretion, decide to show more information about them. The most
|
|
common case is when describing options; the standard function
|
|
<code>_describe</code> that handles descriptions for a whole lot of options tests
|
|
the <code>verbose</code> style and will print information about the options it is
|
|
completing.</p>
|
|
<p>You can also set the string style <code>auto-description</code>; it too is useful
|
|
for options, in the case that they don't have a special description, but
|
|
they do have a single following argument, which completion already knows
|
|
about. Then the description of the argument for verbose printing will be
|
|
available as `<code>%d</code>' in <code>auto-describe</code>, so that something like the
|
|
manual recommendation `<code>specify: %d</code>' will document the option itself.
|
|
So if a command takes `<code>-o <output-file></code>' and the argument has the
|
|
description `<code>output file</code>', the `<code>-o</code>', when it appears as a possible
|
|
completion, will have the description `<code>specify: output file</code>' if it
|
|
does not have its own description. In fact, most options recognized by
|
|
the standard completion functions already have their own descriptions
|
|
supplied, and this is more subtlety than most people will probably need.</p>
|
|
<p><strong><code>list-colors</code></strong></p>
|
|
<p>This is used to display lists of matches for files in different colours
|
|
depending on the file type. It is based on the syntax of the
|
|
<code>$LS_COLORS</code> environment variable, used by the GNU version of <code>ls</code>. You
|
|
will need a terminal which is capable of displaying colour such as a
|
|
colour xterm, and should make sure the <code>zsh/complist</code> library is loaded,
|
|
(it should be automatically if you are using menu selection set up with
|
|
the <code>menu</code> style, or if you use this style). But you can make sure
|
|
explicitly:</p>
|
|
<pre><code> zmodload -i zsh/complist
|
|
</code></pre>
|
|
<p>The <code>-i</code> keeps it quiet if the module was already loaded. To install a
|
|
standard set of default colours, you can use:</p>
|
|
<pre><code> zstyle ':completion:*' list-colors ''
|
|
</code></pre>
|
|
<p>--- note the use of the `<code>default</code>' tag --- since a null string sets
|
|
the value to the default.</p>
|
|
<p>If that's not good enough for you, here are some more detailed
|
|
instructions. The parameter <code>$ZLS_COLORS</code> is the lowest-level part of
|
|
the system used by <code>zsh/complist</code>. There is a simple builtin default,
|
|
while having the style set to the empty string is equivalent to:</p>
|
|
<pre><code> ZLS_COLORS="no=00:fi=00:di=01;34:ln=01;36:\
|
|
pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:\
|
|
ex=01;32:lc=\e[:rm=m:tc=00:sp=00:ma=07:hi=00:du=00
|
|
</code></pre>
|
|
<p>It has essentially the same format as <code>$LS_COLORS</code>, and indeed you can
|
|
get a more useful set of values by using the <code>dircolors</code> command which
|
|
comes with <code>ls</code>:</p>
|
|
<pre><code> ZLS_COLORS="no=00:fi=00:di=01;34:ln=01;36:\
|
|
pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:\
|
|
or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:\
|
|
*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:\
|
|
*.z=01;31:*.Z=01;31:*.gz=01;31:*.deb=01;31:\
|
|
*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.ppm=01;35:\
|
|
*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:\
|
|
*.mpg=01;37:*.avi=01;37:*.gl=01;37:*.dl=01;37:"
|
|
</code></pre>
|
|
<p>You should see the manual for the <code>zsh/complist</code> module for details, but
|
|
note in particular the addition of the type `<code>ma</code>', which specifies how
|
|
the current match in menu selection is displayed. The default for that
|
|
is to use standout mode --- the same effect as the sequence <code>%S</code> in a
|
|
prompt, which you can display with `<code>print -P %Sfoo</code>'.</p>
|
|
<p>However, you need to define the style directly, since the completion
|
|
always uses that to set <code>$ZLS_COLORS</code>; otherwise it doesn't know whether
|
|
the value it has found has come from the user or is a previous value
|
|
taken from some style. That takes this format:</p>
|
|
<pre><code> zstyle ':completion:*' list-colors "no=00" "fi=00" ...
|
|
</code></pre>
|
|
<p>You can use an already defined <code>$LS_COLORS</code>:</p>
|
|
<pre><code> zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
|
|
</code></pre>
|
|
<p>(which splits the parameter to an array on colons) as <code>$LS_COLORS</code> is
|
|
still useful for <code>ls</code>, even though it's not worth setting <code>$ZLS_COLORS</code>
|
|
directly. This should mean GNU ls and zsh produce similar-looking lists.</p>
|
|
<p>There are some special effects allowed. You can use patterns to tell how
|
|
filenames are matched: that's part of the default behaviour, in fact,
|
|
for example '*.tar=01;31' forces tar files to be coloured red. In that
|
|
case, you are limited to `<code>*</code>' followed by a string. However, there's a
|
|
way of specifying colouring for any match, not just files, and for any
|
|
pattern: use <code>=<pat>=<col></code>. Here are two ways of getting jobs coloured
|
|
red in process listings for the `<code>kill</code>' command.</p>
|
|
<pre><code> zstyle ':completion:*:*:kill:*' list-colors '=%*=01;31'
|
|
</code></pre>
|
|
<p>This uses the method just described; jobs begin with `<code>%</code>'.</p>
|
|
<pre><code> zstyle ':completion:*:*:kill:*:jobs' list-colors 'no=01;31'
|
|
</code></pre>
|
|
<p>This uses the tag, rather than the pattern, to match the jobs lines. It
|
|
has various advantages. Because you are using the tag, it's much easier
|
|
to alter this for all commands using jobs, not just kill --- just miss
|
|
out `<code>kill</code>' from the string. That wasn't practical with the other
|
|
method because it would have matched too many other things you didn't
|
|
want. You're not dependent on using a particular pattern, either. And
|
|
finally, if you try it with a `<code>format</code>' description you'll see that
|
|
that gets the colour, too, since it matched the correct tag. Note the
|
|
use of the `<code>no</code>' to specify that this is to apply for a normal match;
|
|
the other two-letter codes for file types aren't useful here.</p>
|
|
<p>However, there is one even more special effect you can use with the
|
|
general pattern form. By turning on `backreferences' with `<code>(#b)</code>'
|
|
inside the pattern, parentheses are active and the bits they match can
|
|
be coloured separately. You do this by extending the list of colours,
|
|
each code preceded by an `<code>=</code>' sign, and the extra elements will be
|
|
used to colour what the parenthesis matched. Here's another example for
|
|
`<code>kill</code>', which turns the process number red, but leaves the rest
|
|
alone.</p>
|
|
<pre><code> zstyle ':completion:*:*:kill:*:processes' list-colors \
|
|
'=(#b) #([0-9]#)*=0=01;31'
|
|
</code></pre>
|
|
<p>The hieroglyphics are extended globbing patterns. You should note that
|
|
the <code>EXTENDED_GLOB</code> option is always on inside styles --- it's required
|
|
for the `<code>#b</code>' to take effect. In particular, `<code>#</code>' means `zero or
|
|
more repetitions of the previous bit of the pattern' with extended glob
|
|
patterns; see the globbing manual page for full details.</p>
|
|
<p><strong><code>ignored-patterns</code></strong></p>
|
|
<p>Many shells, including zsh, have a parameter <code>$fignore</code>, which gives a
|
|
list of suffixes; filenames ending in any of these are not to be used in
|
|
completion. A typical value is:</p>
|
|
<pre><code> fignore=(.o \~ .dvi)
|
|
</code></pre>
|
|
<p>so that normal file completion will not produce object files, EMACS
|
|
backup files, or TeX DVI files.</p>
|
|
<p>The <code>ignored-patterns</code> style is an extension of this. It takes an array
|
|
value, like <code>fignore</code>, but with various differences. Firstly, these
|
|
values are patterns which should match the <em>whole</em> value to be
|
|
completed, including prefixes (such as the directory part of a filename)
|
|
as well as suffixes. Secondly, they apply to <em>all</em> completions, not just
|
|
files, since you can use the style mechanism to tune it to apply
|
|
wherever you want, down to particular tags.</p>
|
|
<p>Hence you can replace the use of <code>$fignore</code> above with the following:</p>
|
|
<pre><code> zstyle ':completion:*:files' ignored-patterns '*?.o' '*?~' '*?.dvi'
|
|
</code></pre>
|
|
<p>for completion contexts where the tag `<code>files</code>' is in use. The extra
|
|
`<code>?</code>'s are because <code>$fignore</code> was careful only to apply to real
|
|
suffixes, i.e. strings which had something in front of them, and the
|
|
`<code>?</code>' forces there to be at least one character present.</p>
|
|
<p>Actually, this isn't quite the same as <code>$fignore</code>, since there are other
|
|
file tags than <code>files</code>; apart from those for directories, which you've
|
|
already met, there are <code>globbed-files</code> and <code>all-files</code>. The former is
|
|
for cases where a pattern is specified by the completion function, for
|
|
example `<code>*.dvi</code>' for files following the command name <code>dvips</code>. These
|
|
don't use this style, because the pattern was already sufficiently
|
|
specified. This follows the behaviour for <code>$fignore</code> in the old
|
|
completion system. Another slight difference, as I said above when
|
|
discussing the <code>_ignored</code> completer, is that you get to choose whether
|
|
you want to see those ignored files if the normal completions fail, by
|
|
having <code>_ignored</code> in the completer list or not.</p>
|
|
<p>The other tag, <code>all-files</code>, applies when a <code>globbed-files</code> tag failed,
|
|
and says any old file is good enough in that case; you can arrange how
|
|
this happens with the <code>tag-order</code> style. In this example,</p>
|
|
<pre><code> zstyle ':completion:*:*:dvips:argument*' \
|
|
tag-order globbed-files all-files
|
|
</code></pre>
|
|
<p>is enough to say that you want to see all files if no files were
|
|
produced from the pattern, i.e. if there were no `<code>*.dvi</code>' files in the
|
|
directory. Finally the point of this ramble: as the <code>all-files</code> tag is
|
|
separate from the <code>files</code> tag, in this case you really would see all
|
|
files (except for those beginning with a `<code>.</code>', as usual). You might
|
|
find this useful, but you can easily make the <code>all-files</code> tag behave the
|
|
same way as <code>files</code>:</p>
|
|
<pre><code> zstyle ':completion:*:(all-|)files' ignored-patterns ...
|
|
</code></pre>
|
|
<p>Here's the example of using tag labels I promised earlier; it's simply
|
|
taken from the manual. To refresh your memory: tag labels are a way of
|
|
saying that tags should be looked up under a different name. Here we'll
|
|
do:</p>
|
|
<pre><code> zstyle ':completion:*:*:-command-:*' tag-order 'functions:-non-comp'
|
|
</code></pre>
|
|
<p>This applies in command position, from the special `<code>-command-</code>'
|
|
context, the place where functions occur most often, along with other
|
|
types of command which have their own tags. This says that when
|
|
functions are first looked up, they are to be looked up with the name
|
|
`<code>functions-non-comp</code>' --- remember that with a hyphen as the first
|
|
character of the label part, the bit after the colon, the <code>functions</code>
|
|
tag name itself, the bit before the colon, is to be stuck in front to
|
|
give the full label name `<code>functions-non-comp</code>'. We can use it as
|
|
follows:</p>
|
|
<pre><code> zstyle ':completion:*:functions-non-comp' ignored-patterns '_*'
|
|
</code></pre>
|
|
<p>In the context of this tag label, we have told completion to ignore any
|
|
patterns --- i.e. any function names --- beginning with an underscore.
|
|
What happens is this: when we try completion in command position,
|
|
<code>tag-order</code> is looked up and finds we want to try functions first, but
|
|
under the name <code>functions-non-comp</code>; this completes functions apart from
|
|
ones beginning with an underscore (presumably completion functions you
|
|
don't want to run interactively). Since <code>tag-order</code> normally tries all
|
|
the other tags, unless it was told not to, in this case all the normal
|
|
command completions will appear, including functions under their normal
|
|
tag name, so this just acts as a sort of filter for the first attempt at
|
|
completion. This is typically what tag labels are intended for ---
|
|
though maybe you can think up a lot of other uses, since the idea is
|
|
quite powerful, being backed up by the style mechanism.</p>
|
|
<p>You way wonder why you would want to ignore such functions at this
|
|
point. After all, you're only likely to be doing completion when you've
|
|
already typed the first character, which either is `<code>_</code>' or it isn't.
|
|
It becomes useful with correction and approximation --- particularly
|
|
since many completion functions are similar to the names of the commands
|
|
for which they handle completion. You don't want to be offered
|
|
`<code>_zmodload</code>' as a completion if you really want `<code>zmodload</code>'. The
|
|
combination of labels and ignored patterns does this for you.</p>
|
|
<p>You can generalise this using another feature: tags can actually be
|
|
patterns, which I mentioned but didn't demonstrate. Here's a more
|
|
sophisticated version of the previous example, adapted from the manual:</p>
|
|
<pre><code> zstyle ':completion:*:*:-command-:*' tag-order \
|
|
'functions:-non-comp:non-completion\ functions *' functions
|
|
</code></pre>
|
|
<p>It's enhanced so that completion tries all other possible tags at the
|
|
same time as the labelled <code>functions</code>. However, it only ever tries a tag
|
|
once at each step, so the `<code>*</code>' doesn't put back <code>functions</code> as you
|
|
might expect --- that's still tried under the label
|
|
`<code>functions-non-comp</code>', and the <code>ignored-patterns</code> style we set will
|
|
still work. In the final word, we try all possible functions, so that
|
|
those beginning with an underscore will be restored.</p>
|
|
<p>Use of the `<code>_ignored</code>' completer can allow you to play tricks without
|
|
having to label your tags:</p>
|
|
<pre><code> zstyle ':completion:*' completer _complete _ignored
|
|
zstyle ':completion:*:functions' ignored-patterns '_*'
|
|
</code></pre>
|
|
<p>Now anywhere the <code>functions</code> tag is valid, functions matching `<code>_*</code>'
|
|
aren't shown until completion reaches the `<code>_ignored</code>' in the completer
|
|
list. Of course, you should manipulate the completer list the way you
|
|
want; this just shows the bare bones.</p>
|
|
<p><strong><code>prefix-hidden</code>, <code>prefix-needed</code></strong></p>
|
|
<p>You will know that when the shell lists matches for files, the directory
|
|
part is removed. The boolean style <code>prefix-hidden</code> extends this idea to
|
|
various other types of matches. The prefixes referred to are not just
|
|
any old common prefix to matches, but only some places defined in the
|
|
completion system: the <code>-</code> prefix to options, the `<code>%</code>' prefix to jobs,
|
|
the <code>-</code> or <code>+</code> prefix to directory stack entries are the most commonly
|
|
used.</p>
|
|
<p>The <code>prefix-needed</code> applies not to listings, but instead to what the
|
|
user types on the command line. It says that matches will only be
|
|
generated if the user has typed the prefix common to them. It applies on
|
|
broadly the same occasions as <code>prefix-hidden</code>.</p>
|
|
<p><strong><code>list-packed</code>, <code>list-rows-first</code>, <code>accept-exact</code>, <code>last-prompt</code>,
|
|
<code>menu</code></strong></p>
|
|
<p>The first two of these have already been introduced, and correspond to
|
|
the <code>LIST_PACKED</code> and <code>LIST_ROWS_FIRST</code> options. The <code>accept-exact</code> and
|
|
<code>last-prompt</code> styles correspond essentially to the <code>REC_EXACT</code> and
|
|
<code>ALWAYS_LAST_PROMPT</code> options in the same way.</p>
|
|
<p>The style <code>menu</code> roughly corresponds to the <code>MENU_COMPLETE</code> option, but
|
|
there is also the business of deciding whether to use menu selection, as
|
|
described above. These two uses don't interfere with each other ---
|
|
except that, as I explained, menu completion must be started to use menu
|
|
selection --- so a value like `<code>true select=6</code>' is valid; it turns on
|
|
menu completion for the context, and also activates menu selection if
|
|
there are at least 6 choices.</p>
|
|
<p>There are some other, slightly more obscure, choices for <code>menu</code>:</p>
|
|
<ul>
|
|
<li><strong><code>yes=</code><em>num</em></strong><br />
|
|
turn on menu completion only if there are at least <em>num</em> matches;</li>
|
|
<li><strong><code>no=</code><em>num</em></strong><br />
|
|
turn off menu completion if there are as many as <em>num</em> matches;</li>
|
|
<li><strong><code>yes=long</code></strong><br />
|
|
turn on menu completion if the list does not fit on the screen, and
|
|
completion was attempted;</li>
|
|
<li><strong><code>yes=long-list</code></strong><br />
|
|
the same, but do it even if listing, not completion, was attempted;</li>
|
|
<li><strong><code>select=long</code></strong><br />
|
|
like <code>yes=long</code>, but this time turn on menu selection, too;</li>
|
|
<li><strong><code>select=long-list</code></strong><br />
|
|
like <code>yes=long-list</code>, but turn on menu selection, too.</li>
|
|
</ul>
|
|
<p>In case your eyes glazed over before the end, here's a full description
|
|
of the last one, <code>select=long-list</code>, which is quite useful: if you are
|
|
attempting completion or even just listing completions, and the list of
|
|
matches would be too long to fit on the screen, then menu selection is
|
|
turned on, so that you can use the cursor keys (and other selection
|
|
keys) to move up and down the list. Generally, the above possibilities
|
|
can be combined, unless the combined effect wouldn't work.</p>
|
|
<p>As always, <code>yes</code> and <code>true</code> are equivalent, as are <code>no</code> and <code>false</code>. It
|
|
just hurts the eyes of programmers to read something which appears to
|
|
assign a value to <code>true</code>.</p>
|
|
<p><strong><code>hidden</code></strong></p>
|
|
<p>This is a little obscure for most users. Its context should be
|
|
restricted to specific tags; any corresponding matches will not be shown
|
|
in completion listings, but will be available for inserting into the
|
|
command line. If its value is `<code>true</code>', then the description for the
|
|
tag may still appear; if the value is `<code>all</code>', even that is suppressed.
|
|
If you don't want the completions even to be available for insertion,
|
|
use the <code>tag-order</code> style.</p>
|
|
<p><span id="l159"></span></p>
|
|
<h3 id="653-styles-affecting-particular-completions"><a class="header" href="#653-styles-affecting-particular-completions">6.5.3: Styles affecting particular completions</a></h3>
|
|
<p>The styles listed here are for use only with certain completions as
|
|
noted. I have not included the styles used by particular completers,
|
|
which are described with the completer in question in the subsection
|
|
`<strong>Specifying completers and their options</strong>'. I have also not
|
|
described styles used only in separate widgets that do completion; the
|
|
relevant information is all together in the next section.</p>
|
|
<p><strong>Filenames (1): patterns: <code>file-patterns</code></strong></p>
|
|
<p>It was explained above for the <code>tag-order</code> style that when a function
|
|
uses pattern matching to generate file completions, such as all <code>*.ps</code>
|
|
files or all <code>*.gz</code> files, the three tags <code>globbed-files</code>, <code>directories</code>
|
|
and <code>all-files</code> are tried, in that order.</p>
|
|
<p>The <code>file-patterns</code> style allows you to specify a pattern to override
|
|
whatever would be completed, even in what would otherwise be a simple
|
|
file completion with no pattern. Since this can easily get out of hand,
|
|
the best way of using this style is to make sure that you specify it for
|
|
a narrowly enough defined context. In particular, you probably want to
|
|
restrict it to completions for a single command and for a particular one
|
|
of the tags usually applying to files. As always, you can use <code>^Xh</code> to
|
|
find out what the context is. It has a labelling mechanism --- you can
|
|
specify a tag with a pattern for use in looking up other styles. Hence
|
|
`<code>*.o:object-files</code>' gives a pattern `<code>*.o</code>' and a tag name
|
|
`<code>object-files</code>' by which to refer to these.</p>
|
|
<p>The patterns you specify are tried in order; you don't need to use
|
|
<code>tag-order</code>. In fact <code>file-patterns</code> replicates its behaviour in that
|
|
you can put patterns in the same word to say they should be tried
|
|
together, before going on to the pattern(s) in the next word. Also, you
|
|
can give a description after a second colon in the same way. Indeed,
|
|
since <code>file-patterns</code> gets its hands on the tags first, any ordering
|
|
defined there can't be overridden by <code>tag-order</code>.</p>
|
|
<p>So, for example, after</p>
|
|
<pre><code> zstyle ':completion:*:*:foo:*:*' file-patterns \
|
|
'*.yo:yodl-files:yodl\ files *(-/):directories'
|
|
</code></pre>
|
|
<p>the command named `<code>foo</code>' will complete files ending in `<code>.yo</code>', as
|
|
well as directories. For once, you don't have to change the completer to
|
|
alter what's completed: `<code>foo</code>' isn't specially handled, so it causes
|
|
default completion, and that means completing files, so that
|
|
<code>file-patterns</code> is active anyway.</p>
|
|
<p>Here's a slightly enhanced example; it shows how <code>file-patterns</code> can be
|
|
used instead of <code>tag-order</code> to offer the tags in the order you want.</p>
|
|
<pre><code> zstyle ':completion:*:*:foo:*:*' file-patterns \
|
|
'*.yo:yodl-files:yodl\ files' '*(-/):directories:directories' \
|
|
'^*.yo(-^/):other-files:other\ files'
|
|
</code></pre>
|
|
<p>Completion will first try to show you only `<code>.yo</code>' files, if there are
|
|
any; otherwise it will show you directories, if there are any; otherwise
|
|
it will show you any other files: `<code>^*.yo(-^/)</code>' is an extended glob to
|
|
match any file which doesn't end in `<code>.yo</code>' and which isn't a directory
|
|
and doesn't link to a directory. As always, you can cycle through the
|
|
sets of possibilities using the `<code>_next_tag</code>' completion command.</p>
|
|
<p>Note that <code>file-patterns</code> is an exception to the general rule that
|
|
styles don't determine <em>which</em> tags are called only <em>where</em> they're
|
|
called, or what their behaviour is: this time, you actually get to
|
|
specify the set of tags which will be used. This means it doesn't use
|
|
the the standard file tags (unless you use those names yourself, of
|
|
course), just `<code>files</code>' if you don't specify one. Hence it's good style
|
|
to add the tags, following colons, although it'll work without.</p>
|
|
<p>Another thing to watch out for is that if there is already a completion
|
|
which handles a file type --- for example, if we had tried to alter the
|
|
effect of file completion for the `<code>yodl</code>' command instead of the
|
|
fictitious `<code>foo</code>' --- the results may well not be quite what you want.</p>
|
|
<p>Another feature is that `<code>%p</code>' in the pattern inserts the pattern which
|
|
would usually be used. That means that the following is essentially the
|
|
same as what file completion normally does:</p>
|
|
<pre><code> zstyle ':completion:*' file-patterns '%p:globbed-files' \
|
|
'*(-/):directories' '*:all-files'
|
|
</code></pre>
|
|
<p>You can turn completion for a command that usually doesn't use a pattern
|
|
into one that does. Another example taken from the manual:</p>
|
|
<pre><code> zstyle ':completion:*:*:rm:*:globbed-files' file-patterns \
|
|
'*.o:object-files' '%p:all-files'
|
|
</code></pre>
|
|
<p>So if there are any <code>*.o</code> files around, completion for <code>rm</code> will just
|
|
complete those, even if arguments to <code>rm</code> are otherwise found by default
|
|
file completion (which they usually are). The <code>%p</code> will use whatever
|
|
file completion normally would have; probably any file at all. You can
|
|
change this, if you like; there may be files you don't ever want
|
|
automatically completed after <code>rm</code>.</p>
|
|
<p>Remember that using explicit patterns overrides the effect of
|
|
<code>$fignore</code>; this is obviously useful with <code>rm</code>, since the files you want
|
|
to delete are often those you usually don't want to complete.</p>
|
|
<p><strong>Filenames (2): paths: <code>ambiguous</code>, <code>expand</code>, <code>file-sort</code>,
|
|
<code>special-dirs</code>, <code>ignore-parents</code>, <code>list-suffixes</code>, <code>squeeze-slashes</code></strong></p>
|
|
<p>Filename completion is powerful enough to complete all parts of a path
|
|
at once, for example `<code>/h/p/z</code>' will complete to `<code>/home/pws/zsh</code>'.
|
|
This can cause problems when the match is ambiguous; since several
|
|
components of the path may well be ambiguous, how much should the
|
|
completion system complete, and where should it leave the cursor? This
|
|
facility is associated with all these styles affecting filenames.</p>
|
|
<p>With ordinary completion, the usual answer is that the completion is
|
|
halted as soon as a path component matches more than one possibility,
|
|
and the cursor is moved to that point, with the remainder of the string
|
|
left unaltered. With menu completion, you can simply cycle through the
|
|
possibilities with the cursor moved to the end as usual. If you set the
|
|
style <code>ambiguous</code>, then the system will leave the cursor at the point of
|
|
the first ambiguity even if menu completion is in use. Note that this is
|
|
always used with the `<code>paths</code>' tag, i.e. the context ends in
|
|
`<code>...:paths</code>'.</p>
|
|
<p>The style <code>expand</code> is similar and is also applied with the `<code>paths</code>'
|
|
tag. It can include either or both of the strings <code>prefix</code> and <code>suffix</code>.
|
|
Be careful when setting both --- they have to be separate words, for
|
|
example</p>
|
|
<pre><code> zstyle ':completion:*' expand prefix suffix
|
|
</code></pre>
|
|
<p>Don't put quotes around `<code>prefix suffix</code>' as it won't work.</p>
|
|
<p>With <code>prefix</code>, <code>expand</code> tells the completion system always to expand
|
|
unambiguous prefixes in a path (such as `<code>/u/i</code>' to `<code>/usr/in</code>', which
|
|
matches both <code>/usr/include</code> and <code>/usr/info</code>) --- even if the remainder
|
|
of the string on the command line doesn't match any file. So this
|
|
expansion will now happen even if you try this on
|
|
`<code>/u/i/ALoadOfOldCodswallop</code>', which it otherwise wouldn't.</p>
|
|
<p>Including <code>suffix</code> in the value of <code>expand</code> extends path completion in
|
|
another way: it allows extra unambiguous parts to be added even after
|
|
the first ambiguous one. So if `<code>/home/p/.pr</code>' would match
|
|
`<code>/home/pws/.procmailrc</code>' or `<code>/home/patricia/.procmailrc</code>', and
|
|
nothing else, the last word would be expanded. Set up like this, you
|
|
will always get the longest unambiguous match for all parts of the path.</p>
|
|
<p>In older versions of the completion system, <code>suffix</code> wasn't used if you
|
|
had menu completion active by default, although it was if menu
|
|
completion was only started by the <code>AUTO_MENU</code> option. However, in
|
|
recent versions, the setting is always respected. This means that
|
|
setting the <code>expand</code> style to include the value <code>suffix</code> allows menu
|
|
completion to cycle through all possible completions, as if there were a
|
|
`<code>*</code>' after each part of the path, so `<code>/u/i/k</code>' will offer all
|
|
matches for `<code>/u*/i*/k*</code>'.</p>
|
|
<p>The <code>file-sort</code> style allows files to be sorted in a way other than by
|
|
alphabetical order: sorting applies both to the list of files, and to
|
|
the order in which menu completion presents them. The value should
|
|
include one of the following: `<code>size</code>', `<code>links</code>', `<code>modification</code>'
|
|
(same as `<code>time</code>', `<code>date</code>'), `<code>access</code>', `<code>inode</code>' (same as
|
|
`<code>change</code>'). These pick the obvious properties for sorting: file size,
|
|
number of hard links, modification time, access time, inode change time.
|
|
You can also add the string `<code>reverse</code>' to the value, which reverses
|
|
the order. In this case the tag is always `<code>files</code>'.</p>
|
|
<p>The <code>special-dirs</code> style controls completion of the special directories
|
|
`<code>.</code>' and `<code>..</code>'. Given that you usually need to type an initial dot
|
|
to complete anything at all beginning with one, the idea of
|
|
`completing' `<code>.</code>' is a little odd; it simply means that the directory
|
|
is accepted when the completion is started on it. You can set the style
|
|
to <code>true</code> to allow completion to both of the two, or to `<code>..</code>' to
|
|
complete `<code>..</code>' but not `<code>.</code>'. Like <code>ambiguous</code>, this is used with the
|
|
tag set to `<code>paths</code>'.</p>
|
|
<p>The style <code>ignore-parents</code> is used with the <code>files</code> tag, since it
|
|
applies to paths, but not necessarily completion of multiple path names
|
|
at once; it can be used when completing just the last element. There are
|
|
two main uses, which can be combined. The first case is to include the
|
|
string `<code>parent</code>' in the style. This means that when you complete after
|
|
(say) <code>foo/../</code>, the string <code>foo</code> won't appear as a choice, since it
|
|
already appeared in the string. Secondly, you can include `<code>pwd</code>' in
|
|
the value; this means don't complete the current working directory after
|
|
`<code>../</code>' --- you can see the sense in that: if you wanted to complete
|
|
there, you wouldn't have typed the `<code>..</code>' to get out if it.</p>
|
|
<p>Actually, the function performs both those tests on the directories in
|
|
question even if the string `<code>..</code>' itself hasn't been typed. That might
|
|
be more confusing, and you can make sure that the tests for <code>parent</code> and
|
|
<code>pwd</code> are only made when you typed the `<code>..</code>' by including a `<code>..</code>' in
|
|
the style's value. Finally, you can include the string `<code>directory</code>' in
|
|
the values: that means the tests will only be performed when directories
|
|
are being completed, while if some other sort of file, or any file, can
|
|
be completed, the special behaviour doesn't occur. You may have to read
|
|
that through a couple of times before deciding if you need it or not.</p>
|
|
<p>Next, there is <code>list-suffixes</code>. It applies when expanding out earlier
|
|
parts of the filename path, not just the last part. In this case, it is
|
|
possible that early parts of the path were ambiguous. Normally
|
|
completion stops at the point where it finds the ambiguity, and leaves
|
|
the rest of the path alone. When <code>list-suffixes</code> is set, it will list
|
|
all the possible values of all ambiguous components from the point of
|
|
ambiguity onward.</p>
|
|
<p>Lastly, there is the style <code>squeeze-slashes</code>. This is rather simpler.
|
|
You probably already know that in a UNIX filename multiple slashes are
|
|
treated just like a single slash (with a few minor exceptions on some
|
|
systems). However, path completion usually assumes that multiple slashes
|
|
mean multiple directories to be completed: `<code>//termc</code>' completes to
|
|
`<code>/etc/termcap</code>' because of this rule. If you want to stick with the
|
|
ordinary UNIX rule you can set <code>squeeze-slashes</code> to <code>true</code>. Then in this
|
|
example only files in the root directory will be completed.</p>
|
|
<p><strong>Processes: <code>command</code>, <code>insert-ids</code></strong></p>
|
|
<p>Some functions, such as <code>kill</code>, take process IDs (i.e. numbers) as
|
|
arguments. These can be completed by using the <code>ps</code> command to generate
|
|
the process numbers. The <code>command</code> style allows you to specify which
|
|
arguments are to be passed to <code>ps</code> to generate the numbers; it is simply
|
|
<code>eval</code>'d to generate the command line. For example, if you are root and
|
|
want to have all processes as possible completions, you might use
|
|
`<code>-e</code>', for many modern systems, or `<code>ax</code>', for older BSD-like
|
|
systems. The completion system tries to find a column which is headed
|
|
`<code>PID</code>' or `<code>pid</code>' (or even `<code>Pid</code>', in fact) to use for the process
|
|
IDs; if it doesn't find one, it just uses the first column.</p>
|
|
<p>The default is not to use any arguments; most variants of <code>ps</code> will then
|
|
just show you interactive processes from your current session. To show
|
|
all your own processes on a modern system, you can probably use the
|
|
value `<code>ps -u$USER</code>' for the style --- remembering to put this in
|
|
single quotes. Clearly, you need to make sure the context is narrow
|
|
enough to avoid unexpectedly calling odd commands.</p>
|
|
<p>You can make the value begin with a hyphen, then the usual command line
|
|
will put afterward and the hyphen removed. The suggested use for this is
|
|
adding `<code>command</code>' or `<code>builtin</code>' to make sure the right version of a
|
|
command is called.</p>
|
|
<p>The completion system allows you to type the name of a command, for
|
|
example `<code>emacs</code>', which will be converted to a PID. Note that this is
|
|
different from a job name beginning with `<code>%</code>'; in this case, any
|
|
command listed by <code>ps</code>, given the setting of the <code>command</code> style, can be
|
|
used. Obviously, command names can be ambiguous, unlike the process IDs
|
|
themselves, so the names are usually converted immediately to PIDs; if
|
|
the name could refer to more than one process, you get a menu of
|
|
possible PIDs.</p>
|
|
<p>The style <code>insert-ids</code> allows the completion system to keep using the
|
|
names rather than the PIDs. If it is set to <code>single</code>, the name will be
|
|
retained until you type enough to identify a particular process. If it
|
|
is set to <code>true</code> (or anything else but <code>menu</code>, actually), menu
|
|
completion is delayed until you have typed a string longer than the
|
|
common prefix of the PIDs. This is intended to be similar to
|
|
completion's usual logic --- don't do anything which gets rid of
|
|
information supplied by the user --- so is probably more useful in
|
|
practice than it sounds.</p>
|
|
<p><strong>Job control: <code>numbers</code></strong></p>
|
|
<p>Builtin functions that take process IDs usually also take job
|
|
specifications, strings beginning with `<code>%</code>' and followed either by a
|
|
small number or a string. The style <code>numbers</code> determines how these are
|
|
completed. By default, the completion system will try to complete an
|
|
unambiguous string from the name of the job. If you set <code>numbers</code> to
|
|
true, it will instead complete the job number --- though the listing
|
|
will still show the full information --- and if you set it to a number,
|
|
it will only use that many words of the job name, and switch to using
|
|
numbers if those are not unique. In other words, if you set it to `<code>1</code>'
|
|
and you have two jobs `<code>vi foo</code>' and `<code>vi bar</code>', then they will
|
|
complete as `<code>%1</code>' and `<code>%2</code>' (or maybe other numbers) since the first
|
|
words are the same.</p>
|
|
<p>Note also that <code>prefix-needed</code> applies here; if it is set, you need to
|
|
type the `<code>%</code>' to complete jobs rather than processes.</p>
|
|
<p><strong>System information: users, groups, hosts etc.</strong></p>
|
|
<p>There are many occasions where you complete the names of users on the
|
|
system, groups on the system (not to be confused with completion
|
|
groups), names of other hosts you connect to via the network, and ports,
|
|
which are essentially the names of internet services available on
|
|
another host such as <code>nntp</code> or <code>smtp</code>.</p>
|
|
<p>By default, the completion system will query the usual system files to
|
|
find the names of users, groups, hosts and ports, though in the final
|
|
case it will only look in the file `<code>/etc/hosts</code>', which often includes
|
|
only a very small number of not necessarily very useful hosts. It is
|
|
possible to tell the completion system always to use a specified set by
|
|
setting the appropriate style --- <code>users</code>, <code>groups</code>, <code>hosts</code>, <code>ports</code>
|
|
--- to the set of possibilities you want. This is nearly always useful
|
|
with <code>hosts</code>, and on some systems you may find it takes an inordinate
|
|
amount of time for the system to query the database for groups and
|
|
users, so you may want to specify a subset containing just those you use
|
|
most often.</p>
|
|
<p>There are also three sets of combinations: <code>hosts-ports</code>,
|
|
<code>hosts-ports-users</code> and <code>users-hosts</code>. These are used for commands which
|
|
can take both or all three arguments. Currently, the command socket uses
|
|
<code>hosts-ports</code>, telnet uses <code>hosts-ports-users</code>, while the style
|
|
<code>users-hosts</code> is used by remote login commands such as <code>rsh</code> and <code>ssh</code>,
|
|
and anywhere the form `<code>user@host</code>' is valid.</p>
|
|
<p>The last is probably the most useful, so I'll illustrate that. By
|
|
setting:</p>
|
|
<pre><code> zstyle ':completion:*' users-hosts \
|
|
pws:foo.bar.uk peters@frond.grub.uk
|
|
</code></pre>
|
|
<p>you tell <code>rsh</code> and friends the possible user/host combinations. Note
|
|
that for the separator you can use either `<code>:</code>', as usual inside the
|
|
completion system, or `<code>@</code>', which is more natural in this particular
|
|
case. If you type `<code>rsh -l </code>', a username is expected and either
|
|
<code>pws</code> or <code>peters</code> will be completed. Suppose you picked <code>pws</code>; then for
|
|
the next argument, which should be a host, the system now knows that it
|
|
must be <code>foo.bar.uk</code>, since the username for the other host doesn't
|
|
match.</p>
|
|
<p>If you don't need that much control, completion for all these commands
|
|
will survive on just the basic `<code>hosts</code>', `<code>users</code>', etc. styles; it
|
|
simply won't be as clever in recognising particular combinations. In
|
|
fact, even if you set the combined styles, anything that doesn't match
|
|
will be looked up in the corresponding basic style, so you can't lose,
|
|
in principle.</p>
|
|
<p>The other combined styles work in exactly the same way; just set the
|
|
values separated by colons or `<code>@</code>', it doesn't matter which.</p>
|
|
<p><strong>URLs for web browsers</strong></p>
|
|
<p>Completion for URLs is done by setting a parallel path somewhere on your
|
|
local machine. The <code>urls</code> style specifies the top directory for this.
|
|
For example, to complete the URL <code>http://zsh.org/</code>, you need to make a
|
|
set of subdirectories of the <code>path</code> directory <code>http/zsh.org/</code>. You can
|
|
extend this for however many levels of directory you need; as you would
|
|
expect, if the last object is a file rather than a directory you should
|
|
create it with `<code>touch</code>' rather than `<code>mkdir</code>'. The style will always
|
|
use the tag `<code>urls</code>' for this purpose, i.e. the context always matches
|
|
`<code>:completion:*:urls</code>'. This is a neat way of using the ordinary filing
|
|
system for doing the dirty work of turning URLs into components.
|
|
Arguably the system should be able to scan your browser's bookmarks
|
|
file, but currently it won't; there is, however, a tool provided with
|
|
the shell distribution in <code>Misc/make-zsh-urls</code> which should be able to
|
|
help --- ask your system administrators about this if it isn't
|
|
installed, I'm sure they'll be delighted to help.</p>
|
|
<p>If you only have a few URLs you want to complete, you can use one of two
|
|
simpler forms for the <code>urls</code> style. First, if the value of the style
|
|
contains more than one word, the values are used directly as the URLs to
|
|
be completed, e.g.:</p>
|
|
<pre><code> zstyle ':completion:*:urls' urls \
|
|
http://www.foo.org/ ftp://ftp.bar.net
|
|
</code></pre>
|
|
<p>Alternatively, you can set the <code>urls</code> style to the name of a normal
|
|
file, which contains the URLs to complete separated by white space or
|
|
newlines.</p>
|
|
<p>Note that many modern browsers allow you to miss out an initial
|
|
`<code>http://</code>', and that lots of pseudo-URLs appear in newspapers and
|
|
advertisements without it. The completion system needs it, however.</p>
|
|
<p>There is a better way when the web pages actually happen to be hosted on
|
|
a system whose directories you can access directly. Set the <code>local</code>
|
|
style to an array of three strings: a hostname to be considered local
|
|
(you can only give one per context), the directory corresponding to the
|
|
root of the files, and the directory where a user places their own web
|
|
pages, relative to their home directory. For example, if your home page
|
|
is usually retrieved as <code>http://www.footling.com/</code>, and that looks for
|
|
the index file (often called <code>index.html</code>) in the directory
|
|
<code>/usr/local/www/files</code>, and your own web pages live under `<code>~/www</code>',
|
|
then you would set</p>
|
|
<pre><code> zstyle ':completion:*:urls' local \
|
|
www.footling.com /usr/local/www/files www
|
|
</code></pre>
|
|
<p>and when you type `<code>lynx http://www.footling.com/</code>', all the rest will
|
|
be completed automatically.</p>
|
|
<p><strong>The X files</strong></p>
|
|
<p>There is another use for the <code>path</code> style with the tag `<code>colors</code>': it
|
|
gives the path to a file which contains a list of colour names
|
|
understood by the X-windows system, usually in file named `<code>rgb.txt</code>'.
|
|
This is used in such contexts as `<code>xsetroot -solid </code>', which
|
|
completes the name of a colour to set your root window (wallpaper) to.
|
|
It may be that the default value works on your system without your
|
|
needing to set this.</p>
|
|
<p><span id="l160"></span></p>
|
|
<h2 id="66-command-widgets"><a class="header" href="#66-command-widgets">6.6: Command widgets</a></h2>
|
|
<p><span id="l161"></span></p>
|
|
<h3 id="661-_complete_help"><a class="header" href="#661-_complete_help">6.6.1: <code>_complete_help</code></a></h3>
|
|
<p>You've already met this, usually bound to `<code>^Xh</code>' unless you already
|
|
had that bound when completion started up (in which case you should pick
|
|
your own binding and use `<code>bindkey</code>'), but don't forget it, since it's
|
|
by far the easiest way of finding out what context to use for setting
|
|
particular styles.</p>
|
|
<p><span id="l162"></span></p>
|
|
<h3 id="662-_correct_word-_correct_filename-_expand_word"><a class="header" href="#662-_correct_word-_correct_filename-_expand_word">6.6.2: <code>_correct_word</code>, <code>_correct_filename</code>, <code>_expand_word</code></a></h3>
|
|
<p>The first and last of these have been mentioned in describing the
|
|
related completers: <code>_correct_word</code>, usually bound to <code>^Xc</code>, calls the
|
|
<code>_correct</code> completer directly to perform spelling correction on the
|
|
current word, and <code>_expand_word</code>, usually bound to <code>^Xe</code>, does the same
|
|
with the <code>_expand</code> completer. The contexts being
|
|
`<code>:completion:complete-word</code>' and `<code>:completion:expand-word</code>'
|
|
respectively, so that they can be distinguished in styles from the
|
|
ordinary use of the completer. If you want the same styles to be used in
|
|
both contexts, but not others, you should define them for patterns
|
|
beginning `<code>:completion:complete(|-word)...</code>'.</p>
|
|
<p>The middle one simply corrects filenames, regardless of the completion
|
|
context. Unlike the others, it can also be called as an ordinary
|
|
function: pass it an argument, and it will print out the possible
|
|
corrections. It does this because it bypasses most of the usual
|
|
completion system. Probably you won't often need it, but it is usually
|
|
bound to `<code>^XC</code>' (note the capital `<code>C</code>').</p>
|
|
<p><span id="l163"></span></p>
|
|
<h3 id="663-_history_complete_word"><a class="header" href="#663-_history_complete_word">6.6.3: <code>_history_complete_word</code></a></h3>
|
|
<p>This is usually bound to `<code><ESC-/></code>' for completing back in the
|
|
history, and `<code><ESC-,></code>' for completing forward --- this will
|
|
automatically turn on menu completion, temporarily if you don't normally
|
|
have that set, to cycle through the matches. It will complete words from
|
|
the history list, starting with the most recent. Hence</p>
|
|
<pre><code> touch supercalifragilisticexpialidocious
|
|
cat sup<ESC-/>
|
|
</code></pre>
|
|
<p>will save you quite a bit of typing --- although in this particular
|
|
case, you can use `<code><ESC-.></code>' to insert the last word of the previous
|
|
command.</p>
|
|
<p>Various styles are available. You can set the `<code>stop</code>' style which
|
|
makes it stop once before cycling past the end (or beginning) of the
|
|
history list, telling you that the end was reached.</p>
|
|
<p>You can also set the `<code>list</code>' style to force matches to be listed, the
|
|
`<code>sort</code>' style to sort matches in alphabetical order instead of by
|
|
their age in the history list, and the `<code>remove-all-dups</code>' style, which
|
|
ensures that each match only occurs once in the completion list ---
|
|
normally consecutive identical matches are removed, but the code does
|
|
not bother searching for identical matches elsewhere in the list of
|
|
possibilities. Finally, the <code>range</code> style is supported via the
|
|
<code>_history</code> completer, which does the work. This style restricts the
|
|
number of history words to be searched for matches and is most useful if
|
|
your history list is large. Setting it to a number <em>n</em> specifies that
|
|
only the last <em>n</em> history words should be searched for possible matches.
|
|
Alternatively, it can be a value of the form `<em>max</em><code>:</code><em>slice</em>', in
|
|
which case it will search through the last <em>slice</em> history words for
|
|
matches, and only if it doesn't find any, the <em>slice</em> words before that;
|
|
<em>max</em> gives an overall limit on the maximum number of words to search
|
|
through.</p>
|
|
<p><span id="l164"></span></p>
|
|
<h3 id="664-_most_recent_file"><a class="header" href="#664-_most_recent_file">6.6.4: <code>_most_recent_file</code></a></h3>
|
|
<p>This function is normally bound to `<code>^Xm</code>'. It simply completes the
|
|
most recently modified file that matches what's on the line already. Any
|
|
pattern characters in the existing string are active, so this is a cross
|
|
between expansion and completion. You can also give it a numeric prefix
|
|
to show the <code>N</code>th most recently modified file that matches the pattern.</p>
|
|
<p>By the way, you can actually do the same by setting appropriate styles,
|
|
without any new functions. The trick is to persuade the system to use
|
|
the normal <code>_files</code> completer with the <code>file-sort</code> style. By restricting
|
|
the use of the styles to the context of the widget --- which is simply
|
|
the <code>_generic</code> completer described above:</p>
|
|
<pre><code> zstyle ':completion:(match-word|most-recent-file):*' \
|
|
match-original both
|
|
zstyle ':completion:most-recent-file::::' completer \
|
|
_menu _files _match
|
|
zstyle ':completion:most-recent-file:*' file-sort modification
|
|
zstyle ':completion:most-recent-file:*' file-patterns \
|
|
'*(.):normal\ files'
|
|
zstyle ':completion:most-recent-file:*' hidden true
|
|
zstyle ':completion:most-recent-file:*:descriptions' format ''
|
|
bindkey '^Xm' most-recent-file
|
|
zle -C most-recent-file menu-complete _generic
|
|
</code></pre>
|
|
<p>It may not be obvious how this works, so here's a blow by blow account
|
|
if you are interested. (It works even if you aren't interested,
|
|
however.)</p>
|
|
<ul>
|
|
<li>The `<code>zle -C</code>' defines a widget which does menu completion, and
|
|
behaves like ordinary completion (that's what <code>_generic</code> is for)
|
|
except that the context uses the name of the widget we define.</li>
|
|
<li>When we invoke the widget, the system uses the <code>completer</code> style to
|
|
decide what completions to perform. This instructs it: use menu
|
|
completion, complete files, use pattern matching if the completion
|
|
so far didn't work.</li>
|
|
<li>First, <code>_menu</code> comes along; it actually does nothing more than tell
|
|
the system to use menu completion.</li>
|
|
<li>Then <code>_files</code> generates a list of files. This uses the <code>file-sort</code>
|
|
and <code>file-patterns</code> styles defined for the <code>most-recent-file</code>
|
|
context. They produce a set of files in modification time order, and
|
|
include only regular files (so not directories, symlinks, device
|
|
files and so on).</li>
|
|
<li>If that failed, the <code>_match</code> style allows the word on the command
|
|
line to be treated as a pattern; for example, <code>*.c</code> to complete the
|
|
most recent C source file. This uses the <code>match-original</code> style; the
|
|
setting tells it that it should try first without adding an extra
|
|
`<code>*</code>' for matching (this is what we want for the case where we
|
|
already have a complete pattern like <code>*.c</code>), and if that fails, add
|
|
a <code>*</code> at the end and try again.</li>
|
|
<li>The <code>hidden</code> style means that the matches aren't listed; all that
|
|
happens is the first is inserted on the line. The setting for the
|
|
<code>format</code> tag similarly simplifies the display in this case by
|
|
removing verbose descriptions.</li>
|
|
<li>The net result is the first step of a menu completion: insert the
|
|
first matched file (the most recently modified) onto the line. This
|
|
is exactly what you want. Note, however, that as we are in menu
|
|
completion you can keep on hitting <code>^xm</code> and the shell will cycle
|
|
through the matches, which here gives you files that are
|
|
progressively less recently modified.</li>
|
|
</ul>
|
|
<p>Omit the <code>file-patterns</code> line if you don't want the match restricted to
|
|
regular files (I sometimes need the most recently modified directory,
|
|
but often it's irrelevant). The whole version using styles comes from
|
|
Oliver Kiddle, who recommends using <code>_generic</code> in this way any time you
|
|
want to generate a widget from a specific completion such as <code>_files</code>.
|
|
There is a brief section on <code>_generic</code> below.</p>
|
|
<p><span id="l165"></span></p>
|
|
<h3 id="665-_next_tags"><a class="header" href="#665-_next_tags">6.6.5: <code>_next_tags</code></a></h3>
|
|
<p>This is a very neat way of getting round the order of tags just with a
|
|
key sequence. An example is the best way of showing it; it's bound by
|
|
default to the key sequence `<code>^Xn</code>'.</p>
|
|
<pre><code> % tex ^D
|
|
Completing TeX or LaTeX file
|
|
bar.tex foo.tex guff.tex
|
|
</code></pre>
|
|
<p>Our file is not in that directory, but by default we don't get to see
|
|
the directory if there was a file that matched the pattern --- here
|
|
`<code>*.tex</code>'. (This will actually change in 4.1, since most people don't
|
|
know about <code>_next_tags</code> but do know about directories, but you can still
|
|
cycle through the different sets of tags.) You can set the <code>tag-order</code>
|
|
style to alter whether they appear at the same time, but <code>_next_tags</code>
|
|
lets you do this very simply. Just hit <code>^Xn</code>. You're now looking at</p>
|
|
<pre><code> Completing TeX or LaTeX file
|
|
dir1/ dir2/ dir3/
|
|
</code></pre>
|
|
<p>and if you carry on hitting <code>^Xn</code> you will get to all files, and then
|
|
you will be taken back to the <code>.tex</code> files again. (Where our file
|
|
actually is, is left as an exercise for the reader.)</p>
|
|
<p>Of course this works with any set of tags whatsover; it simply has the
|
|
effect of cycling you around the tag order.</p>
|
|
<p><span id="l166"></span></p>
|
|
<h3 id="666-_bash_completions"><a class="header" href="#666-_bash_completions">6.6.6: <code>_bash_completions</code></a></h3>
|
|
<p>This function provides compatibility with a set of completion bindings
|
|
in bash, in which escape followed by one of the following characters
|
|
causes a certain type of (non-contextual) completion: `<code>!</code>', command
|
|
names; `<code>$</code>', environment variables; `<code>@</code>', host names; `<code>/</code>',
|
|
filenames, and `<code>~</code>' user names. `<code>^X</code>' followed by the same
|
|
characters causes the possible completion to be listed. This function
|
|
decides by examining its own binding which of those it should be doing,
|
|
then calls the appropriate completion function. If you want to use it
|
|
for all those possible bindings, you need to issue the right statements
|
|
in your <code>.zshrc</code>, since only the bindings with `<code>~</code>' are set up by
|
|
default to avoid clashes. This will do it:</p>
|
|
<pre><code> for key in '!' '$' '@' '/'; do
|
|
bindkey "\e$key" _bash_complete-word
|
|
bindkey "^X$key" _bash_list-choices
|
|
done
|
|
</code></pre>
|
|
<p>Unlike most widgets, which are tied to functions of the same name to
|
|
minimize confusion, the function <code>_bash_completions</code> is actually called
|
|
under the names of the two different widgets shown in that code so as to
|
|
be able to implement both completion and listing behaviour.</p>
|
|
<p><span id="l167"></span></p>
|
|
<h3 id="667-_read_comp"><a class="header" href="#667-_read_comp">6.6.7: <code>_read_comp</code></a></h3>
|
|
<p>This function, usually bound to `<code>^X^R</code>', does on-the-fly completion.
|
|
When you call it, it prompts for you to enter a type of completion;
|
|
usually this will be the name of a completion function with the required
|
|
arguments. Thus it's not much use unless you already have some fairly
|
|
in-depth knowledge of how the system is set up. For example, try it,
|
|
then enter `<code>_files -/</code>', which generates directories. There is a
|
|
rudimentary completion for the function names built into it.</p>
|
|
<p>The next time you start it up, it will produce the same type of
|
|
completion. You need to give it a numeric prefix to tell it to prompt
|
|
for a different sort.</p>
|
|
<p><span id="l168"></span></p>
|
|
<h3 id="668-_generic"><a class="header" href="#668-_generic">6.6.8: <code>_generic</code></a></h3>
|
|
<p>Rather than being directly bound, like the others, this widget gives you
|
|
a way of creating your own special completions. You define it as a
|
|
widget and bind it as if it were any completion function:</p>
|
|
<pre><code> zle -C foo complete-word _generic
|
|
bindkey '<keys>' foo
|
|
</code></pre>
|
|
<p>Now the keys bound will perform ordinary contextual completion, but any
|
|
styles will be looked up with the command context `<code>foo</code>'. So you can
|
|
give it its own set of completers:</p>
|
|
<pre><code> zstyle ':completion:foo:*' completer _expand
|
|
</code></pre>
|
|
<p>and, indeed, give it special values for any style you like. To put it
|
|
another way, you've now got a complete, separate copy of the completion
|
|
system where the only difference is the extra word in the context.</p>
|
|
<p>Good example of the use of this function were given above in the
|
|
descriptions of <code>_all_matches</code> and <code>_most_recent_file</code>.</p>
|
|
<p><span id="l169"></span></p>
|
|
<h3 id="669-predict-on-incremental-complete-word"><a class="header" href="#669-predict-on-incremental-complete-word">6.6.9: <code>predict-on</code>, <code>incremental-complete-word</code></a></h3>
|
|
<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
|
|
these,</p>
|
|
<pre><code> autoload -U incremental-complete-word predict-on
|
|
zle -N incremental-complete-word
|
|
zle -N predict-on
|
|
zle -N predict-off
|
|
bindkey '^Xi' incremental-complete-word
|
|
bindkey '^Xp' predict-on
|
|
bindkey '^X^P' predict-off
|
|
</code></pre>
|
|
<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><span id="l170"></span></p>
|
|
<h2 id="67-matching-control-and-controlling-where-things-are-inserted"><a class="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
|
|
in order from left to right. For example,</p>
|
|
<pre><code> zstyle ':completion:*' matcher-list 'm:{a-z-}={A-Z_}' \
|
|
'r:|[-_./]=* r:|=*'
|
|
</code></pre>
|
|
<p>tries the first specification, which is for case-insensitive completion,
|
|
and if no matches are generated tries the second, which does partial
|
|
word completion; I'll explain both these specifications in detail as we
|
|
go along. You can make it do both forms the second time round simply by
|
|
combining the values with a space, i.e. the last word on the command
|
|
line becomes <code>'m:{a-z-}={A-Z_} r:|[-_./]=* r:|=*'</code>. It is also perfectly
|
|
valid to have a first matcher empty, i.e. <code>'``'</code>; this means that
|
|
completion is tried with no matching rule the first time, and will only
|
|
go on to subsequent matchers in the list if that fails. This is quite a
|
|
good practice as it avoids surprises.</p>
|
|
<p><span id="l171"></span></p>
|
|
<h3 id="671-case-insensitive-matching"><a class="header" href="#671-case-insensitive-matching">6.7.1: Case-insensitive matching</a></h3>
|
|
<p>To perform case-insensitive matching for all completions, you can set:</p>
|
|
<pre><code> zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
|
|
</code></pre>
|
|
<p>The `<code>m:</code>' specifies standard matching, with the `<code>{a-z}</code>' describing
|
|
what's on the command line, and the `<code>{A-Z}</code>' what's in the trial
|
|
completion. The braces indicate `correspondence classes', which are not
|
|
lessons taken by email (that's a joke), but a relative of the more usual
|
|
character classes like `<code>[a-z]</code>', which, as you no doubt know, would
|
|
match any of the letters between <code>a</code> and <code>z</code>. In this context, with the
|
|
braces, the letters are forced to match on the left and right hand side
|
|
of the `<code>=</code>', so an `<code>a</code>' on the command line must match an `<code>A</code>' in
|
|
the trial completion, a `<code>b</code>' must match a `<code>B</code>', and so on. Since an
|
|
<code>a</code> in the command line will always match an `<code>a</code>' in the trial
|
|
completion, matcher or no matcher, this means that if you type an `<code>a</code>'
|
|
it will match either `<code>a</code>' or `<code>A</code>' --- in other words,
|
|
case-insensitively. The same goes for any other lowercase letter you
|
|
type. The difference from `<code>m:[a-z]=[A-Z]</code>' is that, because ordinary
|
|
character classes are unordered, <em>any</em> lowercase letter would have
|
|
matched <em>any</em> uppercase letter, which isn't what you want. The rest of
|
|
the shell doesn't know about correspondence classes at all.</p>
|
|
<p>Finally, the use of a lowercase `<code>m</code>' at the start means that the
|
|
characters actually inserted onto the line are those from the trial
|
|
completion --- if you type `<code>make<TAB></code>', the completion process
|
|
generates file names, and <code>matcher-list</code> allows what you type to match
|
|
the file `<code>Makefile</code>', then you need the latter to be inserted on the
|
|
command line. Use of `<code>M:</code>' at the start of the matcher would keep
|
|
whatever was on the line to begin with there.</p>
|
|
<p>If you want completely case-insensitive matching, so that typing
|
|
`<code>MAKE<TAB></code>' would also potentially complete to `<code>Makefile</code>' or
|
|
`<code>makefile</code>' (and so on), the extension is fairly obvious:</p>
|
|
<pre><code> zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'
|
|
</code></pre>
|
|
<p>because now as well as `<code>a</code>' matching `<code>A</code>', `<code>A</code>' will match `<code>a</code>'
|
|
--- and, of course, `<code>a</code>' and `<code>A</code>' each still match themselves.</p>
|
|
<p>More detail on the patterns: they do not, in fact, allow all the
|
|
possible patterns you can use elsewhere in the shell, since that would
|
|
be too complicated to implement with little extra use. Apart from
|
|
character classes and correspondence classes, you can use `<code>?</code>' which
|
|
has its usual meaning of matching one character, or literal characters,
|
|
which match themselves; or the pattern for the trial completion only can
|
|
be a single `<code>*</code>'. which matches anything. That's it, however; you
|
|
can't do other things with the `<code>*</code>' since it's too difficult for the
|
|
system to guess what characters should be covered by it.</p>
|
|
<p>For the same reason, the `<code>*</code>' must be in an <em>anchored</em> pattern, the
|
|
idea behind which is shown in the next example.</p>
|
|
<p><span id="l172"></span></p>
|
|
<h3 id="672-matching-option-names"><a class="header" href="#672-matching-option-names">6.7.2: Matching option names</a></h3>
|
|
<p>I explained back in <a href="zshguide01.html#intro">chapter 1</a> that zsh didn't
|
|
care too much how you specified options: `<code>noglob</code>' and `<code>NOGLOB</code>' and
|
|
`<code>No_Glob</code>' and `<code>__NO_GLOB_</code>' are all treated the same way. Also,
|
|
this is the negation of the option `<code>glob</code>'. Having learnt how to match
|
|
case-insensitively, we have two further challenges: how to ignore a
|
|
`<code>_</code>' anywhere in the word, and how to ignore the <code>NO</code> at the beginning
|
|
so that we can complete an unnegated option name after it.</p>
|
|
<p>Well, here's how. Since you don't want this for all completions, just
|
|
for option names, I shall show it as an argument for the `<code>compadd</code>'
|
|
command, which gives the system the list of possible completions. The
|
|
option names should then appear as the remaining arguments to the
|
|
command, and the easiest way of doing that is to have the
|
|
<code>zsh/parameter</code> module loaded, which it always is for new completion,
|
|
and use the keys of the special associative array <code>$options</code>:</p>
|
|
<pre><code> compadd -M 'B:|[nN][oO]= M:_= M:{A-Z}={a-z}' - ${(k)options}
|
|
</code></pre>
|
|
<p>Here, we're interested in the thing in quotes --- it means exactly the
|
|
same here as it would as an element of the matcher list, except that it
|
|
only applies to the trial completions given after the `<code>-</code>'. It's in
|
|
three bits, separated by spaces; as they're in the same word, all are
|
|
applied one after the other regardless of any previous ones having
|
|
matched.</p>
|
|
<p>Starting from the right, you can see that the last part matches letters
|
|
case-insensitively; the capital `<code>M</code>' means that, this time, the
|
|
letters on the command line, not those in the trial completion are kept;
|
|
this is safe because of the way options are parsed, and reduces
|
|
unexpected changes.</p>
|
|
<p>Moving left, you can now guess `<code>M:_=</code>': it means that the `<code>_</code>'
|
|
matches nothing at all in the trial completion --- in other words, it is
|
|
simply ignored. The rule for matching across the `<code>=</code>' is that you move
|
|
from left to right, pairing off characters or elements of character
|
|
classes as I already described, and when you run out, you treat any
|
|
missing characters as, well, missing.</p>
|
|
<p>The first part has an `anchor', indicated by what lies between the
|
|
`<code>:</code>' and the `<code>|</code>'. The <code>B</code> specifies that the case insensitive match
|
|
of `<code>no</code>' must occur at the start of the word on the command line (with
|
|
`<code>b</code>' it would be the word in the list of matches), but here it is lax
|
|
enough to allow this to happen after the `<code>M:_=</code>' has stripped any
|
|
initial underscores away. Hence it matches <code>no</code>, <code>NO</code>, <code>No</code> or <code>nO</code> at
|
|
the start of the string, and, just like the `<code>M:_=</code>' part, it ignores
|
|
it, since there's nothing on the right. Again, the capital `<code>B</code>' at the
|
|
start means keep what's on the command line: that's important in this
|
|
case, since if you lost the `<code>no</code>', the meaning would change
|
|
completely.</p>
|
|
<p>So consider the combined effect when trying to complete <code>NO_GL</code>. The
|
|
first specification allows it to match against <code>_GL</code>; the second allows
|
|
it to match against <code>GL</code>; the third, against <code>gl</code>; and finally the usual
|
|
effect of completion means that any option beginning <code>gl</code> may be
|
|
completed. Try `<code>setopt NO_GL^D</code>' and you should see something like:</p>
|
|
<pre><code> NO_GLob NO_GLobassign NO_GLobdots
|
|
NO_GLobalrcs NO_GLobcomplete NO_GLobsubst
|
|
</code></pre>
|
|
<p>--- after the bit you've typed, the form of the words reverts to
|
|
whatever's in the trial completion, i.e. lowercase letters with no
|
|
`<code>_</code>'s.</p>
|
|
<p><span id="l173"></span></p>
|
|
<h3 id="673-partial-word-completion"><a class="header" href="#673-partial-word-completion">6.7.3: Partial word completion</a></h3>
|
|
<p>This example shows the other sort of anchoring, on the right, and also
|
|
how to use a `<code>*</code>' in the right hand part of a pattern. Consider:</p>
|
|
<pre><code> zstyle ':completion:*' matcher-list 'r:|.=* r:|=*'
|
|
</code></pre>
|
|
<p>The `<code>r:</code>' specifies a right-anchored match, using the characters from
|
|
the trial completion rather than what's already on the command line. As
|
|
the anchor is on the right this time, the pattern (between `<code>:</code>' and
|
|
`<code>|</code>') is empty, and its anchor (between `<code>|</code>' and `<code>=</code>') is `<code>.</code>'.
|
|
So this specifies that nothing --- a zero length string, or a gap
|
|
between characters if you want to think of it like that --- when
|
|
followed by a `<code>.</code>', matches anything at all in the trial completion.</p>
|
|
<p>Consequently, the second part says that nothing anchored on the right by
|
|
nothing --- in other words, the right hand end of the command line
|
|
string --- matches anything. This is what completion normally does, add
|
|
anything at all at the end of the string; we've added this part to the
|
|
matcher in case the cursor is in the middle of the word. It means that
|
|
the right hand end will always be completed, too.</p>
|
|
<p>Let's see that in action. Here are the actual contents of my actual
|
|
<code>tmp</code> directory, never mind why:</p>
|
|
<pre><code> regframe.rpm t.c testpage.dvi testpage.log testpage.ps
|
|
</code></pre>
|
|
<p>Now I set the <code>matcher-list</code> style as above and type:</p>
|
|
<pre><code> echo t.p<TAB>
|
|
</code></pre>
|
|
<p>and get</p>
|
|
<pre><code> echo testpage.ps
|
|
</code></pre>
|
|
<p>So, apart from the normal completion at the end (<code>p</code> to <code>ps</code>), the empty
|
|
string followed by a <code>.</code> was allowed to match anything, too, and I got
|
|
the effect of completing both bits of the word.</p>
|
|
<p>You might wonder what happens when there's a file <code>testpage.old.ps</code>
|
|
around, i.e. the anchor appears twice in that. With the matcher set as
|
|
given above, that won't be completed; the anchor needs to be matched
|
|
explicitly, not by a wildcard. If you don't like that, you can change
|
|
the `<code>*</code>' after the `<code>=</code>' in the specification to `<code>**</code>'; this form
|
|
allows the anchor to occur in the string being matched. You can think of
|
|
`<code>*</code>' and `<code>**</code>' as taking the shortest and the longest possible
|
|
matches respectively. If you use a lot of `<code>**</code>' specifications in your
|
|
matches, things can get very confusing, however.</p>
|
|
<p>Other shells have a facility for completing inside words like this,
|
|
where it goes by such names as `enhanced' completion, although it is
|
|
usually not so flexible. In the case of tcsh, not just `<code>.</code>' but also
|
|
`<code>-</code>' and `<code>_</code>' have this effect. You can force this with</p>
|
|
<pre><code> zstyle ':completion:*' matcher-list 'r:|[._-]=* r:|=*'
|
|
</code></pre>
|
|
<p><span id="l174"></span></p>
|
|
<h3 id="674-substring-completion"><a class="header" href="#674-substring-completion">6.7.4: Substring completion</a></h3>
|
|
<p>I've mentioned `<code>r</code>' and `<code>B</code>', but corresponding to `<code>r</code>' there is
|
|
`<code>l</code>', which anchors on the left instead of the right, and
|
|
corresponding to `<code>B</code>' there is `<code>E</code>' which matches at the end instead
|
|
of the beginning; and, of course, all exist in both upper- and lowercase
|
|
forms, meaning `keep what the user typed' and `keep what is in the
|
|
list of possible matches', respectively.</p>
|
|
<p>Here is an example of using `<code>l:|=*</code>' to match anything at the start of
|
|
the word: this is the effect of having an empty anchor, as you saw with
|
|
`<code>r</code>' above, but note with `<code>l</code>', the anchor appears, logically
|
|
enough, on the left of the `<code>|</code>', in the order they would appear on the
|
|
command line. By combining this with the `<code>r</code>' form, you can make the
|
|
completion system work when what is on the command line matches only a
|
|
substring of a trial completion --- i.e., has anything else on the left
|
|
and on the right. Since this can potentially generate a lot of matches,
|
|
it might by an idea to try it after any other matcher specifications you
|
|
have. So the following tries case-insensitive completion, then
|
|
partial-word completion (case-sensitively), then substring completion:</p>
|
|
<pre><code> zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}' \
|
|
'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
|
|
</code></pre>
|
|
<p><span id="l175"></span></p>
|
|
<h3 id="675-partial-words-with-capitals"><a class="header" href="#675-partial-words-with-capitals">6.7.5: Partial words with capitals</a></h3>
|
|
<p>This section illustrates another feature: if you use `<code>||</code>' when
|
|
specifying anchors for `<code>L</code>' or `<code>R</code>' or their lowercase variants, the
|
|
pattern part for what appears on the command line, which would usually
|
|
be translated into some other pattern, is treated instead as another
|
|
anchor on the other side of the pattern --- which isn't matched against
|
|
the pattern in the word, it just has to appear. In other words, this
|
|
part matches without being `swallowed up' in the process. An example
|
|
(again adapted from the manual) will make this clearer.</p>
|
|
<pre><code> compadd -M 'r:[^A-Z0-9]||[A-Z0-9]=** r:|=*' \
|
|
LikeTHIS LooHoo foo123 bar234
|
|
</code></pre>
|
|
<p>The four possible completions are on the second line. The second of the
|
|
two matcher specifications just allows anything to match on the right,
|
|
so if we are inside the word, the remainder may be completed. The first
|
|
word is where the action is; it says `A part of the completion which
|
|
has on the left something other than an upper case letter or a digit,
|
|
and on the right an upper case letter or a digit, may match anything,
|
|
including the anchor'. So in particular, this would allow `<code>LH</code>' to
|
|
complete to `<code>LooHoo</code>' --- and only that, since `<code>LikeTHIS</code>' has an
|
|
uppercase letter to the left of the `<code>H</code>', which is not allowed. In
|
|
other words, the chunks of word beginning with uppercase letters and
|
|
digits act like the start of substrings. (If you like, remember that
|
|
last sentence and the specification, and forget the rest.)</p>
|
|
<p><span id="l176"></span></p>
|
|
<h3 id="676-final-notes"><a class="header" href="#676-final-notes">6.7.6: Final notes</a></h3>
|
|
<p>To put everything together, the possible specifications are
|
|
`<code>m:...=...</code>', `<code>l:...|...=...</code>', `<code>r:...|...=...</code>',
|
|
`<code>b:...|...=...</code>' and `<code>e:...|...=...</code>', which cause the command line
|
|
to be altered to the match found, and their counterparts with an
|
|
uppercase letter, which cause what's already on the command line to be
|
|
left alone and the remaining characters to be inserted directly from the
|
|
completion found. The `<code>...</code>' are patterns, which all use the same
|
|
format. They can include literal characters, a `<code>?</code>', and character or
|
|
correspondence classes, while the rightmost pattern in each type may
|
|
also consist of a `<code>*</code>' on its own. Characters are matched from left to
|
|
right; a missing character matches an empty string, `<code>*</code>' matches any
|
|
number of characters. Specifications may be joined in a single string,
|
|
in which case all parts will be applied together.</p>
|
|
<p>When using the <code>matcher-list</code> style, a list of different specifications
|
|
can be given; in this case, they will be tried in turn until one of them
|
|
generates matches, and the rest will not be used.</p>
|
|
<p>There's another style apart from <code>matcher-list</code>, called <code>matcher</code>. This
|
|
can be set for a particular context, possibly with specific tags, and
|
|
will add the given matcher specifications using exactly the same syntax
|
|
as <code>matcher-list</code> for that context, except that here all specifications
|
|
are used at once, even if they are given as different elements of an
|
|
array. This is possibly useful because <code>matcher-list</code> is only aware of
|
|
the completer, not of any more specific part of the context.</p>
|
|
<p>Although I won't talk about matching control after this section, there
|
|
may be cases where you want to include `<code>compadd -M ...</code>' in a
|
|
completion function of your own to help the user. Many of the existing
|
|
completion functions provide partial word completion where it seems
|
|
useful; for example, completion of zle functions allows <code>i-c-w</code> to be
|
|
completed to <code>incremental-complete-word</code> in this way.</p>
|
|
<p>Actually, you can configure this to a considerable extent without
|
|
altering a function, using styles and labelled tags. From the manual:</p>
|
|
<pre><code> zstyle ':completion:*:*:foo:*' tag-order '*' '*:-case'
|
|
zstyle ':completion:*-case' matcher 'm:{a-z}={A-Z}'
|
|
</code></pre>
|
|
<p>In command <code>foo</code>, whatever the tags are, they are to be tried normally
|
|
first (the `<code>*</code>' argument to <code>tag-order</code>), then under the same name
|
|
with `<code>-case</code>' appended. The second style defines a matcher for any tag
|
|
ending in the suffix `<code>-case</code>', which allows lowercase characters to
|
|
match uppercase ones. The upshot is that completion of anything at all
|
|
for the command <code>foo</code> will be tried first case-sensitively, then
|
|
case-insensitively.</p>
|
|
<p><span id="l177"></span></p>
|
|
<h2 id="68-tutorial"><a class="header" href="#68-tutorial">6.8: Tutorial</a></h2>
|
|
<p>Before bamboozling you with everything there is to know about writing
|
|
your own completion function, I'll give you an example of something I
|
|
wrote myself recently. If you were doing this yourself, you would then
|
|
just stick this function somewhere in your function search path, and
|
|
next time you started the shell it would start doing its work. However,
|
|
the file already exists: it's called <code>_perforce</code> and you should find it
|
|
in the function search for versions 4.1.1 and above of zsh. I apologize
|
|
if it's not the ideal function to start with, but it is fresh in my
|
|
mind, so what I'm saying has some chance of being correct.</p>
|
|
<p>This section is subtitled, `How I struggled to write a set of
|
|
completions for Perforce'. Perforce is a commercial configuration
|
|
management tool (as they now call revision control systems); consult
|
|
<a href="http://www.perforce.com/">http://www.perforce.com/</a> for details. It's concepts aren't a million
|
|
miles from CVS, the archetypal system of this kind, but it was
|
|
sufficiently different that the completion functions needed rewriting
|
|
from the ground up. You won't need to know anything about CVS or
|
|
Perforce, because at each stage I'll explain what I'm trying to complete
|
|
and why. This should give you plenty of meat for writing completions of
|
|
your own. After the tutorial, the chapter goes into the individual
|
|
details, which will expand on some of the things that appeared briefly
|
|
in the tutorial.</p>
|
|
<p>What I tend to find the most complicated part of this is making sure the
|
|
completion system knows the correct types of completions and their tags
|
|
to be completed at once. This probably won't be your first priority when
|
|
trying to write completions of your own, but if you do it right, all the
|
|
stuff about selecting types and arranging them in groups that I showed
|
|
above will just work. In this tutorial we arrange to use enough of the
|
|
higher level functions that it will work without too much (apparent)
|
|
effort. Of course, working out from scratch which those functions are
|
|
isn't always that easy; hence the tutorial.</p>
|
|
<p>Needless to say, I will simplify grossly at a lot of points. You can see
|
|
the finished product in the zsh 4.1 distribution. It even has a few
|
|
comments in.</p>
|
|
<p><strong>Basic structure</strong></p>
|
|
<p>Like the <code>cvs</code> command and a few other of the more complicated commands
|
|
you might use, Perforce is run by a single command, <code>p4</code>, followed by an
|
|
argument giving the particular Perforce command, followed by an options
|
|
and arguments to that command.</p>
|
|
<p>This dictates the basic tasks the completion functions must do:</p>
|
|
<ul>
|
|
<li>If we are in the first argument, complete the name of the
|
|
subcommand.</li>
|
|
<li>If we are in a subsequent argument, look up the name of the
|
|
subcommand and call the function which handles its arguments.</li>
|
|
</ul>
|
|
<p>This is more complicated than most commands you will write completions
|
|
for. However, one useful feature of the completion system is you can do
|
|
completions in a recursive fashion. So once you get to the point where
|
|
you are handling arguments for a particular subcommand, you can
|
|
completely forget about the first step --- as if the subcommand was the
|
|
command on the line.</p>
|
|
<p>In addition to the subcommands, there are lots of other types of object
|
|
Perforce knows about: files, obviously, plus revisions of files, set of
|
|
changes (`changelists') applied at once, numbers of fixes applied to
|
|
files (essentially a way of tying changlists to a particular change
|
|
request for bugtracking purposes), types of file --- text, binary, etc.,
|
|
and several others. We will break down each of these completions into
|
|
its own function. That means that any time we need to complete a
|
|
particular type of object, wherever it appears (and many of these
|
|
objects can appear in lots of different places), we just call the same
|
|
function.</p>
|
|
<p>Hence there are a large number of different functions:</p>
|
|
<ul>
|
|
<li>The main dispatcher for the command, called <code>_perforce</code> for clarity
|
|
--- the main command it handles is `<code>p4</code>', but the name Perforce is
|
|
more familiar.</li>
|
|
<li>One function for each subcommand.</li>
|
|
<li>One function for each type of object Perforce knows about and we
|
|
complete (we don't bother completing dates, for example).</li>
|
|
<li>In some cases, in particular files, multiple functions since there
|
|
are different types of file --- regular files and directories
|
|
completed in the normal way, files completed by asking Perforce
|
|
where it has stored them, files opened for some form of change to be
|
|
made to them, and so on. Each of these is completed by a different
|
|
function.</li>
|
|
</ul>
|
|
<p>This makes it impractical to put all the functions in separate files
|
|
since editing them would be a nightmare. What's more, since we will
|
|
always go through the dispatcher <code>_perforce</code>, we don't need to tell the
|
|
shell to autoload all the other functions; it can just hook them in from
|
|
the main file. The file <code>_perforce</code> therefore has the structure:</p>
|
|
<pre><code> #compdef p4
|
|
# Main dispatcher
|
|
_perforce() {
|
|
# ...
|
|
}
|
|
|
|
# Helper functions for the various types of object
|
|
|
|
_perforce_files() {
|
|
# ...
|
|
}
|
|
|
|
# ...
|
|
|
|
# Dispatchers for the individual subcommands.
|
|
|
|
_perforce_cmd_help() {
|
|
# ...
|
|
}
|
|
|
|
# Code to make sure _perforce is run when we load it
|
|
_perforce "$@"
|
|
</code></pre>
|
|
<p>That last line is probably the least obvious. It's because of the fact
|
|
that zsh (unlike other shells) usually treats the file of an autoloaded
|
|
function as being the body of the function. Since everything else here
|
|
just defines a function, without the last line nothing would happen the
|
|
first time it was run; it would define <code>_perforce</code> and all the other
|
|
functions, but that was it. The last line makes sure <code>_perforce</code> gets
|
|
run with all the arguments passed down. The shell is smart enough to
|
|
know that the <code>_perforce</code> function we defined in the file is the one to
|
|
keep for future use, not the entire file, so from then on things are
|
|
easy; we just have a complete set of ready-defined files.</p>
|
|
<p>In fact the various helper functions didn't even need to use the `<code>_</code>'
|
|
convention for completion functions, since the completion system didn't
|
|
see them directly. However, I've kept it for consistency.</p>
|
|
<p>There's one extra trick: apart from <code>_perforce</code> itself, the function
|
|
definitions look like this:</p>
|
|
<pre><code> (( $+functions[_perforce_cmd_diff] )) ||
|
|
_perforce_cmd_diff() {
|
|
# body of function
|
|
}
|
|
</code></pre>
|
|
<p>This is to allow the user to override each function separately. The test
|
|
uses the <code>$functions</code> special associative array from the <code>zsh/parameter</code>
|
|
module, which the completion system loads. If the function is already
|
|
defined, because the corresponding element in the <code>$functions</code> parameter
|
|
is set, then we skip the definition of the function here, because the
|
|
user has already defined it. So if you were to write your own
|
|
<code>_perforce_cmd_diff</code> and put it into the function path, it would be
|
|
used, as you no doubt intended.</p>
|
|
<p><span id="l178"></span></p>
|
|
<h3 id="681-the-dispatcher"><a class="header" href="#681-the-dispatcher">6.8.1: The dispatcher</a></h3>
|
|
<p>This top level is only necessary for complex commands with multiple
|
|
subcommands. There are interesting titbits here, but if you just want to
|
|
know how to complete a command with ordinary UNIX-style argument
|
|
parsing, skip to the next section.</p>
|
|
<p>The main <code>_perforce</code> function has the two purposes described at the top
|
|
of the previous subsection. We need to decide whether we are in the
|
|
first word after the <code>p4</code> command itself. A simple way of doing that is:</p>
|
|
<pre><code> if (( CURRENT > 2 )); then
|
|
# Remember the subcommand name
|
|
local cmd=${words[2]}
|
|
# Set the context for the subcommand.
|
|
curcontext="${curcontext%:*:*}:p4-$cmd"
|
|
# Narrow the range of words we are looking at to exclude `p4'
|
|
(( CURRENT-- ))
|
|
shift words
|
|
# Run the completion for the subcommand
|
|
_perforce_cmd_$cmd
|
|
else
|
|
local hline
|
|
local -a cmdlist
|
|
_call_program help-commands p4 help commands | while read -A hline; do
|
|
(( ${#hline} < 2 )) && continue
|
|
[[ $hline[1] = (#i)perforce ]] && continue
|
|
cmdlist=($cmdlist "${hline[1]}:${hline[2,-1]}")
|
|
done
|
|
_describe -t p4-commands 'Perforce command' cmdlist
|
|
fi
|
|
</code></pre>
|
|
<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
|
|
that follow the tutorial.</p>
|
|
<p><span id="l179"></span></p>
|
|
<h3 id="682-subcommand-completion-_arguments"><a class="header" href="#682-subcommand-completion-_arguments">6.8.2: Subcommand completion: <code>_arguments</code></a></h3>
|
|
<p>Suppose we are now completing after `<code>p4 diff</code>'. We have altered the
|
|
command line so that the function now sees the `<code>diff</code>' as the first
|
|
word, as if this were the command. This makes the next step easier; the
|
|
<code>_arguments</code> function won't see irrelevant words on the command line,
|
|
since it is designed to handle the arguments to a simple command in the
|
|
standard form `<code>command [ options ] arguments ...</code>'. Here's the simple
|
|
version.</p>
|
|
<pre><code>
|
|
_perforce_cmd_diff() {
|
|
_arguments -s : \
|
|
'-f[diff every file]' \
|
|
'-t[include non-text files]' \
|
|
'(-sd -se -sr)-sa[opened files, different or missing]' \
|
|
'(-sa -se -sr)-sd[unopened files, missing]' \
|
|
'(-sa -sd -sr)-se[unopened files, different]' \
|
|
'(-sa -sd -se)-sr[opened files, same as depot]' \
|
|
'-d-[select diff option]:diff option:'\
|
|
'((b\:ignore\ blanks c\:context n\:RCS s\:summary'\
|
|
'u\:unified w\:ignore\ all\ whitespace))' \
|
|
"*::file:_perforce_files"
|
|
}
|
|
</code></pre>
|
|
<p>I've split the argument beginning <code>-d</code> into three lines to fit, but it's
|
|
just a single argument. Also, for clarity I've missed out the line with
|
|
the `<code>$+functions</code>' test to see if <code>_perforce_cmd_diff</code> was already
|
|
defined; I'll forget about that for now.</p>
|
|
<p>The function <code>_arguments</code> has been described as having `the syntax from
|
|
hell', but with the arguments already laid out in front of you it
|
|
doesn't look so bad. The are three types of argument: options to
|
|
<code>_arguments</code> itself, arguments saying how to handle options to the
|
|
command (i.e. `<code>p4 diff</code>'), and arguments saying how to handle normal
|
|
arguments to the command.</p>
|
|
<p>The first two are for <code>_arguments</code> itself; `<code>-s</code>' tells it that
|
|
single-letter options are allowed, i.e. they can be combined as in
|
|
`<code>-ft</code>'. Luckily for our purposes, that doesn't stop us having multiple
|
|
word options, too. The colon on its own then says everything else is an
|
|
argument relating to the command line being handled.</p>
|
|
<p>We then start off with some simple options; as you can probably guess
|
|
straight away, the first two say that `<code>p4 diff -f</code>' passes a flag to
|
|
say any file can be diff'ed (not just ones open for editing), and that
|
|
`<code>p4 diff -t</code>' passes a flag to say that binary files can be diff'ed
|
|
(not just text files). Note the use of square brackets for giving a
|
|
description; this is handled by the <code>verbose</code> style as I mentioned for
|
|
<code>_describe</code>. In fact, the list of possible options and arguments,
|
|
suitably rearranged, will end up passing through <code>_describe</code>. The
|
|
descriptions in square brackets are optional, as the use of square
|
|
brackets might suggest; you could just have `<code>-f</code>' and `<code>-t</code>' (making
|
|
it fairly obvious why the `<code>:</code>' to separate off _arguments's own
|
|
options is a good idea).</p>
|
|
<p>The next step in complexity is that set of functions with the list in
|
|
parentheses in front. These give mutually exclusive options. In other
|
|
words, if there's already a <code>-sa</code> on the command line, don't complete
|
|
any of <code>-sd</code>, <code>-se</code> or <code>-sr</code>, and so on. (Remember that by default you
|
|
need to type the first `<code>-</code>' of an option, or the system will go
|
|
straight to normal arguments, which we'll come to in a moment.)</p>
|
|
<p>Next comes the specification for the option <code>-d</code>. All those colons
|
|
indicate that this option has an argument, and the <code>-</code> following
|
|
straight after the <code>-d</code> indicates that it has to be in the same word,
|
|
i.e. follow the <code>-d</code> without a space. After the first colon comes a
|
|
description for the argument. This is what you see when you try to
|
|
complete the after <code>-d</code>; compare this with the expression in square
|
|
brackets before, which is what you see when you try to complete the <code>-d</code>
|
|
itself. Then after the second colon is an expression saying how to
|
|
complete that argument.</p>
|
|
<p>This final part of the specification for an option with an argument can
|
|
take various forms. The simplest is just a single space; this means
|
|
there's nothing to complete, but the system is aware the user needs to
|
|
type something for that word and can prompt with the description. The
|
|
next simplest is a set of words in parentheses: here, we could have had
|
|
`<code>(b c n s u w)</code>'. Instead, we've had a variant on that which gives yet
|
|
another set of descriptions, namely those for the individual completions
|
|
that appear after <code>-d</code>. Note various things: the parentheses are doubled
|
|
and the colons and spaces within the completion options are backslashed.
|
|
All of these are simply there to make it easy for <code>_arguments</code> to parse
|
|
the string. The upshot of this is that in the following context:</p>
|
|
<pre><code> p4 diff -d
|
|
</code></pre>
|
|
<p>a verbose completion using the <code>format</code> style as described above looks
|
|
like:</p>
|
|
<pre><code> Completing diff option
|
|
b # ignore blanks
|
|
c # context
|
|
n # RCS
|
|
s # summary
|
|
u # unified
|
|
w # ignore all whitespace
|
|
</code></pre>
|
|
<p>or similar --- I have the <code>list-separator</code> style set to `<code>#</code>', because
|
|
it looks like a comment normal shell syntax, but in your case you may
|
|
get `<code>-``-</code>' as the separator.</p>
|
|
<p>(In case you were wondering why the colons needed to be quoted when it
|
|
seemed you'd already got to the last argument: it's possible for options
|
|
to have multiple arguments, and you can continue having sets of
|
|
<code>:</code><em>description</em><code>:</code><em>action</em> pairs. This means the system needs some way
|
|
of distinguishing these colons from ones inside arguments. While I'm
|
|
digressing, you may also have noticed that I could have written the
|
|
<code>-s</code><em>X</em> as an option with arguments, in which case you can have a bonus
|
|
point.)</p>
|
|
<p>The final argument starts with a `<code>*</code>', which means it applies to all
|
|
remaining arguments to `<code>p4 diff</code>' after the options have been
|
|
processed. Most of the rest is similar to the form for options, except
|
|
for the doubled colon, which indicates that <code>$CURRENT</code> and <code>$words</code>
|
|
should be altered to reflect only the arguments being handled by this
|
|
argument specifier --- exactly what we did before calling
|
|
<code>_perforce_cmd_diff</code> in the first place, in fact. As we mentioned
|
|
before, this makes the next step of processing easier if happens to call
|
|
<code>_arguments</code> again. (Actually it doesn't in this case.) The `<code>file</code>'
|
|
then describes the arguments and the final part, <code>_perforce_files</code>,
|
|
tells the system to call that function to complete a file name.</p>
|
|
<p>There are numerous (it sometimes seems, endless) subtleties to
|
|
<code>_arguments</code>. I won't try to go into them in the tutorial; see the
|
|
description of <code>_arguments</code> below for something more detailed to refer
|
|
to, and if you are feeling <em>really</em> brave look at the description in the
|
|
<code>zshcompsys</code> manual page. Even better, dig into one of the existing
|
|
completion functions --- something handling completion for a UNIX
|
|
command is probably good, since these make heavy use of <code>_arguments</code> ---
|
|
and see how those work. Despite the complexities, I would definitely
|
|
suggest using <code>_arguments</code> wherever possible to take away any need on
|
|
your part to do processing of command line arguments.</p>
|
|
<p><span id="l180"></span></p>
|
|
<h3 id="683-completing-particular-argument-types"><a class="header" href="#683-completing-particular-argument-types">6.8.3: Completing particular argument types</a></h3>
|
|
<p>Now we'll look inside the <code>_perforce_files</code> function as an example of
|
|
the nitty gritty of completing one particular type of argument, which
|
|
might have some quite complicated internal structure. This is true in
|
|
Perforce as the filename can have extra information tacked on the end:
|
|
`<code>file#</code><em>revision</em>' indicates the revision of a file,
|
|
`<code>file@</code><em>change</em>' indicates a change status, and in some cases you can
|
|
get `<code>file@</code><em>change1</em><code>,</code><em>change2</em>' to indicate a range of changes
|
|
(likewise revisions). Furthermore, <code>file</code> can be specified in different
|
|
ways, and the file to be completed may be limited by some kind of
|
|
context information. We'll start from simple filenames and gradually add
|
|
these possibilities in.</p>
|
|
<p><strong>Different types of file, part 1</strong></p>
|
|
<p>There are so many possibilities for files that I'm going to split up
|
|
<code>_perforce_files</code> into individual functions handling different aspects.
|
|
For example, even if we are just handling ordinary files in the way the
|
|
completion system normally does, Perforce commands understand a special
|
|
file name `<code>...</code>' which means `every subdirectory to any depth'.
|
|
(Interestingly, zsh used to have this to mean the same thing, instead of
|
|
`<code>**</code>'; it was changed in zsh because as the `<code>.</code>'s are regular
|
|
characters there's no easy way of quoting them. You didn't need to know
|
|
this.)</p>
|
|
<p>I'm going to say we can complete both like this:</p>
|
|
<pre><code> _alternative \
|
|
"files:file:_path_files" \
|
|
"subdirs:subdirectory search:_perforce_subdir_search"
|
|
</code></pre>
|
|
<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'
|
|
)
|
|
# add other alternatives, such as the `...' thing
|
|
altfiles=($altfiles
|
|
"subdirs:subdirectory search:_perforce_subdir_search"
|
|
)
|
|
_alternative $altfiles
|
|
else
|
|
_alternative \
|
|
"files:file:_path_files" \
|
|
"subdirs:subdirectory search:_perforce_subdir_search"
|
|
fi
|
|
</code></pre>
|
|
<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>
|
|
<pre><code> _perforce_depot_files() {
|
|
# Normal completion of files in depots
|
|
local pfx=${(Q)PREFIX} expl
|
|
local -a files
|
|
|
|
compset -P '*/'
|
|
files=(${${${(f)"$(\
|
|
_call_program files p4 files \
|
|
\"\$pfx\*\$\{\(Q\)SUFFIX\}\" 2>/dev/null)"}%\#*}##*/})
|
|
[[ $#files -eq 1 && $files[1] = '' ]] && files=()
|
|
compadd "$@" -a files
|
|
}
|
|
</code></pre>
|
|
<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
|
|
numbers with the all-important descriptions.</p>
|
|
<pre><code> _perforce_revisions() {
|
|
local rline match mbegin mend pfx
|
|
local -a rl
|
|
|
|
pfx=${${(Q)PREFIX}%%\#*}
|
|
compset -P '*\#'
|
|
|
|
# Numerical revision numbers, possibly with text.
|
|
if [[ -z $PREFIX || $PREFIX = <-> ]]; then
|
|
# always allowed (same as none)
|
|
rl=($rl 0)
|
|
_call_program filelog p4 filelog \$pfx 2>/dev/null |
|
|
while read rline; do
|
|
if [[ $rline = (#b)'... #'(<->)*\'(*)\' ]]; then
|
|
rl=($l "${match[1]}:${match[2]}")
|
|
fi
|
|
done
|
|
fi
|
|
# Non-numerical (special) revision names.
|
|
if [[ -z $PREFIX || $PREFIX != <-> ]]; then
|
|
rl=($rl 'head:head revision' 'none:empty revision'
|
|
'have:current synced revision')
|
|
fi
|
|
_describe -t revisions 'revision' rl
|
|
}
|
|
</code></pre>
|
|
<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><span id="l181"></span></p>
|
|
<h3 id="684-the-rest"><a class="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><span id="l182"></span></p>
|
|
<h2 id="69-writing-new-completion-functions-and-widgets"><a class="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
|
|
suggest this to us.</p>
|
|
<p><span id="l183"></span></p>
|
|
<h3 id="691-loading-completion-functions-compdef"><a class="header" href="#691-loading-completion-functions-compdef">6.9.1: Loading completion functions: <code>compdef</code></a></h3>
|
|
<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
|
|
<code>#compdef</code> inside completion functions.</p>
|
|
<p><span id="l184"></span></p>
|
|
<h3 id="692-adding-a-set-of-completions-compadd"><a class="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><span id="l185"></span></p>
|
|
<h3 id="693-functions-for-generating-filenames-etc"><a class="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><span id="l186"></span></p>
|
|
<h3 id="694-the-zshparameter-module"><a class="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.
|
|
First, the associative arrays.</p>
|
|
<ul>
|
|
<li><strong><code>$aliases</code>, <code>$dis_aliases</code>, <code>$galiases</code></strong><br />
|
|
The keys of these arrays give ordinary aliases, disabled ordinary
|
|
aliases for those where you have done <code>disable -a <alias></code> to turn
|
|
them off temporarily, and global aliases as defined with <code>alias -g</code>.</li>
|
|
<li><strong><code>$builtins</code>, <code>$dis_builtins</code></strong><br />
|
|
The keys give active and disabled shell builtin commands.</li>
|
|
<li><strong><code>$commands</code></strong><br />
|
|
The keys are all external commands stored in the shells internal
|
|
tables; it does this both for the purposes of fast completion, and
|
|
to avoid having to search each time a command is executed. It's
|
|
possible that a command is missing or incorrectly stored if the
|
|
contents of your <code>$path</code> directories has changed since the shell
|
|
last updated its tables; the <code>rehash</code> command fixes it.</li>
|
|
<li><strong><code>$functions</code>, <code>$dis_functions</code></strong><br />
|
|
The keys are active and disabled shell functions.</li>
|
|
<li><strong><code>$history</code></strong><br />
|
|
Here, the <em>values</em> are complete lines stored in the internal
|
|
history. The keys are the numbers of the history line; it's an
|
|
associative, rather than an ordinary, array because they don't
|
|
necessarily start at line 1. However, see the <code>historywords</code>
|
|
ordinary array below.</li>
|
|
<li><strong><code>$jobtexts</code>, <code>$jobdirs</code>, <code>$jobstates</code></strong><br />
|
|
These give you information about jobs; the keys are the job numbers,
|
|
as presented by the <code>jobs</code> command, and the values give you the
|
|
other information from jobs: <code>$jobtexts</code> tells you what the job is
|
|
executing, <code>$jobdirs</code> its working directory, and <code>$jobstates</code> its
|
|
state, where the bit before the colon is the most useful as it
|
|
refers to the whole job. The remainder describes the state of
|
|
individual processes in the job.</li>
|
|
<li><strong><code>$modules</code></strong><br />
|
|
The keys give the names of modules which are currently available to
|
|
the shell, i.e. loaded or to be autoloaded, essentially the same
|
|
principle as with functions.</li>
|
|
<li><strong><code>$nameddirs</code></strong><br />
|
|
If you have named directories, either explicitly (e.g. assigning
|
|
`<code>foo=/mydir</code>' and using `<code>~foo</code>') or via the <code>AUTO_NAME_DIRS</code>
|
|
option, the keys of this associative array give the names and the
|
|
values the expanded directories.</li>
|
|
<li><strong><code>$options</code>, <code>$parameters</code></strong><br />
|
|
The keys give shell options and parameters, and are used by the
|
|
functions <code>_options</code> and <code>_parameters</code> for completion, so you will
|
|
mostly not need to refer to them directly.</li>
|
|
<li><strong><code>$userdirs</code></strong><br />
|
|
The keys give all the users on the system. The values give the
|
|
corresponding home directory, so `<code>${userdirs[juser]}</code>' is
|
|
equivalent to having <code>~juser</code> expanded and is thus not all that
|
|
interesting, except that by doing it this way you can test whether
|
|
the expansion exists without causing an error.</li>
|
|
</ul>
|
|
<p>Now here are the ordinary arrays, which you would therefore refer to
|
|
simply as <code>${reswords}</code> etc.</p>
|
|
<ul>
|
|
<li><strong><code>$dirstack</code></strong><br />
|
|
This contains your directory stack, what you see with `<code>dirs -v</code>'.
|
|
Note, however that the current directory, which appears as number 0
|
|
with that command, doesn't appear in <code>dirstack</code>. Of course it's easy
|
|
to add it to a completion if you want.</li>
|
|
<li><strong><code>$funcstack</code></strong><br />
|
|
This is the call stack of functions, i.e. all the functions which
|
|
are active at the time the array was referenced. <code>^Xh</code> uses this to
|
|
display which functions have been called for completion.</li>
|
|
<li><strong><code>$historywords</code></strong><br />
|
|
Unlike <code>$history</code>, this contains just the individual words of the
|
|
shell's command line history, and is therefore likely to be more
|
|
useful for completion purposes.</li>
|
|
<li><strong><code>$reswords</code>, <code>$dis_reswords</code></strong><br />
|
|
The active and disabled reserved words (effectively syntactically
|
|
special commands) understood by the shell.</li>
|
|
</ul>
|
|
<p><strong>Other ways of getting at information</strong></p>
|
|
<p>Since the arguments to <code>compadd</code> undergo all the usual shell expansions,
|
|
it's easy to get words from other sources for completion, and you can
|
|
look in the existing completion functions for many examples. A good
|
|
understanding of zsh's parameter and command expansion mechanisms and a
|
|
strong stomach will be useful here.</p>
|
|
<p>For example, here is the expansion used by the <code>_limits</code> function to
|
|
retrieve the names of resource limits from the <code>limit</code> command itself:</p>
|
|
<pre><code> print ${${(f)"$(limit)"}%% *}
|
|
</code></pre>
|
|
<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><span id="l187"></span></p>
|
|
<h3 id="695-special-completion-parameters-and-compset"><a class="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>
|
|
<pre><code> #compdef - nohup nice eval time rusage noglob nocorrect exec
|
|
|
|
shift words
|
|
(( CURRENT-- ))
|
|
|
|
_normal
|
|
</code></pre>
|
|
<p>It applies for all the standard commands which do nothing but evaluate
|
|
their remaining arguments as a command, with some change of state, e.g.
|
|
ignoring a certain signal (<code>nohup</code>) or altering the priority (<code>nice</code>).
|
|
All the completion system does here is shift the first word off the end
|
|
of the <code>$words</code> array, decrement the index of the current word into
|
|
<code>$words</code>, and call <code>_normal</code>. This is the function called when
|
|
completion occurs not in one of the special <code>-context-</code>s, in other words
|
|
when an argument to an ordinary command is being completed. It will look
|
|
at the new command word <code>$words[1]</code>, which was previously the first
|
|
argument to <code>nohup</code> or whatever, and start completion again based on
|
|
that, or even complete that word itself as a command if necessary. The
|
|
net effect is that the first word is ignored completely, as required.</p>
|
|
<p>Here's just an edited chunk of the file <code>_user_at_host</code>; as its name
|
|
suggests, it completes words of the form <code><user>@<host></code>, and it's used
|
|
anywhere the <code>user-hosts</code> style, described above, is appropriate:</p>
|
|
<pre><code> if [[ -prefix 1 *@ ]]; then
|
|
local user=${PREFIX%%@*}
|
|
|
|
compset -P 1 '*@'
|
|
|
|
# complete the host for which we want the user
|
|
else
|
|
# no @, so complete the user
|
|
fi
|
|
</code></pre>
|
|
<p>We test to see if there is already a `<code><user>@</code>' part. If there is, we
|
|
extract the user with an ordinary parameter substitution (so ordinary
|
|
even other shells could do it). Then we strip off that from the bit to
|
|
be completed with <code>compset</code>; we already know it matches the prefix, so
|
|
we don't need to test the return value. Then we just do normal hostname
|
|
completion on what remains --- except that the <code>user-hosts</code> style might
|
|
be able to give us a clue as to which hosts have such a user. If the
|
|
original test failed, then we simply complete what's there as a user.</p>
|
|
<p>Finally, here is essentially what the function <code>_most_recent_file</code> uses
|
|
to extract the <code>$NUMERIC</code>th (default first) most recently modified file.</p>
|
|
<pre><code> local file
|
|
file=($~PREFIX*$~SUFFIX(om[${NUMERIC:-1}]N))
|
|
(( $#file )) && compadd -U -i "$IPREFIX" -I "$ISUFFIX" -f -Q - $file
|
|
</code></pre>
|
|
<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><span id="l188"></span></p>
|
|
<h3 id="696-fancier-completion-using-the-tags-and-styles-mechanism"><a class="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>
|
|
<pre><code> _tags sequences
|
|
while _tags; do
|
|
while _next_label sequences expl sequence; do
|
|
compadd "$expl[@]" $(mark $foldnam 2>/dev/null |
|
|
awk -F: '{ print $1 }') && ret=0
|
|
compadd "$expl[@]" reply next cur prev \
|
|
first last all unseen && ret=0
|
|
_files "$expl[@]" -W folddir -g '<->' && ret=0
|
|
done
|
|
(( ret )) || return 0
|
|
done
|
|
</code></pre>
|
|
<p>Here's what's going on. The <code>_tags</code> call works just as it did in the
|
|
first example I showed for that, deciding whether the tag in question,
|
|
<code>sequences</code>, has been asked for; the tag name comes because MH allows
|
|
you to define sets of messages called exactly `sequences'. The first
|
|
`<code>while</code>' selects all values from <code>tag-order</code> where the `<code>sequences</code>'
|
|
tag appears, with or without a label. The second `<code>while</code>' loop then
|
|
sorts out any occurrences of labelled sequences to be presented to the
|
|
user at the same time, i.e. given in the same element of the <code>tag-order</code>
|
|
value array. The first <code>compadd</code> extracts from the folder (MH's name for
|
|
a directory) identified by the function the names of any sequences you
|
|
have defined; the second adds a lot of standard sequences --- although
|
|
strictly speaking <code>unseen</code> isn't a standard sequence since you can name
|
|
it yourself in <code>~/.mh_profile</code>. Finally, the third adds files in the
|
|
folder itself whose names are just digits, which is how MH stores
|
|
messages. The handling of <code>return</code> makes sure it stops as soon as you
|
|
have matches for one particular element of <code>tag-order</code>; if you put it in
|
|
the inner loop, you would just have the first of those sets that
|
|
happened to be generated, while here, if you specify that all types of
|
|
sequence should appear in the same completion list, they are all
|
|
correctly collected.</p>
|
|
<p>Why, in that last example, is there no call to <code>_requested</code>, now I've
|
|
gone to the trouble of explaining what that does? The answer is that
|
|
there is only one tag; <code>_tags</code> can decide if we want it at all, and
|
|
after that the tag is known, so we don't need <code>_requested</code> to find that
|
|
information out for us. It's only needed if there is more than one type
|
|
of match --- indeed, that's why we introduced it, so this is not
|
|
actually a new complication, although you can be forgiven for thinking
|
|
otherwise.</p>
|
|
<p>Here's an example of using that code for sequences. You might decide
|
|
that you only want to see named sequences unless there aren't any,
|
|
otherwise ordinary messages. You could do this by setting your styles as
|
|
follows:</p>
|
|
<pre><code> zstyle ':completion:*' tag-order sequences:-name sequences:-num
|
|
zstyle ':completion:*:sequences-name' ignored-patterns '(|,)<->'
|
|
zstyle ':completion:*:sequences-num' ignored-patterns '^<->'
|
|
</code></pre>
|
|
<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>
|
|
<pre><code> local tmpcdpath
|
|
tmpcdpath=(${(@)cdpath:#.})
|
|
_alternative \
|
|
'local-directories:local directories:_path_files -/' \
|
|
'path-directories:directories in cdpath:
|
|
_path_files -W tmpcdpath -/'
|
|
</code></pre>
|
|
<p>The only tricky bit is that <code>$tmpcdpath</code>: it removes the `<code>.</code>' from
|
|
<code>$cdpath</code>, if it's present, so that the current directory is always
|
|
searched for with the tag `<code>local-directories</code>', never with
|
|
`<code>path-directories</code>'. Actually, you could argue that it should be
|
|
treated as being in `<code>path-directories</code>' when it's present; but that
|
|
confuses the issue over what `<code>local-directories</code>' really means, and it
|
|
is useful to have the distinction.</p>
|
|
<p>It's now an easy exercise to replace the example function I gave for
|
|
<code>_requested</code> by a call to <code>_alternative</code> with the arguments to <code>compadd</code>
|
|
turned into a list in parentheses as the <code><action></code> part of the
|
|
arguments to <code>_alternative</code>.</p>
|
|
<p><strong>How to look up styles</strong></p>
|
|
<p>If your completion function gets really sophisticated, you may want it
|
|
to look up styles to decide what its behaviour should be. The same
|
|
advice goes as for tags: only invent a new style if the old ones don't
|
|
seem to cover the use you want to make, since by using contexts you can
|
|
always restrict the scope of the style. However, by the same token don't
|
|
try to squeeze too much meaning into one style, which will force the
|
|
user to narrow the context --- it's always much easier to set a style
|
|
for the general context `<code>:completion:*</code>' than to have to worry about
|
|
all the circumstances where you need a particular value.</p>
|
|
<p>Retrieving values of styles is no harder than defining them, but you
|
|
will need to know about the parameter <code>$curcontext</code>, which is what
|
|
stores the middle part of the context, sans `<code>:completion:</code>' and sans
|
|
tag. When you need to look something up, you pass this context to
|
|
<code>zstyle</code> with `<code>:completion:</code>' stuck in front:</p>
|
|
<pre><code> zstyle -b ":completion:${curcontext}:tag" style-name parameter
|
|
</code></pre>
|
|
<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><span id="l189"></span></p>
|
|
<h3 id="697-getting-the-work-done-for-you-handling-arguments-etc"><a class="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
|
|
section by mentioning it again.</p>
|
|
<p><strong>Handling ordinary arguments</strong></p>
|
|
<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>
|
|
<pre><code> local context state line
|
|
typeset -A opt_args
|
|
|
|
_arguments '-type[specify type]:type:->type' \
|
|
'*:greek letter:->gklet' && return 0
|
|
|
|
case $state in
|
|
(type) compadd normal unusual && return 0
|
|
;;
|
|
(gklet) compadd alpha beta gamma && return 0
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
</code></pre>
|
|
<p>In fact the possibilities here are so simple that you don't need to use
|
|
<code>$state</code>; you can just use the form with the values in parentheses as
|
|
the action passed to `<code>_arguments</code>'. Anyway, if you put this into a
|
|
function `<code>_foo</code>', type `<code>compdef _foo foo</code>', and attempt completion
|
|
for the fictitious command `<code>foo</code>', you will see <code>_arguments</code> in
|
|
action.</p>
|
|
<p>I haven't shown the gory tag handling; as it's written, you'll see that
|
|
no tag is ever defined for the <code>compadd</code> arguments shown. In this case
|
|
you could just use <code>_wanted</code>. What you get for free with arguments,
|
|
however, is the context: in the first case, you would have
|
|
`<code>:option-type-1</code>' in the argument field (the second last, just before
|
|
the tag), and in the second case `<code>:argument-rest:</code>'. Go back to where
|
|
I originally described contexts if you've forgotten about these; I
|
|
didn't tell you at the time, but it's the <code>_argument</code> function that is
|
|
responsible for them. (However, you can supply a `<code>-C</code>' argument to
|
|
<code>_wanted</code> to tell that a context.)</p>
|
|
<p>A note about the form: that `<code>&& return 0</code>' makes the completion
|
|
function return if <code>_arguments</code> was satisfied that it found a completion
|
|
on its own. It's useful in more complex cases. Remember that most
|
|
completion functions return status zero if and only if matches were
|
|
added; this function is written to follow that convention. I already
|
|
showed this in the section on tags, but you might have skipped that.</p>
|
|
<p>Note all the things you had to make local: <code>$context</code>, <code>$state</code>, <code>$line</code>
|
|
and the associative array <code>$opt_args</code>. The last named allows you to
|
|
retrieve the values for a particular option; for example
|
|
`<code>$opt_args[-o]</code>' contains any value already on the command line for
|
|
the option <code>-o</code>. For options that take multiple arguments, these appear
|
|
separated by colons, so if the line contains `<code>-P prefix 3</code>',
|
|
<code>$opt_args[-P]</code> will contain `<code>prefix:3</code>'.</p>
|
|
<p><strong>Handling options</strong></p>
|
|
<p>Option handling is broadly similar, with the `<code><where I am></code>' part just
|
|
giving the option name --- I already showed one example with `<code>-type</code>'
|
|
above. In this case, the option will just be completed to itself, the
|
|
first part of the specification, and the rest says how to complete its
|
|
arguments. Since options can take any number of arguments, including
|
|
zero, the <code>:description:action</code> pair can be repeated, or omitted
|
|
entirely. Otherwise, it behaves similarly to the way described for
|
|
ordinary command arguments, with all the same possible actions. So a
|
|
simple option specification could be</p>
|
|
<pre><code> _arguments '-turnmeon'
|
|
</code></pre>
|
|
<p>for an option with no arguments,</p>
|
|
<pre><code> _arguments '-file:input file:_files'
|
|
</code></pre>
|
|
<p>for an option with one argument, or</p>
|
|
<pre><code> _arguments '-iofiles:input file:_files:output file:_files'
|
|
</code></pre>
|
|
<p>for an option with two arguments, both files but with different
|
|
descriptions.</p>
|
|
<p>The first part of the specification for an option can be more
|
|
complicated, to reflect the fact that options can be used in all sorts
|
|
of different ways. You can specify a description for the option itself
|
|
--- as I tried to explain, the descriptions in the rest of the
|
|
specification are instead for the arguments to the option. To specify an
|
|
option description, just put that after the option, before any colons,
|
|
in square brackets:</p>
|
|
<pre><code> _arguments '-on[turn me on, why not]'
|
|
</code></pre>
|
|
<p>Next, some options to a command are mutually exclusive. As <code>_arguments</code>
|
|
has to read its way along the command line to parse it, it can record
|
|
what options have already appeared, and can ensure that an option
|
|
incompatible with one there already will not be completed. To do this,
|
|
you need to include the excluded option in parentheses before the option
|
|
itself:</p>
|
|
<pre><code> _arguments '(-off)-on[turn me on, why not]' \
|
|
'(-on)-off[turn me off, please]'
|
|
</code></pre>
|
|
<p>This completes either of the options `<code>-on</code>' or `<code>-off</code>', but if
|
|
you've already given one, it won't complete the other on the same
|
|
command line. If you need to give multiple excluded options, just list
|
|
them separated by spaces, like `<code>(-off -noton)</code>'.</p>
|
|
<p>Some options can themselves be repeated; <code>_arguments</code> usually won't do
|
|
that (in a sense, they are mutually exclusive with themselves), but you
|
|
can allow it to happen by putting a `<code>*</code>' in front of the option
|
|
specification:</p>
|
|
<pre><code> _arguments '*-o[specify extra options]:option string:->option'
|
|
</code></pre>
|
|
<p>allows you to complete any number of `<code>-o <option></code>' sets using the
|
|
<code>$state</code> mechanism. The <code>*</code> appears after any list of excluded options.</p>
|
|
<p>There are also ways of allowing different methods of option handling. If
|
|
the option is followed by <code>-</code>, that means the value must be in the same
|
|
word as the option, instead of in the next word; if that is allowed, but
|
|
the argument could be in the next word instead, the option should be
|
|
followed by a `<code>+</code>'. The latter behaviour is very common for commands
|
|
which take single letter options. Some commands, particularly many
|
|
recent GNU commands, allow you to have the argument in the next word or
|
|
in the current word after an `<code>=</code>' sign; you get this by putting an
|
|
`<code>=</code>' after the option name. For example,</p>
|
|
<pre><code> _arguments '-file=:input file:_files'
|
|
</code></pre>
|
|
<p>allows you to complete `<code>-file </code><em><filename></em>' or
|
|
`<code>-file=</code><em><filename></em>'. With</p>
|
|
<pre><code> _arguments '-file=-:input file:_files'
|
|
</code></pre>
|
|
<p>only the second is possible, i.e. the argument must be after the `<code>=</code>',
|
|
not in its own word.</p>
|
|
<p>You can handle optional and repeated arguments to options, too. This
|
|
illustrates some possibilities:</p>
|
|
<pre><code> _arguments '-option:first arg:->first::optional arg:->second'
|
|
</code></pre>
|
|
<p>The doubled colon indicates that the second argument is optional. In
|
|
other words, at that point on the command line <code>_arguments</code> will either
|
|
try to complete via the state <code>second</code>, or will try to start another
|
|
specification entirely.</p>
|
|
<pre><code> _arguments '-option:first arg:->first:*:other args:->other'
|
|
</code></pre>
|
|
<p>Here, all arguments after the first --- everything else on the command
|
|
line --- is taken as an argument to the option, to be completed using
|
|
the state <code>other</code>.</p>
|
|
<pre><code> _arguments '-option:first arg:->first:*-:other args till -:->other'
|
|
</code></pre>
|
|
<p>This is similar, but less drastic: there is a pattern after the `<code>*</code>',
|
|
here a `<code>-</code>', and when that is encountered, processing of arguments to
|
|
`<code>-option</code>' stops. A command using this might be called as follows:</p>
|
|
<pre><code> cmdname -option <first> <other1> <other2> .... - <remainder>
|
|
</code></pre>
|
|
<p>where of course completion for <code><remainder></code> might be handled by other
|
|
specifications.</p>
|
|
<p>There are yet more possible ways of handling options. I've assumed that
|
|
option names can have multiple letters and hence must occur in separate
|
|
words. You can specify single-letter options as well, of course, but
|
|
many commands allow you to combine these into one word. To tell
|
|
<code>_arguments</code> that's OK you should give it the option <code>-s</code>; it needs to
|
|
come before any specifications, to avoid getting mixed up with them.
|
|
After you specify this, a command argument beginning with a single
|
|
`<code>-</code>' will be treated by <code>_arguments</code> as a list of single options, so
|
|
`<code>-lt</code>' is treated the same as `<code>-l -t</code>'. However, options beginning
|
|
with `<code>-``-</code>' are still treated as single options, so a `<code>-``-prefix</code>'
|
|
on the command line is still handled as a single long option by
|
|
<code>_arguments</code>.</p>
|
|
<p>One nice feature which can save a lot of trouble when using certain
|
|
commands, notably those written by the GNU project and hence installed
|
|
on most Linux-based systems, which take an option `<code>-``-help</code>' that
|
|
prints out a list of all options. This is in a human-readable form, but
|
|
<code>_arguments</code> is usually able to extract a list of available options
|
|
which use the `<code>-``-...</code>' form, and even in many cases whether they
|
|
take an argument, and if so what type that is. It knows because
|
|
`<code><command> -``-help</code>' often prints out a message like
|
|
`<code>-``-file=FILE</code>' which would tell <code>_arguments</code> (1) that `<code>-``-file</code>'
|
|
is a possible option (2) that it takes an argument because of the `<code>=</code>'
|
|
(3) that that argument should be a file because of the message `<code>FILE</code>'
|
|
at the end.</p>
|
|
<p>You specify that the command in question works in this way by using the
|
|
(fairly memorable) option `<code>-``-</code>' to `<code>_arguments</code>'. You can then
|
|
help it out with completion of option arguments by including a pattern
|
|
to be matched in the help test after the `<code>-``-</code>'; the format is
|
|
otherwise similar to a normal specification. For example
|
|
`<code>*=FILE*:file:_files</code>' says that any option with `<code>=FILE</code>' in it has
|
|
the description `<code>file</code>' and uses the standard <code>_files</code> function for
|
|
completion, while `<code>*=DIR*:directory:_files -/</code>' does the same for
|
|
directories. These two examples are so common that they are assumed by
|
|
`<code>_arguments -``-</code>'.</p>
|
|
<p>So for example, here is the completion for <code>gdb</code>, the GNU debugger,
|
|
which not surprisingly understands the GNU option format:</p>
|
|
<pre><code> _arguments -- '*=(CORE|SYM)FILE:core file:_files' \
|
|
'*=EXECFILE:executable:_files -g \*\(\*\)' \
|
|
'*=TTY:terminal device:compadd /dev/tty\*' && return 0
|
|
</code></pre>
|
|
<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><span id="l190"></span></p>
|
|
<h3 id="698-more-completion-utility-functions"><a class="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>
|
|
<p><strong><code>_call_function</code></strong></p>
|
|
<p>This is a simple front end to calling a function which may not be
|
|
defined and hanging onto the return status of the function. One good use
|
|
for this is to call a possibly non-existent function which might have
|
|
been defined by the user, before doing some default stuff the user might
|
|
want to skip. That would look like this:</p>
|
|
<pre><code> local ret # returned status from called function, if it was called
|
|
|
|
_call_function ret _hook_function arg1 arg2 && return ret
|
|
|
|
# if we get here, _hook_function wasn't called,
|
|
# so do the default stuff.
|
|
</code></pre>
|
|
<p>As you can work out, <code>_call_function</code> itself returns status zero if the
|
|
function in the second argument got called, and in that case the first
|
|
argument is the name of a parameter with the return status from the
|
|
function itself. The whole point is that this is safe if
|
|
<code>_hook_function</code> doesn't exist.</p>
|
|
<p>This function is too low level to know about the tags mechanism; use
|
|
<code>_wanted</code> or similar to handle tags properly.</p>
|
|
<p><strong><code>_contexts</code></strong></p>
|
|
<p>This is another shorthand: the arguments it takes are a set of short
|
|
contexts, in other words either names of commands or special contexts
|
|
like `<code>-math-</code>'. The completion for each of these contexts is tried in
|
|
turn; <code>_contexts</code> simply handles all the boring looking up of functions
|
|
and testing the return values. The definition, if you want to look, is
|
|
reassuringly simple. It only has one use at the moment: <code>_subscript</code>,
|
|
which handles the <code>-subscript-</code> context we met early in the chapter,
|
|
calls `<code>_contexts -math-</code>' to try mathematical completion, since
|
|
ordinary array subscripts can contain mathematical expressions.</p>
|
|
<p>This is also too low level to handle tags. In zsh 4.1, it is made
|
|
obsolete by a cleverer mechanism for handling different contexts which
|
|
can be used, for example, for handling of arguments to redirections for
|
|
particular commands, or keys in a particular associative array. I expect
|
|
I'll describe that when 4.1 is finally released.</p>
|
|
<p><strong><code>_describe</code></strong></p>
|
|
<p>Don't confuse this with <code>_description</code> which was explained above and is
|
|
the basic function for adding a description to a set of completions of a
|
|
certain type. I mentioned in the description of the <code>verbose</code> style that
|
|
this function was responsible for showing, or not showing, the
|
|
descriptions for a whole lot of options at once. It allows you to do
|
|
that with several different sets of completions that may require
|
|
different options to <code>compadd</code>. The general form looks something like
|
|
this:</p>
|
|
<pre><code> _describe "description of set 1" descs1 compls1 \
|
|
<compadd-opts-1> -- \
|
|
"description of set 2" ...
|
|
</code></pre>
|
|
<p>where you can have any number of sets separated by the `<code>-``-</code>'. The
|
|
<code>descs1</code> and <code>compls1</code> are arrays of the same length, giving a list of
|
|
descriptions and a list of completions, respectively. Alternatively, you
|
|
need only give one array name and each element of that will contain a
|
|
completion and a description separated by the now-traditional colon. The
|
|
`<code><compadd-opts-1></code>' are a set of any old options recognised by
|
|
<code>compadd</code>, such as <code>-q</code>, or <code>-S=/</code>, or what have you. I won't give an
|
|
example for this, since to find something requiring it would almost need
|
|
me to rewrite the completion system from scratch.</p>
|
|
<p><strong><code>_combination</code></strong></p>
|
|
<p>This is the function at the heart of the completions such as
|
|
<code>users-hosts</code> described above, where combinations of elements need to be
|
|
completed at the same time. It's easiest to describe with an example;
|
|
let's pick the <code>users-hosts</code> example, and I'll assume you remember how
|
|
that works from the user's point of view, including the format of the
|
|
<code>users-hosts</code> style itself. The completion for the username part is
|
|
performed as:</p>
|
|
<pre><code> _combination my-accounts users-hosts users
|
|
</code></pre>
|
|
<p>where <code>my-accounts</code> is the tag to be used for the completion, then comes
|
|
the style, and then the part of the style to be extracted.</p>
|
|
<p>Now suppose we come back into the completion function again to complete
|
|
the host later on the command line, so that the username is already
|
|
there. We can find that by searching the command line; suppose we store
|
|
what we find in <code>$userarg</code>. Then we can complete the hostname as
|
|
follows:</p>
|
|
<pre><code> _combination my-accounts users-hosts users=$userarg hosts
|
|
</code></pre>
|
|
<p>and the magic part, the fact that we can limit the hostnames to be
|
|
completed to only those with a user <code>$userarg</code>, is handled by
|
|
<code>_combination</code>. This extends to <code>hosts-ports-users</code> and any larger
|
|
combined set in the obvious way: the first field not to contain an
|
|
`<code>=</code>' is the one being completed. You don't need to supply other fields
|
|
if they are not known; in other words, the field to be completed doesn't
|
|
need to be the first one in sequence not known, it can be any, just as
|
|
long as it matches part of the style given in the second argument, so
|
|
you could have omitted the `<code>users=$userarg</code>' in the last example if
|
|
you couldn't extract the right username.</p>
|
|
<p>There are various bells and whistles: after the field to be completed
|
|
you can add any options to be passed down to <code>compadd</code>; you can give
|
|
<code>_combination</code> itself the option `<code>-s <sep></code>' to specify a character
|
|
other than colon to separate the parts of the style values; if the style
|
|
lookup fails, but there is a corresponding function, which would be
|
|
called `<code>_users</code>' or `<code>_hosts</code>' in this example, it is called to
|
|
generate the matches, and gets the options at the end which are
|
|
otherwise destined for <code>compadd</code>.</p>
|
|
<p>As you can see, this function is at a high enough level to handle the
|
|
tags mechanism itself.</p>
|
|
<p><strong><code>_multi_parts</code></strong></p>
|
|
<p>This takes two arguments, a separator and a list of matches. The list of
|
|
matches is normal, except that each element is likely to contain the
|
|
separator. In the most obvious usage, the separator is `<code>/</code>' and the
|
|
list of matches is a lot of files with path components. Here's another
|
|
reasonable usage:</p>
|
|
<pre><code> local groups expl
|
|
groups=($(awk -F: '{ print $1 }' ~/.newsrc))
|
|
_wanted groups expl 'newsgroup' _multi_parts "$expl[@]" . groups
|
|
</code></pre>
|
|
<p>The generated array contains names of Usenet newsgroups, i.e. names with
|
|
components separated by a `<code>.</code>', and <code>_multi_parts</code> allows you to
|
|
complete these piece by piece instead of in one go. This is a good deal
|
|
better for use with menu completion, and the list which appears is
|
|
smaller too. The <code>_wanted</code> part handles the tags mechanism, which
|
|
<code>_multi_parts</code> doesn't.</p>
|
|
<p><strong><code>_sep_parts</code></strong></p>
|
|
<p>This also completes a word piece by piece, but unlike <code>_multi_parts</code> the
|
|
trial completions are also only supplied for each piece. The arguments
|
|
are alternating arrays and separators; arrays are in the usual form, in
|
|
other words either the name of an array parameter, or a literal array in
|
|
parentheses, quoted to protect it from immediate shell expansion. The
|
|
separators are simply strings. For example</p>
|
|
<pre><code> local expl
|
|
array1=(apple banana cucumber)
|
|
_wanted breakfast expl 'breakfast' \
|
|
_sep_parts array1 + '(bread toast croissant)' @ '(bowl plate saucer)';
|
|
</code></pre>
|
|
<p>completes strings like `<code>apple+toast@plate</code>', piece by piece. This is
|
|
currently not used by the distributed completion code.</p>
|
|
<p><strong><code>_values</code></strong></p>
|
|
<p>This works a little like <code>_arguments</code>, but is designed for completing
|
|
the values of a single argument in a form like
|
|
`<code>key=val,flag,key=other</code>', in which you can specify the list
|
|
separator, here `<code>,</code>' by using the option <code>-s</code>, e.g. `<code>-s ,</code>'. The
|
|
first argument to <code>_values</code> is the overall description of the set of
|
|
arguments. The other arguments are very much like those to <code>_arguments</code>
|
|
except that, as you would expect from the form given, no pluses or minus
|
|
signs are involved and each value can only have one argument, which must
|
|
follow an `<code>=</code>'. Virtually everything else is identical, with the
|
|
exception that the associative array where the arguments are stored for
|
|
each value is called <code>$val_args</code>.</p>
|
|
<p>I won't bother giving the instructions for <code>_arguments</code> again; instead,
|
|
here is an example based on the values used by the <code>-o</code> option to the
|
|
<code>mount</code> command:</p>
|
|
<pre><code> local context state line
|
|
typeset -A val_args
|
|
|
|
_values -s , 'file system options' \
|
|
'(rw)ro[mount file system read-only]' \
|
|
'(ro)rw[mount file system read-write]' \
|
|
'uid[set owner of root]:user ID:' \
|
|
'gid[set group of root]:group ID:' \
|
|
'bs[specify block size]:block size:(512 1024 2048 4192)'
|
|
</code></pre>
|
|
<p>I've just picked out a few of the umpteen possibilities for
|
|
illustration; see the function <code>_mount</code> if you want more. Remember that
|
|
the `<code>(rw)</code>' before the `<code>ro</code>' means that the options are mutually
|
|
exclusive, and the one in parentheses won't be offered if the other
|
|
appears on the command line; the strings in square brackets are
|
|
descriptions of the particular options; and if there is a colon after
|
|
the name of the value, the value takes an argument whose own description
|
|
comes next. The second colon is followed by possible completions for
|
|
that argument, using the usual convention for actions in <code>_arguments</code>;
|
|
as you'll see from the <code>local</code> statement, the <code>$state</code> mechanism can be
|
|
used here. Only the `<code>bs</code>' argument here is given possible completions;
|
|
for <code>uid</code> and <code>gid</code> you'll have to type in the number without
|
|
completion; <code>ro</code> and <code>rw</code> don't take arguments.</p>
|
|
<p>Hence a typical(?) list to be completed by this would be
|
|
`<code>rw,uid=123,bs=2048</code>'.</p>
|
|
<p>Remember also that you can use a `<code>*</code>' before the option name to say
|
|
that it can appear more than once in the value list. The <code>_values</code>
|
|
function handles the context and tags in a similar way to <code>_arguments</code>.</p>
|
|
<p><strong><code>_regex_arguments</code></strong></p>
|
|
<p>This function is for use when the behaviour of a set of command
|
|
arguments is so complicated that even <code>_arguments</code> can't help. It allows
|
|
you to describe the arguments as a regular expression (i.e. a pattern).
|
|
I won't explain it because I haven't yet figured out how it works. If
|
|
you think you need to use it, look at the manual entry and then at the
|
|
<code>_apt</code> function which is currently its main application.</p>
|
|
<p><span id="l191"></span></p>
|
|
<h2 id="610-finally"><a class="header" href="#610-finally">6.10: Finally</a></h2>
|
|
<p>Completion is big and complex: this means that there are probably lots
|
|
of bugs around, and things that I haven't described simply enough or
|
|
which may be implemented in too complicated a way. Please send the
|
|
<code>zsh-workers</code> mailing list any reports or constructive criticism on the
|
|
subject.</p>
|
|
<p>Last of all, remember that the new completion system is ideally just
|
|
supposed to work without you needing to worry exactly how. That's a bold
|
|
hope, but at least much of the time you should be able to get away with
|
|
using just the tab key and ordinary characters.</p>
|
|
|
|
</main>
|
|
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
|
<!-- Mobile navigation buttons -->
|
|
<a rel="prev" href="zshguide05.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next" href="zshguide07.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
|
|
<div style="clear: both"></div>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
|
<a rel="prev" href="zshguide05.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
|
<i class="fa fa-angle-left"></i>
|
|
</a>
|
|
|
|
<a rel="next" href="zshguide07.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
|
<i class="fa fa-angle-right"></i>
|
|
</a>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
window.playground_copyable = true;
|
|
</script>
|
|
|
|
|
|
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
|
|
|
|
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
|
|
<script src="book.js" type="text/javascript" charset="utf-8"></script>
|
|
|
|
<!-- Custom JS scripts -->
|
|
|
|
|
|
</body>
|
|
</html>
|