# VI[M] Editor Command Reference #

Table of Contents
1. Introduction - Basic Info
2. The Tiniest Bit of History - vi vs. vim
3. Conventions - How To Understand This Document
4. Invoking vi[m] - How to Start Vi[m]
5. Settings & Your .vimrc - Enhance the Convenience
6. Command Mode Access Command - You won't get far without this.
7. Edit Mode Access Commands - Just try to edit without Edit Mode...
8. Mastering the Vim Command Line
9. File Commands - Opening, Saving, Closing
10. Cursor Movement Commands - How to Get Around
11. Edit Commands - How to Do Stuff
12. Markers - Convenient Location Memory Tool
13. Search Commands - With Regular Expressions!
14. Search & Replace - Also with regex!
15. Vi Metacharacters - "Characters About Characters"
16. Using Vim Editing Windows - Edit Multiple Files Simultaneously!
17. Tags - How to Navigate Intelligently
18. Visual Mode - How to Select Text Quickly
20. Macros - How to Record and "Play back" Complex Operations
98. Other Vi[m] References
99. Miscellaneous Useful Stuff


^ Back to Top
1. Introduction
vi is unlike most other
editors in that it has two
"modes". These are:
COMMAND mode and INSERT mode.

When you are in COMMAND mode,
the characters you type will
perform special functions
(commands), instead of appearing
on the screen in your document.

When you are in INSERT mode,
the characters you type will appear
like normal.

One advantage of having these two
distinct modes is that you can perform
a very large and diverse number of complex
functions without ever moving your hands
from the "home row" on your QWERTY
keyboard.

I have found that after working through
the first few painful days of becoming
accostomed to this new editing concept,
I am able to edit files (especially programs)
much, much more quickly than before.

As is usually the case, the quickest
way to master the vi editor is practice.
USE IT. The command keys will soon flow
from your fingers in a way you cannot
even imagine now.  :-)
Give it a shot. You'll probably like it.
(And while you're shooting it, make sure
you search this document for "undo"...
it will save you a lot of time and anguish.)

This document attempts to provide an
at-a-glance explanation for many
of the vi commands.

For more precise and in-depth documentation,
see the vim help files, by typing
:h[elp]
at the vim command-line.
NOTE: To navigate the help files,
you need to have a basic understanding
of tags.

^ Back to Top
2. The Tiniest Bit of History
The original vi editor has the basic
functionality described here. But more
recently, a new editor has been developed:
vim (standing for vi-improved).
The vim editor is extremely capable, as
well as well-documented.

This document is written for the real
newbies (as well as the old-bies who, like
myself, are constantly forgetting old tricks).

I have probably made mistakes in this
document. If you find one, PLEASE
email me!

^ Back to Top
3. Conventions
I've tried to specify the relevant help-keywords
below the title of each section.

For example, in section 7 (Edit Mode Access) you see
":help inserting" under the title. If you run
that help command in vim you will be taken to
the part of the actual vim manual that deals
with that topic.
Commands preceeded by a colon
must be typed on the COMMAND LINE.
To reach the COMMAND LINE, type a
colon (":") while you are in
COMMAND MODE.

I will point out here that vim (like
bash) has the beautiful feature of
TAB-COMPLETION. That means that when
you are typing commands on the vim command
line, you can press the TAB key, and vim
will guess what your command is going to be.
(vim will guess command names and filenames!)
And if you use my .vimrc (see below),
vim will present you with a menu of
available options whenever there is
ambiguity in your command line at
the time you press TAB.
Commands with no colon may
be typed at any time you are
in COMMAND MODE.
Commands preceeded by this string:
bash $
are shell commands, runable from the
Linux command line. (They will only be
used in the "Invoking vi" section, below.)

Ok, so I'm lying just a little. I also
mention shell commands in one other place-
in the Misc section.
If there appear to be two commands
separated by a comma, that is probably
the case. Either performs the same
function.
For example: ZZ, :wq
Means that either "ZZ" or ":wq" saves
your work and quits.
Unless otherwise noted, an optional number
in a command string (usually denoted 'n' in
this document) always defaults to '1' if it
is not present.
Except for the regular expression usage
of the brackets ("[" and "]"), arguments
and portions of arguments in brackets are
optional.
Except for the regular expression usage
of the braces ("{" and "}"), braces with
pipes ("|") represent a choice you must
make. For example:
{h | j | k | l}
means that you must choose "h", "j", "k",
or "l" as an argument.

