VIM REFERENCE MANUAL - Part 7

By Bram Moolenaar

CONTENTS

[Note: The commands for multiple windows and buffers are explained in a different file, see vim_win.html]

  1. Introduction
  2. Notation
  3. Starting Vim
    1. Command line
    2. Workbench (Amiga only)
    3. Vim window (Amiga only)
    4. Initialization
    5. Suspending
    6. The viminfo file
  4. Modes
    1. Introduction
    2. Switching from mode to mode
    3. Insert and Replace mode
      1. special keys
      2. special special keys
      3. 'textwidth' option
      4. 'expandtab' option
      5. Replace mode
      6. Insert mode completion
    4. Command_line mode
      1. Command line editing
      2. Command line completion
      3. Ex command lines
      4. Ex command line ranges
      5. Ex special characters
    5. The window contents
    6. Abbreviations
    7. Digraphs
    8. Using the mouse
    9. On-line help
  5. Editing files
    1. Introduction
    2. Editing a file
    3. The argument list
    4. Writing and quitting
    5. Using the QuickFix mode
    6. Editing binary files
    7. Automatic commands
  6. Cursor motions
    1. Left-right motions
    2. Up-down motions
    3. Word motions
    4. Text object motions
    5. Text object selection
    6. Pattern searches
    7. Various motions
  7. Scrolling
  8. Tags and special searches
    1. Tags
    2. Identifier searches
  9. Inserting text
  10. Deleting text
  11. Changing text
    1. Delete and insert
    2. Simple changes
    3. Complex changes
    4. Formatting text
    5. Formatting C programs
  12. Copying and moving text
  13. Visual mode
  14. Various commands
  15. Repeating commands
    1. Single repeats
    2. Multiple repeats
    3. Complex repeats
  16. Undo and redo
  17. Key mapping
  18. Recovery after a crash
    1. The swap file
    2. Recovery
  19. Options
    1. Setting options
    2. Automatically setting options
    3. Saving settings
    4. Options summary
  20. Terminal information
    1. Startup
    2. Terminal options
    3. Window size
    4. Slow and fast terminals
  21. Differences from Vi and Ex
    1. Missing commands
    2. Missing options
    3. Limits

13. Visual mode

Visual mode is a flexible and easy way to select a piece of text for an operator. It is the only way to select a block of text. {Vi has no Visual mode, the name "visual" is used for Normal mode, to distinguish it from Ex mode}
v
start Visual mode per character. {not in Vi}

V
start Visual mode linewise. {not in Vi}

CTRL-V
start Visual mode blockwise. {not in Vi}

o
go to Other end of highlighted text: The current cursor position becomes the start of the highlighted text and the cursor is moved to the Other end of the highlighted text. {not in Vi}

gv
Start Visual mode with the same area as the previous area and the same mode. In Visual mode the current and the previous Visual area are exchanged. {not in Vi}

<LeftMouse>
Set the current cursor position. If Visual mode is active it is stopped. Only when 'mouse' option is contains 'n' or 'a'. If the position is within 'so' lines from the last line on the screen the text is scrolled up. If the position is within 'so' lines from the first line on the screen the text is scrolled down. {not in Vi}

<RightMouse>
Start Visual mode if it is not active. The text from the cursor position to the position of the click is highlighted. If Visual mode was already active move the start or end of the highlighted text, which ever is closest, to the position of the click. Only when 'mouse' option contains 'n' or 'a'. {not in Vi}

<LeftRelease>
This works like a <LeftMouse>, if it is not a the same position as <LeftMouse>. In an xterm you won't see the selected area until the button is released. Only when 'mouse' option contains 'n' or 'a'. {not in Vi}
To apply an operator on a piece of text:
  1. mark the start of the text with "v", "V" or CTRL-V The character under the cursor will be used as the start.
  2. move to the end of the text The text from the start of the Visual mode up to and including the character under the cursor is highlighted.
  3. hit an operator The highlighted characters will be operated upon.
The 'highlight' option can be used to set the display mode to use for highlighting in Visual mode.

The highlighted text includes the character under the cursor. On terminals where it is possible to make the cursor invisible the cursor position is also highlighted. On terminals where this is not possible the cursor is displayed normally. If your cursor cannot be made invisible and you want Vim to highlight the character under the cursor anyway, you could set the 't_cv' and 't_ci' options to something harmless, for example:

