Documentation chapter.
author |
Steve Losh <steve@stevelosh.com> |
date |
Sat, 03 Nov 2012 18:15:30 -0400 |
parents |
ad477bf7ad4e |
children |
41e61b3dce7a |
Strict Mapping
==============
Hold on, things are about to get a little wild.
So far we've used `map`, `nmap`, `vmap`, and `imap` to create key mappings that
will save time. These work, but they have a downside.
Run the following commands:
:::vim
:nmap - dd
:nmap \ -
Now try pressing `\` (in normal mode). What happens?
When you press `\` Vim sees the mapping and says "I should run `-` instead".
But we've already mapped `-` to do something else! Vim sees that and says "oh,
now I need to run `dd`", and so it deletes the current line.
When you map keys with these commands Vim will take *other* mappings into
account. This may sound like a good thing at first but in reality it's pure,
unadulterated evil. Let's talk about why, but first remove those mappings by
running the following commands:
:::vim
:nunmap -
:nunmap \
Recursion
---------
Run this command:
:::vim
:nmap dd O<esc>jddk
You might think that this would change `dd` to:
* Open a new line above this one.
* Exit insert mode.
* Move back down.
* Delete the current line.
* Move up to the blank line just created.
In effect, this should "clear the current line". Try it.
Vim will seem to freeze when you press `dd`. If you press `<c-c>` you'll get
Vim back, but there will be a ton of empty lines in your file! What happened?
This mapping is actually *recursive*! When you press `dd`, Vim says:
* `dd` is mapped, so perform the mapping.
* Open a line.
* Exit insert mode.
* Move down a line.
* `dd` is mapped, so perform the mapping.
* Open a line.
* Exit insert mode.
* Move down a line.
* `dd` is mapped, so perform the mapping.
* ...
This mapping can never finish running! Go ahead and remove it with the
following command:
:::vim
:nunmap dd
Side Effects
------------
Not only do the `*map` commands we've learned so far run the danger of
recursing, but because they take other mappings into account they can change
when we install various plugins.
When you install a new Vim plugin there's a good chance that you won't use and
memorize every mapping it uses. Even if you *do*, you'd have to go back and
look through your `~/.vimrc` file to make sure none of your custom mappings use
something that the plugin has mapped, and vice versa.
This would make installing plugins tedious and error-prone. There must be
a better way.
Nonrecursive Mapping
--------------------
Vim offers another set of mapping commands that will *not* take mappings into
account when they perform their actions. Run these commands:
:::vim
:nmap x dd
:nnoremap \ x
Now press `\` and see what happens.
When you press `\` Vim ignores the `x` mapping and does whatever it would do for
`x` by default. Instead of deleting the current line, it deletes the current
character.
Each of the `*map` commands has a `*noremap` counterpart that ignores other
mappings: `noremap`, `nnoremap`, `vnoremap`, and `inoremap`.
When to Use
-----------
When should you use these nonrecursive variants instead of their normal
counterparts? The answer is: always.
**Always.**
**No, seriously, ALWAYS.**
Using a bare `*map` is just *asking* for pain down the road when you install
a plugin or add a new custom mapping. Save yourself the trouble and type the
extra characters to make sure it never happens.
Exercises
---------
Convert all the mappings you added to your `~/.vimrc` file in the previous
chapters to their nonrecursive counterparts.
Read `:help unmap`.