Poor man's rspec mode for emacs

Written by Hemant on March 27, 2013; tagged under , ,

For whatever reason rspec-mode didn’t work for me. I couldn’t either get it to use current version of Ruby or it used to crap out on Bundler detection.

Annoyed, I decided to write a very simple rspec-mode that works almost always. More importantly it runs rspec from root of current project directory using your current shell and hence you don’t need to configure RVM or rbenv from Emacs. Whatever version of Ruby your shell has it will run using that. As a bonus it runs rspec in a comint buffer that means if you are using pry or a debugger you can interact with it from Emacs itself.

(require 'compile)
;; Find root directory by searching for Gemfile
(defun* get-closest-gemfile-root (&optional (file "Gemfile"))
  (let ((root (expand-file-name "/")))
    (loop 
     for d = default-directory then (expand-file-name ".." d)
     if (file-exists-p (expand-file-name file d))
     return d
     if (equal d root)
     return nil)))

(defun rspec-compile-file ()
  (interactive)
  (compile (format "cd %s;bundle exec rspec %s"
                   (get-closest-gemfile-root)
                   (file-relative-name (buffer-file-name) (get-closest-gemfile-root))
                   ) t))

(defun rspec-compile-on-line ()
  (interactive)
  (compile (format "cd %s;bundle exec rspec %s -l %s"
                   (get-closest-gemfile-root)
                   (file-relative-name (buffer-file-name) (get-closest-gemfile-root))
                   (line-number-at-pos)
                   ) t))

(add-hook 'enh-ruby-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c l") 'rspec-compile-on-line)
            (local-set-key (kbd "C-c k") 'rspec-compile-file)
            ))

An astute reader will notice that I am not using default ruby-mode. You can change the hook to ruby-mode-hook if you are using default ruby-mode. So last few lines will become:

(add-hook 'ruby-mode-hook
          (lambda ()
            (local-set-key (kbd "C-c l") 'rspec-compile-on-line)
            (local-set-key (kbd "C-c k") 'rspec-compile-file)
            ))