:set t_cv=^[^[ t_ci=^[^[

With "v" the text before the start position and after the end position will not be highlighted. However, All uppercase and non-alpha operators, except "~", will work on whole lines anyway. See the list of operators below.

With CTRL-V (blockwise Visual mode) the highlighted text will be a rectangle between start position and the cursor. However, some operators work on whole lines anyway (see the list below). The change and substitute operators will delete the highlighted text and then start insertion at the top left position.

When the "$" command is used with blockwise Visual mode, the right end of the highlighted text will be determined by the longest highlighted line. This stops when a motion command is used that does not move straight up or down.

If you use <Esc>, click the left mouse button or use any command that does a jump to another buffer while in Visual mode, the highlighting stops and no text is affected. Also when you hit "v" in characterwise Visual mode, "CTRL-V" in blockwise Visual mode or "V" in linewise Visual mode. If you hit CTRL-Z the highlighting stops and the editor is suspended or a new shell is started.

old mode new mode after typing:
"v" "CTRL-V" "V"
Normal Visual blockwise Visual linewise Visual
Visual Normal blockwise Visual linewise Visual
blockwise Visual Visual Normal linewise Visual
linewise Visual Visual blockwise Visual Normal

For moving the end of the block many commands can be used, but you cannot use Ex commands, commands that make changes or abandon the file. Commands (starting with) ".pPiIaAO&", CTRL-^, "ZZ", CTRL-], CTRL-T, CTRL-R, CTRL-I and CTRL-O cause a beep and Visual mode continues.

If Visual mode is not active and the "v", "V" or CTRL-V is preceded with a count, the size of the previously highlighted area is used for a start. You can then move the end of the highlighted area and give an operator. The type of the old area is used (character, line or blockwise).

  • Linewise Visual mode: The number of lines is multiplied with the count.
  • Blockwise Visual mode: The number of lines and columns is multiplied with the count.
  • Normal Visual mode within one line: The number of characters is multiplied with the count.
  • Normal Visual mode with several lines: The number of lines is multiplied with the count, in the last line the same number of characters is used as in the last line in the previously highlighted area.
The start of the text is the Cursor position. If the "$" command was used as one of the last commands to extend the highlighted text, the area will be extended to the rightmost column of the longest line.

If you want to highlight exactly the same area as the last time, you can use "gv" gv v_gv.

The operators that can be used are:
~ switch case
d delete
c change
y yank
> shift right (1)(*)
< shift left (1)(*)
! filter through external command (1)
= filter through 'equalprg' option command (1)
Q format lines to 'textwidth' length (1)
The objects that can be used are:
a word
A WORD
s sentence
p paragraph
P block
Additionally the following commands can be used:
: start ex command for highlighted lines (1)
r change
C change (2)
R change (2)
x delete
D delete (2)
X delete (2)
Y yank (2)
J join (1)
U make uppercase
u make lowercase
^] find tag
(1): always whole lines, see :visual_example
(2): whole lines when not using CTRL-V
(*): in a future a blockwise shift will move the block only, not whole lines.

Note that the ":vmap" command can be used to specifically map keys in Visual mode.

If you want to give a register name using the """ command, do this just before typing the operator character: "v{move around}"xd".

If you want to give a count to the command, do this just before typing the operator character: "v{move around}3>" (move lines 3 indents to the right).

When repeating a Visual mode operator, the operator will be applied to the same amount of text as the last time:

  • Linewise Visual mode: The same number of lines.
  • Blockwise Visual mode: The same number of lines and columns.
  • Normal Visual mode within one line: The same number of characters.
  • Normal Visual mode with several lines: The same number of lines, in the last line the same number of characters as in the last line the last time.
The start of the text is the Cursor position. If the "$" command was used as one of the last commands to extend the highlighted text, the repeating will be applied up to the rightmost column of the longest line.

Currently the ":" command works on whole lines only. When you select part of a line, doing something like ":!date" will replace the whole line. If you want only part of the line to be replaced you will have to make a mapping for it. In a future release ":" may work on partial lines.

:vmap _a a`\!!datekJJ

(In the <> notation, is CTRL-V, "`\<" is typed as "`<")

What this does is:
stop Visual mode
a break the line after the Visual area
`\< jump to the start of the Visual area
i break the line before the Visual area
!!date filter the Visual text through date
kJJ Join the lines again

14. Various commands

CTRL-L
Clear and redraw the screen.

<Del>
When entering a number: Remove the last digit. Note: if you like to use <BS> for this, add this mapping to your .vimrc:
:map CTRL-V <BS> CTRL-V <Del>
See :fixdel if your <Del> key does not do what you want.

:as[cii] or
ga
Print the ascii value of the character under the cursor in decimal, hexadecimal and octal. For example, when the cursor is on a 'R':
<R> 82, Hex 52, Octal 122
When the character is a non-standard ASCII character, but printable according to the 'isprint' option, the non-printable version is also given. When the character is larger than 127, the <M-x> form is also printed. For example:
<~A> <M-^A> 129, Hex 81, Octal 201
<p> <|~> <M-~> 254, Hex fe, Octal 376
(where <p> is a special character) The character in a file is stored internally as , but it will be shown as: <^@> 0, Hex 00, Octal 000 Mnemonic: Get Ascii value. {not in Vi}

:[range]p[rint]
Print [range] lines (default current line).

:[range]p[rint] {count}
Print {count} lines, starting with [range] (default current line, See Command line ranges).

:[range]l[ist] [count]
Same as :print, but display unprintable characters with '^'.

:[range]nu[mber] [count]
Same as :print, but precede each line with its line number. (See also 'highlight' option).

:[range]# [count]
synonym for :number.

:=
Print the cursor line number.

:norm[al][!] {commands}
Execute Normal mode commands {commands}. This makes it possible to execute normal mode commands typed on the command line. {commands} is executed like it is typed. For undo all commands are undone together. If the [!] is given, mappings will not be used. If {commands} does not finish a command, more characters need to be typed. Mostly useful for autocommands. This command cannot be followed by another command, since any '|' is considered part of the command. {not in vi}

:sh[ell]
Escape to a shell (name from 'shell' option).

:!{cmd}
Execute {cmd} with the shell. See also the 'shell' and 'shelltype' option.

:!!
Repeat last ":!{cmd}".

:![!]{cmd} [!][arg]
Execute a command with the shell. The optional bangs are replaced with the previously given command. The optional [arg] is appended. See also the 'shell' and 'shelltype' option.

:ve[rsion]
Print the version number of the editor. If the compiler used understands "__DATE__" the compilation date is mentioned. Otherwise a fixed release-date is shown. The following lines contain information about which options were defined when Vim was compiled.

:ve[rsion] {nr}
Set the version number to {nr}. Used in .vimrc files. When omitted Vim will give a warning message. If {nr} is higher than the current Vim version this will result in an error message. {not in Vi}

K
Run a program to lookup the keyword under the cursor. The name of the program is given with the 'keywordprg' (kp) option (default is "man"). The keyword is formed of letters, numbers and the characters in 'iskeyword'. The keyword under or right of the cursor is used. The same can be done with the command
":!{program} {keyword}".
There is an example of a program to use in the tools directory of Vim. It is called 'ref' and does a simple spelling check. If 'keywordprg' is empty, the ":help" command is used. {not in Vi}

{Visual}K
Like "K", but use the visually highlighted text for the keyword. Only works when the highlighted text is not more than one line. {not in Vi}

[N]gs
:[N]sleep [N]
Do nothing for [N] seconds. Can be interrupted with CTRL-C (CTRL-break on MS-DOS). "gs" stands for "goto sleep". While sleeping the cursor is positioned in the text (if visible). {not in Vi}

15. Repeating commands

15.1 Single repeats
.
Repeat last change with count replaced with [count].

Simple changes can be repeated with the "." command. Without a count, the count of the last change is used. If you enter a count, it will replace the last one. If the last change included a specification of a numbered register, the register number will be incremented. See the section on undo and redo for an example how to use this. Note that when repeating a command that used a Visual selection, the same SIZE of area is used, see repeat_Visual.

@:
Repeat last command line [count] times.
15.2 Multiple repeats
:[range]g[lobal]/{pattern}/[cmd]
Execute the Ex command [cmd] (default ":p") on the lines within [range] where {pattern} matches.

:[range]g[lobal]!/{pattern}/[cmd]
Execute the Ex command [cmd] (default ":p") on the lines within [range] where {pattern} does NOT match.

:[range]v[global]/{pattern}/[cmd]
Same as :g!.
The global commands work by first scanning through the [range] lines and marking each line where a match occurs. In a second scan the [cmd] is executed for each marked line with its line number prepended. If a line is changed or deleted its mark disappears. The default for [range] is the whole buffer (1,$). Use "CTRL-C" to interrupt the command. If an error message is given for a line the global command aborts.

To repeat a non-Ex command, you will have to put the command in a file and use "source!". For example:

:g/pat/so! scriptfile
Make sure that the scriptfile ends with a whole command, otherwise Vim will wait for you to type the rest of the command for each match. The screen will not have been updated, so you don't know what you are doing.

The undo/redo command will undo/redo the whole global command at once. The previous context mark will only be set once (with "''" you go back to where the cursor was before the global command).

The global command sets both the last used search pattern and the last used substitute pattern (this is vi compatible). This makes it easy to globally replace a string:

:g/pat/s//PAT/g
This replaces all occurences of "pat" with "PAT". The same can be done with:
:%s/pat/PAT/g
Which is two characters shorter!
15.3 Complex repeats
q<0-9a-zA-Z">
Record typed characters into register <0-9a-zA-Z"> (uppercase to append). The 'q' command is disabled while executing a register. {Vi: no recording}

q
Stops recording. (Implementation note: The 'q' that stops recording is not stored in the register, unless it was the result of a mapping) {Vi: no recording}

@<0-9a-z".>
Execute the contents of register <0-9a-z".> [count] times. Note that register '%' (name of the current file) cannot be used. See also @:. {Vi: only named registers}

@@
Repeat the previous @<0-9a-z":> [count] times.

:[addr]@<0-9a-z">
Execute the contents of register <0-9a-z"> as an Ex command. First set cursor at line [addr] (default is current line). When the last line in the register does not have a <CR> it will be added automatically when the 'e' flag is present in 'cpoptions'. {Vi: only in some versions} Future: Will execute the register for each line in the address range.

:[addr]@:
Repeat last command line [count] times. First set cursor at line [addr] (default is current line). {Vi: only in some versions}

:[addr]@@
Repeat the previous :@<0-9a-z">. First set cursor at line [addr] (default is current line). {Vi: only in some versions}

:so[urce] {file}
Read Ex commands from {file}.

:so[urce]! {file}
Read Vim commands from {file}. {not in Vi}
All commands and command sequences can be repeated by putting them in a named register and then executing it. There are two ways to get the commands in the register:
  • Use the record command "q". You type the commands once, and while they are being executed they are stored in a register. Easy, because you can see what you are doing. If you make a mistake, 'put' the register into the file, edit the command sequence, and then delete it into the register again. You can continue recording by appending to the register (use an uppercase letter).
  • Delete or yank the command sequence into the register.
Often used command sequences can be put under a function key with the ':map' command.

An alternative is to put the commands in a file, and execute them with the ':source!' command. Useful for long command sequences. Can be combined with the ':map' command to put complicated commands under a function key.

The ':source' command reads Ex commands from a file line by line. You will have to type any needed keyboard input. The ':source!' command reads from a script file character by character, interpreting each character as if you typed it.

Example: When you give the ":!ls" command you are asked to "hit return to continue". If you ':source' a file with the line "!ls" in it, you will have to type the return yourself. But if you ':source!' a file with the line ":!ls" in it, the next characters from that file are read until a <CR> is found. You will not have to type <CR> yourself, unless ":!ls" was the last line in the file.

It is possible to put ':source[!]' commands in the script file, so you can make a top-down hierarchy of script files. The ':source' command can be nested as deep as the number of files that can be opened at one time (about 15). The ':source!' command can be nested up to 15 levels deep.

In script files terminal-dependent key codes are represented by terminal-independent two character codes. This means that they can be used in the same way on different kinds of terminals. The first character of a key code is 0x80 or 128, shown on the screen as "~@". The second one can be found in the list key_notation. Any of these codes can also be entered with CTRL-V followed by the three digit decimal code. This does NOT work for the <t-xx> termcap codes, these can only be used in mappings.

MS-DOS: Files that are read with ":source" normally have <CR>-<NL> line separators. These always work. If you are using a file with <NL> line separators (for example, a file made on Unix), this will be recognized if you have 'textauto' on and the first line does not end in a <CR>. This fails if the first line has something like ":map <F1> :help^M", where "^M" is a <CR>. If the first line ends in a <CR>, but following ones don't, you will get an error message, because the <CR> from the first lines will be lost.

16. Undo and redo

<Undo> or
u
Undo [count] changes. {Vi: only one level}

:u[ndo]
Undo one change. {Vi: only one level}

CTRL-R
Redo [count] changes which were undone. {Vi: redraw screen}

:red[o]
Redo one change which was undone. {Vi: no redo}

U
Undo all latest changes on one line. {Vi: while not moved off of it}
The last changes are remembered. You can go back in time with the "u" command. You can then go forward again with the 'CTRL-R' command. If you make a new change after the "u" command, the 'CTRL-R' will not be possible anymore. The number of changes that are remembered is set with the 'undolevels' option. If it is zero, the old fashioned Vi undo is present: one level of undo and undo undoes itself. If it is negative no undo is possible. Use this if you are running out of memory.

The "U" command is treated by undo/redo just like any other command. Thus a "u" command undos a "U" command and a 'CTRL-R' command redoes it again. When mixing "U", "u" and 'CTRL-R' you will notice that the "U" command will restore the situation of a line to before the previous "U" command. This may be confusing. Try it out to get used to it.

When all changes have been undone the buffer is not considered to be changed. Vim can then be exit with ":q" instead of ":q!". {this is not in Vi}

The numbered registers can also be used for undoing deletes. Each time you delete text, it is put into register "1. The contents of register "1 are shifted to "2, etc. The contents of register "9 are lost. You can now get back the most recent deleted text with the put command: '"1P'. (also, if the deleted text was the result of the last delete or copy operation, 'P' or 'p' also works as this puts the contents of the unnamed register). You can get back the text of three deletes ago with '"3P'.

If you want to get back more than one part of deleted text, you can use a special feature of the repeat command ".". It will increase the number of the register used. So if you first do ""1P", the following "." will result in a '"2P'. Repeating this will result in all numbered registers being inserted.

Example: If you deleted text with 'dd....' it can be restored with '"1P....'.

If you don't know in which register the deleted text is, you can use the :display command. An alternative is to try the first register with '"1P', and if it is not what you want do 'u.'. This will remove the contents of the first put, and repeat the put command for the second register. Repeat the 'u.' until you got what you want.

17. Key mapping

:map {lhs} {rhs}
Map the key sequence {lhs} to {rhs} in Normal and Visual mode.

:map! {lhs} {rhs}
Map the key sequence {lhs} to {rhs} in Insert and Command_line mode.

:no[remap] {lhs} {rhs}
Map the key sequence {lhs} to {rhs} in Normal and Visual mode. Disallow remapping of {rhs}. {not in Vi}

:no[remap]! {lhs} {rhs}
Map the key sequence {lhs} to {rhs} in insert and Command_line mode. Disallow remapping of {rhs}. {not in Vi}

:unm[ap] {lhs}
Remove the mapping of {lhs} for Normal and Visual mode.

:unm[ap]! {lhs}
Remove the mapping of {lhs} for Insert and Command_line mode.

:map
List all key mappings for Normal and Visual mode.

:map!
List all key mappings for Insert and Command_line mode.

:map {lhs}
List the key mappings for the key sequences starting with {lhs} in Normal and Visual mode. {not in Vi}

:map! {lhs}
List the key mappings for the key sequences starting with {lhs} in insert and Command_line mode. {not in Vi}

:nm[ap]
Same as :map, but for Normal mode only. {not in Vi}

:nun[map]
Same as :unmap, but for Normal mode only. {not in Vi}

:nn[oremap]
Same as :noremap, but for Normal mode only. {not in Vi}

:vm[ap]
Same as :map, but for Visual mode only. {not in Vi}

:vu[nmap]
Same as :unmap, but for Visual mode only. {not in Vi}

:vn[oremap]
Same as :noremap, but for Visual mode only. {not in Vi}

:cm[ap]
Same as :map!, but for Command_line mode only. {not in Vi}

:cu[nmap]
Same as :unmap!, but for Command_line mode only. {not in Vi}

:cno[remap]
Same as :noremap!, but for Command_line mode only. {not in Vi}

:im[ap]
Same as :map!, but for Insert mode only. {not in Vi}

:iu[nmap]
Same as :unmap!, but for Insert mode only. {not in Vi}

:ino[remap]
Same as :noremap!, but for Insert mode only. {not in Vi}

:mapc[lear]
Remove all mappings for Normal and Visual mode. {not in Vi}

:mapc[lear]!
Remove all mappings for Insert and Command_line mode. {not in Vi}

:nmapc[lear
] Remove all mappings for Normal mode. {not in Vi}

:vmapc[lear]
Remove all mappings for Visual mode. {not in Vi}

:imapc[lear]
Remove all mappings for Insert mode. {not in Vi}

:cmapc[lear]
Remove all mappings for Command_line mode. {not in Vi}

These commands are used to map a key or key sequence to a string of characters. You can use this to put command sequences under function keys, translate one key into another, etc. See the "Options" chapter below for how to save and restore the current mapping.

There are four sets of mappings

  • For Insert mode. These are also used in Replace mode.
  • For Command_line mode: When entering a ":" or "/" command.
  • For Normal mode: When typing commands.
  • For Visual mode: When typing commands while the Visual area is highlighted.
The original Vi did not have separate mappings for Normal/Visual mode and Insert/Command_line mode. Therefore the ":map" and ":map!" commands enter and display mappings for both. In Vim you can use the ":nmap", "vmap", ":cmap" and ":imap" commands to enter mappings for each mode separately. When listing mappings the character in column 1 is

char mode
<Space> Normal and Visual
n Normal
v Visual
! Insert and Command_line
i Insert
c Command_line

Note: When using mappings for Visual mode, you can use the '< mark, which is the start of the last selected Visual area.

Everything from the first non-blank after {lhs} up to the end of the line (or '|') is considered to be part of {rhs}. This allows the {rhs} to end with a space.

To include a space in {lhs} precede it with a CTRL-V (type two CTRL-Vs for each space). If you want a {rhs} that starts with a space, precede {rhs} with a single CTRL-V (You have to type CTRL-V two times). You can create an empty {rhs} by typing nothing after the two CTRL-Vs.

It is not possible to put a comment after this command, because the '"' character is considered to be part of the {rhs}. To put a '|' in {rhs} escape it with a backslash or a CTRL-V (to get one CTRL-V you have to type it twice). When 'b' is present in 'cpoptions', only CTRL-V can be used, "\|" will be recognized as a mapping ending in a '\' and then another command. This is vi compatible, but unlogical. Summary:
:map _l :!ls \| more^M works in Vim when 'b' is not in 'cpo'
:map _l :!ls ^V| more^M works always, in Vim and vi

To avoid mapping of the characters you type in insert or Command_line mode, type a CTRL-V first. The mapping in Insert mode is disabled if the 'paste' option is on.

Note that when an error is enountered (that causes an error message) the rest of the mapping is not executed. This is vi-compatible.

Note that the second character (argument) of the commands @zZtTfF[]rm'`"v and CTRL-X is not mapped. This was done to be able to use all the named registers and marks, even when the command with the same name has been mapped.

Some examples (given as you type them; e.g. the "^V" is CTRL-V which you type, but will not show up on the screen):

:map g /foo^V^Mcwbar^V^[ (replace next "foo" with "bar")
:map! qq quadrillion questions

Vim will compare what you type with the start of a mapped sequence. If there is an incomplete match, it will get more characters until there either is a complete match or until there is no match at all. Example: If you map! "qq", the first 'q' will not appear on the screen until you type another character. This is because Vim cannot know if the next character will be a 'q' or not. If the 'timeout' option is on (which is the default) Vim will only wait for one second (or as long as specified with the 'timeoutlen' option). After that it assumes that the 'q' is to be interpreted as such. If type slowly, or your system is slow, reset the 'timeout' option. Then you might want to set the 'ttimeout' option. See the "Options" chapter.

If you include the {lhs} in the {rhs} you have a recursive mapping. When {lhs} is typed, it will be replaced with {rhs}. When the {lhs} which is included in {rhs} is encountered it will be replaced with {rhs}, and so on. This makes it possible to repeat a command an infinite number of times. The only problem is that the only way to stop this is by causing an error. The macros to solve a maze uses this, look there for an example. There is one exception: If the {rhs} starts with {lhs}, that part is not mapped again. For example:

:map a ab
will execute the "a" command and insert a 'b' in the text. The 'a' in the {rhs} will not be mapped again.

If you want to exchange the meaning of two keys you should use the :noremap command. For example:

:noremap k j
:noremap j k
This will exchange the cursor up and down commands.

With the normal :map command, when the 'remap' option is on, mapping takes place until the text is found not to be a part of a {lhs}. For example, if you use:

:map x y
:map y x
Vim will replace x with y, and then y with x, etc. When this has happened 'maxmapdepth' times (default 1000), Vim will give the error message "recursive mapping".

See the file "index" for keys that are not used and thus can be mapped without losing any builtin function. I suggest you use function keys, and meta-keys. If you are prepared to lose a command that you hardly ever use you can make mappings that start with '_' or '-'. You can also use ":help <key>^D" to find out if a key is used for some command. (<key> is the specific key you want to find out about, ^D is CTRL-D).

If you include an undo command inside a mapped sequence, this will bring the text back in the state before executing the macro. This is compatible with the original Vi, as long as there is only one undo command in the mapped sequence (having two undo commands in a mapped sequence did not make sense in the original Vi, you would get back the text before the first undo).

There are three ways to map a special key:

  1. The Vi-compatible method: Map the key code. Often this is a sequence that starts with <Esc>. To enter a mapping like this you type ":map " and then you have to type CTRL-V before hitting the function key. Note that when the key code for the key is in the termcap (the t_ options), it will automatically be translated into the internal code and become the second way of mapping.
  2. The second method is to use the internal code for the function key. To enter such a mapping type CTRL-K and then hit the function key, or use the form "#1", "#2", .. "#9", "#0", "<Up>", "<S-Down>", "<S-F7>", etc. (see table of keys, all keys from <Up> can be used). The first ten function keys can be defined in two ways: Just the number, like "#2", and with "<F>", like "<F2>". Both stand for function key 2. "#0" refers to function key 10, defined with option 't_f10', which may be function key zero on some keyboards.
  3. Use the termcap entry, with the form <t-xx>, where "xx" is the name of the termcap entry. Any string entry can be used. For example:
    :map <t-F3> G
    Maps function key 13 to "G".
The advantage of the second and third method is that the mapping will work on different terminals without modification (the function key will be translated into the same internal code or the actual key code, no matter what terminal you are using. The termcap must be correct for this to work, and you must use the same mappings).

DETAIL: Vim first checks if a sequence from the keyboard is mapped. If it isn't the terminal key codes are tried (see section 20.2 terminal_options). If a terminal code is found it is replaced with the internal code. Then the check for a mapping is done again (so you can map an internal code to something else). What is written into the script file depends on what is recognized. If the terminal key code was recognized as a mapping the key code itself is written to the script file. If it was recognized as a terminal code the internal code is written to the script file.

18. Recovery after a crash

You have spent several hours typing in that text that has to be finished next morning, and then disaster strikes: Your computer crashes.

DON'T PANIC!

You can recover most of your changes from the files that Vim uses to store the contents of the file. Mostly you can recover your work with one command:

vim -r filename
18.1 The swap file
Vim stores the things you changed in a swap file. Using the original file you started from plus the swap file you can mostly recover your work.

You can see the name of the current swap file being used with the command:

:sw[apname]

The name of the swap file is normally the same as the file you are editing, with the extension ".swp". On MS-DOS machines and when the 'shortname' option is on, any '.' in the original file name is replaced with '_'. If this file already exists (e.g. when you are recovering from a crash) a warning is given and another extension is used, ".swo", ".swn", etc. An existing file will never be overwritten. The swap file is deleted as soon as Vim stops editing the file.

Technical:
The replacement of '.' with '_' is done to avoid problems with MS-DOS compatible filesystems (e.g. crossdos, multidos). If Vim is able to detect that the file is on an MS-DOS-like filesystem, a flag is set that has the same effect as the 'shortname' option. This flag is reset when you start editing another file.

If the ".swp" filename already exists, the last character is decremented until there is no file with that name or ".swa" is reached. In the last case, no swap file is created.

By setting the 'directory' option you can place the swap file in another place than where the edited file is.
Advantages:
  • You will not pollute the directories with ".swp" files.
  • When the 'directory' is on another partition, reduce the risk of damaging the file system where the file is (in a crash).
Disadvantages:
  • You can get name collisions from files with the same name but in different directories (although Vim tries to avoid that by comparing the path name). This will result in bogus ATTENTION warning messages.
  • When you use your home directory, and somebody else tries to edit the same file, he will not see your swap file and will not get the ATTENTION waring message.
On the Amiga you can also use a recoverable ram disk, but there is no 100% guarantee that this works. Putting swap files in a normal ram disk (like RAM: on the Amiga) or in a place that is cleared when rebooting (like /tmp on Unix) makes no sense, you will lose the swap file in a crash. If you want to put swap files in a fixed place, put a command resembling the following ones in your .vimrc:
:set dir=dh2:tmp (for Amiga)
:set dir=~/tmp (for Unix)
:set dir=c:\\tmp (for MS-DOS and Win 32)
This is also very handy when editing files on floppy. Of course you will have to create that "tmp" directory for this to work!

When starting to edit a file, Vim checks if a swap file already exists for that file. If there is one, you will get a message indicating that something is wrong and you are to take one of two actions:

  1. Quit editing this file, because another edit session is active on this file. Continuing to edit will result in two versions of the same file. The one that is written last will overwrite the other one, resulting in loss of changes.
  2. Recover a previously crashed edit session. See below recovery.
Vim cannot always detect that a swap file already exists for a file. This is the case when the other edit session puts the swap files in another directory or when the path name for the file is different when editing it on different machines.

The swap file is updated after typing 200 characters or when you have not typed anything for four seconds. This only happens if the buffer was changed, not when you only moved around. The reason why it is not kept up to date all the time is that this would slow down normal work too much. You can change the 200 character count with the 'updatecount' option. You can set the time with the 'updatetime' option. The time is given in milliseconds. After writing to the swap file Vim syncs the file to disk. This takes some time, especially on busy Unix systems. If you don't want this you can set the 'swapsync' option to an empty string. The risk of loosing work becomes bigger though. On some non-Unix systems (MS-DOS, Amiga) the swap file won't be written at all.

If the writing to the swap file is not wanted, it can be switched off by setting the 'updatecount' option to 0. The same is done when starting Vim with the "-n" option. Writing can be switched back on by setting the 'updatecount' option to non-zero. Swap files will be created for all buffers when doing this. But when setting 'updatecount' to zero, the existing swap files will not be removed, it will only affect files that will be opened after this.

If you want to make sure that your changes are in the swap file use this command:

:pres[erve]
Write all text for all buffers into swap file. The original file is no longer needed for recovery. {Vi: emergency exit}
A Vim swap file can be recognized by the first six characters: "b0VIM ". After that comes the version number, e.g. "3.0".
18.2 Recovery
In most cases recovery is quite easy: Start Vim on the same file you were editing when the crash happened, with the "-r" option added. Vim will read the ".swp" file and may read bits and pieces of the original file.

Example: vim -r vim_ref.html

If you were editing without a file name, give an empty string as argument:

vim -r ""

If there are several swap files that look they may be the one you want to use, a list is given of these swap files and you are requested to enter the number of the one you want to use. In case you don't know which one to use, just try them one by one and check the resulting files if they are what you expected.

If you know which swap file needs to be used, you can recover by giving the swap file name. Vim will then find out the name of the original file from the swap file.

Example: Vim -r vim_ref.html.swo

This is also handy when the swap file is in another directory than expected. If this still does not work, see what file names Vim reports and rename the files accordingly. Check the 'directory' option to see where Vim may have put the swap file.

Another way to do recovery is to start Vim and use the ":recover" command. This is easy when you start Vim to edit a file and you get the "ATTENTION: Found a swap file ..." message. In this case the single command ":recover" will do the work. You can also give the name of the file or the swap file to the recover command:

:rec[over] [file]
Try to recover [file] from the swap file. If [file] is not given use the file name for the current buffer. The current contents of the buffer are lost. This command fails if the buffer was modified.

:rec[over]! [file]
Like ":recover", but any changes in the current buffer are lost.
Vim has some intelligence about what to do if the swap file is corrupt in some way. If Vim has doubt about what it found, it will give an error message and insert lines with "???" in the text. If you see an error message while recovering, search in the file for "???" to see what is wrong. You may want to cut and paste to get the text you need.

Be sure that the recovery was successful before overwriting the original file or deleting the swap file. It is good practice to write the recovered file elsewhere and run 'diff' to find out if the changes you want are in the recovered file.

Once you are sure the recovery is ok delete the swap file. Otherwise, you will continue to get warning messages that the ".swp" file already exists.

{Vi: recovers in another way and sends mail if there is something to recover}


Part 1 Part 2 Part 3 Part 4 Part 5 Part 6 Part 7 Part 8 Part 9
Send feedback on this page to Rajesh Kallingal
For Vim version 3.24. Last modification: 1996 Apr 25