^ Back to Top
4. Invoking vi[m]
bash $ vi ["filename"] begins a vi session, editing "filename",
if "filename" is specified (default is to open
a blank session)
bash $ vim ["filename"] begins a vim session, editing "filename",
if "filename" is specified (default is to open
a blank session)
bash $ alias vi=vim makes the command 'vi' invoke vim instead,
but only for the current shell

To make this "permanent" (which I recommend),
insert that command line into your ".bashrc"
file, located in your home directory.
(Make sure to look your .bashrc
over first, in case your administrator has
asked you to make your personalizations
in another file.)

Once you have determined into which file
you should insert your environment
personalizations, typing the following
string of characters would do so.
(In this example, the string "filename"
represents your filename, and you should
substitute yours for it. "{CR}" represents
a Carriage Return, and "{ESC}" represents
the Escape key.) Keystrokes:
vim filename{CR}
Goalias vi=vim{ESC}:wq!
bash $ man vi shows you the manual for vi
This will let you know about all
the arguments you can pass to vi,
so that it behaves in different ways.
bash $ man vim shows you the manual for vim
This will let you know about all
the arguments you can pass to vim,
so that it behaves in different ways.

^ Back to Top
5. Settings & Your .vimrc
One of the cool things about vim is
that you can control much of your environment
through a config file, which lives
in your home directory and is called
".vimrc".
This file is examined every time you
start a vim session, and it can create
a whole host of settings for you.

Here is my entire vim setup: my vimsettings.
Run
bash $ tar -xzvf vim_settings.tgz
in your home directory to use my settings,
which have been compiled from a number of sources.
CAUTION: Yours will be overwritten!
:set shows you the current settings of your vim session

^ Back to Top
6. Command Mode Access Command
ESC Enter COMMAND mode
(may be repeated in case you
are not sure in which mode you are)

CAUTION! If you are using classic vi,
hitting ESC twice will exit your editor!

^ Back to Top
7. Edit ("Insert") Mode Access Commands
:help inserting
i Enter INSERT mode, and place the cursor
before the current character.
I Enter INSERT mode, and place the cursor
at the beginning of the line.
a Enter INSERT mode, and place the cursor
after the current character.
A Enter INSERT mode, and place the cursor
at the end of the current line.
o Enter INSERT mode, and place the cursor
in a new, blank line below the current line.
O Enter INSERT mode, and place the cursor
in a new, blank line above the current line.

^ Back to Top
8. Mastering the Vim Command Line
The vim command line behaves in a manner
similar to the bash or ksh command lines
when they are in emacs mode.

<irony> THE VIM EDITOR USES EMACS-
STYLE COMMAND LINE EDITING.
</irony>
That means that some of the editing keys from
emacs work on the vim command line. These include...
^a place the cursor at the beginning of the
current command line ("^a" means CTRL-a)
^e place the cursor at the End of the
current command line ("^e" means CTRL-e)
^p, up-arrow recall previous commands, travelling
upward through your command history
("^p" means CTRL-p)
^n, down-arrow recall next command, if you have
already travelled upward into your
command history ("^n" means CTRL-n)
^c abort current command & return
to editor ("^c" means CTRL-c)
^u erase current command line and
place cursor at its beginning,
after the colon ("^u" means CTRL-u)
ESC (pressed twice) abort current command & return
to editor (same functionality as "^c")

^ Back to Top
9. File Commands
In general, following a command with
an exclamation point forces the command
to execute and squelches warnings.
You will see examples of this below.
:w[rite] Write current file
:w[rite] "filename" Write to "filename"
:w[rite]! "filename" Write to "filename" even though "filename" exists
:m,nw "filename" Write lines m through n to "filename"
:q[uit] Quit
ZZ, :wq Combination of ":w[rite]" and ":q[uit]";
Write current file and quit
:wq! This time I MEAN IT!!! WRITE AND QUIT!!
Seriously, squelches "This file is read only,
are you SURE you want to write to it?" warning.
:q[uit]! Quit without saving changes
:r[ead] "filename" Read and insert contents of "filename"
after current cursor location
:e[dit] "filename" Close current file, and open "filename"
in its place.
:e[dit]! "filename" Close current file, discarding changes,
and open "filename" in its place.
^g, :f[ile] report information about the current file ("^g" means CTRL-g)

