ruby, rails, textmate, automation, etc.

Opening Ruby gems in TextMate

Posted on March 29, 2008

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 like this (where "[tab][tab]" means "press tab twice"), to browse your locally installed gems:

mategem [tab][tab]

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.

Comments
  1. Mike CzepielApril 10, 2008 @ 07:04 AM
    Might be worth checking out the "gem environment" command just to reduce the upfront configuration. I've typically just "gem which foo -q | xargs mate" and then manually figured out the parent, but your tab completion is much friendlier when you can't remember the exact name of a gam you're looking for :-) Thanks
  2. Mario AquinoApril 10, 2008 @ 10:53 AM
    Hooahh!
  3. Dejan SimicApril 10, 2008 @ 11:37 AM
    This is great! Thanks!
  4. JamesApril 10, 2008 @ 05:48 PM
    No love on OSX. I get <<< source ~/.bash_profile complete: usage: complete [-abcdefgjksuv] [-pr] [-o option] [-A action] [-G globpat] [-W wordlist] [-P prefix] [-S suffix] [-X filterpat] [-F function] [-C command] [name ...] >>>
  5. JamesApril 10, 2008 @ 05:51 PM
    Ah, here's one of those differences between .bash_profile and .bashrc. There aren't that many, so this caught me.
  6. Nick DeMonnerApril 10, 2008 @ 06:31 PM
    Awesome.
  7. Neil LottApril 10, 2008 @ 06:38 PM
    Check out gemedit. It does exactly this. http://gemedit.rubyforge.org/
  8. Tim HarperApril 10, 2008 @ 07:37 PM
    Insanely useful tip! No more browsing to the gem folder for me :)
  9. Lachie CoxApril 11, 2008 @ 04:07 AM
    Hi Graham, Here's how I did the same thing, and evolved it into a textmate gui: http://smartbomb.com.au/2008/2/1/i-love-me-some-source Lachie
  10. GrahamApril 11, 2008 @ 08:06 AM
    It seems as though this problem has been solved several times before, each time in a slightly different way. I like your TextMate GUI version Lachie, it's very neat. I've installed it so I've no exscuses for not opening the source...
  11. CharmedApril 11, 2008 @ 04:35 PM
    Thanks so much for this tip! So simple and yet it makes the gem files a LOT more accessible....
  12. Jim MeyerApril 15, 2008 @ 08:00 PM
    If you're weird (like me) and have changed your default shell to tcsh, you can do this:
    
    # Open a gem in TextMate
    setenv TM_GEMDIR "`gem environment gemdir`/gems"
    a mategem 'mate $TM_GEMDIR/gems/\!*'
    complete mategem "p@*@D:$TM_GEMDIR@"
    
    
  13. Dr NicApril 17, 2008 @ 03:27 AM
    Just for completeness :) there's also find_gem, which includes two apps: find_gem (returns path to a gem) and edit_gem (opens the gem, using open cmd).
  14. Dr NicApril 17, 2008 @ 03:52 AM
    Also, this made me want a short cut in textmate (like Lachie's) http://github.com/drnic/rubyamp/commit/a3b0ca0ddccd43c5a96d7386e9994a7e5635bfd2 This is in my RubyAMP TM bundle - put the cursor on a rubygem name, and Shift+Alt+G brings up the bundle in TextMate.
  15. Tim HarperApril 24, 2008 @ 07:43 PM
    FYI: The said feature Dr. Nic implemented has now been merged into the mainline repository. http://github.com/timcharper/rubyamp/tree/master