TFM:Vi

From ProgSoc Wiki

Jump to: navigation, search

Contents

Vi---An Inert and Sadomasochistic Guide

Dennis Cook

Everything You Wanted to Know, but were Afraid to Ask

This is roughly the fifth of a series of increasingly improbable guides to vi, the first two being entitled "Vi---A Quick and Dirty Guide"; the third, "Vi---A Quick and Nasty Guide."; the fourth, "Vi---A Slow and Malicious Guide."; Constructive criticism, or more likely blame, can't be directed towards Dennis --- not only has he left the building (1996), but the building has moved (2002). If you must talk to somebody about problems with this chapter, try tomchristmas@progsoc.org. Dennis would like to thank Brent Curtis and David Morgan for advice on LaTeX, and Grant Heinrich for his merciless, but much needed, editing.

Introduction

What is Vi?

Vi, pronounced "Vee-Eye", is a full screen text editor traditionally associated with Unix. Like most Unix tools, it is characterised by being useful and powerful when mastered, but also has an atrociously high learning curve, an interface that is anything but intuitive, and all the charm and character of the lukewarm brown liquid that passes for coffee[1] at the Concourse cafe or the Building 1, Level 3 "coffee" machines.

Vi has been around for along time, and has splintered into about a million different versions. vim (or "vi Improved") is a very popular incarnation (and the version you are most likely to encounter today -- it's also slightly easier to use and slightly more intuitive than classic vi), but you might also want to check out gvim (it's graphical!), nvi and elvis. All of these build upon basic vi, and are all 100% backwards compatible, so you will be able to follow along with this tutorial, no matter which variant you use.

So, Why Learn Vi at All??

Having read thus far, one might be wary of this editor. Overhearing the first year students cursing its very name, one might be inclined to think twice and use some more "friendly" editor like nano.

The virtues of the editor extolled.

There are a couple of reasons why you might wish to persevere. Firstly, vi is standard throughout almost all Unix and Unix-like systems (including Linux). No matter what system you use, you will always have vi and ex; the same cannot be said for pico/nano or emacs. vi can also run on Windows machines and Macs.

The second reason is a little more complex, and has to do with the style of the user interface. vi works on the principle that although difficult to begin with, it allows an experienced user to work far more efficiently than they would with a friendlier but more cumbersome interface[2]

So, in summary, if you plan to do a lot of editing[3] or you want to be able to use a text editor no matter what Unix system you're using, read on.