^ Back to Top
10. Cursor Movement Commands
:help left-right-motions
:help up-down-motions
:help scroll-down
:help scroll-up
:help scroll-cursor
The regular arrow keys may work
in your vim setup. I would
recommend that you learn the
following "home row" movement
commands, however. First of all,
the original vi won't let you use
the arrow keys, and you may be forced
to use it someday. Secondly, by using
the arrow keys you lose so much of the
benefit of being able to do everything
you want to without needing to
move your hand...

'h','j','k', and 'l' will quickly
become natural to you, and you will
be frustrated that other editors
don't have this convenience.
h move left one position
l move right one position
j move down one line
k move up one line
gj move down one screen line
(avoids line-wrap annoyances)
gk move up one screen line
(avoids line-wrap annoyances)
0 (zero) move to beginning of current line
$ move to end of current line
w move forward one word
(punctuation delimited)
W move forward one word
(whitespace delimited)
b move backward one word
(punctuation delimited)
B move backward one word
(whitespace delimited)
e move to the end of the current word
(punctuation delimited)
E move to the end of the current word
(whitespace delimited)
[n]^e scroll forward n "Extra" lines
("^e" means CTRL-e)
[n]^y scroll back n lines
NOTE: In MS Windows, CTRL-y
is remapped to "redo".
("^y" means CTRL-y)
[n]^b scroll back n pages
("^b" means CTRL-b)
[n]^f scroll forward n pages
("^f" means CTRL-f)
[n]^u scroll back (Up) n/2 pages
("^u" means CTRL-u)
[n]^d scroll forward (Down) n/2 pages
("^d" means CTRL-d)
G go to end of file
nG, :n go to line n
L go to last ("Low") line on screen
M go to middle line on the screen
H go to first ("High") line on screen

^ Back to Top
11. Edit Commands
:help deleting
:help { delete-insert | replacing }
:help { simple-change | changing }
:help complex-change
:help copy-move
:help formatting
:help C-indenting
In general, 'd' deletes.
Preceeding 'd' with a number
makes that many deletions happen,
and following 'd' with a movement
command (h,j,k,l,w,b,e,W,B,E)
makes the deletion happen in that
direction.
[n]x delete n characters
[n]dw delete n words
[n]dd delete n lines
d$ delete to end of line
d^ delete to beginning of line
dgg delete through beginning of file
dG delete through end of file
[n]cw change n words (delimited by punctuation)
[n]cW change n words (delimited by whitespace)
c$ change to end of line
c^ change to beginning of line
cG change through last line
[n]~ switch the case of the next n characters
"Yanking" takes some portion of
your file and places it in a "buffer",
so that you can "place" that portion
of your file somewhere else.
(You are probably familiar with the
analogous terms "copy" and "paste".)

In this somewhat out of context place,
I will mention that if you wish to paste
into vi from another application you should:
1. be in insert mode
2. have "paste" set (Run ":set paste" on
the vi command line.)
[n]yw yank (copy) n words
(delimited by punctuation)
[n]yW yank (copy) n words
(delimited by whitespace)
yy yank (copy) current line
[n]yy yank (copy) n lines
y$ yank (copy) to end of current line
y^ yank (copy) to beginning of current line
[n]p place the contents of the buffer
after the current cursor location,
n times
[n]P place the contents of the buffer
before the current cursor location,
n times
All of the above commands yank into and place
from the default buffer. It is also possible
to yank into a named buffer.
The advantage of this is that you can have
several different things available for
placing ("pasting") at any time.

For example, right now I can 'place'
A new table, a new row, or a new
'separating' row, like the one above
this cell. (Go ahead, look at it.)
Thus, with three keystrokes, I
can place any one of those three
html constructs into my file, and
I avoid the hassle of typing each
and every html tag repeatedly...

So how can you do that? Read on...
A buffer may be named with a single
character. I'm not exactly sure which
ones are available, I just use the
alphabetic characters.

