Exploring TextMate...a Ruby perspective

Marshall Vandegrift has posted an interesting screencast showing off Emacs as a tool for Ruby/Rails development. I enjoyed the screencast, and Emacs certainly has cool features but all I could think whilst watching it was (WARNING: FLAMEBAIT ALERT!)...”urgh, its soooo ugly, how could anybody work with that all day. And TextMate does all of this and in a much nicer way…”.

It got me thinking about how I use TextMate every day and whether I really take full advantage of its built-in commands and snippets for Ruby and Rails development. I wondered how many of the features in the above Emacs screencast were already in TextMate and the answer was…most of them! This inspired write a post about some of my favorite TextMate snippets and hopefully you’ll find out about a few you didn’t know about.

Whether you are a new or seasoned TextMate user, its really worth spending some time to learn some of the more useful snippets in the bundles for the languages that you are using. I’m sure most Ruby and Rails developers are aware of the basics such as do..end completion and the various snippets for creating classes, modules and methods. What follows is an overview of some of the cooler functionality built into the Ruby/Rails bundles that you might not have come across. There is a certain amount of mental overhead in learning these snippets but if you can you will find yourself being even more productive.

But first…

If you are running a stock TextMate install, you’ll only have the default set of bundles. There is a wealth of bundles in the Macromates Subversion repository. I won’t repeat the installation instructions here, but I will mention a small tip for managing your bundles.

The Macromates repository has a lot of bundles and the chances are you will only need a small selection of them. Installing all the bundles slows down TextMate’s opening times and adds a lot of noise to the Bundles/Snippets menus. Instead of simply checking out all of the bundles into your /Library/Application Support/TextMate folder, create a folder in a Subversion repository of your own, and check the empty folder out to /Library/Application Support/TextMate. Now, add all the folders in the Macromates repository except the Bundles folder to your repository as an svn:externals entry. Next, create a Bundles folder and check this in. Finally, add all of the Bundles that you want as svn:externals entries in the Bundles folder.

If the above sounds too complicated or time-consuming, you can use my own setup as a starting point.

Syntax constructs

Note: for the rest of this article, I will put any relevant tab-triggers in square brackets.

The TextMate Ruby bundle has snippets for most of the common declarations that you are likely to use…there are definitions for classes [cla], modules [mod] and methods [def] and other common blocks such as conditional statements [if, ife, elsif], loops [until, while], exception handling [begin] and generic blocks [do].

The class and module snippets, like a lot of newer snippets, use a single tab expansion for multiple snippets, with the different options appearing as a contextual menu. This reduces the overhead of learning lots of obscure triggers and gives you a good overview of what you can do with a particular trigger. The class snippets, for example, have variations for creating standard classes, classes with inheritance, classes with a generated initialize template and more. You can even create a new Test::Unit testcase, complete with the necessary requires, Test::Unit::TestCase inheritance and a default test method with a single trigger [tc].

Finally, there are snippets for many of the common tasks performed when writing a Ruby script, such as entering the shebang line [rb], requiring files [req], generating symbol => value key/value pairs for hashes [:], lambda blocks [lam], and one of my favorites, path-from-here [patfh] which is used for getting the path relative to the current script and generates:

File.join(File.dirname(__FILE__), *%w[rel path here])

Writing classes/modules

In addition to the snippets for defining classes and modules, there are some other goodies too.

If you want to add Enumerable support to your class, you need to include the Enumerable module and define an each method. To do this in Textmate, simply create a new class then inside your class definition, use the Enumerable snippet [Enum]. This will generate something like this for you:

class Foo
  include Enumerable

  def each(&block)

  end
end

In a similar fashion, the Comparable snippet [Comp] will include the Comparable module and create a stub <=> method for you to fill in.

Defining attributes for your class is a breeze – TextMate contains snippets for attr_reader [r], attr_writer [w] and attr_accessor [rw]. You can define class methods just as easily as you define instance methods [defs], alias methods [am] and overwrite method_missing [mm]. Don’t forget the singleton class for helping out with that meta-programming goodness [sin].

Other cool snippets

There are plenty of snippets for all of your favorite iterators including each [ea], each_pair [eap], collect/map [col/map] and everybody’s favorite, inject [inj]. There are too many to mention here – there are snippets for all of the common iterators and block methods defined in Enumerable and other collection classes, as well as snippets for iterating over files.

How often do you fire up IRB just to run a simple snippet of code? I do…but why waste time loading up IRB when you can execute lines of Ruby directly in TextMate? Simply write a line of Ruby code, then run the “Execute line as Ruby” command [Ctrl + Shift + E]. The result of the expression will be inserted directly on the next line.

Finally, some personal favorites. Trying to convert all those string keys to symbols in your Rails app to make things much easier to read? TextMate makes it easy to switch between strings and symbols – simply move the cursor onto the string/symbol you want to switch and hit [Ctrl + :].

Interested to know whats going on under the hood of the library that you’ve required in your script? Put the cursor over the require line, and hit [Cmd + Shift + D]. If TextMate can find the required file, it will open it for you. How cool is that?

