When writing ruby code, you need a tool to manage your ruby versions as well all the gem you need to have installed. In this post I'll show you some of the advantages of using rbenv if you are using emacs.

TLDR: Scroll down and copy past the elisp code into your .emacs to use rbenv. That's all you need.

The most popular tools to manage ruby versions are chruby, rvm and rbenv.

The best tools in a developer tool belt stay out of our way. rvm does exactly the opposite, it tries to do too much, handling gemsets, installing ruby versions, managing installed gems, etc.

chruby seems like it tries to do the right thing, doing one thing well, but unfortunately it doesn't integrate very well with emacs.

When using chruby, you need to invoke a chruby <ruby version> command in your shell before invoking bundler, gem, or any other command that uses ruby.

Emacs usually uses it's subprocess creation functions to run commands like flymake or when you run ruby or rspec in a *Compilation* buffer. This means that before you can execute a ruby process, you always need to call chruby <version> so that chruby can set all the required environment variables before your ruby process is executed.

This is not easy to manage since every emacs mode can have a different way of invoking shell commands. You could use chruby.el or something similar, but this means that all your emacs modes need to be aware of chruby.el, or you need tome automatic way to call the chruby.el API everytime you run a ruby subprocess.

But we don't need this complexity if the right environment variables and settings are always in your PATH when emacs starts a shell to execute some command.

Enter rbenv. If you make sure that emacs has rbenv's shims path in PATH everytime it starts a new command, then you don't need to worry if emacs selects the right ruby version before running your command. rbenv will do the right thing and setup all the required environment variables for you.

This means that all you need in emacs to run rbenv is the following two lines:

(setenv "PATH"
        (concat (getenv "HOME") "/.rbenv/shims:"
                (getenv "HOME") "/.rbenv/bin:" (getenv "PATH")))

(setq exec-path
      (cons (concat (getenv "HOME") "/.rbenv/shims")
            (cons (concat (getenv "HOME") "/.rbenv/bin") exec-path)))

This guarantees that everytime a subprocess command is used in emacs, rbenv's shims will be in your PATH and you don't have to worry about calling any other commands before invoking ruby commands from emacs. flymake and other common emacs modes will work without any extra configuration.

It's this simple, to use rbenv with emacs you just need these lines in your .emacs!

comments powered by Disqus