mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-30 15:38:06 +01:00
18fd508d01
right ;). Reviewed by: Sean Eric Fagan
1459 lines
69 KiB
Plaintext
1459 lines
69 KiB
Plaintext
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
|
||
which you are not familiar, say, buffers, you might {/buffer/^M} followed by
|
||
several {n} to do a keyword search of the file for more details on that item.
|
||
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
|
||
surrounded by curly-braces on the section line where that command is
|
||
mentioned.
|
||
|
||
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
|
||
commands.
|
||
|
||
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
|
||
way. We have already seen how {3x} deletes three characters, and {22G} moves
|
||
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
|
||
which use it as a line number.
|
||
|
||
For example:
|
||
|
||
{3^D} means scroll down in the file three lines. Subsequent {^D} OR {^U} will
|
||
scroll only three lines in their respective directions!
|
||
|
||
{3z^M} says put line three of the file at the top of the screen, while {3z.}
|
||
says put line three as close to the middle of the screen as possible.
|
||
|
||
{50|} moves the cursor to column fifty in the current line.
|
||
|
||
{3^F} says move forward 3 screenfulls. This is a repetition count. The
|
||
documents advertise that {3^B} should move BACK three screenfulls, but I
|
||
can't get it to work.
|
||
|
||
Position the cursor on some text and try {3r.}. This replaces three characters
|
||
with '...'. However, {3s.....^[} is the same as {3xi.....^[}.
|
||
|
||
Try {10a+----^[}.
|
||
|
||
A very useful instance of a repetition count is one given to the '.' command,
|
||
which repeats the last 'change' command. If you {dw} and then {3.}, you will
|
||
delete first one and then three words. You can then delete two more words with
|
||
{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
|
||
work: indeed, if you are at the end of your file and try {3^B} sufficiently
|
||
often, the editor will hang you in an infinite loop. Please don't try it:
|
||
take my word for it.
|
||
|
||
Section 28: {t} {T} {|}
|
||
|
||
Position the cursor on line 13 below:
|
||
|
||
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
|
||
specified letter and moves the cursor to it. The {t} command finds the
|
||
specified letter and moves the cursor to the character immediately preceding
|
||
it. {T} searches backwards, as does {F}.
|
||
|
||
Now try {60|}: the cursor is now on the 'o' in 'brought', which is the
|
||
sixtieth character on the line.
|
||
|
||
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
|
||
discuss buffers at this stage, but will limit ourselves to count
|
||
specifications. Examples speak louder than words: position the cursor at the
|
||
beginning of line 14:
|
||
|
||
Line 14: Euclid alone has looked on beauty bear.
|
||
|
||
Obviously, there is something wrong with this quotation. Type {2fb} to
|
||
position the cursor on the 'b' of 'bear'. Now, type {cwbare^[}
|
||
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.
|
||
|
||
Position the cursor on the period in Line 14. (one way is to use {f.})
|
||
Now, type {cbbeast^[}. This specifies the range of the change command to be the
|
||
previous word (the 'b' reminiscent of the {b} command). If we had wished to
|
||
delete the word rather than change it, we would have used the {d} operator,
|
||
rather than the {c} operator.
|
||
|
||
Position the cursor at the beginning of the line with {0}. Type
|
||
{d/look/^M}. The search string specified the range of the delete.
|
||
Everything UP TO the word 'looking' was deleted from the line.
|
||
|
||
In general, almost any command that would move the cursor will specify a range
|
||
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
|
||
suffixes (suffices? suffici?) and the ranges they specify:
|
||
|
||
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
|
||
will be effective.
|
||
|
||
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
|
||
running on a 300 baud terminal (that's 30 characters per second transmission
|
||
rate) not all 24 lines of the screen would be used by vi. In addition, there
|
||
is 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
|
||
changed.
|
||
|
||
Furthermore, some of you may have noticed (it depends on your terminal) that
|
||
deleting lines or changing large portions of text may leave some lines on the
|
||
screen looking like:
|
||
@
|
||
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:
|
||
~
|
||
indicating that that screen line would not be affected by {^R}. These lines
|
||
simply indicate the end of the file.
|
||
|
||
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
|
||
deletes are stored. Buffer 1 is the default buffer for the modify commands and
|
||
is 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
|
||
advantage.
|
||
|
||
Section 32: rearranging and duplicating text: {y} {Y} {p} {P}
|
||
|
||
Position yourself on line 15 below and {z^M}:
|
||
|
||
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
|
||
with the single character @ on it) or (again depending on your terminal) Line
|
||
16 has moved up and taken its place. We could recover Line 15 with an undo
|
||
{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
|
||
simply done with the put command {p}, which you should type now. What has
|
||
happened is that {dd} put Line 15 into the unnamed buffer, and the {p} command
|
||
retrieved the line from the unnamed buffer.
|
||
|
||
Now type {u} and observe that Line 15 disappears again (the put was undone
|
||
without affecting the unnamed buffer). Type {P} and see that the capital {P}
|
||
puts the line BEFORE the cursor.
|
||
|
||
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
|
||
into your file.
|
||
|
||
Experiment with {d} and {p} on words, paragraphs, etc. Whatever {d}
|
||
deletes, {p} can put.
|
||
|
||
Position the cursor on Line 17 and {z^M}:
|
||
|
||
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:
|
||
|
||
{"idw}{"adw}{"cdw}{"edw}{"bdw}{"ddw}{"gdw}{"hdw}{"fdw}
|
||
|
||
stores each of the words in the named buffer corresponding to the first letter
|
||
of each of the words ('interest' goes in buffer "i, 'apple' goes in buffer "a,
|
||
etc.). Now to put the words in order type:
|
||
|
||
{"ap$}{"bp$}{"cp$}{"dp$}{"ep$}{"fp$}{"gp$}{"hp$}{"ip$}
|
||
|
||
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
|
||
words.
|
||
|
||
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
|
||
specification. Therefore, instead of {dw}{P} to load the unnamed buffer with a
|
||
word without deleting the word, use {yw} (yank a word).
|
||
|
||
{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}.
|
||
|
||
If the text you yank or modify forms a part of a line, or is an object such as
|
||
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}
|
||
command.
|
||
|
||
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 {.}:
|
||
|
||
{"1p}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}{u}{.}
|
||
|
||
will show you all the buffers and leave them and your file intact.
|
||
|
||
If you had cheated above and deleted the nine lines with {9dd}, all nine lines
|
||
would have been stored in both the unnamed buffer and in buffer number 1.
|
||
(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.
|
||
Instead of entering vi and editing the first file, exiting, entering vi and
|
||
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
|
||
file2:
|
||
|
||
% vi file1 file2
|
||
|
||
will set up file1 for editing. When you are done editing file one, write it
|
||
out {:w^M} and then type {:n^M} to get the next file on the list. On large
|
||
programming projects with many source files, it is often convenient just to
|
||
specify all source files with, say:
|
||
|
||
% vi *.c
|
||
|
||
If {:n^M} brings in a file that does not need any editing, another {:n^M}
|
||
will bring in the next file.
|
||
|
||
If you have made changes to the first file, but decide to discard these changes
|
||
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
|
||
will replace the current list of files (if any).
|
||
|
||
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
|
||
put the contents AFTER the cursor line.
|
||
|
||
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.
|
||
|
||
If it is a single command that you want to execute, type {:!cmd^M}, where cmd
|
||
is 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
|
||
porcupine). When you got your first prompt on the terminal (probably a '%'
|
||
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
|
||
goes to sleep, the shell wakes up and says "you rang?" in the form of another
|
||
prompt (probably '%'). At this point you are talking to the shell again and
|
||
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
|
||
stopped jobs.")
|
||
|
||
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
|
||
selected range of lines to a file. To write this section to a file, position
|
||
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
|
||
its 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
|
||
is 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
|
||
passed/filtered/piped to the UNIX command you type. The output of the UNIX
|
||
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
|
||
development. Of major concern was the formatting of sections of the tutorial
|
||
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
|
||
paragraph from nroff. The awk program was used to strip these blank lines from
|
||
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.
|
||
Position the cursor on the next line and {z^M}.
|
||
|
||
******** contents of file f **********
|
||
#
|
||
nroff -i form.mac | awk "length != 0 { print }"
|
||
***** contents of file form.mac ******
|
||
.na
|
||
.nh
|
||
.ll 79
|
||
.ec
|
||
.c2
|
||
.cc
|
||
**************************************
|
||
|
||
Determine the line numbers of the two lines of file f. They should be
|
||
something like 574 and 575, although you better double check: this file is
|
||
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
|
||
rather ratty in appearance. With our newly created files we can
|
||
clean it up dramatically. Position the cursor at the beginning
|
||
of this paragraph and type the following sequence of
|
||
characters
|
||
(note that we must abandon temporarily our convention
|
||
of curly braces since the command itself contains a curly brace - we
|
||
will use square brackets for the nonce): [!}f^M].
|
||
|
||
Here is a brief explanation of what has happened. By typing [!}f^M] we
|
||
specified that the paragraph (all text between the cursor and the first blank
|
||
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
|
||
is 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
|
||
six keys each time: I have an abbreviation (which see).
|
||
|
||
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
|
||
sure, you might want to type {:set magic^M}.
|
||
|
||
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
|
||
strings of characters that must be matched exactly, e.g. {/card/^M} searches
|
||
for a specific string of four characters. Let us suppose that you have
|
||
discovered that you consistently have mistyped this simple word as either ccrd
|
||
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
|
||
character.
|
||
|
||
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,
|
||
while {/Line 27/^M} will find an occurrence of this string anywhere in the
|
||
line.
|
||
|
||
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
|
||
special meaning. Try {/\/ the$\//^M} and note that the dollar-sign is not the
|
||
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
|
||
previous regular expression (the '.' in our example) is to be repeatedly
|
||
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
|
||
characters.
|
||
|
||
We could have specified that 'back' and 'file' are to be words by themselves by
|
||
using the magic sequences '\<' or '\>'. E.g. {/\<back\>.*\<file\>/^M}. The
|
||
sequence '\<' specifies that this point of the search string must match the
|
||
beginning of a word, while '\>' specifies a match at the end of a word. By
|
||
surrounding a string with these characters we have specified that they must be
|
||
words.
|
||
|
||
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
|
||
words like 'learning', 'warning', and 'leading'. The '[..]' notation matches
|
||
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'.
|
||
|
||
If you wish to find all Capitalized words, try {/\<[A-Z][a-z]*\>/^M}. The
|
||
following will find all character sequences that do NOT begin with an
|
||
uncapitalized letter by applying a special meaning to the '^' character in
|
||
square brackets: {/\<[^a-z][a-z]*\>/^M}. When '^' is the first character of a
|
||
square-bracket expression, it specifies "all but these characters". (No
|
||
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}.
|
||
|
||
In summary, here are the primitives for building regular expressions:
|
||
|
||
^ 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
|
||
superstructure on the line-oriented editor ex and the colon commands are
|
||
simply a way of accessing commands within ex (see section #EX). This gives us
|
||
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
|
||
pattern specified after the first slash (this is called the search pattern),
|
||
and replace it with the pattern specified after the second slash (called,
|
||
obviously enough, the replacement pattern). E.g. position the cursor on line
|
||
28 below and {:s/esample/example/^M}:
|
||
|
||
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
|
||
search, albeit limited to the current line). Do an {u} on the above line, and
|
||
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
|
||
pattern. But, in general, we do not know what that character is! (In this
|
||
particular example we obviously do, but more complicated examples will follow.)
|
||
Therefore, vi (really ex) has a duplication mechanism to copy patterns matched
|
||
in 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.
|
||
|
||
In general, you can nest parts of the search pattern in \( .. \) and refer to
|
||
it in the replacement pattern as \n, where n is a digit. The problem outlined
|
||
in 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
|
||
powerful, if not necessary, is in colon-substitutes that cover a range of
|
||
lines. (See the next section for a particularly comprehensive example.)
|
||
|
||
If the entire character sequence matched by the search pattern is needed in
|
||
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
|
||
word 'not' prepended to a pattern, then '~' can save you from re-typing the
|
||
replacement pattern. E.g. {:s/some pattern/~/^M} after the previous example
|
||
would be equivalent to {:s/some pattern/not &/^M}.
|
||
|
||
One other useful replacement pattern allows you to change the case of
|
||
individual letters. The sequences {\u} and {\l} cause the immediately
|
||
following character in the replacement to be converted to upper- or lower-case,
|
||
respectively, if this character is a letter. The sequences {\U} and {\L} turn
|
||
such conversion on, either until {\E} or {\e} is encountered, or until the end
|
||
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
|
||
patterns matched on the line to be substituted, append a 'g' after the
|
||
replacement pattern: {:s/123/456/g^M} will substitute EVERY occurrence
|
||
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
|
||
specifying the lines on which a set of commands will act. For example, if you
|
||
would like to see lines 50 through 100 of your file: {:50,100p^M} will display
|
||
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
|
||
what if you would like to make changes to just those lines? Then the
|
||
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
|
||
string will put things right. Be very careful when typing this: it is very
|
||
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
|
||
range of the substitute was limited by the address specification {/^Line
|
||
33/,/^Line 35/^M}. It might have been simpler to do {:set number^M} to see 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
|
||
what the substitute is doing, the command is duplicated below with the various
|
||
patterns named for easier reference:
|
||
|
||
s/\([^:]*\): \([^ ]*\) \([^ ]*\) \([^.]*\)/\1: \2 \4 \3/
|
||
|--\1---| |--\2---| |--\3---| |--\4---|
|
||
|--------search pattern------------------|-replacement|
|
||
|--pattern---|
|
||
|
||
In overview, the substitute looks for a particular pattern made up of
|
||
sub-patterns, which are named \1, \2, \3, and \4. These patterns are specified
|
||
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
|
||
specification of \1 comes {: }, specifying that the next two characters must be
|
||
a colon followed by a blank.
|
||
|
||
Patterns \2 and \3 are similar, specifying character sequences that are
|
||
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
|
||
patterns.
|
||
|
||
This is a particularly complicated example, perhaps the most complicated
|
||
in 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
|
||
powerful and slightly simpler to use than vi for this kind of file
|
||
manipulation. But, it is another command language to learn.)
|
||
|
||
Many times, you will not want to operate on every line in a certain
|
||
range. Rather you will want to make changes on lines that satisfy
|
||
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
|
||
works in the following way: all lines that match the pattern
|
||
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
|
||
|
||
Type:
|
||
|
||
{: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
|
||
pattern are tagged and operated on by the commands.
|
||
|
||
Using {^V} to quote carriage return (see section 39) can be used in global
|
||
substitutions to split two lines. For example, the command
|
||
{:g/\. /s//.^V^M/g^M} will change your file so that each sentence is on a
|
||
separate line. (Note that we have to 'escape' the '.', because '.' by itself
|
||
matches any character. Our command says to find any line which contains a
|
||
period followed by 2 spaces, and inserts a carriage return after the period.)
|
||
|
||
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
|
||
sequence with SQUARE braces, as on the previous Section line.)
|
||
|
||
In working with a document, particularly if using the text formatting
|
||
programs nroff or troff, it is often advantageous to work in terms of
|
||
sentences, paragraphs, and sections. The operations {(} and {)} move to
|
||
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,
|
||
it 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
|
||
would recognize only one sentence in the following line, but two
|
||
sentences on the second following line.
|
||
|
||
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
|
||
paragraph macros. A section begins after each line with a form-feed ^L in the
|
||
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
|
||
if 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
|
||
during input mode. These are summarized in the following table.
|
||
|
||
^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
|
||
abnormally.
|
||
^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
|
||
|
||
If you wish to type in your erase or kill character (say # or @ or ^U) then you
|
||
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
|
||
rests. This indicates that the editor expects you to type a control character
|
||
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
|
||
part of a substitution string will result in the matched line being split in
|
||
two. This, in effect, is how to split lines by using a substitution.) You can
|
||
insert 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
|
||
way to type ^S or ^Q, since the system normally uses them to suspend and resume
|
||
output and never gives them to the editor to process.
|
||
|
||
If you are using the autoindent option you can backtab over the indent which it
|
||
supplies by typing a ^D. This backs up to the boundary specified by the
|
||
shiftwidth option. This only works immediately after the supplied autoindent.
|
||
|
||
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
|
||
restore the previous indent on the next. You can also type a 0 followed
|
||
immediately 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
|
||
effective.
|
||
|
||
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
|
||
running vi you can escape to the line oriented editor of ex by giving
|
||
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 {:}.
|
||
|
||
In rare instances, an internal error may occur in vi. In this case you
|
||
will get a diagnostic and will be left in the command mode of ex. You can
|
||
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
|
||
giving ex the command {vi}.
|
||
|
||
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.)
|
||
|
||
If you are on a hardcopy terminal or a terminal which does not have a cursor
|
||
which can move off the bottom line, you can still use the command set of vi,
|
||
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
|
||
which the text is displayed.
|
||
|
||
In open mode the editor uses a single line window into the file, and moving
|
||
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.
|
||
|
||
If you are on a hardcopy terminal, the {^R} command will retype the current
|
||
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
|
||
see what the line looks like again.
|
||
|
||
It is sometimes useful to use this mode on very slow terminals which can
|
||
support vi in the full screen mode. You can do this by entering ex and using
|
||
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.
|
||
|
||
If you decide that you have a favorite set of options and would like to change
|
||
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
|
||
placed in it a file that is executed each time you log in. If one of the
|
||
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:
|
||
|
||
setenv EXINIT='set tabstop=4 wrapmargin=8 autoindent'
|
||
|
||
or equivalently
|
||
|
||
setenv EXINIT='se ts=4 wm=8 ai'
|
||
|
||
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
|
||
start of the line. It then aligns the cursor at the level of indentation so
|
||
determined.
|
||
|
||
If the user then types lines of text in, they will continue to be justified at
|
||
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
|
||
stop one can hit {^D}. The tab stops going backwards are defined at multiples
|
||
of the shiftwidth option. You cannot backspace over the indent, except by
|
||
sending an end-of-file with a {^D}. A line with no characters added to it
|
||
turns into a completely blank line (the white space provided for the autoindent
|
||
is 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
|
||
in 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,
|
||
substitute, t, undo or shift command. This has the same effect as supplying a
|
||
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
|
||
discarded from the input. A complaint is registered the first time a backspace
|
||
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
|
||
in 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
|
||
remembered, and to be toggled by repeating the suffices. The suffix r makes
|
||
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
|
||
system expands tabs).
|
||
|
||
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
|
||
striaghtforward, intuitive fashion to have meaning for lisp.
|
||
|
||
[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.
|
||
|
||
If nomagic is set, the number of regular expression metacharacters is greatly
|
||
reduced, with only up-arrow `^' and `$' having special effects. In addition
|
||
the metacharacters `~' and `&' of the replacement pattern are treated as normal
|
||
characters. All the normal metacharacters may be made magic when nomagic is
|
||
set by preceding them with a `\'.
|
||
|
||
[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
|
||
paragraph more confusing than this one. What it says is: mesg allows people to
|
||
write to you even if you are in visual or open mode; nomesg locks your terminal
|
||
so they can't write to you and mess up your screen.]
|
||
|
||
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
|
||
|
||
If {noopen}, the commands open and visual are not permitted. This is set for
|
||
edit to prevent confusion resulting from accidental entry to open or visual
|
||
mode.
|
||
|
||
[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
|
||
program, ex, with different options set: ex itself, vi, and edit.]
|
||
|
||
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
|
||
speeding output on terminals without addressable cursors when text with leading
|
||
white space is printed.
|
||
|
||
[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
|
||
which start paragraphs.
|
||
|
||
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
|
||
general anything that writes is affected. This option is turned on if you
|
||
invoke 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
|
||
right of the cursor position are refreshed as each input character is typed).
|
||
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
|
||
|
||
If on, macros are repeatedly tried until they are unchanged. For example, if o
|
||
is 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
|
||
potentially more far reaching scope, the net change in the number of lines in
|
||
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
|
||
individual 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
|
||
present.
|
||
|
||
[Editor's note: I would suggest that you place the following line in
|
||
your .login file:
|
||
setenv SHELL '/bin/csh'
|
||
]
|
||
|
||
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
|
||
option.
|
||
|
||
Section 44.27: {showmatch}, {sm} default: nosm
|
||
|
||
In open and visual mode, when a `)' or `}' is typed, if the matching `(' or `{'
|
||
is 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
|
||
during input of new text to improve throughput when the terminal in use is both
|
||
slow and unintelligent. See "An Introduction to Display Editing with Vi" for
|
||
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
|
||
is 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
|
||
seen it used. I'm not even sure I know what they are talking about.]
|
||
|
||
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
|
||
wait forever. This is useful if you want multi-character macros, but if
|
||
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
|
||
escape.
|
||
|
||
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
|
||
screen (minus one line) at higher speeds.
|
||
|
||
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
|
||
screen around which vi looks for a convenient place to insert a new-line
|
||
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
|
||
|
||
Inhibit the checks normally made before write commands, allowing a write to any
|
||
file which the system protection mechanism will allow.
|
||
|
||
Section 44.41: {w300}, {w1200}, {w9600} defaults: w300=8
|
||
w1200=16
|
||
w9600=full screen minus one
|
||
|
||
These are not true options but set the default size of the window for when the
|
||
speed is slow (300), medium (1200), or high (9600), respectively. They are
|
||
suitable for an EXINIT and make it easy to change the 8/16/full screen rule.
|
||
|
||
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
|
||
visual
|
||
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.]
|