Vim for Perl Development

G. Wade Johnson

Houston Perl Mongers

What Is Vim?

Editor, not Writer

We normally think that most of our time in the editor is spent writing. In actually, we spend more time changing old text than writing new text. For Vim, adding text is a subset of the functionality of the editor. Vim has extensive capabilities for editing.

Vim is Modal

Only one of the four modes is directly related to entering text. The other thre are related to navigation and editing of text.

Navigation Commands

One of the hardest things for people to learn with VI or Vim is that the navigation commands are done with normal keys rather than with special navigation keys. This turns out to be very efficient for touch typists. You can navigate without taking your hands far from the home keys.

In addition, Vim's navigation commands are much richer than those in most editors. Instead of pounding on (or holding down) an arrow key, you can often move to almost exactly the right place with a few keystrokes.

Repeated Movement

Most of movement commands can be preceeded by a count which applies the same command multiple times.

Editing Commands

The first set of commands perform the following actions when followed by a motion command: change, delete, yank, paste after, paste before, outdent, indent, toggle case, lowercase, uppercase, and justify. The <, >, and gq commands need a line motion, the others expect a character motion.

The single character edits do not require a motion command but can be preceeded by a count to affect that many characters: delete, replace, toggle case, change, and join next line with this one.

Line edits affect the entire line. Adding a count, affects that many lines. The end of line variants edit from the current position to the end of the line.

Registers

One really under-appreciated concept in Vim concerns the registers. When cutting, copying, and pasting, Vim does not just use one clipboard. Instead, the program supports a number of registers. Anytime a yank, delete, or change is executed, the data goes into the unnamed register (and register 0), unless you specify a particular named register. Each time one of those commands is executed, the previous value of the 0 register is moved to the 1 register. This is repeated for each numbered register, up to register 9.

If you want to hold onto a piece of text for longer than one cut/paste, you can use one of the 26 named registers, by prefixing the command with " and the letter naming the register. So, "byy yanks the current line into register b. Using an uppercase letter, appends to that register rather than just replacing. If you use name a register before the p or P command, it pastes the data from that register instead.

One other special register is +. This register is mapped to the system clipboard. This feature allows easily moving data to and from other programs.

Insert Mode

There are a number of ways to enter insert mode. Vim novices pick one, use it to get into insert mode and spend most of their time entering text. As you become more familiar with the different ways to enter insert mode, you find that using the correct command can save you typing. For example, a starts appending after the current character, but A appends to the end of the line. This saves you from cursoring to the end of the line (or $, if you are more Vim-savvy). Likewise, I inserts before the first non-whitespace character on the line. The commands o and O inserts a new line after/before the current line, moves there, and enters insert mode.

Visual Mode

Visual mode could also be called selection mode. Any motion commands after entering visual mode extends the selection. The way the selection extends is determined by how visual mode was entered. Using a command such as y, c, or d applies to the entire selection. This selection can also specify the range affected by one of the colon commands, like substitute.

CmdLine Mode

The first group of commands has to do with writing a buffer, editing a new file, reading a file into the current buffer, moving to the next/previous file from the commands line, quitting the current buffer, and find a file from the path and edit it.

The substitute command is your search and replace command. It supports regular expressions. The other commands of this group can often be done more easily with normal mode commands: copy, move, delete, and change. One place where these can be particularly useful is where the range can be determined by a search.

The search commands use regular expressions to find text. The n and N commands are used to move to the next match.

The filter command is possibly the most powerful. The selected text or the specified range is supplied as standard input to the specified command. The output from the command then replaces the selection. This allows any filter-type command on the system to be used to modify text in the editor, without leaving the editor.

Text Objects

In many cases, commands that take a motion can take a text object instead. This allows some pretty powerful edits to be accomplished with a few keystrokes. Unfortunately, constructing the text object requires a small amount of getting used to. The text object starts with wither i or a. This makes it either an inner text object (without the delimiters) or all (with the delimiters). In the case of the first set of object, the difference is the surrounding whitespace. For the other text objects, i means without the delimiters and a includes the delimiters.

The first set of object characters specifies words, non-whitespace characters, sentences, and paragraphs. The matching sets define a text object delimited by the specified pairs of characters. You only need to specify one of them. The b character is a synonym for the parentheses. The B character is a synonym for the curly braces. The t character refers to XML or HTML tags. So it refers to the text object delimited by the nearest enclosing tags.

