Thursday, July 31, 2008

Vi Text Editing


Vi (o_cially pronounced 'vee-eye'/uno_cially pronounced 'six' because of the

feeling one gets when using vi that it may be the text editor of the antichrist)

is a display oriented interactive text editor.

Vi15 makes one major philosophical deviation from every other text editor

I have come in contact with. The basic idea is that your hands don't have any

business straying from the home row keys. This can be an advantage for the

touch typist, but the guy who needs to see the letter on the key before pushing

it down tends to be less enamored with this characteristic. Since your _ngers

can only reach about _fty (50) keys without moving your hands, and since vi

has in excess of 100 commands, something drastic must be done in order to

designate all the functions a decent text editor must have. Rather than relying

on extra keys on your keyboard that seem a little too far away or special key

combinations that involve keys that your keyboard may or may not have, vi

simply assigns a couple functions to the keys in reach.

Vi operates in two modes16 (insert and command) in order to determine

which function should be performed when a key is pressed. This two mode

novelty, in my opinion, is what causes some to confuse vi with the devil himself

and causes others to place vi equal with God. Although I _nd it hard to justify

worshiping a text editor, I can (after much e_ort) appreciate the utility of vi.

Why vi? Vi is the default editor for Unix. It is possible to use other editors,

but if you learn vi you can be con_dent that it will be on any Unix machine

you use. However, the same level of con_dence with another editor may be

shortlived. It would be to your advantage to learn at least the basics of vi. For

those who use a text editor on a daily basis, particularly for programming, vi

will become a joy to use after a few months of friendship building.

As with any friendship, an emphasis must be placed on quality time, not just

quantity. Those who have little use for a text editor may be satis_ed with a cold

professional relationship with conversations limited to a few basic commands.

The rest of us would certainly bene_t from a little quality time with vi. By

quality time, I don't mean merely having the same conversations over and over

(repeating commands you already know). I don't mean just reading about what

makes vi tick. Although these are important activities, I mean telling vi things

you've never told it before and observing its response. Don't discuss important

issues with vi until you're pretty sure you know how it will react. Make sure

you make a backup copy of the _le you experiment with.

15Short for visual, but in keeping with the Unix mentality that any command longer than

_ve characters isn't worth using, the command has been truncated to the _rst two letters.

16Technically, there are three modes, but I have chosen to treat the command and line editor

modes as one mode. The line editor commands are a carry-over from the ex line editor.

30

3.2 Starting vi

To start vi just type vi at the operating system prompt. You will see a screen

with a column of tildes (~) down the left side of the screen. This signi_es

an empty workspace. To edit a _le, just include the _lename after it, e.g. vi

filename. You will see the text of the _le you included.17 Vi is now in command

mode. The most basic command to enter insert mode is i which lets you insert

text to the left of the cursor.

3.3 Insert mode

I begin with a brief description of the insert mode because it is very straight

forward. In insert mode the characters you type are inserted into your document.

You can use the backspace key to delete any typing mistakes you have made on

the current input line. The escape key (<esc>) takes you out of insert mode

and back to the command mode. If you are ever in doubt about what mode you

are in, just press <esc> a few times until vi starts complaining. You will then

know that you are in the command mode.

3.4 Command mode

Command mode is where you do everything that isn't done in insert mode. In

command mode the same keys that caused letters to appear on your screen in

insert mode now represent totally di_erent functions. Rather than go into a

detailed discussion of the 100 or so commands, this section contains a list of the

more popular commands. The next section contains a more comprehensive list

of vi commands.

3.4.1 Moving around

h move the cursor one character to the left

j move the cursor one character down

k move the cursor one character up

l move the cursor one character to the right

0 move to the beginning of a line

$ move to the end of a line

G move to the end of a file

1G move to the first line of a file

move down one screen

move up one screen

If you try to move somewhere that vi doesn't want to go, e.g. pressing h

when the cursor is in the left-most column, your terminal will complain by either

beeping or ashing the screen.

17If the _le does not exist, it will be created.

31

3.4.2 Deleting text

