shell

Vim. Key mapping

Maps are a way to create an association between a set of key strokes and a set of actions. They are really powerful. However, in this post, I will not explain them in the deepest detail. If you need further information, you will need a good Vim manual. As it happens with abbreviations, maps can be used regardless of the mode you are in Vim or they can be restricted to a certain operation mode. They work the same way in every mode. Type :help :map to know which map commands work in which mode.

First off,

:map
...
...
<Esc>OM       <CR>
<Esc>Ol       ,
<Esc>Ok       +
<Esc>Om       -
<Esc>Oj       *
<Esc>Oo       :
<F2>          :sp ~/TODO<CR>Go* <Esc><Up><Right><CR>
<xHome>       <Home>
<xEnd>        <End>
<S-xF4>       <S-F4>
<S-xF3>       <S-F3>
<S-xF2>       <S-F2>
<S-xF1>       <S-F1>
<xF4>         <F4>
<xF3>         <F3>

shows a list of available maps

Let us start with a small example:

:map <F2> :r!ls ~/<CR>

As you can see, maps are created very much like abbreviations.
When you type F2, Vim executes the associated sequence for that key. It is important to use <CR> when you are using :commands. Otherwise, you will have to type ENTER yourself. The map above reads the content of the ls ~/ command, i.e. it lists the $HOME directory.

When you work with maps, you are not limited to commands. You can tell Vim to “simulate” certain keystrokes. For example, you might want to execute something like “After this, I would like to move the cursor to the left”. This can be done with the “<>” notation (:help <> for more information). The following map illustrates this concept:

:map <F2> ifor(;;) {<CR>}<Up><Right><Right><Right>

Now, when pressing F2, the following text is inserted (the underscore represents the position of the cursor):

for(_;;) {
}

Notice you are still in insert mode. We could have achieved something similar with the following map:

:map <F2> ifor(;;) {<CR>}<ESC>kf;i

I personally prefer the latter. In my opinion, working in command mode is cleaner.

The following map is quite useful:

:map <F4> I#include <<ESC>A>

Let us analyze what that sequence does. First, it goes into command mode and places the cursor at the beginning of the line in insert mode. Then, it inserts the “#include <” string. Finally, it adds “>” at the end of the line.

Assuming you have a text like the following:

stdio.h

Placing the cursor on that line (at any column) and pressing F4 rewrites the line as follows:

#include <stdio.h>

Maps can deal with buffers, windows, tabs (from Vim 7 onwards) and such. Here is a small example. Suppose you have a TODO file in your $HOME directory. From time to time, while you are working, you want to add a new entry. Sounds reasonable, right?. Imagine we have a TODO file that looks like this:

* Stuff
* Things

We could easily open the file and make it ready to write a new entry with a simple map:

:map <F2> :sp ~/TODO<CR>Go* <Esc>a

Let us explain what is going on here: We split the window horizontally, editing the TODO file at the same time (:sp ~/TODO). Then the cursor is placed at the end of the file. We open a new empty line and write a “* ” (Go* ). Finally, we leave the cursor in insert mode. This way we just have to type the thing we want to remember and then we can :close the top window.

Another simple example:

:map <F6> :w %.bakcup

This saves the current buffer with the same name plus the “.backup” extension. The % is a special variable which contains the name of the current file.

Finally, if you want to delete a map because it is no longer useful, you can :unmap it.

Conclusion
Maps are a very powerful tool. You can do almost anything you may need, no matter how complex it is. There are a lot of interesting macros on the Internet. I recommend you to search the web!

VIM SHEET (VIII)

  • map Map a key to a set of commands / List available maps
  • unmap Unmap key

2 Comments

  • On 09.14.10 takizo said:

    Great tips. let say I would like to map Ctrl + character. Do I use u or u?

  • On 09.14.10 n0str0m0 said:

    Since Ctrl-u is already defined to delete the text written in the current line, you could use :inoremap <c-u> commands. Something like: inoremap <c-u> <Esc>ihello

speak up

Add your comment below, or trackback from your own site.

Subscribe to these comments.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*Required Fields