XXXX
COPYRIGHT
INDEX

vi(1) Reference Manual Chapter 6

Special topics

  1. Editing on slow terminals
  2. Options, set, and editor startup files
  3. Recovering lost lines
  4. Recovering lost files
  5. Continuous text input
  6. Features for editing programs
  7. Filtering portions of the buffer
  8. Commands for editing LISP
  9. Macros

6.1. Editing on slow terminals

When you are on a slow terminal, it is important to limit the amount of output which is generated to your screen so that you will not suffer long delays, waiting for the screen to be refreshed. We have already pointed out how the editor optimizes the updating of the screen during insertions on dumb terminals to limit the delays, and how the editor erases lines to @ when they are deleted on dumb terminals.

The use of the slow terminal insertion mode is controlled by the slowopen option. You can force the editor to use this mode even on faster terminals by giving the command :se slowCR. If your system is sluggish this helps lessen the amount of output coming to your terminal. You can disable this option by :se noslowCR.

The editor can simulate an intelligent terminal on a dumb one. Try giving the command :se redrawCR. This simulation generates a great deal of output and is generally tolerable only on lightly loaded systems and fast terminals. You can disable this by giving the command :se noredrawCR.

The editor also makes editing more pleasant at low speed by starting editing in a small window, and letting the window expand as you edit. This works particularly well on intelligent terminals. The editor can expand the window easily when you insert in the middle of the screen on these terminals. If possible, try the editor on an intelligent terminal to see how this works.

