////////////////////////////////////////////////////////////////////////
/                         VI REFERENCE (by maart@cs.vu.nl)             /
////////////////////////////////////////////////////////////////////////

default values         : 1
^X                     : <ctrl>x
[*]                    : * is optional
<*>                    : * must not be taken literally
<sp>                   : space
<cr>                   : carriage return
<lf>                   : linefeed
<ht>                   : horizontal tab
<esc>                  : escape
<del>                  : delete
<a-z>                  : an element in the range
N                      : number (* = allowed, - = not used)
CHAR                   : char unequal to <ht>|<sp>
WORD                   : word followed by <ht>|<sp>|<lf>

/////////////////
/ move commands /
/////////////////

 N | Command           | Meaning
---+-------------------+------------------------------------------------------
 * | h | ^H            | <*> chars to the left
 * | j | <lf> | ^N     | <*> lines downward
 * | l | <sp>          | <*> chars to the right
 * | k | ^P            | <*> lines upward
 * | $                 | to the end of line <*> from the cursor
 - | ^                 | to the first CHAR of the line
 * | _                 | to the first CHAR <*> - 1 lines lower
 * | -                 | to the first CHAR <*> lines higher
 * | + | <cr>          | to the first CHAR <*> lines lower
 - | 0                 | to the first char of the line
 * | |                 | to column <*> (<ht>: only to the endpoint !)
 * | f<char>           | <*> <char>s to the right (find)
 * | t<char>           | till before <*> <char>s to the right
 * | F<char>           | <*> <char>s to the left
 * | T<char>           | till after <*> <char>s to the left
 * | ;                 | repeat latest "f"|"t"|"F"|"T" <*> times
 * | ,                 | idem in opposite direction
 * | w                 | <*> words forward
 * | W                 | <*> WORDS forward
 * | b                 | <*> words backward
 * | B                 | <*> WORDS backward
 * | e                 | to the end of word <*> forward
 * | E                 | to the end of WORD <*> forward
 * | G                 | go to line <*> (default EOF)
 * | H                 | to line <*> from top of the screen (home)
 * | L                 | to line <*> from bottom of the screen (last)
 - | M                 | to the middle line of the screen
 * | )                 | <*> sentences forward
 * | (                 | <*> sentences backward
 * | L                 | <*> paragraphs forward
 * | E                 | <*> paragraphs backward
 - | ]]                | to the next section (default EOF)
 - | [[                | to the previous section (default begin of file
 - | `<a-z>            | to the mark
 - | '<a-z>            | to the first CHAR of the line with the mark
 - | ``                | to the cursor position before the latest absol
                       | jump (of which are examples "/" and "G")
 - | ''                | to the first CHAR of the line on which the cur
                       | was placed before the latest absolute jump
 - | /<string>         | to the next occurrence of <string>
 - | ?<string>         | to the previous occurrence of <string>
 - | n                 | repeat latest "/"|"?" (next)
 - | N                 | idem in opposite direction
 - | %                 | find the next bracket and go to its match
                       | (also E L and [ ])

/////////////////////////
/ searching (see above) /
/////////////////////////

^e                     | search in the tags file where the function under the
                       | cursor is defined (file, line) and go to it
:[x,y]g/<string>/<cmd> | search globally [from line x to y] after <string>
                       | and execute the "ex" <cmd> on each occurrence

///////////////////
/ undoing changes /
///////////////////

u                      | undo the latest change
U                      | undo all changes on a line, while not having moved
                       | off it (unfortunately)
:q!                    | quit vi without writing
:e!                    | re-edit a messed-up file

///////////////////////////////////
/ appending text (end with <esc>) /
///////////////////////////////////

 * | a                 | <*> times after the cursor
 * | A                 | <*> times at the end of line
 * | i                 | <*> times before the cursor (insert)
 * | I                 | <*> times before the first CHAR of the line
 * | o                 | on a new line below the current (open)
                       | the count is only useful on a slow terminal
 * | O                 | on a new line above the current
                       | the count is only useful on a slow terminal
 * | ><move>           | shift the lines described by <*><move> one
                       | shiftwidth to the right (layout)
 * | >>                | shift <*> lines one shiftwidth to the right
 * | .                 | repeat latest command <*> times
 * | ["<a-z1-9>]p      | put the contents of the (default undo) buffer <*>
                       | times after the cursor
                       | a buffer containing lines is put only once, below
                       | the current line
 * | ["<a-z1-9>]P      | put the contents of the (default undo) buffer <*>
                       | times before the cursor
                       | a buffer containing lines is put only once, above
                       | the current line

/////////////////
/ deleting text /
/////////////////

Everything deleted can be stored into a buffer. This is achieved by putting a
" and a letter <a-z> before the delete command. The deleted text will be in
the buffer with the used letter. If <A-Z> is used as buffer name, the adjugate
buffer <a-z> will be augmented instead of overwritten with the text. The undo
buffer always contains the latest change. Buffers "<1-9> contain the latest 9
LINE deletions ("1 is most recent).

 * | x                 | delete <*> chars under and after the cursor
 * | X                 | <*> chars before the cursor
 * | d<move>           | from begin to endpoint of <*><move>
 * | dd                | <*> lines
 - | D                 | the rest of the line
 * | <<move>           | shift the lines described by <*><move> one
                       | shiftwidth to the left (layout)
 * | <<                | shift <*> lines one shiftwidth to the left
 * | .                 | repeat latest command <*> times

/////////////////////////////////
/ changing text (end with <esc> /
/////////////////////////////////

 * | r<char>           | replace <*> chars by <char> - no <esc>
 * | R                 | overwrite the rest of the line, append <*> - 1 times
 * | s                 | substitute <*> chars
 * | S                 | <*> lines
 * | c<move>           | change from begin to endpoint of <*><move>
 * | cc                | <*> lines
 * | C                 | the rest of the line and <*> - 1 next lines
 * | =<move>           | if the option 'lisp' is set, this command will
                       | realign the lines described by <*><move> as though
                       | they had been typed with the option 'ai' set too
 - | ~                 | switch lower and upper cases
 * | J                 | join <*> lines (default 2)
 * | .                 | repeat latest command <*> times ("J" only once)
 - | &                 | repeat latest "ex" substitute command, e.g.
                       | ":s/wrong/good"

//////////////////////////////
/ remembering text (yanking) /
//////////////////////////////

With yank commands you can put "<a-z> before the command, just as with
delete commands. Otherwise you only copy to the undo buffer. The use of buffers
<a-z> is THE way of copying text to another file: see the ":e <file>" command.

 * | y<move>           | yank from begin to endpoint of <*><move>
 * | yy                | <*> lines
 * | Y                 | idem (should be equivalent to "y$" though)
 - | m<a-z>            | mark the cursor position with a letter

////////////////////////////////////////
/ commands while in append|change mode /
////////////////////////////////////////

^@                     | if typed as the first character of the insertion, it
                       | is replaced with the previous text inserted (max. 128
                       | chars), after which the insertion is terminated
^V                     | deprive the next char of its special meaning
                       | (e.g. <esc>)
^D                     | one shiftwidth to the left
0^D                    | remove all indentation on the current line
                       | (there must be no other chars on the line)
^^D                    | idem, except that it is restored on the next line
^T                     | one shiftwidth to the right
^H                     | one char back
^W                     | one word back
^U                     | back to the begin of the change on the current line
                       | (generally your kill char)
<del>                  | like <esc>

/////////////////////////////////////////////////
/ writing, editing other files, and quitting vi /
/////////////////////////////////////////////////

:q                     | quit vi after writing
:q!                    | quit vi without writing
:w                     | write the file
:w <name>              | write to the file <name>
:w >> <name>           | append the buffer to the file <name>
:w! <name>             | overwrite the file <name>
:x,y w <name>          | write lines x through y to the file <name>
:wq                    | write the file and quit vi, WITHOUT checking if the
                       | write has been successful (use "ZZ" instead)
ZZ                     | write if the buffer has been changed, and quit vi
:x                     | idem
:x!                    | ":w!" and ":q"
:e <file>              | edit another file without quitting vi - the buffers
                       | are not changed (except the undo buffer), so text can
                       | be copied from one file to another this way
:e! <file>             | idem, without writing the current buffer
:e#                    | edit the previous file
^^                     | idem
:rew                   | edit the first file (when "vi file1 file2 ...")
:rew!                  | idem, without writing the current buffer
:n [<file>]            | edit the next file
:n! [<file>]           | idem, without writing the current buffer

////////////////////
/ display commands /
////////////////////

^G                     | give current line number and relative position
^L                     | refresh the screen (sometimes "^P" or "^R")
^R                     | sometimes vi replaces a deleted line by a '@', to be
                       | deleted by "^R" (also with option 'noredraw')
[*]^E                  | scroll <*> lines downward
[*]^Y                  | scroll <*> lines upward
[*]^D                  | scroll <*> lines downward
                       | (default the number of the previous scroll;
                       | initialization: half a page)
[*]^U                  | scroll <*> lines upward
                       | (default the number of the previous scroll;
                       | initialization: half a page)
[*]^F                  | <*> pages forward
[*]^B                  | <*> pages backward (in older versions only ^B works)

If in the next commands the field <wi> is present, the windowsize will change
to <wi>. The window will always be displayed at the bottom of the screen.

[*]z[wi]<cr>           | put line <*> at the top of the window
                       | (default the current line)
[*]z[wi]+              | put line <*> at the top of the window
                       | (default the first line of the next page)
[*]z[wi]-              | put line <*> at the bottom of the window
                       | (default the current line)
[*]z[wi].              | put line <*> in the centre of the window
                       | (default the current line)

////////////////////////////
/ mapping and abbreviation /
////////////////////////////

When mapping turn off the option 'timeout' by ":set noto", and with 'map!'
turn on 'remap' by ":set remap".

:map <string> <seq>    | <string> is interpreted as <seq>, e.g.
                       | ":map ^C :!cc %^V<cr>" to compile from within vi
                       | (vi replaces % by the current file name)
:map                   | show all mappings
:unmap <string>        | deprive <string> of its mapping
                       | when vi complains about non-mapped macros (whereas
                       | no typos are made), first do something like
                       | ":map <string> Z", followed by ":unmap <string>"
                       | ('Z' must not be a macro itself)
:map! <string> <seq>   | mapping in append mode, e.g.
                       | ":map! \be begin^V<cr>end;^V<esc>O<ht>"
                       | when <string> is preceded by ^V, no mapping is done
:map!                  | show all append mode mappings
:unmap! <string>       | deprive <string> of its mapping (see ":unmap")
:ab <string> <seq>     | whenever in append mode <string> is followed by a
                       | breakpoint (e.g. <sp> or ','), it is interpreted as
                       | <seq>, e.g. ":ab p procedure"
                       | a char preceded by ^V is not considered a breakpoint
:ab                    | show all abbreviations
:unab <string>         | do not consider <string> an abbreviation anymore
                       | (see ":unmap")
@<a-z>                 | consider the contents of the named register a
                       | command, e.g.:
                       |       o0^D:s/wrong/good/<esc>"zdd
                       | explanation:
                       |       o              - open a new line
                       |       0^D            - remove indentation
                       |       :s/wrong/good/ - this input text is an "ex"
                       |                        substitute command
                       |       <esc>          - finish the input
                       |       "zdd           - delete the line just created,
                       |                        into register 'z'
                       | now you can type @z to substitute 'wrong' by 'good'
                       | on the current line
@@                     | repeat last register command

/////////////////////////////
/ switch and shell commands /
/////////////////////////////

Q | <del><del>         | switch from vi to "ex"
:                      | an "ex" command can be given
:vi                    | switch from "ex" to vi
:sh                    | execute a subshell, back to vi by ^D
:!<cmd>                | execute a shell <cmd>
:!!                    | repeat the last shell command
[*]!<move><cmd>        | the shell executes <cmd>, with as standard inp
                       | lines described by <*><move>, next the standard
                       | output replaces those lines
                       | (think of cb, sort, nroff, etc.)
[*]!!<cmd>             | give <*> lines as standard input to the shell <cmd>,
                       | next let the standard output replace those lines
:x,y w !<cmd>          | let lines x to y be standard input for <cmd>
                       | (notice the space between 'w' and '!')
:r!<cmd>               | put the output of <cmd> onto a new line
:r <name>              | read the file <name> into the buffer

//////////////
/ vi startup /
//////////////

vi [file]              : edit the file and display the first page

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

       EXINIT='<cmd>|<cmd>|...'
       <cmd>:  set options
               map ...
               ab ...
       export EXINIT (in the Bourne shell)

However, the list of initializations can also be put into a file. If this
file is located in your home directory, and is named ".exrc" AND the
variable EXINIT is NOT set, the list will be automatically excuted at
startup time. If the 3 conditions are not met, you have to give the execute
command yourself:

       :source file
or
       :so file

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

vi +x file             : the cursor will immediately jump to line x
vi +/<string> file     : ~ to the first occurrence of <string>

Sometimes (e.g. if the system crashed while you were editing) it is possible
to recover files lost in the editor by "vi -r file".
If you just want to view a file by using vi, and you want to avoid any change,
instead of vi you can use the "view" command: the option 'readonly' will be set
automatically (with ":w!" you can override this option).
The most important options are:

ai                     | autoindent - in append mode after a <cr> the cursor
                       | will move directly below the first CHAR on the
                       | previous line.
                       | however, if the option 'lisp' is set, the cursor
                       | will align at the first argument to the last open
                       | list.
aw                     | autowrite - write at every shell escape
                       | (useful when compiling from within vi)
dir=<string>           | directory - the directory for vi to make temporary
                       | files (default /tmp)
eb                     | errorbells - beeps when you goof
                       | (not on every terminal)
ic                     | ignorecase - no distinction between upper and lower
                       | cases when searching
lisp                   | redefine the following commands:
                       | "(", ")"   - move backward (forward) over
                       |              S-expressions
                       | "E", "L"   - idem, but don't stop at atoms
                       | "[[", "]]" - go to previous (next) line beginning
                       |              with a '('
                       | see option 'ai'
list                   | <lf> is shown as '$', <ht> as '^I'
magic                  | some metachars can be used when searching:
                       | ^<string>    - <string> must begin the line
                       | <string>$    - <string> must end the line
                       | .            - matches any char
                       | [a-z]        - matches any char in the range
                       | [<string>]   - matches any char in <string>
                       | [^<string>]  - matches any char not in <string>
                       | <char>*      - 0 or more <char>s
                       | \<<string>\> - <string> must be a word
nu                     | number - numbers before the lines
para=<string>          | paragraphs - every pair of chars in <string> is
                       | considered a paragraph delimiter nroff macro (for "E"
                       | and "L").
                       | a <sp> preceded by a '\' indicates that the previous
                       | char is a single letter macro.
                       | ":set para=P\ bp" introduces '.P' and '.bp' as
                       | paragraph delimiters.
                       | furthermore completely empty lines and section
                       | boundaries are paragraph boundaries too.
redraw                 | the screen remains up to date
report=<*>             | vi reports whenever e.g. a delete
                       | or yank command affects <*> or more lines
ro                     | readonly - the file is not to be changed
                       | however, ":w!" will override this option
sect=<string>          | sections - gives the section delimiters (for "[[" and
                       | "]]"); see option 'para', however a 'E' as first
                       | char on a line also starts a section (C functions!)
sh=<string>            | shell - which program is to be used for shell escapes
sw=<*>                 | shiftwidth - gives the swiftwidth (default sw=8)
sm                     | showmatch - whenever you append a ')', vi tries to
                       | show its match by putting for a moment the cursor
                       | onto it (also with E L)
terse                  | short error messages
ts=<*>                 | tabstop - the length of a <ht>;
                       | warning: this is only IN the editor, outside of it
                       | <ht>s have their normal length (default ts=8)
wa                     | writeany - no checks when writing (dangerous)
warn                   | warn you when you try to quit without writing
wi=<*>                 | window - the number of lines vi is to show default
wm=<*>                 | wrapmargin - when in append mode vi automatically
                       | puts a <lf> whenever there is a breakpoint (e.g. <sp>
                       | or ',') within <wm> columns from the right margin
ws                     | wrapscan - when searching, the end is considered
                       | 'stuck' to the begin of the file

:set option            | turn option on
:set no option         | turn option off; no <sp> between "no" and the option
:set option=value      | give an option a value
:set                   | show all non-default options and their values
:set option?           | show an option's value
:set all               | show all options and their values