Vi for programmers

This is a great article that shows you how to really harness some of the power of VIM. I snagged it from Builder.com.

It was a multiple part article so this is going to be kind of long but really filled with a lot of great information.

If you're a developer working on a UNIX/Linux platform, you've already encountered vi. Vi users fall into one of two categories: those who hate it and continually curse its finger-twisting key combinations and hard-to-remember commands, and those who love the flexibility and power it offers. For a long time, I was in the former category. However, continuous usage has led to a gradual appreciation for the speed and power under the cryptic interface, and I've since learnt a bunch of shortcuts and key combinations that ease the task of writing code in the editor. This article discusses my personal top ten features. Before proceeding, ensure that you have a copy of ViM (that's Vi iMproved) installed and working on your system. You can download both binaries and sources from vim.org.

Automatic indenting

Let's start with the basics: making your code readable. Most of the time, you do this through the careful use of indentation around nested code blocks (and, of course, lots of comments!). ViM isn't smart enough to write the comments for you, but it can certainly help with the indenting through its very powerful auto-indenting feature.

To control the indenting of your code, there are two important variables in ViM: tabstop and autoindent . The first one controls the number of spaces a <tab> represents. If you want a <tab> to equal two spaces, you can use this command (executed from within vi):

:set tabstop=2

Now, every time you press the <tab> key for an indent, ViM will move the cursor forward two spaces.

You can also have ViM automatically indent your code blocks for you, so that you never (well, almost never) need to manually hit the <tab> key. To do this, turn on auto-indenting:

:set autoindent

With this option turned on, ViM will automatically tab a new line to the same indenting level used by the previous line. If you're starting a loop, a conditional block or any other nested structure, this ensures that each line of code is correctly indented and in sync with the lines above it.

You won't usually regret turning this feature on, but if you ever find it annoying—say, you switch from writing a script to writing a letter and a <tab> no longer indicates the beginning of a code block—you can turn it off with this command:

:set noautoindent

Syntax highlighting

You know how all those Windows editors can color-code your scripts so that they look pretty? Well, ViM can do that too; the editor comes with a very powerful syntax-highlighting module that supports most common programming languages such as Perl, PHP, JavaScript, HTML, XML, and JSP.

To activate syntax highlighting on your script, type:

:syntax enable

ViM automatically detects the file type and loads the appropriate set of colors. To turn syntax highlighting off (because it can sometimes cause things to slow down), use:

:syntax off

If the colors are not to your liking, you can change them to something more suitable. ViM has a ready-made solution for you here too—a number of custom color schemes ship with the distribution, and you can activate any of them with the colorscheme command, like this:

:colorscheme elflord

For a complete list of available schemes, look in the colors/ directory of the ViM shared areas (personally, I like pablo , elflord and the interestingly-named peachpuff the most).

Reading linked files

Like most programmers, you probably make it a point to create reusable code libraries that are abstracted out of your main scripts and brought in where needed through include() or require() statements. But what happens when you open up a script you wrote a few months back, and have no idea what all the include() s at the top refer to?

With ViM, finding out is a snap. If, for example, you have the following line of code at the top of your script:

#include <mydefs.h>

And, you want to look inside mydefs.h to see what it contains, simply place your ViM cursor under the filename and type:

gf

ViM will search for the file in the search path (set via the path variable) and display the file in the window immediately. This capability is a very useful one, especially when dealing with applications that have a large code tree and many internal links.

Exploring the file system

Speaking of files, ViM comes with a powerful file explorer that significantly eases the task of finding and opening files for editing. To see how it works, type:

:edit .

in the ViM editor, and watch as a file listing for the current directory is generated for you. This file listing is part of a basic but fully-functional file manager that is built in to ViM, and it's great for quickly finding and opening a file in another directory on the file system (especially if you're not completely sure of the exact file name).

Once the file manager has popped up, you can use the arrow keys to navigate between files and directories, and select a file for editing with the [Enter] key. While in the file explorer, use the "i" key shortcut to toggle display of file timestamps and dates...very useful if you're looking for the most recently-edited file.

Using line numbers

Often, the error messages generated by your scripts include line numbers indicating the source of the error. By default, however, ViM does not automatically print line numbers next to each line in edit mode. To fix this, use:

:set number

command to have ViM prefix a line number before each line in the file. I have found this feature most useful when testing and debugging code simultaneously on two consoles; it's very handy to quickly jump to "bad" lines of code.

To find out which line you're currently editing in a file, type <CTRL>-g and look at the status bar. ViM prints a message containing statistics on the total number of lines in the file, as well as the current line number.

Even with line numbers on, you can save your <page up> and <page down> keys a bit of wear and tear by using ViM's built-in key shortcuts to quickly jump to specific lines of your script:

  • To jump to a particular line, type the line number then <SHIFT>-g . For example, to jump to line 26, type 26<SHIFT>-g .
  • To jump to the beginning of the file, type gg .
  • To jump to the end of the file, use <SHIFT>-g .

To turn off line number display, use:

:set nonumber

And things will go back to normal.

Multiple-window editing

When you're writing code, it's common to switch back and forth between multiple files, either for reference or to copy/paste lines of code. On the Windows platform, this is simple—as the name suggests, all you need to do is open multiple windows and work on them simultaneously.
But what happens in a UNIX console? Like all the best text editors, ViM supports viewing and editing files in different windows.
To see how this works, simply type

:split

from inside vi and watch as your window subdivides horizontally into two. Each subwindow will display the contents of the selected file, and you can move around independently in each one. To move from one window to the other, type

<CTRL>-w-w.

To open a new blank window, type

:new

Instead of having the same file appear in each window, you can tell ViM to open a different file in the new window by adding the file path and name after the split command, as below:

:split /tmp/test.c

The cut, copy, and paste commands—d, y, and p—work as usual and can be used to move text from one window to another. If your console and ViM build support "visual mode," you can even "select" blocks of text and "drag and drop" them between windows.