(You won't be thought any the worse if you wimp out and use nano, but remember, at least vi has an undo command, and can recover your file when the system crashes in the middle of editing!)

Preliminaries

This guide assumes that you have access to and can log on to a Unix system. It assumes that you have a basic understanding of commands like ls, cd, mv, etc. and are familiar with the shell you are using. Not expected, but also useful, would be a familiarity with the stty command.

In the examples, things that you type will normally be set in courier, but things that you have to fill in, such as filenames, will be set in italics. (Optional values will be given in parentheses[4].) Responses that the machine gives will generally be in boldface.

This -ENTER symbol means to press the Enter or Return key, while CTRL-A means to hold down the CTRL (or Control) key and type a.

Approach

The next two sections contain instructions on how to enter and leave vi, followed by an outline of its basic capabilities. At the very least, you should read these two sections through, then re-read them while experimenting with the commands on a file. After that, you should become familiar with the last-line commands in the next section, and the search and replace commands which are given in a section of their own.

A complete summary of all the vi commands known to man is given at the end of this chapter; this should come in useful as a reference.

Esoterica

Finally, after you have become a bit more confident with the editor, you should look at the sections entitled "Esoterica", which follow each principal section. These contain extra information, shortcuts and dirty tricks you may wish to try out.

Getting into (and out of) vi

The basic command line for vi is

vi filename

where filename is the name of the file you wish to edit.

Very occasionally, you may have to use the -r option. This only happens if the system crashes[5] or your session or window unexpectedly dies while you're in vi. Your file will be saved, and you will get some mail, telling you that you can recover the file using the command

vi -r filename

Backups are not performed continuously, so you may lose up to the last ten minutes or so of your session.

When you're in vi, the editor makes a copy of your file into a buffer, which is what you actually edit. When you finish a session, you must decide whether you wish to save the contents of the buffer to the file, or whether you wish to get out without making any permanent changes.[6]

When you exit vi, first press ESC to get into command mode. (If it beeps then you're already in command mode[7].) You now have two options: whether you wish to write the buffer to the file you're editing, or quit without writing.

  • If you wish to write the file, type :wq-ENTER, which stands for write, then quit.
  • If you wish to quit without writing, type :q-ENTER, which stands for quit. At this point you may get the message, No write since last change, :quit! overrides. This is vi warning you that you've made changes, and haven't saved them. If you wish to exit without making changes, then follow the instructions and type :quit!-ENTER or :q!-ENTER.

A quicker way to exit vi, is to type :x-ENTER, which will automatically write the file if it has been modified. An even quicker way is simply to type ZZ in command mode.

Esoterica

There are a number of factors that affect the way vi will behave when you start it up.

It reads your TERM environment variable to determine what type of terminal you're using; if this has been incorrectly set vi will not be able to function. Also check your stty settings to ensure the correct size of your terminal (in terms of lines and columns) has been recorded. This should be done automatically, but the system may lose track. Try not to resize the Vi window when you are in vi --- some versions don't notice, and the results are ugly.

vi also looks for a file called .exrc in your home directory and reads any commands there, and also from your EXINIT environment variable. You use these to configure vi, by placing commands from last-line mode in them. A typical .exrc file might read:

set showmode
set autoindent
set showmatch

This tells vi to display a message, telling you which mode it's in; to switch on auto-indentation mode; and to show matching pairs of braces and parentheses. Note that the commands are not prefixed with a colon.

Starting to Learn vi

This section gives an overview of how vi works, and how it differs from some other text editors. After reading this section through, you should consider experimenting with some of the commands described here.

Modes

The principal difference between vi and some other editors is that vi is what's known as a modal editor. Many editors work by having the user type in text, which is inserted at the cursor, while other keys, such as control and function keys, are used to carry out changes, such as deletion, substitution, and moving the cursor. vi, however, operates in two quite different modes: input mode, where characters that are typed are inserted at the cursor position, and command mode, where characters typed have a special meaning to the editor. (e.g. a lowercase x tells the editor to delete one character to the right of the cursor.)

vi typically starts up in command mode, so the user normally enters a command, such as i for insert, to switch to input mode. When finished, the user switches back into command mode by pressing the -ESC key. There is an additional mode, called "last-line" or Ex[8] mode, for giving complicated commands.

 This is a very short			
 text file.				
 ~					
 ~					
 ~					
 ~
 ~
 ~
 ~			
 ~					
 ~					
 ~					
 "thingy", 2 lines, 32 characters

Figure 1. Screen Layout

Screen Layout

When you start up vi the contents of your file (if it exists) will be displayed on the screen, along with a message on the bottom line telling you how large the file is. If your file fits completely on the screen, i.e. less than (probably) 24 lines, the remaining lines on the screen will contain tildes[9], to indicate where the file ends.

The bottom line of the screen is used for vi to display warning and error messages, general information, and to type in commands in last-line mode.

Adding Text

To add text to the file, you'll need to get into input mode. There are four basic commands to do this: append after cursor, append to end of line, insert before cursor, insert at beginning of line, and open a new line. These commands are given as the keystrokes a, A, i, I, and o or O. These commands are case sensitive; a does not have the same effect as A. The input commands are listed in Table 1.

i

Insert before the cursor.
The next character typed will appear to the left of the cursor.

a

Append after the cursor.
The next character typed will appear to the right of the cursor.

A

Append at the end of the current line.
The cursor will move to the end of the current line; the input will appear there.

I

Insert at the beginning of the current line.
The cursor will move to the first non-blank character in the line; new input will appear there.

o

Open a new line below the current line.
Similar to typing A, then pressing RETURN.

O

Open a new line above the current line.
Similar to typing I, then your text, and then an extra RETURN.

Table 1. Commands for inserting text


For example, assuming you have an empty file, you could start entering text by typing i for insert. Any text that you type will now appear on the screen, until you press ESC. You can correct mistakes on a line by using either the Backspace or Delete keys to delete a single character, CTRL-W to delete words, and CTRL-U to delete lines[10]. When you press RETURN (ENTER), a new line is automatically opened up, but at this point you can't go back and fix up earlier lines. In order to do that, or when you've finished typing in your text, press ESC, and you'll be returned to command mode.

Distinguishing between command and input modes.

You'll have already noticed that there is no readily apparent way of discerning whether you're in command mode or input mode, without experimentally pressing a few keys to see what happens. A way around this is to make vi show you what mode it's operating in. Do this by going to command mode --- press ESC : if you're in command mode already you'll get a beep, if you're in input mode you'll be transferred to command mode. Then type :set showmode-ENTER. You'll notice that when you type the colon, the cursor will leap down to the last line on the screen and you'll have a colon prompt. This is an example of a command in last-line mode. When you've done this, a message will appear in the bottom right hand corner of your screen every time you enter input mode.

This setting will remain in effect only for your current session in vi; to make it permanent, you will have to put an entry for it in your .exrc file.

In each case, you return to input mode by pressing the ESC key. Note how most of the key strokes are a one letter mnemonic for their function, that they are case sensitive, and that a command in upper case is usually a variant of one in lower case.

Moving Around

In command mode commands are either motion commands, for moving around the file, or commands that change (or delete) text. Motion commands can be given in terms of characters, words, lines, sentences, paragraphs, pages, or search patterns.

Motion commands are typically a single character, optionally prefixed by a number, indicating how many times to repeat it. For example, typing 10, followed by the down arrow key, will move the cursor down 10 lines.

Moving by Character

The simplest way of moving around the file is character by character. As well as the arrow keys, the keys h, j, k and l, move the cursor left, down, up and right respectively. If a movement command cannot be carried out, for instance moving right when the cursor is at the end of the line, vi will beep.

Also worth mentioning are the caret and dollar-sign keys, ^ and $, which move the cursor to the start and end of the current line respectively.

Since movement by character is also the most tedious way of moving around the file, you may wish to read on for more elaborate ways of finding your way around the file.

Moving by Line

The simplest way of moving forward a line is to press the RETURN key. If a new line opens up when you do this, you're still in input mode. Other ways include the + key and CTRL-N, which move down a line; the - key and CTRL-P which move up a line. These may of course be preceded by a count; typing 10- moves the cursor up 10 lines.

Another important command is G, or goto line. If you type an upper case G on its own, the cursor will move to the end of the file. However, if you precede the G with a number n, the cursor will move to the start of line n. For example, typing 55G will move the cursor to the start of line 55; typing 1G will move the cursor to the start of the file, i.e. line 1.

Moving by Screen

Scrolling and paging

There are two ways of moving through a file by screen: scrolling and paging. The scrolling commands are CTRL-U and CTRL-D which scroll up and down half a screen respectively. The paging commands are CTRL-B and CTRL-F which page backward and forward by a whole screen at a time.

There are two other commands, CTRL-Y and CTRL-E which cause the screen to scroll up and down by one line, but leaving the cursor in the same place.

Also, you can position the cursor on the first, middle or last line of the screen by typing H, M, or L respectively. (The mnemonics for these are Home, Middle, and Last.)

Words, Sentences, and Paragraphs

vi also allows movement in terms of words, sentences and paragraphs. vi regards a word as a series of alphanumeric characters, separated by spaces and punctuation marks. Sentences are terminated by a full-stop, question or exclamation mark, followed by a newline or two spaces. The motion commands are shown in table 2.

e

Move to the end of the current word

b

Move to the beginning of the current word

w

Move to the start of the next word

)

Move to end of current sentence

(

Move to beginning of current sentence

}

Move to end of current paragraph

{

Move to beginning of current paragraph

]]

