June 7, 2007

Five scripts that make life easier with Vim

Author: Joe 'Zonker' Brockmeier

The Vim editor allows you to modify its behavior via scripts, and the Vim community has produced hundreds of scripts that may help you be more productive, or add functions to Vim that you've always wished it would have. Here are five that I find particularly useful.

To install most scripts, copy them to your ~/.vim/plugins directory and restart Vim. Each script should (and usually does) have instructions on installing it, so check the script's page for additional directions.

Simple revision control

Vim automatically saves copies of your work, so you don't have to worry too much about saving your file while you're writing -- you can always recover the swap file when you're done. However, it's handy to be able to save revisions in case you need to go back to an earlier version of a file -- particularly when you're editing configuration files.

The writebackup script allows you to create backup versions of your files from within Vim with very little effort. Just copy the script to ~/.vim/plugins and run :WriteBackup within Vim. This will save a revision of the file you can refer to later if you need to revert to an earlier version.

When the file is saved, it will have the date and a letter appended to the filename. For instance, if you save a file called revision.txt on May 17, 2007, it would be saved as revision.txt.20070517a. The next revision, if saved on the same day, would be revision.txt.20070517b. Note that you are limited to 26 revisions per day -- the script will complain that it has run out of backup names if you try to save a 27th revision on the same day.

If :WriteBackup is too long, you can always create a command alias in your ~/.vimrc:

map <F4> <Esc> :WriteBackup

This will allow you to execute :WriteBackup while in command mode just by pressing F4.

You can apply aliases to other scripts with long commands as well. If you're going to be using the commands frequently, you might want to create mappings that reduce the number of keystrokes you need to get things done.

Finally, don't forget that Vim has command completion. If you type the first few letters of a command -- in this case :Wri -- and press Tab, Vim will cycle through the alternatives, meaning that you still don't need to type out the entire command.

Even more revision control

The writebackup script has a companion, writebackupVersionControl, which builds on writebackup to add more revision control goodness to Vim.

The original script doesn't check to see whether your current revision matches another revision -- so you could wind up with several identical revisions saved, which is a waste of disk space. With the writebackupVersionControl script installed, you can run :WriteBackupIsBackedup and see if the current version of your file matches one of the backups. If not, then you can run :WriteBackup to save it. (Or whatever shortcut you've assigned to :WriteBackup....)

You might also want to see what revisions you have available. To do that, run :WriteBackupListVersions and the script will return the list of available backups and when the last version was saved.

If you need to see how the current and previous version differ, you can use :WriteBackupDiffWithPred to run a diff of the file and its most recent backup, and display it in Vim.

Once you've diffed the two files, you might want to revert to a previous version. :WriteBackupRestoreFromPred will attempt to restore from the most recent revision; if you want to go back two or more revisions, you'll need to do it manually. The script will also confirm that you want to go back, and will identify the most recent revision, so you can bail out if you decide you don't want to revert after all.

Tab completion for Vim

By default, Vim will autocomplete words if you use Ctrl-p and Ctrl-n; Ctrl-p searches forward and Ctrl-n searches backward. For instance, if you've typed in writebackupVersionControl once, there's no need to type it again -- just type in "writeb" and press Ctrl-p. Vim will either autocomplete the word, or if "writeb" matches multiple words, Vim will give you a dropdown with all of your options.

That's great -- but some folks are used to using the Tab key for autocompletion. The SuperTab script lets you do that, and a little more.

Just copy the script to your ~/.vim/plugins directory and fire up Vim. You'll still be able to use Ctrl-p and Ctrl-n, but you can now use Tab as well to search forward through the available strings.

Multiple searches in Vim

Vim's search capabilities are great as they are, but if you want to see more than one search term highlighted at a time, you'll need the MultipleSearch plugin.

This one's very simple. Just install the plugin, then run :Search blah to search for the first term, and :search skatchemagowza to search for a second term. Each term will be highlighted in a different color.

When you're ready to get rid of the search results, use :SearchReset and the highlighting will be cleared.

The MultipleSearch script also has :SearchBuffers and :SearchBuffersReset functions, which work the same way as :Search and :SearchReset, but across all of Vim's buffers.

Close HTML and XML tags automatically

I spend most of my time in Vim writing or editing articles in HTML. I've used mappings to make it easy to insert the open tags for the HTML elements that I use the most, such as <strong> and <code>, but instead of mapping the closing tags for those elements, I use closetag.

The CloseTag script allows you to use a single shortcut to close pretty much any HTML or XML tag. Install the closetag script under ~/.vim/scripts, then edit your ~/.vimrc to automatically source the file:

autocmd FileType html,xml,xsl source ~/.vim/scripts/closetag.vim

You'll also want to install the InsertCloseTag() function in your ~/.vimrc:

function! InsertCloseTag()
if &filetype == 'html'

" list of tags which shouldn't be closed:
let UnaryTags = ' Area Base Br DD DT HR Img Input LI Link Meta P Param '

" remember current position:
normal mz

" loop backwards looking for tags:
let Found = 0
while Found == 0
" find the previous <, then go forwards one character and grab the first
" character plus the entire word:
execute "normal ?\<LT>\<CR>l"
normal "zyl
let Tag = expand('<cword>')

" if this is a closing tag, skip back to its matching opening tag:
if @z == '/'
execute "normal ?\<LT>" . Tag . "\<CR>"

" if this is a unary tag, then position the cursor for the next
" iteration:
elseif match(UnaryTags, ' ' . Tag . ' ') > 0
normal h

" otherwise this is the tag that needs closing:
let Found = 1

endwhile " not yet found match

" create the closing tag and insert it:
let @z = '</' . Tag . '>'
normal `z
if col('.') == 1
normal "zP
normal "zp

else " filetype is not HTML
echohl ErrorMsg
echo 'The InsertCloseTag() function is only intended to be used in HTML ' .
\ 'files.'
echohl None

endif " check on filetype

endfunction " InsertCloseTag()

Then, when you open one of the appropriate filetypes, Vim will automagically use the closetag script. The closetag script includes the mappings you need to close tags. When you want to insert the closing tag, just press Ctrl-Shift-_. (In case that's difficult to read, the last character is an underscore.)

As you can see, the tags that don't require closing tags are declared in the script on this line:

let UnaryTags = ' Area Base Br DD DT HR Img Input LI Link Meta P Param '

You should add additional tags here if there are any tags that you use that should not have a closing tag. Otherwise, if you have an <img> tag in the document, for example, the closetag function will attempt to close it the first time you use the closetag function after another element.

Find your own scripts

That's just a small sample of the scripts that are available for Vim. In general, if you've ever thought to yourself, "Vim's really nice, but I wish it could do this," there's a good chance that someone has written a script to do just that. You can even find a script that gives Vim Emacs-like keybindings, which is actually a bit disturbing.

If you program, you'll find plenty of scripts specific to C, Python, Perl, Ruby, and other languages. You'll find tons of other useful scripts, as well as a few entertaining but not-so-useful scripts, on Vim's scripts page. Spend some time browsing the site, and you're bound to find a few scripts that fit your needs.

If you don't, Vim's documentation includes a reference for scripting Vim to help you get started.

Click Here!