Saturday, May 29, 2010

SBT and ENSIME

I imported Ray Racine's sbt.el into the ENSIME project today. What this means is that sbt users can now type C-c C-a to launch (or switch to an existing) sbt interactive shell.

Warnings and errors are automatically highlighted in the shell, and file references are hyperlinked (just like in an Emacs compilation-mode buffer).

Users can customize ensime-sbt-compile-on-save to enable automatic recompilation every time a scala/java buffer is saved. This option is disabled by default, as it eats a lot of CPU, and I don't feel it adds a whole lot over the existing ENSIME syntax/type checking. It may be useful, though, if you're working on a project that you need to run frequently.

If you'd like to bind short-cut keys to sbt actions, you can use the function: ensime-sbt-action which issues an action, provided as a string argument, to the sbt shell.

Thanks to Ray for a nice piece of code. I use sbt for ENSIME development, so this is a welcome addition : )

Thursday, May 27, 2010

The State of Completion

ENSIME uses two completion facilities provided by the Scala presentation compiler, askScopeCompletion and askTypeCompletion. The first lists the symbols that are accessible in the current scope. The second lists the symbols that are accessible as members of the Type of the Symbol at the given Position.

The decision of whether to complete a symbol or a member is made in Emacs, based on the current syntactic context. If the user hits TAB when typing a symbol that follows what looks like an expression, separated by a dot or space, we try to complete as a type member. Otherwise, we assume it's just a floating symbol.

ENSIME augments the completion information with information about the Type and 'callability' of each symbol. This way, we can fill in parenthesis and parameter information when the user selects a callable symbol.

Today I added a third context for completion of a symbol following 'new'. In this situation ENSIME will only return completion candidates that are known to be class constructors. As with methods, we provide param help in the mini-buffer after a completion is chosen.

Tuesday, May 25, 2010

One Emacs, many projects

Often I'll be editing code in an ENSIME enabled project, and I'll want to quickly switch over to another Scala file that's not part of my project. In the SLIME way of doing things, the newly opened file will use the value of slime-default-connection to issue commands to the server process. This value is shared amongst all slime-mode buffers, and is only changed if the user explicitly requests that it be changed. This works well in Lisp, where the Lisp process is not really coupled to any project ... you might want to eval code from many locations. Oftentimes you eval code that's not part of any project -- just lisp forms in a temporary buffer.

An ENSIME server, however, is designed to provide services to exactly one project. So if I open a random file, I don't want that file to be associated with my project's connection unless that source is part of my project.

After today's changes, ENSIME will determine the appropriate connection by examining the currently visited file-name and comparing it to the project information associated with all active connections. This fixes the issue where out-of-project Scala buffers would send commands to our project's connection. It also allows for multiple, coexisting projects.

Monday, May 24, 2010

Day 1

Today is the the first day of coding for GSOC 2010!

I'll be using this blog to track the progress of the ENSIME Scala mode for Emacs.

All ENSIME development is hosted at github.com:
http://github.com/aemoncannon/ensime

There's also a high-level list of goals for the summer:
http://wiki.github.com/aemoncannon/ensime/

ENSIME is already useful (I use it to develop the ENSIME server component, naturally), so if you're an Emacs user, and you don't mind playing with a work-in-progress, grab the latest download package here:
http://github.com/aemoncannon/ensime/downloads

Feedback is welcome!

And a big thanks to Google and The Scala Team for giving me the opportunity to spend my summer hacking Scala and Emacs Lisp. I can't think of anything I'd rather be doing : )