The remainder of the tutorial can

Found at: gopher.black:70/archive/vi/vi.advanced

Section 26: Index to the rest of the tutorial

The remainder of the tutorial can be perused at your leisure.  Simply find the
topic of interest in the following list, and {/Section xx:/^M} to get to the
appropriate section.  (Remember that ^M means the return key) 

The material in the following sections is not necessarily in a bottom up
order.  It should be fairly obvious that if a section mentions something with
Another point to remember is that commands are surrounded by curly-braces and
can therefore be found rather easily.  To see where, say, the X command is
used try {/{X}/^M}.  Subsequent {n} will show you other places the command was
used.  We have tried to maintain the convention of placing the command letter

Finally, you should have enough 'savvy' at this point to be able to do your
own experimentation with commands without too much hand-holding on the part of
the tutorial.  Experimentation is the best way to learn the effects of the

 Section      Topic - description
 -------      -------------------
(Sections 1 through 25 are located in the file vi.beginner.)
    1         introduction: {^F} {ZZ}
    2         introduction (con't) and positioning: {^F} {^B}
    3         introduction (con't) and positioning: {^F} {^B}
    4         positioning: {^F} {^B} ^M (return key)
    5         quitting: {:q!} ^M key
    6         marking, cursor and screen positioning: {m} {G} {'} {z}
    7         marking, cursor and screen positioning: {m} {G} {'} {z}
    8         marking, cursor and screen positioning: {z} {m} {'}
    9         marking and positioning: {m} {''}
   10         line positioning: {^M} {-}
   11         scrolling with {^M}
   12         scrolling with {-} and screen adjustment {z}
   13         notes on use of tutorial
   14         other scrolling and postioning commands: {^E} {^Y} {^D} {^U}
   15         searching: {/ .. /^M}
   16         searching: {? .. ?^M} {n} (in search strings ^ $)
   17         searching: \ and magic-characters in search strings
   18         colon commands, exiting: {:} {ZZ}
   19         screen positioning: {H} {M} {L}
   20         character positioning: {w} {b} {0} {W} {B} {e} {E} {'} {`}
   21         cursor positioning: {l} {k} {j} {h}
   22         adding text: {i} {a} {I} {A} {o} {O} ^[ (escape key)
   23         character manipulation: {f} {x} {X} {w} {l} {r} {R} {s} {S} {J}
   24         undo: {u} {U}
   25         review
(The following sections are in this file.)
   26         Index to the rest of the tutorial ******** YOU ARE HERE *******
   27         discussion of repeat counts and the repeat command: {.}
   28         more on low-level character motions: {t} {T} {|}
   29         advanced correction operators: {d} {c}
   30         updating the screen: {^R}
   31         text buffers: {"}
   32         rearranging and duplicating text: {p} {P} {y} {Y}
   33         recovering lost lines
   34         advanced file manipulation with vi
   34.1          more than one file at a time: {:n}
   34.2          reading files and command output: {:r}
   34.3          invoking vi from within vi: {:e} {:vi}
   34.4          escaping to a shell: {:sh} {:!}
   34.5          writing parts of a file: {:w}
   34.6          filtering portions of text: {!}
   35         advanced searching: magic patterns 
   36         advanced substitution: {:s} 
   37         advanced line addressing: {:p} {:g} {:v}
   38         higher level text objects and nroff: ( ) { } [[ ]]
   39         more about inserting text
   40         more on operators: {d} {c} {<} {>} {!} {=} {y}
   41         abbreviations: {:ab}
   42         vi's relationship with the ex editor: {:}
   43         vi on hardcopy terminals and dumb terminals: open mode
   44         options: {:set} {setenv EXINIT}
   44.1          autoindent
   44.2          autoprint
   44.3          autowrite
   44.4          beautify
   44.5          directory
   44.6          edcompatible
   44.7          errorbells
   44.8          hardtabs
   44.9          ignorecase
   44.10         lisp
   44.11         list
   44.12         magic
   44.13         mesg                    
   44.14         number
   44.15         open
   44.16         optimize
   44.17         paragraphs
   44.18         prompt
   44.19         readonly
   44.20         redraw
   44.21         remap
   44.22         report
   44.23         scroll
   44.24         sections
   44.25         shell
   44.26         shiftwidth
   44.27         showmatch
   44.28         slowopen
   44.29         tabstop
   44.30         tags
   44.31         taglength
   44.32         term
   44.33         terse
   44.34         timeout
   44.35         ttytype
   44.36         warn
   44.37         window
   44.38         wrapscan
   44.39         wrapmargin
   44.40         writeany
   44.41         w300, w1200, w9600

Section 27: repetition counts and the repeat command {.}

Most vi commands will use a preceding count to affect their behavior in some
us to line 22 of the file.  For almost all of the commands, one can survive by
thinking of these leading numbers as a 'repeat count' specifying that the
command is to be repeated so many number of times.

Other commands use the repeat count slightly differently, like the {G} command

For example:

{3^D} means scroll down in the file three lines.  Subsequent {^D} OR {^U} will

{3z^M} says put line three of the file at the top of the screen, while {3z.}

{50|} moves the cursor to column fifty in the current line.

{3^F} says move forward 3 screenfulls.  This is a repetition count.  The
can't get it to work.

Try {10a+----^[}.

A very useful instance of a repetition count is one given to the '.' command,
{2.}.  If you {3dw}, you will delete three words.  A subsequent {.} will delete
three more words.  But a subsequent {2.} will delete only two words, not three
times two words.

Caveat: The author has noticed that any repetition count with {^B} will NOT
often, the editor will hang you in an infinite loop.  Please don't try it:
take my word for it.

Section 28: {t} {T} {|}

Line 13: Four score and seven years ago, our forefathers brought ...

Note that {fv} moves the cursor on/over the 'v' in 'seven'.  Do a {0} to return
to the beginning of the line and try a {tv}.  The cursor is now on/over the
first 'e' in 'seven'.  The {f} command finds the next occurrence of the
t.  {T} searches backwards, as does {F}.

Now try {60|}: the cursor is now on the 'o' in 'brought', which is the

Section 29: {d} {c}

Due to their complexity we have delayed discussion of two of the most powerful
operators in vi until now.  Effective use of these operators requires more
explanation than was deemed appropriate for the first half of the tutorial.

{d} and {c} are called operators instead of commands because they consist of
three parts: a count specification or a buffer specification (see section
#BUFFERS), the {d} or {c}, and the object or range description.  We will not
beginning of line 14:

Line 14: Euclid alone has looked on beauty bear.

Obviously, there is something wrong with this quotation.  Type {2fb} to
and observe the results.  The {cw} specifies that the change command {c} is to
operate on a word object.  More accurately, it specifies that the range of the
change command includes the next word.

Now, type {cbbeast^[}.  This specifies the range of the change command to be the

{d/look/^M}.  The search string specified the range of the delete.
Everything UP TO the word 'looking' was deleted from the line.

for these commands.  The most confusing exception to this rule is when {dd} or
{cc} is entered: they refer to the whole line.  Following is a summary of the

    suffix        will delete{d}/change{c}
    ------        ------------------------
      ^[            cancels the command
      w             the word to the right of the cursor
      W             ditto, but ignoring punctuation
      b             the word to the left of the cursor
      B             ditto, but ignoring punctuation
      e             see below.
      E               ditto
      (space)       a character
      $             to the end of the line
      ^             to the beginning of the line
      / .. /        up to, but not including, the string
      ? .. ?        back to and including the string
      fc            up to and including the occurrence of c 
      Fc            back to and including the occurrence of c
      tc            up to but not including the occurrence of c
      Tc            back to but not including the occurrence of c
      ^M            TWO lines (that's right: two)
      (number)^M    that many lines plus one
      (number)G     up to and including line (number)
      (             the previous sentence if you are at the beginning of
                    the current sentence, or the current sentence up to where 
                    you are if you are not at the beginning of the current 
                    sentence.  Here, 'sentence' refers to the intuitive
                    notion of an English sentence, ending with '!', '?',
                    or '.' and followed by an end of line or two spaces.
      )             the rest of the current sentence
      {             analogous to '(', but in reference to paragraphs:
                    sections of text surrounded by blank lines
      }             analogous to ')', but in reference to paragraphs
      [[            analogous to '(', but in reference to sections
      ]]            analogous to ')', but in reference to sections
      H             the first line on the screen
      M             the middle line on the screen
      L             the last line on the screen
      3L            through the third line from the bottom of the screen
      ^F            forward a screenful
      ^B            backward a screenful
      :  etc. etc. etc.

This list is not exhaustive, but it should be sufficient to get the idea
across: after the {c} or {d} operator, you can specify a range with another
move-the-cursor command, and that is the region of text over which the command

Section 30: updating the screen {^R}

Vi tries to be very intelligent about the type of terminal you are working on
and tries to use the in-terminal computing power (if any) of your terminal.
Also if the terminal is running at a low baud rate (say 1200 or below), vi sets
various parameters to make things easier for you.  For example, if you were
s a large portion of the editor keeping track of what your screen currently
looks like, and what it would look like after a command has been executed.  Vi
then compares the two, and updates only those portions of the screen that have

Furthermore, some of you may have noticed (it depends on your terminal) that 
meaning that this line of the screen does not correspond to any line in your
file. It would cost more to update the line than to leave it blank for the
moment.  If you would like to see your screen fully up-to-date with the
contents of your file, type {^R}.

To see it in action, delete several lines with {5dd}, type {^R}, and then type
{u} to get the lines back.

Here is as good a place as any to mention that if the editor is displaying the
end of your file, there may be lines on the screen that look like: 
ndicating that that screen line would not be affected by {^R}.  These lines

Section 31: text buffers {"}

Vi gives you the ability to store text away in "buffers".  This feature is very
convenient for moving text around in your file.  There are a total of thirty-
five buffers available in vi.  There is the "unnamed" buffer that is used by all
commands that delete text, including the change operator {c}, the substitute
and replace commands {s} and {r}, as well as the delete operator {d} and delete
commands {x} and {X}.  This buffer is filled each time any of these commands
are used. However, the undo command {u} has no effect on the unnamed buffer.

There are twenty-six buffers named 'a' through 'z' which are available for the
user.  If the name of the buffer is capitalized, then the buffer is not
overwritten but appended to.  For example, the command {"qdd} will delete one
line and store that line in the 'q' buffer, destroying the previous contents of
the buffer.  However, {"Qdd} will delete one line of text and append that line
to the current contents of the 'q' buffer.

Finally, there are nine buffers named '1' through '9' in which the last nine
s sometimes called the unnamed buffer.

To reference a specific buffer, use the double-quote command {"} followed by
the name of the buffer.  The next two sections show how buffers can be used to

Section 32: rearranging and duplicating text: {y} {Y} {p} {P}

Line 15: A tree as lovely as a poem ...
Line 16: I think that I shall never see

Type {dd}.  Line 15 has disappeared and been replaced with the empty line (one
{u} but that would simply return it to its original location.  Obviously, the
two lines are reversed, so we want to put line 15 AFTER line 16.  This is

Now type {u} and observe that Line 15 disappears again (the put was undone

To get Line 15 where it belongs again type {dd}{p}.

Also in Line 15 note that the words 'tree' and 'poem' are reversed.  Using the
unnamed buffer again: {ft}{dw}{ma}{fp}{P}{w}{dw}{`aP} will set things aright 
(note the use of the reverse quote).

The put commands {p} and {P} do not affect the contents of the buffer.
Therefore, multiple {p} or {P} will put multiple copies of the unnamed buffer
nto your file.

Experiment with {d} and {p} on words, paragraphs, etc.  Whatever {d}

Line 17: interest apple cat elephant boy dog girl hay farmer

Our task is to alphabetize the words on line 17.  With the named buffers (and a
contrived example) it is quite easy:


of each of the words ('interest' goes in buffer "i, 'apple' goes in buffer "a,
etc.).  Now to put the words in order type:


Notice that, because 'farmer' was at the end of the line, {dw} did not include
a space after it, and that, therefore, there is no space between 'farmer' and
'girl'.  This is corrected with {Fg}{i ^[}.

This example could have been done just as easily with lines as with

You do not have to delete the text in order to put it into a buffer.  If all
you wish to do is to copy the text somewhere else, don't use {d}, rather use
the yank commands {y} or {Y}.  {y} is like {d} and {c} - an operator rather
than a command.  It, too, takes a buffer specification and a range

{Y} is designed yank lines, and not arbitrary ranges.  That is, {Y} is
equivalent to {yy} (remember that operators doubled means the current line),
and {3Y} is equivalent to {3yy}.

a sentence which partially spans more than one line, then when you put the text
back, it will be placed after the cursor (or before if you use {P}).  If the
yanked text forms whole lines, they will be put back as whole lines, without
changing the current line.  In this case, the put acts much like the {o} or {O}

The named buffers "a through "z are not affected by changing edit files.
However, the unnamed buffer is lost when you change files, so to move text from
one file to another you should use a named buffer.

Section 33: recovering lost lines

Vi also keeps track of the last nine deletes, whether you ask for it or not.
This is very convenient if you would like to recover some text that was
accidentally deleted or modified.  Position the cursor on line 18 following,
and {z^M}.

Line 18: line 1
Line 19: line 2
Line 20: line 3
Line 21: line 4
Line 22: line 5
Line 23: line 6
Line 24: line 7
Line 25: line 8
Line 26: line 9
Type {dd} nine times: now don't cheat with {9dd}!  That is totally different.

The command {"1p} will retrieve the last delete.  Furthermore, when the
numbered buffers are used, the repeat-command command {.} will increment the
buffer numbers before executing, so that subsequent {.} will recover all nine
of the deleted lines, albeit in reverse order.  If you would like to review the
last nine deletes without affecting the buffers or your file, do an undo {u}
after each put {p} and {.}:


(Obviously, buffer number 1 IS the unnamed buffer and is just the default
buffer for the modify commands.)

Section 34: advanced file manipulation: {:r} {:e} {:n} {:w} {!} {:!}

We've already looked at writing out the file you are editing with the
{:w} command.  Now let's look at some other vi commands to make editing
more efficient.

Section 34.1: more than one file at a time {:n} {:args}

Many times you will want to edit more than one file in an editing session.
editing the second, etc., vi will allow you to specify ALL files that you wish
to edit on the invocation line.  Therefore, if you wanted to edit file1 and

% vi file1 file2

out {:w^M} and then type {:n^M} to get the next file on the list.  On large

% vi *.c

and proceed to the next file, {:n!^M} forces the editor to discard the current
contents of the editor.

You can specify a new list of files after {:n}; e.g., {:n f1 f2 f3^M}.  This

You can see the current list of files being edited with {:args^M}.

Section 34.2: reading files and command output: {:r}

Typing {:r fname^M} will read the contents of file fname into the editor and

Typing {:r !cmd^M} will read the output of the command cmd and place that
output after the cursor line.

Section 34.3: invoking vi from within vi: {:e} {:vi}

To edit another file not mentioned on the invocation line, type {:e filename^M}
or {:vi filename^M}.  If you wish to discard the changes to the current file,
use the exclamation point after the command, e.g. {:e! filename^M}.

Section 34.4: escaping to a shell: {:sh} {:!} {^Z}

Occasionally, it is useful to interrupt the current editing session to perform
a UNIX task.  However, there is no need to write the current file out, exit
the editor, perform the task, and then reinvoke the editor on the same file.
One thing to do is to spin off another process.  If there are several UNIX
commands you will need to execute, simply create another shell with {:sh^M}.
At this point, the editor is put to sleep and will be reawakened when you log
out of the shell.

s the command that you wish to run.  The output of the command will come to
the terminal as normal, and will not be made part of your file.  The message
"[Hit return to continue]" will be displayed by vi after the command is
finished.  Hitting return will then repaint the screen.  Typing another
{:!cmd^M} at this point is also acceptable.

However, there is a quicker, easier way: type {^Z}.  Now this is a little
tricky, but hang in there.  When you logged into UNIX, the first program you
began communicating with was a program that is called a "shell" (i.e. it 'lays
over' the operating system protecting you from it, sort of like a considerate
character) this was the shell telling you to type your first command.  When
you typed {vi filename} for some file, the shell did not go away, it just went
to sleep.  The shell is now the parent of vi.  When you type {^Z} the editor
you can do anything that you could before including edit another file!  (The
only thing you can't do is log out: you will get the message "There are

When your business with the shell is done, type {fg} for 'foreground' and the
last process which you ^Z'd out of will be reawakened and the shell will go
back to sleep.  I will refer you to the documentation for the Berkeley shell
'csh' for more information on this useful capability.

Section 34.5: writing parts of a file: {:w}

The {:w} command will accept a range specifier that will then write only a
the cursor on the section line (e.g. {/^Section 34.5:/^M}) and {z^M}.  Now type
{^G} to find out the line number (it will be something like "line 513").  Now
{/^Section 34.6:/-1^M} to find the last line of this section, and {^G} to find
ts line number (it will be something like 542).  To write out this section of
text by itself to a separate file which we will call "sepfile", type
{:510,542w sepfile^M}.  If sepfile already exists, you will have to use the
exclamation point: {:1147,1168w! sepfile^M} or write to a different, non-
existent file.

{:!cat sepfile^M} will display the file just written, and it should be the
contents of this section.

There is an alternate method of determining the line numbers for the write.
{:set number^M} will repaint the screen with each line numbered.  When the file
s written and the numbers no longer needed, {:set nonumber^M} will remove the
numbers, and {^R} will adjust the screen.

Or, if you remember your earlier lessons about marking lines of text,
mark the beginning and ending lines.  Suppose we had used {ma} to mark the
first line of the section and {mb} to mark the last.  Then the command
{:'a,'bw sepfile^M} will write the section into "sepfile".  In general,
you can replace a line number with the 'name' of a marked line (a single-quote
followed by the letter used to mark the line)

Section 34.6: filtering portions of text: {!}

{!} is an operator like {c} and {d}.  That is, it consists of a repetition
count, {!}, and a range specifier.  Once the {!} operator is entered in its
entirety, a prompt will be given at the bottom of the screen for a UNIX
command.  The text specified by the {!} operator is then deleted and
command is then placed in your file.  For example, place the cursor at the
beginning of the following line and {z^M}:

ls -l vi.tutorial
********* marks the bottom of the output from the ls command **********

Now type {!!csh^M}.  The line will be replaced with the output from the ls
command.  The {u} command works on {!}, also.

Here is an extended exercise to display some of these capabilities.  When this
tutorial was prepared, certain auxiliary programs were created to aid in its
to fit on a single screen, particularly the first few sections.  What was
needed was a vi command that would 'format' a paragraph; that is, fill out
lines with as many words as would fit in eighty columns.  There is no such vi
command.  Therefore, another method had to be found.

Of course, nroff was designed to do text formatting.  However, it produces a
'page'; meaning that there may be many blank lines at the end of a formatted
the output from nroff.  Below are the two files used for this purpose: I refer
you to documentation on nroff and awk for a full explanation of their function.

******** contents of file f **********
nroff -i form.mac | awk "length != 0 { print }"
***** contents of file form.mac ******
.ll 79

Determine the line numbers of the two lines of file f.  They should be
under constant revision and the line numbers may change inadvertently.  Then
{:574,575w f^M}.  Do the same for the lines of file form.mac.  They will be
approximately 577 and 582.  Then {:577,582w form.mac^M}.  File f must have
execute privileges as a shell file: {:!chmod 744 f^M}.

Observe that this paragraph is
clean it up dramatically.  Position the cursor at the beginning
of this paragraph and type the following sequence of
(note that we must abandon temporarily our convention
of curly braces since the command itself contains a curly brace - we 

Here is a brief explanation of what has happened.  By typing [!}f^M] we
line) will be removed from the edit file and piped to a UNIX program called
"f".  This is a shell command file that we have created.  This shell file runs
nroff, pipes its output to awk to remove blank lines, and the output from awk
s then read back into our file in the place of the old, ratty paragraph.  The
file form.mac is a list of commands to nroff to get it to produce paragraphs
to our taste (the right margin is not justified, the line is 79 characters
long, words are not hyphenated, and three nroff characters are renamed to
avoid conflict: note that in this file, the {^G} you see there is vi's display
of the control-G character, and not the two separate characters ^ up-arrow and
G upper-case g).

This example was created before the existence of the fmt program.  I now type
[!}fmt^M] to get the same effect much faster.  Actually, I don't type those

Section 35: searching with magic patterns

The documentation available for "magic patterns" (i.e. regular expressions) is
very scanty.  The following should explain this possibly very confusing feature
of the editor.  This section assumes that the magic option is on.  To make

By "magic pattern" we mean a general description of a piece of text that the
editor attempts to find during a search.  Most search patterns consist of
for a specific string of four characters.  Let us suppose that you have
or czrd (this is not so far-fetched for touch typists).  You could {/ccrd/^M}
and {n} until there are no more of this spelling, followed by {/czrd/^M} and
{n} until there are no more of these.  Or you could {/c.rd/^M} and catch all of
them on the first pass.  Try typing {/c.rd/^M} followed by several {n} and
observe the effect.

Line 27: card cord curd ceard

When '.' is used in a search string, it has the effect of matching any single

The character '^' (up-arrow) used at the beginning of a search string means
the beginning of the line.  {/^Line 27/^M} will find the example line above,

Similarly, {/ the$/^M} will find all occurrences of the word 'the' occurring
at the end of a line.  There are several of them in this file.

Note that {:set nomagic^M} will turn off the special meaning of these magic
characters EXCEPT for '^' and '$' which retain their special meanings at the
beginning and end of a search string.  Within the search string they hold no
last character in the search string.  Let the dollar-sign be the last
character in the search string, as in {/\/ the$/^M} and observe the result.

Observe the result of {/back.*file/^M}.  This command, followed by sufficient
{n}, will show you all lines in the file that contain both the words 'back'
and 'file' on the same line.  The '*' magic character specifies that the
matched zero or more times.  In our example we specified that the words 'back'
and 'file' must appear on the same line (they may be parts of words such as
'backwards' or 'workfile') separated by any number (including zero) of

We could have specified that 'back' and 'file' are to be words by themselves by
using the magic sequences '\<' or '\>'.  E.g.  {/\.*\/^M}.  The
beginning of a word, while '\>' specifies a match at the end of a word.  By

To find all words that begin with an 'l' or a 'w', followed by an 'a' or an
'e', and ending in 'ing', try {/\<[lw][ea][a-z]*ing\>/^M}.  This will match
exactly ONE character.  The character matched will be one of the characters
enclosed in the square brackets.  The characters may be specified individually
as in [abcd] or a '-' may be used to specify a range of characters as in [a-d].
That is, [az] will match the letter 'a' OR the letter 'z', while [a-z] will
match any of the lower case letters from 'a' through 'z'.  If you would like to
match either an 'a', a '-', or a 'z', then the '-' must be escaped: [a\-z] will
match ONE of the three characters 'a', '-', or 'z'.

following will find all character sequences that do NOT begin with an
uncapitalized letter by applying a special meaning to the '^' character in
one claimed vi was consistent.)

To find all variable names (the first character is alphabetic, the remaining
characters are alphanumeric):  try {/\<[A-Za-z][A-Za-z0-9]*\>/^M}.

     ^      at beginning of pattern, matches beginning of line
     $      at end of pattern, matches end of line
     .      matches any single character
     \<     matches the beginning of a word
     \>     matches the end of a word
     [str]  matches any single character in str
     [^str] matches any single character NOT in str
     [x-y]  matches any character in the ASCII range between x and y
     *      matches any number (including zero) of the preceding pattern

Section 36: advanced substitution: {:s} 

The straightforward colon-substitute command looks like the substitute
command of most line-oriented editors.  Indeed, vi is nothing more than a
a lot of global file processing not usually found in visual oriented editors.

The colon-substitute command looks like: {:s/ .. / .. /^M} and will find the
and replace it with the pattern specified after the second slash (called,
obviously enough, the replacement pattern).  E.g. position the cursor on line

Line 28: This is an esample.

The {u} and {U} commands work for {:s}.  The first pattern (the search pattern)
may be a regular expression just as for the search command (after all, it IS a
try the following substitute, which will do almost the same thing: 
{:s/s[^ ]/x/^M}.  
Better undo it with {u}.  The first pattern {s[^ ]} matches an 's'
NOT followed by a blank: the search therefore ignores the 's'es in 'This' and
'is'.  However, the character matched by {[^ ]} must appear in the replacement
Therefore, vi (really ex) has a duplication mechanism to copy patterns matched
n the search string into the replacement string.  Line 29 below is a copy of
line 28 above so you can adjust your screen.

Line 29: This is an esample.

t in the replacement pattern as \n, where n is a digit.  The problem outlined
n the previous paragraph is solved with {:s/s\([^ ]\)/x\1/^M}: try it.  Here
\1 refers to the first pattern grouping \( .. \) in the search string.

Obviously, for a single line, this is rather tedious.  Where it becomes
lines.  (See the next section for a particularly comprehensive example.)

the replacement pattern, then the unescaped character '&' can be used.  On
Line 29 above, try {:s/an e.ample/not &/^M}.  If another line is to have the

One other useful replacement pattern allows you to change the case of
ndividual letters.  The sequences {\u} and {\l} cause the immediately
following character in the replacement to be converted to upper- or lower-case,
of the replacement pattern.

For example, position the cursor on a line: pick a line, any line.  Type
{:s/.*/\U&/^M} and observe the result.  You can undo it with {u}.

The search pattern may actually match more than once on a single line.
However, only the first pattern is substituted.  If you would like ALL
on the line of 123 with 456.

Section 37: advanced line addressing: {:p} {:g} {:v}

Ex (available through the colon command in vi) offers several methods for
them, wait for you to [Hit return to continue], and leave you on line 100.
Obviously, it would be easier just to do {100G} from within vi.  But
addressing is important and powerful.

Line 30: This is a text.
Line 31: Here is another text.
Line 32: One more text line.

The lines above contain a typing error that the author of this tutorial tends
to make every time he attempts to type the word 'test'.  To change all of these
'text's into 'test's, try the following:
{:/^Line 30/,/^Line 32/s/text/test/^M}.  This finds the beginning and end of
the portion of text to be changed, and limits the substitution to each of the
lines in that range.  The {u} command applies to ALL of the substitutions as 
a group.

This provides a mechanism for powerful text manipulations.
And very complicated examples.

Line 33: This test is a.
Line 34: Here test is another.
Line 35: One line more test.

The above three lines have the second word out of order.  The following command
long, full of special characters, and easy to mess up.  You may want to
consider reading the following section to understand it before trying the
experiment.  Don't worry about messing up the rest of the file, though: the
address range is specified.

{:/^Line 33/,/^Line 35/s/\([^:]*\): \([^ ]*\) \([^ ]*\) \([^.]*\)/\1: \2 \4 \3/^M}

There are several things to note about this command string.  First of all, the
line numbers directly, and then, in place of the two searches, typed
the line numbers, e.g. {1396,1398}.  Or to mark the lines with {ma} and {mb}
and use {'a,'b}.

Then follows the substitute pattern itself.  To make it easier to understand

     s/\([^:]*\): \([^ ]*\) \([^ ]*\) \([^.]*\)/\1: \2 \4 \3/
       |--\1---|  |--\2---| |--\3---| |--\4---|
      |--------search pattern------------------|-replacement|

by stating what they are NOT.  Pattern \1 is the sequence of characters that
are NOT colons: in the search string, {[^:]} will match exactly one character
that is not a colon, while appending the asterisk {[^:]*} specifies that the
'not a colon' pattern is to be repeated until no longer satisfied, and
{\([^:]*\)} then gives the pattern its name, in this case \1.  Outside of the
a colon followed by a blank.

not blanks.  Pattern \4 matches up to the period at the end of the line.

The replacement pattern then consists of specifying the new order of the

This is a particularly complicated example, perhaps the most complicated
n this tutorial/reference.  For our small examples, it is obviously
tedious and error prone.  For large files, however, it may be the most
efficient way to make the desired modifications.

(The reader is advised to look at the documentation for awk.  This tool is very
manipulation.  But, it is another command language to learn.)

Many times, you will not want to operate on every line in a certain
certain patterns; e.g. for every line that has the string 'NPS' on it,
change 'NPS' to 'Naval Postgraduate School'.  The {:g} addressing
command was designed for this purpose.  The example of this paragraph
could be typed as {:g/NPS/s//Naval Postgraduate School/^M}.

The general format of the command is {:g/(pattern)/cmds^M} and it
following the {:g} are 'tagged' in a special way.  Then each of these
lines have the commands following the pattern executed over them.

Line 36: ABC rhino george farmer Dick jester lest
Line 37: george farmer rhino lest jester ABC
Line 38: rhino lest george Dick farmer ABC jester 


{:g/^Line.*ABC/s/Dick/Harry Binswanger/|s/george farmer/gentleman george/p^M}

There are several things of note here.  First, lines 36, 37, and 38 above are
tagged by the {:g}.  Type {:g/^Line.*ABC/p^M} to verify this.  Second, there
are two substitutes on the same line separated by '|'.  In general, any colon
commands can be strung together with '|'.  Third, both substitutes operate on
all three lines, even though the first stubstitute works on only two of the
lines (36 and 38).  Fourth, the second substitute works on only two lines (36
and 37) and those are the two lines printed by the trailing 'p'.

The {:v} command works similarly to the {:g} command, except that the sense of
the test for 'tagging' the lines is reversed: all lines NOT matching the search

Using {^V} to quote carriage return (see section 39) can be used in global
{:g/\.  /s//.^V^M/g^M} will change your file so that each sentence is on a 
matches any character.  Our command says to find any line which contains a 

Caveat:  In some of the documentation for ex and vi you may find the
comment to the effect that {\^M} can be used between commands following
{:g}.  The author of this tutorial has never gotten this to work and has
crashed the editor trying.

Section 38: higher level text objects and nroff: {(} {)} [{] [}] {[[} {]]}

(Note: this section may be a little confusing because of our command
notation.  Using curly braces to surround command strings works fine as
long as the command string does not contain any curly braces itself.
However, the curly braces are legitimate commands in vi.  Therefore, for
any command sequence that contains curly braces, we will surround that

the beginning of the previous and next sentences, respectively.  Thus
the command {d)} will delete the rest of the current sentence; likewise
{d(} will delete the previous sentence if you are at the beginning of
the current sentence, or, if you are not at the beginning of a sentence,
t will delete the current sentence from the beginning
up to where you are.

A sentence is defined to end at a '.', '!', or '?' which is followed
by either the end of a line, or by two spaces.  Any number of closing
')', ']', '"', and ''' characters may appear after the '.', '!', or '?'
before the spaces or end of line.  Therefore, the {(} and {)} commands

Line 39: This is one sentence. Even though it looks like two.
Line 40: This is two sentences.  Because it has two spaces after the '.'.

The operations [{] and [}] move over paragraphs and the operations {[[}
and {]]} move over sections.

A paragraph begins after each empty line, and also at each of a set of nroff
first column, and at each of a set of nroff section macros.  When preparing a
text file as input to nroff, you will probably be using a set of nroff macros
to make the formatting specifications easier, or more to your taste.  These
macros are invoked by beginning a line with a period followed by the one or two
letter macro name. Vi has been programmed to recognize these nroff macros, and
f it doesn't recognize your particular macro you can use the {:set paragraphs}
or {:set sections} commands so that it will.

Section 39: more about inserting text

There are a number of characters which you can use to make correnctions

    ^H      deletes the last input character
    ^W      deletes the last input word
    (erase) same as ^H; each terminal can define its own erase character; 
            for some it is ^H, for others it is the DELETE key, and for
            others it is '@'.
    (kill)  deletes the input on this line; each terminal can define its
            own line-kill character; for some it is ^U, for others it is
            '@'; you will need to experiment on your terminal to find
            out what your line-kill and erase characters are.
    \       escapes a following ^H, (kill), and (erase) characters: i.e.
            this is how to put these characters in your file.
    ^[      escape key; ends insertion mode
    ^?      the delete key; interrupts an insertion, terminating it
    ^M      the return key; starts a new line.
    ^D      backtabs over the indentation set by the autoindent option
    0^D     backtabs over all indentation back to the beginning of the line
    ^^D     (up-arrow followed by control-d)same as 0^D, except the indentation 
	    will be restored at the beginning of the next line.
    ^V      quotes the next non-printing character into the file

must precede it with a \, just as you would do at the normal system command
level.  A more general way of typing non-printing characters into the file is
to precede them with a ^V.  The ^V echoes as a ^ character on which the cursor
and it will be inserted into the file at that point.  There are a few
exceptions to note.  The implementation of the editor does not allow the null
character ^@ to appear in files.  Also the linefeed character ^J is used by the
editor to separate lines in the file, so it cannot appear in the middle of a
line.  (Trying to insert a ^M into a file, or putting it in the replacement 
two.  This, in effect, is how to split lines by using a substitution.)  You can 
nsert any other character, however, if you wait for the editor to echo the ^
before you type the character.  In fact, the editor will treat a following 
letter as a request for the corresponding control character.  This is the only 
output and never gives them to the editor to process.

When you are using the autoindent option you may wish to place a label at the
left margin of a line.  The way to do this easily is to type ^ (up-arrow) and
then ^D.  The editor will move the cursor to the left margin for one line, and
mmediately by a ^D if you wish to kill all indentation and not have it resume
on the next line.

Section 40: more on operators: {d} {c} {<} {>} {!} {=} {y}

Below is a non-exhaustive list of commands that can follow the operators
to affect the range over which the operators will work.  However, note
that the operators {<}, {>}, {!}, and {=} do not operate on any object
less than a line.  Try {!w} and you will get a beep.  To get the
operator to work on just the current line, double it.  E.g. {<<}.

    suffix        will operate on
    ------        ------------------------
      ^[            cancels the command
      w             the word to the right of the cursor
      W             ditto, but ignoring punctuation
      b             the word to the left of the cursor
      B             ditto, but ignoring punctuation
      e             see below.
      E               ditto
      (space)       a character
      $             to the end of the line
      ^             to the beginning of the line
      / .. /        up to, but not including, the string
      ? .. ?        back to and including the string
      fc            up to and including the occurrence of c 
      Fc            back to and including the occurrence of c
      tc            up to but not including the occurrence of c
      Tc            back to but not including the occurrence of c
      ^M            TWO lines (that's right: two)
      (number)^M    that many lines plus one
      (number)G     up to and including line (number)
      (             the previous sentence if you are at the beginning of
                    the current sentence, or the current sentence up to where 
                    you are if you are not at the beginning of the current 
                    sentence.  Here, 'sentence' refers to the intuitive
                    notion of an English sentence, ending with '!', '?',
                    or '.' and followed by an end of line or two spaces.
      )             the rest of the current sentence
      {             analogous to '(', but in reference to paragraphs:
                    sections of text surrounded by blank lines
      }             analogous to ')', but in reference to paragraphs
      [[            analogous to '(', but in reference to sections
      ]]            analogous to ')', but in reference to sections
      H             the first line on the screen
      M             the middle line on the screen
      L             the last line on the screen
      3L            through the third line from the bottom of the screen
      ^F            forward a screenful
      ^B            backward a screenful
      :  etc. etc. etc.

This list is not exhaustive, but it should be sufficient to get the idea
across: after the operator, you can specify a range with a move-the-cursor
command, and that is the region of text over which the operator will be

Section 41: abbreviations: {:ab}

When typing large documents you may find yourself typing a large phrase
over and over.  Vi gives you the ability to specify an abbreviation for
a long string such that typing the abbreviation will automatically
expand into the longer phrase.

Type {:ab nps Naval Postgraduate School^M}.  Now type:

{iThis is to show off the nps's UNIX editor.^M^[}

Section 42: vi's relationship with the ex editor: {:}

Vi is actually one mode of editing within the editor ex.  When you are
the command {Q}.  All of the colon-commands which were introduced above
are available in ex.  Likewise, most ex commands can be invoked from vi
using {:}.   

then save your work and quit if you wish by giving the command {x} after
the colon prompt of ex.  Or you can reenter vi (if you are brave) by

Section 43: vi on hardcopy terminals and dumb terminals: open mode

(The author has not checked the following documentation for accuracy.  It is
abstracted from the Introduction to Vi Editing document.)

but in a different mode.  When you give the vi command to UNIX, the editor will
tell you that it is using open mode.  This name comes from the open command in
ex, which is used to get into the same mode.

The only difference between visual mode (normal vi) and open mode is the way in

backward and forward in the file causes new lines to be displayed, always below
the current line.  Two commands of vi work differently in open: {z} and {^R}.
The {z} command does not take parameters, but rather draws a window of context
around the current line and then returns you to the current line.

line.  On such terminals, the editor normally uses two lines to represent the
current line.  The first line is a copy of the line as you started to edit it,
and you work on the line below this line.  When you delete characters, the
editor types a number of \'s to show you the characters which are deleted.  The
editor also reprints the current line soon after such changes so that you can

an {open} command.

Section 44: options: {:set} {setenv EXINIT}

You will discover options as you need them.  Do not worry about them very much
on the first pass through this document.  My advice is to glance through them,
noting the ones that look interesting, ignoring the ones you don't understand,
and try re-scanning them in a couple of weeks.

the default values for the editor, place a {setenv EXINIT} command in your
.login file.  When you are given an account under UNIX your directory has
commands in this file sets the environment variable EXINIT to a string of vi
commands, you can have many things done for you each time you invoke vi.  For
example, if you decide that you don't like tabstops placed every eight columns
but prefer every four columns, and that you wish the editor to insert linefeeds
for you when your typing gets you close to column 72, and you want
autoindentation, then include the following line in your .login file:

or equivalently

Each time you bring up vi, this command will be executed and the options set.

There are forty options in the vi/ex editor that the user can set for his/her
own convenience.  They are described in more detail in individual sections
below.  The section line will show the full spelling of the option name, the
abbreviation, and the default value of the option.  The text itself
comes from the ex reference manual and is not the epitome of clarity.

Section 44.1: {autoindent}, {ai} default: noai

Can be used to ease the preparation of structured program text.  At the
beginning of each append, change or insert command or when a new line is opened
or created by an append, change, insert, or substitute operation within open or
visual mode, ex looks at the line being appended after, the first line changed
or the line inserted before and calculates the amount of white space at the

the displayed indenting level.  If more white space is typed at the beginning
of a line, the following line will start aligned with the first non-white
character of the previous line.  To back the cursor up to the preceding tab
of the shiftwidth option.  You cannot backspace over the indent, except by
turns into a completely blank line (the white space provided for the autoindent
s discarded). Also specially processed in this mode are lines beginning with
an up-arrow `^' and immediately followed by a {^D}.  This causes the input to
be repositioned at the beginning of the line, but retaining the previous indent
for the next line.  Similarly, a `0' followed by a {^D} repositions at the
beginning but without retaining the previous indent.  Autoindent doesn't happen
n global commands or when the input is not a terminal.

Section 44.2: {autoprint}, {ap} default: ap

Causes the current line to be printed after each delete, copy, join, move,
trailing `p' to each such command.  Autoprint is suppressed in globals, and
only applies to the last of many commands on a line.

Section 44.3: {autowrite}, {aw} default: noaw

Causes the contents of the buffer to be written to the current file if you have
modified it and give a next, rewind, stop, tag, or {!} command, or a control-
up-arrow {^^} (switch files) or {^]} (tag goto) command in visual.  Note, that
the edit and ex commands do not autowrite.  In each case, there is an
equivalent way of switching when autowrite is set to avoid the autowrite
({edit} for next, rewind!  for rewind, stop!  for stop, tag!  for tag, shell
for {!}, and {:e #} and a {:ta!} command from within visual).

Section 44.4: {beautify}, {bf} default: nobeautify

Causes all control characters except tab ^I, newline ^M and form-feed ^L to be
character is discarded.  Beautify does not apply to command input.

Section 44.5: {directory}, {dir} default: dir=/tmp 

Specifies the directory in which ex places its buffer file.  If this directory
n not writable, then the editor will exit abruptly when it fails to be able to
create its buffer there.

Section 44.6: {edcompatible} default: noedcompatible

Causes the presence or absence of g and c suffixes on substitute commands to be
the substitution be as in the {~} command, instead of like {&}.

[Author's note: this should not concern users of vi.]

Section 44.7: {errorbells}, {eb} default: noeb

Error messages are preceded by a bell.  However, bell ringing in open and
visual modes on errors is not suppressed by setting noeb.  If possible the
editor always places the error message in a standout mode of the terminal (such
as inverse video) instead of ringing the bell.

Section 44.8: {hardtabs}, {ht} default: ht=8

Gives the boundaries on which terminal hardware tabs are set (or on which the

Section 44.9: {ignorecase}, {ic} default: noic

All upper case characters in the text are mapped to lower case in regular
expression matching.  In addition, all upper case characters in regular
expressions are mapped to lower case except in character class specifications
(that is, character in square brackets).

Section 44.10: {lisp} default: nolisp

Autoindent indents appropriately for lisp code, and the {(}, {)}, [{], [}],
{[[}, and {]]} commands in open and visual modes are modified in a

[Author's note: but don't ask me to define them precisely.]

Section 44.11: {list} default: nolist

All printed lines will be displayed (more) unambiguously, showing tabs as ^I
and end-of-lines with `$'.  This is the same as in the ex command {list}.

Section 44.12: {magic} default: magic for {ex} and {vi}, nomagic for edit.

the metacharacters `~' and `&' of the replacement pattern are treated as normal
characters.  All the normal metacharacters may be made magic when nomagic is

[Author's note: In other words, if magic is set a back-slant turns the magic
off for the following character, and if nomagic is set a back-slant turns the
magic ON for the following character.  And, no, we are not playing Dungeons and
Dragons, although I think the writers of these option notes must have played it
all the time.]

Section 44.13: {mesg} default: mesg

Causes write permission to be turned off to the terminal while you are in
visual mode, if nomesg is set.

[Author's note: I don't know if anyone could have made any one sentence

Section 44.14: {number, nu} default: nonumber

Causes all output lines to be printed with their line numbers.  In addition
each input line will be prompted with its line number.

Section 44.15: {open} default: open

edit to prevent confusion resulting from accidental entry to open or visual

[Author's note: As you may have guessed by now, there are actually three
editors available under Berkeley UNIX that are in reality the same

Section 44.16: {optimize, opt} default: optimize

Throughput of text is expedited by setting the terminal to not do automatic
carriage returns when printing more than one (logical) line of output, greatly

[Author's note: I still don't know what this option does.]

Section 44.17: {paragraphs, para} default: para=IPLPPPQPP LIbp

Specifies the paragraphs for the [{] and [}] operations in open and visual.
The pairs of characters in the option's value are the names of the nroff macros

Section 44.18: {prompt} default: prompt

Command mode input is prompted for with a `:'.

[Author's note: Doesn't seem to have any effect on vi.]

Section 44.19: {readonly}, {ro} default: noro, unless invoked with -R 
                                         or insufficient privileges on file

This option allows you to guarantee that you won't clobber your file by
accident.  You can set the option and writes will fail unless you use an `!'
after the write.  Commands such as {x}, {ZZ}, the autowrite option, and in
nvoke the editor with the -R flag.

Section 44.20: {redraw} default: noredraw

The editor simulates (using great amounts of output), an intelligent terminal
on a dumb terminal (e.g. during insertions in visual the characters to the
Useful only at very high baud rates, and should be used only if the system is
not heavily loaded: you will notice the performance degradation yourself.

Section 44.21: {remap} default: remap

s mapped to O, and O is mapped to I, then if remap is set, o will map to I,
but if noremap is set, it will map to O .

Section 44.22: {report} default: report=5 for ex and vi, 2 for edit

Specifies a threshold for feedback from commands.  Any command which modifies
more than the specified number of lines will provide feedback as to the scope
of its changes.  For commands such as global, open, undo, and visual which have
the buffer is presented at the end of the command, subject to this same
threshold.  Thus notification is suppressed during a global command on the
ndividual commands performed.

Section 44.23: {scroll} default: scroll=1/2 window

Determines the number of logical lines scrolled when a {^D} is received from a
terminal in command mode, and determines the number of lines printed by a
command mode z command (double the value of scroll).

[Author's note: Doesn't seem to affect {^D} and {z} in visual (vi) mode.]

Section 44.24: sections {sections} default: sections=SHNHH HU 

Specifies the section macros from nroff for the {[[} and {]]} operations in
open and visual.  The pairs of characters in the options's value are the names
of the macros which start paragraphs.

Section 44.25: {shell}, {sh} default: sh=/bin/sh 

Gives the path name of the shell forked for the shell escape command `!', and
by the shell command.  The default is taken from SHELL in the environment, if

[Editor's note: I would suggest that you place the following line in
your .login file:

Section 44.26: {shiftwidth}, {sw} default: sw=8 

Used in reverse tabbing with {^D} when using autoindent to append text, and
used by the shift commands.  Should probably be the same value as the tabstop

Section 44.27: {showmatch}, {sm} default: nosm 

s on the screen, move the cursor to it for one second.  Extremely useful with
complicated nested expressions, or with lisp.

Section 44.28: {slowopen}, {slow} default: terminal dependent

Affects the display algorithm used in visual mode, holding off display updating
more details.

Section 44.29: {tabstop}, {ts} default: ts=8

The editor expands tabs ^I to tabstop boundaries in the display.

Section 44.30: {taglength}, {tl} default: tl=0

Tags are not significant beyond this many characters.
A value of zero (the default) means that all characters are significant.

Section 44.31: {tags} default: tags=tags /usr/lib/tags

A path of files to be used as tag files for the tag command.  A requested tag
s searched for in the specified files, sequentially.  By default files called
tags are searched for in the current directory and in /usr/lib (a master file
for the entire system).

[Author's note: The author of this tutorial has never used this option, nor

Section 44.32: {term} default: from environment variable TERM

The terminal type of the output device.

Section 44.33: {terse} default: noterse

Shorter error diagnostics are produced for the experienced user.

Section 44.34: {timeout} default: timeout

Causes macros to time out after one second.  Turn it off and they will
your terminal sends escape sequences for arrow keys, it will be
necessary to hit escape twice to get a beep.

[Editor's note: Another paragraph which requires a cryptographer.]

Section 44.35: ttytype

[Editor's note: I have found no documentation for this option at all.]

Section 44.36: {warn} default: warn

Warn if there has been `[No write since last change]' before a `!' command

Section 44.37: {window} default: window=speed dependent

The number of lines in a text window in the visual command.  The default is 8
at slow speeds (600 baud or less), 16 at medium speed (1200 baud), and the full

Section 44.38: {wrapscan}, {ws} default: ws

Searches using the regular expressions in addressing will wrap around past the
end of the file.

Section 44.39: {wrapmargin}, {wm} default: wm=0

Defines a margin for automatic wrapover of text during input in open and visual
modes.  The numeric value is the number of columns from the right edge of the
character (wm=0 is OFF).  This is very convenient for touch typists.
Wrapmargin behaves much like fill/nojustify mode does in nroff.

Section 44.40: {writeany}, {wa} default: nowa

file which the system protection mechanism will allow.

Section 44.41: {w300}, {w1200}, {w9600} defaults: w300=8
                                                 w9600=full screen minus one

These are not true options but set the default size of the window for when the

Section 45: Limitations

Here are some editor limits that the user is likely to encounter:
       1024   characters per line
       256    characters per global command list
       128    characters per file name
       128    characters in the previous inserted and deleted text in open or 
       100    characters in a shell escape command
       63     characters in a string valued option
       30     characters in a tag name
       250000 lines in the file (this is silently enforced).

The visual implementation limits the number of macros defined with map to 32,
and the total number of characters in macros to be less than 512.

[Editor's note: these limits may not apply to versions after 4.1BSD.]