Vi (pronounced "vee-eye") is a popular and very powerful text editor. It's fairly hard to learn, but it's well worth learning, especially since it's often the only editor available on an unfamiliar Unix system.

The first thing you'll notice about vi when you run it is that you can't enter text straight away. This is because vi starts in command mode, which uses many commands based on keys that would normally produce a character (such as letters and punctuation). This is an unusual approach but it works well as the majority of commands are single, unshifted keystrokes on the main part of the keyboard, meaning that for the vast majority of your time using vi, your hands stay in exactly the same place. This way you don't waste time moving your hands around the keyboard. Also, the rarity of commands using CTRL or ALT reduces the amount of stretching that the hand has to do, reducing the probability of repetitive strain injury.

Modes

Vi has several modes; the most important are command mode, insert mode, command line mode and visual mode. In any of these modes you can press ESC to go back to command mode.

Insert mode

Insert mode behaves much as you'd expect: pressing a key inserts the appropriate character. You can use the arrow keys to move about, but bear in mind that going back to command mode is often faster, especially if you have a long way to move.

There are several ways to enter insert mode from command mode. Most commonly you will press i to start typing before the cursor, or a to start typing after it. You can also press o or O to insert a blank line respectively after or before the current one and start typing in it. (Note that vi is case sensitive.)

To leave insert mode, just press ESC.

Command mode

Most of your time will be spent in command mode. Here you enter commands to enter other modes, move the cursor around, and do simple text manipulation such as deleting (cutting), yanking (copying) and pasting.

In general, there are two types of command: those that are modified using a count, and those that are modified using a movement. Commands taking a count can be entered without one, but commands taking a movement don't do anything until they get a movement telling them how much text to act on.

As an exanple, there are two ways to delete 5 lines, and to delete 10 characters to the right of the cursor.

Supplying a count

To delete the current line and the four lines after it, press 5dd. Similarly, to delete the current character and 9 characters to the right of it, press 10x.

The exact meaning of the count depends on the command. For example, the K command looks up the word under the cursor in the manual (exactly as if you had typed man (word) in the shell). Adding a count tells the command to look the word up in that section of the manual (exactly as if you had typed man (count) (word) in the shell).

Combining a command with a movement

Movement of the cursor is achieved using the keys h, j, k and l - these are left, down, up and right respectively. Think of the curve in the j as being an arrow pointing downwards. These are "count" commands - that is, they can be repeated by typing a number before it. You can also move the cursor using the arrow keys, but they can't be combined with commands as described below like hjkl can. There are also lots of advanced movement commands that move further, e.g. to the beginning / end of the word / sentence / paragraph. These are documented in vim's online help system (type :h to read it).

To delete the current line and the 4 lines after it, press d4j. In words, this means "delete lines from here until wherever the movement 4j goes". Similarly, d9l deletes the current character and the 9 characters to the right of it - it says "delete characters from here until wherever the movement 9l goes".

Command mode reference

CommandMeainingModifier
aAppend text after cursor (enters insert mode)Count
dDelete (cut) textMovement
ddDelete lineCount
DDelete rest of line (if given count > 1, also deletes count-1 following lines)Count
ggMove to start of file (or countth line)Count
GMove to end of file (or countth line)Count
hMove leftCount
iInsert text before cursor (enters insert mode)Count
jMove downCount
JJoin lines (minimum count 2, if specified)Count
kMove upCount
lMove rightCount
nRepeat last searchCount
oInsert text in a blank line after current line (enters insert mode)Count
OInsert text in a blank line before current line (enters insert mode)Count
pPaste after cursorCount
PPaste before cursorCount
uUndo (very useful!)Count
CTRL-rRedoCount
vEnter visual modeMovement
VEnter linewise visual modeMovement
xDelete character at cursorCount
XDelete character before cursorCount
yYank (copy)Movement
yyYank lineCount
/Search forwards from cursorCount
?Search backwards from cursorCount
:Enter command-line modeCount or Visual
<Shift line left count timesCount
>Shift line right count timesCount
<<Shift line left onceNone
>>Shift line right onceNone
%Match brackets / braces etc (handy if you get lost among lots of parentheses)None
^Move to start of line (but after whitespace)None
0Move to start of lineNone
$Move to end of lineNone