Move to end of section

[[

Move to start of section

Table 2. High Level Motion Commands

Searching

You can position the cursor by searching for a pattern. The form of this command is

/pattern ENTER

where the pattern is a string of characters. Note that when you type the slash, the cursor moves to the last line of the screen, and that you terminate the pattern by pressing ENTER.

The simplest pattern contains just the characters you're searching for. For example /dog-ENTER will move the cursor to the first occurrence of the pattern "dog". But this could be at the start of the word "dogmatic". For more exciting things to put in your patterns, see Search and Replace.

For now, just be aware that the characters, \, [, ], *, ^, $ and the full-stop have a special significance in patterns.

This command searches forwards through the file; to search backwards, replace the slash with a question mark, e.g. ?dog-ENTER.

Once you've entered a pattern, you can search for the next pattern like it in the same direction by typing n, for next. The direction of the search is reversed by typing N.

Changing Text

Change commands are used to delete and replace specific items of text, and have a slightly more complicated syntax than the movement commands.

The Replace Command

The replace commands allow you to replace a single character or overtype a line of text. To replace a single character, move the cursor onto that character and type rc, where c is the character you wish to replace it with. Note that you don't have to press ESC when done.

Overtyping

The other replace command, R, acts as an "overtype" command; each character you type will replace the current character and move the cursor to the right until ESC is pressed. For example, if you place the cursor at the start of the word "internal", and typed the sequence, "R e x ESC", you'd end up with word "external". If you press ENTER when replacing, vi will stop replacing, open up a new line and throw you into input mode.

The Change Command

A change command allows the user to select and replace a specific unit of the text. The basic form of a change command is

(number)cmovement command

The preceding number is optional. When a command of this type is issued, the editor marks the area you are about to change with a dollar sign. The replacement text is typed in, and when ESC is pressed, any remaining text of the old unit will be gobbled up.

An example of this would be the change word command, or cw. Typing cw would cause the last character of the current word to be replaced by a dollar sign; any text entered until you press ESC would replace that word. For an example of this see figure 2[11].

``Beware the Jabberwock, my son!		
The awful bite, the claws that catch!	
Beware the Jubjub bird, and shun		
The frumious Bandersnatch!			
etc.				
etc.				

Before typing cw.The cursor is represented by the underscore.

``Beware the Jabberwock, my son!		
The awfu$ bite, the claws that catch!	
Beware the Jubjub bird, and shun		
The frumious Bandersnatch!			
etc.				
etc.                                         CHANGE MODE

After typing cw

``Beware the Jabberwock, my son!		
The teeth that bite, the claws that catch!	
Beware the Jubjub bird, and shun		
The frumious Bandersnatch!			
etc.				
etc.                                         CHANGE MODE

After typing teeth that

``Beware the Jabberwock, my son!		
The teeth that bite, the claws that catch!	
Beware the Jubjub bird, and shun		
The frumious Bandersnatch!			
etc.				
etc.				

After pressing ESC.

Figure 2. The 4 Stages of a change word command

There are three other change commands: C, which changes to the end of the current line[12], cc which changes the entire current line, and s, which deletes one character to the right, then starts inserting[13]. Some examples are listed in table 3.

c3w

Change three words. Change from the cursor to end of the third word on the right.

c$ or C

Change to the end of line. Changes everything between the cursor and the end of line.

c3-ENTER\ or 3cc

Change three lines.

c)

Change to end of sentence.

cl or s

Change one character to the right of the cursor.

Table 3. Change Commands

The Undo Command

vi also provides an undo command. There are two of these, u and U.

The first variety, u undoes the last command. Note that after typing u once, a second u will result in the first undo being undone.

If you make a number of changes to a particular line, you can recover the original line by typing U. This will recover the line as it was before you positioned the cursor on it. Obviously if you move the cursor off a line after making a number of changes, you can't then move it back and type U, since it's no longer the current line.

Deleting Text

Now for some real fun. The delete commands work in much the same way as the change commands. Most commands take the form of

(number)dmovement command

where d stands for "delete", the number is optional, and the motion command specifies the scope.

For example, dw will delete to the end of the current word, and 6dw will delete 6 words[14].

Other deletion commands are dd to delete one line, n\tt dd to delete n lines, and D to delete from the cursor to the end of line.

There are also two shortcuts: x, which deletes a single character to the right of the cursor, and X, which deletes a single character to the left of the cursor.

Some examples are shown in table 4.

d3w

Delete three words. Delete from the cursor to end of the third word on the right.

d$

Delete to the end of line. Delete everything between the cursor and the end of line.

d^

Delete to the start of the line.


d3-ENTER or 3dd

Delete three lines.

d)

