This is a read-only archive. Find the latest Linux articles, documentation, and answers at the new Linux.com!

Linux.com

Feature

Vim tips: Using Vim mappings and abbreviations

By Joe 'Zonker' Brockmeier on June 14, 2006 (8:00:00 AM)

Share    Print    Comments   

Vim ships with a lot of useful functions that make life easier when you're editing text, but Vim is also an extremely extensible editor. If you find yourself typing the same long commands or strings of text over and over again, it's time you learned how to set mappings and abbreviations in Vim, to save valuable keystrokes for your code or prose.

Just as you can set shortcuts in KDE, you can map keystrokes to actions in Vim. A mapping can be as simple as creating an abbreviation that converts your initials to your full name, or something more complicated, like running a function when you press F10. Let's take a look at mappings, and how they can make you much more productive when working in Vim.

Types of mappings

Vim actually recognizes different types of mappings, depending on what mode the editor is in. For example, you might have a mapping for F2 in insert mode that enters an HTML tag or a line of C code, and a different mapping for F2 that toggles the syntax mode on when you're in normal mode.

Vim provides several different types of map commands, including:

  1. cmap handles command-line mappings.
  2. imap handles insert-only mappings.
  3. map maps keys in normal, visual, and operator-pending mode.
  4. map! maps keys in Vim's command and insert modes.
  5. nmap maps keys in normal mode only.
  6. omap maps keys in operator-pending mode only.
  7. vmap maps keys in visual mode only.

So, use imap if you want to set a mapping that works in Vim's insert mode, cmap for mappings to work in command (last line) mode, omap to map keys to function after an operator has been used in normal mode, and so on.

Setting a mapping

Let's start with something simple. To set a mapping while in Vim, enter command mode and use the map command. Here's a quick example:

:map <F10> <Esc>:tabnew<CR>

The syntax is pretty simple. First you tell Vim that you're setting a mapping. Then, tell Vim the key that will be bound to the action -- in this case, F10. Finally, spell out the action that Vim will perform when you use F10. This is pretty easy, because you're basically just listing the same keystrokes that you'd use if you were doing it manually.

In this example, we tell Vim to enter command mode (Esc:) and run the tabnew command, followed by the carriage return to return us to normal mode. (<CR> is the same as <Enter>, just faster to type.) Now, when you type F10 in normal mode, visual mode, or operator-pending mode, Vim will open a new tab.

Every now and again, it might be useful to set a mapping on the fly -- but the odds are, if it's worth doing once, it's worth setting the mapping permanently. To do this, just open your .vimrc and insert the mapping there, like so:

map <F10> <Esc>:tabnew<CR>

Want to see all of the mappings you have set? Type :map with no arguments, and Vim will list the defined mappings, like so:

n  ,S            <Esc>:syn off<CR>
n  ,s            <Esc>:syn on<CR>
   <F11>         <Esc>:setlocal nospell<CR>
   <F10>         <Esc>:setlocal spell spelllang=en_us<CR>

The other mapping commands, :imap and :omap, can also be used without arguments to show what characters are mapped for those modes -- the :map command only shows keys mapped for modes set with :map.

In this example, you can see that I have F10 set to turn on spellchecking, and F11 set to turn it off. This will work in normal and visual mode. In normal mode, using ,S will turn syntax highlighting off, and ,s will turn it on. I use the comma in that mapping for a couple of reasons. First, the comma has no special meaning in normal mode on its own. Second, it's within easy reach of the home keys.

Since I spend a lot of time working with HTML, I've set a few mappings to work in insert mode to insert HTML tags that I use frequently:

imap <F2> <p>
imap <F3> <strong>
imap <F4> <em>
imap <F5> <code>
imap <F6> <a href="
imap <S-F6> ">
imap <F7> <blockquote>
imap <S-F2> &lt;
imap <S-F3> &gt;

