Archive for June 27th, 2010

Ctags and Vim for Ruby on Rails Development

Tagging is a feature that gives vim IDE-like code browsing powers.

:help tags

A tag is an identifier that appears in a “tags” file. It is a sort of label that can be jumped to. For example: In C programs each function name can be used as a tag. The “tags” file has to be generated by a program like ctags, before the tag commands can be used.

ctags -R *

is probably the most simple usage of ctags command from the command line, issued from the root of the Rails project. The result is a file named tags which indexed all objects, so it makes easy to jump, for example, to a Ruby method definition just by using CTRL-[ shortcut anywhere in the code where that method is used.

However, ctags can be told to exclude some of the files and directories and it makes sense to ignore the .git and log directories as they do not contain useful information:

ctags -R --exclude=.git --exclude=log *

But it would be more useful if we could have access to the Rails core method definitions and documentation, as well as for the included gems. Bellow, I have included the gem directory of my default ruby (ruby-head under rvm):

ctags -R --exclude=.git --exclude=log * ~/.rvm/gems/ruby-head/*

Navigation tips:

  • :ta belongs_to jumps to belongs_to method definition
  • CTRL-] if you see a call to a method and wonder what it does, position the cursor inside the method name and hit CTRL-]
  • CTRL-T to go back from the method definition

Two other useful shortcuts: CTRL-I and CTRL-O – think of them in and out the method definition.

Navigating through a list of methods with similar names

:ta /^validates_*

will look for all method definitions that starts with the given string. By default it will jump to the first definition found, but we can do more.

Following vim commands can be used to navigate through the method definitions:

  • :ts shows the list
  • :tn goes to the next tag in that list
  • :tp goes to the previous tag in that list
  • :tf goes to the first tag of the list
  • :tl goes to the last tag of the list