A Vim in TextMate clothing

I’ve been meaning to write all this stuff up for ages, but millions of everything got in the way. After my TextMate trial period expired, it became obvious that I could do most everything I wanted with Vim and a few more downloaded scripts. The great thing about TextMate is that it’s all there for you, no months years of hacking to get things just so. The great thing about Vim though (and Emacs I’m sure) is that it grows with you.

OS X key mappings

The first thing I hacked on Vim, setting up as many Mac key bindings as I could think of. As Vim is a unix app, the Mac command key is completely unbound, a fresh keystroke namespace to frolic in. Bind Mac keys with <D-...>.

Quote/bracket matching dark evil

TextMate’s bracket and quote matching magic is really nice, takes a few days before you stop typing the matching character, but it makes sense in the long run. To mimic this in Vim I simply mapped the characters to their complete equivalents in insert mode, e.g.

inoremap <buffer> <silent> " ""<Esc>i

Now this is pretty brute force. It doesn’t support TextMate’s nice addition of quoting/bracketing selected text. Select text in TextMate and type ’(’ and you’ll get the selected text wrapper with brackets correctly. You can map the same in Vim, but “ has a special meaning (select register). I chose to create alternate versions prefixed with _, e.g.

vnoremap <buffer> <silent> _" c""<Esc>hgpa

Some other people are playing around with similar ideas in tip #153 and tip #318 on the Vim site.

Snippets and abbreviations

TextMate’s snippets are probably it’s most raved about feature. They’re useful and easy to user and setup. Vim has some similar ideas with mappings and abbreviations, but nothing quite as powerful. snippetsEmu is a Vim plugin which attempts to provide similar functionality. It does do the same things but it’s not as slick IMHO. Your mileage may vary however. I started using it, but I’ve kind of stopped, possibly due to the inaccessibility of the key binding I chose :-).

Project plugin

The project tab in TextMate is quite useful but the project plugin by Aric Blumer beats it hands down. It’s a wonderfully Vimmish solution to the problem. Highly recommended.

Ctags

The quick jump to file functionality is absolutely awesome, certainly the thing I miss by far the most in Vim. Whilst I’m pretty sure it would be possible to write something very similar, I haven’t had a stab, nor uncovered any plugins as yet (let me know if you find any!). What I have done instead is to make the project plugin a regular part of my setup, and to use Vim’s built in support for jumping to related files with the gf command and ctags files. Ctags is excellent, g<click> to go to any token either in your own code or in external references. Double-clicking a file in the project window is slower than staying on the keyboard and using TextMate’s quick open, but it’s certainly tolerable.

K mapping and CSS 2.1 ref

Hit K in normal mode to do a reference lookup on the keyword under the cursor. You can set what kind of lookup by modifying the keywordprg option. I have external programs that do things like invoke Google searches in Safari, often passing parameters like site:docs.python.org. You can also use :help as a valid keywordprg to look stuff up in Vim’s help.

This is not just useful for hacking Vim scripts, you can get other content in Vim help format, such as this handy CSS 2.1 reference. I use this a lot. Unfortunately, the basic K/keywordprg approach does not work, as the keywords need to be rewritten before jumping into the help file. I use this mapping on CSS buffers to get around the problem:

map <buffer> <silent> K :execute "help '" . expand("<cword>:h") . "'"<CR>

Dictionaries

Vim features a powerful completion system. I find the SuperTab plugin useful to bind this all to the tab key properly. The system itself reads completion words from many locations, the first and often most useful is the set of currently open buffers. However, it’s sometimes useful to have a lookup dictionary, such as languages with fairly narrow namespaces such as CSS or HTML. Tip #91 explains how to set up dictionary files and use them with Vim’s completion system. It’s as straightforward as:

setlocal dictionary+=~/.vim/dicts/css.txt

Where ~/.vim/dicts/css.txt is a file full of CSS keywords.

Vim 7

Vim 7 has some cool new features which I haven’t really got to grips with yet. The most notable is omni-completion, a feature which pretty much invalidates the above tip :-). Omni-completion can use syntax highlighting as a source of keywords, or it can use custom functions. Vim 7 ships with functions for CSS, HTML and many others.

Vim 7 also has built-in spell-checking, with Word-style wiggly red lines, tabs (a la TextMate, Safari, Firefox, etc), browsing through Netrw, syntax highlighting for Django templates built-in and a whole tonne of other stuff which I have no idea how I’m going to make use of yet (undo branches anyone?). Here are some nice animations of some of the new features (ignore the Vim vs Emacs flame-war!). It’s officially released now as well, so go get it!