You can control the size of the window which is redrawn each time the screen is cleared by giving window sizes as argument to the commands which cause large screen motions:

         :  /  ?  [[  ]]  `  '
Thus if you are searching for a particular instance of a common string in a file you can precede the first search command by a small number, say 3, and the editor will draw three line windows around each instance of the string which it locates.

You can easily expand or contract the window, placing the current line as you choose, by giving a number on a z command, after the z and before the following RETURN, . or -. Thus the command z5. redraws the screen with the current line in the center of a five line window.+

If the editor is redrawing or otherwise updating large portions of the display, you can interrupt this updating by hitting a DEL or RUB as usual. If you do this you may partially confuse the editor about what is displayed on the screen. You can still edit the text on the screen if you wish; clear up the confusion by hitting a ^L; or move or search again, ignoring the current state of the display.

See section 7.8 on open mode for another way to use the vi command set on slow terminals.

6.2. Options, set, and editor startup files

The editor has a set of options, some of which have been mentioned above. The most useful options are given in the following table.
 Name         Default               Description
 ______________________________________________________________________________________
 autoindent   noai                  Supply indentation automatically
 autowrite    noaw                  Automatic write before :n, :ta, [ctrl]^, !
 ignorecase   noic                  Ignore case in searching
 lisp         nolisp                ( { ) } commands deal with S-expressions
 list         nolist                Tabs print as ^I; end of lines marked with $
 magic        nomagic               The characters . [ and * are special in scans
 number       nonu                  Lines are displayed prefixed with line numbers
 paragraphs   para=IPLPPPQPbpP LI   Macro names which start paragraphs
 redraw       nore                  Simulate a smart terminal on a dumb one
 sections     sect=NHSHH HU         Macro names which start new sections
 shiftwidth   sw=8                  Shift distance for <, > and input ^D and ^T
 showmatch    nosm                  Show matching ( or { as ) or } is typed
 slowopen     slow                  Postpone display updates during inserts
 term         dumb                  The kind of terminal you are using.
The options are of three kinds: numeric options, string options, and toggle options. You can set numeric and string options by a statement of the form
         set opt=val
and toggle options can be set or unset by statements of one of the forms
         set opt
         set noopt
These statements can be placed in your EXINIT in your environment, or given while you are running vi by preceding them with a : and following them with a CR.

You can get a list of all options which you have changed by the command :setCR, or the value of a single option by the command :set opt?CR. A list of all possible options and their values is generated by :set allCR. Set can be abbreviated se. Multiple options can be placed on one line, e.g. :se ai aw nuCR.

Options set by the set command only last while you stay in the editor. It is common to want to have certain options set whenever you use the editor. This can be accomplished by creating a list of ex commands+ which are to be run every time you start up ex, edit, or vi. A typical list includes a set command, and possibly a few map commands. Since it is advisable to get these commands on one line, they can be separated with the | character, for example:

         set ai aw terse|map @ dd|map # x
which sets the options autoindent, autowrite, terse, (the set command), makes @ delete a line, (the first map), and makes # delete a character, (the second map). (See section 6.9 for a description of the map command) This string should be placed in the variable EXINIT in your environment. If you use the shell csh, put this line in the file .login in your home directory:

         setenv EXINIT 'set ai aw terse|map @ dd|map # x'
If you use the standard shell sh, put these lines in the file .profile in your home directory:
         EXINIT='set ai aw terse|map @ dd|map # x'
         export EXINIT
Of course, the particulars of the line would depend on which options you wanted to set.
+ Note that the command 5z. has an entirely different effect, placing line 5 in the center of a new window.

6.3. Recovering lost lines

You might have a serious problem if you delete a number of lines and then regret that they were deleted. Despair not, the editor saves the last 9 deleted blocks of text in a set of numbered registers 1-9. You can get the n'th previous deleted text back in your file by the command "np. The " here says that a buffer name is to follow, n is the number of the buffer you wish to try (use the number 1 for now), and p is the put command, which puts text in the buffer after the cursor. If this doesn't bring back the text you wanted, hit u to undo this and then . (period) to repeat the put command. In general the . command will repeat the last change you made. As a special case, when the last command refers to a numbered text buffer, the . command increments the number of the buffer before repeating the command. Thus a sequence of the form
         "1pu.u.u.
will, if repeated long enough, show you all the deleted text which has been saved for you. You can omit the u commands here to gather up all this text in the buffer, or stop after any . command to keep just the then recovered text. The command P can also be used rather than p to put the recovered text before rather than after the cursor.
+ All commands which start with : are ex commands.

6.4. Recovering lost files

If the system crashes, you can recover the work you were doing to within a few changes. You will normally receive mail when you next login giving you the name of the file which has been saved for you. You should then change to the directory where you were when the system crashed and give a command of the form:

         % vi -r name
replacing name with the name of the file which you were editing. This will recover your work to a point near where you left off.+

You can get a listing of the files which are saved for you by giving the command:

         % vi -r
If there is more than one instance of a particular file saved, the editor gives you the newest instance each time you recover it. You can thus get an older saved copy back by first recovering the newer copies.

For this feature to work, vi must be correctly installed by a super user on your system, and the mail program must exist to receive mail. The invocation ``vi -r'' will not always list all saved files, but they can be recovered even if they are not

6.5. Continuous text input

When you are typing in large amounts of text it is convenient to have lines broken near the right margin automatically. You can cause this to happen by giving the command :se wm=10CR. This causes all lines to be broken at a space at least 10 columns from the right hand edge of the screen.

If the editor breaks an input line and you wish to put it back together you can tell it to join the lines with J. You can give J a count of the number of lines to be joined as in 3J to join 3 lines. The editor supplies white space, if appropriate, at the juncture of the joined lines, and leaves the cursor at this white space. You can kill the white space with x if you don't want it.


+ In rare cases, some of the lines of the file may be lost. The editor will give you the numbers of these lines and the text of the lines will be replaced by the string `LOST'. These lines will almost always be among the last few which you changed. You can either choose to discard the changes which you made (if they are easy to remake) or to replace the few lost lines by hand.

6.6. Features for editing programs

The editor has a number of commands for editing programs. The thing that most distinguishes editing of programs from editing of text is the desirability of maintaining an indented structure to the body of the program. The editor has a autoindent facility for helping you generate correctly indented programs.

To enable this facility you can give the command :se aiCR. Now try opening a new line with o and type some characters on the line after a few tabs. If you now start another line, notice that the editor supplies white space at the beginning of the line to line it up with the previous line. You cannot backspace over this indentation, but you can use ^D key to backtab over the supplied indentation.

Each time you type ^D you back up one position, normally to an 8 column boundary. This amount is settable; the editor has an option called shiftwidth which you can set to change this value. Try giving the command :se sw=4CR and then experimenting with autoindent again.

