ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics

Using the vi Editor

10/25/2001

Okay, I admit it. I like using the vi editor. In fact, I have fond memories of using vi when I was teaching myself C++ while playing Peter Gabriel at full blast. I never became highly proficient at C++, but I can still type and get vi's bell to go off in rhythm to any piece of music. I sorta miss that bell when I'm using another editor.

Everyone knows they should have a passing knowledge of vi, but most people groan at the thought of using it. In today's article, I'd like to demonstrate some of the tricks that vi has up its sleeve. It really is a powerful little editor and I'm constantly amazed at its number of built-in shortcuts.

One of the more recent tips I learned is from UGU's tip of the day. If you haven't heard of this great reference, you can read the archives or sign up to receive the daily tip.

Let's say that I've sent a file to a pager:

more a_file

and I notice a typo as I'm reading through the file. If I type:

v

the vi editor will be invoked and the bottom of my screen will show the name of the file and the line number my cursor is on. I can then correct the typo. To save the correction and go back to the pager:

:wq

What could possibly be more efficient than that?

The vi editor comes with a built-in help system which is useful for learning new shortcuts. If you type

:help

you'll see this at the bottom of your screen:

To see the list of vi commands, enter ":viusage<CR>"
To see the list of ex commands, enter ":exusage<CR>"
For an ex command usage statement 
  enter ":exusage [cmd] <CR>"
For a vi key usage statement enter ":viusage [key]<CR>"
To exit, enter "q!"
Press any key to continue [: to enter more ex commands]:

For example, if I think I remember that vi uses the letter "o", but I can't remember for what, I can type:

:viusage o
  Key: o append after line
Usage: [count]o
Press any key to continue [: to enter more ex commands]:

Or, if I feel the need to kill an afternoon, I can enter:


:viusage

and practice using the shortcuts I'm not familiar with. While this is handy, it can be quite overwhelming when you're first learning vi. One of the neatest tricks I learned was how to make a customized help screen. I picked up this tip from Steve Moritsugu's "Using Unix" (ISBN 0-7897-1632-1). I like to create a file with about 10 commands I want to learn, and once I've mastered those, I'll edit the file with a new set of commands.

Let's create a help file for a beginner that shows the most basic commands:

vi /tmp/help

echo "
:q!     abort without saving
:wq     write changes and quit

a       append text after cursor
i       insert text before cursor
o       open a new line below current line
O       open a new line above current line

x       delete character
dd      delete line 
1p      restore most recently deleted text at cursor
u       undo last change (repeat to undo undo)

10G     go to line 10 (can use any line number)
G       go to last line
0       move to beginning of current line
$       move to end of current line"

Let's start with those commands; the trick is to make a help file that will fit on one screen. Don't forget the echo command and the quotation marks at the beginning and end of your file. Now, become the superuser, and type:

ls -l /usr/bin/help
ls: /usr/bin/help: No such file or directory

Ignore the error message, it's a good thing. Now type:

cd /usr/bin
mv /tmp/help help
chmod 755 help
exit

To use the customized help screen while in a vi session, type:

:!help

Note that you have to remember to include the exclamation mark as you're really telling vi to execute a command you created called "help".

The vi editor also has quite a few set commands. It's useful to try them out first in a vi session and see which ones you like as you can invoke them permanently by creating a vi configuration file. Let's take a look at the set commands first, then create the file. From a vi session, type:

:set showmode

You'll note that a word appeared at the bottom right corner of your screen telling you what mode you are in. Some examples are Command, Insert, Replace, and Append modes.

Another handy set command allows you to turn on autowrap, meaning you never have to remember to press "enter" as vi will wrap your long lines for you. To set this option, type either:

:set wrapmargin=10

or

:set wm=10

If you would like to have each line numbered:

:set nu

If you decide that looks yucky, turn it off with:

:set nonu

In fact, any set command can be turned off by repeating it with no like so:

:set nowm=10
:set noshowmode

To see your current settings, type:

:set all

If you're unsure what each set command does, you'll find them in the vi man page if you do a search for unset:

man vi
/unset

Finally, if you set a set command during a vi session, it will be lost when you quit your vi session. To permanently keep a setting, create a file in your home directory called .exrc like so:

vi ~/.exrc
set showmode
set wm=10

Include your favourite set commands, and when you're finished, save your changes:

:wq

One of the neatest things about the vi editor is that you can run commands without leaving vi and even save the command's output within your vi session. Let's say I'm typing along in my vi session and I need to see this month's calendar. I can type:

:! cal

Don't panic when you see this month's calendar appear at the bottom of your screen instead of your file. Once you're finished looking at the calendar, you can press any key to see your file again.

To insert this month's calendar into your file, place your cursor where you want it to appear, and type:

:!! cal

If you forget to have your cursor in the right place and end up inserting cal's output in the wrong spot, don't forget that u will undo your change so you can try again.