x delete the character under the cursor

dd delete a line

3.4.3 Saving and quitting

:w write to disk

ZZ write to disk and exit

:q! exit without writing to disk

Actually, the command for quitting vi is :q. You can save and quit by

typing :wq but ZZ does the same thing18 and takes one less keystroke. If there

are unsaved changes to the text and you try to quit using :q, vi will warn you

that you have unsaved changes and will prevent you from quitting. In order to

quit without saving the changes you must use the override switch, !.

3.4.4 Copy, delete, and moving text

Knowing how to copy, delete, and move text is a prerequisite to any serious

text editing task. If you have a small amount of text to delete or copy you may

_nd it convenient to use dd or yy. These commands delete or yank the line of

text that the cursor is on. dd deletes the current line of text and places it in a

bu_er. yy copies the current line of text to a bu_er while leaving the original

text unaltered. Many commands can be preceded by a number. This number

indicates the number of times the command is repeated. These commands are

no exception, e.g. 3dd deletes the line the cursor is on as well as the two lines

below it and places them in a bu_er. Text can be retrieved from the text bu_er

by typing p. The \pull" command inserts the text from the bu_er into the text

_le beginning on the line below the cursor. This method of deleting and yanking

works well for text blocks of known length or an easily countable number of lines,

but is less satisfactory of large blocks of text.

As a result, vi has another method of text manipulation that involves marking

text. Vi is capable of marking 26 di_erent locations in a _le. To mark a

location in a text _le move the cursor to the desired location and type m followed

by the name you want to use. Each lowercase letter of the alphabet is a name.

Suppose we have a portion of text we wish to move from one location to

another. We can do this by marking the beginning of the text block with the

name q, i.e. mq will give the current cursor location the name q. Then we move

to the end of the portion of text we wish to move and type d'q. This command

deletes everything from the marked position to the cursor position and places

it in a bu_er. Text in the bu_er is retrieved using the \pull" command already

described. The \yank" command allows you to copy the text to the bu_er

18For the pureist, :wq and ZZ are not exactly the same. :wq always saves, whereas ZZ saves

only if changes have been made since the last save.

32

instead of deleting it. Typing y'q instead of d'q will place a copy of the text

in the bu_er and leave the original text unaltered.19

3.4.5 Search and replace

The search command is /. To search for polite type /polite. n repeats the

search in the same direction, and N repeats the search in the opposite direction.

The search option accepts most of the standard Unix pattern matching language.

(See section 2.7.1.) Suppose I had a _le that contained the following

text:

There was a young man of Milan

Whose poems, they never would scan;

When asked why it was,

