VI

------------------------- How to Use VI --------------------------


vi and emacs are the two editors of choice for unix machines. Both are quick, versatile and powerful. Emacs has a few more bells and whistles, while vi is available by default on every unix machine I've seen. Because of its universal availability, I chose to learn vi. Parts of the editor are a bit cryptic, but within a day or two you should be pretty much over most of the learning curve. No pain, no gain. And there is gain - you can really fly through most editing jobs very quickly with vi. In linux Redhat 9.0 there is a command called vimtutor that you might try for an interactive lesson.

You'll avoid most of the confusion surrounding vi if you understand that it uses two modes, command mode, where you tell vi such things as where you want to move in the file, mark your location, delete words, find strings, etc., and insert mode, where vi simply puts whatever you type in as text into your file. To go from insert mode to command mode, hit the escape key (if you are already in command mode, you'll get a beep, no damage done). There are several ways to move from command to insert mode, the most common being i (insert), a (append), o (open a new line), and R (replace).

Note: vi starts you out in command mode, so type `a' or `i' to start adding text, and return to command mode by hitting escape. Then save your file by typing :wq (ZZ also works for those like me who can't type).

Basic Commands

CTL is the control key. CR is a carriage return.

Moving Within a File
The h, j, k, and l commands reflect the arrow keys on those old VT100 terminals, and always
work.  Sometimes the arrow keys also do the same things, depending on your keyboard:

