Tuesday, August 31, 2010

Using TextMate for Scala Development

I’ve been developing Scala using TextMate for a couple of months now. It’s been a pleasure but every once in a while I’ve stumbled upon features that were missing that would improve the experience. I couldn’t resist the urge to implement the most interesting of these features so while working on my GSoC Project, Lift and a commercial Scala project I set out to develop a SBT Plugin and a Scala Bundle.

In this blog post I’ll guide you through the installing progress, show you the robes and you’ll be off happily hacking Scala using TextMate shortly after that.

Just to get you excited I've taken some screen shots

Installation

The bundle

Installing and configuring the bundle is a three step process. First off download & install it by typing the following in your terminal (requires git):

git clone git://github.com/mads379/scala.tmbundle.git
open scala.tmbundle

Then add the shell variable SCALA_HOME in TextMate -> Preferences... -> Advanced -> Shell Variables to the root of your Scala installation. For me this is

/Users/Mads/dev/programming_languages/scala-2.8.0.final

Some of the features of the bundle uses ctags, so please add the following to your ~/.ctags file (If you haven’t got one, simply create one)

--langdef=scala
--langmap=scala:.scala
--regex-scala=/^[ \t]class[ \t]+([a-zA-Z0-9_]+)/\1/c,classes/
--regex-scala=/^[ \t]trait[ \t]+([a-zA-Z0-9]+)/\1/t,traits/
--regex-scala=/^[ \t]*type[ \t]+([a-zA-Z0-9]+)/\1/T,types/
--regex-scala=/^[ \t]def[ \t]+([a-zA-Z0-9_\?]+)/\1/m,methods/
--regex-scala=/^[ \t]val[ \t]+([a-zA-Z0-9]+)/\1/C,constants/
--regex-scala=/^[ \t]*var[ \t]+([a-zA-Z0-9]+)/\1/l,local variables/
--regex-scala=/^[ \t]package[ \t]+([a-zA-Z0-9_.]+)/\1/p,packages/
--regex-scala=/^[ \t]case class[ \t]+([a-zA-Z0-9]+)/\1/c,case classes/
--regex-scala=/^[ \t]*final case class[ \t]+([a-zA-Z0-9]+)/\1/c,case classes/
--regex-scala=/^[ \t]object[ \t]+([a-zA-Z0-9_]+)/\1/o,objects/
--regex-scala=/^[ \t]private def[ \t]+([a-zA-Z0-9_]+)/\1/pd,defs/

And that’s it! For more information about the bundle check out the Github project. If you haven’t done so already feel free to ‘watch’ the bundle. It encourages me when I see a new watcher ;)

The plugin

Now, for the bundle just visit this site and download the newest version of the plugin. At the time of writing this is Terminal-BETA-2.0.zip. Once you’ve downloaded it simply unzip it and double click the Terminal.tmplugin file.

You also have to add the SBT_PATH shell variable in TextMate. It has to point to a shell script that starts SBT without colors, here’s an example:

java -Xmx1512M -XX:+CMSClassUnloadingEnabled -Dsbt.log.noformat=true  -XX:MaxPermSize=256m -jar dirname $0/sbt-launch-0.7.4.jar “$@”

My SBT path is set like this:

SBT_PATH = /Users/Mads/dev/tools/sbt/sbtnocolors

Now relaunch TextMate (I’m pretty sure this is necessary) and open the TextMate preference. The plugin should’ve added a new tab called SBT Console. In this view you can change the colors of error messages etc. so it matches your current theme.

Using it

The bundle

Like any other TextMate bundle this bundle includes a language definition which tells TextMate how it should highlight the file, indention rules, comment rules etc. The syntax definition for this bundle have been greatly improved by Paul Phillips. Paul Phillips works on the Scala compiler (to my knowledge) so the syntax highlighting is pretty precise.

Besides the basic language definition it comes with a set of snippets also. The best way to explore these is by hitting ctrl+escape in a .scala file and check out the menus.

Now for the fun part. The bundle also comes with a set of commands. I’ll go through the most awesome ones now.

  • Navigation (⌘⇧c)
    This is my all-time favorite. This will display a pretty list of all the traits/classes/objects/types in the project. Simply pick the one you want and press enter and Textmate will jump to the appropriate line in the file where you declare that class/trait (etc.). This command requires you to have an index file of the project. To create one hit ⎇⌃⌘t.
  • Comments
    • Javadoc for line (⌃⇧d)
      This will analyze the the current line and add the appropriate documentation for the line (i.e. correct @param etc.)
    • New javadoc line (shift-enter in comment scope)
      This will create a new correctly indented comment line.
  • Refactoring
    • Organize imports (⌃⇧o)
      This will take the current selection and organize the imports alphabetically.
    • Reformat Document (⌃⇧h)
      This will reformat the current document using Scalariform (http://github.com/mdr/scalariform).

The plugin

The plugin is of course only relevant to you if you’re using SBT. But who am I kidding. Of course you’re using SBT.

Open a TextMate project - so just any folder that contains a SBT project. Now hit ⌃⇧1 to toggle the SBT console. Now you can start an interactive SBT session by typing sbt shell or you can run a single command by typing sbt compile or whatever command you want. You can toggle focus between the document and console by hitting ⌘⇧1

If any errors/warnings happen it will link to the appropriate line in the file that contains an error. Try removing a { or similar to try it out.

Thats it. Thanks for Reading,
Mads Hartmann

7 comments:

  1. Thanks for this! FYI, the ctags binary you supply seems to be compiled as 10.6 only. On 10.5.8, I get "dyld: unknown required load command 0x80000022 Trace/BPT trap"

    ReplyDelete
  2. Hey Adriaan, since the blog post there's been made a fork which should work on older systems :) You can check it out here: http://github.com/oxlade39/scala.tmbundle

    Thanks,
    Mads Hartmann

    ReplyDelete
  3. Hi Mads,

    Pretty nice your work! Congrats!

    For some reason I cannot see the terminal in textmate. I triple checked the instructions, tried different Terminal builds and nothing. I am using TextMate 10.5.8. Any tips?

    ReplyDelete
  4. Hello
    Navigate still not working with 10.5.8 and http://github.com/oxlade39/scala.tmbundle
    I have only blank widow.

    ReplyDelete
  5. Hi,
    Nice Scala bundle. I had issues with the plugin however. I couldn't enter anything until I switched to horizontal mode. Then I could get it to run, but it wasn't parsing the output (e.g. making errors clicky). So I ended up making my own simple SBT bundle based on the Java bundle's parsing of the Ant output. It is on github here: http://github.com/willu/SBT.tmbundle

    Thanks again for the Scala bundle.

    Will

    ReplyDelete
  6. Great effort! But, I'm having the same issue others have been reporting, where the console comes up but doesn't take any input (no cursor, no activity). Since this is working for some, I suspect it's environmental. Any insight? (BTW, Dave Pollack says hi and that you should fix this :))

    ReplyDelete
  7. Really nice bundle. But I still cannot figure out how to use Navigation. Would you provide some hints on how to create project index? By pressing ⎇⌃⌘t I only see the Bundle Editor. :(

    ReplyDelete