The vi Text Editor


In this article, we will use brackets "< >" to indicate keys to be pressed.  Thus, the instruction press <m> means to press the letter "m" key.

If you have problems with or questions about the contents of this takeout, you may call the VCU IT Support Center at 804-828-2227.

The vi (pronounced "vee-eye") text editor was written by Bill Joy of the University of California at Berkeley.  It is a visual extension of an older UNIX editor, hence the name vi.  It acts as a window to the file you are editing, using all but the last line of the screen for the display of text being edited.

Vi is a very powerful and flexible editor.  It operates quite differently than most text editors, and this makes it undesirable to many people.  But, those who get past that point and learn about all the capabilities and conveniences it offers generally consider vi to be one of the best, if not the best, of the text editors around.

This document does not attempt to cover all of the commands and facilities available in vi.  Please refer to other documentation for a more complete coverage.  Perhaps the definitive documentation is contained in the articles An Introduction to Display Editing with Vi and Ex Reference Manual, both by William Joy, and found in the Unix User's Manual Supplementary Documents.

Note that several vi-like editors have been developed.  These generally have all the features of vi, and more.  A favorite of these is the vim ("vi improved") editor, that is available on many Linux systems (if so, it can be launched from the command prompt by typing vim or vim filename).  It is available at  Some of the extra features it offers are multiple levels of undo and redo (instead of just one) and a screen display indicating when you are in insert mode (see next section).  This document, however, covers only the original vi editor (but all the features discussed, and more, are available in vim).

It is important to understand that when you are editing a file, you are working with a buffer.  This means that if you edit a previously existing file, vi copies the file into a temporary storage space (the buffer), and you edit the copy.  Any changes you make are made only to the copy.  The original file is untouched until you "write" (save) the file to disk.


When you use any text editor, you need to be able to do two basic things.  You obviously need to type text into your document.  But, you also need to give commands to the editor - to tell it to find a word, delete text, save your file, etc.

Most other editors and word processors require you to press special keys on the keyboard (function keys, the Control key, the arrow keys, etc.) in order to give commands.  Pressing just the "regular" keys (the alphabetic keys, digit keys, or punctuation keys) simply results in text being entered into your document.

Vi takes the most unusual (some would say ingenious) approach of using the "regular" keys for both purposes!  That is, you use the same keys on the keyboard for entering text and for issuing commands.  Actually, there are a few instances when you have to press a special key to give a command, but, for the most part, only the regular keys are used.

Obviously, there has to be some way for vi to know what your intent is when you go pressing a key.  Vi solves this problem by having two "modes" of operation.  These are called command mode and insert mode.  Here's how they work:

  • When you launch vi, it always starts out in command mode.  Any and all keys you press while in command mode will be interpreted by vi as commands (so be careful!).  As you will see shortly, there are all sorts of commands available for doing things like moving the cursor, deleting text, finding and replacing text, etc. -- vi is a very powerful editor.  The creators of vi tried to make the commands easy to remember.  For example, to move the cursor ahead to the next word you press w, or to delete a word you press dw.  Usually, you will not see the command keys you press displayed on the screen -- vi will simply go ahead and perform the command you gave it.  Since it's important, we repeat: When vi is in command mode, every key you press is considered a command or part of a command.
  • When you are ready to type some text into your document, you must first put vi into insert mode.  There is, of course, a command you can issue that will do that (actually, there are several).  While you are in insert mode, you can type text into your document and you can press the Backspace key to erase the text that you just typed.  But that's all you can do.  You can not move the cursor to another line, you cannot tell vi to find a word, etc.  You can just type and backspace.  When you finish typing (for now) and wish to do something else (move the cursor, find a word, etc.), you must get out of insert mode and back into command mode.  To do this, you press the Escape key.  Remember: To get out of insert mode, press Escape.

Thus, a typical editing session will find you going back and forth between command mode and insert mode as you go about issuing commands to vi and inserting text in your document.

