Next Previous Contents

5. TIPS AND TECHNIQUES

Note: This section contains various macros written in Vim's macro language, called ``

notation'' (you can find the description by doing ``:h key_notation''). All macros should be entered as is in your .vimrc file or on Vim's command line. You should even be able to cut and paste the information. This is a short description of the language:

* Any printable characters are typed directly, except backslash and '<'. * A backslash is represented with ``\\'', double backslash. * A real '<' is represented with ``\<''. * ``key '' means the special key typed. A few examples:

Esc Escape key C-G CTRL-G Up cursor up key C-LeftMouse Control- left mouse click Shifted function key 11 M-a Meta- a ('a' with bit 8 set) M-A Meta- A ('A' with bit 8 set) kd> "kd" termcap entry (cursor down key)

If you want to use this notation in Vim, you have to remove the 'B' flag from 'cpoptions' and make sure the '<' flag is excluded. The default values for cpoptions should work fine.

:set cpo=ceFs

For mapping, abbreviation and menu commands you can then copy-paste the examples and use them directly. Or type them literally, including the '<' and '>' characters. This does NOT work for other commands, like ``:set'' and ``:autocmd''!

Other tips, not appearing in this FAQ, can be found by doing ``:h tips''.

5.1 How do I use the help files?

Help can be found for all functions of Vim. In order to use it, use ``:h''. This will bring you to the main help page. On that first page, you will find explanations on how to move around. Basically, you move around in the help pages the same way you would in a read-only document. You can jump to specific subjects by using tags. This can be done in two ways:

* Use the ``>'' command while standing on the name of a command or option. This only works when the tag is a keyword. ``Ctrl-LeftMouse '' and ``gLeftMouse '' work just like ``>''. * use the ``:ta subject'' command. This works with all characters.

Use ``Ctrl-T '' to jump back to previous positions in the help files. Use ``:q'' to close the help window.

If you want to jump to a specific subject on the help pages, use ``:h {subject}''. If you don't know what to look for, try ``:h index'' to get a list of all available subjects. Use the standard search keys to locate the information you want. By version 6 or 7, we should have a search engine available. ;-)

5.2 Why is a backup file written even if I set nobackup?

In order to keep Vim from writing a backup, you must also do ``:set nowritebackup''.

5.3 How can I keep Vim from beeping all the time?

Well, you can use ``set noerrorbells" but it does not turn off the bell for all cases. It only makes a difference for error messages; the bell will be always be used for a lot of errors without a message (e.g., hitting Esc in Normal mode).

If you want Vim to stop beeping then all you need is ``:set vb'' which tries to do a screen flash rather than an audible beep. Some terminals can't do screen flashes, but if yours does and you don't want it to flash or beep then use ``:set vb t_vb=''.

5.4 How do I map the Tab key?

:map Tab right-hand-side

5.5 How do I map the Esc key?

On some keyboards the escape key is not placed very well. It's either part of the numeric block or it can be a small button (as with some Macintosh keyboards). But do not despair - make your own escape key! You can map one of the commands keys you do not need to Esc. Example: map CTRL-O to ESC:

:map C-O Esc

5.6 How do I tell Vim where the helpfile is?

To tell Vim where to find the help file, ``:set helpfile'' to the correct value, i.e., including the full path. As with most options you can abbreviate ``helpfile'' to ``hf''. On the other hand, if your VIM environment variable points to the directory containing the help file, vim will find the help file with no need to ``:set hf=''.

'a'?

5.7 How do I get back to the exact position within a line I have marked with

Use ```a'' (that's a backtick!). If the backtick is awkwardly placed on your keyboard, the following maping may be useful to you:

map ' `

5.8 How do I read in the output of a command?

Use ``:r!command''.

5.9 Why can't I abbreviate ``'xy''?

The abbreviation consists of a non-id character followed by two id characters, which does not satisfy either category of a ``full-id''. However, ``_ps'' and ``'p'' will work.

5.10 How do I jump to the beginning/end of the highlighted text?

The command 'o' will jump to the beginning/end of the highlighted text.

``noautoindent''? Completion of ``:set no'' seems to work.

5.11 Why does completion of ``:set n'' not show negated settings, e.g.,