Any of the above yanking or placing
commands can be preceeded by (literally):
"a
Where the 'a' is the name of your buffer.

For example,
"t3yy
copies the current line and the next
two lines into the buffer named 't'.

To place the contents of a buffer,
use the same syntax.
For example:
"tp
places the contents of the buffer named
't' after the current cursor location.

I have read that the original vi editor
only has 4 named buffers, so whenever
you write to a fifth, the first is
destroyed. I really don't know how many
the vim (vi-improved) editor has... I've
never used more than 4 or 5.

The only way to master these is to experiment.
In time, you'll find these methods of
duplicating and moving your text so much
more convenient than constantly moving
your hand to your mouse and scrolling,
copying, pasting, scrolling, copying,
pasting...
r replace current character
R replace (overstrike) until
you enter command mode (by pressing ESC)
[n]u undo the last n changes you made
U undo all changes to current line
[n]^r redo the last n changes you
undid

^ Back to Top
12. Markers
:help mark-motions
You can have "markers" in your file,
meaning that a certain line-location in your file
can be named by a marker, so that you can
return to it instantly if you desire to do so.
(This can prevent you from scrolling back and
forth in a file time after time after time...)
ma mark the current location and name it 'a'
(I'm not sure which characters may be used
to name markers, but I've never needed more than
a few alphabetic characters.)
'a jump immediately to the marker named 'a'