Unfortunately, vi does not display any indication on the screen of which mode you're in at the time.  But usually, that's not a problem, because you'll remember, based on what you're doing at the time.  If you do forget and are not sure which mode you're in, simply press the Escape key.  After you press Escape, you always know that you are back in command mode.  (Don't press other keys if you're not sure, because if you happen to be in command mode, those keys will be commands that vi will try to perform.)

There are advantages and disadvantages to this unusual command mode/insert mode approach that vi takes.  The disadvantage is that you must get used to it.  It usually takes novice users a little while to "get the hang of" switching back and forth between command and insert mode.  But after a short time, it becomes second nature, and you do it almost without thinking.  The advantage comes for touch typists.  Since you use the "regular keys" to do everything, you can do ALL your editing without ever having to take your eyes off the screen.  You can move to the end of the document, insert some text, move back two paragraphs, copy and paste a sentence, etc., all quickly and easily, without ever having to look down at the keyboard to find a function key or other "special" key.  (If you are not a touch typist, you should learn!  You are wasting a significant portion of your computer life searching for keys.)


The subsequent sections of this document will describe the many editing commands that are available in vi.  In this section, we will make some suggestions, describe some general patterns that vi commands follow and give some other notes.  This should help you remember the commands and use them more easily.

First, we recommend that you start by learning just a few basic vi commands and use them until you become comfortable with vi.  Later you can expand your knowledge of vi, as you desire.  We will list a good basic set to use at the end of this section (after we explain what a colon command is).

As for learning the other commands, your task is made easier because vi commands, in general, follow a pattern, as we explain next.

For the most part, the vi commands are in three general categories: commands that move the cursor, commands that delete text, and commands that change text.  In general, if there is a command to move the cursor by a certain amount (to the next word or paragraph, etc.) and you put the letter "d" in front of it, it becomes a command that will delete that amount of text.  For example, the w command tells vi to move the cursor from its current position ahead to the beginning of the next word.  The command dw tells vi to delete the text between the current cursor position and the beginning of the next word.  As another example, G (capital g) tells vi to move (go) to the very bottom of the document, whereas dG tells vi to delete all text between the cursor and the very bottom of the document.

Likewise, if you take a vi movement command and put the letter "c" in front of it, it becomes a command to change text.  By changing text, we mean to erase some amount of text (word, paragraph, etc.) that is already in the document and type something else in its place.  Using w and G again as examples, the command cw would erase all text between the cursor and the beginning of the next word and would also put you in insert mode (all in one step) so that you could begin typing the replacement text.  The command cG would erase all text between the cursor and the end of the document and also put you in insert mode.

Another pattern, so to speak, of vi commands, is that, in general, you can put a number in front of a command to make it repeat.  For example, w will move the cursor ahead by one word, and 4w will move it ahead by four words.  Likewise, dw deletes one whole word (assuming the cursor is at the beginning of a word), and 4dw will delete four words.