You can also set a mapping to call a function. For instance, I like Vim's highlight search, when I've just performed a search. But I like to get rid of the highlighting as soon as I am done with it. I found a useful tip on the Vim.org site with a function to toggle highlight search, so I could turn it off and on with a simple quick keystroke. Here's the function that I put in my .vimrc:

function ToggleHLSearch()
       if &hls
            set nohls
       else
            set hls
       endif
endfunction

Then, I added this to the mapping section:

nmap <silent> <C-n> <Esc>:call ToggleHLSearch()<CR>.

In this example, <silent> isn't a key -- it's to tell Vim not to print a message when it runs the command. Then, the key shortcut that is mapped to the action, and the action that will be called.

Mappings can be really useful once you start writing your own Vim functions -- or using Vim functions that other folks have written already. It's certainly easier to type Ctrl-n than type :call ToggleHLSearch() every time!

Also, I don't know about other Vim users, but I've always found the F1 mapping for Vim's :help command to be a bit annoying. It's not unusual for me to accidentally tap the F1 key when I mean to hit Escape or F2. So I've taken to mapping F1 to Escape in my .vimrc:

map <F1> <Esc>
imap <F1> <Esc>

Unsetting mappings

From time to time, you might want to get rid of a mapping. You can do this in a couple of ways. The first is to change the mapping for a key -- if you want to set F10 to a new mapping, just run :map <F10> command , to replace it for that session. To unmap it completely, use :unmap <F10>.

Each of the map commands has its own unmap command -- so, to unmap an insert map (imap) command, use :iunmap; to unmap a normal mode command (nmap), use :nunmap; and so forth.

Unlike the :map commands, the :unmap commands require an argument -- so, running :unmap won't just unset all of the active mappings, it will simply return an error.

You can also prevent a key from being remapped by using the :noremap command, or :inoremap, :onoremap, etc. This can be useful if you want to set a mapping using map, but want that key to be used for something else in operator-pending mode, or something like that. Despite the name, you can override a noremap command while in Vim.

Mapping notation

We've covered the notation for some of the special keys already, such as Escape (<Esc>), Enter (<CR>), and function key notation (<F1>, <F2>, etc.). For the most part, the notation is pretty intuitive, but not always.

For example, if you want to set a mapping for Ctrl-Esc, you'd use <C-Esc>. If you want to use Shift-F1, you'd use <S-F1>. For Mac users, if you want to set a mapping for the Command key (the weird symbol-thingy that PC users scratch their heads over), you'd use <D>. Note that Alt and Meta are the same, and you can use <M-key> or <A-key>.

You can also combine several keys if you want to emulate the Emacs hand-cramp style of key mappings. For example, if you want to run a command using Shift-Alt-F2, you could use map <S-A-F2> command .

See the Vim online help for a full list of special keys and their notation.

Abbreviations

Abbreviations are much like mappings, but they're used primarily to insert plain strings of text. They're only triggered when you enter a character like a space, Escape, or Enter. If I set a mapping for F10, it takes effect as soon as I type F10. If I set an abbreviation for insert mode to replace "i" with "I," it won't take effect if I type "imagine" or "Delphi," but it will take effect if I type just "i" followed by a space.

Another difference between mappings and abbreviations is that you can't use special keys, such as F10 or Shift-F10, to trigger an abbreviation. That's OK, because abbreviations tend to accumulate, and there are only so many ways you can combine the function, Control, Alt, and Shift keys anyway. (Especially since desktop environments like KDE also claim a number of them.)

Abbreviations are useful for a number of situations. For example, if you are prone to certain typos -- like typing "helllo" instead of "hello" -- just set an abbreviation in your .vimrc like this:

ab helllo hello

If you'd like the abbreviation to work in insert mode only, use iab instead.

Like mappings, abbreviations can be unset during your session. To remove a single abbreviation, use :una abbrv . To clear all abbreviations, use :abc.

If you go at it a little at a time, eventually you'll have a set of mappings and abbreviations tuned for your work that help make Vim even more efficient than it is to begin with.

Share    Print    Comments   

Comments

on Vim tips: Using Vim mappings and abbreviations

