18.2.1. Command Mode Maps
The map command acts a
lot like ab (Section 17.23) except that you define a macro for command
mode instead of text-input mode. The map! command
works during text-input mode; see the following list.
- map x sequence
-
Define x as a sequence of
editing commands.
- unmap x
-
Disable the x definition.
- map
-
List the characters that are currently mapped.
As with other ex-mode commands, these map commands
can be saved in your .exrc file
(Section 17.30) or typed in after a colon (:). If you
want a keymap to use just during this editing session, you might find
that vi @-functions (Section 18.4) are easier to create and use. The map
commands are best for keymaps that you save in your
.exrc file and use during many editing sessions.
Before you can start creating your own maps, you need to know the
keys not used in command mode that are available for user-defined
commands. Here's a list of the unused keys in
original vi:
- Letters
-
g K q V v
- Control keys
-
^A ^K ^O ^T ^W ^X
- Symbols
-
_ * \ =
NOTE:
The = is used by vi if Lisp mode is set. In
addition, other letters such as v may already be used in other
systems.
With maps you can create simple or complex command sequences. As a
simple example, you could define a command to reverse the order of
words. In vi, with the cursor as shown:
you can the scroll page
the sequence to put the after
scroll would be dwwP: (delete
word), dw; (move to the next word),
w; (put the deleted word before that word),
P. (You can also use W instead
of w.) Saving this sequence:
map v dwwP
enables you to reverse the order of two words at any time in the
editing session with the single keystroke v.
You can also map certain multiple-character sequences. Start the map
with one of the symbols in the previous list. For example, to map the
keystrokes *s to put single quotes around a word
('word')
and *d to use double quotes
("word"):
^[ Section 18.6
map *s Ea'^[Bi'^[
map *d Ea"^[Bi"^[
Now you'll be able to make
hundreds of keymaps (though your version of vi
probably has a limit).
You may also be able to associate map sequences with your
terminal's function keys if your termcap or terminfo entry
(Section 5.2) defines those keys. For example, to make
function key F1 transpose words:
map #1 dwelp
NOTE:
Map assignments are not really limited to unused keys. You can map
keys that are defined as other vi commands, but
then the key's original meaning is inaccessible.
This is probably okay if the key is tied to a command that you rarely
use. There's more information in Section 18.12 about the noremap option.
18.2.2. Text-Input Mode Maps
The map! command
works like map, but map! works
during text-input mode. You actually set the map!
during command mode, in the same way as a plain
map: at a colon (:) prompt. Type
map! followed by a space and the key(s) that
activate the map; then type a space and the text for which the
text-input mode map stands. These text-input mode maps are a lot like
abbreviations (Section 17.23); the difference is that
map! lets your keymap switch from text-input mode
to command mode, execute commands, then go back to text-input mode.
To go to command mode during a map!, put an ESC
key in the value of the map by typing CTRL-v
and then ESC (Section 18.6). After your
map! does whatever it does in command mode, it can
re-enter text-input mode with the usual commands:
a, i, and so on.
Let's say you normally never type the caret
(^) key during input mode. When
you're typing along, as you realize that what
you're typing is important, you want to press the
caret key. Then, vi should open a line above and
insert the phrase "THIS IS
IMPORTANT:". Finally, vi should
return you to text-input mode at the end of the line where you
pressed the caret key. To do that, go to command mode and enter the
following map! command. The first
^ comes from pressing the caret key. Then
you'll see two places with ^[;
that are made by pressing CTRL-v followed by the ESC key. Finish the
map by pressing RETURN:
:map! ^ ^[OTHIS IS IMPORTANT:^[jA
What does that do? It executes the same vi
commands you'd use to add those three words
yourself, manually. During text-input mode, typing a caret
(^) will:
-
Do ESC to go to command mode.
-
Use O to open a new line above (in text-input
mode).
-
Enter the text THIS IS IMPORTANT:.
-
Do another ESC to go back to command mode.
-
Do j to go down a line (to the line where you
started).
-
Do A to put you at the end of the line, in
text-input mode.
The trick is to use
map! only to redefine keys you'll
never use for anything else during text-input mode. To disable a
text-input mode map temporarily, press CTRL-v before the key. For
example, to put a real caret into your file, type CTRL-v ^. To
disable an input-mode map for the rest of your vi
session, type :unmap! followed by the character(s)
that activate the map.
A
more common example is mapping your keyboard's arrow
or function keys to do something during text-input mode. These keys
send a special series of characters. Normally, without a
map! defined for these keys, the characters they
send will be put into your editor buffer -- just as if
you'd typed the characters they make yourself, one
by one. For instance, my left-arrow key sends the characters
ESC, then [ (left bracket),
then D. Without a text-input mode
map! defined for that three-character sequence,
vi will be hopelessly confused if I press that
arrow key.[51] Many
Unix developers have added text-input mode maps for arrow keys. You
can see them when you list all your text-input mode maps by typing
:map! by itself, with nothing after:
up ^[[A ^[ka
down ^[[B ^[ja
left ^[[D ^[hi
right ^[[C ^[la
^ ^ ^[OTHIS IS IMPORTANT:^[jA
Section 18.3 lists some problems with
map!.
--JP, DG, and LL