Relisp: Rubyfied Emacs Lisp


Okay, look. If you use Emacs extensively and have never wished you could use something, anything, to customize it besides Lisp…well, then, 100 hacker points for you. But not this project. This project is not for you.

This purpose of Relisp is to:

  • call Ruby from Emacs
  • call Elisp from Ruby
  • manipulate Emacs without using Elisp to some extent (Ruby wrappers around some Elisp functions and objects)
  • reduce the number of blog entries titled “Is Ruby an acceptable Lisp?” and flame wars under the title “ruby vs. lisp vs. scheme vs. haskell vs. …”

How about some examples?

Call Ruby from Emacs

(relisp-start-slave)
(ruby-eval "1 + 2 + 3")
;    => 6
(ruby-eval "'ruby string'.reverse")
;    => "gnirts ybur"

Emacs starts a ruby process and they both pass questions and answers back and forth. Simple enough. But it’s more than just handing each other strings:

(type-of (ruby-eval "{:first => 'john', :last => 'doe'}"))
;    => hash-table
(setq list '(3 5 2 6 4 1))
(ruby-eval (concat (relisp-to-ruby list) ".class"))
;    => Relisp::Cons
(ruby-eval (concat (relisp-to-ruby list) ".to_list.class"))
;    => Relisp::List [a subclass of Array]
(ruby-eval (concat (relisp-to-ruby list) ".to_list.sort"))
;    => (1 2 3 4 5 6)
(type-of (ruby-eval (concat (relisp-to-ruby list) ".to_list.sort")))
;    => cons

Whenever objects are passed from Elisp to Ruby or back again they’re translated to the appropriate analogous type/class in the other language. An Elisp integer becomes a Ruby Fixnum, a vector becomes an Array, things like that.

Call Elisp from Ruby

I’ll admit it—I initially added this functionality just so I could run Relisp’s unit tests from the Ruby side. But if you ever want to use some Lisp in your Ruby programs, you can do that now.

require 'relisp'
 
emacs = Relisp::ElispSlave.new
emacs.elisp_eval( "(+ 1 2)" )
#    => 3
emacs.elisp_eval( '(concat "two " "words")' )
#    => "two words"

Looks sort of like the Lisp version, right? Using the typical method_missing magic, unknown ElispSlave methods are translated into calls to Lisp functions:

emacs.*(5, 2)
#    => 10 [calls (* 5 2)]
emacs.create_file_buffer( "blah.txt" )
#    =>  #<Relisp::Buffer:0x7f3839cf8168 ...> [calls (create-file-buffer "blah.txt")]

The result to that last example sort of gives away the grand finale. Wouldn’t it be nice to have a Ruby interface to things like buffers, windows and frames? Yes. Yes it would:

new_buffer = Relisp::Buffer.new("name_of_new_buffer")
new_buffer.switch_to
Relisp::Frame.new({:width => 80, :height => 20, :name => "ruby frame"})

Installation

For all of the glorious details, see the documentation at http://relisp.rubyforge.org/. To get the gem, just pull up the terminal:

[sudo] gem install relisp

There’s one little extra step after installing the gem that involves putting the relisp.el file in your ~/.elisp directory. The instructions will come up when you install the gem.

, ,

  1. #1 by zhando on October 8, 2010 - 5:39 pm

    This is nice.

    I was about to slog through doing a web-app for a text processing/analysis app when I thought why not use emacs which already knows how to window and has all the machinery and ui to browse and navigate window contents baked in.

    But then I’d have to really learn elisp.. groan.. Another learning curve.

    Thankfully less of one with this library. I should learn elisp anyway but this suffices for prototypes that might end up being production apps at the end of the day.

    Thanks.

  2. #2 by don on October 8, 2010 - 6:48 pm

    It sounds like you want to the same sort of thing that I was doing when I decided to write this. I hope it’s useful for you—please let me know how it goes, and if you see areas for improvement.

  3. #3 by Marcelo de Moraes Serpa on September 2, 2012 - 6:59 pm

    This is so freaking awesome! The potential to use emacs and emacs extensions from Ruby opens a lot of possibilities. For example, I’ve been using org-ruby, a nice gem that can parse org files, but it’s limited. With relisp and some glue code, I can actually use orgmode! Is this project still being mantained? You should move it to github, so that more people can be aware of it!

    Cheers,

    - Marcelo.

  4. #4 by don on November 25, 2012 - 5:58 pm

    I’m glad you’re excited about it. I saw your post on emacs-orgmode list. Please let me know what you end up doing with it.

    It is still being maintained in the sense that if I or someone else finds bugs or needs more features, I’d like to work on it. I guess that what “maintained” means, but I just haven’t had a lot of time or need to work on it lately.

    Re github: Yes, I really should, a long time ago. But it’s up now. Thanks for pushing me to do it. I started the project so long ago that I was originally using bazaar, and knew switching to git would require spending a whole 5 minutes researching how to import.

(will not be published)