Delete to end of sentence.

dG

Delete from the current line to the end of the file.

d1G

Delete from the current line to the beginning of the file.

dl or x

Delete one character to the right of the cursor.

3X

Delete three characters to the left of the cursor.

Table 4. Examples of Deletion

Yank and Put

When anything is deleted, it is placed in a buffer from which it can be recovered, either by the undo command, or by the put command. This process is sometimes referred to as cutting, copying and pasting. Material can also be put into this buffer without deleting by using the yank command.

The yank command functions in a similar manner to the change and delete commands, it has the form of

(count)ymovement

with the usual variations. Some of these are y$, to yank from the cursor to the end of line; yy, or Y to yank the current line; 10yy, to yank the next 10 lines; y), to yank to the end of the current sentence.

There are two variations of the put command, p and P. The first of these, p copies out the contents of the buffer after the cursor. If the buffer contains a whole line, or more, its contents will be copied out onto the next line. The uppercase P dumps the buffer before the current character or line.

A useful application of this is using the sequence xp to transpose two adjacent characters, and the sequence ddp to transpose two adjacent lines.

Other Stuff

There are some other commands that don't fit in anywhere else.

  • To join two lines together, type J. This can be preceded by a count, or followed by a movement command. Note that vi can only handle a limited line length; if a line becomes too large, vi will complain and make a mess of things.
  • The command to shift lines one tab stop to the right is >. The usual variants apply: >> will shift a single line to the right, count>> will shift that many lines below the cursor, and >>move will shift all lines in the move. For example, >} would shift the current paragraph. The command to shift a paragraph left is } and behaves in exactly the same manner. Also see Options and Last-Line Modefor more about setting up tab positions.
  • The tilde key ~ when pressed in command mode reverses the case of the current character and moves one position to the right.
  • The full-stop key . repeats the previous command. For instance, typing x to erase a character, and then typing . will cause the next character to be deleted.
  • The screen can be re-drawn by typing CTRL-L, which is useful if your screen gets scrambled by a message from another user.
  • Typing CTRL-G makes vi tell you the name of the file you're editing, and what line you're currently on. You'll get a message like
    ""starting.tex" [Modified] line 656 of 688 --95%-- ".
  • Another useful movement command is the percent key, % which, if pressed when the cursor is on a parenthesis, bracket or brace, will move the cursor to the matching item.

Esoterica

You'll have probably noticed the mess made when you try to press an arrow key while in input mode. This is because an arrow key just transmits a normal sequence of characters which are interpreted by vi. For example, on a VT100 terminal, or an xterm window, the up arrow key transmits the sequence, ESC, O, A, which says, "finish input mode, open a new line on the line above and enter an upper case A" . The moral of the story is never to press the arrow keys in input mode. But check the next set of esoterica to find out how to make vi actually do what you want here.

Occasionally you'll need to insert control characters into your file which have a special meaning to vi, such as ESC and ENTER. In order to do this, precede them with a CTRL-V. Naturally, a CTRL-V in your file is produced by typing two CTRL-V's in a row.

As well as using just plain yank and put commands with a single buffer, you can yank and delete text into explicitly named buffers for retrieval later. The form of these commands is

" a command

where a is a single lower case character, naming the buffer, and command is either a delete or yank. For instance, to delete 3 lines into buffer "q", type "q3dd. This buffer could then be recovered at any time in the same session by typing "qP. If you specify the buffer name in upper case in a delete or yank operation, the text will be appended to that buffer. For example, "Q3dd will delete 3 lines, and append them to whatever is already in buffer q. While these are buffers are not preserved when you quit vi, they are preserved when you change files with the :e command.

vi also puts anything deleted into numbered buffers: buffer 1 holds the item most recently deleted, buffer 2 the second most recent item to be deleted, and so forth up to buffer number 9. These buffers are retrieved in the same way as the alphabetic buffers, for example, "1p inserts the item most recently deleted after the cursor. The sequence, "1pu.u.u.u. etc. will recover up to the last nine deletions in reverse order.

Another interesting, although rarely used feature is the capability of passing certain portions of the file through a Unix command. For example, you might want to sort the first 20 lines of the file into alphabetical order.

The shell command has the form of either !movement command shell command-ENTER, or count !! shell command-ENTER.

For example, to sort the first twenty lines in the file into alphabetical order, move to the top of the file (1G) and type 20!!sort-ENTER. To right-justify a paragraph you could type !}nroff-ENTER. When you enter the shell command, it will appear on the last line of the screen.

Options and Last-Line Mode

The commands issued in last line mode can be divided into three main groups.

  • Commands for writing to files, changing files, and reading files.
  • Commands for setting and viewing options.
  • Commands for doing complicated search and replace operations.

These commands all start with a colon, and are entered on the last line of the screen. You can edit them using backspace, CTRL-U and CTRL-W, and execute them by pressing ENTER or ESC.

Manipulating Files

The commands in this section are used for reading files into the buffer, writing the buffer to files, changing from one file to another, and exiting vi.

Reading Files with :r

The :r command inserts the contents of a named file into the buffer at the current line. For example, to read in a file called "thang", type :r thang-ENTER. Without an argument, i.e. :r-ENTER, the file you're currently editing will be selected.

Writing Files with :w