Two particular commands deserve special mention.  The u command will "undo" the most recent action that you performed.  Thus, if you deleted a paragraph or changed a word, issue the u command to undo your action.  You must do it right away, before issuing some other command, since u only undoes your most recent action (if you're using the "vim" editor, you can undo multiple actions).  Likewise, the . command (just type a period) will "redo" your most recent action.  For example, if you have just issued the cw command and changed the word "Smith" to "Van Gogh", you can now move the cursor to some other word and press the period key, and immediately that word (whatever it is) will also change to "Van Gogh".

Finally, we need to point out that there is a special set of commands known as colon commands.  They have this name because you begin them by typing a colon (not a semicolon, but a colon).  While in command mode, if you type a colon, you will see a colon displayed on the very bottom line of your screen, with the cursor sitting beside it waiting for you to type the remainder of the command.  As you type the command, you will see it displayed on the screen (unlike most vi commands).  And, after you finish typing the command, you press the <Enter> key to tell vi to perform the command.  Vi will perform the command and then place the cursor back in your document at an appropriate place.  There are various colon commands listed in this guide.  An example is :write (or just :w for short), which is the command to "write" (save) your file to disk.  To issue this command, first be sure you are in command mode.  Then type a colon and the letters write.  Then press <Enter> to execute the command. 

Note that the discussions above concerning the redo command and about putting a "d" or "c" or a number in front of commands do not apply to colon commands.  But the undo command does work (you can undo a colon command).

Now, as promised, below is a suggested set of basic commands for you to begin using.  Note that the first two commands put vi in insert mode so that you can type text into your document -- remember that after you finish typing you will have to press Escape before you can issue any other commands.  Also, note that the last four commands listed below are colon commands (begin by typing a colon).  Finally, be careful to type all commands in lower case or upper case, exactly as shown here (case makes a difference).

i Put vi in insert mode.
o Open (insert) a new blank line for typing and put vi in insert mode.
h j k l Move the cursor left, down, up, and right, respectively. (the arrow keys also work)
w Move the cursor ahead to the next word.
b Move the cursor back to the previous word.
x Delete one character.
dw Delete all text up to the next word.
dd Delete the entire line.
G Go to the last line in the document.
24G Go to the 24th line in the document. (use any number)
:w Write (save) the document to disk.
:w filename Write the document to disk under a different name.
:q Quit vi.
:q! Quit vi without saving changes. (be careful here)



In describing vi commands, the bracket notation (<>) will only be used for "special" keys (e.g. <Ctrl>, <Enter>, <Spacebar>, etc.) and not for simple letters or numbers.  In addition, the following conventions will apply to command descriptions:

  • Commands beginning with : (colon) must end with <Enter>
  • file is the name of a file.
  • cursor_cmd is a cursor movement command (e.g. G j w b).
  • char is a single character.
  • str is a character string (can contain pattern matching characters).
  • text is a character string which can span multiple lines.
  • <Ctrl-x> means you press <Ctrl>, hold it down, and press the <x> key.
  • n,m can be two line numbers (e.g. 4,50), line markers (e.g. .,$ or 'a,'b), or search expressions (e.g. /string1/,/string2/).
  • (a-z) means you choose a letter from a through z.



To start a vi session, you should be at a command prompt -- if you are in the menu, quit the menu to obtain a command prompt. At the command prompt, enter the command vi filename (substitute the name of the file you wish to edit). If the file exists, the first lines in the file will appear on the screen. If the file doesn't exist or if you don't specify a file, the cursor appears at the top left corner of the screen, and a column of tildes (~) appears under it on the left. The tildes represent unused space at the end of the buffer and are not actually a part of the file.

In either case, when you first enter vi you are automatically placed in command mode.



When you are finished editing the file, you need to save the changes you have made before actually exiting vi. You may also want to save changes while you are editing - just in case! The following commands apply:

:w file Save the buffer into a file named file but do not exit vi (omitting file saves into the current file). If the file already exists and is not the current file, you will not be allowed to do this.
:w! file Save the buffer into an existing file named file, overwriting its existing contents and do not exit vi.
:n,mw file Write lines n through m to file.
:n,mw>> file Append lines n through m to the end of the file.
:q Leave vi if no changes have been made since the last write.
:q! Leave vi without saving changes since the last write.

ZZ or :wq or :x

Save file and exit vi.



6.1 Placing Marks

Commands which use line numbers as a part of the command can also use line markers - symbols which designate a location in the file. There are two default line markers which always exist. They are the period (.) which designates the current line and the dollar sign ($) which designates the last line in the file. In addition, you can specify other markers with the command

m(a-z) Mark current cursor position with a letter a through z (e.g. ma).


6.2 Moving the Cursor

The following commands are used to move the cursor within the file. Most of these can be prefixed with a number to specify the number of times the command will be executed (e.g. 5w will move the cursor five words).

k or <up arrow> or <Ctrl-p> Move cursor up one line (a vi line may be more than one line as shown on your screen).
 or <down arrow> or<Ctrl-j> or <Ctrl-n> Move cursor down one line.
h or <left arrow> or <Backspace> or <Ctrl-h> Move cursor left one character (a "Tab" counts as only one character even though it may display as multiple spaces on the screen).
l (the letter 'l') or <right arrow> or <Spacebar> Move cursor right one character.
w or W Move cursor to start of next word (W ignores punctuation).
b or B Move cursor to start of the previous word (B ignores punctuation).
e or E Move cursor to end of next word (E ignores punctuation).
0 (zero) or | Move cursor to the first column in current line.
n| Move cursor to column n in the current line.
^ (caret) Move cursor to the first non-blank character in the current line.
$ Move cursor to the last character in the current line.
+ or <Enter> Move cursor to the first character in next line.
- Move cursor to the first non-blank character in the previous line.
( Move cursor back to beginning of sentence.
) Move cursor forward to beginning of next sentence.
{ Move cursor back to the beginning of the paragraph.
} Move cursor forward to beginning of next paragraph.
H Move cursor to the top line of the screen.
M Move cursor to the middle line of the screen.
L Move cursor to the bottom line of the screen.
G Move cursor to the last line in the file.
nG Move cursor to line n in the file (e.g. 1G moves to the first line in the file).
'(a-z) Move cursor to the line containing the specified marker (e.g. 'a moves to line where the ma command was given).

