Emacs: setup geared towards doing `Ruby based Web-Applications`

For me to call an editor decent(for Ruby based WebApps), it must have:

  • A good Ruby editor
  • Good Haml editor
  • Good rhtml/html+erb editor
  • Good JavaScript editor
  • Terrific auto-completion
  • Decent ruby debugging support
  • Decent tag navigation(eg. navigating from method/class/module/variable usage to definition)
  • Ability run Test::Unit/Rspec tests from the editor
  • Ability to show multiple files at the same time(by splitting windows)
  • Ability to jump between related files(controller – model – view – spec/test etc)
  • Ability to run an interactive ruby console within the editor
  • Auto-generatable snippets (some call this one LiveTemplates)

RubyMine has support for certain things like decent ruby editor, showing multiple files at a time(i am assuming it works well, because this was supported in IntelliJ Idea when i used it last), ruby debugging and auto-generatable snippets, but it lacks on certain other fronts. For example, it does not have Haml editor and no key-binding to jump between related entities(controller, model, view, spec, helper etc). However, the major drawback with RubyMine is its resource footprint. I have seen developers force shutdown their OS X (running on MacBook Pro) because RubyMine decided to go unresponsive and `kill -9 <pid>` failed to get rid of it. Even GNU/Linux users are forced to kill it sometimes because it freezes too often(however `kill -9 <pid>` does work reliably on Linux, hence no operating system restart required ;-)). JavaScript support is dumb and doesn’t highlight errors too well. I do give it some points for navigation and searching though.

TextMate unlike RubyMine is light on resource footprint. But unfortunately, it also is low on features. Ruby editor is decent, but auto-completion is retard(it completes words from the current buffer(file) only).  Besides, key binding for auto-complete(which is such a common operation) is Esc(no touch-typist in the sane world would like that). It has no debugging support at all, and running rspec needs a plugin which in turn needs rspec installed as a gem, and if you have a frozen version of rspec/rspec-rails in your application codebase, then tough luck(there is no easy way to configure it to pick things up on a per project basis, you need to roll your sleeves up and dig into /Application/TextMate.app, to modify some badly written ruby/shell-script mess). Navigation and searching is horrible(slow and unintuitive). Command-T has no notion of priority, and brings up all the wrong files first. Haml support has to be installed seperately as a plugin, and is terrible(be it indentation, or syntax hilight). There is no interactive console and no spliting of windows supported.

There is more that i expect from an editor before i call it a good programming environment. Here is what I think my definition of good programming tool looks like(in addition to the features in the bulleted list above):

  • Ablity to run multiple terminals within the editor
  • Ability to open directories as buffer(allowing easy selection of files)
  • Ability to run IRC client(i like to be on IRC channels all the time, helping people and seeking help is a great way to learn)
  • Snappy frontend and sensible keystrokes(close to the host row, not forcing user to get out of touchtyping mode too often)
  • Straightforward key-bindings for macro record and play.(Both TextMate and RubyMine claim to have Macro support, but its hidden somewhere under the MenuBar-Submenu(s))
  • Ability to run commands without leaving the editor or creating a terminal within it.