A final, Rails-related mention goes to the Rails migration snippets. There are only three commands you need to know: columns, tables and indexes [mcol, mtab, mind]. All of the common migration commands are supported and where possible, the snippets will generate your self.down method for you, whilst you are writing the self.up method! A particularly good example of this is “Drop and Create table” – type in the name of the table you want to drop, hit tab twice and it will populate self.down using the relevant section of your schema.rb. Clever stuff.

Writing your own bundles

Of course, the real power behind TextMate lies not only in its pretty good set of existing bundles, but the ability to write your own. Writing snippets is the easiest of the lot and I really advise you to create your own “personal” bundle to store all of the little snippets tailor-made for you. The next step up is writing commands and here is the killer feature – you can write your commands in whatever language you know best, as long as TextMate can find the interpreter (it uses a shebang line at the top of your command). A lot of the built-in commands are written in Bash, but many of the Ruby commands are written in, unsurprisingly, Ruby. Take a look at some of the built-in commands to give you an idea of what you can do.

Here are some of the bundles that I’ve written that are available for all:

The last two are still very much under development but the RSpec bundle is pretty comprehensive and covers all of the built-in expectations, as well as the mocking API, Rails integration and spec runners.

Feedback

Have you got any favorite snippets that you want to share with the world? Let me know. You can use the comments below, although I advise for anything but short snippets that you pastie them and post the link.

Return to home page | Check out my tumblelog

16 Comments on this article

1. Comment by Carlos Gabaldon on 30 Oct 2006 at 20:10

Great article, I am a TextMate fanatic, I did not know about [Cmd + Shift + D], that is so cool.

Also, thanks for the bundles, I was planning to write a bundle on RSpec, but kept putting it off, now you just need to do one for ActiveSpec.

2. Comment by Jordan Arentsen on 30 Oct 2006 at 21:10

Thank you very much for your post. Lately, I’ve been actively attempting to learn Textmate to a fuller degree, hoping to learn a lot of the shortcuts Allan uses in the screencasts. In your post, it was useful to see the shortcuts that are oft used, versus those that are more obscure. Thanks again.

3. Comment by John Nunemaker on 31 Oct 2006 at 02:10

I’m starting to think one could study textmate for years and never learn all their is to it.

4. Comment by Dr Nic on 02 Nov 2006 at 14:11

For non-Mac ppl, RadRails does support “templates” though they aren’t as powerful in capabilities as Textmate’s snippets (limitation of Eclipse upon which RadRails is developed).

I’m converting over all Textmate snippets into RadRails so that I too can watch Rails videos and learn the tab-completion codes. Should be available for RR soon.

5. Comment by Dylan on 07 Nov 2006 at 18:11

l33t h4×0R5 uZ VIm !

6. Comment by McCathy on 18 Nov 2006 at 23:11

TextMate is pretty but has no language bundle for Lisp, SML, Prolog etc… Emacs does, been around for a long time… I know its no rocket science to write these bundles, but hey, you got to know the languages pretty well… mind you, i don’t know how to use Emacs either !

7. Comment by Luke Redpath on 19 Nov 2006 at 00:11

There is actually a Prolog bundle and many more (no Lisp or SML though).

http://macromates.com/svn/Bundles/trunk/Bundles/

8. Comment by KevinB on 06 Dec 2006 at 13:12

Not quite as sexy as [cla], but [class] is nice when you just want a class and nothing else. No messing around w/ a contextual menu.

9. Comment by Brian on 14 Dec 2006 at 12:12

Thanks, [Cmd + Shift + D] is an excellent tip.

If the require is a gem we get the ‘File not found’ message. I am not a Textmate expert. Would it be possible to make Textmate to find installed gem files too?

10. Comment by Allan Odgaard on 21 Feb 2007 at 22:02

McCathy: TextMate does have bundles for Lisp, Prolog, and Standard ML (SML).

11. Comment by Bill Berry on 06 Mar 2007 at 19:03

The URL for the UJS4Rails Bundle should be http://source.ujs4rails.com/goodies/UJS4Rails.tmbundle/

12. Comment by push on 19 Jun 2007 at 11:06

hi..to all!

13. Comment by Steve Roth on 26 Aug 2007 at 16:08

I just proved myself once again that no matter how confident of a certain application I am, I can always learn something new. Thanks for the snippets!

14. Comment by Saving Silverman on 17 Oct 2007 at 07:10

Thanks. Good stuff

15. Comment by Extefearady on 05 Jan 2008 at 16:01

Your topic deserves consideration. Extrefox

16. Comment by Cezar on 14 May 2008 at 20:05

”urgh, its soooo ugly, how could anybody work with that all day. And TextMate does all of this and in a much nicer way…”.

Emacs is ugly ? Is that hard to accept that TM < Emacs ? :P

http://www.mixandgo.com/emacs-web-demo.mpeg

Return to home page | Check out my tumblelog

Commenting on this article is now closed