Running an Inferior Ruby/Rails Shell in Emacs


Here is a list of tips and tricks to get started and work efficiently with the IRB shell in Emacs.

Problem with the IRB prompt

  1. Even though this I tried this tip with Ruby 2.7 and Emacs 27, it seems to be relevant with other versions of Emacs as well.
  2. The tip, while it makes irb usable within Emacs, has some problem with flushing IO. If the prompt does not appear, press enter again, after which two prompts appear.

Recent versions of the IRB console set the prompt and the input line in a fancy way which Emacs does not quite like.

If you run into problems with the IRB prompt and line being unresponsive, you can set the prompt in the ~/.irbrc file:

   puts "Inside Emacs we are.  Simple prompt we need."

   IRB.conf[:USE_MULTILINE] = nil
   IRB.conf[:USE_SINGLELINE] = false

   IRB.conf[:USE_READLINE] = false 
   IRB.conf[:USE_COLORIZE] = true

Preserving history across sessions

Put the following code in the .irbrc file:

require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 200
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history"

Unresponsive IRB buffer

The IRB console runs on top of an interactive shell and the performances decrease as the Emacs buffer grows in size.

Two solve the issue we can either:

  1. Reduce the amount of output produced by Rails, by raising the log level to :warn or :err in the IRB console. This is easily achieved with the following command:

    irb(main):001:0> Rails.logger.level = :warn
  2. Erase the buffer. Unfortunately M-x erase-buffer is of no help, since the text in the buffer is marked as “read only”. However, two other commands come to the rescue:

    Key Elisp function Brief description
    C-c M-o comint-clear-buffer clears the buffer
    C-c C-o comint-delete-output deletes the output of a command

Sending code to the Rails console from an Org Mode file

Using Org Mode and literate programming to interact with a Rails console can be particularly useful to extract and analyze data stored in the DB.

To execute code in the Rails console, follow these steps:

  1. Launch the inferior Ruby shell with inf-ruby-console-auto
  2. In the Org Mode file, refer to the console using :session rails. For instance:

    #+BEGIN_SRC ruby :session rails :results value :exports results
    unit_1 = Unit.find_by(short: "Unit 1")

For some reasons I have not been able to have :results output work, so I always make sure the last instruction in the code returns an array or some other data structure Org Mode recognizes.