Vim Tricks for Ruby and Rails Developers

UPDATE - 17 June: My .vimrc file caused my backspace to stop working under gVim. The code snippet has been updated to fix that now.

RailsCamp5 was awesome, but it left me a little depressed. Watching all the folks using their Macs and TextMate, I couldn't help but thing "Hell! Look how super efficient and productive these people are! What kind of second rate environment am I working in!?". It left me a little despondent to think that, regardless of anything else, these folks were going to be more productive than me just due to their setup.

On the Saturday evening, we held a Vim BOF session - a chance for Vim users to share their tips and tricks, and to attempt to convert some of the Mac crowd into the cult that is Vim. I fully expected to go in there and pick up only a few cool key combos that I'd missed, or a few cool syntax files. How wrong I was.

From that session, I now feel entirely better about my dev environment of choice (Gentoo Linux and Vim). In fact, just the things I picked up from that session have me feeling orders of magnitude more productive.

The first awesome tool I had been missing was NERD Tree, which is a plugin for Vim which gives you the project pane / directory style window on the side showing all of the source code in your project. This feature, in fact, was the only reason why I had recently adopted GEdit in preference to Vim when working with Rails apps; it is just so handy to have a list of all of your files available.

To set it up, simply download it (or check out the git repo), and drop the NERD_tree.vim file into your ~/.vim/plugin directory.

To make it easier to access (rather than typing :NERDTreeToggle all the time), I've added a mapping for Ctrl+D to my .vimrc file :

:map <C-d> :execute 'NERDTreeToggle ' .getcwd()<CR>

Then, it's as simple as selecting the file I want, and pressing "t" (to open in a new tab), "o" to open in a new vertical panel, or "i" to open in a new horizontal panel. Combined with "m" (to handle file operations like delete, copy, move, etc.) it's as feature rich as any other project panel.

(Note for those who forget - Ctrl+W and direction to navigate between panels)

The second thing that has helped has been rails.vim, which is a plugin to make Vim more Rails aware. Not only does this fix a bunch of syntax issues, but it also provides some helpers to jump around your project quickly. For example .gf will look for a controller or model which matches whatever is under the cursor. This allows you the quickly jump to the Model from a Controller (for example).

I've yet to play with the integration with script/* and the partial extraction stuff, but it looks cool.

One slight tweak I've made is because I'm under the impression that Rik and I are the only two people in the Ruby community who actually prefer using TABs over spaces in our source code (likely stemming from the fact that I like to tweak my tabs at 2 or 3 spaces, depending on what I'm doing, whereas Rik likes his at 4 or 8). As rails.vim forces the Rails "2 space indentation", I've added a hack to my .vimrc allowing preventing TABs from being expanded.

autocmd User Rails    set no expandtab

Suck it, space-lovers! Do what you like in your projects, I'll do what I like in mine!

And, to make sure I can tell when there are TABs vs. Spaces (something I was missing from e), I have set them to display as characters rather than whitespace :

set list listchars=tab:>-,trail:.
:highlight SpecialKey ctermfg=darkgrey

This means that \t characters are now replaced with a grey >- or >-- depending on my indentation setting (using set ts). It also adds grey "." characters for any trailing spaces at the end of the line - handy for trimming up garbage left when moving code around.

The final tool I've added is the fuzzy_finder plugin, which acts similarly to TextMate's fuzzy finder and allows you to type in parts of a filename and it attempts to find it for you. For example typing "a/m/contr" will search for files matching this sort of structure. In my case, it suggests files including "app/models/contract.rb" - the file I was looking for.

I got most of the information about this from Jamis Buck's blog post Coming home to Vim . Suffice to say, you need fuzzyfinder.vim AND Jamis' fuzzyfinder_textmate code.

Again, I've added some easier keybindings so allow me to use the finder:

" Ctrl+T to find a file and open it in this buffer
:map <C-t> :FuzzyFinderTextMate<CR>
" Ctrl+B to search the buffers currently open
:map <C-b> :FuzzyFinderBuffer<CR>
" Because I don't want to find my log files
let g:fuzzy_ignore_limit = 70

For reference, my complete .vimrc file is :

set ts=2
setlocal spell spelllang=en_au
set noexpandtab

" gvim backspace breaks unless I provide this, so...
set bs=2

" enable syntax by default, ensure we're using a meaningful scheme
colo slate
syn on

" make sure that bottom status bar is running
set ruler
set laststatus=2
set mouse=a
set list listchars=tab:>-,trail:.
:highlight SpecialKey ctermfg=darkgrey

" Stop rails.vim from fucking with my expandtab settings.
" I don't care if everyone else likes spaces, TABs all the way baby!
autocmd User Rails      set noexpandtab

:map <C-n> <ESC>:tabnew<RETURN>

:map <C-t> :FuzzyFinderTextMate<CR>
:map <C-b> :FuzzyFinderBuffer<CR>
:map <C-d> :execute 'NERDTreeToggle ' . getcwd()<CR>
let g:fuzzy_ignore = "*.log" 
let g:fuzzy_matching_limit = 70

These tools, combined with the incredible power that Vim already has (regex substitution, I'm looking at you!), means that I am now feeling more comfortable with my environment of choice. Combined with my other tools - screen, XFCE - I feel that I can get anything done quickly that I need to.

(Reference, gt to swap tabs, or Ctrl+PageUp and Ctrl+PageDown)