Rinari

Rinari Is Not A Ruby IDE.

Well, ok it kind of is. Rinari is a set of Emacs Lisp modes that is aimed towards making Emacs into a top-notch Ruby and Rails development environment.

It's still a bit rough around the edges, but it's definitely ready for general consumption. That's not to say there isn't room for improvement though—If you want to help or you've got ideas about functionality you wish Rinari had, please contact the developers via Rubyforge; or #emacs on freenode. We are always open to new ideas.

© 2006 - 2007 Phil Hagelberg, Forrest Chang, Ryan Davis, Paul Stickne, and others.

Rubyforge Project

Tutorial: Rails and Emacs - a Dynamic Duo

Rails, in case you haven't heard, is the web development tool that is dramatically lessening the effort involved in producing web applications. Emacs is... well, it's kind of hard to define both accurately and succinctly, but many people call it a text editing environment, a definition that will at least suit our purposes here. The point is that Emacs is quite possibly the most flexible piece of software known to mankind, and thus with the proper encouragement can be shaped into the perfect tool[1] for developing with Rails.

If you aren't using Emacs or Rails, I won't try to convince you; that's been done better elsewhere[2]. It is my intent here to show what I've done (the Rinari package) and what I've learned about how to use Emacs as a Rails development tool. (For the rest of you, when you finally realize that you should be using Emacs and Rails, feel free to come back and read over this later--I'm afraid it might not be that interesting right now.) Keep in mind that this is always a work in progress, and that part of the Dao of Emacs is the state of constantly evaluating your work process and environment to gain an awareness of how it could be improved.

Getting started

Installing Emacs is usually pretty easy. If you're on an OS with a package management system (any decent Linux distribution, for example), you can probably use it to grab GNU Emacs or XEmacs[3]. If you are on Windows, XEmacs seems to be a little easier to install a recent version of; you can get it from xemacs.org. Unofficial precompiled GNU Emacs binaries for Windows are available from several sources listed on the emacswiki. Mac users can get what they need from aquamacs.org, or so I'm told.

Installing Rinari

Rinari Is Not A Rails IDE. By that we mean the same thing as Gnu's Not Unix--that it actually is, but the definition of an (IDE|Unix) is slippery and not worth getting into arguments about. For now you should use Subversion to install Rinari. In your Emacs Lisp directory[4] type svn co svn://rubyforge.org/var/svn/rinari/trunk rinari to fetch the files from the Rubyforge repository. Add these lines of code to your .emacs file, replacing "~/.emacs.d" with your lisp directory:

