Another way to do this is with @-functions (Section 18.4).
Not every keymap is something you want to save in your .exrc file. Some maps are handy just because you have to do a repetitive series of edits. Developing a complex map to repeat your edits can save more time than it takes. For example, assume that you have a glossary with entries like this, separated by blank lines:
map - an ex command which allows you to associate a complex command sequence with a single key.
You want to convert this glossary list to HTML format, so that it looks like:
<DT>map</DT> <DD> An ex command which allows you to associate a complex command sequence with a single key. </DD>
The best way to define a complex map is to do the edit once manually, writing down each keystroke that you must type. Then recreate these keystrokes as a map.
Use I
to insert the tag for an data
list term (<DT>
) at the
beginning of the line.
Press ESC to terminate text-input mode. Move just before the dash
(t-
). Use 3s
to replace the dash and space after it
with the closing term tag (</DT>
).
Still in text-input mode, press RETURN to insert a new line. (This
moves the definition to a newline underneath the <DT>
tags.) Enter the opening data
list definition (<DD>
) tag, and
press RETURN again. (The definition moves to yet another newline
underneath the <DD>
tag.)
Press ESC to terminate text-input mode. Your cursor is at the start of
the definition. Capitalize the first word of the definition (~
).
Go to the blank line after the definition (}
), open a newline above (O
), and insert the closing data list definition (</DD>
) tag. Press ESC to end
text-input mode.
Press RETURN to end the keymap definiton.
That's quite an editing chore if you have to repeat it more than a few times.
With map
you can save the entire sequence so
that it can be re-executed with a single keystroke:
map g I<DT>^[t-3s</DT>^M<DD>^M^[~}O</DD>^[
(To store a map during a vi session, type a
colon (:) first.) Note that you have to "quote" both the ESC and RETURN
characters with CTRL-v (Section 18.6). ^[
is the sequence that appears when you type CTRL-v followed by ESC. ^M
is the sequence shown
when you type CTRL-v RETURN.
Now, simply typing g
will perform the
entire series of edits. At a slow data rate you can actually see the edits
happening individually. At a fast data rate it will seem to happen by
magic.
Don't be discouraged if your first attempt at keymapping fails. A small error
in defining the map can give very different results from the ones you expect.
You can probably type u
to undo the edit and
try again. It's safer to write the file (:w
)
before you use the keymap — in case your version of vi can't undo complex keymaps.
If the keymap is complex, or if you're defining several maps at once, you can
make a temporary keymap file and edit the maps there until you've worked out the
bugs. For instance, write your buffer and type :e
temp
to open a temporary file temp. Make the
keymaps, one per line — without a colon (:) first. Write this map file (:w
), then read it in to the editor (:so %
). If there's no error, switch to the
original file (:e #
or CTRL-^), and try the
map. (Section 17.3 explains %
and #
.) Then,
if there are problems, go back to the map file (:e!
#
, where the !
tells vi not to write the mistakes out to the file), fix
the keymap, and repeat the process until you get what you wanted.
In this case, for instance, maybe the next glossary definition starts with an
uppercase letter, but the ~
in the keymap is
changing that letter to lowercase. You need to change the ~
to an ex
substitution command that converts a lowercase letter to
uppercase (Section
17.16). If you've saved the keymap in a temporary file, just type
:e#
and change it:
map g I<DT>^[t-3s</DT>^M<DD>^M^[:s/^./\u&/^M}O</DD>^[
We've changed ~
to :s/^./\u&/^M
. As you can see, complex keymaps can be tough to
decipher after you've written them, which makes the notes you've written even
more useful.
—TOR and JP, from Learning the vi Editor (O'Reilly, 1998)