Please note that in order to view this page properly, you must use a Web browser which supports tables. For instance, Netscape V1.1 (or better) or Mosaic V2.6 for UNIX (or better).
This page provides an overview of the vi editor. Users learning vi should consider getting a textbook on vi, or a Unix textbook that describes vi. A list of Unix and Unix related texts is available.
The following symbols are used to represent special keys:
vi is a standard Unix full-screen editor. vi stands for "visual editor" and is pronounced "vee eye". It is based on an underlying line mode editor called ex.
The vi editor has three modes: command, insert, and last line modes. When you first bring up vi, you are in command mode, where you can move the cursor around, delete or append text, type last line mode commands, or enter insert mode. When you are in insert mode, all you can do is insert text. You cannot move your cursor around while you are in insert mode (except that the cursor moves as you insert text, of course, and you can use your Delete key to delete characters you mistype). To return to command mode from insert mode, press the <Esc> key.
Last line mode is for commands beginning with: (the ex commands), as well as commands starting with /, ?, or !. Whenever you type a last line command, your cursor moves to the last line of your screen (which is why these commands are called last line commands).
vi commands are case sensitive; the a command, for example, is different from the A command. Sometimes, when vi seems to be behaving strangely, it is because your Caps lock (or Shift lock) key is turned on, and you are actually typing uppercase commands when you think you are typing lower case ones!
Before using vi you need to tell the system what kind of terminal you are using. This is done by setting the environment variable TERM to your terminal type. If you are using the X Window system, your terminal type is usually either "xterm" or "xterms" (the latter is for Sun workstations with the Sun-enhanced version of X Windows). If you are using VT100 style terminal emulation, your terminal type is "vt100". If you can't get vi to work properly (for example, the lines at the top of the file you are editing scroll by really fast), try using vt100 as your terminal type.
You set environment variables for the Bourne, Korn, and POSIX shells in the .profile file. In addition to setting your TERM environment variable, you should also set the EDITOR environment variable to vi so that various system utilities know that your preferred editor is vi.
To set your default editor to vi, enter the following in your .profile:
EDITOR=vi; export EDITOR
If you are using X Windows, enter:
TERM=xterm; export TERM
For Sun workstations with the Sun-enhanced version of X Windows enter:
TERM=xterms; export TERM
For VT100 emulation, enter:
TERM=vt100; export TERM
You set environment variables for the C and Tenex C shells in the .login or .cshrc file. Traditionally, environment variables are set in the .login, but sometimes when you login to a computer using X Windows the .login is not executed. Therefore, it is safest to place the following commands in your .cshrc.
In the C shell, it is also necessary to let the system know your window size, if you are using X Windows. This is done by using the:
eval `resize`
command. Note that the `s in `resize` are back quotes.
The C shell equivalents for the above Bourne shell commands are:
setenv EDITOR vi
setenv TERM xterm; eval `resize`
setenv TERM xterms; eval `resize -s`
setenv TERM vt100
To create a new file and start inserting text into it, type:
vi filename<Ret> i
After typing the i, start typing the text you want to insert. Do not press the Return key after typing the i; just start typing your input text.
Return to command mode by typing <Esc>.
To save your file and exit from vi, type the following (from command mode):
ZZ
Alternatively, type:
:wq<Ret>
As soon as you type the :, your cursor will move to the bottom of the screen. Continue typing wq<Ret>.
Some people say that using :wq<Ret> is safer than ZZ, but ZZ is easier! Normally, you shouldn't have problems using ZZ.
If you want to exit from vi without saving the changes you have made, type:
:q!<Ret>
Many vi mode commands may be prefixed by a command repeat factor. This means that most character, change, delete, word, movement, and positioning commands may be preceded by a number which refers to the number of times the command should be repeated. For example, j moves the cursor 1 character down, and 4j moves the cursor 4 characters down. In the commands listed below, examples of using the repeat factor are shown by placing the character n in front of a vi mode command. Not all vi mode commands are shown with a repeat factor; just a few, to remind you that it exists!
Note that the repeat factor only works with vi mode commands; it does not work with ex commands (which are described later).
You will be able to do much of your editing using the following commands. Once you are familiar with the list below, read through the rest of the article to pick up additional useful commands.
<Esc> | Return to command mode. |
<Ret> or + | Go to the first non-blank character of the next line. |
- | Go to the first non-blank character of the previous line (- is the minus sign). |
a | Append text after the cursor. |
A | Append text at the end of the current line. |
dd | Delete the current line. |
D or d$ | Delete from the cursor to the end of the line. |
u | Undo the last change. |
U | Undo all changes to the current line. |
x | Delete the current character (the one at the cursor). |
nx | Delete n characters to the right, starting with the current character. |
ZZ | Save changes and exit. |
:wq<Ret> | Save changes and exit. |
:w<Ret> | Save changes without exiting. |
:q!<Ret> | Quit without saving changes. |
The following commands enter insert mode. To return to command mode, press the <Esc> key.
a | Append text after the cursor. |
na | Append after the cursor. Whatever you type until you press <Esc>gets replicated n times. For example: if you type 3a, then 12<Esc>, the string 121212 is inserted. |
A | Append text at the end of the current line. |
i | Insert text before the cursor. |
I | Insert text at the beginning of the current line. |
o | Open a new line below the current line. |
O | Open a new line above the current line. |
Note: <Ctrl> represents the Control key. <Ctrl>f means hold the Control key, then press the f key.
<Ctrl>&f | Move forward (downward) by 1 screen. |
n<Ctrl>f | Move forward by n screens. |
<Ctrl>b | Move backward (upward) by 1 screen. |
<Ctrl>d | Move downward by 1/2 screen. |
<Ctrl>u | Move upward by 1/2 screen. |
<Ctrl>e | Scroll downward one line. |
<Ctrl>y | Scroll upward one line. |
H | Go to the first line on the screen. |
M | Go to the middle line on the screen. |
L | Go to the last line on the screen. |
z<Ret> | Shifts the current line to the top of the screen. |
z- | Shifts the current line to the bottom of the screen. |
z. | Shifts the current line to the center of the screen. |
h or left arrow | Move left one character. |
nh | Move left n characters. |
j or down arrow | Move down one line. |
k or up arrow | Move up one line. |
l or right arrow | Move right one character. |
G | Go to end of the file. |
1G | Go to the top of the file. |
nG | Go to line n. |
0 | Go to the beginning of the current line (0 is the digit zero). |
^ | Go to the first non-blank character in the current line. |
$ | Go to the end of the current line. |
<Ret> or + | Go to the first non-blank character of the next line. |
- | Go to the first non-blank character of the previous line (- is the minus sign). |
n| | Go to column n (| is the vertical bar). |
Note: If you moved away from a spot by using a search or G command, you can return to your previous location by typing two single quotes:
''
In vi, a "word" is either a group of letters, digits and _; or a group of punctuation marks (including special characters other than _). For example:
one 1 word: one one! 2 words: one and ! one!). Next 3 words: one and !). and Next one!). "Next 4 words: one and !). and " and Next
A "blank delimited word" (called WORD in the explanations below of commands that use it) includes adjacent punctuation. WORDs are separated by spaces, tabs or newlines (what you get when you type <Ret>). For example:
one 1 WORD: one one! 1 WORD: one! one!). Next 2 WORDs: one!). and Next one!). "Next 2 WORDs: one!). and "Next
w | Move right one word or group of punctuation marks. |
b | Move left one word or group of punctuation marks. |
e | Move right to the end of the next word or group of punctuation marks. |
W | Move right one WORD (see above for the definition of WORD). |
B | Move left to the beginning of the next WORD. |
E | Move left to the end of the next WORD. |
In vi, a sentence ends with a ., !, or ?, followed by TWO BLANK SPACES (one blank space doesn't cut it!) or a newline (what you get when you type <Ret>). Paragraphs are separated by one or more blank lines.
) | Move to the next sentence. |
( | Move to the beginning of the current sentence, (or to the beginning of the previous sentence if you are already at the beginning of a sentence). |
} | Move to next paragraph. |
{ | Move to the end of the previous paragraph. |
>> | Shift right one tab stop. |
n>> | Shift n lines right one tab stop. |
<< | Shift left one tab stop. |
n<< | Shift n lines left one tab stop. |
Note: The default tabstop is 8 characters. To change your tabstop, use the :set tabstop command, as explained below in the section called "The .exrc vi Startup File and Setting vi Parameters".
x | Delete the current character (the one at the cursor). |
nx | Delete n characters to the right, starting with the current character. |
X | Delete the character to the left of the cursor. |
nX | Delete n characters to the left of the cursor (starting with the character to the left of the cursor). |
dd | Delete the current line. |
ndd | Delete n lines (from the current line through n lines below the current line. |
d<Ret> | Beware: this deletes 2 lines!! |
D or d$ | Delete from the cursor to the end of the line. |
dw | Delete from the cursor to end of the current word. |
ndw | Delete n words starting at the cursor and deleting rightward. |
db | Delete from the character to the left of the cursor leftward to the start of the current word. |
d/string | Deletes from (and including) the cursor position until, but not including, string |
dL | Delete all lines from the current line downward till the bottom of the screen. |
dH | Delete all lines from the current line upward till the top of the screen. |
dM | Delete lines from the current line to the middle of the screen (either direction depending on current location). |
dG | Delete from the current line through the end of the file. |
Change commands effectively insert data. With the exception of r, all the change commands listed below will put you in insert mode. To return to command mode use the <Esc> key.
rx | Replace the current character (where the cursor is positioned) with the character x. |
R | Replace all the characters starting with the current character until you press the <Esc> key. Characters after the character at which you press <Esc> are unchanged. |
C | Replace all the characters from the cursor to end of line. A $ will appear as the last character of the line (to show you what you are replacing). |
cw | Change to end of word. A $ will appear at the end of the word. |
ncw | Change to end of n'th word. A $ will appear at the end of the n'th word. |
cW | Change to end of WORD (including punctuation). A $ will appear at the end of the WORD. |
cc | Change (replace) the current line. The line disappears and the cursor is positioned at the beginning of the line. |
ncc | Change n lines. |
s | Substitute character. A $ will appear at the cursor location. You replace the current character and append additional text until you press <Esc>. |
ns | Substitute n characters. A $ will replace the nth character. |
u | Undo the last change. |
U | Undo all changes to the current line. |
ZZ | Save changes and exit. |
:wq<Ret> | Save changes and exit. |
:w<Ret> | Save changes without exiting. |
:q!<Ret> | Quit without saving changes. |
:q<Ret> | Try to quit. Invokes a warning message if there are any changes in the edit buffer and does not quit. |
:w newfile<Ret> | Save changes to the file newfile without exiting. |
:w! filename<Ret> | Overwrite the existing file filename. |
We now introduce the following more advanced vi topics:
ex commands, those that begin with a : and are used in vi's "last line mode", are often used with an ex command address range to indicate which lines the ex command should be applied to. : commands are executed only after you press <Ret>. If you want to exit last line mode without executing a command, type <Ctrl>c (hold the Control key, then press the c key).
Remember that whenever you type a last line mode command, your cursor moves to the last line of the screen, where you type the rest of the command.
The following ex command deletes lines 10 through 25:
:10,25d<Ret>
The address in the above example is 10,25. The : indicates that this is an ex command, and d is the actual command (delete).
Some of the commonly used ex command addresses are:
. | the current line. |
$ | the last line in the file. |
% | all the lines in the file. |
n | line n |
n,m | lines n through m |
-n | n lines above the current line |
+n | n lines below the current line |
For example, to delete the first line in the file through the current line, type:
:1,.d<Ret>
The following example would erase the contents of the file and leave it empty:
:%d<Ret>
Lines above or below the current line can be specified by a - or a + and may be used to designate a block of lines. The following example shows the 5 lines before and the 8 lines after the current line being deleted (the current line is deleted as well):
:-5,+8d<Ret>
A marker is a pointer to a line or to a character in a line. There are 26 markers, one for each lowercase letter of the alphabet. The marked line (or character) is addressed by preceding its marker letter with a single quote.
The command ma marks the current cursor position with the letter a (where a can be any letter from a to z).
For example, to mark line number 15 with a "j" and line number 30 with an "a", move the cursor to line 15 and type:
mj
Then move the cursor to line 30 and type:
ma
Then, from anywhere within the text you can move the cursor to line 15, which has been marked with the letter j, by typing:
'j
Alternatively, you can use `j to go to the specific character where the cursor was located when you marked the line.
If you want to delete lines 15 through 30, you can type:
:'j,'ad<Ret>
An alternative way of deleting a block of lines is by:
mk
d'k
There are nine buffers available to hold yanked or deleted text. The most recently deleted text is in buffer 1, the default buffer, and the oldest deleted text is in buffer 9 (the buffers are automatically recycled). Only the default buffer (buffer 1) is used for yanked text.
To retrieve text, a " (double quote, not two single quotes) precedes the buffer number and is followed by the p ("place the contents of the buffer in a new line created below the current line) or P ("place the contents of the buffer in a new line created above the current line) command. For example:
"2p
places the contents of buffer 2 below the current line.
P
places the contents of the default (most recent) buffer above the current line.
There are 26 available named buffers using lowercase letters a through z. If you repeat the same buffer letter in a command, the most recently deleted or yanked text will replace the older text. The buffer is named by preceding its letter with a double quote (not two single quotes). For example,
"ayy
places the contents of the current line into buffer a (using the yy yank line command). You can then retrieve the contents of this buffer by typing:
"ap
Don't confuse marked lines with named buffers! Marked lines are indicated with ' or ` in commands; named buffers are indicated with ".
:n1,n2d<Ret> | Delete from line n1 through line n2. |
:'a,'bd<Ret> | Delete from marker a through marker b. |
yy | Yank the current line into the default buffer. |
nyy | Yank n lines, starting with the current line, into the default buffer. |
yw | Yank word into the default buffer. |
p | Put the default buffer contents into a new line below the current line (or after the cursor if words, and not lines, have been yanked). |
"np | Put the contents from buffer number n (if n is a number) or buffer named n (if n is a letter). |
P | Put the default buffer contents into a new line above the current line (or before the cursor if words, and not lines, have been yanked). |
"nP | Put the contents from buffer number n (if n is a number) or buffer named n (if n is a letter). |
:n1,n2y<Ret> | Yank lines n1 through n2 into the default buffer. |
i<Ret> | Split line at cursor. |
J | Join two lines. |
nJ | Join n lines. |
:n1mn2<Ret> | Move line n1 below line n2. |
:n1,n2mn3<Ret> | Move lines n1 through n2 below line n3. |
:n1tn2<Ret> | Copy line n1 below line n2. |
:n1,n2tn3<Ret> | Copy lines n1 through n2 below line n3. |
:r filename<Ret> | Insert file filename below current line. |
The following sequence of commands shows how to incorporate part of a second file into the file you are currently editing.
:e newfile<Ret> | Edit a second file, newfile. |
"cnyy | Yank n lines into named buffer c. |
:e#<Ret> | Return to the original file from the second file. |
"cp or "cP | Place buffer c contents below or above the current line. |
:n1,n2w newfile | Place lines n1 through n2 into the file newfile. Note that there is a space between the w and newfile. |
:n1,n2w>>otherfile | Append lines n1 through n2 to otherfile. |
The slash (/) is used to search forwards, and the question mark (?) to search backwards. Both / and ? are last line mode commands: when you type a / or a ? your cursor moves to the last line of the screen, where you type the rest of the search command. Search commands are executed only after you press <Ret>. If you want to exit last line mode without executing the search command, type <Ctrl>c.
Case is respected in searches unless you issue the ex command:
:set ignorecase<Ret>
which can be abbreviated:
:set ic<Ret>
The search will wrap around the end-of-file to the beginning-of-file or vice versa, depending on the direction of the search, unless you issue the ex command:
:set nowrapscan<Ret>
which can be abbreviated:
:set nows<Ret>
in which case the search will stop when it reaches the last line in its search direction.
To repeat the search in its original direction, type:
n
To reverse the direction of the original search, type:
N
Example of a forward search on the word greetings:
/greetings<Ret>
If the string is found, to search backward for the next occurrence, type:
N
Example of a backward search on the word greetings:
?greetings<Ret>
To continue searching backward, type:
n
There are two global search commands, one (g) which includes the search string, and one (v) which excludes the search string. These search commands may be followed by edit commands, such as d to delete the line in which the search string appears or doesn't appear. For example:
:g/gimbel/d<Ret>
Deletes all lines that contain the string gimbel.
:v/gyre/d<Ret>
Deletes all lines that DO NOT contain the string gyre.
Some of the special characters that can be used within search strings are:
Character(s) | Function |
---|---|
^ | Matches the beginning of the line.
For example: /^The<Ret> finds the next line that contains The in columns 1-3. |
$ | Matches the end of the line. |
. | Matches any one or more characters. For
example: /t.e<Ret> finds the, these , torrent, but does not find tea. |
\> | Matches the end of a word.
For example: /ed\><Ret> finds the next word that ends with ed. |
\< | Matches the beginning of a word. Use
/<word>/ to match a
word, as opposed to a character string.
For example: /and<Ret> finds sandwich, land, and stranded; whereas /\<and\><Ret> finds only the word and. |
[ ] | Square brackets define a "character class" and match any one character located between the brackets. Inside the brackets, a ^ in the first position means "use any but the following characters". Some examples of character classes are in the table below below. |
Character Class | Function |
---|---|
[abcd] | a or b or c or d |
[a-d] | a or b or c or d |
[^I-L] | any character except I, J, K, L |
[AB][X-Z] | A or B, followed immediately by X or Y or Z |
2[1-5] | 21 or 22 or 23 or 24 or 25 |
The special characters ^, $, ., [, ], /, and \ must be preceded by a backslash to search for them specifically.
To search for a dollar sign ($), type:
/\$
To search for a backslash (\), type:
/\\
If you search for special characters a lot, you can turn off the special search meanings of . , [ , ] , /<, and /> by typing:
:set nomagic
^ and $ always retain their special search meanings, no matter whether you have "magic" or "nomagic" set.
The search and substitute command has two option flags: the g flag for making global changes, and the c flag for making conditional changes (these are described below). The format of the search and substitute command is:
:[address]s/search_string/replace_string/flags<Ret>
To search on the current line for the first occurrence of "may" and replace it by the word "will":
:s/may/will<Ret>
To change all of the occurrences of "may" to "will" on the current line, use the g (for global) flag:
:s/may/will/g<Ret>
In the following example, both the g and c flags are used. The g means global, and will cause all occurrences in lines 1 through 5 to be selected, instead of just the first occurrence in each line. The c means conditional, and means that you will be asked whether or not to make the substitution.
:1,5s/want/would like/cg<Ret>
Respond:
y<Ret>
for yes, or:
n<Ret>
for no (the default).
To replace all the words "blue" with the word "red" throughout the file:
:%s/blue/red/g<Ret>
The ampersand (&) is a special "metacharacter". If it is used in the replacement string, it keeps the search string as part of the replacement. For example, to change "red" to "red car":
:s/red/& car/<Ret>
To repeat the last replacement string, use a percent sign. If you have typed:
:s/car/great big beautiful limousine/<Ret>
then
:s/red/%/<Ret>
will change a new search string to the previous long replacement string.
fc | Forward to character c. Cursor is positioned on c. |
tc | Forward to character c. Cursor is positioned on the character before c. |
Fc | Backward to character c. Cursor is positioned on c. |
Tc | Backward to character c. Cursor is positioned on the character after c. |
; | Repeat last line search command. |
, | Reverse last line search command. |
Use <Ctrl>g to display the current filename and line number.
Use <Ctrl>l to clear and refresh the screen. This is useful when your screen gets cluttered by a message another user might write to you while you are in vi. While the screen does look messy when this happens, no harm has been done to your text (as you can verify by refreshing the screen with <Ctrl>l.
A tilde ( ~ ) typed at the cursor position will change uppercase to lower and vice versa. The following will also change case:
:n1,n2s/[a-z]/\U&/g | Changes lowercase letters to uppercase in lines n1 through n2. |
:n1,n2s/[A-Z]/\L&/g | Changes uppercase letters to lowercase in lines n1 through n2. |
To transpose two characters at the cursor, type:
xp
If you place the cursor on a left or right parenthesis, left or right brace ({ or }), or left or right bracket ([ or ]), and type in the percent sign %, vi will move the cursor to the matching character of the pair.
If you have a long phrase that is repeatedly used in your text, you can set up an abbreviation for it. When the abbreviation is used in insert mode, the full text will be substituted.
For example, when you are in command mode, to set up an abbreviation for "Really Terrific Foobar Manufacturing", type:
:abbr rtfm Really Terrific Foobar Manufacturing
Then, when you are in insert mode, if you type:
Thanks to.rtfm.
This will appear on your screen:
Thanks to.Really Terrific Foobar Manufacturing.
Note: Blanks may be substituted for the two periods in the above example, so that the expanded phrase will have a blank on either end. A non-alphabetic, non-numeric character must be used at the beginning and end of the abbreviation for expansion to occur.
The abbr command can be put in your .exrc file, in which case the leading colon, :, is omitted.
If the system has crashed while you were editing a file with vi, you may be able to recover the file with:
vi -r filename<Ret>
To list recoverable files, type:
vi -r<Ret>
To execute a single shell command, type:
:!command<Ret>
To create a shell and execute multiple shell commands, type:
:sh<Ret>
To return to your vi session after executing the shell commands, type:
exit<Ret>
:r !command<Ret> | Note: There is a blank after the r. |
:!}fmt -72 | Format the text between the current line and the end of the current paragraph, within columns 1 to 72 (see the Unix fmt for more information). |
:!}sort | Sort the current paragraph by the first word on each line. |
You may want to scan the contents of a file without the ability to change it. To do this, you may use the read-only option. To enter vi in read-only mode, type:
vi -R filename<Ret>
or:
view filename<Ret>
You can set up your own editing environment by using a file named .exrc, which will be executed whenever you begin a vi editor session. The contents of the .exrc file consists of set and possibly other commands. The set command is used to set vi parameters. Some of the possible set commands are listed below.
set number set nu | Lines will be numbered on the left. |
set showmode set smd | The editor will display the words INSERT MODE, REPLACE MODE, APPEND MODE, OPEN MODE, CHANGE MODE, or INPUT MODE, depending upon your command. |
set warn | You will be warned if you exit without saving your work (this is the default setting). |
set ignorecase set ic | Uppercase and lowercase will be ignored in searches and substitutions. |
set autoindent set ai | If you indent a line with spaces or tabs, all subsequent lines will be automatically indented. |
set wrapmargin=n set wm=n | The vi editor will automatically insert a <Ret> and wrap to the next line when it reaches the right-hand margin of n characters. |
set wrapscan set ws | Searches will wrap around end-of-file to beginning-of- file to continue searching. (This is the default.) |
set tabstop=3 | Sets tab margins in every 3 columns (the default is every 8 columns). |
For example, your .exrc file might consist of the following 4 lines:
While editing a file with vi, to negate the number, showmode, warning, ignorecase, autoindent, or wrapscan settings, type:
:set nonu<Ret> | Do not display numbers at the left of the lines. |
:set nosmd<Ret> | Do not show mode. |
:set nowarn<Ret> | Do not warn if you exit without saving your work. |
:set noic<Ret> | Do not ignore case. |
:set noai<Ret> | Do not autoindent. |
:set nows<Ret> | Do not wrap during searches. |
Other :set commands that may be useful are:
:set list<Ret> | Displays tabs as ^I and displays the end of the line with $ (so that you can see where these characters are in your file) |
:set nolist<Ret> | Display tabs and end-of-lines as white space. |
:set nomagic<Ret> | Disable the special search meanings of . , [ , ] , \<, and \>. |
:set magic<Ret> | Enable the special meanings of these characters. |
To find out what options are currently set type:
:set<Ret> | Display currently set vi options. |
:set all<Ret> | Display all set values available. |
The following were used as references in preparing this article: