FIRST STEPS: VI


Please save the file located at this link as vilesson.txt. It will serve as a practice file for vi exercises.


1. Intro

Arguably, the most prolific editor in the world is vi. Available on every UNIX machine (and in its many incarnations also on Windows, Mac OS X, and other platforms), with the Internet explosion, this lean and powerful editor is attracting as much praise as criticism from the cyberspace citizens.

When vi is first started, it expects commands, be it text input, deletions, changes, searches. Following the command, an argument usually needs to be given, for example, following command i (insert text at the cursor), one would type text and then end the command with Escape. For deletion, one would press d and then an argument, for example w for word, or 3w for three words or } which in vi-speak means to the end of the paragraph. If simple mnemonic commands are not sufficient, command line is provided through pressing : (colon). From there long commands can be executed to be applied to ranges of lines in text. Even external programs can be used as filters to process parts of the text.

To a traditional Windows or Mac user, vi seems foreign at first mainly because it sees text input command as any other editing instruction and does not allow stacking it with other commands which almost all Windows and Mac editors do allow. For example, when inserting text in Windows "Notepad", can you press PageDown to go down? Yes, naturally, you will say. Not in vi, however, since text inserting does not have any special ability to be mixed with other commands. In vi you would first end text inserting command by pressing Esc (that's how all text input commands are terminated) and then you would press Ctrl-F (for Forward Page). Therefore, it is crucial to remember that everything is considered a command in vi. Some authors talk about "insert mode" and "command mode" to emphasize this difference from other editors. I personally find this explanation unnecessarily confusing. As long as it is clear that text input is just another command which must be terminated before other editing commands can be issued, one will do just fine with vi.

Repeat: After one issues a text input command which does not have a pre-determined argument length (A, I, O, R, a, c, i, o), and after one is finished typing text, one must press Escape key.

Why don't other commands require termination? This is because the length of the arguments is easily determined. For example, if one presses d to signify delete, the editor will wait for the symbol of the object to be deleted and (optionally) the number of the objects. Therefore, whether the complete command is d} (delete to the end of the paragraph) or d3w (delete three words), it will be obvious to the editor where the arguments to the command d end. However, this is not the case with inserting text, as the editor cannot guess at which point we no longer wish to treat our keystrokes as text input. That's why the length of the argument cannot be pre-determined, and that's why when we're done with inserting text, we must press Escape to make it clear.

While it may seem unintuitive to Windows and Mac users in the beginning, it allows the use of single letter keystrokes as editing instructions, making vi not only a very fast editor, but also a very frugal one when used over the wire.

This particular design model has also allowed the author to make commands easy to remember and easy to deduce once some of them are memorized. This easy inference is necessary in vi since its bandwidth frugality precluded it from having menus.

2. Commands

Below you will find a cheat-sheet with vi commands. This cheat sheet will also come in handy in the next section of this document, Practice Lesson #1.

vi cheat-sheet

a. cursor movements (items below are sometimes called objects):
        h - left one character
        l - right one character
        j - down one line
        k - up one line
        w - right one word
        b - back one word
        $ - to the end of line
        0 - to the beginning of the line
        ) - right one sentence
        ( - left one sentence
        } - right one paragraph
        { - left one paragraph
        Ctrl-F - forward one page
        Ctrl-B - back one page
        G - go to (without arguments, go to end of file)
b. deleting:
        d - delete
                then add one of the cursor movement symbols to
                show what should be deleted, i.e.:
                d$ - delete to end of line
                d0 - delete to the beginning of the line
                d} - delete to the end of paragraph
        dd - delete delete (delete the whole line)
        x - delete character cursor is on
c. other basic commands:
        r - replace one character
        ZZ - save and exit (hold down shift and press "z" twice)
        y - yank (copy into temporary buffer)
                then add cursor movement symbol to show what should be
                copied, for example: y) - copy to the end of sentence
        Y - yank line cursor is on
        p - paste below cursor line (deleted or copied text)
        P - paste above cursor line
        u - undo last editing command
        /sometext - search for "sometext"
d. any command can take numeric argument before the name of "object", i.e.:
        5dd - delete 5 lines beginning with cursor line (or) d5d - same
        2dw - delete two words (or) d2w - delete two words
        c3w - change 3 words
        3Ctrl-B - move up three pages
        1G - go to the first line
e. external commands can be performed on the selected text (in lines)
   if command is started with "!", i.e.:
        !}fmt - reformat paragraph to 72 columns
f. command line (sometimes called "ex mode"):
        :
g. from the command line a "set" command can be executed to 
   customize editing environment, i.e.:
        :set all - will show the state of all options
        :set number - will show on the screen numbers of all lines
        :set autoindent   // obvious
h. from the command line operations can be performed on the range of lines,
   i.e.:
        :18,24 del - delete from line 18 to line 24
        :23,48 copy 17 - block from line 23 to 48 copy to line 17
        :2,17 move 92 - block from line 2 to 17 move to line 92
i. from the command line any external UNIX command can be performed on 
   the range of lines if line range is superseded by "!":
        :11,16! sed -e "s/^/\/\*/" -e "s/$/\*\//"
                (the command above wraps the block of text with
                 "C" style comments - /* text */.  It can be done
                  easier, but this is an example)
        :14,19! sort -r +3
                (sort the table in reverse order by fourth column)
j. file manipulation from the command line:
        :r somefile - read in "somefile"
        :x - save and exit (if file is "Read Only", this command will
                exit without saving)
        :wq - write and quit (same as above)
        :w - write (save) if the file permissions allow it
        :w! - save file even if it is read-only as long as we own it
        :w somefile - save this file as "somefile"
        :q - quit without saving
        :q! - quit without saving if changes were made
k. text input commands (all require "Esc" to terminate):
        i - insert text before the character cursor is on
        I - insert text at the beginning of the line
        a - append (insert text after the character cursor is on)
        A - append text to the end of the line
        c - change (replace previous text with new one)
                takes arguments just like the delete command - it is
                a fast and powerful way of changing original text -
                much more so than typical "overwrite"
        R - start overwriting text
        o - start entering text at the beginning of the new line
            below the cursor
        O - start entering text at the beginning of the new line
            above the cursor
l. if in doubt, press "Esc"

3. Practice Lesson #1

You should have a practice file called vilesson.txt in your home directory. We will use it now:

$ vi vilesson.txt

Please note that in this lesson we will only practice the very basics of vi. It is up to you to explore the editor further using the provided cheat-sheet.

General Rules

  1. Do not use arrow keys to move the cursor
  2. Do not use PgDn or PgUp keys
  3. Do not use Home or End keys

If you accidently violate any of the above rules and cause strange characters to be inserted into the file, or if anything else unexpected happens, and you don't know how to correct it, press Escape followed with :q! (quit without saving command). Then open the file again and continue the lesson.

All exercises in Practice Lesson #1 consist of Actions (marked here as A:) and Verifications (marked here as V:).

Moving Around Text

First we will move around the file line by line.

A:
Press j three times.
V:
Cursor should now be resting on the fourth line.
A:
Type 8j
V:
Cursor should have moved 8 lines down to "Mr. John Bigfoot".
A:
Go up 2 lines by pressing k twice. Now go up 7 more lines using the combination of a number and the k command.
V:
Your cursor should be on the "Big Town" line.

There is a way to move to a specific line number.