h - move to the left                            CTL-f - change display forward a page
j - `jump' down a line                          CTL-b - change display back a page
k - move up a line                              CTL-d - change display down half a page
l - move to the right                           CTL-u - change display up half a page
- - same as k                                   CTL-y - shift display down on screen
+ - same as j                                   CTL-e - shift display up on screen
e - move to the end of a word                   z. - recenter display around cursor
w - move forward to the beginning of a word     z- - recenter display so cursor is at top
b - move backward to the beginning of a word    z+ - recenter display aso cursor is at bottom
$ - move to the end of the line                 zCR - recenter display so cursor is at top
0 - move to the beginning of the line           'm - move to the beginning of the line of mark m
^ - move to the beginning of the line           `m - move to the location of mark m
G - move to the end of the file                  ) - move forward 1 sentence
H - move to the top of the display               ( - move back 1 sentence
M - move to the middle of the display            } - move forward 1 paragraph
L - move to the bottom of the display            { - move back 1 paragraph
B - move back to previous blank space           20| - go to 20th character in the line
E - move ahead to next blank space              CTL-L - clear and redraw
B - move back to previous blank space           CR - same as j
CTL-G - print current location in the file       :22 - move to line 22

6w - move forward 6 words
6b - move backward 6 words
8+ - move down 8 lines
etc.
Inserting and Replacing Text
o - open a new line above cursor(*)               O - open a new line below cursor(*)
i - insert text ahead of cursor(*)                I - insert text at the beginning of the line(*)
a - append text after the cursor(*)               A - append text at the end of the line(*)
c$ - change to end of the line (*)                d$ - delete to end of the line
C - same as c$ (*)                                D - same as d$
cG - change to end of the file (*)                dG - delete to end of the file
c0 - change to beginning of file (*)              d0 - delete to beginning of file
cc - change line (*)                              dd - delete line
c'm - change from cursor through mark m (*)       d'm - delete from cursor through mark m
3cc - change 3 lines (*)                          3dd - delete 3 lines
8cw - change next 8 words (*)                     8dw - delete next 8 words
R - overwrite current line, starting at cursor(*) r - replace character at cursor 
s - substitute for character at cursor (*)        8s - substitute for next 8 characters (*)        
S - substitute for entire line (*)                J - join two lines together
. - repeats previous edit command                 xp - transpose two characters
easESC - add a plural, and go back to command mode

(*) - leaves you in insert mode until you hit ESC key
Undo [Important enough to have its own section (at least for me!)]

u: undo previous edit

Simple Searches

/where    - search forward for the string 'where'
?where    - search backward for the string 'where'
n         - search in the same direction for the same string
N         - search in the reverse direction for the same string
Simple Substitutions

:g/this/s//that - replace first occurance of `this' with `that' in each line
:g/this/s//that/g - replace `this' with `that' throughout file

Storing the File

:w name  - writes file 'name'
:w! name - overwrites file 'name'
:q       - terminates editing session
:q!      - terminates editing session without storing changes
:wq      - writes changes and quits
ZZ       - same as :wq


More Advanced Commands

Marks

mk - record current location as mark k (redefines any previous mark k)
'k - return to line of mark k                `k - return to mark k
d'k - delete to line of mark k              d`k - delete to mark k
c'k - change text to line of mark k         c`k - change text to mark k
"ay'd - yank text into buffer a from cursor through line of mark d
Buffers, Cut and Paste

vi has a total of 27 buffers where you can store text. There is one for each letter of the alphabet, and an `unnamed' buffer, which is where any text you delete goes. Any deleted text pushes the contents of the unnamed buffer into buffer `1'. Anything that was in buffer `1' goes into buffer `2', etc. You access the buffers with the " key. For example, "a means 'buffer a'. To yank 4 lines into buffer k, type "k4yy These lines remain undisturbed in buffer k until you put something else into buffer k, or exit vi.

A few tricks with buffers. To append 4 lines to a buffer that already has some text, type "K4YY You can also store whatever is in your buffers into a new file by typing :w (to write out your current file), then :r newfile, and "kp to put the contents of buffer k into newfile. Note that vi forgets the contents of buffer k if you exit using :wq and then vi newfile.
Note "a means `buffer a'
yy - yank current line to unnamed buffer            "j8yy - yank 8 lines into buffer j
19yy - yank next 19 lines to unnamed buffer         "J8YY - append the next 8 lines into buffer j
p - put unnamed buffer contents after cursor                  p - recover previous edit
P - put unnamed buffer contents before cursor               "1p - recover 2nd previous edit
19dd - delete next 19 lines, and put them in unnamed buffer "7p - recover 8th previous edit
"bp - put the contents of buffer p into current file 
:11,14 ya w - yank lines 11 through 14 into buffer w
:94 pu w - put contents of buffer w after line 94
More Complex Searches and Substitutions

The :g commands are powerful and quick, though cryptic to learn. The & is my favorite. Note use of \ as escape character.
:2,8/this/s//that    - replace first occurance of `this' with `that' in lines 2 through 8
:2,$/this/s//that    - replace first occurance of `this' with `that' in lines 2 through the end
:.,'ms/this/that/g  - replace `this' with `that' throughout file from current line thru mark m
:.,$s/this/that/g   - replace `this' with `that' throughout file from current line thru the end
:g/ok/s//hi/g        - replace `ok' with `hi' throughout the file
:g/\/home\/me/s//\/r2\/you/g  - replace /home/me with /r2/you throughout the file
:g/.*/s//hi & there  - replace each entire line with 'hi', the line contents, and 'there'
:g/$/s// bye         - append the string ' bye' to the end of each line
:33,224s/^/hh/       - insert the string 'hh' at the beginning of lines 
:g/read/p            - prints all occurances of `read' [kind of like a Unix grep]
fc                   - search for the character 'c' in the current line
;                    - find the next occurance of the same character in the current line
,                    - same as ; but search backwards in the line
                       (f ; and , are not that useful in my opinion)

:abbr ph Pat Hartigan - The abbreviate command. Whenever you type 'ph' followed by a space
                        or punctuation in the file, vi will print 'Pat Hartigan'.  Could be
                        useful I guess.  Such definitions can be put into one's .exrc file.
File Manipulation

:e newfile   - begin editing 'newfile' without exiting vi (keeps buffer contents)
:r newfile   - read contents of `newfile' into current file
vi file*     - sequentially edit file1, file2, file3, etc.
:n           - edit the next file in the sequence
:!pwd        - do the Unix command 'pwd' and return to vi 
Macros, Special Characters

What to do when you want to insert CTL-C into a file? Precede it within insert mode with CTL-V. This procedure also works for adding carriage returns. Hence, a CTL-V CR will appear as a ^M in the file. This is also a way to put the escape character in a file.

Suppose you want to delete two words, jump down 3 lines, move back a word, and then do this process over and over within a file. Define these commands to an unused vi key (e.g. v) by typing
:map v 2dw3jb
then simply keep the v key depressed until you are done. To insert the string 'hi', a CR, the string 'there', then delete the second to last word in the next line and skip 2 lines, define
:map v ihiCTL-VCRthereCTL-VESC$2bdw2j

vi Options

These are read from your .exrc file if you have one. For example, if you want vi by default to not distinguish between capital and small letters in a search, put the line
set ignorecase
in your .exrc file. You can always override the defaults once in vi by typing
:set ignorecase

Examples of some potentially useful settings. The inverse of `number' is `nonumber', of `nowrapscan' is 'wrapscan', etc.

:set all          - view all current settings
:set nowrapscan   - do not wrap around file when looking for a string
:set number       - add line numbers to left of file
:set noautoindent - do not automatically indent the file
:set report=0     - always report at bottom when any number of lines are yanked
:set ignorecase   - treat capital and small letters the same when searching

Telnet Woes

Sometimes vi has a hard time recognizing the size of your window in a telnet session. A symptom is that files larger than your window size behave oddly when loading, and you don't see the entire file. To fix this, at the Unix prompt try 'resize', which should define the size of your terminal, and reopen the file with vi

If this doesn't work, you can try to reset your TERM variable from the Unix prompt. When telnetting in from a PC the first thing I do is type 'setenv TERM xterms' which seems to make everything work right. Another possibility is to use 'setenv TERM vt100', though I found that vi doesn't deal with lines > 80 chars or refresh the screen right in insert mode (you need to type a lot of 'z.' to redraw the screen) for this setting. At the Unix prompt you can fix minor annoyances like the delete key not being set right by typing 'stty ERASE {key}' where {key} is what you want for an erase key. You might also need to type 'stty echoe' to have your screen actually remove the characters you erased. Within vi you can always limit the size of your vi window to 15 lines if desired by typing 'z15'.

Changing to :ex Mode and Back

Suddenly have a : prompt, and don't know what to do? Typing with mittens on? You are in ex mode. To return to vi at the colon prompt, type vi

To get to ex-mode (: prompt) from vi (why would you want to do this?) type Q

Crash Recovery

Try `vi -r filename' to recover the changes made if the computer crashes while you are editing.