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)
Copyright © 2003 O'Reilly & Associates. All rights reserved.