Command line mode

Vi has a "command line" which is used to enter a number of "Ex commands" that have long names or take various textual arguments - for example, opening and saving files and setting variables. To enter an Ex command first press : (colon). There isn't much to say about this mode except to give a list of some commonly used commands.

CommandMeaning
eOpen a new file for editing - follow by filename
wSave (write) - follow by filename to use (unless you want to save with the same filename)
qQuit
wqSave and quit
nohStop highlighting things found by the last search
syntax onTurn syntax colouring on (vim-specific)
syntax offTurn syntax colouring off (vim-specific)
setSet an option
letSet a variable
s/foo/bar/Substitute regular expression foo with bar. Useful for changing large amounts of text at the same time or in the same way
hRead vim's online help - optionally follow by a word to look up. (vim-specific, though probably works in some other versions)

Sometimes it might be a bad idea to execute a command - for example, typing :q without saving first. In these cases vi might not let the command go ahead. You can override this using an exclamation mark; for example, :q! quits without saving, even if the buffer has changed since you last saved.

For commands that act on the current line only, the command can be preceded by % to make it act on every line instead. There are a few such range modifiers, all of which are documented in vim's online help.

Visual mode

This provides a convenient alternative to most movement-oriented commands rather like selection in other editors. Pressing v starts a highlight on the current character that can be expanded by moving about (with hjkl or other movement commands, but not the arrow keys). Similarly, pressing V selects text a line at a time, and moving up and down changes the amount of text selected.

For example, v9ld will delete the current character and the 9 to the right of it, but, equivalently, you can press v, then l nine times, followed by d. And V4jd, or V followed by j four times and then d, will delete the current line and the four lines after it. Between the v or V and the command, the text which the command will act on is highlighted.

To cancel visual mode, press ESC.

(Historical note: vi is an abbreviation for "visual", but it wasn't named after this mode - rather, it was to distinguish it from line editors such as ed which were the only editors available when the original vi was created back in the early 1970s. They're not much used now because the hardcopy terminals they were designed for are long since obsolete.)

Ex mode

Ex mode is like command-line mode, except that you enter a sequence of Ex commands instead of directly working on the file. It's rather like ed. As such it is rather hard to use and not particularly useful.

Some useful features in vim

The following instructions refer only to vim; other clones may have similar mechanisms, but probably not the same ones.

Syntax colouring

Many clones of vi, including vim, provide highlighting of syntactic elements in a large number of programming and markup languages. This can greatly help in understanding the structure of code, especially if you are dyslexic.

To turn on syntax highlighting, type :syntax on. If you are using an appropriate filename (i.e. one that has the canonical extention for the language you are editing) vim will be able to guess which language you want. in some cases the guess is wrong - in these cases you can tell vim to highlight for a different language by typing :set syntax=(language).

In particular, the filename extension .pl is, by default, associated with Perl. Unfortunately this clashes with the default extension for Prolog source files, which is also .pl. You can tell vim to interpret the file as Prolog by typing :set syntax=prolog.

Another thing to watch out for is that each syntax specification may support several dialects. For example, vim's Pascal highlighting supports GNU Pascal as well as Delphi. Generally you need to set a variable to change vim's behaviour in these cases:

Autoindent and c-indent

These are two exceptionally handy features when editing source code:

Note: When pasting text into vim using the middle mouse button under X, autoindent and cindent can easily mess up the formatting of the text being pasted. You should turn both options off before pasting.

Folds

Many of the editors supplied with integrated development environments (IDEs) allow you to collapse large sections of code, such as a class, function, or loop body. Folds achieve the same effect in vim.

In C-like languages, a convenient way to fold all {} blocks is to do:

:syn region myFold start="{" end="}" transparent fold
:syn sync fromstart
:set foldmethod=syntax

This will automatically fold all {} blocks. To expand the fold under the cursor, press za, and the same to close it again. To manually create a fold, use the zf command with a movement or Visual mode selection.