(add-to-list 'load-path "~/.emacs.d/rinari")
(add-to-list 'load-path "~/.emacs.d/rinari/rhtml")
(require 'rinari)

In the future we will be offering gem and tarballs as alternate installation methods.

Finding your way around

We'll start with something really simple that has nothing to do with Rails: when you're scanning through a file looking for a certain bit of code, you can speed this up by using an incremental search. Just press C-s [5] and type your phrase to jump to the spot it is found. Pressing C-s again will go to the next occurance. It doesn't seem like a big deal, but if you can train yourself to use this every time you're looking for something, it will speed things up quite a bit overall. Emacs also highlights each occurrence, which helps in visually scanning the screen. Use C-r to go backwards. C-M-s and C-M-r search with regular expressions.

A lot of the mental overhead of working with a Rails project is devoted to finding files and switching between files you've already opened. For finding files, there is a handy function called find-file-in-project (bound to C-x C-M-f by default) which allows you to choose from list of all files in the root directory of your current Rails project to open. You can use tab-completion to speed things up just like regular find-file allows you to tab-complete for any file in a directory.

There are also a few common configuration files that you are likely to want quick access to. For these, you can set up bookmarks so that you can jump to them with a few keystrokes. TODO: how to set up new bookmarks. C-c C-f is bound to rinari-find-config-file, which provides an autocompleting list of commonly accessed config files. To add a to this list, modify the rinari-config-files variable.

Sometimes which file you're working on can provide clues to Emacs about what files you would like to visit next. For instance, if you're working on a model, it's quite likely you'll want to take a look at the unit tests for that model. Ryan Davis's toggle.el allows you to just do a quick C-c C-t, and you're there. (It also works the other direction, as well as switching between controller actions and their respective views with C-c C-v.) Pressing C-c C-b will invoke rinari-find-by-context which will examine the line you're on for any references to a partial, action, or controller in another file and find that.

In a file

The snippets.el mode lets you insert commonly-used bits of text by typing a short small trigger. For instance, typing ars SPC will insert assert_response :success and leave your point on ":success" so you can enter a different expected response. Many common Rails idioms have been predefined for you, so take a look at all the available completions. The most commonly used is expanding "% SPC" into "<% -%>" and "%% SPC" into "<%= %>" in RHTML. To enter a % and not have it expand, prefix the next letter with C-q.

If you need to reuse a bit of code in a view, mark it[6] and run M-x extract-partial on it. Emacs will ask you to name your partial, and then it will whisk away your marked text into a new buffer named properly after your partial. It will also insert a render :partial line where the text you had selected used to be.

Interacting with Rails

TODO:
 * get-path (with params and session)
 * script/stuff
 * test help (compile-mode, autotest)
 * arguments for rake
 * psvn
 * emacsclient on error pages?
 * file-name-cache

There is a very handy RI integration for Emacs (not bundled with rinari) that allows you to do quick lookups with autocomplete. You can get it at rubyforge. To really take advantage of it, be sure that ri docs for Rails have been generated. If they haven't, run rdoc -Y in your Rails gem directory. Recent versions of Gem should do this for you. If you have fastri installed (recommended), it will be used instead.

You can keep a script/console running in Emacs as well so you don't have to switch to a terminal all the time. Just invoke the rinari-console function (bound to C-c C-s). Pressing that again while the console buffer is still open will switch to the existing console rather than starting a new one.

Colors

Rinari's RHTML mode defines background colors that are meant to be used with a white background. If you're like me and prefer a more stylish color theme, things get a bit messy. Currently the solution is to define the background on the face that rhtml-mode uses for embedded Ruby in your .emacs file.

(defface erb-face
  `((t (:background "grey18")))
  "Default inherited face for ERB tag body"
  :group 'rhtml-faces)

(defface erb-delim-face
  `((t (:background "grey15")))
  "Default inherited face for ERB tag delimeters"
  :group 'rhtml-faces)

Make sure this snippet is included before you (require 'rinari) in your .emacs file and you should be fine.

Summary

C-c C-s
Open script/console in its own buffer
C-c C-v
Toggle between view and action
C-c C-t
Toggle between model/controller and test
C-c C-r
Invoke Rake
C-c C-f
Find config file
C-c C-M-t
Run current test file
C-c C-S-t
Run current test
C-x C-M-f
Find file in project

1 - The astute reader will note that the execution of this claim requires someone who understands the perfect tool. Obviously all our tools are limited by our imaginations as toolsmiths, but in the case of Emacs that is very nearly the only limitation.

2 - To quote Neal Stephenson: "Emacs outshines all other editing software in approximately the same way that the noonday sun does the stars. It is not just bigger and brighter; it simply makes everything else vanish."

3 - GNU Emacs is the "official" Emacs, and XEmacs is an alternate forked version. Without getting into the ugly historical details, the general gist is that XEmacs provides a few more things by default that may help new users feel more at home, like visually displaying all the open buffers you have in tabs. GNU Emacs can be a bit more cryptic at first, but it's compatible with more existing Emacs Lisp code that is out there. Rinari should work fine in either.

4 - Over time you'll build up a collection of code that you want executed every time Emacs is launched. Placing these snippets of code in a file in your home directory called ".emacs" will make Emacs load all this code every time it's started. Eventually you'll have more code than is convenient to fit in a single file, so you'll want a directory to store it in. It's conventional to store such code in a directory called ".emacs.d" or "elisp" in your home directory. Adding (add-to-list 'load-path "~/.emacs.d") to your .emacs file will ensure that Emacs can always find code that's stored in there.

5 - C-s means hold down the Control key and press 's'. If you're not familiar with this notation, you should definitely read through the Emacs tutorial. To do so, press C-h t -- that is, hold down Control, press 'h', release control, and press 't'. When you see 'M-' prefixing a letter, it means you should use the Meta key. On most systems this means Alt. On Macs sometimes the Command key is used. You can also press Esc before a letter (without holding it down) to invoke Meta.

6 - You "mark" a region of text in a buffer by pressing C-Space at one end, and moving the point to the other end. This is similar to what is called the selection in many other programs. To make Emacs treat the region more like a selection, enable transient-mark-mode. If you prefer this behaviour, you should add the line (transient-mark-mode) to your .emacs file.[4]