It is not like the vi editor needs introducing to seasoned UNIX users. The vi editor, originally developed by Bill Joy of Sun Microsystems, is an endlessly extensible, easy to use light ASCII editor and the bane of the newbie existence. This section will introduce the vi editor to the newbie and perhaps toss in a few ideas for the seasoned user as well.
The first half of this section will overview editing, saving, yanking/putting and navigating a file within a vi session. The second half will be a step by step sample vi session to help get started.
This is intended as a primer for using the vi editor, it is not by any means a thorough guide. It is meant to get the first time user up and using vi with enough skills to make changes to and create files.
Using the vi editor really is not much different than any other terminal based
software with one exception, it does not use a tab type (or curses if you will)
style interface, although many versions of vi do use curses it does not give
the same look and feel of the typical curses based interface. Instead it works
in two modes, command and edit. While this may seem strange, it is not much
different than windows based editing if you think about it. Take this as an
example, if you are using say gedit and you take the mouse, highlight some text,
select cut and then paste, the whole time you are using the mouse you are not
editing (even though you can). In vi, the same action is done by simply deleting
the whole line with
dd in command mode, moving to the line you wish to place
it below and hitting
p in command mode. One could almost say the analogy is
mouse mode vs. command mode (although they are not exactly identical,
conceptually the idea is similar).
To start up a vi session, one simply begins the way they might with any terminal based software:
$ vi filename
One important note to remember here is that when a file is edited, it is loaded into a memory buffer. The rest of the text will make reference to the buffer and file in their proper context. A file only changes when the user has committed changes with one of the write commands.
The vi editor sports a range of options one can provide at start up, for the time being we will just look at the default startup. When invoked as shown above, the editors default startup mode is command mode, so in essence you cannot commence to typing into the buffer. Instead you must switch out out of command mode to enter text. The following text describes edit start modes:
a-- Append after cursor.
A-- Append to end of line.
C-- Change the rest of current line.
cw-- Change the current word.
i-- Insert before cursor.
I-- Insert before first non blank line.
o-- Open a line below for insert.
O-- Open a line above for insert.
Of course knowing the edit commands does not do much good if you can't switch
back to command mode and save a file, to switch back simply hit the
To enter certain commands, the colon must be used. Write commands are one such
set of commands. To do this, simply enter
Hitting the colon then will put the user at the colon (or command if you will) prompt at the bottom left corner of the screen. Now let us look at the save commands:
:w-- Write the buffer to file.
:wq-- Write the buffer to file and quit.
What good is an editor if you cannot manipulate blocks of text? Of course vi
supports this feature as well and as with most of the vi commands it somewhat
intuitive. To yank a line but not delete it, simply enter
command mode and the current line will be copied into a buffer. To put the line
somewhere, navigate to the line above where the line is to be put and hit the
p key for the put command. To move a line, simply delete the whole line
dd command, navigate and put.
Undo is pretty simple,
u undoes the last action and
U undoes the last line
deleted or changes made on the last line.
Most vi primers or tutorials start off with navigation, however, not unlike most editors in order to navigate a file there must be something to navigate to and from (hence why this column sort of went in reverse). Depending on your flavor of vi (or if it even is vi and not say elvis, nvi or vim) you can navigate in both edit and command mode.
For the beginner I feel that switching to command mode and then navigating is a bit safer until one has practiced for awhile. The navigation keys for terminals that are not recognized or do not support the use of arrow keys are the following:
k-- Moves the cursor up one line.
j-- Moves the cursor down one line.
l-- Moves the cursor right one character.
h-- Moves the cursor left one character.
If the terminal is recognized and supports them, the arrow keys can be used to navigate the buffer in command mode.
In addition to simple one spot navigation vi supports jumping to a line by simply typing in the line number at the colon prompt. For example, if you wanted to jump to line 223 the keystrokes from editor mode would look like so:
The vi editor supports searching using regular expression syntax, however, it is
slightly different to invoke from command mode. One simply hits the
/ key in
command mode and enters what they are searching for, as an example let us say I
am searching for the expression foo:
That is it, to illustrate a slightly different expression, let us say I am looking for foo bar:
Searching and scrolling are not the only ways to navigate a vi buffer. Following is a list of succinct navigation commands available for vi:
0-- Move to beginning of line.
$-- Move to end of line.
b-- Back up one word.
w-- Move forward one word.
G-- Move to the bottom of the buffer.
H-- Move to the top line on the screen.
L-- Move to the last line on the screen.
M-- Move the cursor to the middle of the screen.
N-- Scan for next search match but opposite direction.
n-- Scan for next search match in the same direction.
Now that we have covered the basics, let us run a sample session using a couple of the items discussed so far. First, we open an empty file into the buffer from the command line like so:
# vi foo.txt
Next, we switch to edit mode and enter two lines separated by an empty line,
remember our buffer is empty so we hit the
i key to insert before cursor and
enter some text:
This is some text there we skipped a line ~ ~ ~ ~
Now hit the
ESC key to switch back into command mode.
Now that we are in command mode, let us save the file. First, hit the
the cursor should be sitting in the lower left corner right after a prompt. At
: prompt enter
w and hit the
RETURN key. The file has just
been saved. There should have been a message to that effect, some vi editors
will also tell you the name, how many lines and the size of the file as well.
It is time to navigate, the cursor should be sitting wherever it was when the
file was saved. Try using the arrow keys to move around a bit. If they do not
work (or you are just plain curious) try out the
hjkl keys to see how they
Finally, let us do two more things, first, navigate up to the first line and then to the first character. Try out some of the other command mode navigation keys on that line, hit the following keys a couple of times:
$ 0 $ 0
The cursor should hop to the end of line, back to the beginning and then to the end again.
Next, search for an expression by hitting the
/ key and an expression like so:
The cursor should jump to the first occurrence of we.
Now save the file and exit using write and quit:
The standard editor supplied with NetBSD is, needless to say, vi, the most loved and hated editor in the world. If you don't use vi, skip this section, otherwise read it before installing other versions of vi. NetBSD's vi (nvi) was written by Keith Bostic of UCB to have a freely redistributable version of this editor and has many powerful extensions worth learning while being still very compatible with the original vi. Nvi has become the standard version of vi for BSD.
Amongst the most interesting extensions are:
- Extended regular expressions (egrep style), enabled with option
- Tag stacks.
- Infinite undo (to undo, press
u; to continue undoing, press
- Incremental search, enabled with the option
- Left-right scrolling of lines, enabled with the option
leftright; the number of columns to scroll is defined by the
- Command line history editing, enabled with the option
- Filename completion, enabled by the
- Backgrounded screens and displays.
- Split screen editing.
The following example shows a
.exrc file with some extended options enabled.
set showmode ruler set filec=^[ set cedit=^[
The first line enables the display of the cursor position (row and column) and
of the current mode (Command, Insert, Append) on the status line. The second
line (where ^[ is the ESC character) enables filename completion with the ESC
character. The third line enables command line history editing (also with the
ESC character.) For example, writing
: and then pressing ESC opens a window
with a list of the previous commands which can be edited and executed (pressing
Enter on a command executes it.)
The source tarball (
src.tgz) contains a lot of useful documentation on (n)vi
and ex, in the
/usr/src/usr.bin/vi/docs directory. For example:
- Edit: A tutorial
- Ex Reference Manual
- Vi man page
- An Introduction to Display Editing with Vi by William Joy and Mark Horton
- Ex/Vi Reference Manual by Keith Bostic
- Vi Command & Function Reference
- Vi tutorial (beginner and advanced)
If you have never used vi, the Vi tutorial is a good starting point. It is meant to be read using vi and it gradually introduces the reader to all the vi commands, which can be tested while reading. An Introduction to Display Editing with Vi by William Joy and Mark Horton is also a very good starting point.
If you want to learn more about vi and the nvi extensions you should read the Ex/Vi Reference Manual by Keith Bostic which documents all the editor's commands and options.
This topic is not directly related to NetBSD but it can be useful, for example, for examining the kernel sources.
When you examine a set of sources in a tree of directories and subdirectories you can simplify your work using the tag feature of vi. The method is the following:
cdto the base directory of the sources.
$ cd /path
Write the following commands:
$ find . -name "*.[ch]" > filelist $ cat filelist | xargs ctags
Add the following line to
(substitute the correct path instead of