He said, `It's because

I always try to get as many words into the last line as I possibly can'.

|anonymous

Here are a few examples (using this text) that you will probably never use

but may _nd inspiring:

/[a-z]as

will search for any lowercase letter followed by as. In this example, it would

_nd was and last but not as or asked.

/[^c]an

will search for any an preceded by any character other than a c. In our text it

would _nd Milan but not scan or can.

/^[A-Z].*\. *$

will search for any line that begins with a capital letter and ends with a period

and any number of blanks. Our only match in the example text would be with

the last line.

All of these search patterns can be used in the search and replace command

that takes on the following structure:

:s/search_string/replacement_string/g

This command replaces every search string on the current line with replace-

ment string. Omitting the g (global) ag at the end of the command will cause

only the _rst occurrence of search string to be altered. Often you may wish

to con_rm each replacement. This can be done with the con_rm ag c. The

con_rm ag should be placed after or in place of the g ag. Suppose I had the

following line:

19Using ' in d'q begins deleting text at the beginning of the line that the q mark is on.

Using ` instead, i.e. d`q begins deleting text at the exact location of the mark. This holds

for the yank command as well.

33

Give a skeptic and inch... and he'll take a mile.

and typed

:s/take a mile/measure it/

I would be left with

Give a skeptic and inch... and he'll measure it.

Any command that begins with a \:" is called a line mode command and

performs its duty on the line the cursor is currently on. However, you can

override vi's default of operating only on the current line by preceding them

with a range of line numbers. For example, if I wanted to replace guy with gal

on lines 32 through 56 I would type

:32,56s/guy/gal/g

Omitting the g would cause only the _rst occurrence of guy in each line to be

replaced. The \." and \$" play a special role in this sort of designation. \."

indicates the current line, and \$" indicates the last line of the _le. Therefore, if

I wanted to delete20 from the current line to the end of the _le I would enter:21

:.,$d

I could even do something like:

:.,/Edison/d

which would delete from the current line to the next line that contained Edison.

One other shortcut that might be worth mentioning is that 1,$ and % both

indicate all the lines in the _le. Therefore,

:1,$s/search_string/replacement_string/g

and

:%s/search_string/replacement_string/g

do exactly the same thing.

3.4.6 Undo

The undo command, u, is another feature that has saved me many times. Pressing

u undoes the last command you told vi to perform. Another form of the

undo command is U which undoes all the changes made to the current line since

you moved there.

20This works because :d is a line mode command that deletes the current line.

21The same could be accomplished by typing dG.

34

3.4.7 Repeat

Often times you may desire to repeat the last command performed. This can

be done with the \." command. Place the cursor in the appropriate position

and press \." to repeat the most recent command. Suppose I had a C program

in which I wished to switch a variable name from no way to yes way in two

di_erent places. One way I could accomplish this would be to place my cursor

on the beginning of the _rst no way and type cw (change word) and then type

yes way <esc>. This would accomplish my task for the _rst case. Now all I

would need to do to change the second no way would be to place my cursor at

the beginning of it and type \." to repeat the last command.

3.5 Vi reference

Here is a more comprehensive list of vi commands in command mode.22 23

3.5.1 Notation for this reference

default values : 1

<*> : `*' must not be taken literally

[*] : `*' is optional

^X :

: Space

: Carriage return

: Linefeed

: Horizontal tab

: Escape

: Your erase character

: Your kill character

: Your interrupt character

: An element in the range

N : Number (`*' = allowed, `-' = not appropriate)

CHAR : Char unequal to |

WORD : Word followed by ||

3.5.2 Move commands (See also Display commands)

N | Command | Meaning

---+--------------------+-----------------------------------------------

* | h | ^H | | <*> chars to the left.

* | j | | ^N | <*> lines downward.

* | l | | <*> chars to the right.

* | k | ^P | <*> lines upward.

* | $ | To the end of line <*> from the cursor.

- | ^ | To the first CHAR of the line.

* | _ | To the first CHAR <*> - 1 lines lower.

* | - | To the first CHAR <*> lines higher.

22Heavily borrowed from Vi Reference by Maarten Litmaath.

23Warning: some vi versions don't support the more esoteric features described in this

document.

35

* | + | | To the first CHAR <*> lines lower.

- | 0 | To the first char of the line.

* | | | To column <*> (: only to the endpoint).

* | f | <*> s to the right (find).

* | t | Till before <*> s to the right.

* | F | <*> s to the left.

* | T | Till after <*> s to the left.

* | ; | Repeat latest `f'|`t'|`F'|`T' <*> times.

* | , | Idem in opposite direction.

* | w | <*> words forward.

* | W | <*> WORDS forward.

* | b | <*> words backward.

* | B | <*> WORDS backward.

* | e | To the end of word <*> forward.

* | E | To the end of WORD <*> forward.

* | G | Go to line <*> (default EOF).

* | H | To line <*> from top of the screen (home).

* | L | To line <*> from bottom of the screen (last).

- | M | To the middle line of the screen.

* | ) | <*> sentences forward.

* | ( | <*> sentences backward.

* | } | <*> paragraphs forward.

* | { | <*> paragraphs backward.

- | ]] | To the next section (default EOF).

- | [[ | To the previous section (default begin of file).

- | ` | To the mark.

- | ' | To the first CHAR of the line with the mark.

- | `` | To the cursor position before the latest absolute