A:
Type :set number and press Enter key.
V:
Line numbers should be displayed at the left margin.
A:
Type 33G
V:
Your cursor should be resting at line #33.
A:
Type :set nonumber
V:
Line numbers should disappear.
A:
Go to the first line in the file by typing 1G (as in line #1, GO).
V:
Your cursor should be at the top of the file.
A:
To go to the last line in the file, you do not need to specify the line number at all (it would often be inconvenient). Type G
V:
Cursor should be at the last line of the file.

To move sideways we will use command l (letter el) to move right, and command h to move left. First go back to the beginning of the line "40 PR Special (Pink Squirrel)". When you're done, continue with the exercise.

A:
Press l three times.
V:
Cursor should be on character "P".
A:
Type 10l (number 10 followed by letter el)
V:
Cursor should be resting on white space between words "Special" and "Pink".
A:
Press h twice.
V:
Cursor should be on character "a" of the letter "Special".
A:
Now go directly to the end of the line by pressing $ (dollar sign).
V:
Cursor should be at the end of the line.
A:
Go back to the beginning of the line by pressing 0 (zero).
V:
Cursor should be at the beginning of the line.

We can also move using words, sentences and paragraphs as delimiters. First make sure your cursor is still at the beginning of the line "40 PR Special (Pink Squirrel)".

A:
Press w (as in word) twice.
V:
Cursor should be at the beginning of the word "Special".
A:
Type 3w
V:
Cursor should be at the beginning of the word "Squirrel". Note that vi knows that "(" is not a part of the word, and it counts those elements separately.
A:
Go two paragraphs down by pressing 2} (right curly brace).
V:
Cursor should be resting before the beginning of the paragraph "We are looking forward [...]"
A:
Go to the previous sentence by pressing ( (left parenthesis).
V:
Cursor should be on the word "We". Note: Using sentences as delimiters is known to be broken in a couple of vi implementations.
A:
Move to the end of the word by pressing e (as in end of the word).
V:
Cursor should be resting on the letter "e".
A:
To move one page forward, press Ctrl-F
V:
Depending on your terminal definition, the cursor should have moved an appropriate number of lines forward. In our case, since the file is short, you are most likely at the last line.
A:
Press Ctrl-B to go back one page.
V:
Cursor should have moved up one terminal page.

Searching

Make sure your cursor is at the top of the file, then proceed with the exercise.

A:
Press /, type your and press Enter
V:
Cursor should be on the word "your" in the middle of the sentence "Thank you for placing your order with us".
A:
Press n (for 'next').
V:
Cursor should be on the word "your" before words "March 25".
A:
Press G to go to the end of the file.
V:
Cursor should be at the bottom of the file.
A:
Press ?, type ( and press Enter
V:
Your cursor should be on the left parenthesis before the word "Moscow".

Deleting, Copying, And Pasting

We will practice commands d (delete), p and P (paste), and the command . (period, which means repeat last edit). Make sure your cursor is still on the left paren before the word "Moscow".

A:
Type d$
V:
You have just asked to delete to the end of line: d for delete and $ for end of line (to indicate the scope of the operation). Entire description of the "Stock Option" drink should have disappeared.
A:
Press n to find the next instance of "(" (that was our last search).
V:
Cursor should be on the left paren before the word "Ping-Pong".
A:
Repeat the previous edit (delete to end of the line) by pressing . (period).
V:
Description of the "Day in TAC" drink should have disappeared.
A:
Press n again followed by . (period).
V:
Description of the "PR Special" drink should have disappeared.
A:
Repeat the last operation.
V:
All of the descriptions of the drinks (please ignore the fact that some of them are intentionally wrong) should be gone.
A:
Exit the file without saving it by typing command :q!
V:
You should be at the UNIX shell command prompt.

Bring the file back into the editor with the command:

$ vi vilesson.txt

By now you have noticed that one of the drinks is really an appetizer. We need to move it into the right place.

A:
Type /Early and press Enter
V:
Cursor should be on the line with "Early Release".
A:
Delete the whole line by pressing d twice.
V:
Line should be gone.
A:
Press P (upper case).
V:
The line you deleted is pasted above "Sales Engineer Special".
A:
Now press u for undo, remember which line your cursor is on and then press p (lowercase).
V:
The line you deleted is pasted below your cursor line.

Note that uppercase P pastes text above the cursor line, lowercase p pastes below.

If you only wish to copy the original line(s) without deleting at the same time, use the yank command.

A:
Move you cursor to the second line, type 3Y, move your cursor all the way down by pressing G and press p
V:
Lines 2, 3, and 4 should have been pasted under "Tony Thomas".
A:
Now press u to undo the changes.
V:
The lines you have pasted should have disappeared.

The above operation could also be accomplished using lowercase yank and the symbol for the object to be copied.

A:
Move your cursor back to line 2. Type commands y}Gp
V:
Lines 2, 3, and 4 should have been pasted under "Tony Thomas".
A:
Now undo the changes.
V:
The lines you have pasted should have disappeared.

Replacing Text

You have just noticed that the name of the addressee is spelled "Bigfoot". It should be "Bigshot". You will now globally change it.

A:
Press : (vi command line), type %s/Bigfoot/Bigshot/g and press Enter
V:
All instances of "Bigfoot" should have changed to "Bigshot".

What you have typed means command line (:), the whole file (%), substitute (s), Bigfoot with Bigshot (/Bigfoot/Bigshot/), any occurance on a line (g). Without the last g, the substitution would be performed only once per line. In our case it would not make any difference, but it is a cheap insurance to take. The character % at the beginning of the command means literally from the first to the last line. You could specify a narrower range of lines. :13,19s/Bigfoot/Bigshot/ would perform the substitution on a range of lines 13 through 19.

It is possible to replace specific number of words with whatever text we wish to type in.

A:
Press / and then type send and press Enter. Now type cw (for change word), type be delivering and press Escape
V:
The word "send" should have been replaced with "be delivering". Note that only the word "send" was replaced.

You could also specify multiple words to be replaced, for example c3w. This has a distinct advantage over more conventional overwriting because it has clear word-boundary delimiters.

Overwriting one character, however, can be useful as a quick correction. Note that the word "Febeuary" is misspelled.

A:
Place your cursor on the second "e" in that word and press r twice.
V:
The word "Febeuary" should now read "February".

The first time you pressed r above it meant replace, the second time with letter r. You do not need to finish the command with Escape because there is an understanding that only one letter will be input. This was single-letter overwriting. Should you wish to overwrite continuously, you would use the letter R instead. You would also need to finish the command by pressing Escape since the number of characters to be overwritten is not pre-determined.

Changing Case

Notice that the word "serVEd" has improperly capitalized two letters.

A:
Go to the word "serVEd", place your cursor over the first miscapitalized letter and press ~ (tilde) twice.
V:
The word should now read "served".

Saving Files

It is time to save the changes.

A:
Press : (for command line), type w (for write) and press Enter
V:
The changes have been saved. There could be a one-line note at the bottom of the screen saying, "vilesson.txt: 48 lines, 954 characters" (or something similar) to confirm a successful save.

There are other ways to save files, so please read the cheat-sheet for the command summary.

Inserting Text

There are three parts to entering text:

  1. input command (A, I, O, R, a, c, i, o)
  2. text to be inserted (anything you wish)
  3. termination of input command (Escape key)

The third part is always the same. All text input commands listed above are terminated with Escape key. Part one is where the variation occurs.

A:
Move the cursor to the beginning of line 38. Press i and start typing text. When you finish the sentence, press Escape.
V:
As you have noticed, i inserts text before the letter the cursor rests on.

To enter text after the cursor, you would use a (append) command. Now move your cursor to the second line in the table listing drinks to be delivered.

A:
Press o.
V:
A new blank line should have been opened below the cursor line.
A:
Type some text. Press Escape.
V:
Text should have been entered on the blank line.
A:
Press u.
V:
Text you entered should have disappeared.
A:
Now press capital O, type some text and press Escape.
V:
Text should have been entered on the line above the former cursor line.

Note that the capitalized version of the same command opens the line for text input above the cursor line. Note similarities to the p and P commands. Press u.

Make sure you are approximately in the middle of the line of text (any line).

A:
Press I (the capitalized version of the insert command). Start typing text. Press Escape.
V:
Text should have been entered at the beginning of the line.
A:
Press u to undo changes.
V:
Text you entered should have disappeared.
A:
Now press A (the capitalized version of the append command, type some text and terminate the command.
V:
Text should have been appended to the end of the line.
A:
Press u to undo changes.
V:
Text you entered should have disappeared.

Exiting file

You can exit file with or without saving changes.

A:
To save and exit, type :wq and press Enter.
V:
File has been saved and you should be at the UNIX command prompt.
A:
Open the file using vi vileson.txt and make some changes (if you are entering text, please remember to terminate the text input command with Escape). Type :q and press Enter.
V:
Normally that would allow you to quit file, but since you have changed the file, vi most likely will ask you to either save or use bang (! command) to overwrite the protection.
A:
Type :q! and press Enter.
V:
You should be back at the UNIX command prompt.

Note that bang also works in conjunction with :w and :wq commands.

End Of Practice Lesson #1

4. Startup File

Having explored vi commands somewhat, we are now ready to create a default editing environment through the use of .exrc, the configuration file which resides in user's home directory.

.exrc typically contains at least three types of entries:

  1. set commands to create preferred editing environment
  2. map commands to assign functions or macros to keys
  3. ab commands to either map abbreviations or automatically correct common spelling errors

When mapping escape sequences of some keys, we may need to quote them, that is, to insert them literally. This can be accomplished in vi by issuing a text input command and pressing Ctrl-V before the key we wish to quote is pressed.

Now let's look at a sample .exrc:

set autoindent
set wrapmargin=8
set ignorecase
map     #4      !}fmt^M
ab      teh     the
ab      cutsomer customer

Lines 1 and 2 set autoindent mode on and turn on wordwrap at column 72. Line 3 specifies that all searches are to be case insensitive. Line 4 maps function key 4 to reformat from the cursor position to the end of the paragraph. Finally, lines 5 and 6 map some common misspellings to the correct spelling. Note that ^M on lines 4 and 5 are created by pressing Ctrl-V and then hitting Ctrl-M.

With a little creativity you can make vi look as personal as you wish.

NOTE: After creating .exrc make sure that EXINIT environment variable is not set as it would overwrite whatever settings you entered into .exrc. You can verify whether the EXINIT variable is set using this command from the UNIX command prompt:

$ set | grep EXINIT

If you see no output, you're fine.

Make sure that .exrc contains no blank lines - they are not allowed.

5. Practice Lesson #2

In this lesson we will set up vi configuration file .exrc and will test the configuration.

Also, in this lesson we will no longer follow the Action/Verification exercise structure. You should be sufficiently comfortable with vi by now to successfully complete the exercises on your own.

Open vi on a blank file:

$ vi

Type commands :set all and press Enter. You are likely to see something similar to the following:

noaltwerase     noextended   matchtime=7  report=5       term="xterm"
autoindent      filec=""     mesg         noruler        noterse
autoprint       flash        nomodeline   scroll=24      notildeop
noautowrite     nogtagsmode  noprint=""   nosearchincr   timeout
backup=""       hardtabs=0   nonumber     nosecure       nottywerase
nobeautify      noiclower    nooctal      shiftwidth=8   noverbose
cdpath=":"      ignorecase   open         noshowmatch    warn
cedit=""        keytime=6    optimize     noshowmode     window=48
columns=80      noleftright  path=""      sidescroll=16  nowindowname
nocomment       lines=50     print=""     noslowopen     wraplen=0
noedcompatible  nolisp       prompt       nosourceany    wrapmargin=15
escapetime=6    nolist       noreadonly   tabstop=8      wrapscan
noerrorbells    lock         noredraw     taglength=0    nowriteany
noexrc          magic        remap        tags="tags"
directory="/tmp"
msgcat="/usr/share/vi/catalog/"
paragraphs="IPLPPPQPP LIpplpipbp"
recdir="/var/tmp/vi.recover"
sections="NHSHH HUnhsh"
shell="/usr/local/bin/bash"
shellmeta="~{[*?$`'"\"

These are vi environment variables. They can be modified through the :set commands. In this practice we will configure only a few of those variables. You are encouraged to experiment with others.

Exit vi. Make sure you are in your home directory. The easiest way is to do that is to execute cd with no arguments at the UNIX command prompt. Now open the .exrc file:

$ vi .exrc

If your .exrc file is not blank, exit, back it up first and start from scratch. Now create six entries exactly as described above in Section 4: Startup File. Save, and open vi with no arguments. Type text without hitting Enter key. It should wrap around 72nd column. Indent one of the lines with the Tab key. Continue typing on the same line. It should wrap and start on the left side aligned with the previous indentation. Now join two of the lines using J command. Go to the beginning of the joined line and press function key 4. If your terminal is set up properly, and the fmt utility is present in your distribution, your paragraph should be reformatted.

Type a couple of lines and intentionally misspell "customer" as "cutsomer" and "the" as "teh". Watch your text as it is corrected on the fly.

This concludes our practice. The remainder of this document is left up to the reader to practice at his convenience.

End Of Practice Lesson #2

6. Editing Multiple Files

Editing multiple files in vi is possible in two different ways:

  1. invoke vi with multiple files on the command line
  2. use command :e from within vi

Once the files are loaded, movement from one file to another can be accomplished using following commands:

:n     - next file
:e#    - previous file
Ctrl-^ - last edited file, keep cursor on last edited line

7. Using Named Buffers

It is possible to copy or delete text from any file to a named buffer, and to keep as many as 26 of those buffers around for convenience. Buffers are created using lower case single letters. Using upper case letter means append to the existing buffer. The command beginning buffer operation is " (double quotation mark). Following it is the name of the buffer and then description of the operation to be performed:

"ay}   - yank (copy) from cursor to end of paragraph into buffer "a".
         If buffer exists, overwrite it.
"A12d  - delete 12 lines from cursor down and append it to the
         existing buffer "a".
"ap    - take contents of buffer "a" and paste it below cursor line.

Notice that lower case name for a buffer causes it to be created every time a command is issued.

8. Macros

Buffers can also act as macros if they contain valid vi or ex commands. To execute such a macro, type:

@a     - where "a" is the name of the buffer

Example: From a file containing definitions of complex macros, yank one paragraph (say, 20 lines) to a named buffer "a". Then return to a file you were originally editing and type @a. The commands contained in the buffer will be executed on the file being edited.

It is possible to make files act as vi macros by using command:

:so filename

The most powerful macros, however, are created using programs combined into shell scripts (or CMD batch files), and acting as filters on the text sent to them from within vi. Such shell scripts or programs must take standard input and send results to standard output (which most UNIX tools do).

Even though seemingly strange at first, with a little practice using vi becomes second nature.


Feedback is always welcomed. It helps us improve this cheat-sheet.
/*  The article above and any accompanying files are freely
 *  distributable, but please leave this notice and the text intact.
 *  Best yet, simply point your URL at the home location below.
 *  Home for this document: http://www.infobound.com/vi.html
 *  Copyright (C) 1994, 1999, 2010 Tony Griffen
 *  Last revision April 24, 2010
 *  UNIX is a trademark of The Open Group
 */