Based on "An Introduction to Display Editing with Vi" by William Joy and Mark Horton of UC Berkeley.
Edited by aleksey@verticalsysadmin.com
Created: 30 Aug 2012
Last updated: 31 Aug 2012
Change |
Delete |
Copy |
From cursor to… |
cH |
dH |
yH |
Top of screen |
cL |
dL |
yL |
Bottom of screen |
c+ |
d+ |
y+ |
Next line |
c5| |
d5| |
y5| |
Column 5 of current line |
2c) |
2d) |
2y) |
Second sentence following |
c{ |
d{ |
y{ |
Previous paragraph |
c/pattern |
d/pattern |
y/pattern |
Pattern |
cn |
dn |
yn |
Next pattern |
cG |
dG |
yG |
End of file |
c13G |
d13G |
y13G |
Line number 13 |
If you are using a slow terminal, are on a slow connection or on a heavily loaded host, you can speed up editing by reducing your display window size so vi can redraw it faster.
Changing window size
zxCR will set window size to x lines and redraw the screen.
Terminal speed |
Default window size |
< 1200 baud |
8 lines |
1200 baud |
16 lines |
> 1200 baud |
full screen (24 lines) |
zCR Place line on the 1st line of the display.
z. Place line in the center of the display.
z- Place line in the last line of the display.
xzCR Place line x on the 1st line of the display.
xz. Place line x in the center of the display.
xz- Place line x in the last line of the display.
Current POSIX spec (2008) allows to resize window and reposition text all in one command - this functionality is present in vim 7.4.
xzyCR
xz.y
xz-y
The options are of three kinds:
You can set numeric and string options by
set opt=val
You can set or unset toggle options by
set opt
set noopt
Name |
Default |
Description |
autoindent |
noai |
Supply indentation automatically |
autowrite |
noaw |
Automatic write before :n, :tag, etc. |
ignorecase |
noic |
Ignore case in searching |
list |
nolist |
Tabs print as ^I; end of lines marked with $ |
number |
nonu |
Lines are displayed prefixed with line numbers |
shiftwidth |
sw=8 |
Shift distance for <, > and input D and T |
showmatch |
nosm |
Show matching ( or { as ) or } is typed |
Set options while you are running vi:
:set optCR
:set opt=valCR
Options set by the set command only last while you stay in the editor.
To make these options persist, add them to your shell start file into the EXINIT variable:
EXINIT=set nu
export EXINIT
Get a list of all options which you have changed:
:setCR
Get the value of a single option:
:set opt?CR.
Get the list of all possible options and their values:
:set allCR
Set can be abbreviated se.
Multiple options can be placed on one line, e.g.:
se ai aw nuCR
A typical startup 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).
Put in your .profile file in your home directory:
EXINIT=set ai aw terse|map @ dd|map # x
export EXINIT
You might have a serious problem if you delete a number of lines and then regret that they were deleted AND your editor does not have multi-level undo.
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 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.
Try:
"1p……..
to show you all the deleted text which has been saved for you.
If the system crashes, you can recover the work you were doing to within a few changes.
% 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.
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.
When editing programs, you often want to maintain an indented structure to the body of the program.
The editor has an 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, enter a few tabs, and type some characters. 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.
^^D kills autoindent for the current line only
0^D kills all the autoindent
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 right or left.
Try >L and <L shifting the rest of the display right and left.
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 {, (in the first column), 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]].
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.
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.
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.
Put the macro body in a buffer register, say x. You can then type @x to invoke the macro.
@@ will repeat the last macro.
:map lhs rhsCR
will map lhs into rhs.
Restrictions:
To get a space, tab or newline into lhs or rhs you should escape them with a ^V.
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.
In vim, this would be:
:nmap q :wq^VCR CR
to setup a map for normal mode (command mode).
Exercises:
Macros can be deleted with
unmap lhs
The undo command reverses an entire macro call as a unit, if it made any changes.
map! makes the mapping apply to input mode, rather than command mode.
Exercise: Map "yt" to "Yours Truly,CR" Enter some text in input mode starting with y and observe the 1 second wait for the second macro character.
In vim, !map applies to Insert mode and Command-line mode, and imap applies to Insert mode only.
A feature similar to macros in input mode is word abbreviation.
This allows you to type a short word and have it expanded into a longer word or words.
The commands are :abbreviate and :unabbreviate (:ab and :una) and have the same syntax as :map. For example:
:ab eecs Electrical Engineering and Computer Sciences
causes the word ‘eecs’ to always be changed into the phrase ‘Electrical Engineering and Computer Sciences’.
Word abbreviation is different from macros in that only whole words are affected. You could say macros force the editor to be more sensitive to your input than to abbreviations.
There is no need for an abbreviation to be a single keystroke, as it should be with a macro.
Exercise: Set up an abbreviation from your Linux login name to your full real name. Go into input mode, and type your login name and then another word and watch when the abbreviation is expanded.
The editor has a number of short commands which abbreviate longer commands which we have introduced here.
They often save a bit of typing and you can learn them as convenient.
For example:
A - $a
I - ^i
D - d$
C - c$
S - cc
The editor folds long logical lines onto many physical lines in the display. Commands which advance lines advance logical lines and will skip over all the segments of a line in one motion.
The command | moves the cursor to a specific column, and may be useful for getting near the middle of a long line to split it in half.
Tip: Try 80| on a line which is more than 80 columns long.
The editor only puts full lines on the display; if there is not enough room on the display to fit a logical line, the editor leaves the physical line empty, placing only an @ on the line as a place holder. When you delete lines on a dumb terminal, the editor will often just clear the lines to @ to save time (rather than rewriting the rest of the screen.)
Exercise:
If you wish, you can have the editor place line numbers before each line on the display.
:se nuCR - enable line numbering
:se nonuCR - disable line numbering
:se listCR - have tabs represented as ^I and the ends of lines indicated with ‘$’
:se nolistCR - turn this off
Lines consisting of only the character ‘~’ are displayed when the last line in the file is in the middle of the screen. These represent physical lines which are past the logical end of file.
Most vi commands will use a preceding count to affect their behavior in some way. The following table gives the common ways in which the counts are used:
new window size |
: / ? [[ ]] ` ´ |
(does not work in vim) |
scroll amount |
^D ^U |
(does not work in vim) |
line/column number |
z G | |
|
repeat effect |
most of the rest |
10a+----ESC will insert a grid-like string of text.
Except for a few commands which ignore any counts (such as ^L), the rest of the editor commands use a count to indicate a simple repetition of their effect. Thus 5w advances five words on the current line, while 5RETURN advances five lines.
A very useful instance of a count as a repetition is a count given to the . command, which repeats the last changing command. If you do dw and then 3., you will delete first one and then three words. You can then delete two more words with 2..
If you make changes to the editor’s copy of a file, but do not wish to write them back, then you must give an ! after the command you would otherwise use; this forces the editor to discard any changes you have made. Use this carefully.
The following table lists the file manipulation commands which you can use in vi.
:w |
write back changes |
:wq |
write and quit |
:x |
write (if necessary) and quit (same as ZZ). |
:w name |
write buffer to file name |
:w %.bak |
make a backup of the current file. % is replaced with current file name. |
:w! name |
overwrite file name |
:x,yw name |
write lines x through y to name. |
:'x,'yw name |
write mark x to y to name. |
:e name |
edit file name |
:e! |
reedit current file, discarding changes |
:e name + |
edit file name, starting at end |
:e name +n |
edit name, but run command n first (e.g.: +4 or +/pattern or r !/bin/echo Updated on: `date`). Same argument can be given to vi when first loading the file. |
:e # |
edit alternate file (the alternate file name is usually the previously edited file) |
:r name |
read file name into buffer |
:r !cmd |
read output of cmd into buffer |
:n |
edit next file in argument list |
:n! |
edit next file, discarding changes to current |
:n args |
specify new argument list (can use wildcards) |
:ta tag |
edit file containing tag tag, at tag |
If you are editing large programs, you will find the :ta command very useful.
/usr/bin/ctags can create a data base of function names and their locations
vi can use this database to quickly find a function whose name you give.
If the :ta command will require the editor to switch files, then you must :w or abandon any changes by switching with :ta!.
You can repeat the :ta command without any arguments to look for the same tag again.
When you are searching for strings in the file with / and ?, the editor normally places you at the next or previous occurrence of the string.
If you are using an operator such as d, c or y, then you may well wish to affect lines up to the line before the line containing the pattern. You can give a search of the form /pattern/-n to refer to the n'th line before the next line containing pattern, or you can use + instead of - to refer to the lines after the one containing pattern.
If you don’t give a line offset, then the editor will affect characters up to the match place, rather than whole lines; thus use “+0” to affect to the line which matches.
You can have the editor ignore the case of words in the searches it does by giving the command :se icCR. The command :se noicCR turns this off.
Strings given to searches may actually be regular expressions. If you do not want or need this facility, you should
set nomagic
in your EXINIT. In this case, only the characters ^ and $ are special in patterns. The character \ is also then special (as it is most everywhere in the system), and may be used to get at the an extended pattern matching facility. (see next slide)
Note: It is necessary to use a \ before a / in a forward scan or a ? in a backward scan.
The following table gives the extended forms when magic is set.
^ at beginning of pattern, matches beginning of line
$ at end of pattern, matches end of line
. matches any character
\< matches the beginning of a word
\> matches the end of a word
[str] matches any single character in str
[^str] matches any single character not in str
[x-y] matches any character between x and y
* matches any number of the preceding pattern
If you use nomagic mode, then the . [ and * primitives are given with a preceding \.
There are a number of characters which you can use to make corrections during input mode. These are summarized in the following table.
^H, erase |
deletes the last input character |
^W |
deletes the last input word |
kill |
your kill character, deletes the input on this line |
ESC |
ends an insertion |
CR |
starts a new line |
^D |
backtabs over autoindent |
0^D |
kills all the autoindent |
D |
same as 0^D, but restores indent next line |
^V |
quotes the next non-printing character into the file |
Your system kill character (such as ^U), will erase all the input you have given on the current line.
In general, you can neither erase input back around a line boundary nor can you erase characters which you did not insert with this insertion command.
To make corrections on the previous line after a new line has been started you can hit ESC to end the insertion, move over and make the correction, and then return to where you were to continue.
A general way of typing non-printing characters into the file is to precede them with a ^V. The ^V echoes as a ^ character on which the cursor rests. This indicates that the editor expects you to type a control character. In fact you may type any character and it will be inserted into the file at that point.
Vi is actually one mode of editing within the editor ex. When you are running vi you can escape to the line oriented editor of ex by giving the command Q.
There are a number of things which you can do more easily in ex than in vi. Systematic changes in line oriented material are particularly easy.
Example of global (and partial) search and replace
Backreferences \1 through \9 using \( \) Backreference &
Please email aleksey@verticalsysadmin.com