Alan P.W. Hewett
Revised for version 2.12 by Mark Horton
This document does not claim to be 100% complete. There are a few commands listed in the original document that I was unable to test either because I do not speak lisp, because they required programs we don't have, or because I wasn't able to make them work. In these cases I left the command out. The commands listed in this document have been tried and are known to work. It is expected that prospective users of this document will read it once to get the flavor of everything that vi can do and then use it as a reference document. Experimentation is recommended. If you don't understand a command, try it and see what happens.
[Note: In revising this document, I have attempted to make it completely reflect version 2.12 of vi. It does not attempt to document the VAX version (version 3), but with one or two exceptions (wrapmargin, arrow keys) everything said about 2.12 should apply to 3.1. Mark Horton]
[option] is used to denote optional parts of a command. Many vi commands have an optional count. [cnt] means that an optional number may precede the command to multiply or iterate the command. {variable item} is used to denote parts of the command which must appear, but can take a number of different values. <character [character]> means that the character or one of the characters in the range described between the two angle brackets is to be typed. For example <esc> means the escape key is to be typed. <az> means that a lower case letter is to be typed. ^<character> means that the character is to be typed as a control character, that is, with the <cntl> key held down while simultaneously typing the specified character. In this document control characters will be denoted using the upper case character, but ^<uppercase chr> and ^<lowercase chr> are equivalent. That is, for example, <^D> is equal to <^d>. The most common character abbreviations used in this list are as follows:
<esc> <cr>
<lf> <nl> <bs> <tab> <bell> <ff> <sp> <del> |
escape, octal 033 carriage return, ^M, octal 015 linefeed ^J, octal 012 newline, ^J, octal 012 (same as linefeed) backspace, ^H, octal 010 tab, ^I, octal 011 bell, ^G, octal 07 formfeed, ^L, octal 014 space, octal 040 delete, octal 0177 |
To run vi the shell variable TERM must be defined and exported to your environment. How you do this depends on which shell you are using. You can tell which shell you have by the character it prompts you for commands with. The Bourne shell prompts with `$', and the C shell prompts with `%'. For these examples, we will suppose that you are using an HP 2621 terminal, whose termcap name is ``2621''.
To manually set your terminal type to 2621 you would type:
TERM=2621 |
* On a version 6 system without environments, the invocation of tset is simpler, just add the line ``tset -d 2621'' to your .login or .profile.
[cnt]<bs> or [cnt]h or [cnt]¬
Move the cursor to the left one character. Cursor stops at the left margin of the page. If cnt is given, these commands move that many spaces. |
[cnt]^N or [cnt]j or [cnt]¯ or [cnt]<lf>
Move down one line. Moving off the screen scrolls the window to force a new line onto the screen. Mnemonic: Next |
[cnt]^P or [cnt]k or [cnt]
Move up one line. Moving off the top of the screen forces new text onto the screen. Mnemonic: Previous |
[cnt]<sp> or [cnt]l or [cnt]®
Move to the right one character. Cursor will not go beyond the end of the line. |
[cnt] |
[cnt]+ or [cnt]<cr>
Move the cursor down the screen to the beginning of the next line. Scroll up if necessary. |
|
[cnt]$ |
Move the cursor to the end of the line. If there is a count, move to the end of the line "cnt" lines forward in the file. |
^ 0 [cnt]| [cnt]w |
Move the cursor to the beginning of the first word on the line. Move the cursor to the left margin of the current line. Move the cursor to the column specified by the count. The default is column zero. Move the cursor to the beginning of the next word. If there is a count, then move forward that many words and position the cursor at the beginning of the word. Mnemonic: nextword |
[cnt]W |
Move the cursor to the beginning of the next word which follows a "white space" (<sp>,<tab>, or <nl>). Ignore other punctuation. |
[cnt]b [cnt]B |
Move the cursor to the preceding word. Mnemonic: backupword Move the cursor to the preceding word that is separated from the current word by a "white space" (<sp>,<tab>, or <nl>). |
[cnt]e |
Move the cursor to the end of the current word or the end of the "cnt"'th word hence. Mnemonic: endofword |
[cnt]E |
Move the cursor to the end of the current word which is delimited by "white space" (<sp>,<tab>, or <nl>). |
[line number]G |
|
Move the cursor to the line specified. Of particular use are the sequences "1G" and "G", which move the cursor to the beginning and the end of the file respectively. Mnemonic: Goto |
NOTE: The next four commands (^D, ^U, ^F, ^B) are not true motion commands, in that they cannot be used as the object of commands such as delete or change.
[cnt]^D |
Move the cursor down in the file by "cnt" lines (or the last "cnt" if a new count isn't given. The initial default is half a page.) The screen is simultaneously scrolled up. Mnemonic: Down |
[cnt]^U |
Move the cursor up in the file by "cnt" lines. The screen is simultaneously scrolled down. Mnemonic: Up |
[cnt]^F |
Move the cursor to the next page. A count moves that many pages. Two lines of the previous page are kept on the screen for continuity if possible. Mnemonic: Forwardapage |
[cnt]^B |
Move the cursor to the previous page. Two lines of the current page are kept if possible. Mnemonic: Backupapage |
[cnt]( |
Move the cursor to the beginning of the next sentence. A sentence is defined as ending with a ".", "!", or "?" followed by two spaces or a <nl>. |
[cnt]) [cnt]} |
Move the cursor backwards to the beginning of a sentence. Move the cursor to the beginning of the next paragraph. This command works best inside nroff documents. It understands two sets of nroff macros, -ms and -mm, for which the commands ".IP", ".LP", ".PP", ".QP", "P", as well as the nroff command ".bp" are considered to be paragraph delimiters. A blank line also delimits a paragraph. The nroff macros that it accepts as |
paragraph delimiters is adjustable. See paragraphs under the Set Commands section. |
|
[cnt]{ ]] |
Move the cursor backwards to the beginning of a paragraph. Move the cursor to the next "section", where a section is defined by two sets of nroff macros, -ms and -mm, in which ".NH", ".SH", and ".H" delimit a section. A line beginning with a <ff><nl> sequence, or a line beginning with a "{" are also considered to be section delimiters. The last option makes it useful for finding the beginnings of C functions. The nroff macros that are used for section delimiters can be adjusted. See sections under the Set Commands section. |
[[ % |
Move the cursor backwards to the beginning of a section. Move the cursor to the matching parenthesis or brace. This is very useful in C or lisp code. If the cursor is sitting on a ( ) { or } the cursor is moved to the matching character at the other end of the section. If the cursor is not sitting on a brace or a parenthesis, vi searches forward until it finds one and then jumps to the match mate. |
[cnt]H |
If there is no count move the cursor to the top left position on the screen. If there is a count, then move the cursor to the beginning of the line "cnt" lines from the top of the screen. Mnemonic: Home |
[cnt]L |
If there is no count move the cursor to the beginning of the last line on the screen. If there is a count, then move the cursor to the beginning of the line "cnt" lines from the bottom of the screen. Mnemonic: Last |
M m<az> |
Move the cursor to the beginning of the middle line on the screen. Mnemonic: Middle This command does not move the cursor, but it marks the place in the file and the character "<az>" becomes the label for referring to this location in the file. See the next two commands. Mnemonic: mark NOTE: The mark command is not a motion, and cannot be used as the target of commands such as delete. |
´<az> <az> |
Move the cursor to the beginning of the line that is marked with the label "<az>". Move the cursor to the exact position on the line that was marked with with the label "<az>". |
´´ |
Move the cursor back to the beginning of the line where it was before the last "nonrelative" move. A "nonrelative" move is something such as a search or a jump to a specific line in the file, rather than moving the cursor or scrolling the screen. Move the cursor back to the exact spot on the line where it was located before the last |
"nonrelative" move. |
The following commands allow you to search for items in a file.
[cnt]f{chr} | |
Search forward on the line for the next or "cnt"'th occurrence of the character "chr". The cursor is placed at the character of interest. Mnemonic: find character |
|
[cnt]F{chr} |
|
Search backwards on the line for the next or "cnt"'th occurrence of the character "chr". The cursor is placed at the character of interest. |
|
[cnt]t{chr} |
|
Search forward on the line for the next or "cnt"'th occurrence of the character "chr". The cursor is placed just preceding the character of interest. Mnemonic: move cursor up to character |
|
[cnt]T{chr} |
|
Search backwards on the line for the next or "cnt"'th occurrence of the character "chr". The cursor is placed just preceding the character of interest. |
|
[cnt]; [cnt], |
Repeat the last "f", "F", "t" or "T" command. Repeat the last "f", "F", "t" or "T" command, but in the opposite search direction. This is useful if you overshoot. |
[cnt]/[string]/<nl>
Search forward for the next occurrence of "string". Wrap around at the end of the file does occur. The final </> is not required. |
[cnt]?[string]?<nl>
Search backwards for the next occurrence of "string". If a count is specified, the count becomes the new window size. Wrap around at the beginning of the file does occur. The final <?> is not required. |
n |
N |
:g/[string]/[editor command]<nl>
Using the : syntax it is possible to do global searches ala the standard UNIX "ed" editor. |
The following commands allow for the insertion of text. All multicharacter text insertions are terminated with an <esc> character. The last change can always be undone by typing a u. The text insert in insertion mode can contain newlines.
a{text}<esc>
A{text}<esc> i{text}<esc> I{text}<esc> o{text}<esc> |
Insert text immediately following the cursor position. Mnemonic: append Insert text at the end of the current line. Mnemonic: Append Insert text immediately preceding the cursor position. Mnemonic: insert Insert text at the beginning of the current line. Insert a new line after the line on which the cursor appears and insert text there. Mnemonic: open new line |
|
O{text}<esc> |
Insert a new line preceding the line on which the cursor appears and insert text there. |
The following commands allow the user to delete text in various ways. All changes can always be undone by typing the u command.
[cnt]x
[cnt]X D [cnt]d{motion} |
Delete the character or characters starting at the cursor position. Delete the character or characters starting at the character preceding the cursor position. Deletes the remainder of the line starting at the cursor. Mnemonic: Delete the rest of line |
Deletes one or more occurrences of the specified motion. Any motion from sections 4.1 and 4.2 can be used here. The d can be stuttered (e.g. [cnt]dd) to delete cnt lines. |
The following commands allow the user to simultaneously delete and insert new text. All such actions can be undone by typing u following the command.
r<chr> |
Replaces the character at the current cursor position with <chr>. This is a one character replacement. No <esc> is required for termination. Mnemonic: replace character |
R{text}<esc> |
Starts overlaying the characters on the screen with whatever you type. It does not stop until an <esc> is typed. |
[cnt]s{text}<esc>
Substitute for "cnt" characters beginning at the current cursor position. A "$" will appear at the position in the text where the "cnt"'th character appears so you will know how much you are erasing. Mnemonic: substitute |
[cnt]S{text}<esc>
Substitute for the entire current line (or lines). If no count is given, a "$" appears at the end of the current line. If a count of more than 1 is given, all the lines to be replaced are deleted before the insertion begins. |
[cnt]c{motion}{text}<esc>
Change the specified "motion" by replacing it with the insertion text. A "$" will appear at the end of the last item that is being deleted unless the deletion involves whole lines. Motion's can be any motion from sections 4.1 or 4.2. Stuttering the c (e.g. [cnt]cc) changes cnt lines. |
Vi provides a number of ways of moving chunks of text around. There are nine buffers into which each piece of text which is deleted or "yanked" is put in addition to the "undo" buffer. The most recent deletion or yank is in the "undo" buffer and also usually in buffer 1, the next most recent in buffer 2, and so forth. Each new deletion pushes down all the older deletions. Deletions older than 9 disappear. There is also a set of named registers, az, into which text can optionally be placed. If any delete or replacement type command is preceded by "<az>, that named buffer will contain the text deleted after the command is executed. For example, "a3dd will delete three lines starting at the current line and put them in buffer "a.* There are two more basic commands and some variations useful in getting and putting text into a file.
["<az>][cnt]y{motion}
Yank the specified item or "cnt" items and put in the "undo" buffer or the specified buffer. The variety of "items" that can be yanked is the same as those that can be deleted with the "d" command or changed with the "c" command. In the same way that "dd" means delete the current line and "cc" means replace the current line, "yy" means yank the current line. |
["<az>][cnt]Y |
Yank the current line or the "cnt" lines starting from the current line. If no buffer is specified, they will go into the "undo" buffer, like any delete would. It is equivalent to "yy". Mnemonic: Yank |
["<az>]p |
Put "undo" buffer or the specified buffer down after the cursor. If whole lines were yanked or deleted into the buffer, then they will be put down on the line following the line the cursor is on. If something else was deleted, like a word or sentence, then it will be inserted immediately following the cursor. Mnemonic: put buffer It should be noted that text in the named buffers remains there when you start editing a new file with the :e file<esc> command. Since this is so, it is possible to copy or delete text from one file and carry it over to another file in the buffers. However, the undo buffer and the ability to undo are lost when changing files. |
["<az>]P |
Put "undo" buffer or the specified buffer down before the cursor. If whole lines where yanked or deleted into the buffer, then they will be put down on the line preceding the line the cursor is on. If something else was deleted, like a word or sentence, then it will be inserted immediately preceding the cursor. |
[cnt]>{motion} |
The shift operator will right shift all the text from the line on which the cursor is located to the line where the motion is located. The text is shifted by one shiftwidth. (See section 6.) >> means right shift the current line or lines. |
[cnt]<{motion} |
The shift operator will left shift all the text from the line on which the cursor is located to the line where the item is located. The text is shifted by one shiftwidth. (See section 6.) << means left shift the current line or lines. Once the line has reached the left margin it is not further affected. |
[cnt]={motion} |
Prettyprints the indicated area according to lisp conventions. The area should be a lisp sexpression. |
Vi has a number of miscellaneous commands that are very useful. They are:
ZZ |
This is the normal way to exit from vi. If any changes have been made, the file is written out. Then you are returned to the shell. |
^L |
Redraw the current screen. This is useful if someone "write"s you while you are in "vi" or if for any reason garbage gets onto the screen. |
^R |
On dumb terminals, those not having the "delete line" function (the vt100 is such a terminal), vi saves redrawing the screen when you delete a line by just marking the line with an "@" at the |
* Referring to an upper case letter as a buffer name (AZ) is the same as referring to the lower case letter, except that text placed in such a buffer is appended to it instead of replacing it.
beginning and blanking the line. If you want to actually get rid of the lines marked with "@" and |
|
:q[!] |
Causes vi to exit. If you have modified the file you are looking at currently and haven't written it out, vi will refuse to exit unless the "!" is supplied. |
:e[!] [+[cmd]] [file]
Start editing a new file called "file" or start editing the current file over again. The command ":e!" says "ignore the changes I've made to this file and start over from the beginning". It is useful if you really mess up the file. The optional "+" says instead of starting at the beginning, start at the "end", or, if "cmd" is supplied, execute "cmd" first. Useful cases of this are where cmd is "n" (any integer) which starts at line number n, and "/text", which searches for "text" and starts at the line where it is found. |
^^ |
Switch back to the place you were before your last tag command. If your last tag command stayed within the file, ^^ returns to that tag. If you have no recent tag command, it will return to the same place in the previous file that it was showing when you switched to the current file. |
:n[!] |
Start editing the next file in the argument list. Since vi can be called with multiple file names, the ":n" command tells it to stop work on the current file and switch to the next file. If the current file was modifies, it has to be written out before the ":n" will work or else the "!" must be supplied, which says discard the changes I made to the current file. |
:n[!] file [file file ...]
Replace the current argument list with a new list of files and start editing the first file in this new list. |
:r file
:r !cmd :!cmd :ta[!] tag |
Read in a copy of "file" on the line after the cursor. Execute the "cmd" and take its output and put it into the file after the current line. Execute any UNIX shell command. Vi looks in the file named tags in the current directory. Tags is a file of lines in the format: tag filename visearchcommand If vi finds the tag you specified in the :ta command, it stops editing the current file if necessary and if the current file is up to date on the disk and switches to the file specified and uses the search pattern specified to find the "tagged" item of interest. This is particularly useful when editing multifile C programs such as the operating system. There is a program called ctags which will generate an appropriate tags file for C and f77 programs so that by saying :ta function<nl> you will be switched to that function. It could also be useful when editing multifile documents, though the tags file would have to be generated manually. |
Vi takes the value of $TERM and looks up the characteristics of that terminal in the file /etc/termcap. If you don't know vi's name for the terminal you are working on, look in /etc/termcap.
When vi starts, it attempts to read the variable EXINIT from your environment.* If that exists, it takes the values in it as the default values for certain of its internal constants. See the section on "Set Values" for further details. If EXINIT doesn't exist you will get all the normal defaults.
Should you inadvertently hang up the phone while inside vi, or should the computer crash, all may not be lost. Upon returning to the system, type:
vi -r file |
This will normally recover the file. If there is more than one temporary file for a specific file name, vi recovers the newest one. You can get an older version by recovering the file more than once. The command "vi r" without a file name gives you the list of files that were saved in the last system crash (but not the file just saved when the phone was hung up).
* On version 6 systems Instead of EXINIT, put the startup commands in the file .exrc in your home directory.
Vi has a number of internal variables and switches which can be set to achieve special affects. These options come in three forms, those that are switches, which toggle from off to on and back, those that require a numeric value, and those that require an alphanumeric string value. The toggle options are set by a command of the form:
:set option<nl> |
and turned off with the command:
:set nooption<nl> |
Commands requiring a value are set with a command of the form:
:set option=value<nl> |
To display the value of a specific option type:
:set option?<nl> |
To display only those that you have changed type:
:set<nl> |
and to display the long table of all the settable parameters and their current values type:
:set all<nl> |
Most of the options have a long form and an abbreviation. Both are listed in the following table as well as the normal default value.
To arrange to have values other than the default used every time you enter vi, place the appropriate set command in EXINIT in your environment, e.g.
EXINIT='set ai aw terse sh=/bin/csh' |
export EXINIT |
|
or |
|
setenv EXINIT 'set ai aw terse sh=/bin/csh' |
for sh and csh, respectively. These are usually placed in your .profile or .login. If you are running a system without environments (such as version 6) you can place the set command in the file .exrc in your home directory.
autoindent ai |
Default: noai Type: toggle |
autoprint ap |
Default: ap Type: toggle |
autowrite aw |
Default: noaw type: toggle |
beautify bf |
Default: nobf Type: toggle |
directory dir |
Default: dir=/tmp Type: string |
errorbells eb |
Default: noeb Type: toggle |
hardtabs ht |
Default: hardtabs=8 Type: numeric |
ignorecase ic |
Default: noic Type: toggle |
lisp |
Default: nolisp Type: toggle |
list |
Default: nolist Type: toggle |
magic |
Default: magic Type: toggle |
number nu |
Default: nonu Type: toggle |
open |
Default: open Type: toggle |
optimize opt |
Default: opt Type: toggle |
paragraphs para |
|
Default: para=IPLPPPQPP bp Type: string :set paragraphs=P\ bp<nl> would cause vi to consider .P and .bp as paragraph delimiters. |
|
prompt |
Default: prompt Type: toggle |
redraw |
Default: noredraw Type: toggle |
report |
Default: report=5 Type: numeric |
scroll |
Default: scroll={1/2 window} Type: numeric |
sections |
Default: sections=SHNHH HU Type: string |
shell sh |
Default: sh=from environment SHELL or /bin/sh Type: string |
shiftwidth sw |
Default: sw=8 Type: numeric |
showmatch sm |
Default: nosm Type: toggle |
on the current screen. |
|
slowopen slow |
Default: terminal dependent Type: toggle |
tabstop ts |
Default: ts=8 Type: numeric |
taglength tl |
Default: tl=0 Type: numeric |
term |
Default: (from environment TERM, else dumb) Type: string |
terse |
Default: terse Type: toggle |
warn |
Default: warn Type: toggle |
window |
Default: window={8 at 600 baud or less, 16 at 1200 baud, and screen size - 1 at 2400 baud or more} Type: numeric |
w300, w1200, w9600
These set window, but only within the corresponding speed ranges. set w300=4 w1200=12 |
They are useful in an |
causes a 4 lines window at speed up to 600 baud, a 12 line window at 1200 baud, and a full screen
(the default) at over 1200 baud.
wrapscan ws |
Default: ws Type: toggle |
wrapmargin wm |
|
Default: wm=0 Type: numeric |
|
writeany wa |
Default: nowa Type: toggle |