Note: The following definitions are used in vi:

Word A character string with either Whitespace or Punctuation at both ends.
Line a character string with an end of line mark at both ends. A single vi line, depending on its length, may be displayed as multiple physical lines on the screen.
Whitespace one or more spaces and/or one or more tabs, or the end of a line.
Punctuation any character that is not a letter or a number.
Sentence a string of words and punctuation with either a period (.) or a blank line at both ends. A sentence may span more than one line.
Paragraph a string of sentences with either a blank line or the beginning or end of the file at both ends.


6.3 Adjusting the Screen

The following commands are used to scroll the text across the screen in order to see where you are working:

<Ctrl-e> Move screen up one line.
<Ctrl-y> Move screen down one line.
<Ctrl-u> Move screen up 1/2 page.
<Ctrl-d> Move screen down 1/2 page.
<Ctrl-b> Move screen up one page.
<Ctrl-f> Move screen down one page.
<Ctrl-t> (the letter 'l') Redraw the screen (in case your display has gotten messed up).




7.1 Inserting Text

To leave insert mode, press <Esc>.

a Append text after the cursor.
A Append text after the end of the current line.
i Insert text before the cursor.
I Insert text before the first non-blank character in the current line.
o Open a new line below current line and insert text.
O (the letter 'O') Open a new line above current line and insert text.

While inserting text, you can ignore special meaning of a char by using the sequence <Ctrl-v>
 char (e.g. for inserting characters like <Esc> and control characters).

You can insert text from another file into the current file with the command :r file. This does NOT put you in insert mode.


7.2 Deleting Text

While in insert mode:

<Backspace> or <Ctrl-h> Delete previous character.
 <Ctrl-w> Delete the previous word.
 <Ctrl-x> Delete to the beginning of inserted text.

While in command mode:

nx Delete n characters beginning with current; omitting n deletes current character.
nX Delete previous n characters; omitting n deletes the previous character.
ndw Delete next n words beginning with current; omitting n deletes current word.
ndb Delete previous n words; omitting n deletes the previous word.
ndd Delete n lines beginning with current; omitting n deletes current line.
:n,md Delete lines n through m.
D or d$ Delete from the cursor to the end of current line.
dcursor_cmd Delete text to cursor_cmd (e.g. dG deletes from current line to end of file).


7.3 Changing Text

Preceding these commands with n (a number) repeats the command n times.

xp Switch character at the cursor with the following character.
rchar Replace current character(s) with char.
Rtext<Esc> Replace current character(s) with text. (Note: this will put you in insert mode and allow multiple lines of text. You must press when finished to return to command mode.)
stext<Esc> Substitute text for the current character(s).
Stext<Esc> or cctext<Esc> Substitute text for the entire line.
cwtext<Esc> Change current word(s) to text.
Ctext<Esc> or c$text<Esc> Change rest of current line to text.
ccursor_cmd text<Esc> Change to text from current position to cursor_cmd.