The thing is that the ``no'' is not actually part of the option's name; the name comes after that. So after ``no'', Vim knows to complete any boolean setting name (starts the completion just after the ``no'', which is not part of the name). After ``n'', Vim will complete all setting names starting with ``n''. It would be a bummer if you wanted to complete ``number'', but had to wade through all the boolean option names with ``no'' prepended too.

5.12 Is there a command to remove any or all digraphs?

No. The digraphs table is defined at compile time. You can only add new ones. Adding a command to remove digraphs is on the todo list.

5.13 How do I use a spell checker with Vim?

You can call a non-interactive spell checker from Vim without a problem. A function to look up a word is included with the command ``K''. So what you do is get such a spell checker, then you issue the command ``:set keywordprg=ispell'', and then hit ``K'' on the word you want to look up, i.e., check. If you need to give options to your spell checker command, escape all spaces with a backslash.

If you need to use an interactive spell checker and are working with Unix, you can try this approach proposed by Ives Aerts ives@sonycom.com:

noremap ;ispell :%! ispell-filterCR C-L

where ispell-filter is the following script:

#!/bin/sh # # This little script can be used to run ispell on stdin, returning the result # through stdout. # It can be used from VI like this (or map it to a key sequence): # :%!  /bin/ispell-filter # cat > /tmp/tmp.$$ ispell $* /tmp/tmp.$$ < /dev/tty > /dev/tty cat /tmp/tmp.$$ rm -f /tmp/tmp.$$

or this macro proposed by Dr. Charles E. Campbell Jr. cec@gryphon.gsfc.nasa.gov:

map #fi :wCR :!ispell %CR :e %CR

position?

5.14 Can I copy the character above the cursor to the current cursor

In Insert mode, you can copy the character above the cursor to the current cursor position by typing Ctrl-Y . The same can be done with the characters below the cursor by using Ctrl-E . This is neat when you need to duplicate partial lines without going through the process of yanking a line and deleting the unwanted part.

5.15 How do I remove empty lines?

To remove all empty lines do ``:g/^$/d''.

``:g/[ Tab ]*$/d'' deletes lines that aren't blank but look it, too.

5.16 How do I reduce a range of empty lines into one line only?

You can try ``:v/./.,/./-1join''. Note that this will give an error message if the empty lines are at the end of the file. To correct this, use the following mapping instead:

map _b GoZEsc :g/^[ Tab ]*$/,/[^ Tab ]/-jCR Gdd

Vim?

5.17 How can I paste large amounts of text between two running sessions of

If you are using the GUI version of Vim, with the Motif or Athena interface, you can actually cut and paste between the two, and text will be copied exactly; that is, tabs will not change into spaces, and if you copy a rectangular block, then that is what you will paste too!

Otherwise, in a terminal Vim, use these mappings:

" _Y: Yank the highlighted block of text (or a single line) to a tmp file. " _P: Put the text yanked with \_Y (possibly in another invocation of Vim). " nmap _Y :.w!  /.vi_tmpCR

vmap _Y :w!  /.vi_tmpCR

nmap _P :r  /.vi_tmpCR

Now you just highlight the area you want to copy with ``V'' etc, and yank it with ``_Y''. Then you can paste it in another Vim with ``_P''.

5.18 Can I use compressed versions of the help files?

For those that are really short on disk space, you can compress the help files and still be able to view them with Vim. This example assumes you have gzip on your system. You do have it, don't you? :-) If not, you will need to adapt it to work with a different compression utility.

