Opening Ruby gems in TextMate

Update: Mike pointed out below how to avoid hard coding the path to your installed gems, so I've updated the scripts to use gem environment gemdir accordingly. Thanks Mike...

How often do you find yourself wanting to check the source code of a locally installed Ruby gem? Do you find it painful digging around your filesystem to locate the gems directory?

Rather than this:

mate /Library/Ruby/Gems/1.8/gems/activerecord-2.0.2

I now type this:

mategem activerec[tab]

Note the [tab] key, which converts "activerecord" into "activerecord-2.0.2".

mategem is a bash script. Here's the code (copy it into a file called mategem in the /usr/local/bin directory on your Mac):

#!/bin/sh

usage()
{
     echo "Usage: $(basename $0) <gem>" 1>&2
     exit 1
}

GEM="$1"

[ -z "$GEM" ] && usage
mate "$(gem environment gemdir)/gems/$GEM"

Then make it executable:

chmod +x /usr/local/bin/mategem

You now have a working copy of mategem.

The eagle eyed amongst you will notice that we've not done anything to setup the behaviour of the tab key. And you'd be right; it won't work yet. Tab completion is controlled by Bash (the command prompt that is probably running in your Terminal). To tell Bash how to convert "activerec" into "activerecord-2.0.2", add this code to the end of your ~/.bashrc file:

_mategem()
{
    local curw
    COMPREPLY=()
    curw=${COMP_WORDS[COMP_CWORD]}
    local gems="$(gem environment gemdir)/gems"
    COMPREPLY=($(compgen -W '$(ls $gems)' -- $curw));
    return 0
}
complete -F _mategem -o dirnames mategem

Now tell bash to re-read your ~/.bashrc file:

source ~/.bashrc

Test it by typing mategem and pressing the tab key twice. You should then be able to browse through your locally installed gems. Neat, eh?

You can use this technique to browse the source of any programming language, not just Ruby; just change a few paths, rename the command, and you'll be away.