7.4 Copying and Placing Text

These commands are used to copy and move text. To copy text use the yank command and then put it in its new location. To move text, use one of the delete commands and then put it where you want it.

nyy or nY Yank n lines (place them in a buffer); omitting n yanks the current line.
ycursor_cmd Yank text from cursor to cursor_cmd (e.g. yG yanks current line to the last line in the file).
p (lower case) Put yanked text or last deleted text after the cursor.
P Put yanked text or last deleted text before the cursor.

The put command can be repeated several times to copy text to multiple locations.

7.5 Joining Lines

J Join the next line to the end of the current line. If the joined lines exceed the width of the screen, the resulting line will be "folded" on the display but will only be counted as one line for any command purposes.
nJ Join next n lines.




8.1 Pattern Matching

Pattern matching characters are used in search strings to help find text in the file with similar characteristics.  Two of the Set Commands (described below), magic and ic can also be used to control the search. The following characters are used for pattern matching:

^ (caret) Match the beginning of a line.
$ Match the end of a line.
\< Match the beginning of a word.
\> Match the end of a word.
. Match any single character.
[str] Match any single character in str.
[^str] Match any character not in str.
[a-n] Match any character from a to n.
* Match zero or more occurrences of the previous character in expression.
\ Escape meaning of next character (e.g. \$ lets you search for $ and \\ lets you search for \).


8.2 Searching

% Find other end of balancing ( ) { } or [ ].
fchar Search forward in current line to char.
>Fchar Search backward in current line to char.
tchar Search forward in current line to the character before char.
Tchar Search backward in current line to the character after char.
/str<Enter> Search forward in file for str.
?str<Enter> Search backward in the file for str.


8.3 Global Search and Replace

:n,ms/str1/str2/opt Search from n to m for str1 (omitting n,m searches the current line). If str1 is found, it is replaced with str2 controlled by the options in opt. The values for opt can be:
  • g - replace all occurrences of str1 in a line (default is to replace only the first occurrence).
  • c - confirm the change. Press <y> to make the change, <Enter> to skip the change.
  • p - print the changed line(s).

Note: if the character / appears in either str1 or str2, another character which is not contained in either string can be used in its place in the command.

g/str1/s/str2/str3/ Find a line containing str1 and replace str2 in that line with str3.



The following commands allow you to change your mind after you have made a change and reduce the amount of typing you have to do if you are giving the same command multiple times.

u Undo the last command.
U Restore the current line to its original state.
n Repeat the last / or ? search command.
N Repeat, in the reverse direction, the last / or ? search command.
& Repeat the last :s search and replace command.
; (semi-colon) Repeat the last f F t or T search command.
, (comma) Repeat, in the reverse direction, the last f F t or T search command.
. (period) Repeat the last text change or delete command.



There are various options which control how vi performs. You can check and change these options by using the :set command.  You can turn an option on (:set option) or turn it off (:set nooption).  If you want certain options to be set to other than their defaults every time you enter vi, you can place the set commands (without the preceding colons (:)) in a .exrc file in your home directory.

Listed below are some of the options you may want to change with their default settings:

:set all Display all options with current settings.
:set ap Display line after d c J m :s t u command.
:set eb Precede error messages with bell (or beep).
:set noic Ignore case when searching (turned off).
:set magic Pattern match with special characters. Turning this off disables all of the Pattern Matching characters except ^ and $.
:set nolist Turning this on changes your display to show tabs as "^I" and end of lines as "$".
:set nonu Turning this on prefixes text with the line numbers.
:set scroll=n Sets the number of lines a <Ctrl-d> command will scroll.
:set ts=8 Sets tab stops for text input.  Changes made here may not be reflected in printed or other output of the file.
:set window=n Set the number of lines in a text window.
:set wm=n Set automatic text wrapping n spaces from the right margin of the screen.

This article was updated: 04/16/2019