The :w command writes the buffer to either the current file or another file. To write the current file, just typed :w-ENTER. To write the contents of the buffer to another file, type :w filename-ENTER. You can also copy the buffer to the end of a file, i.e. append it, by typing :w>> filename-ENTER. Also, a number range can be specified; the command :20,50w thang-ENTER would write lines 20 to 50 of the buffer to a file called "thang".

Changing Files (:e and :n)

It is possible to select another file to edit from within vi, this is done with the :e or :edit command. If you don't specify a file, by typing :e-ENTER, the editor will re-read in the current file. Alternately, you can specify another file by name, e.g. :e thang-ENTER and that file will be read in.

In either case, when you use the :e command, and you've modified the current file, vi will refuse to let you change files unless you either write the current file (i.e. :w-ENTER), or override by typing :e! or :edit! instead.

If you've specified multiple files on the command line, you can change files by typing :n-ENTER or :next-ENTER. Again, you will be warned if you haven't saved your current file.

Exiting vi

There are a number of ways of exiting vi. These were also discussed in Getting into (and out of) vi, but are included here for completeness.

To quit, type :q-ENTER or :quit-ENTER. If you haven't saved your file, you will either have to save it first, or type :q!-ENTER or :quit!-ENTER to quit without saving. The command :x-ENTER will automatically save your file if it's been modified and then quit.

A shortcut for :x-ENTER is to type ZZ in command mode.

Setting and Displaying Options

There are various options that the user can set to govern the way vi displays, and inputs text. One example of this was the showmode option discussed, in Starting to Learn vi.

The command to access these options is :set, and is used in last line mode. Typing :set-ENTER on it's own will display the current settings of a few of the most commonly used options, and any that you've modified since starting vi. Typing :set all-ENTER will show you the current values of all options. You can query the value of a single option by typing :set option?-ENTER, where option is the name of an option.

There are two types of option, those which are toggles, and can be either on or off, and those which take a numeric value. To set a toggle or boolean option, type :set option-ENTER; to turn it off, type :set nooption-ENTER. For example, to activate auto-indentation (q.v.), type :set autoindent-ENTER; to switch it off, type :set noautoindent-ENTER.

With numeric options, the form of the command is :set option=n, where n is a number. For example to set the word wrapping margin (q.v.) to 20, type :set wrapmargin=20-ENTER.


Some Commonly Used Options

While covering all of the options available is beyond the scope of this guide[15], a few of the most useful options will be described here.

autoindent

Auto indentation allows you to enter text so that text on a new line will automatically start underneath the first non-blank character on the previous line.

For example, if you type in a line starting with 3 spaces, and press ENTER, the cursor will automatically start in the fourth column, underneath the first character of the previous line. In order to move the cursor left at this point, use CTRL-D.

It is preferable to use the TAB key to indent, as vi will automatically replace sequences of more than 8 spaces at the start of a line with TAB characters. To use increments of indentation other than TAB characters, set the shiftwidth (abbreviated sw) parameter to the number of spaces you require. For example, many people prefer to indent their program code in increments of four spaces. To do this, type :set shiftwidth=4-ENTER. When entering text, CTRL-T will produce the right number of spaces.

Note that the tabstop and hardtabs options are used for controlling how vi displays TAB characters on your terminal; they are not normally altered.

number

This option causes vi to display a line number to the left of each line. Note that the line numbers are not physically part of their lines; the editing window is effectively shifted to the right to accommodate them. To switch on, type :set number-ENTER; to switch off, :set nonumber-ENTER. These can be abbreviated by :set nu-ENTER and :set nonu-ENTER.

list

Typing :set list-ENTER will cause vi to display all special characters, such as newline and TAB characters. Newlines are represented as dollar signs, and control characters are represented by a caret before the letter, e.g. CTRL-A = ^A.

Since a TAB character is just a CTRL-I, any instances are represented by the sequence ^I.

showmode

The showmode toggle discussed earlier, causes vi to place a message in the bottom right hand corner of the screen indicating whether it's in in input or command mode.

showmatch

When activated, this toggle causes vi to show matching braces and parentheses when in input mode. When a right brace or parenthesis is typed, and the matching left one is on the screen, the cursor will briefly flash on the matching item. If an unmatched right brace or parenthesis is typed, vi will beep in warning.

vi and Ex

Some readers will also be familiar with a UNIX editor called ex, which is a line, rather than screen-based editor. It is useful then to know that your efforts in learning ex have not been in vain. Indeed, in the last section you will notice that some of the commands are suspiciously familiar. This is because ex and vi are essentially two different sides of the same program.

You can switch from ex to vi while editing a file simply by typing vi at the colon (:) prompt in ex. Likewise, you can go from vi to ex by typing Q, while in command mode. You can also enter an ex command whilst in vi simply by preceding it with a colon.

Occasionally, when vi suffers a particularly nasty error, it will change into ex[16]. Just type vi-ENTER at the colon prompt to resume.

Esoterica

Another way of changing your current file is doing so by tag. When you type the command ":ta \em tagname-ENTER", vi looks for a file in the current directory called tags, then looks for an entry for tagname. If an entry is found, vi will change to the file containing that tag. You can generate a tags file for a C program by using the Unix command, ctags. See the manual entry for more information on how this works.

A way of making input less painful is the :abbr or abbreviate command. This has the format of :abbr \em lhs rhs-ENTER, where the left hand side will be replaced by the right hand side whenever it's typed as a single word in input mode. For example, if you're tired of typing "University of Technology, Sydney" a lot, you could put the line

abbr uts University of Technology, Sydney

