who needs docs when you have ctags
Ever since I watched Aaron Patterson's Peepcode Play-by-Play, I've been absolutely fascinated with the use of CTags to jump around the various codebases you have installed (if you use Ruby, you know how much of a maze it can be to figure out exactly where an error is coming from!). As the name would imply, CTags were created for C programmers dealing with massive codebases that typically had minimal to no documentation. Developed during the first boon of open source distribution, and created by some of the people on the BSD UNIX project (it was originally released with BSD UNIX), it was championed as a quick, easy and light-weight way of moving around a codebase.
required equipment
I've written about my setup in the past, and I created a shell framework for zsh users that implements all of the concepts I'm talking about here. This technique requires that you're editing your code with Vim (and any derivatives thereof) and managing your RubyGems with Bundler
vim for the win
CTags was designed for Vim, and since I'm a Vim user I'm going to mostly talk about Exuberant CTags. If you're an Emacs user, you might have to do some extra customization in your editor, but the concept of CTags is still relevant and in my opinion, still useful for any modern programmer.
bundler-managed gemsets
If you're a Rubyist, this probably won't work as intended unless you
manage your application's gems with Bundler and don't use
RVM to manage gemsets/rubies. The reason for this is that
Bundler stores your gem's code inside your application's root
directory (I have it configured to use vendor/gems
, but most people
use vendor/bundle
or something...I think that's the default), and
when you generate your tags
file, it will only look at code under
the given root directory, so if you're only using Bundler to manage
your gem dependencies, you'll be able to access not only your
application's code, but the code of the entire Rails framework as well
as every other gem you're using. From what Michael Papis and
Deryl have been saying on IRC, RVM2 will have support
for custom gem directories, so you can use RVM and Bundler to manage
dependencies in subdirectories of your project, rather than ~/.rvm
,
which makes it a pain for CTags to function (though I have seen Rake
tasks where this becomes a possibility).
let's get it started
To set up CTags, we first need to install Exuberant CTags and get it working with Vim. Thankfully, Exuberant CTags used to be included with Vim, so they compliment each other quite nicely. It's a separate project, now,
OS X USERS!!!
I'm on OS X, so I actually had to rename a built-in binary bundled along with my OS to use Exuberant CTags. OS X comes bundled with Emacs CTags, which are not compatible with Vim (or practically anything else that uses CTags, for that matter). Not sure if people on Linux-based OSes or other flavors of UNIX also have to do this, but before installing Exuberant CTags, I had to do the following command:
$ sudo mv /usr/bin/ctags /usr/bin/etags
This still kept the Emacs binary around, but renames it to something that
won't conflict with the ctags
binary you're about to install.
On OS X, you can just do the following to install Exuberant CTags:
$ brew install ctags
This will place the binary in /usr/local/bin/ctags
. Regardless of your
shell setup, I think it's just easier if you rename the Emacs CTags binary
and install from Homebrew or some other package manager, if you have to.
I'm not going to tell you how to install [Homebrew][brew] because you should already know how or have it on your system. What are you waiting for???
use the tags, luke
CTags is just as easy to use as it is to install. Go to the root directory
of your project and create the tags
file:
$ cd ~/Code/very_important_application $ ctags -R .
Now, open your application code back up. Browse to a method definition,
it would be best if this method was one you knew had only one place it
was defined. Highlight the method_name
in visual mode and hit Ctrl+]
to jump to it's tag definition. Did you notice how your buffer snapped
to the file where that method was defined? You can also go back to
previous definitions of a method by doing Ctrl-[, if the method has
been overridden numerous times. This is especially useful in Rails,
where lots of abstraction and overriding is taking place, and in such
a big codebase it's terribly useful to be able to quickly move between
the different method definitions, showing the evolution of the code
that you will eventually run as you call that method from a higher level.
It's so much easier to get work done when leaving the editor is only done when you're really done coding or you need to look up something that maybe isn't explained quite well in the documentation, as is the case with many of Rails' lesser-known methods (especially those nice little helpers in the view layer).
keep it ignant
Remember to keep your tags
file in your global gitignore file,
~/.gitignore
, in order to keep it out of your repos. It's not terribly
useful to have in there and generally, each developer is going to have
to generate their own tags index every time they download your code
anyway, so it's kinda pointless to version control the index.
I hope that this was an informative crash course on installing, building and using CTags in your daily life. It would be even better if CTags makes at least your work life a bit easier to deal with every day.