Emacs is a pretty powerful and mature editor which has passed the test of time and has got several refinements and enhancements over the years it has lived. Most of the major things that i want in my development environment are bundled with Emacs out of the box(and the once that aren’t, are available as plug-ins). I believe the best thing about Emacs is its written in lisp, which means you can change things very easily and cleanly. I do Ruby/Rails development in my day job, and have been customizing my Emacs repository for some time now. Over a period of time, i have accumulated/tweaked some emacs goodies which have not only made Emacs a better Ruby, JavaScript, Lisp, C++ editor, but a better IRC, Mail, RSS, Atom and News client. I keep my add-ons and customizations on github.com as a public repository, which helps me share it with other developers, and also gives me protection against disk failures and other bad things.
So here is what my setup looks like.

  • Ruby: ruby-mode(written by Matz) + ruby-electric(minor mode)
  • Haml: haml-mode(Nathan Weizenbaum) (by far the best support for HAML syntax highlight and marvelous indentation strictness, people who write haml know how painful it can get in TextMate/RubyMine to hunt bad indentation and fix it, but not with Emacs)
  • Rhtml/Erb: rhtml/rhtml-erb (Paul Nathan Stickney) Great syntax highlighting and indentation support.
  • JavaScript: I was waiting to come to this one. js2(Steve Yegge) has the best JavaScript editing support I have ever seen. js2 has remarkable indentation, very good syntax highlighting and terrific error detection(warns you even about missing var and semicolons, let alone the more obvious errors).
  • Auto completion: Of course. This one works across buffers, across modes and unlike TextMate’s `Esc` the key binding(M-/) is quite sane. You don’t have to go out of touch-typing mode, and the same shortcut can be used to browse through other possible completions.
  • Ruby Debugging: rubydb3x to rescue (rubydb2x for Emacs 19.2 and older). Just fire rubydb and get rolling. It uses GUD (Grand Unified Debugger), and has sensible(easy to remember) shortcuts(unlike F7, F8, F9 that most IDE(s) have). Some common key bindings are C-n for next line C-s to step in, C-f to finish function, C-r to resume and <, > to roll stack frames up and down(the name-space used is C-c, so it doesn’t override any of the usual actions that those shortcuts are supposed to perform).
  • Tag navigation: Navigation is a breeze. M-. to get to the implementation, M-* to pop out of it. I enhanced it to make it a look recursively up the directory hierarchy to find the tags file(a file named TAGS) and load it up and navigate seamlessly, all by itself. (etags doesn’t have ruby support, so use exuberant-ctags)(“/usr/bin/ctags -e -a –Ruby-kinds=-cmfF -o TAGS -R <dir_name>” can be used to generate a file named TAGS which emacs will read to navigate ruby code).
  • Test::Unit/Rspec tests: test-runner(a tiny add-on) runs your test as you load a test file, and then autoruns it every time the test file is saved. It supports Test::Unit by itself, I added support for Rspec(even running single spec) to it. Works like a charm, and is very easy to tweak.
  • Ability to show multiple files by splitting windows up: Do i need to say anything about windows support? Emacs is loved for this capability. However, navigation between windows was a bit painful before i added window-numbering.el (Nikolaj Schumacher), which made it sweet.
  • Ability to jump between related files: Rinari(Phil Hagelberg, Eric Schulte) uses jump(Eric Schulte) to make jumping between controller-model-view-helper-spec-test on a Rails project seamless and quick.
  • Runing interactive console: ruby-mode has a this hook called run-ruby(bound to C-c C-s), which can be used to start an interactive ruby session.While in a Rails project C-c M-s can be used to load script/console (irb with the project environment loaded).
  • Auto-generatable snippets: YASnippet(pluskid) has this awesome snippet support which can be used to selectively load snippets for a particular mode. Snippets can be overridden by adding a custom location to pick snippets from after loading the default snippets(no need to dive into library code base to make changes)
  • Ability to run multiple terminals: Not just one, there are multiple flavors of terminal supported within Emacs(ansi-term, shell and eshell to name a few). Each one has its own strong points, but they are all great.
  • Ability to open directory within a buffer: dired is your friend (its a full blown file manager).
  • IRC client: rcirc can be used to keep in touch with IRC channels. A line or two of lisp can be dropped in to change its default behavior(such as what channels to join, on which servers, using what alias… etc).
  • Snappy frontend and sensible keystrokes: Its has lower footprint than most other editors, TextMate and RubyMine are no match. I can not say it has not frozen ever, it does(but very occasionally). Even when it is frozen, 3 Esc hits or C-g can be used to abort the activity causing it to freeze. I don’t remember killing it(have been using it for more than a few months now). It just never gets that bad.
  • Straightforward key-bindings: I feel key-bindings are very carefully chosen. More common the key, closer it it to the home row index finger positions(f and j). Macro record/play is bound to C-x ( <definition> C-x ) (parenthesis make sense to developers at once, and i believe its quite intuitive a binding to define something. C-e can be used subsequently to play the macro(macros can be stored by numbers and names too). Even complicated keyboard shortcuts like kill-rectangle have sensible C-x r k (r -> rectangle, k-> kill), paste rectangle similarly is C-x r y (y -> yank). Navigation keys are C-n (n -> next), C-p (p -> previous), C-f (f -> forward), C-b (b -> backward). Sensible key bindings are much easier to remember. Orthogonality is maintained across actions C-u <x> <action> does something x number of times and works across different types of actions.
  • Running single commands: M-! can be used to run commands from within emacs(output is captured in a buffer and shown to the user).

In addition to these emacs comes with some not so well-known features(which need a little exploration), for example make-frame-on-display can create frames on other hosts(making pair-programming really simple). It has terrific Mail/News/Feed reader called Gnus, a beautiful mode for organizing yourself up called Org-mode and a host of other great things like TRAMP(Transparent Remote (file) Access, Multiple Protocol) which lets you edit remote files over a whole bunch of protocols(including ssh, smb, rcp etc) and also allows editing of local files as root(using su). It can open compressed archives(and edit files in place), java jars, PDF files, images…. you name it. Combined with dired, these capabilities make it a great tool. This post has only tried to explain what Emacs is capable of with respect to other editors, and trust me, I haven’t even skimmed the surface of it. One really needs to use it to find out what a brilliant tool it is.

It can be a little daunting for a beginner to set Emacs up from scratch(it is not difficult; its just takes some time and patience). I have spent time setting it up for myself, and I think it is a good setup to start with for people doing Ruby(Rails)/JavaScript and Lisp in general. My repository is available at http://github.com/janmejay/emacs. One of my motivations to put it out is to help other developers(especially people starting out with Emacs), so feel free to pull it up and take it for a ride.

Like every other powerful tool, Emacs has bit of a learning curve, but i believe it pays off, and it pays off pretty well. To a programmer, its not just an editor, it is a “friend for life”.

pluskid

About this entry