<navid="sidebar"class="sidebar"aria-label="Table of contents">
<divclass="sidebar-scrollbox">
<olclass="chapter"><liclass="chapter-item expanded affix "><ahref="zshguide.html">A User's Guide to the Z-Shell</a></li><liclass="chapter-item expanded "><ahref="zshguide01.html"><strongaria-hidden="true">1.</strong> A short introduction</a></li><liclass="chapter-item expanded "><ahref="zshguide02.html"><strongaria-hidden="true">2.</strong> What to put in your startup files</a></li><liclass="chapter-item expanded "><ahref="zshguide03.html"><strongaria-hidden="true">3.</strong> Dealing with basic shell syntax</a></li><liclass="chapter-item expanded "><ahref="zshguide04.html"class="active"><strongaria-hidden="true">4.</strong> The Z-Shell Line Editor</a></li><liclass="chapter-item expanded "><ahref="zshguide05.html"><strongaria-hidden="true">5.</strong> Substitutions</a></li><liclass="chapter-item expanded "><ahref="zshguide06.html"><strongaria-hidden="true">6.</strong> Completion, old and new</a></li><liclass="chapter-item expanded "><ahref="zshguide07.html"><strongaria-hidden="true">7.</strong> Modules and other bits and pieces Not written</a></li></ol>
<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p>Unlike completion, <code>zle</code> doesn't have many options associated with it;
most of the control is done by key bindings and builtin commands. Only
two are really useful; both control beeps. The option <code>beep</code> can be
unset to tell the shell never to make a noise on an error; the option
<code>histbeep</code> can be unset to disable beeps only in the case of trying to
go back before the first or forward after the last history entry.</p>
<p>The not-very-useful options are <code>zle</code> and <code>singlelinezle</code>. The former
controls whether zle is active at all and isn't that useful because it's
usually on automatically whenever you need it, in other words in
interative shells, and off whenever you don't. It's sometimes useful to
test via `<code>[[ -o zle ]]</code>', however; this lets you make a function do
something cleverer in an interative shell.</p>
<p>The option <code>singlelinezle</code> restricts editing to one line; if it gets too
long, it will be truncated and a `<code>$</code>' printed where the missing bits
are. It's only there for compatibility with ksh and as a safeguard if
your terminal is really screwed up, though even in that case zsh tries
to guess whether everything it needs is available.</p>
<p>Other functions that affect zle include the history functions. These
were described back in <ahref="zshguide02.html#init">chapter 2</a>; once you've
set it off, searching through the history works basically the same way
in zle as with the `<code>!</code>' history commands.</p>
<p><spanid="l85"></span></p>
<h3id="432-the-minibuffer-and-extended-commands"><aclass="header"href="#432-the-minibuffer-and-extended-commands">4.3.2: The minibuffer and extended commands</a></h3>
<p>The `minibuffer' is yet another Emacs concept; it is a prompt that
appears just under the command line for you to enter some edit required
by the editor itself. Usually, it comes and goes as it pleases and you
don't need to think about it. The most common uses are entering text for
searches, and entering a command which isn't bound to a string. That's
yet another Emacs feature: <code>\ex</code> prompts you to enter the name of a
command. Luckily, since the names tend to be rather long, completion is
available. So typing `<code>echo foo<ESC>xba<TAB>w<TAB></code>' ends up with:</p>
<pre><code> % echo foo
execute: backward-word
</code></pre>
<p>and hitting return executes that function, taking you to the start of
the <code>foo</code>; you might be able to think of easier ways of doing that. This
does provide a way of running commands you don't often use.</p>
<p>(I hope my notation isn't too confusing. I write things like <code><TAB></code>
when I'm showing a single character you hit, to make it stand out from
the surrounding text. However, when I'm not showing text being entered,
I would write that as `<code>\t</code>', which is how you would enter the
character into a key sequence to be bound, or a string to be printed.)</p>
<p>The minibuffer only handles a very limited set of editing commands.
Typing one it doesn't understand usually exits whatever you were trying
to do with the minibuffer, then executes the keystroke. However, in this
particular case, it won't let you exit until you have finished typing a
command; your only other option is to abort. The usual zle abort
character is <code>^g</code>, `<code>send-break</code>'. This is different from the more
drastic <code>^c</code>, which sends the shell itself an interrupt signal. Quite
often they have the same effect in zle, however. (You'll notice <code>^c</code> is
actually `bound to <code>undefined-key</code>', in other words zle doesn't
consider it does anything. However, the terminal driver probably causes
it to send an interrupt, and zle does respond to that.)</p>
<p>Another feature useful with rare commands is `<code>where-is</code>'. Surprise!
it's not bound by default, so typing `<code><ESC>xwhere-is</code>' is then the way
of runing it. Then you type another editor command at the `<code>Where is:</code>'
prompt, and the shell will tell you what keystrokes, if any, are bound
to it. You can also simply use <code>grep</code> on the output of <code>bindkey</code>, which,
<p>Many commands can be repeated by giving them a numeric prefix or digit
argument. For example, at the end of a long line of text, type
`<code><ESC>4<ESC>b</code>'. The `<code><ESC>b</code>' on its own would take you one word
backwards. The `<code><ESC>4</code>' passes it the number four and it moves four
words backwards. Generally speaking, this works any time it make sense
to repeat a command. It works for <code>self-insert</code>, too, just repeatedly
inserting the character. If it doesn't work, the prefix argument is
simply ignored.</p>
<p>You can build up long or negative arguments by repeating both the <code>\e</code>
and the digit or `<code>-</code>' after it; for example, `<code><ESC>-<ESC>1<ESC>0</code>'
specifies minus ten. It varies from command to command how useful
negative numbers are, but they generally switch from backwards to
forwards or similar: `<code><ESC>-<ESC>4<ESC>\f</code>' is a pointless way of
executing the same as `<code><ESC>4<ESC>b</code>'.</p>
<p>The shell also has Emacs' `<code>universal-argument</code>' feature, but it's not
bound by default --- in Emacs it is <code>\C-u</code>, but as we've seen that's
already in use. This is an alternative to all those escapes. If you bind
the command to a keystroke (it's absolutely pointless as a shortcut
otherwise), and type that key, then an option minus followed by any
digits are remembered as a prefix. The next keystroke which is not one
of those is then executed as a command, with the prefix formed by the
number typed after <code>universal-argument</code>.</p>
<p>For example, on my keyboard, the key <code>F12</code> sends the key sequence
`<code>\e[[24~</code>' --- see below for how to find out what functions keys send.
Hence I use</p>
<pre><code> bindkey '\e[[24~' universal-argument
</code></pre>
<p>Then if I hit the characters <code>F12</code>, <code>4</code>, <code>0</code>, <code>a</code>, a row of forty `a's
is inserted onto the command line. I'm not claiming this example is
particularly useful.</p>
<p><spanid="l87"></span></p>
<h3id="434-words-regions-and-marks"><aclass="header"href="#434-words-regions-and-marks">4.3.4: Words, regions and marks</a></h3>
<p>Words are handled a bit differently in zsh from the way they are in most
editors. First, there is a difference between what Emacs mode and vi
mode consider words. That is to say, there is a difference between the
functions bound by default in those modes; you can use the same
functions in either mode by rebinding the keys.</p>
<p>In both vi and Emacs modes, the same logic about words applies whether
you are moving forward or backward a number of words, or deleting or
killing them; the same amount of text is removed when killing as the
cursor would move in the other case.</p>
<p>In vi mode, words are basically the same as what vi considers words to
be: a sequence of alphanumeric characters together with underscores ---
essentially, characters that can occur in identifiers, and in fact
that's how zsh internally recognises vi `word characters'. There is one
slight oddity about vi's wordwise behaviour, however, which you can
easily see if you type `<code>/a/filename/path/</code>', leave insert mode with
<code>ESC</code>, and use `<code>w</code>' or `<code>b</code>' to go forward or backward by words over
it. It alternates between moving over the characters in a word, and the
characters in the separator `<code>/</code>'.</p>
<p>In Emacs, however, it is done a bit differently. The vi `word
characters' are always considered parts of a word, but there is a
parameter <code>$WORDCHARS</code> which gives a string of characters which are
<em>also</em> part of a word. This is perhaps opposite to what you would
expect; given that alphanumerics are always part of a word, you might
expect there to be a parameter to which you add characters you <em>don't</em>
want to be part of a word. But it's not like that.</p>
<p>Also unlike vi, jumping a word always means jumping to a word character
at the start of a word. There is no extra `turn' used up in jumping
over the non-word characters.</p>
<p>The default value for <code>$WORDCHARS</code> is</p>
<pre><code> *?_-.[]~=/&;!#$%^(){}<>
</code></pre>
<p>i.e. pretty much everything and the kitchen sink. Usually, therefore,
you will want to remove characters which you don't want to be considered
parts of words; `<code>-</code>', `<code>/</code>' and `<code>.</code>' are particularly likely
possibilities. If you want to remove individual characters, you can do
it with some pattern matching trickery (next chapter):</p>
<pre><code> % WORDCHARS=${WORDCHARS//[&.;]}
% print $WORDCHARS
*?_-[]~=/!#$%^(){}<>
</code></pre>
<p>shows that the operation has removed those three characters in the
group, i.e. `<code>&</code>', `<code>.</code>' and `<code>;</code>', from <code>$WORDCHARS</code>. The `<code>//</code>'
indicates a global substitution: any of the characters in the square
brackets is replaced by nothing.</p>
<p>Many other line editors, even those like <code>readline</code> with Emacs bindings,
behave as if only identifier characters were part of a word, i.e. as if
<code>$WORDCHARS</code> was empty. This is very easy to do with a zle shell
function. Recent versions of zsh supply the functions
`<code>bash-forward-word</code>', `<code>bash-kill-word</code>', and a set of other similar
ones, for you to bind to keys in order to have that behaviour.</p>
<p>Other behaviours are also possible by writing functions; for example,
you can jump over real shell words (i.e. individual command arguments)
by using some more substitution trickery, or you can consider only
space-delimited words (though that's not so far from what you get with
<code>$WORDCHARS</code> by adding `<code>"`'\@</code>').</p>
<p><spanid="l88"></span></p>
<h3id="435-regions-and-marks"><aclass="header"href="#435-regions-and-marks">4.3.5: Regions and marks</a></h3>
<p>Another useful concept from Emacs is that of regions and marks. In
Emacs-speak `point' is where the cursor is and `mark' is somewhere
where you leave a mark to come back to later. The command to set the
mark at the current point is `<code>^@</code>' as in Emacs, a hieroglyphic which
usually means holding down the control key and pressing the space key.
On some systems, such as the limited version of <code>telnet</code> provided with a
well-known non-UNIX-based windowing system, you can't send this
sequence, and you need to bind a different sequence to
<code>set-mark-command</code>. One possibility is `<code>\e </code>' (escape followed by
space), as in MicroEMACS. (Some X Windows configurations don't allow
<code>^@</code> to work in an xterm, either, though that is usually fixable.)</p>
<p>To continue with Emacs language, the region between point and mark is
described simply as `the region'. In zsh, you can't have this
highlighted, as you might be used to with editors running directly under
windowing systems, so the easiest way to find out the ends of the region
is with <code>^x^x</code>, <code>exchange-point-and-mark</code>, which I mentioned before ---
mark, by default, is left at the beginning of the line, hence the
behaviour you saw above.</p>
<p>Various editing commands --- usually those with `<code>region</code>' in the name
--- operate on this. The most usual are those which kill or copy the
region. Annoyingly, <code>kill-region</code> isn't bound --- in Emacs, it's <code>^w</code>,
but zsh follows the tradition of having that bound to
<code>backward-kill-word</code>, even though that's also available as the
traditional Emacs binding <code>\e^?</code>. So it's probably useful to rebind it.
To copy the region, the usual binding `<code>\ew</code>' works.</p>
<p>You then `yank' back the text copied or killed at another point with
`<code>^y</code>'. The shell implements the `kill ring' feature, which means if
you perform a yank, then type `<code><ESC>y</code>' (<code>yank-pop</code>) repeatedly, the
shell cycles back through previously killed or copied text, so that you
have more available than just the last one.</p>
<p><spanid="l89"></span></p>
<h2id="44-history-and-searching"><aclass="header"href="#44-history-and-searching">4.4: History and searching</a></h2>
<p>Zle has access to the lines saved in the shell's history, as described
in `Setting up history' in <ahref="zshguide02.html#init">chapter 2</a>. There are
essentially three ways of retrieving bits of the history: moving back
through it line by line, searching back for a matching line, and
extracting individual words from the history. In fact, the first two are
pretty similar, and there are hybrid commands which allow you to move
back step by step but still matching only particular lines.</p>
<p><spanid="l90"></span></p>
<h3id="441-moving-through-the-history"><aclass="header"href="#441-moving-through-the-history">4.4.1: Moving through the history</a></h3>
<p>The simplest behaviour is what you get with the normal cursor key
bindings, `<code>up-line-or-history</code>' and `<code>down-line-or-history</code>'. If you
are in text which fits into a single line (which may be a continuation
line, i.e. it has a new prompt in the form given by <code>$PS2</code> at the start
of the line), this replaces the entire line with the line before or
after in the history. The history is not circular, it has a beginning
and an end. The beginning is the first line still remembered by the
shell (i.e. <code>$HISTSIZE</code> lines back, taking into account that the actual
number of lines present will be modified by the effects of any special
history options you have set to remove unwanted lines); the end is the
line you are typing. You can use <code>\e<</code> and <code>\e></code> to go to the first and
last line in the history.</p>
<p>The last phrase sounds trivial but isn't quite. Type `<code>echo This is the last line</code>', go back a few lines with the up arrow, and then back down
to the end, and you will see what I mean --- the shell has remembered
the line you were typing, even though it hadn't been entered, so you can
scroll up and down the history and still come back to it.</p>
<p>Of course, you can edit any of the earlier history lines, and hit
`return' so that they are executed --- that's the whole point of being
able to scroll back through the history. What is maybe not so obvious is
that the shell will remember changes you make to these lines, too, until
you hit `return'.</p>
<p>For example, type `<code>echo this is the last line</code>' at a new shell prompt,
but don't hit return. Now hit the up arrow once, and edit the previous
line to say `<code>echo this is the previous line</code>'. If you scroll down and
up, you will see that the shell has kept both of those lines. When you
decide which one to use and hit return, that line is executed and added
to the end of the history, and any changes to previous lines in the
history are forgotten.</p>
<p>Sometimes you don't want to add a new line to history, instead
re-execute a whole series of earlier commands one by one. This can be
done with <code>^o</code>, <code>accept-line-and-down-history</code>. When you hit <code>^o</code> on a
line in the history, that is executed, and the line after it in the
history is shown. So you just need to keep hitting it to keep executing
the commands.</p>
<p>There are two other similar commands I don't use as much,
<code>infer-next-history</code>, bound to <code>^x^n</code>, and
<code>accept-and-infer-next-history</code>, not bound by default. `Inferring' the
next history means that the shell looks at what is in the current line,
whatever its provenance --- you might just have typed it, for example
--- and looks back in the history for a matching line; the `inferred'
next history line is the one following that line. In the first case, you
are simply shown that line; in the second case, the current line is
executed first, then you are shown the inferred line. Feel free to drop
me a line if you find this is the best thing since sliced bread.</p>
<p>One slight confusion about the history is that it can be hard to
remember quite where you are in it, for example, if you were editing a
line and had to scroll back to look for something else. In cases like
this, <code>\e></code> is your friend, as it takes you the last line. Also,
whenever you hit return, you are guaranteed to be at the end of the
history, even if you were editing a line some back in the history,
unlike certain other systems (though <code>accept-line-and-down-history</code> can
emulate those). So it's usually not too hard to stay unconfused about
what you're editing.</p>
<p><spanid="l91"></span></p>
<h3id="442-searching-through-the-history"><aclass="header"href="#442-searching-through-the-history">4.4.2: Searching through the history</a></h3>
<p>Zsh has the commands you would expect to search through the history,
i.e. where you hit a search key and then type in the words to search
for. However, it also has other features, probably more used by the zsh
community, where the search is based on some feature of the current
line, in particular the first word or the line up to the cursor
position. These typically enable you to search backwards more quickly,
since you don't need to tell the shell what you are looking for.</p>
<p><strong>Ordinary searching</strong></p>
<p>The standard search commands, by which I mean the ones your are probably
most familiar with from ordinary text editors (if either Emacs or vi can
be so called), are designed to make Emacs and vi users feel at home.</p>
<p>In Emacs mode, you have incremental search: <code>^r</code> to search backwards ---
this is usually what you want, since you usually start at the end ---
and <code>^s</code> to search forwards. Note that <code>^s</code> is another keystroke which
is often intercepted by the terminal driver; in this case, it usually
freezes output to the terminal until you type <code>^q</code> to turn it back on.
If you don't like this, you can either use `<code>stty stop</code>' and `<code>stty start</code>' to change the characters, or simply `<code>unsetopt flowcontrol</code>' to
turn that feature off altogether. However, the command bound to <code>^s</code>,
<code>history-incremental-search-forward</code>, is also bound to <code>^xs</code>, so you can
use that instead.</p>
<p>As in Emacs, for each character that you type, incremental search takes
you to the nearest history entry that matches all the characters, until
the match fails. Typing the search keystroke again at any point takes
you to the next match for the characters in the minibuffer.</p>
<p>In vi command mode, the keystrokes available by default are the familiar
`<code>/</code>' and `<code>?</code>'. There are various differences from vi, however. First
of all, it is `<code>/</code>' that searches backwards --- this is the one you
will use more often. Secondly, you can't search for regular expressions
(patterns); the only exception is that the character `<code>^</code>' at the start
anchors the search to the start of a line. Everything else is just a
plain string.</p>
<p>The other two standard vi search keystrokes are also present: `<code>n</code>'
searches for the next match of the current string, and `<code>N</code>' does the
same but reverses the direction of the search.</p>
<p><strong>Search for the first word</strong></p>
<p>The next sort of search is probably the most commonly used, but is only
bound in Emacs mode: <code>\ep</code> and <code>\en</code> search forward or backward for the
next history line with the same first word as the current line. So often
to reuse a command you will type just the command name itself, and hit
<code>\ep</code> until the command line you want appears. These commands are called
simply `<code>history-search-backward</code>' and `<code>history-search-forward</code>'; the
name doesn't really describe the function all that well.</p>
<p><strong>Prefix searching</strong></p>
<p>Finally, you can search backwards for a line which has the entire
starting point up to the cursor position the same as the current line.
This gives you a little more control than <code>history-search-</code><em>direction</em>.
The corresponding commands, <code>history-beginning-search-backward</code> and
<code>history-beginning-search-forward</code>, are not bound by default. I find it
useful to have them bound to <code>^xp</code> and <code>^xn</code> since this is similar to
<p>and you can test the return status to see if the search succeeded.</p>
<p><spanid="l92"></span></p>
<h3id="443-extracting-words-from-the-history"><aclass="header"href="#443-extracting-words-from-the-history">4.4.3: Extracting words from the history</a></h3>
<p>Sometimes instead of editing a previous line you just want to extract a
word from it into the current line. This is particularly easy if the
word is the last on the line, and the line isn't far back in the
history: just hit <code>\e.</code> repeatedly, and the shell will cycle through the
last word on previous lines. You can give this a prefix argument to pick
the <em>N</em>th from last word on the line just above the last line you picked
a word from. As you can tell from the description, this gets a little
hairy; version 4.1 of the shell will probably provide a slightly more
flexible version.</p>
<p>Although it's strictly not to do with the history, you can copy the
previous word on the current line with <code>copy-prev-word</code>, which for some
reason is bound to <code>\e^_</code>, escape followed (probably) by control and
slash. I have this bound to <code>\e=</code> instead (in some versions of ksh that
key sequence is taken by the equivalent of <code>list-choices</code>). This copies
words delimited by whitespace, but you can copy what the shell would see
as the previous complete argument by using <code>copy-prev-shell-word</code>
instead. This isn't bound by default, as it is newer than the other one,
but it is arguably more useful.</p>
<p>Sometimes you want to complete a word from the history; this is possible
using the completion system, described in the next chapter.</p>
<p><spanid="l93"></span></p>
<h2id="45-binding-keys-and-handling-keymaps"><aclass="header"href="#45-binding-keys-and-handling-keymaps">4.5: Binding keys and handling keymaps</a></h2>
<p>There are two topics to cover under the heading of key bindings: first,
how to bind keys themselves, and secondly, keymaps and how to use them.
Manipulating both key bindings and keymaps is done with the <code>bindkey</code>
command. The first topic is the more immediately useful, so I'll start
<p>If you want to remove a key binding, you can simply bind it to something
else. Near all uses of the <code>bindkey</code> and <code>zle</code> commands are smart about
removing dead wood in such cases. However you can also use `<code>bindkey -r</code><em>key-sequence</em>' to remove the binding explicitly. You can also
simply bind the sequence to the command <code>undefined-key</code>; this has
exactly the same effect --- even down to pruning completely any bindings
for long sequences. For example, suppose you bind `<code>\e\C-x\C-x</code>' to a
command, then to <code>undefined-key</code>. All memory that `<code>\e\C-x\C-x</code>' was
ever bound is removed; <code>\e\C-x</code> will no longer be marked as a prefix
key, unless you had some other binding with that prefix.</p>
<p>You can remove all bindings starting with a given prefix by adding the
`<code>-p</code> option. The example given in the manual,</p>
<pre><code> bindkey -rpM viins '\e'
</code></pre>
<p>(except it uses the equivalent form `<code>^[</code>') is amongst the most useful,
as it will remove the annoying delay after you type `<code>\e</code>' to enter vi
command mode. The delay is there because the cursor keys usually also
start with <code>\e</code> and the shell is waiting to see if you actually typed
one of those. So if you can make do without cursor keys in vi insert
mode you may want to consider this.</p>
<p>Note that any binding for the prefix itself is not removed. In this
example, <code>\e</code> stays bound as it was in the <code>viins</code> keymap, presumably to
<code>vi-cmd-mode</code>.</p>
<p>All manipulations like this are specific to one particular keymap. You
need to repeat them with a different <code>-M</code><em>...</em> option argument, which
is described below, to have the same effect in other keymaps.</p>
<p><spanid="l96"></span></p>
<h3id="453-function-keys-and-so-on"><aclass="header"href="#453-function-keys-and-so-on">4.5.3: Function keys and so on</a></h3>
<p><spanid="fkeys"></span></p>
<p>It's usually possible to bind the function keys on your keyboard,
including the specially named ones such as `Home' and `Page Up'. It
depends a good deal on how your windowing system or terminal driver
handles them, but these days it's nearly always the case that a well
set-up system will allow the function keys to send a string of
characters to the terminal. To bind the keys you need to find out what
that string is.</p>
<p>Luckily, you are usually aided by the fact that only the first character
of the string is `funny', i.e. does something other than insert a
character. So there is a trick for finding out what the sequence is. In
a shell window, hit <code>^v</code> (if you are using vi bindings, you will need to
be in insert mode), then the function key in question. You will probably
see a string like `<code>^[OP</code>' --- this is what I get from the F1 key. A
note in my <code>.zshrc</code> suggests I used to get `<code>\e[11~</code>', so be prepared
for something different, even if, like me, you are using a standard
xterm terminal emulator. A quick poll of terminal emulators on this
Linux/GNU/XFree86 system suggests these two possibilities are by far the
most popular.</p>
<p>You may even be able to get different sequences by holding down shift or
control as well (after pressing <code>^v</code>, of course). On my keyboard,
combining F1 with shift gives me `<code>^[O2P</code>', with control `<code>^[O5P</code>' and
with both `<code>^[O6P</code>'. Again, your system may do something completely
different.</p>
<p>If you move the cursor back over that `<code>^[</code>', you'll find it's a single
character --- you can position the cursor over the `<code>^</code>', but not the
`<code>[</code>'. This is zsh's way of inserting a real, live escape character
into the line. In fact, if you type</p>
<pre><code> bindkey '
</code></pre>
<p>then <code>^v</code>, the function key, and the other single quote, you have a
perfectly acceptable way of binding the key on the command line. Zsh is
generally quite relaxed about your use of unprintable characters; they
may not show up correctly on your terminal, but the shell is able to
handle all single-byte characters. It doesn't yet have support for those
longer than a single byte, however.</p>
<p>You can also do the same in your <code>.zshrc</code>; the shell will handle strange
characters in input without a murmur. You can also use the two
characters `<code>^[</code>', which is just another way of entering an escape key.
However, the kosher thing to do is to turn it into `<code>\e</code>'. For example,</p>
<pre><code> bindkey '\e[OP' where-is # F1
bindkey '\e[O2P' universal-argument # shift F1
</code></pre>
<p>and so on. Using this, you can give sensible meanings to `Home',
`End', etc. Note the windowing system's sensible way of avoiding the
problem with prefixes --- any extra characters are inserted before the
final character, so the shell can easily tell when the sequence is
complete without having to wait and see if there is more to follow.</p>
<p>There is a utility supplied with zsh called <code>zkbd</code> which can help with
all of this by finding out and remembering the definitions for you. You
can probably use it simply by autoloading it and running it, as it is
usually installed with the other functions. It should be reasonably
self-explanatory, else consult the <code>zshcontrib</code> manual.</p>
<p>If you are using X Windows and are educated enough, you can tinker with
your <code>.Xdefaults</code> file to tweak how keys are interpreted by the terminal
emulator. For example, the following turns the backspace key into a
delete key in anything using a `VT100 widget', which is the basis of
xterm's usual mode of operation:</p>
<pre><code> *VT100.Translations: #override \
<Key>BackSpace: string(0x7F)
</code></pre>
<p>Part of the reason for showing this is that it makes zsh's key binding
system look wonderfully streamlined by comparison. However, tinkering
around at this level gives you very much more control over the use of
key modifiers (shift, alt, meta, control, and maybe even super and hyper
if you're lucky). This is far beyond the scope of this guide --- which I
say, as you probably realise by now, to cover up for not knowing much
about it. Here's another example from Oliver Kiddle, though; it uses
control with the left-cursor key to send an escape sequence: insert</p>
<p>binds the usual up-cursor key in <code>vicmd</code> mode, whatever keymap is
currently set. Actually, any version of the shell which understands the
<code>-M</code> option probably has that bound already.</p>
<p>Secondly, you can force zle to use a particular keymap. This is done in
a slightly non-obvious way: zle always uses the keymap <code>main</code> as the
current keymap (except when it's off in vi command mode, which is
handled a bit specially). To use your own, you need to make <code>main</code> an
alias for that with `<code>bindkey -A</code>'. The order after this is the same as
that after <code>ln</code>: the existing keymap you want to refer to comes first,
then what you want to make an alias for it, in this case <code>main</code>. This
means that</p>
<pre><code> bindkey -A emacs main
</code></pre>
<p>has the same effect as</p>
<pre><code> bindkey -e
</code></pre>
<p>but is more explicit, if a little more baroque. Don't link <code>vicmd</code> to
main, since then you can't use <code>viins</code>, which is bad. Note that
`<code>bindkey -M emacs</code>' doesn't have this effect; it simply lists the
bindings in the <code>emacs</code> keymap.</p>
<p>You can create your own keymaps, too. The easiest way is to copy an
existing keymap, such as</p>
<pre><code> bindkey -N mymap emacs
</code></pre>
<p>which creates (or replaces) <code>mymap</code> and initialises it with the bindings
from <code>emacs</code>. Now you can use <code>mymap</code> just like <code>emacs</code>. The bindings in
each are completely separate. If you finish with a keymap, you can
remove it with `<code>bindkey -D keymap</code>', although you'd better make sure
it's not linked to <code>main</code> first.</p>
<p>You can omit `<code>emacs</code>' to create an empty keymap; this might be
appropriate if your keymap is only going to be used in certain special
places and you want complete control on what goes into it. Currently the
shell isn't very good at letting you apply your own keymaps just in
certain places, however.</p>
<p>There are various other keymaps you might encounter, used in special
circumstances. If you list all keymaps, which is done by `<code>bindkey -l</code>', you may see <code>listscroll</code> and <code>menuselect</code>. These are used by the
new completion system, so if that isn't active, you probably won't see
them. They reside in the module <code>zsh/complist</code>. There will be more about
their effects in <ahref="zshguide06.html#comp">chapter 6</a>; <code>listscroll</code> allows
you to move up and down completion lists which more than fill the
terminal window, and <code>menuselect</code> allows you to select items
interactively from a displayed list. You can bind keys in them as with
<p>All Bourne-like shells allow you to edit continuation lines; that is, if
the shell can work out for sure that you haven't finished typing, it
will show you a new prompt, given by <code>$PS2</code>, and allow you to continue
where you left off from the previous line. In zsh, you can even see what
it is the shell is waiting for. For a simple example, type
`<code>array=</code>(<code>first</code>' and then `return'. The shell is waiting for the
final parenthesis of the array, and prints `<code>array></code>' at you, unless
you have altered <code>$PS2</code>. You can continue to add elements to the array
until you close the parentheses.</p>
<p>Shells derived from csh are less happy about continuation lines;
historically, this is because they try to evaluate everything in one go,
and became confused if they couldn't. The original csh didn't have a
particularly sophisticated parser. For once, zsh doesn't have an option
to match the csh behaviour; you just have to get used to the idea that
things work in zsh.</p>
<p>Where zsh improves over other shells is that you aren't just limited to
editing a single continuation line; you can actually edit a whole block
of lines on screen as you would in a full screen editor --- although you
can't scroll off the chunk of lines you're editing, which wouldn't make
sense.</p>
<p>The easiest way of doing this is to hit escape before you type a newline
at the point where you haven't finished typing. Actually, you can do
this any time, even if the line so far is complete. For example,</p>
<pre><code> % print This is line one<ESC><RET>
print This is line two
</code></pre>
<p>where those angle brackets at the end of the line means you type escape,
then return. Nothing happens, and there is no new prompt; you just type
blithely on. Hit return, unescaped this time, and both lines will be
executed. Note there is no implicit backslash, or anything like that;
when zsh reads the whole caboodle, that escaped carriage return became a
real carriage return, just as the shell would have read it from a
script.</p>
<p>This works because `<code>\e\r</code>' is actually bound to the command
<code>self-insert-unmeta</code>' which means `insert the character you get by
stripping the escape or top bit from what I just typed' --- in other
words, a literal carriage return. You would have got exactly the same
effect by typing <code>^v^j</code>, since the <code>^v</code> likewise escapes the <code>^j</code>
(newline), as it does any other character.</p>
<p>(Aside for the terminally curious only: Why newline here and not
carriage return --- the `enter' key --- as you might expect? That's a
rather grotesque story. It turns out that for mostly historical reasons
UNIX terminal drivers like to swap newline and carriage return, so when
you type carriage return (sent both by that key and by <code>^m</code>, which is
the same as the character represented by <code>\r</code>), it comes out as newline
(on most keyboards, just sent by <code>^j</code>, which is the same as the
character represented by <code>\n</code>). It is the newline character which is the
one you `see' at the end of the line (by virtue of the fact it is the
end of the line). However, <code>^v</code> sees through this and if you type <code>^m</code>
after it, it inserts a literal <code>^m</code>, which just looks like a <code>^m</code>
because that's how zsh outputs it. So that's why that doesn't work.
Actually, <code>self-insert-unmeta</code> would see the <code>^m</code>, too, because that's
what you get when you strip off the <code>\e</code>, but it has a little extra code
to make UNIX users feel at home, and behaves as if it were a newline.
Normally, <code>^j</code> and <code>^m</code> are treated the same way (<code>accept-line</code>), but
the literal characters have different behaviours. If you're now very
confused, just be thankful I haven't told you about the additional
contortions which go on when outputting a newline.)</p>
<p>It probably doesn't seem particularly useful yet, because all you've
done is miss out a new prompt. What makes it so is that you can now go
up and down between the two (or more) lines just using the cursor keys.
I'm assuming you haven't rebound the cursor keys, your terminal isn't a
dumb one which doesn't support cursor up, and the option <code>singlelinezle</code>
isn't in effect --- just unset it if it is, you'll be grateful later.</p>
<p>So for example, type</p>
<pre><code> % if [[ true = false ]]; then<ESC><RET>
print Fuzzy logic rules<ESC><RET>
fi
</code></pre>
<p>where I indented that second line just with spaces, because I usually do
inside an `if'. There are no continuation prompts here, just the
original <code>$PS1</code>; that's not a misprint. Now, before hitting return, move
up two lines, and edit <code>false</code> to <code>true</code>. You can see how this can be
useful. Entering functions at the command line is probably a more
typical example.</p>
<p>Suppose you've already gone through a few continuation lines in the
normal way with <code>$PS2</code>'s? You can't scroll back then, even though the
block hasn't yet been edited. There's a magic way of turning all those
continuation lines into a single block: the editor command
<code>push-line-or-edit</code>. If you're not on a continuation line, it acts like
the normal <code>push-line</code> command, which we'll meet below, but for present
purpose you use it when you are on a continuation line. You are
presented with a seamless block of text from the (redrawn) prompt to the
end which you can edit as one. It's quite reasonable to bind
<code>push-line-or-edit</code> instead of <code>push-line</code>, to either <code>^q</code> or <code>\eq</code> (in
Emacs mode, which I will assume, as usual). Be careful with <code>^q</code>, though
--- if the option <code>flowcontrol</code> is set it will probably be swallowed up
by the terminal driver and not get through to the shell, the same
problem I mentioned above for <code>^s</code>.</p>
<p><spanid="l101"></span></p>
<h3id="462-the-builtin-vared-and-the-function-zed"><aclass="header"href="#462-the-builtin-vared-and-the-function-zed">4.6.2: The builtin vared and the function zed</a></h3>
<p>I mentioned the <code>vared</code> command in <ahref="zshguide03.html#syntax">chapter 3</a>;
it uses the normal line editor to editor a variable, typically a long
one you don't want to have to type in completely like <code>$path</code>, although
you need to remember <em>not</em> to put the `<code>$</code>' in front or the shell will
substitute it before <code>vared</code> is run. However, since it's just a piece of
text like any other input, this, too, can have multiple lines, which you
enter in the same way --- and since a shell parameter can contain
anything at all, you have a pretty general purpose editor. The shell
function `<code>zed</code>' is supplied with the shell and allows you to edit a
file using all the now-familiar commands. Since when editing files you
don't expect a carriage return to dump you out of the editor, just to
insert a new line, zed rebinds carriage return to <code>self-insert-unmeta</code>
(the `<code>-unmeta</code>' here is just to get the swapping behaviour of turning
the carriage return into a newline). To save and exit, you can type
<code>^j</code>, or, if your terminal does something odd with that, you can also
use <code>^x^w</code>, which is designed to look like Emacs' way of writing a file.</p>
<p>If you look at <code>zed</code>, you will see it has a few bells and whistles ---
for example, `<code>zed -f</code>' allows you to edit a function --- but the code
to read a file into a parameter, edit the parameter, and write the
parameter back to the file is extremely simple; all the hard editing
code is already handled within <code>vared</code>. Indeed, <code>zed</code> is essentially a
completely general purpose editor, though it quickly becomes inefficient
with long files, particularly if they are larger than a single screen;
as you would expect, zle was written to cope efficiently with short
chunks of text.</p>
<p>It would probably be nice if you could make key bindings that only
applied within vared by using a special keymap. That may happen one day.</p>
<p>By the way, note that you can edit arrays with vared and it will handle
the different elements sensibly. As usual, whitespace separates
elements; when it presents you with an array which contains whitespace
within elements, vared will precede it with a backslash to show it isn't
a separator. You can insert quoted spaces with backslashes yourself.
Only whitespace characters need this quoting, and only backslashes work.</p>
<p>For example,</p>
<pre><code> array=('one word' 'two or more words')
vared array
</code></pre>
<p>presents you with `<code>one\ word two\ or\ more\ words</code>'. If you add `<code> and\ some\ more.</code>', hit return, and type `<code>print -l $array</code>' to show
one element per line you will see</p>
<pre><code> one word
two or more words
and some more.
</code></pre>
<p>Some older versions of the shell were less careful about spaces within
elements.</p>
<p><spanid="l102"></span></p>
<h3id="463-the-buffer-stack"><aclass="header"href="#463-the-buffer-stack">4.6.3: The buffer stack</a></h3>
<p>The mysterious other use for <code>push-line-or-edit</code> will now be explained.
Let's stick to <code>push-line</code>, in fact, since I've already dealt with the
<code>-or-edit</code> bit.</p>
<p>Type</p>
<pre><code> print I was just in the directory
</code></pre>
<p>(no newline). Oh dear, which directory were you just in? You don't want
to interrupt the flow of text to find out. Hit `<code>\eq</code>'; the line you've
been typing disappears --- but don't worry, it hasn't gone. Now type</p>
<pre><code> dirs
</code></pre>
<p>Two things happen: that last line is executed, of course, showing the
list of directories on the directory stack (your use of <code>pushd</code> and
<code>popd</code>), but also the line you got rid of before has reappeared, so you
can continue to edit it.</p>
<p>You may not realise straight away quite how useful this is, but I used
it several times just while I was writing the previous paragraph. For
example, I was alternating directories between the zle source code and
the directory where I keep this guide, and I started typing a `<code>grep</code>'
command before realising I was in the wrong directory. All I need to do
is type <code>\eq</code>, then <code>pushd</code>, to put me where I want to be, and finish
off the <code>grep</code>.</p>
<p>The `buffer stack', which is the jargon for this mechanism, can go as
deep as you like. It's a last-in-first-out (LIFO) stack, so the line
pushed onto it by the most recently typed <code>\eq</code> will reappear first,
followed by the back numbers in reverse order. You can even prime the
buffer stack from a function --- not necessarily a zle function, though
that works too --- with `<code>print -z</code><em>command-line</em>'.</p>
<p>You can pull something explicitly off the stack, if you want, by typing
<code>\eg</code>, but that has the same effect as clearing the current line and
hitting return. You can of course push the same line multiple times: if
you need to do a whole series of things before executing it, just hit
<code>\eq</code> again each time the line pops back up.</p>
<p>I lied a little bit, to avoid confusion. The cleverness of
<code>push-line-or-edit</code> about multi-line buffers extends to the this case,
too. If you do a normal <code>push-line</code> on a multi-line buffer, only the
current single line is pushed; the command to push the whole lot, which
is probably what you want, is <code>push-input</code>. But if you have
<code>push-line-or-edit</code> bound, you can forget the distinction, since it will
do that for you. If you've been paying attention you can work out the
following sequence (assuming <code>\eq</code> has been rebound to
<code>push-line-or-edit</code>):</p>
<pre><code> % if [[ no = yes ]]; then
then> print<ESC>q<ESC>q
</code></pre>
<p>The first <code>\eq</code> turns the two lines into a single buffer, then the
second pushes the whole lot onto the buffer stack. This saves a lot of
thinking about bindings. Hence I would recommend users of Emacs mode add</p>
<pre><code> bindkey '\eq' push-line-or-edit
</code></pre>
<p>to their <code>.zshrc</code> and forget the distinctions.</p>
<p>If you don't speak English as you first language, first of all,
congratulations for getting this far. Secondly, you may think of
`widget' only as a technical word applied to the object which realises
some computational idea, like the thing that implements text editing in
a window system, for example. However, to most English speakers,
`widget' is a humorous word for an object, a bit like
`whatyoumacallit' or `thingummybob', as in `where's that clever
widget that undoes the foil and takes out the cork in one go'. Zsh's use
has always seemed to me closer to the second, non-technical version, but
I may be biased by the fact that the internal object introduced by
Zefram to represent a widget, and never seen by the user, is called a
`thingy', which I won't refer to again since you don't need to know.</p>
<p>Anyway, a `widget' is essentially what I've been calling an editor
command up to now, something you can bind to a key sequence. The reason
the more precise terminology is useful is that as soon as you have shell
functions flying around, the word `command' is hopelessly non-specific,
since functions are full of commands which may or may not be widgets. So
I make no apology for using the word.</p>
<p>So now we are introducing a second type of widget: one which, instead of
something handled by code built into the shell, is handled by a function
written by the user. They are completely equivalent; <code>bindkey</code> and
company don't care which it is. All you need to do to create a widget is</p>
<pre><code> zle -N widget-name function-name
</code></pre>
<p>then <em>widget-name</em> can be used in <code>bindkey</code>, or <code>execute-named-cmd</code>, and
the function <em>function-name</em> will be run. If the <code>widget-name</code> and
<code>function-name</code> are the same, which is often the simplest thing to do,
you just need one of them.</p>
<p>You can list the existing widgets by using `<code>zle -l</code>', although often
`<code>zle -lL</code>' is a better choice since the output format is then the same
as the form you would use to define the widget. If you see lots of
`<code>zle -C</code>' widgets when you do that, ignore them for now; they are
completion widgets, handled a bit differently and described in <ahref="zshguide06.html#comp">chapter
6</a>.</p>
<p>Now you need to know what should go into the function.</p>
<p><spanid="l105"></span></p>
<h3id="472-executing-other-widgets"><aclass="header"href="#472-executing-other-widgets">4.7.2: Executing other widgets</a></h3>
<p>The simplest thing you can do inside a function implementing a widget is
call an existing function. So,</p>
<pre><code> my-widget() {
zle backward-word
}
zle -N my-widget
</code></pre>
<p>creates a widget called <code>my-widget</code> which behaves in every respect
(except speed) like the builtin widget <code>backward-word</code>. You can even
give it a prefix argument, which is passed down; <code>\e3</code> then whatever you
bound the widget to (or <code>\exmy-widget</code>) will go backward three words.</p>
<p>Suppose you wanted to pass your own prefix argument to <code>backward-word</code>,
instead of what the user typed? Or suppose you want to take account of
the prefix argument, but do something different with it? Both are
possible.</p>
<p>Let's take the first of those. You can supply a prefix argument for this
command alone by putting <code>-n</code><em>argument</em> after the widget name (note
this is not where most options go).</p>
<pre><code> my-widget() {
zle backward-word -n 2
}
</code></pre>
<p>This always goes backwards two words, overriding any numeric argument
given by the user. (You can redefine the function without telling zle
about it, by the way; zle just calls whatever function happens to be
defined when the widget is run.) If you put just <code>-N</code> after the name
instead, it will cancel out any prefix given by the user, without
introducing a new one.</p>
<p>The other part of prefix handling --- intercepting the one the user
specified and maybe modifying it --- introduces one of the most
important parts of user-defined widgets. Zle provides various parameters
which can be read and often written to alter the behaviour of the editor
or even the text being edited. In this case, the parameter is <code>$PREFIX</code>.
For example,</p>
<pre><code> my-widget() {
zle backward-word -n $(( ${NUMERIC:-1} * 2 ))
}
</code></pre>
<p>This uses an arithmetic substitution to provide an argument to
<code>backward-word</code> which is twice what the user gave. Note that
<code>${NUMERIC:-1}</code> notation, which is important: most of the time, you
don't give a numeric argument to a command at all, and in that case zle
naturally enough treats <code>$NUMERIC</code> as if it wasn't set. This would mess
up the arithmetic substitution.</p>
<p>By the way, if you do make an error in a shell function, you won't see
it; you'll just get a beep, unless you've turned that off with <code>setopt nobeep</code>. The output from such functions is junked, since it would mess
up the display. So you should do any basic debugging before turning the
function into a widget, for example, stick a <code>print</code> in front and run it
directly --- you can't execute widgets from outside the editor.</p>
<p>The following also works:</p>
<pre><code> my-widget() {
(( NUMERIC = ${NUMERIC:-1} * 2 ))
zle backward-word
}
</code></pre>
<p>because you can alter <code>$NUMERIC</code> directly, and unless overridden by the
<code>-n</code> argument it is used by any widgets called from the function. If you
called more widgets inside the function --- and you can call as many as
you like --- the same argument would apply to all the ones that didn't
have an explicit <code>-n</code> or <code>-N</code>.</p>
<p>Some widgets allow you to specify non-numeric arguments. At the moment
these are mainly search functions, which you can give an explicit search
string. Usually, however, you want to specify a new search string each
time. The most useful way of using this I can see is to provide an
initial argument for incremental search commands. Later, I'll show you
how you can read in characters in a similar fashion to Emacs mode's <code>^r</code>
<h3id="473-some-special-builtin-widgets-and-their-uses"><aclass="header"href="#473-some-special-builtin-widgets-and-their-uses">4.7.3: Some special builtin widgets and their uses</a></h3>
<p>There are some things you might want to do with the editor in a zle
function which wouldn't be useful executed directly from zle. One is to
cause an error in the same way as a normal widget does. You can do that
with `<code>zle beep</code>'. However, this doesn't automatically stop your
function at that point; it's up to you to return from it.</p>
<p>It's possible to redefine a builtin widget just by declaring it with
`<code>zle -N</code>' and defining the corresponding function. From now on, all
existing bindings which refer to that widget will cause yours to be run
instead of the builtin one. This happens because zle doesn't actually
care what a widget does until it is run. You can see this by using
<code>bindkey</code> to define a key sequence to call an undefined widget such as
<code>any-old-string</code>. The shell doesn't complain until you actually hit the
key sequence.</p>
<p>Sometimes, however, you want to be sure to call the builtin widget, even
if the behaviour has been redefined. You can do this by putting a `<code>.</code>'
in front of the name of the widget; `<code>zle .up-line-or-history</code>' always
calls the builtin widget usually referred to as <code>up-line-or-history</code>,
even if the latter has been redefined. One use for this is to rebind
`<code>accept-line</code>' to do something whenever zle is about to pass a line up
to the shell, but to accept the line anyway: you write your own widget
<code>accept-line</code>, make sure it calls `<code>zle .accept-line</code> just before it
finishes, and then use `<code>zle -N accept-line</code>. Here's a trivial but not
entirely stupid example:</p>
<pre><code> accept-line() {
print -n "\e]2;Executing $BUFFER\a"
zle .accept-line
}
zle -N accept-line
</code></pre>
<p>Now every time you hit return to execute a command, that <code>print</code> command
will be executed first. As written, it puts `<code>Executing</code>' and then the
contents of the command line (see below) into the title of your xterm
window, assuming it understands the usual xterm escape sequences. In
fact, this particular example is usually handled with the special shell
function (not zle function) `<code>preexec</code>' which is passed a command line
about to be executed as an argument instead of in <code>$BUFFER</code>. There seems
to be a side effect of rebinding <code>accept-line</code> that the return key stops
working in the minibuffer under some circumstances.</p>
<p>Note that to undo the fact that return executes your new widget, you
need to alias <code>accept-line</code> back to <code>.accept-line</code>:</p>
<pre><code> zle -A .accept-line accept-line
</code></pre>
<p>If you have trouble remembering the order, as with most alias or rename
commands in zsh and UNIX generally, including <code>ln</code> and <code>bindkey -A</code>, the
existing command, the one whose properties you want to keep, comes
first, while the new name for it comes second. Also, as with those
commands, it doesn't matter if the second name on the line currently
means something else; that will be replaced by the new meaning.
Afterwards, you don't need to worry about your own <code>accept-line</code> widget;
zle handles the details of removing widgets when they're no longer
referred to. The function's still there, however, since as far as the
rest of the shell is concerned it's just an ordinary shell function
which you need to `<code>unfunction</code>' to remove.</p>
<p>Do remember, however, not to delete a widget which redefines a basic
internal widget by the obvious command</p>
<pre><code> # Noooo!
zle -D accept-line
</code></pre>
<p>which stops the return key having any effect other than complaining
there's no such widget. If you get into real trouble,
`<code>\ex.accept-line</code>' should work, as you can use the `<code>.</code>'-widgets
anywhere you can use any other except where they would redefine or
delete a `<code>.</code>' widget. Use the `<code>zle -A</code>' command above with the
extended-command form of `<code>.accept-line</code>' to return to normality. If
you try to redefine or delete a `<code>.</code>' widget, zle will tell you it's
protected. You can remove any other widget in this way, however, even if
it is still bound to a key sequence; you will then see an error if you
type that sequence.</p>
<p>One point to note about <code>accept-line</code> is that the line isn't passed up
to zsh instantly, only when your own function exits. This is pretty
obvious when you think about it; zle is called from the main shell, and
if your own zle widget hasn't finished executing, the main shell hasn't
got control back yet. But it does mean, for example, that if you modify
the command line after a call to <code>accept-line</code> or <code>.accept-line</code>, those
changes are reflected in the line passed up to the shell:</p>
<pre><code> # Noooo! to this one too.
accept-line() {
zle .accept-line
BUFFER='Ha ha!'
}
</code></pre>
<p>This always returns the string `<code>Ha ha!</code>' to the main shell. This is
not particularly useful unless you are constructing a Samuel Beckett
shell for display at an installation in a Parisian art gallery.</p>
<p><spanid="l107"></span></p>
<h3id="474-special-parameters-normal-text"><aclass="header"href="#474-special-parameters-normal-text">4.7.4: Special parameters: normal text</a></h3>
<p>The shell makes various parameters available for easy manipulation of
the command line. You've already seen <code>$NUMERIC</code>. You may wonder what
happens if you have your own parmeter called <code>$NUMERIC</code>; after all, it's
a fairly simple string to use as a name. The good news is you don't need
to worry; when the shell runs a zle function, it simply hides any
existing occurrences of a parameter and makes its special parameters
available. Then when it exits, the original parameter is reenabled. So
all you have to worry about is making sure you don't use these special
parameters for anything else while you are inside a zle widget.</p>
<p>There are four particularly common zle parameters.</p>
<p>First, there are three ways of referring to the text on the command
line: <code>$BUFFER</code> is the entire line as a string, <code>$LBUFFER</code> is the line
left of the cursor position, and <code>$RBUFFER</code> is the line after it
including the character under the cursor, so that the division is always
at the point where the next inserted character would go. Any or all of
these may be empty, and <code>$BUFFER</code> is always the string
<code>$LBUFFER$RBUFFER</code>.</p>
<p>The necessary counterpart to these is <code>$CURSOR</code>, which is the cursor
position with 1 being the first character. If you know how the shell
handles substrings in parameter substitutions, you will be able to see
that <code>$LBUFFER</code> is <code>$BUFFER[1,$CURSOR-1]</code>, while <code>$RBUFFER</code> is
<code>$BUFFER[$CURSOR,-1]</code> (unless you are using the option <code>KSH_ARRAYS</code> for
compatibility of indexes with ksh --- this isn't recommended for
implementing zle or completion widgets as it causes confusion with the
ones supplied with the shell).</p>
<p>The really useful thing about these is that they are modifiable. If you
modify <code>$LBUFFER</code> or <code>$RBUFFER</code>, then <code>$BUFFER</code> and <code>$CURSOR</code> will be
modified appropriately; lengthening or shortening <code>$LBUFFER</code> increases
or decreases <code>$CURSOR</code>. If you modify <code>$BUFFER</code>, you may need to set
<code>$CURSOR</code> yourself as the shell can't tell for sure where the cursor
should be. If you alter <code>$CURSOR</code>, characters will be moved between
<code>$LBUFFER</code> and <code>$RBUFFER</code>, but <code>$BUFFER</code> will remain the same.</p>
<p>This makes tasks along the lines of basic movement and deletion commands
extremely simple, often just a matter of pattern matching. However, it
definitely pays to know about zsh's more sophisticated pattern matching
and parameter substitution features, described in the next chapter. For
example, if you start a widget function with</p>
<pre><code> emulate -L zsh
setopt extendedglob
LBUFFER=${LBUFFER%%[^[:blank:]]##}
</code></pre>
<p>then <code>$LBUFFER</code> contains the line left of the cursor stripped of all the
non-blank characters (usually anything except space or tab) immediately
to the left of the cursor.</p>
<p>This function uses the parameter substitution feature
`<code>${</code><em>param</em><code>%%</code><em>pattern</em><code>}</code>' which removes the longest match of
<em>pattern</em> from the end of <code>$</code><em>param</em>. The `<code>emulate -L zsh</code>' ensures
the shell options are set appropriately for the function and makes all
option settings local, and `<code>setopt extendedglob</code>' which turns on the
extended pattern matching features; it is this that makes the sequence
`<code>##</code>' appearing in the pattern mean `at least one repetition of the
previous pattern element'. The previous pattern element is `anything
except a blank character'. Hence, all occurrences of non-blank
characters are removed from the end of <code>$LBUFFER</code>.</p>
<p>If you want to move the cursor over those characters, you can tweak the
function slightly:</p>
<pre><code> emulate -L zsh
setopt extendedglob
chars=${(M)LBUFFER%%[^[:blank:]]##}
(( CURSOR -= ${#chars} ))
</code></pre>
<p>The string `<code>(M)</code>' has appeared at the start of the parameter
substitution. This is part of zsh's unique system of parameter flags;
this one means `insert the matched portion of the substitution'. In
other words, instead of returning <code>$LBUFFER</code> stripped of non-blank
characters at the end, the substitution returns those very characters
which it would have stripped. To skip over them is now a simple matter
of decreasing <code>$CURSOR</code> by the length of that string.</p>
<p>You'll find if you try these examples that they probably don't do quite
what you want. In particular, they don't handle any blank characters
found next to the non-blank ones which normal word-orientated functions
do. However, you now have enough information to add tests for that
yourself.</p>
<p>If you get more sophisticated, you can then add handling for <code>$NUMERIC</code>.
Remember this isn't set unless the user gave it explicitly, so it's up
to you to treat it as 1 in that case.</p>
<p><spanid="l108"></span></p>
<h3id="475-other-special-parameters"><aclass="header"href="#475-other-special-parameters">4.7.5: Other special parameters</a></h3>
<p>A large fraction of what you are likely to want to do can be done with
the parameters we've already met. Here are some hints as to how you
might want to use some of the other parameters available. As always, for
a complete list with rather less in the way of hints see the manual.</p>
<p><code>$KEYS</code> tells you the keys which were used to call the widget; it's a
string of those raw characters, not turned into the <code>bindkey</code> format. In
other words, if it was a single key (including possibly a control key or
a meta key), <code>$KEYS</code> will just contain a single character. So you can
change the widget's behaviour for different keys. Here's a very (very)
simple function like <code>self-insert</code>:</p>
<pre><code> LBUFFER=$LBUFFER$KEYS
</code></pre>
<p>Note this doesn't work very well with <code>\ex</code> extended command handling;
you just get the <code>^m</code> from the end of the line. You need to make sure
any widgets which use <code>$KEYS</code> are sensibly bound. This also doesn't
handle numeric arguments to repeat characters; it's a fairly simple
exercise (particularly given zsh's `<code>repeat</code>' loop) to add that.</p>
<p><code>$WIDGET</code> and <code>$LASTWIDGET</code> tell you the name of the current widget
being executed and the one before that. These don't sound all that
useful at first hearing. However, you can use <code>$WIDGET</code> together with
the fact that a widget doesn't need to have the same name as the
function that defines it. You can define</p>
<pre><code> zle -N this-widget function
zle -N that-widget function
</code></pre>
<p>and test <code>$WIDGET</code> inside <code>function</code> to see if it contains <code>this-widget</code>
or <code>that-widget</code>. If these have a lot of shared code, that is a
considerable simplification without having to write extra functions.</p>
<p><code>$LASTWIDGET</code> tends to be used for a slightly different purpose:
checking whether the last command to be executed was the same as the
current one, or maybe was just friendly with it. Here are edited
highlights of the function <code>up-line-or-beginning-search</code>, a sort of
cross between <code>up-line-or-search</code> and
<code>history-beginning-search-backward</code> which has been added to the shell
distribution for <code>4.1</code>. If there are previous lines in the buffer, it
moves up through them; else if it's the first in a sequence of calls to
this function it remembers the cursor position and looks backwards for a
line with the same text from the start up to that point, and puts the
cursor at the end of the line; else if the same widget has just been
executed, it uses the old cursor position to search for another match
further back in the history.</p>
<pre><code> if [[ $LBUFFER == *$'\n'* ]]; then
zle .up-line-or-history
__searching=''
else
if [[ $LASTWIDGET = $__searching ]]; then
CURSOR=$__savecursor
else
__savecursor=$CURSOR
fi
__searching=$WIDGET
zle .history-beginning-search-backward
zle .end-of-line
fi
</code></pre>
<p>We test <code>$__searching</code> instead of <code>$WIDGET</code> directly to be able to tell
the case when we are moving lines instead of searching. <code>$__savecursor</code>
gives the position for the backward search, after which we put the
cursor at the end of the line. The parameters beginning `<code>__</code>' aren't
local to the function, because we need to test them from the previous
execution, so they have been given underscores in front to try to
distinguish them from other parameters which might be around.</p>
<p>You'll see that the actual function supplied in the distribution is a
little more complicated than this; for one thing, it uses styles set by
the user to decide it's behaviour. Styles are described for use with
completion widgets in <ahref="zshguide06.html#comp">chapter 6</a>, but you can use
them exactly the same way in zle functions.</p>
<p>The full version of <code>up-line-or-beginning-search</code> uses another
parameter, <code>$PREBUFFER</code>. This contains any text already absorbed by
<code>zle</code> which you can no longer edit --- in other words, text read in
before the shell prompted with <code>$PS2</code> for the remainder. Testing `<code>[[ -n $PREBUFFER ]]</code>' therefore effectively tests whether you are at the
<code>$PS2</code>. You can use this to implement behaviour after the fashion of
<code>push-line-or-edit</code>.</p>
<p><spanid="l109"></span></p>
<h3id="476-reading-keys-and-using-the-minibuffer"><aclass="header"href="#476-reading-keys-and-using-the-minibuffer">4.7.6: Reading keys and using the minibuffer</a></h3>
<p>Every now and then you want the editor to do a sequence of operations
with user input in the middle. This is usually done by a combination of
two commands.</p>
<p>First, you may need to prompt the user in the minibuffer, just like
<code>\ex</code> does. You can do this with `<code>zle -R</code>'. Its basic function is to
redisplay the command line, flushing all the changes you have made in
your function so far, but you can give it a string argument which
appears in the minibuffer, just below the command line. You can give it
a list of other strings after that, which appear in a similar way to
lists of possible completions, but have no special significance to zle
in this case.</p>
<p>To get input back from the user, you can use `<code>read -k</code>' which reads a
single key (not a sequence; no lookup takes place). This command is
always available in the shell, but in this case it is handled by zle
itself. The key is returned as a raw byte. Two facilities of arithmetic
evaluation are useful for handling this key: `<code>#key</code>' returns the ASCII
code for the first character of <code>$key</code>, while `<code>##</code><em>key</em>' returns the
ASCII code for <em>key</em>, which is in the form that <code>bindkey</code> would
understand. For example,</p>
<pre><code> read -k key
if (( #key == ##\C-g )); then
...
</code></pre>
<p>makes the use of arithmetic evaluation. The form on the left turns the
first character in <code>$key</code> into a number, the second turns the literal
bindkey-style string <code>\C-g</code> into a number (ASCII 7, since 1 to 26 are
just <code>\C-a</code> to <code>\C-z</code>). Don't confuse either of these forms with
`<code>$#key</code>', which is the length of the string in the parameter, in this
case almost certainly 1 for a single byte; this form works both inside
and outside arithmetic substitution, the other forms only inside. The
`<code>(( ... ))</code>' form is recommended for arithmetic substitutions whenever
possibly; you can do it with the basic `<code>[[ ... ]]</code>' form, since
`<code>-eq</code>' and similar tests treat both sides as arithmetic, though you
may need extra quoting; however, the only good reason I know for doing
that is to avoid using two types of condition syntax in the same complex
test.</p>
<p>These tricks are only really useful for quite complicated functions. For
an example, look at the function <code>incremental-complete-word</code> supplied
with the zsh source distribution. This function doesn't add to clarity
by using the form `<code>#\\C-g</code>' instead of `<code>##\C-g</code>'; it does the same
thing but the double backslash is very confusing, which is why the other