in your .exrc file. Now, whenever you type uts in input mode, followed by a non alphanumeric character, such as a space, it will be replaced by the full name. To remove an abbreviation, type :unabbr lhs-ENTER. On its own, the :abbr command will show a list of all current abbreviations.

vi also has a parameterless macro facility which allows the user to assign functions to particular key sequences in command mode, using the :map command, and likewise in input mode, using the :map! command.

The :map command has the format of

:map \em lhs rhs-ENTER

where lhs is the keystroke(s) that you want replaced by rhs. For example, if you found you needed to transpose characters a lot, you could type :map T xp-ENTER which would cause a pair of characters to be transposed every time you typed a T in command mode. Note that you would disable the normal effect of a T command by doing this.

More useful however, is the :map! command, which behaves exactly the same way in input mode. One of the most useful applications of this is to re-program the arrow keys so they don't stuff up your file. To re-program the up arrow key to leave input mode, and then move up a line, you'd use the sequence

:map! CTRL-V UP-ARROW SPACE CTRL-V ESC k ENTER

Note that you'll probably need to precede the up arrow key with a CTRL-V, and also the ESC key. (The k tells vi to move the cursor up a line.)

Search and Replace

A search and replace is performed when you want to change some or all occurrences of a particular pattern of characters in your file to something else. For example, in a Pascal program you may want to change all occurrences of the string integer to real and so on.

Seek and Destroy

The search and replace commands are the hardest to master and almost impossible to remember. You will just have to practice these until you get confident about them.

Basic Regular Expressions

In order to replace a pattern you first have to define the pattern to vi in precise terms. This is done by a notation referred to as the regular expression. This notation, used for pattern matching, recurs again and again in UNIX and is well worth the effort of learning[17]. Unfortunately, the discussion of the complete syntax of the regular expression is well beyond the scope of this document, so we will only deal with the basics.

  • The simplest form of a regular expression is a string of normal characters, delineated by two obliques or slashes. For example, /dog/ would search for the pattern "dog".
  • Certain characters however, have special meanings in regular expressions. The two simplest are the caret and dollar sign, which start for "start of line" and "end of line".
    The expression /^procedure/ would find the word "procedure" only if it were at the start of a line. The dollar-sign operates in a similar manner, and the two could be combined: e.g. the pattern /^end$/ would find lines whose sole occupant was the word "end".
  • The full-stop or period matches any single character. Thus the expression /ca./ would find the patterns "cat", "can", "cad" and also "ca ", i.e. a period also matches a space.
  • Brackets can be used to indicate a range of characters to be matched. The expression [a b c] will match any single character that happens to be in the set abc. For example, the pattern /[Vv]i/ would match the words "Vi" and "vi". A range can also be specified, for example, /c[a-z]t/ will match the patterns cat, cbt, cct, etc.
    A caret after the left bracket has the effect of negating the list or range of characters. The expression /c[^au]t/ would match any three letter group starting with "c", ending with "t", but not having "a" or "u" as the middle letter.
  • The most useful (and the most dangerous) special character is the asterisk, which represents "zero or more occurrences of the previous character". Thus, the pattern /a*rgh/ would locate the words "argh", "aaargh", and even "aaaaaaaaaargh"[18]. Needless to say, this can be Very Dangerous. This is where the undo command comes in useful.
  • But what happens if you want to search for an asterisk in your file? In order to nullify these characters in a regular expression, precede them with a backslash, i.e. "\", which is known as the escape character. In order to look for a backslash use two backslashes. For example, if you're editing a TeX file, and you're searching for an \hrule, you'd use the pattern /\\hrule/.

Substitution Commands

Line-Based Substitutions

There are a number of flavours of substitute command. The first variety takes the form of

:s/regexp/string/scope-ENTER

where regexp is a regular expression as described above, and string is the set of characters to replace it with. Without any scope specification, this will substitute the string for the first occurrence of regexp, on the current line. For example, typing <tt>:s/dog/cat/-ENTER will change the first occurrence of the string "dog" to "cat" on the current line. To change all occurrences on the current line, place a g at the end, i.e. :s/dog/cat/g-ENTER.

To have vi ask for confirmation before substituting, add a c at the end, e.g. :s/dog/cat/gc-ENTER. The editor will display each change that it's about to make and prompt you to type in a y-ENTER for "yes", or an n-ENTER (or just ENTER) for "no".

Once you've performed a substitution, typing an ampersand in command mode will cause the substitution to be repeated on the current line.

The s can be prefixed with a line number range, for example, the command :1,30s/dog/cat/g tells the editor to replace all occurrences of "dog" with "cat" on lines 1 to 30. To do a global substitution, you could use :1,$[19], or :g, or even :% (for the last two, see below).

One of the best things about the substitution syntax is that various other shell tools, such as sed, have adopted it. Not exactly, of course, because that would be too easy, but you're sure to find it hauntingly familiar.

Global Substitutions

The next variety, instead of operating on the current line, searches for the next instance of the pattern. It takes the form

:(g)/regexp1/s/regexp2/string/(scope)

where regexp1 and regexp2 are regular expressions. The :g could also be written as :%, in which case the syntax is a bit different -- the s comes before regexp1, thus:

:% s/regexp1/regexp2/(scope).

Note that you still have to use the scope at the end of the line.