Note: Comments are owned by the poster. We are not responsible for their content.

Toggling highlight

Posted by: Anonymous Coward on June 15, 2006 10:47 AM
Here is a simpler way to toggle search highlight (using your keybindin; i have h myself): nmap<nobr> <wbr></nobr>:set hls! hls?.

Similar thing i have to toggle expansion of tabs (expandtab).

#

Re:Toggling highlight

Posted by: Anonymous Coward on June 15, 2006 10:50 AM
WTF? My post does not show less-than & greater-than signs while i selected "Plain Old Text". So much for being plain text. Oh well.

#

Re:Toggling highlight

Posted by: Administrator on June 15, 2006 10:49 PM
Can you post your mapping again using the -
<tt>&lt;</tt>
and -
<tt>&gt;</tt>
codes to show the less-than and greater-than symbols. You can use HTML Formatted with this.


#

Re:Toggling highlight

Posted by: Anonymous Coward on June 16, 2006 02:23 PM
If you want to temporarily disable the highlighting, then use ":noh". It will disable the highlighting till the next search. This way you don't have to disable and enable it all the time.

#

Re:One use for mappings

Posted by: Anonymous Coward on June 15, 2006 03:21 PM
A much better way to do pasting, is to use ":se paste", it disables a lot more than than just indenting. See ":help paste"

#

Re:One use for mappings

Posted by: Administrator on June 15, 2006 08:14 PM

A much better way to do pasting, is to use ":se paste", it disables a lot more than than just indenting. See ":help paste"

Rock! Thanks so much, didn't know about that.

Today seems to be the day of learning new things for old problems. I just learned about the -r option to sed today too, which makes expressions not require so many damn backslashes.

#

Fun articles.

Posted by: Anonymous Coward on August 24, 2006 06:52 PM
I just recently came across these articles and have rather enjoyed them. There have been more than a few things I've picked up that I'm trying to integrate into my usage habits.

I think we all know the help files/documentation exists, but it's rather dry reading and sometimes its so terse you really have no idea *why* you'd want to do something. Further, the comments from other readers have been equally interesting.

Anyway, keep up the good work.

#

emacs keystrokes in vim, yum yum

Posted by: Anonymous Coward on September 22, 2006 05:37 PM
<tt>I don't know why I suffered so long without this - now you can have ctrl-a/ctrl-e in vim, just like emacs!

imap <C-a> <Esc>0i
imap <C-e> <Esc>$a
map <C-a> <Esc>0i
map <C-e> <Esc>$a
</tt>

#

One use for mappings

Posted by: Administrator on June 15, 2006 12:00 AM

Mappings are great. To give you another idea for their use, here is one thing that I use vim mappings for, changing the email signature I use:




map ns<nobr> <wbr></nobr>/^-- ^Md}:read ~/.signature^M

map suso<nobr> <wbr></nobr>/^-- ^Md}:read ~/.signature^M

map blug<nobr> <wbr></nobr>/^-- ^Md}:read ~/.signature-blug^M

map bloomingpedia<nobr> <wbr></nobr>/^-- ^Md}:read<nobr> <wbr></nobr>/.signature-bloomingpedia^M

map personal<nobr> <wbr></nobr>/^-- ^Md}:read ~/.signature-personal^M




Those ^M are actually the newline control character so you'll need to type Ctrl-V + Ctrl-M to get them. I have to use them in place of <CR> for it to actually work on older versions of vim like 6.3. So all you have to do to switch signatures is just type in the mapped word. Makes it handy to change your identity for the email that you are writing.



The first one, 'ns' can be useful if you're using a random signature generating program and you want to cycle through the signatures (like my <a href="http://suso.suso.org/programs/randomsig/" title="suso.org">randomsig </a suso.org> program)



Another useful thing is to map noi to turn off all the indenting options when you need to paste something into a file.


map noi<nobr> <wbr></nobr>:set noautoindent<CR>:set nosmartindent<CR>

#

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya