INTRODUCTION
Vi (Visual editor) is a powerful, mode-oriented full-screen
editor, closely associated with the line editor, ex.
Available on almost all UNIX systems, it is a common
denominator whose availability generally can be relied upon
from system to system.
VI COMMAND SYNTAX
% vi [+n|+/pattern/] [file]
where
n = open the files at line number n
/pattern/ = open the file at the first line matching
the pattern
Notes on the format of commands in the summary:
^X denotes <ctrl>x
[x] denotes an optional item
default argument values are mostly 1
<x> denotes an argument, which can be numerical or
items such as:
<sp> = space
<cr> = carriage return
<lf> = linefeed
<a-z> = any element of the range
CURSOR MOVEMENT
h, ^H : to the left
j, ^J, <lf>, ^N : down
l, <sp> : to the right
k, ^P : up
[nr]$ : to the end of the <nr>th line
after the cursor
^ : to the first real character
(no tab/space) on the line
[nr]- : to the first real character <nr> lines
higher
[nr]+, [nr]<cr>, [nr]^M : to the first real character
<nr> lines below
0 : to the first position on the line
[nr]| : to column <nr> (default column 0)
(tabs: only to the endpoint!)
[nr]w : <nr> words to the right
[nr]W : <nr> real words (followed by a
tab/space) to the right
[nr]b : <nr> words back
[nr]B : <nr> real words back
[nr]e : to the end of the <nr>th word
[nr]E : to the end of the <nr>th real word
[nr]G : goto line <nr> (default EOF)
[nr]H : to the <nr>th line from top of
the screen (home)
[nr]L : to the <nr>th line from bottom of the
screen (last)
M : to the middle line of the screen
[nr]) : <nr> sentences forward
[nr]( : <nr> sentences backward
[nr]} : <nr> paragraphs forward
[nr]{ : <nr> paragraphs backward
]] : to the next section (default EOF)
[[ : to the previous section
(default begin of file)
m<a-z> : put a mark at the cursor position
`<a-z> : back to the mark
'<a-z> : to the begin of the labeled line
`` : back to the cursor position before the
latest absolute jump (of which are
examples "/{string}" and "[nr]G")
'' : to the begin of the line on which the
cursor was placed before the latest
absolute jump
SEARCHING
f{chr} : find the next {chr} on the line
t{chr} : to just before the next {chr} on
the line (till)
F{chr} : to the previous {chr} on the line
T{chr} : to just after the previous {chr}
on the line
(Note: f, F, t, and T can be given a repeat
count, in all contexts (e.g., d3fX
and is the same as 3dfX).)
; : repeat previous "f", "t", "F" or "T"
, : idem into reverse direction
/{string} : to the next {string}
?{string} : to the previous {string}
n : repeat previous "/{string}" or
"?{string}" (next)
N : idem into reverse direction
:g/{string}/[command] : search globally after {string}
[on each occurrence executing the
"ex" command]
^] : search in the tags file after the
function under the cursor and go
to it
% : find the first parenthesis after
the cursor, and go to its match
(also for { } and [ ])
UNDOING CHANGES
u : undo the latest change
U : undo all changes to current line.
If you edit a line heavily, then
move off it, U doesn't work.
:q! : quit vi without writing
APPENDING TEXT (END WITH <ESCAPE>)
a : after the cursor
A : at the end of the line
i : before the cursor (insert)
I : before the begin of the line
o : on a new line after the current (open)
O : on a new line before the current
[nr]>{move} : shift the current line and the lines
described by [nr]{move} one shiftwidth
to the right (layout)
[nr]>> : shift <nr> lines one shiftwidth to the
right
. : repeat the latest command
DELETING TEXT
Everything to be deleted can be saved into a buffer <a-z>:
type a double quote " and a letter <a-z> in front of the
delete command. Otherwise the deleted will go into the
undo buffer only.
"<a-z>p : put the buffer to the right of the
cursor
"<a-z>P : put the buffer to the left of the
cursor
(Note : when dealing with complete lines:
"p" like "o", "P" like "O")
[nr]x : delete <nr> characters under and
after the cursor
[nr]X : <nr> characters before the cursor
[nr]dw : <nr> words after the cursor
[nr]dW : <nr> real words after the cursor
[nr]db : <nr> words before the cursor
[nr]dB : <nr> real words before the cursor
[nr]dd : <nr> lines downward
[nr]dk : <nr> lines upward
D : the rest of the line
[nr]d$ : idem plus <nr> - 1 next lines
d^ : the line upto the cursor
d{move} : from start to endpoint (e.g. "dG")
"<1-9> : these buffers contain the latest 9
deletions ("1 is the most recent)
[nr]<{move} : shift the current line and the lines
described by [nr]{move} one
shiftwidth to the left
[nr]<< : shift <nr> lines one shiftwidth to
the left
. : repeat the previous command
CHANGING TEXT (END WITH <ESCAPE>)
r{chr} : replace the character under the
cursor by {chr} - no <esc>
R : overwrite the rest of the line
[nr]s : substitute <nr> characters
[nr]S : <nr> lines
[nr]cw : change <nr> words
[nr]cW : <nr> real words
[nr]cb : <nr> words before the cursor
[nr]cB : <nr> real words before the cursor
[nr]c$ : the rest of the line plus <nr> - 1
next lines
[nr]C : idem
c^ : the line upto the cursor
[nr]cc : <nr> lines
cf{chr} : upto the next {chr}
cF{chr} : from the previous {chr} upto the
cursor
ct{chr} : till the next {chr}
cT{chr} : from after the previous {chr} upto the
cursor
c{move} : from start to endpoint (e.g. "cG")
~ : switch lower and upper cases
[nr]J : join <nr> lines
. : repeat the previous command
COPYING TEXT (YANKING)
In all these commands the "<a-z> can be left out, causing a
copy to be made only into the undo buffer.
"<a-z>p : put the buffer to the right of the
cursor
"<a-z>P : put the buffer to the left of the
cursor
(Note: when dealing with complete lines :
"p" like "o", "P" like "O")
"<a-z>[nr]yl : copy <nr> characters under and
after the cursor
"<a-z>[nr]yh : <nr> characters before the cursor
"<a-z>[nr]yw : <nr> words after the cursor
"<a-z>[nr]yW : <nr> real words after the cursor
"<a-z>[nr]yb : <nr> words before the cursor
"<a-z>[nr]yB : <nr> real words before the cursor
"<a-z>[nr]yy : <nr> lines
"<a-z>[nr]Y : idem (should be equivalent to "y$"
though)
"<a-z>y{move} : from start to endpoint (e.g. "yG")
"<a-z>[nr]y$ : the rest of the line plus <nr> - 1
next lines
"<a-z>y^ : the line upto the cursor
"<a-z>y'm : the region from the line marked "m" to
the current line
"Xy3j : yank 3 lines and append them to
buffer x (upper case in the command)
COMMANDS WHILE IN APPEND/CHANGE MODE
^V : deprive the next character of its
special meaning (e.g. <esc>) (lnext)
^D : one shiftwidth to the left
^^D : removes all indentation for one line,
then restores current indent. Useful
when entering code and you want to
put in an #ifdef or such.
^T : one shiftwidth to the right
^W : one word back (werase)
^H : one character back (erase)
^X : back to the begin of the change on
the current line (usually the kill
character)
<del> : same as <escape>
WRITING AND QUITTING VI
:q : quit vi after writing
:q! : quit vi without writing
ZZ : write the file and quit vi
:wq : idem
:x : idem
:w : write the file
:w name : write to the file "name"
:w >> name : append the buffer to the file "name"
:w! name : overwrite the file "name"
:12,35 w name : write lines 12 to 35 to the file
"name"
:e file : edit another file without quitting vi
(Note: the buffers <a-z> are not changed
(with the exception of the undo buffer)
text can be copied from one file to
another this way)
:n [file] : edit next file ("vi file1 file2 ...")
:n! [file] : idem, without writing the current
buffer
:rew : edit previous file
("vi file1 file2 ...")
:e# : idem
:rew! : idem, without writing the current
buffer
^^ : edit previous file (always)
DISPLAY COMMANDS
^L : refresh the screen
(sometimes ^P or ^R)
^R : sometimes vi replaces a deleted
line by a '@', to be deleted by
"^R" (also with option noredraw)
[nr]^E : scroll <nr> lines downward
[nr]^Y : scroll <nr> lines upward
[nr]^D : scroll <nr> lines downward
(Note: default the number of the previous
scroll; initialization: half a page)
[nr]^U : scroll <nr> lines upward
(Note: default the number of the previous
scroll; initialization: half a page)
[nr]^F : <nr> pages forward
^B : 1 page backward
(Note: [nr]^B does not do what you expect)
(Note: If in the next commands the field
<wi> is present, the windowsize will
change to <wi>. The window will
always be displayed at the bottom of
the screen.)
[nr]z[wi]<cr> : put line <nr> at the top of the window
(default the current line)
[nr]z[wi]+ : put line <nr> at the top of the window
(default the first line of the
next page)
[nr]z[wi]- : put line <nr> at the bottom of the
window (default the current line)
[nr]z[wi]. : put line <nr> in the centre of the
window (default the current line)
MAPPING AND ABBREVIATION
:map <chr> <command> : whenever <chr> is typed, <command>
is executed, e.g.
":map ^C :!cc %^M"
to compile from within vi
(vi replaces % by the current
file name)
:map : show all mappings
:ab <string1> <string2> : whenever <string1> is
followed by a breakpoint
(e.g. a space or a comma) while
in append mode, it will be
replaced by <string2>,
e.g. ":ab p procedure". a
character preceded by a ^V is
not considered a breakpoint
:ab : show all abbreviations
SWITCH AND SHELL COMMANDS
Q, <del><del> : switch from vi to "ex"
: : an "ex" command can be given
:vi : switch from "ex" to vi
:sh : execute a subshell, back to vi by ^D
:!<command> : let the shell execute <command>
without quitting the editor
:!! : repeat the last shell command
[nr]!{move}<command> : the shell executes <command>, with
standard input formed by the text
lines described by [nr]{move}.
Next, the standard output
replaces those lines
(think of cb, sort, nroff, etc.)
[nr]!!<command> : the shell executes <command>, with
standard input formed by the
current line and <nr> - 1 next
lines. Next, the standard output
replaces those lines
:r!<command> : put the output of <command> onto a new
line
:r name : read the file "name" into the buffer,
after the cursor
VI STARTUP
vi [file] : edit the file and display the
first page (the shell variable
PATH must contain the path of vi)
The editor can be initialized by the shell variable EXINIT,
which looks like:
EXINIT='ex command | ex command | ...'
ex commands : set options
map ...
ab ...
export EXINIT (in the Bourne shell)
Sometimes it is possible (e.g. if the system crashed while
you were editing) to recover lost files by "vi -r file".
The most important options are:
ai : autoindent - while in append mode
after a <lf> the cursor will move
directly below the first real
character of the previous line.
with "^D" one shiftwidth back, with
"^T" one forward
aw : autowrite - write at every shell
escape (useful when compiling from
within vi)
dir : directory - ":set dir=..."
the directory for vi to make
temporary files (default /tmp)
eb : errorbells - beeps when you goof
(not on every terminal)
ic : ignorecase - no distinction between
upper and lower cases when searching
list : <lf> is shown as '$', tab as '^I'
magic : some metachars can be used in searches
^{string} - {string} must be at the
beginning of the line
{string}$ - {string} must be at the
end of the line
. - matches any character
[a-z] - matches any character in
the range
nu : number - numbers before the lines
para : paragraphs - ":set para={strbbing}"
every pair of characters in {string}
is considered a paragraph delimiter
nroff macro. a space preceded by
a \ indicates that the previous
character is a single letter macro.
":set para=P\ bp" introduces '.P'
and '.bp' as paragraph delimiters
(for the "{" and "}" commands)
redraw : the screen remains up to date
report : ":set report=..." - vi reports
whenever e.g. a delete or yank
command affects <report> or more lines
sect : sections - ":set sect={string}"
gives the section delimiters
(for "[[" and "]]") (see option para)
sh : shell - ":set sh=..." tells which
program is to be used for shell
escapes
sw : shiftwidth - ":set sw=..."
gives the swiftwidth (default sw=8)
sm : showmatch - whenever you append
a ')', vi tries to show its match
by putting for a moment the cursor
onto it (also with { })
terse : short error messages
ts : tabstop - ":set ts=..."
gives the length of a tab jump ;
warning : this is only IN the editor,
outside of it tabs have their normal
length (default ts=8)
wa : writeany - no checks when writing
(dangerous)
warn : warn you when you try to quit without
writing
wi : window - ":set wi=..."
gives the number of lines vi is to
show default
wm : wrapmargin - ":set wm=..."
(when in append mode vi automatically
puts a <lf> whenever there is a
breakpoint (e.g. a space or comma)
within <wm> columns from the right
margin
ws : wrapscan - when searching, the end is
considered "stuck" to the begin of the
file
:set option : turn some option on
:set no option : turn some option off; no space
between "no" and the option
(e.g. ":set nonu")
:set option=value : give some option a value
:set : show all non-default options and their
values
:set option? : show an option's value
:set all : show all options and their values
REFERENCES:
Books on UNIX utilities invariably provide some
documentation of vi. Also, see the online manual (man)
pages.