| jump (of which are examples `/' and `G').

- | '' | To the first CHAR of the line on which the cursor

| was placed before the latest absolute jump.

- | / | To the next occurrence of .

- | //+n | To the next nth occurrence of .

- | ? | To the previous occurrence of .

- | n | Repeat latest `/'|`?' (next).

- | N | Idem in opposite direction.

- | % | Find the next bracket and go to its match

| (also with `{'|`}' and `['|`]').

Entries in this table that have an \*" are repeatable commands whereas

entries with a \-" are not. For example, if I type 4w my cursor will travel four

words farther into my document.

3.5.3 Searching

:ta | Search in the tags file[s] where is

| defined (file, line), and go to it.

^] | Use the name under the cursor in a `:ta' command.

^T | Pop the previous tag off the tagstack and return

| to its position.

:[x,y]g// | Search globally [from line x to y] for

| and execute the `ex' on each occurrence.

:[x,y]v// | Execute on the lines that don't match.

36

3.5.4 Undoing changes

u | Undo the latest change.

U | Undo all changes on a line, while not having

| moved off it (unfortunately).

:q! | Quit vi without writing.

:e! | Re-edit a messed-up file.

3.5.5 Inserting text

End inserting text with <esc>

* | a | <*> times after the cursor.

* | A | <*> times at the end of line.

* | i | <*> times before the cursor (insert).

* | I | <*> times before the first CHAR of the line

* | o | On a new line below the current (open).

| The count is only useful on a slow terminal.

* | O | On a new line above the current.

| The count is only useful on a slow terminal.

* | > | Shift the lines described by <*> one

| shiftwidth to the right.

* | >> | Shift <*> lines one shiftwidth to the right.

* | ["]p | Put the contents of the (default undo) buffer

| <*> times after the cursor.

| A buffer containing lines is put only once,

| below the current line.

* | ["]P | Put the contents of the (default undo) buffer

| <*> times before the cursor.

| A buffer containing lines is put only once,

| above the current line.

* | . | Repeat previous command <*> times. If the last

| command before a `.' command references a

| numbered buffer, the buffer number is

| incremented first (and the count is ignored):

|

| "1pu.u.u.u.u - `walk through' buffers 1

| through 5

| "1P.... - restore them

3.5.6 Deleting text

Everything deleted can be stored into a bu_er. This is achieved by putting a "

and a lowercase letter before the delete command. The deleted text will be in

the bu_er with the used letter. If an uppercase letter is used as bu_er name,

the the corresponding bu_er will be augmented instead of overwritten with the

text. The undo bu_er always contains the latest change. Bu_ers <1-9> contain

the latest 9 line deletions ("1 is most recent).

* | x | Delete <*> chars under and after the cursor.

* | X | <*> chars before the cursor.

* | d | From begin to endpoint of <*>.

* | dd | <*> lines.

37

- | D | The rest of the line.

* | < | Shift the lines described by <*> one

| shiftwidth to the left.

* | << | Shift <*> lines one shiftwidth to the left.

* | . | Repeat latest command <*> times.

3.5.7 Changing text

End changing text with <esc>

* | r | Replace <*> chars by - no .

* | R | Overwrite the rest of the line,

| appending change <*> - 1 times.

* | s | Substitute <*> chars.

* | S | <*> lines.

* | c | Change from begin to endpoint of <*>.

* | cc | <*> lines.

* | C | The rest of the line and <*> - 1 next lines.

* | = | If the option `lisp' is set, this command

| will realign the lines described by <*>

| as though they had been typed with the option

| `ai' set too.

- | ~ | Switch lower and upper cases

| (should be an operator, like `c').

* | J | Join <*> lines (default 2).

* | . | Repeat latest command <*> times (`J' only once).

- | & | Repeat latest `ex' substitute command, e.g.

| `:s/wrong/good'.

- | :[x,y]s/

//| Substitute (on lines x through y) the pattern

| (default the last pattern) with . Useful

| flags are `g' for `global' (i.e. change

| every non-overlapping occurrence of

) and

| `c' for `confirm' (type `y' to confirm a

| particular substitution, else ). Instead

| of `/' any punctuation CHAR unequal to

| can be used as delimiter.

3.5.8 Substitute replacement patterns

The basic meta-characters for the replacement pattern are \&" and \~ "; these

are given as n& and n~ when nomagic is set. Each instance of \&" is replaced

by the characters which the regular expression matched. The meta-character

\ ~ " stands, in the replacement pattern, for the de_ning text of the previous

replacement pattern. Other meta-sequences possible in the replacement pattern

are always introduced by the escaping character \n". The sequence nn (where

n is an integer between 1 and 9) is replaced by the text matched by the n

th

regular subexpression enclosed between n( and n). The sequences nu and nl

cause the immediately following character in the replacement to be converted to

uppercase or lowercase respectively if this character is a letter. The sequences

nU and nL turn such conversion on, either until nE or ne is encountered, or until

the end of the replacement pattern.

38

3.5.9 Remembering text (yanking)

With yank commands you can put "<a--zA--Z> before the command, just as

with delete commands. Otherwise you only copy to the undo bu_er.

* | y | Yank from begin to endpoint of <*>.

* | yy | <*> lines.

* | Y | Idem (should be equivalent to `y$' though).

- | m | Mark the cursor position with a letter.

3.5.10 Commands while in insert or change mode

^@ | If typed as the first character of the

| insertion, it is replaced with the previous

| text inserted (max. 128 chars), after which

| the insertion is terminated.

^V | Deprive the next char of its special meaning

| (e.g. ).

^D | One shiftwidth to the left.

0^D | Remove all indentation on the current line

| (there must be no other chars on the line).

^^D | Idem, but it is restored on the next line.

^T | One shiftwidth to the right

^H | | One char back.

^W | One word back.

| Back to the begin of the change on the

| current line.

| Like (but you get a beep as well).

3.5.11 Display commands (See also Move commands)

^G | Give file name, status, current line number

| and relative position.

^L | Refresh the screen (sometimes `^P' or `^R').

^R | Sometimes vi replaces a deleted line by a `@',

| to be deleted by `^R' (see option `redraw').

[*]^E | Expose <*> more lines at bottom, cursor stays

| put (if possible).

[*]^Y | Expose <*> more lines at top, cursor stays put

| (if possible).

[*]^D | Scroll <*> lines downward

| (default the number of the previous scroll;

| initialization: half a page).

[*]^U | Scroll <*> lines upward

| (default the number of the previous scroll;

| initialization: half a page).

[*]^F | <*> pages forward.

[*]^B | <*> pages backward (in older versions `^B'

| only works without count).

z- | Move current line to bottom of the screen.

z. | Move current line to the center of the screen.

/string/z- | Move line with string in it to the bottom of

| the screen.

39

If in the next commands the _eld <wi> is present, the windowsize will

change to <wi>. The window will always be displayed at the bottom of the

screen.

[*]z[wi] | Put line <*> at the top of the window

| (default the current line).

[*]z[wi]+ | Put line <*> at the top of the window

| (default the first line of the next page).

[*]z[wi]- | Put line <*> at the bottom of the window

| (default the current line).

[*]z[wi]^ | Put line <*> at the bottom of the window

| (default the last line of the previous page).

[*]z[wi]. | Put line <*> in the center of the window

| (default the current line).

3.5.12 Writing, editing other _les, and quitting vi

In \:" \ex" commands \%" denotes the current _le, \#" is a synonym for the

alternate _le (which normally is the previous _le). Marks can be used for line

numbers too: '<a-z>. In the :w, :f , :cd, :e, and :n commands, shell metacharacters

can be used.

:q | Quit vi, unless the buffer has been changed.

:q! | Quit vi without writing.

^Z | Suspend vi.

:w | Write the file.

:w | Write to the file .

:w >> | Append the buffer to the file .

:w! | Overwrite the file .

:x,y w | Write lines x through y to the file .

:wq | Write the file and quit vi; some versions quit

| even if the write was unsuccessful!

| Use `ZZ' instead.

ZZ | Write if the buffer has been changed, and

| quit vi. If you have invoked vi with the `-r'

| option, you'd better write the file

| explicitly (`w' or `w!'), or quit the

| editor explicitly (`q!') if you don't want

| to overwrite the file - some versions of vi

| don't handle the `recover' option very well.

:x [] | Idem [but write to ].

:x! [] | `:w![]' and `:q'.

:pre | Preserve the file - the buffer is saved as if

| the system had just crashed; for emergencies,

| when a `:w' command has failed and you don't

| know how to save your work (see `vi -r').

:f | Set the current filename to .

:cd [

] | Set the working directory to

| (default home directory).

:cd! [

] | Idem, but don't save changes.

:e [+] | Edit another file without quitting vi - the

| buffers are not changed (except the undo

| buffer), so text can be copied from one file to

40

| another this way. [Execute the `ex' command

| (default `$') when the new file has been

| read into the buffer.] must contain no

| or . See `vi startup'.

:e! [+] | Idem, without writing the current buffer.

^^ | Edit the alternate (normally the previous) file.

:rew | Rewind the argument list, edit the first file.

:rew! | Idem, without writing the current buffer.

:n [+] [] | Edit next file or specify a new argument list.

:n! [+] [] | Idem, without writing the current buffer.

:args | Give the argument list, with the current file

| between `[' and `]'.

3.5.13 Macros

When mapping take a look at the options to and remap (below).

:map | is interpreted as , e.g.

| `:map ^C :!cc %^V' to invoke `cc' (the C

| compiler) from within the editor

| (vi replaces `%' with the current file name).

:map | Show all mappings.

:unmap | Deprive of its mapping. When vi

| complains about non-mapped macros (whereas no

| typos have been made), first do something like

| `:map Z', followed by

| `:unmap ' (`Z' must not be a macro

| itself), or switch to `ex' mode first with `Q'.

:map! | Mapping in append mode, e.g.

| `:map! \be begin^Vend;^VO'.

| When in append mode is preceded by

| `^V', no mapping is done.

:map! | Show all append mode mappings.

:unmap! | Deprive of its mapping (see `:unmap').

:ab | Whenever in append mode is preceded and

| followed by a breakpoint (e.g. or `,'), it

| is interpreted as , e.g.

| `:ab ^P procedure'. A `^V' immediately

| following inhibits expansion.

:ab | Show all abbreviations.

:unab | Do not consider an abbreviation

| anymore (see `:unmap').

@ | Consider the contents of the named register a

| command, e.g.:

| o0^D:s/wrong/good/"zdd

| Explanation:

| o - open a new line

| 0^D - remove indentation

| :s/wrong/good/ - this input text is an

| `ex' substitute command

| - finish the input

| "zdd - delete the line just

| created into register `z'

41

| Now you can type `@z' to replace `wrong'

| with `good' on the current line.

@@ | Repeat last register command.

3.5.14 Switch and shell commands

Q | ^\ | | Switch from vi to `ex'.

: | An `ex' command can be given.

:vi | Switch from `ex' to vi.

:sh | Execute a subshell, back to vi by `^D'.

:[x,y]! | Execute a shell [on lines x through y;

| these lines will serve as input for and

| will be replaced by its standard output].

:[x,y]!! [] | Repeat last shell command [and append ].

:[x,y]! ! [] | Use the previous command (the second `!') in a

| new command.

[*]! | The shell executes , with as standard

| input the lines described by <*>,

| next the standard output replaces those lines

| (think of `cb', `sort', `nroff', etc.).

[*]!! | Append to the last and execute it,

| using the lines described by the current

| <*>.

[*]!! | Give <*> lines as standard input to the

| shell , next let the standard output

| replace those lines.

[*]!!! [] | Use the previous [and append to it].

:x,y w ! | Let lines x to y be standard input for

| (notice the between the `w' and the `!').

:r! | Put the output of onto a new line.

:r | Read the file into the buffer.

3.5.15 Vi startup

As discussed earlier vi is started by simply typing vi filename where the _lename

is optional. It is possible to include a list of _lenames instead of just the

one. This tells vi to edit the _rst _le. After you are _nished with the _le it

edits the second and continues this process until all the _les in the list have

been edited.

The editor can be initialized by the shell variable EXINIT, which looks like:

EXINIT='||...'

: set options

map ...

ab ...

export EXINIT (in the Bourne shell)

However, a better way is to put the list of initializations into a _le. If this _le

is located in your home directory, and is named .exrc and the variable EXINIT

is not set, the list will be executed automatically at startup time. However, vi

will always execute the contents of a .exrc in the current directory, if you own

the _le. Otherwise you have to type

42

:so file

to source the _le yourself.

In a .exrc _le a comment is introduced with a double quote character: the

rest of the line is ignored.24

On-line initializations can be given with vi + <cmd> file, e.g.:

vi +x file | The cursor will immediately jump to line x

| (default last line).

vi +/ file | Jump to the first occurrence of .

You can start at a particular tag with:

vi -t | Start in the right file in the right place.

Sometimes, e.g. if the system crashed while you were editing, it is possible

to recover _les lost in the editor by typing vi -r file. Typing vi -r shows

the _les you can recover. The readonly ag allows you to view a _le with vi

without the danger of accidentally saving changes. However, if you do make

changes that you decide you want to save, typing :w! will override the readonly

option.

3.5.16 The most important options

ai | autoindent - In append mode after a the

| cursor will move directly below the first

| CHAR on the previous line. However, if the

| option `lisp' is set, the cursor will align

| at the first argument to the last open list.

aw | autowrite - Write at every shell escape

| (useful when compiling from within vi).

dir= | directory - The directory for vi to make

| temporary files (default `/tmp').

eb | errorbells - Beeps when you goof

| (not on every terminal).

ic | ignorecase - No distinction between upper and

| lower cases when searching.

lisp | Redefine the following commands:

| `(', `)' - move backward (forward) over

| S-expressions

| `{', `}' - idem, but don't stop at atoms

| `[[', `]]' - go to previous (next) line

| beginning with a `('

| See option `ai'.

list | is shown as `$', as `^I'.

magic | If this option is set (default), the chars `.',

| `[' and `*' have special meanings within search

| and `ex' substitute commands. To deprive such

| a char of its special function it must be

24An exception to this is if the last command on the line is a map[!] or ab command or a

shell escape, a trailing comment is not recognized, but considered part of the command.

43

| preceded by a `\'. If the option is turned off

| it's just the other way around. Meta-chars:

| ^ - must begin the line

| $ - must end the line

| . - matches any char

| [a-z] - matches any char in the range

| [^a-z] - any char not in the range

| [] - matches any char in

| [^] - any char not in

| * - 0 or more s

| \< - must begin a word

| \> - must end a word

modeline | When you read an existing file into the buffer,

| and this option is set, the first and last 5

| lines are checked for editing commands in the

| following form:

|

| vi:set options|map ...|ab ...|!...:

|

| Instead of a can be used, instead of

| `vi' there can be `ex'. Warning: this option

| could have nasty results if you edit a file

| containing `strange' modelines.

nu | number - Numbers before the lines.

para= | paragraphs - Every pair of chars in is

| considered a paragraph delimiter nroff macro

| (for `{' and `}'). A preceded by a `\'

| indicates the previous char is a single letter

| macro. `:set para=P\ bp' introduces `.P' and

| `.bp' as paragraph delimiters. Empty lines and

| section boundaries are paragraph boundaries

| too.

redraw | The screen remains up to date.

remap | If on (default), macros are repeatedly

| expanded until they are unchanged.

| Example: if `o' is mapped to `A', and `A'

| is mapped to `I', then `o' will map to `I'

| if `remap' is set, else it will map to `A'.

report=<*> | Vi reports whenever e.g. a delete

| or yank command affects <*> or more lines.

ro | readonly - The file is not to be changed.

| However, `:w!' will override this option.

sect= | sections - Gives the section delimiters (for `[['

| and `]]'); see option `para'. A `{' beginning a

| line also starts a section (as in C functions).

sh= | shell - The program to be used for shell escapes

| (default `$SHELL' (default `/bin/sh')).

sw=<*> | shiftwidth - Gives the shiftwidth (default 8

| positions).

sm | showmatch - Whenever you append a `)', vi shows

| its match if it's on the same page; also with

| `{' and `}'. If there's no match at all, vi

| will beep.

taglength=<*> | The number of significant characters in tags

| (0 = unlimited).

44

tags= | The space-separated list of tags files.

terse | Short error messages.

to | timeout - If this option is set, append mode

| mappings will be interpreted only if they're

| typed fast enough.

ts=<*> | tabstop - The length of a ; warning: this is

| only IN the editor, outside of it s have

| their normal length (default 8 positions).

wa | writeany - No checks when writing (dangerous).

warn | Warn you when you try to quit without writing.

wi=<*> | window - The default number of lines vi shows.

wm=<*> | wrapmargin - In append mode vi automatically

| puts a whenever there is a or

| within columns from the right margin

| (0 = don't put a in the file, yet put it

| on the screen).

ws | wrapscan - When searching, the end is

| considered `stuck' to the begin of the file.

:set

:set no

:set

:set | Show all non-default options and their values.

:set

:set all | Show all options and their values.

3.6 Miscellaneous tips

Although you should be able to come up with all of the following commands by

studying the tables of vi commands, I have included a few examples that I have

found useful.

3.6.1 Line deletions

:g/string/d

deletes every line that contains string, while

:v/string/d

deletes every line that does not contain string.

3.6.2 Switching cases

In the replacement part of a substitution command, i.e. between the second \/"

and third \/",

\u means make the following character upper case

\l means make the following character lower case

\U means make the rest of the replacement upper case

\L means make the rest of the replacement lower case

How about a few examples?

45

1. Make the _rst letter of every word from line 18 to 43 uppercase.

:18,43s/\<./\u&/g

2. Change \uPPeR" and \LoweR" in any mixture of cases to lowercase.

:s/[UuLl][PpOo][PpWw][Ee][Rr]/\L&/

3. Make the whole _le uppercase.

:%s/.*/\U&/

4. Make the region from line m to line n all uppercase.

:'m,'ns/.*/\U&/

5. Make a paragraph all lowercase.

:?^$?,/^$/s/.*/\L&/

6. Make the _rst letter of every word in a paragraph uppercase.

:?^$?,/^$/s/\([^ ][^ ]*\)/\u&/g

7. Make the second word of each line uppercase.

:1,$s/^\([^ ]*\) \([^ ]*\) \(.*\)/\1 \U\2\e \3/

3.6.3 Spell checking in vi

To check the spelling of your document without exiting out of vi, type

:!spell % > %.sp

:e %.sp

:e# (To get back to your document)

3.6.4 Additional search and replace

To change Gravity isn't just a "good idea." It's the "law." to Gravity

isn't just a ``good idea.'' It's the ``law.'' type

:g/$/s/"\([^"]*\)"/``\1''/g

The following will _nd words that begin and end with a vowel:

/\<[aeiouAEIOU][a-zA-Z']*[aeiouAEIOU]\>

46

3.6.5 Removing blank lines

Blank lines can be removed from a _le with any of the following:

:v/./d

or

:g/^$/d

or

:%!/usr/ucb/cat -s

or

:%!sed /./,/^$/!d

Be aware that you may need to get rid of trailing whitespace _rst. This can be

accomplished with

:%s/[ ^I]*$/!d

3.6.6 Writing from bu_ers

To save the contents of the a bu_er to _lename, type

:e filename"ap (to edit a new file and put 'a's contents in it)

:w (to save it)

To save a portion of a _le to another _le you could type

ma (mark text at the top of the region to be saved)

mb (mark text at the bottom of the region to be saved)

:'a,'b w filename

3.7 Further reading

A number of other vi documents can be found via anonymous ftp in: /pub/vi

at cs.uwp.edu

47

Search

My Blog List