Emacs tip: running ack in the project root w/rinari

This post covers how to combine the awesomeness of ack with rinari in emacs to run ack in the project root by default. (If you aren’t using ack, definitely check it out for searching your codebase. If you aren’t using emacs, this post isn’t going to convince you to switch).

I’ve been using Kim van Wyk’s ack.el for a few months now, but was annoyed that I had to tell it the directory where to run ack, when in most cases I wanted it to run in the root of my Rails app. So I copied the ack function from ack.el and made one that only asks for the search pattern, then runs in the root of the app (provided by rinari’s rinari-root function). I then bound that function to C-c f a.

Here is the code:

Note: you will need rinari and ack.el loaded, and ack will need to be in your path.

Generating a TAGS file from a git hook

Any decent programmer’s text editor provides some form of symbol lookup. With TextMate, the lookup table generation is built in. If you are using vim or emacs, you will need to use an external program to generate the lookup table. This post covers generating the lookup table for emacs (and with some slight modification, vi), and adding a hook to git to regenerate the table after a pull/merge. For more information on using symbol (tag) lookup with emacs or vim, see this wikia entry for vim, or this emacswiki entry for emacs.


Traditionally, the ctags/etags executable was used to generate lookup tables for vi/emacs respectively. ctag would create a tags file for vi, and etag would create a TAGS file for emacs. Unfortunately, the etags/ctags that ships with MacOS X does not parse ruby code. For that, you will need to use Exuberant Ctags. You can install Exuberant Ctags on MacOS via MacPorts with sudo port install ctags.

git hooks

There are some nice hooks that you can define for git to call after/before it performs certain actions. You can read the full list here. Hooks are defined by placing properly named executables into .git/hooks/ in your repo. The two hooks we care about here are post-merge and post-commit ( Update: the script has been modified to register for the post-checkout hook as well, based on a suggestion from Bryan Liles). The post-merge hook will get called after you do a git pull to merge from another repository, and post-commit is called after a local commit. An important thing to remember about these hooks (and anything else in .git) is that they will not be pushed to the remote repo. So if you develop on multiple machines, or want to share hooks with coworkers, you will need to install them in each local repo.

the kitchen sink

Here is the script I use to handle generating tags from ruby code explicitly, generating tags from a git hook, and installing the git hooks. It really should be two different scripts, but… well… isn’t.

You can read it and see what it does. To have it install the hooks in the current repo, call it with the -i@ option. If you use vim instead of emacs, you will need to remove the @-e option and change TAGS to tags on the ctags call.

Once it is installed, your tags will be regenerated after every commit or pull. You can manually regenerate the tags by calling the script from the repo base directory.

Update: to see a video of this script in action, check out Bryan Liles’ post on smartic.us.