Repeated Edits

There's been a lot of talk so far about edits in Vim being different than just typing text. Now we can see why that is important. The . command repeats the last edit in the current cursor location. That could be as simple an edit as deleting a character (x) or word (dw). Or it could be more complicated like indent the enclosing code block (<iB).

The problem with the . command is that it is just one edit. Once you begin a motion, the edit is considered completed. A macro can include any form of change that you can perofm in Vim. Press q followed by a register name and then perform the edits and motions you need. Finish the macro with another q. You execute the macro by typing @ followed by the macro name. When using recorded macros, the more advanced motion commands are more useful. Your edit can apply to different amounts of text as long as it follows the same structure.

The next feature is vim script, which is a full programming language. Using vim script, you can add new functionality to the editor. We'll discuss this more later.

For Perl programmers, one of the most powerful features is perldo which allows you to execute a perl command on selected portions of your text. This feature is only availabale if Perl support was compiled in to your installation of Vim.

Word Completion

Some languages are very verbose and require editor support to help remember the names of all of the methods and variables you might want to use. Vim provides a relatively simple version of this feature with word completion.

The first two list all of the keywords from the current file that match the text typed so far. The C-xC-i also applies keywords from files that are included. If you've decided you'd rather finish typing rather than select from the list, use C-xC-e. There are also some special purpose completions for definitions or macros, entries in the tags file and filenames found on the path.

Window Support

Vim supports working with multiple windows at one time. You can have the Same file in multiple windows. This is more useful in the gui version of the vim.

An unusual command is :windo which applies a command to the files in every open window.

Tab Support

Tabbed interfaces are pretty popular laterly. Of course, vim supports tabs as well. First you have to be able to open tabs, you can do that using the -p command line option when starting vim. But, it's more useful to create tabs as you need them. The first set of commands opens a file for editing in a new tab, creates an empty tab, finds a file on the path and opens it in a new tab, and opens the filename under the cursor in a new tab.

You can close a tab with :tabc. You can close all but the current tab with :tabo. Navigation is performed with the next set of commands. These move to the next, previous, first (2 ways), and last open tab.

Finally, tabs also support automation through the :tabdo command which applies a supplied command to all of the open tabs.

Customizing Vim

The ~/.vimrc file is loaded when vim starts. This file usually contains configuration commands that customize the editor.

The ~/.vim directory contains a number of directories and files that further customize vim. This is normally where script and doc files are added.

Vim has its own scripting langauge. Much of the customization of vim is accomplished using this scripting language. The vim site contains a large number of scripts written by programmers to add more functionality to vim.

In fact, even vim's syntax highlighting is implemented using this scripting language. The current syntax highlighting system supports around the dyntax for around 480 different languages.

Useful Scripts

These are a few scripts that I found extremely useful. DirDiff allows comparison of two directory trees and the files in them. surround supports editing characters that surround other text. This includes quotes and matching pairs like parens, and braces. The vimballPlugin script supports a mechanism for packaging and installing other scripts. scriptsEmu provides a system for TextMate code snippets. The NERD_commenter script handles commenting and uncommenting large sections of code all at once. The taglist script give vim the ability to make a kind of menu from the file created by the tags program. vcscommand provides functionality to access several different types of version control systems, including SVN, CVS, and git.

Perl-Specific Customizations

The normal vim support for Perl includes some useful customizations. The gf command opens the file under the cursor. With a few customizations, vim recognizes Perl use statements and converts the module name into a filename to open.

With a couple more customizations, we can repurpose vim's built-in make support to give a quick compile check for Perl code. Similarly, vim uses grep to search external files, but we can customize it to use ack instead.

By mapping commands with special keystrokes, we can add functinality. Examples include the ability to run perltidy or perlcritic on code. Vim already supports a keyword-lookup help feature, with a few minor tweaks, it uses perldoc.

Many programming languages need a fair amount of boilerplate to get started. Perl doesn't require much, but we can benefit by starting our files the same way every time. Using the autocmd feature, we can cause vim to read a template any time a new file of a particular type is created.

Perl Custom Commands

In the customization file, I've added maps for the listed strings to commands I might want to run on code. The ,pt for running perltidy and ,pc for running perlcritic have pretty obvious utility. ,pD is a bit different. It compiles the selected Perl code and then decompiles it to show Perl's interpretation of the code. This can be used to de-obfuscate code that came from someone else.