For shifting lines in the program left and right, there are operators < and > These shift the lines you specify right or left by one shiftwidth. Try << and >> which shift one line left or right, and <L and >L shifting the rest of the display left and right.

If you have a complicated expression and wish to see how the parentheses match, put the cursor at a left or right parenthesis and hit %. This will show you the matching parenthesis. This works also for braces { and }, and brackets [ and ].

If you are editing C programs, you can use the [[ and ]] keys to advance or retreat to a line starting with a {, i.e. a function declaration at a time. When ]] is used with an operator it stops after a line which starts with }; this is sometimes useful with y]].

6.7. Filtering portions of the buffer

You can run system commands over portions of the buffer using the operator !. You can use this to sort lines in the buffer, or to reformat portions of the buffer with a pretty-printer. Try typing in a list of random words, one per line and ending them with a blank line. Back up to the beginning of the list, and then give the command !}sortCR. This says to sort the next paragraph of material, and the blank line ends a paragraph.

6.8. Commands for editing LISP

If you are editing a LISP program you should set the option lisp by doing :se lispCR. This changes the ( and ) commands to move backward and forward over s-expressions. The { and } commands are like ( and ) but don't stop at atoms. These can be used to skip to the next list, or through a comment quickly.

The autoindent option works differently for LISP, supplying indent to align at the first argument to the last open list. If there is no such argument then the indent is two spaces more than the last level.

There is another option which is useful for typing in LISP, the showmatch option. Try setting it with :se smCR and then try typing a `(' some words and then a `)'. Notice that the cursor shows the position of the `(' which matches the `)' briefly. This happens only if the matching `(' is on the screen, and the cursor stays there for at most one second.

The editor also has an operator to realign existing lines as though they had been typed in with lisp and autoindent set. This is the = operator. Try the command =% at the beginning of a function. This will realign all the lines of the function declaration.

When you are editing LISP,, the [[ and ]] advance and retreat to lines beginning with a (, and are useful for dealing with entire function definitions.

6.9. Macros

Vi has a parameterless macro facility, which lets you set it up so that when you hit a single keystroke, the editor will act as though you had hit some longer sequence of keys. You can set this up if you find yourself typing the same sequence of commands repeatedly.

Briefly, there are two flavors of macros:

  1. Ones where you put the macro body in a buffer register, say x. You can then type @x to invoke the macro. The @ may be followed by another @ to repeat the last macro.
  2. You can use the map command from vi (typically in your EXINIT) with a command of the form: :map lhs rhsCR
mapping lhs into rhs. There are restrictions: lhs should be one keystroke (either 1 character or one function key) since it must be entered within one second (unless notimeout is set, in which case you can type it as slowly as you wish, and vi will wait for you to finish it before it echoes anything). The lhs can be no longer than 10 characters, the rhs no longer than 100. To get a space, tab or newline into lhs or rhs you should escape them with a ^V. (It may be necessary to double the ^V if the map command is given inside vi, rather than in ex.) Spaces and tabs inside the rhs need not be escaped.

Thus to make the q key write and exit the editor, you can give the command


         :map q :wq^V^VCR CR
which means that whenever you type q, it will be as though you had typed the four characters :wqCR. A ^V's is needed because without it the CR would end the : command, rather than becoming part of the map definition. There are two ^V's because from within vi, two ^V's must be typed to get one. The first CR is part of the rhs, the second terminates the : command.

Macros can be deleted with

         unmap lhs
If the lhs of a macro is ``#0'' through ``#9'', this maps the particular function key instead of the 2 character ``#'' sequence. So that terminals without function keys can access such definitions, the form ``#x'' will mean function key x on all terminals (and need not be typed within one second.) The character ``#'' can be changed by using a macro in the usual way:
         :map ^V^V^I #
to use tab, for example. (This won't affect the map command, which still uses #, but just the invocation from visual mode.

The undo command reverses an entire macro call as a unit, if it made any changes.

Placing a `!' after the word map causes the mapping to apply to input mode, rather than command mode. Thus, to arrange for ^T to be the same as 4 spaces in input mode, you can type:


         :map ^T ^Vbbbb
where b is a blank. The ^V is necessary to prevent the blanks from being taken as white space between the lhs and rhs.