^ Back to Top
13. Search Commands
:help search-commands
Regular expressions may be used here,
see list of metacharacters below.
/searchstring search forward for "searchstring"
?searchstring search backward for "searchstring"
[#]n repeat last search # times, whatever it was
(1 is default for #)
[#]N repeat last search # times, but search in
opposite direction
(1 is default for #)
* searches forward for the word currently under the cursor
# searches backward for the word currently under the cursor

^ Back to Top
14. Search & Replace
:help substitute
Regular expressions may be used here,
see list of metacharacters below.
:[scope]s/searchstring/replacestring/[g][c][i] search for "searchstring" and
replace it with "replacestring"

By default, the search & replacement
only happens in your current line.
Including the optional 'scope' argument
can change that. (Possible values for
a 'scope' argument specified below.)

By default, the search & replacement
only happens for the first instance of
"searchstring" on a line.
Including the optional 'g' suffix
changes that to be "Global", all instances
of "searchstring" are replaced on a line.

By default, the search & replacement
happens all at once.
Including the optional 'c' suffix
changes that, and each replacement
must be actively "Confirmed" before
it is performed.

By default, the search & replacement
is case-sensitive.
Including the optional 'i' suffix
changes that, and the operation
happens with case "Insensitivity".
Possible definitions of "scope"
% entire file
m,n include lines m through n
'<,'> text selected in Visual Mode

^ Back to Top
15. Vi Metacharacters
(characters that mean more than themselves)
These will likely be very confusing at first,
so start small. It will help if you familiarize
yourself with such tools as sed, awk, and grep,
and the language PERL, as well.

NOTE: The vi metacharacters differ slightly from
those in other regex tools.

ADDITIONAL NOTE: I neglected to refer to the "magic"
and "nomagic" modes in this section; this is an
important oversight which I hope to correct someday.
^ matches the start of a line
$ matches the end of a line
. matches any single character
(except an end-of-line)
\p printable character
\s whitespace (space or tab) character
- same as typing [\ \t]
\S non-whitespace character (opposite of \s)
- same as typing [^\ \t]
\d digit (0-9)
- same as typing [0-9]
\D non-digit
- same as typing [^0-9]
\a alphabetic character
- same as typing [A-Za-z]
\A non-alphabetic character
- same as typing [^A-Za-z]
\l lowercase character
- same as typing [a-z]
\L non-lowercase character
- same as typing [^a-z]
\u uppercase character
- same as typing [A-Z]
\U non-uppercase character
- same as typing [^A-Z]
\t tab character
\r return (carriage return) character
(in replacestring only)
\n return (newline) character
(in searchstring only)
[] accept any character between the brackets
(indicate ranges with a hyphen) For example:
[abcde]
will find 'a', 'b', 'c', 'd', and 'e'.

[a-e]
will find the same letters.

[a-zB-F]
will find all the lowercase letters,
along with the uppercase letters B through F.
[^] The '^' character has special meaning
when it is between brackets.
In that context it reverses the effect
of the brackets.
For example:
[^abcde]
will find anything but 'a', 'b', 'c', 'd',
and 'e'.

[^a-e]
will find anything but those same letters.

[^a-zB-F]
will find anything that is neither a lowercase
letter nor an uppercase letter from B through F.
* Find 0 or more of the preceeding item.

For example:
/du*mb
finds a 'd' followed by any number of 'u's,
followed by 'm' and 'b'.
+ Find 1 or more of the preceeding item.

For example:
/du+mb
finds a 'd' followed by AT LEAST ONE 'u',
followed by 'm' and 'b'.
\= Find 0 or 1 of the preceeding item.

For example:
/du\=mb
finds only "dumb" and "dmb".
\{m,n\} Find at least m but not more than n of
the preceeding item.

For example:
/du\{1,5\}mb
matches the following strings:
dumb
duumb
duuumb
duuuumb
duuuuumb

/d\{1,2\}u\{3,6\}m\{3,4\}b
matches the following 16 strings:
duuummmb
dduuummmb
duuuummmb
dduuuummmb
duuuuummmb
dduuuuummmb
duuuuuummmb
dduuuuuummmb
duuummmmb
dduuummmmb
duuuummmmb
dduuuummmmb
duuuuummmmb
dduuuuummmmb
duuuuuummmmb
dduuuuuummmmb
\(\) Keeps the characters between the parenthesees
in a special "search and replace" buffer, so
those characters can be used in the replace string.

The characters within the first set of parenthesees
are saved in special buffer \1, and each successive
set of parenthesses saves its contents into the
next number.

For example:
:s/^\([a-z][B-E][1-8]\)/wobba \1/
searches for the ranges [a-z][B-E][1-8] at
the beginning of the line, and replaces that
string with "wobba " plus itself.

More usefully, the following command
switches the first two fields in a
comma delimited file:
:%s/^\([^,]*\),\([^,]*\)/\2,\1/
In order to search for a character
that is also a metacharacter, you
must precede it with a backslash.
For example:
/^balzak\^
will find an instance of the string
"balzak^" at the beginning of a line.

/\\backslash\/forwardslash
will find the following string:
\backslash/forwardslash

Experimentation is the key here.
If it didn't work the way you wanted,
undo your mistaken changes,
and try it again.

Much-needed search/replace examples
:%s/\t/ /g scope: file-wide
searchstring: tab character
replacestring: two spaces
Replaces all tab characters in file
with two spaces.
:%s/cellpadding=3/cellpadding=6/gc Replace all occurances of "cellpadding=3"
with "cellpadding=6".
:%s/^\([\ \t]*\)n/\1\[n\]/c scope: file-wide
searchstring: beginning of line
followed by 0 or more spaces or tabs,
until the character 'n' is found. This
is all saved into buffer 1.
replacestring: the contents of buffer 1,
followed by "[n]", pending individual
confirmations.
In other words, every time 'n' is the first
character on a line, retain its indentation
level, and replace 'n' with "[n]".
(I just used this to place brackets around
the optional 'n's in this document.)
:%s/^\([^,]*\),\([^,]*\)/\2,\1/ scope: file-wide
searchstring: beginning of line
followed by 0 or more characters that are
anything but commas, all saved into buffer 1,
followed by a comma, followed by 0 or more
characters that are anything but commas,
saved into buffer 2.
replacestring: the contents of buffer 2, (the second
field in a comma delimited file) followed by a
comma, followed by the contents of buffer 1 (the
first field in a comma delimited file).

^ Back to Top
16. Using Vim Editing Windows
:help opening-window
Vim gives you the capability to edit more
than one file simultaneously.
(This allows you conveniently to yank
(copy) and place (paste) between files.)
:sp[lit] [filename] opens an additional window in the current
session, editing the file "filename", if
specified
:vsp[lit] [filename] opens an additional vertical window in the
current session, editing the file "filename",
if specified (most often used with vimdiff)
z height make the current window "height" lines tall
^w prepare for a window command
("^w" means CTRL-w)
The following commands must be preceeded
by the ^w command (see above).
h Move cursor to the window to the left
of the current window.
j Move cursor to the window below
the current window
k Move cursor to the window above
the current window.
l Move cursor to the window to the right
of the current window.
[n]+ increase the current window's relative
size by n lines
[n]- decrease the current window's relative
size by n lines

^ Back to Top
17. Tags - How to Navigate Intelligently
:help tag-commands
A tag is an identifier that appears
in a "tags" file; it is a sort of label
to which you can jump. This "tags" file
must be generated by a program like ctags
before the tag commands can be used.
(One very common use of tags is to
jump to and from different function
definitions in C programs; see the
ctags manpage for details.)
^] jump to the tag referenced by the
keyword currently under the cursor;
push this location onto the stack ("^]" means CTRL-])

In the vim help file, these appear
like this:
|I-am-a-keyword-tag-thingy|
^t return from the current jump;
pop the previous location off the
tag stack
("^t" means CTRL-t)
This returns you to wherever you
were before you hit "^]".

^ Back to Top
18. Visual Mode - How to Select Text Quickly
:help visual-start
In vim you can select text visually when
you are in Visual Selection Mode. Simply
move your cursor normally, and the text over
which you move will be highlighted.

After you have highlighted the section of
text you want, you can perform commands upon
it, such as deletion, yanking, searching, and
replacing. Experimentation is the key; always
remember undo.

If you type a colon (":") while you have text
selected, the following will appear on your command
line:
:'<,'>
This simply means that the scope of your
command is the text you have selected.
v enter visual selection mode
ESC (pressed twice) leave visual selection mode
(selected text is un-selected)

^ Back to Top
20. Macros - How to Record and "Play back" Complex Operations
:help { q | recording }
q{0-9a-zA-Z"}.+q The first {0-9a-zA-Z"} character after
q is used as the name of a register into
which the remaining commands/characters
up to the concluding q are recorded.
[n]@{0-9a-z".=*} Execute the contents of register {)-9a-z".=*}
n times.

Example:
qh0w2xibarf{ESC}jq

This records in register 'h' a command to
replace the first 2 non-blank characters
of the current line with "barf", before
moving on to the next line.

10@h

This command, when executed subsequently,
replaces the first 2 letters of the current
and next 9 lines with "barf". Of course,
this could be done with a simple s[ubstitute]
command as well, but the next one wouldn't
be so easy:

qf0w3^aj

This has recorded in register 'f' a command
that increments the number at the beginning
of the current line by 3. ("^a" means CTRL-a)

NOTE the 'j' at the end of each of these
examples. If you're going to use a macro
with a number of repititions, you need to
move to the next (or previous) line before
the next repition starts.

These are very simple examples, but macros can
be incredibly complex. See the vim help for much
more precise documentation.

^ Back to Top
98. Other Vi[m] References
Linuxdoc How-To
Vim Cookbook
Newbie C/C++-focused Reference

^ Back to Top
99. Miscellaneous Useful Stuff
[n]. repeats previous command n times
(doesn't work for everything, you'll
just have to experiment)
J deletes carriage return at end of
current line
% when cursor is on a parenthesis,
a bracket, or a curly brace, the "%"
sign moves it to the corresponding opening
or closing character (handy for checking
that your statements are closed off, and for
moving back and forth between the
beginning and end of a function)
gq{h | j | k | l} fix justification (line wrapping) of
current paragraph
:!shell_command executes "shell_command" in the shell,
and returns the results to your terminal

If you combine this with the ":r[ead]" command,
you can read the output of your shell command into
your file.
For example:
:r !ls $HOME
will read a list of the files in your home directory
into your file.
[n]== adjust the indentation of the current line and the following (n-1) lines
If you have a certain indentation scheme configured (such as C code), this can re-indent your code for you. Very handy.
^l redraw the screen
deletes annoying stderr messages
from other programs ("^l" means CTRL-l)
^p complete the word under the cursor,
if possible, by searching backward
through the current document to find
words that begin the same way
(awesome tool that helps you avoid
re-typing long names)
("^p" means CTRL-p)
^n complete the word under the cursor,
if possible, by searching forward
through the current document to find
words that begin the same way
(awesome tool that helps you avoid
re-typing long names)
("^n" means CTRL-n)


Copyright 2001, Matt Oquist. No rights whatsoever are reserved. Please copy and distribute this with reckless abandon.