Fist of Senn

a developer's notebook

Emacs Tidbits for Ruby Developers

this is a compilation of little Emacs tips and tricks I use for my daily development. To keep it short I only mention thing related to Ruby.

rvm.el

If you use rvm you should definitly install rvm.el. This is a little package, that I wrote 3 years ago, integrates Emacs with your rvm setup. It configures Emacs to find the right Ruby executables, so that other modes like inf-ruby are set up the way you want it. It reads .rvmrc files and you can switch the current ruby on the fly.

The most important feature though is to open the source of any rubygem in your current gemset. When you call rvm-open-gem you can immedietly jump to any gem and read through the source. This is a huge time saver.

You can find more information about rvm.el in the Emacs Reboot 14 from Avdi Grimm and there is also a blog post on the emacsrookie blog.

Open the spec file for any given class

This is little function requires rspec-mode. It defined a new function to open the spec file for any class in your project. If you only have one window open, it splits your screen and opens the spec file in the other window. It also works the other way around and lets you open the implementation when you got a spec file open.

I’ve bound it to C-c , , but of course you can modify the binding.

1
2
3
4
5
6
7
8
9
10
11
12
13
(defun senny-ruby-open-spec-other-buffer ()
  (interactive)
  (when (featurep 'rspec-mode)
    (let ((source-buffer (current-buffer))
          (other-buffer (progn
                          (rspec-toggle-spec-and-target)
                          (current-buffer))))
      (switch-to-buffer source-buffer)
      (pop-to-buffer other-buffer))))

(eval-after-load 'ruby-mode
  '(progn
     (define-key ruby-mode-map (kbd "C-c , ,") 'senny-ruby-open-spec-other-buffer)))

string interpolation

This function patches your # key to automatically expand to #{} when typed inside a double quoted string.

1
2
3
4
5
6
7
8
9
10
11
12
13
(defun senny-ruby-interpolate ()
  "In a double quoted string, interpolate."
  (interactive)
  (insert "#")
  (when (and
         (looking-back "\".*")
         (looking-at ".*\""))
    (insert "{}")
    (backward-char 1)))

(eval-after-load 'ruby-mode
  '(progn
     (define-key ruby-mode-map (kbd "#") 'senny-ruby-interpolate)))

fixed syntax highlighting for cucumber step definitions

I’m not sure if this one has been fixed in a later release of ruby-mode. With the version of ruby-mode that I use, Emacs gets confused with the regular expressions inside step definition files and your syntax highlighting will be broken for the rest of the buffer. I wrote this patch to get it working as expected:

1
2
3
4
5
6
(eval-after-load 'ruby-mode
  '(progn
     (add-to-list 'ruby-font-lock-syntactic-keywords
                  '("\\(\\(\\)\\(\\)\\|Given\\|When\\|Then\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)"
                    (4 (7 . ?/))
                    (6 (7 . ?/))))))

flymake to check your syntax

I use flymake to instantly see types in my code. This configuration will highlight every syntax error in your current buffer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
(eval-after-load 'ruby-mode
  '(progn
     ;; Libraries
     (require 'flymake)

     ;; Invoke ruby with '-c' to get syntax checking
     (defun flymake-ruby-init ()
       (let* ((temp-file (flymake-init-create-temp-buffer-copy
                          'flymake-create-temp-inplace))
              (local-file (file-relative-name
                           temp-file
                           (file-name-directory buffer-file-name))))
         (list "ruby" (list "-c" local-file))))

     (push '(".+\\.rb$" flymake-ruby-init) flymake-allowed-file-name-masks)
     (push '("Rakefile$" flymake-ruby-init) flymake-allowed-file-name-masks)

     (push '("^\\(.*\\):\\([0-9]+\\): \\(.*\\)$" 1 2 nil 3)
           flymake-err-line-patterns)

     (add-hook 'ruby-mode-hook 'cabbage-flymake-init)

     (add-hook 'ruby-mode-hook
               (lambda ()
                 (when (and buffer-file-name
                            (file-writable-p
                             (file-name-directory buffer-file-name))
                            (file-writable-p buffer-file-name)
                            (if (fboundp 'tramp-list-remote-buffers)
                                (not (subsetp
                                      (list (current-buffer))
                                      (tramp-list-remote-buffers)))
                              t))
                   (local-set-key (kbd "C-c d")
                                  'flymake-display-err-menu-for-current-line)
                   (flymake-mode t))))))

third-party libraries

When I use Emacs for Ruby and Rails development I use the following libraries:

  • rspec-mode (RSpec support)
  • inf-ruby (this is an interactive ruby shell inside Emacs, it is diststributed with ruby-mode)
  • yari (browse RI documentation inside Emacs)
  • cucumber.el (support for *.feature files)

What do you use?

These were a few helpers I use to make Emacs awesome for Ruby development. Have a look at cabbage to see what configuration I use. I’m constantly improving my workflow. If you got awesome Emacs tidbits for Ruby please leave a comment.

Comments