What a command of this form says to do is:

  • Search for the next occurrence of regexp1. If preceded by a g, e.g. :g/thing/..., then search for all occurrences.
  • On each line containing regexp1, replace regexp2 with string. If regexp2 is blank, then assume regexp1 is the pattern to be replaced.
  • If the command is terminated with a g, replace all occurrences on each line instead of just the first occurrence.
  • If followed by a c, ask for confirmation before each substitution.

The :g could also be written as :%, in which case the syntax is a bit different -- the s comes before regexp1, thus:

:% s/regexp1/regexp2/(scope).

Note that you still have to use the scope at the end of the line[20].

Sound confusing? The best way to learn this is by example. Take a look at and try out some of the examples below.

Examples

Below are some typical examples of substitution commands.

:/mushroom/s//fungus/

Search for the next occurrence of the word "mushroom" and replace it with "fungus".

:g/procedure/s//function/

Search the entire file and replace the first occurrence of the word "procedure" on each line with word "function".

:g/cat/s//dog/g

Search the entire file replacing every occurrence on every line of "cat" with "dog".

:g/(.*)/s//()/g

This would replace every string between parentheses with nothing, effectively deleting it. Remember the significance of the asterisk, applied to the period: i.e. "zero or more occurrences of any character."

:g/ *$/s///

Trim all trailing blanks of the end of every line in the buffer.

:g/^ */s///

Trim all leading blanks from every line in the buffer.

:g/excrement/d

A slight variation. The d tells vi, to delete the line. Therefore, this has the effect of deleting any line with the word "excrement" in it. Do not, under any circumstances try :g/.*/d. (See if you can work out what it does, though).

:g/3 \* 2/s//3 + 2/g

Replace all expressions "3 * 2" with "3 + 2". Note the use of the backslash to make vi ignore the special meaning of the asterisk.

:g/vi/s//Vi/gc

Replace all occurrences of "vi" with "Vi", but asking for confirmation each time. (Type a "y" to change, an "n" not to change.)


Esoterica

If you thought the other sections of esoterica were bad, then you ain't seen nuthin' yet.

There are a few other significant characters that you can put in regular expressions in vi. Instead of being nullified by the backslash character, they are introduced by the backslash! They are \< and \>, which stand for "start of word" and "end of word" respectively.

For example, the pattern /\<dog/<tt> finds words starting with "dog", but not words with the string "dog" in their middle. The pattern <tt>/\<dog\>/ will only find occurrences of the word "dog".

The other interesting character is the ampersand. When used in the replacement string, it represents the original regular expression. For example, the command :g/th[ai]ng/s//&y/g, will search for occurrences of the pattern "thing" or "thang", replacing them with "thingy" and "thangy" respectively. How bizarre can you get?

If you still don't feel satisfied, some even more twisted variants on regular expressions and replacement strings can be found in [Var90]

Vi Command Summary

The following tables contain a summary of all the commonly used commands for vi and ex. They include the commands already discussed, as well as further commands. Feel free to experiment.

Invoking vi

vi file
view file
vi file1 file2
vi [options] files

Edit at first line of file.
Edit in read-only mode.
Edit multiple files via :n.
As above, with options.

Command-Line Options

+ n<tt>
<tt> +

+/ pattern
-R
-r
-w n

Start editing at line n.
Start editing at last line.
Start at pattern.
Open file as read only.
Attempt file recovery after crash.
Specify window size of n lines.

Exiting vi

ZZ
:x-ENTER
:wq-ENTER
:w-ENTER
:w>>file-ENTER
: m,nw file-ENTER


Exit and save changes, if any.
As above.
Write changes, then quit.
Write changes to original file.
Append buffer to file.
Write lines m to n to file.


Text Input

i
I
a
A
o
O

Insert at character before cursor.
Insert before first non-blank character on line.
Append after cursor.
Append at end of line.
Open and insert at line below.
Open and insert at line above.

Input mode is terminated by pressing ESC.

Input Mode Commands

CTRL-W
CTRL-H
CTRL-U
CTRL-D
CTRL-T

Delete word.
Delete last character.
Erase current line.
Backspace over autoindent.
Insert soft TAB in autoindent.

Screen Adjustment

CTRL-L
CTRL-E
CTRL-Y
CTRL-B
CTRL-F
CTRL-D
CTRL-U

Redraw screen.
Scroll up one line.
Scroll down one line.
Page backwards.
Page forwards.
Scroll down.
Scroll up.

Cursor Motion

H
M
L
l
h
k
j
^
$
n|
tc
w
W
b
B
e
E

Move cursor to top of page.
...to the middle of page.
...to last line of page.
Cursor left.
Cursor right.
Cursor up.
Cursor down.
Move to beginning of current line.
Move to end of current line.
Move to column n.
Move to character c.
Forward one word.
Forward one word including punctuation.
Backward one word.
Ditto including punctuation.
Move to end of word.
Ditto including punctuation.

File Motion

