[Note: The commands for multiple windows and buffers are explained in
a different file, see vim_win.html]
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:
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:
- 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.
- 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.
- 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:
- 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.
- 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