The ! command will run any command and !! will insert that command's output into your current file. To insert the contents of another file, try:

:!! cat /etc/fstab

The vi editor also has powerful cut-and-paste abilities. When you are in a vi session, you have the equivalent of 26 (for the 26 alphabet characters) clipboards available for your use. The vi editor also automagically stores your last nine deletions for you in separate buffers labeled from 1-9. You can save yourself a lot of typing if you remember to use these buffers.

There are only four letters one has to remember to do any cut-and-paste operation:

m to mark the desired text
d or dd to cut the text
y to yank (copy) the text
p to paste the text

When you're first learning to cut and paste, it is handy to have set your showmode as you have to be in Command mode to enter the cut-and-paste commands. You'll always be able to check you are in the right mode as the word "*Command" will appear in the bottom right corner of your screen. It's a good idea to practice on a file that is not important to you, but don't despair if you really muck up your file as you can always exit the vi editor without saving any of your changes with :q!.

Let's try some cut-and-paste operations. Open up or create a file that contains a couple of paragraphs worth of text. Move your cursor to the first line of a paragraph, and we'll manipulate the lines in that paragraph. My paragraph has six lines in it; to cut out those six lines, I'll type from command mode:

6dd

You'll note that this operation was silently effective, the lines just disappeared. If I type u, the lines reappear, if I type u again, they re-disappear as those lines are stored in vi's buffer. Because they were my last deletion, they are in buffer number one.

To paste those lines, I'll put my cursor somewhere else in the file, and type:

"1p

The quotation mark tells vi to access its buffers; the 1 says I want the number one buffer (the last deletion); and the p says I want to paste those contents at the current cursor position. Again, this is silent, the lines magically appear. If my cursor was in the wrong spot, I can undo the changes with u, move the cursor and try again.

If you forget which buffer your deleted text is in, start with pasting the first buffer, undo that change with u, then repeat the command with the second buffer using . like this:

"1pu.u.u.u.

until you find your text.

You can cycle through all nine buffers this way.

Now let's try copying (yanking) text instead of deleting it. Because the numerical buffers only store deleted text, you instead want to save your copied text to one of the alphabetical clipboards. You can use any clipboard you want, you just have to tell vi which one you want to use.

I'll move to a different paragraph and yank (copy) three of its lines to clipboard letter a like so:

"a3y

You'll note that the lines didn't disappear this time. To see if it worked, I'll move my cursor to a different part of the file and paste in the contents of the a buffer:

"ap

Again, I told vi to access a buffer named a and to paste its contents at the current cursor position.

The contents of a will remain there until I end my vi session. If I want to copy more text, I'll probably send it to clipboard b and so on until I've cycled through all 26 clipboards.

Another way to copy and paste text is to mark the specific text. Move your cursor to any postion in your file; I'll go to the middle of a paragraph and type:

ma

to start a mark named a. Now move your cursor to another position in your file; I'll go down to the end of a line a couple of paragraphs down and type:

y'a

This copies all of the marked text between the initial and ending cursor position to an unnamed buffer. Note that unnamed buffers are referred to by ', whereas named buffers are referred to as ". The bottom of my screen noted that I yanked 14 lines. I'll then move to another part of my file and paste it like so:

p

Now, let's get really fancy by copying the contents of our buffers into another file. Don't exit vi by using the q command or you will erase its buffers. In fact, you can tell vi to open up another file without leaving your current screen by using the e command like so:

:e newfile

If you've made any changes to your current file, vi will complain and tell you to save them first. If you don't want to save your changes, you can still enter the second file if you type:

:e! newfile

You'll note that vi will create an empty file called newfile. If I now type:

p

the contents of that unnamed buffer will be pasted into this new file. I can also copy in the contents of any named buffer by specifying its letter like so:

"ap

And I can even copy in a deletion from the previous file:

"1p

Related Reading

UNIX Power ToolsUNIX Power Tools
By Jerry Peek, Tim O'Reilly & Mike Loukides
Table of Contents
Index
Full Description

If you want to get back to the first file, repeat the e command and specify that file's name. No matter what file you are in, if you type q, you will exit vi and lose your buffers.

There are other ways to get text from one file to another using vi. Let's say I'm working in a large file and I want to copy (write) lines 100 to 125 to a new file. This command will do it:

:100,125w newfile

To see the results, I can open up newfile like so:

:e newfile

Or, if I want to send line 23 to the end of existing_file:

:23w >> existing_file

I've barely scratched the surface of what you can do in vi, but hopefully I've piqued your interest in this editor. Besides UGU and Steve Moritsugu's book, you'll also find more vi tips in "Unix Power Tools" (ISBN 1-56592-260-3). And Garrett Hildebrand's vi Page is definitely worth checking out.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.


Read more FreeBSD Basics columns.

Return to the BSD DevCenter.

Copyright © 2009 O'Reilly Media, Inc.