1. Compress all the help files: ``gzip doc/*.txt''. 2. Edit doc/vim_tags (doc/tags in 5.0) and do :%s=\.txtTab /=.txt.gzTab /= 3. Add these lines to your .vimrc:

set helpfile=dirname /vim_help.txt.gz autocmd BufReadPost *.txt.gz set bin | '[,']!gunzip autocmd BufReadPost *.txt.gz set nobin set cmdheight=2

Where ``dirname'' is the directory where the help files are. If you already have included autocommands to edit ``.gz'' files you should omit the two ``autocmd'' lines. Note that you must ``set nocompatible'' for this to work in Vim 5.0.

5.19 How come I can't set option ``xxxx''?

Some options are compiled into Vim. If you want to enable these options, then you must modify the feature.h file. You can see what compile-time options are available by looking at the version number (:ver). It will give you something like this:

Compiled with (+) or without (-): +autocmd +builtin_terms +cindent -compatible +digraphs -emacs_tags +fork() - -GUI +insert_expand -langmap +lispindent -rightleft +smartindent -terminfo +viminfo +writebackup +X11

As the example shows, all options compiled into the Vim binary are preceded by a '+'. All options that are not compiled in are preceded by a '-'. All options that do not appear in this list do not need to be compiled in.

5.20 How do I format a block of C code?

To format C code, use = instead of Q. Try ``:h C_indenting'' to get more information on controlling the way your code is formatted.

5.21 How do I put a command onto the command history without executing it?

You need only end the input with ESC (not Ctrl-V Esc ).

hit the Escape key?

5.22 Why do I hear a beep (why does my window flash) about 1 second after I

This is normal behavior. If your window flashes, then you've got the visual bell on. Otherwise, you should hear a beep.

Vim (and most, if not all, other implementations of Vi) needs a timeout to tell the difference between a simple escape and, say, a cursor key sequence. When you press a key in normal mode (and even in insert mode) and that key is the beginning of a mapping, Vim waits a certain amount of time to see if the rest of the mapping sequence follows. If the mapping sequence is completed before a given timeout period, the mapping for that sequence of keys is applied. If you interrupt the mapping, the normal actions associated with the keys are executed.

For example, if you have a mapping defined as ``:imap vvv Vim is great!!'' and you type ``vvv'' quickly, the ``Vim is great!!'' will be inserted into your text. But if you type ``vv v'' then that is what will put into your text. This is also true if you type ``vvv'' too slowly where ``too slowly'' is longer than the value for the timeout option. Setting the timeout option to a larger value can help alleviate problems that appear when using function keys over a slow line. Do ``:h timeout'' for more information on using this option and its cohorts.

deleting the characters I'm changing?

5.23 How do I make the 'c' and 's' commands display a '$' instead of

Add ``:set cpoptions=ces$'' to your .vimrc. Vi-compatible behavior can be controlled like this. Do ``:help cpoptions'' for more information.

5.24 How do I add a line before each line with ``pattern'' in it?

1. Yank the line using Y 2. Insert the line with ``:g/pattern/put!''

such as ``|''?

5.25 How can I delete the newline which is followed by a given character,

Look at this problem this way: If there is a newline before the character then the character is the first character of the next line, i.e., it follows the start-of-line meta character (^). So the command to use is to look globally for all lines starting with the given character and the command to use on these lines is ``go back one line'' and ``join'' which will remove the next newline. The resulting command is:

:g/^|/-1join

``*'' and begins with the previous ``|''?

5.26 How do I use the join command within a range of lines that ends with

:?^|?,/*$/join

5.27 How do I map/unmap an abbreviation or a map!ed key sequence?

In either case, ``:set paste'' will do the trick. Use ``:set nopaste'' to return to normal.

For map!ed key sequences, you have a these tricks also;

* After typing the first key of the key sequence, pause about 1 second before typing the rest of the sequence. * Type Ctrl-V before typing the first key in the key sequence.

Normally, you shouldn't need these tricks. When ``:unmap'' finds an argument that is not a ``from'' part, it looks for a matching ``to'' part and unmaps that one.

in my document but doesn't move the cursor properly. What's going on?

5.28 When I use my arrow keys, Vim changes modes, inserts weird characters

There are a couple of things that could be going on: either you are using Vim over a slow connection or Vim doesn't understand the key sequence that your keyboard is generating.

If you are working over a slow connection (such as a 2400 bps modem), you can try to set timeout or ttimeout. These options, combined with timeoutlen and ttimeoutlen, may fix the problem. Do ``:h timeout'' and ``:h timeoutlen'' for a better description on how to use them.

The preceding procedure will not work correctly if your terminal sends key codes that Vim does not understand. In this situation, your best option is to map your key sequence to a matching cursor movement command and save these mappings in a file. You can then ``:source'' the file whenever you work from that terminal.

(i.e.have auto-indenting but towards the left margin instead of the right margin)?

5.29 How do I ``auto-outdent'' some lines containing certain keywords

For example (make sure you adapt the example to your personal needs):

for k=1:10, stuff .. end; ^^^ This word marks the end of a loop and I'd like it to be automatically outdented to the same column as the word for.

The following macro will do this (from Raul Segura Acevedo raul@turing.iquimica.unam.mx):

:iab end; C-D end;

This abbreviation takes effect when you type a non-keyword character after it (``;'', ``!'', space, tab, Esc , CR , etc). You can load this macro automatically using the following autocommands:

au! BufEnter *.f,*.ff iab end; C-D end; au! BufLeave *.f,*.ff iunab end;

5.30 Is there a repository for Vim macros?

As a matter of fact, there is. You can find the latest versions of contributed macros at http://www.grafnetix.com/~laurent/vim/macros.html. At the time this version of the FAQ was updated, the following macros were available:

* A file browser * Some macros to edit HTML code * Macros to deal with numbered lists * A Tic Tac Toe game

another mapping/abbreviation, how do I keep the first from expanding into the second one?

5.31 If I have a mapping/abbreviation whose ending is the beginning of

Instead of using :map lhs rhs, use :noremap lhs rhs. For abbreviations, use noreabbrev lhs rhs. The ``nore'' prefix prevents the mapping or abbreviation from being expanded again. You must be using version 4.5 or greater.

can I improve it?

5.32 Modelines are cool but Vim's modeline support is too restrictive. How

From Benjamin Elijah Griffin eli@NetUSA.Net:

Vim modelines are crippled to reduce the security hazards of modelines. For much closer to vi modeline behavior (with the major risks involved) you can use Benjamin Elijah Griffin's modeline autocmd system. You can find it at http://www.netusa.net/~eli/src/modeline.html.

5.33 How can I use different .vimrc settings for different types of files?

There are a few ways to do this. All of them involve the use of autocommands. Try ``:h autocommand'' for more information.

* You can define autocommands which do everything for you in your .vimrc file:

au!BufRead *.c,*.cc,*.h set fo=croq cin noic au!BufEnter *.c,*.cc,*.h ab #i #include au BufEnter *.c,*.cc,*.h ab #d #define au BufEnter *.c,*.cc,*.h map _hello_world :"Hello World"CR

au BufEnter *.c,*.cc,*.h normal _hello_world au!BufLeave *.c,*.cc,*.h unab #i | unab #d au BufLeave *.c,*.cc,*.h unmap _hello_world

The ``!'' is used just in the first autocommand for each event (BufEnter, BufLeave, etc.). * Or you can define one autocommand for each file type which loads a specific .vimrc file containing the settings you require.

autocmd BufNewFile *.tex read  /.vim/texmodel autocmd BufEnter *.tex source  /.vim/texrc autocmd BufLeave *.tex source  /.vim/notexrc

Remember that all settings that you modify in a BufEnter or BufNewFile event may need to be unset with a corresponding BufLeave event. By using a first file pattern with a value of ``*'', you can define default settings for all your files. The ``mapclear'' and ``abclear'' commands can clear all your mappings or abbreviations if needed.

5.34 How can I search for tags when running Vim over a telnet session?

Darren Hiebert darren@sirsi.com says:

Ctrl-] is the the default telnet escape key. Most version of telnet allow changing or disabling the default escape key. See the man page. If possible, try to use ``rsh'' instead of ``telnet''. It will avoid this problem.

5.35 NEW] I get errors when trying to put scripts in my mappings. Why?

This is a tricky one which deals with the way bars are treated in mappings.For example, if you have something like:

nmap :if has("syntax_items") | syntax off | else | syntax on | endif

Vim treats the line as:

nmap :if has("syntax_items")

and then tries syntax off (which is ok), then tries else (which now has nomatching if). This parsing occurs because |'s are used as command separatorsin Vim. Since those |'s are really part of the command, they should bereplaced by Barin your mapping, to yied something like (on one lineonly):

nmap :if has("syntax_items") Barsyntax off Bar

else Barsyntax on BarendifCR

Thank you to cec@gryphon.gsfc.nasa.gov far theexplanation.

mappings don't exists. What's going on?

5.36 NEW] When I try to remove mappings in my autocommands, Vim says my

The explanation for this phenomenon is similar to that of the previousquestion. Basically, when unmapping your commands, you must not leave anyspaces after the |'s separating the unmap keyword. For example, using thefollowing autocommand:

au BufRead *.c map C-N:cnCR| map C-P:cpCR

This will fail to unmap C-P:

au BufLeave *.c unmap C-N| unmap C-P

But this will succeed:

au BufLeave *.c unmap C-N|unmap C-P


Next Previous Contents