While you're editing, you may find that you are using a command
sequence frequently, or you may occasionally use a very complex
command sequence. To save yourself keystrokes, or the time it takes
to remember the sequence, assign the sequence to an unused key by
using the
map
and
map!
commands.
The
map
command acts a lot like
ab
(
30.31
)
except that you
define a macro for command mode instead of text-input mode.
(The
map!
command works during text-input mode.
See below.)
-
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 (
4.9
)
-
or typed in after a colon (
:
).
If you want a keymap to use only during this editing session, you might
find that
vi
@
-functions (
31.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:
-
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.)
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 list above.
For example, to map the keystrokes
*s
to put single quotes
around a word (
'
word
'
),
and
*d
to use double quotes (
"
word
"
):
^[
|
map *s Ea'^[Bi'^[
map *d Ea"^[Bi"^[
|
Now you'll be able to make hundreds of key maps (though your version
of
vi
probably has a limit).
Article
31.9
has lots of examples.
You may also be able to associate map
sequences with your terminal's function keys if
your
termcap
or
terminfo
entry (
5.2
)
defines those keys.
For example, to make function key F1 transpose words:
map #1 dwelp
A final 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.
But this is probably okay if the key is tied to a command that you
rarely use.
There's more information in article
31.14
about the
noremap
option.
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 that
the text-input mode map stands for.
These text-input mode maps are a lot like
abbreviations (
30.31
)
;
the difference is that
map!
lets you 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!
, you'll need to put an ESC key in the
value of the map by
typing CTRL-v and then ESC (
31.6
)
.
After your
map!
does whatever 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's 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), and
-
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 temporarily disable a text-input mode map, 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 an text-input mode
map!
defined for that three-character
sequence,
vi
will be hopelessly confused
[1]
if I press that arrow key.
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
Article
31.3
lists some problems with
map!
.