G
nG
/ pattern
? pattern
n
N
)
(
}
{
]]
[[

Last line of file.
Line n of file.
Next line containing pattern.
Previous line containing pattern.
Next ? or /.
Last ? or /.
Next sentence.
Last sentence.
Next paragraph.
Last paragraph.
Next section/function.
Last section/function.

Change

cw
ncw
C
c^
cc
ncc
c/regexp/
c)
c{
c}
s

Change to end of word.
Change n words.
Change from cursor to end of line.
Change from cursor to start of line.
Change line.
Change n lines.
Change from cursor to pattern.
Change to end of sentence.
Change to beginning of paragraph.
Change to end of paragraph.
Deletes the character to the right of the cursor and enters input mode.

Yank and Put

yy or Y
nyy or nY
p
P
"ay
"Ay
"ap
"np

Yank current line into buffer.
Yank n lines into buffer.
Put buffer after cursor.
Put buffer before cursor.
Yank into buffer a where a is a lowercase letter, i.e. a...z.
Append into buffer a.
Put from buffer a.
Yank from buffer n, range 1...9.

Deletion

x
nx
X
nX
dw
ndw
D
dd
ndd
d/regexp
d(
d)
d{
d}
"ad

Delete to the right of the cursor.
Delete n characters to the right of the cursor.
Delete to the left of the cursor.
Delete n characters to the left of the cursor.
Delete to end of word.
Delete n words.
Delete from cursor to end of line.
Delete line.
Delete n lines.
Delete from cursor to pattern.
Delete to beginning of sentence.
Delete to end of sentence.
Delete to beginning of paragraph.
Delete to end of paragraph.
Delete into buffer a.

Replace

r
R

Replace single character.
Overtype until ESC pressed.

Setting Options

:set-ENTER
:set all-ENTER
:set option-ENTER
:set nooption-ENTER
:set option?-ENTER

Shows current settings of most options.
Shows current settings of all options.
Enables option.
Disables option.
Displays current setting of option.

Common Options

wrapmargin=n

Causes automatic word-wrapping n columns from the right-hand side of the window in input mode.


autoindent

Autoindent. In input mode, text will automatically be started below the first printing character of the previous line. Use CTRL-D to move back to previous tab-stops.


number

Line-Numbering. Line numbers are placed on the left-hand side of the text, outside the window, which is shifted to the right.


list

Show hidden characters. Control characters are represented as starting with a caret. (CTRL-A = ^A). Newline characters are represented by dollar signs.


showmatch

When a right parenthesis or bracket is typed in input mode, the cursor will highlight the matching item if it's on the screen.


showmode

Place status message in bottom right-hand corner showing whether vi is in input mode or not.


report=n

This will cause vi to announce any deletions, yankings, or puttings of more than n lines with a message. Setting report to zero will cause these activites to be reported regardless of size.


term=name

Records the terminal type; this should be automatically set. The window parameter records the height (in rows) of the terminal.

Regular Expressions

^
$
.
c*
[abc]
[^abc]
[c1-c2]
\
\>
\<

Beginning of line.
End of line.
Any single character.
Zero or more occurrences of c.
Matches a, b or c.
Matches anything but a, b or c.
Anything in the range c1 to c2
.
Escape character for / \ $ ~ ^ [ ] . *
End of word
Beginning of word

Substitution

:s/regexp/string/-ENTER

Replace the first occurrence of regexp with string on the current line. See Search and Replace for a detailed description of regular expressions and replacement strings.


:s/regexp/string/g-ENTER

Replace all occurrences of regexp with string on the current line.


:g/regexp/s//string/-ENTER

Search the entire file, replacing the first occurrence on each line of regexp with string.


:g/regexp/s//string/g-ENTER

Search the entire file, replacing every occurrence on each line of regexp with string.


:g/regexp/s//string/gc-ENTER

As above, but asking for confirmation each time: type y-ENTER to confirm, n-ENTER or just ENTER to skip.


Miscellany

u
U
.
~
J
>move
>>
<move
<<

Undo last change.
Restore all changes on current line.
Repeat last change.
Reverse case of letter and advance.
Join next line to current line.
Shift one tab stop to the right.
Shift current line to the right.
Shift one tab stop to the left.
Shift current line to the left.


  1. The author suggests that Real Coffee can be found at El Bahsa in Newtown. Please consult Surviving at UTS for an up-to-date list.
  2. It's all very well having pop-up dialog windows appear every time you do a search and replace, but in the end what you really want to do is a search and replace rather than wading through a morass of Are you sure? and Click to Continue boxes.
  3. Three years' worth of programming assignments perhaps?
  4. And sarcastic commentary will be given as footnotes.
  5. "IF the system crashes!?" Sorry, when the system crashes.
  6. This usually happens when you've totally screwed up the file.
  7. Folklore among non-Vi users has it that Vi has three major modes - beep mode, flash mode, and randomly-produce-junk-characters mode.
  8. It's called Ex, pronounced "Ee-Ex", after a line editor of the same name. Essentially, these are the only commands you can give in Ex.
  9. A tilde is a wiggly thing that looks like this: ~ .
  10. In order to determine which sequences erase words and lines, vi just looks at your terminal settings. On Sun workstations, CTRL-U and CTRL-W are fine, but this may not be the case on all systems. If in doubt, check your stty settings.
  11. Also read [Car96] to find an unabridged version of the sample text used in this figure. Or you could just look up "Jabberwocky" on your favourite online search engine. Your choice.
  12. Exactly the same as c$.
  13. Like cl
  14. Note that 6dw and d6w have the same effect
  15. For a more substantial discussion of available options, see [Hew80] and [JM80].
  16. In much the same way your mother changes into an ogre when you haven't tidied your room. Editor's Note: Or your flatmate, for those of you who've moved out of home. Author's Rebuttal: Assuming they're brave enough to enter your room.
  17. You'll undoubtedly meet them in at least one of your subjects at uni, so there's no escape!
  18. Also "rgh". Why? Check the meaning of the asterisk again if you're not sure.
  19. i.e. from line 1 to the last line ($).
  20. I prefer this syntax -- I often use it for editing files uploaded from a PC. The command :% s/^V\^M$// will remove all the extra line feeds that DOS uses. -- Ed'97
Personal tools