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.
Comments
Comments are no longer allowed on articles.
Mike Czepiel (10 April 2008, 07:04)
Might be worth checking out the
gem environmentcommand just to reduce the upfront configuration.I’ve typically just
gem which foo -q | xargs mateand then manually figured out the parent, but your tab completion is much friendlier when you can’t remember the exact name of a gem you’re looking for :-) ThanksMario Aquino (10 April 2008, 10:53)
Hooahh!
Dejan Simic (10 April 2008, 11:37)
This is great! Thanks!
James (10 April 2008, 17:48)
No love on OSX. I get
James (10 April 2008, 17:51)
Ah, here’s one of those differences between .bashprofile and .bashrc. There aren’t that many, so this caught me.
Nick DeMonner (10 April 2008, 18:31)
Awesome.
Neil Lott (10 April 2008, 18:38)
Check out gemedit. It does exactly this.
http://gemedit.rubyforge.org/
Tim Harper (10 April 2008, 19:37)
Insanely useful tip! No more browsing to the gem folder for me :)
Lachie Cox (11 April 2008, 04:07)
Hi Graham,
Here’s how I did the same thing, and evolved it into a textmate gui: I love me some source.
Lachie
Graham (11 April 2008, 08:06)
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…
Charmed (11 April 2008, 16:35)
Thanks so much for this tip! So simple and yet it makes the gem files a LOT more accessible….
Jim Meyer (15 April 2008, 20:00)
If you’re weird (like me) and have changed your default shell to tcsh, you can do this:
Dr Nic (17 April 2008, 03:27)
Just for completeness :) there’s also findgem, which includes two apps: findgem (returns path to a gem) and editgem (opens the gem, using open cmd).
Dr Nic (17 April 2008, 03:52)
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.
Tim Harper (24 April 2008, 19:43)
FYI: The said feature Dr. Nic implemented has now been merged into the mainline repository.
http://github.com/timcharper/rubyamp/tree/master