Emacs: jump to Ruby source

While I’m talking about Ruby in Emacs, here’s a handy emacs function I wrote way back when. Suppose you’ve just run a test and it’s failed. I’ve highlighted the location of the failing assertion below. If you navigate to that line and type ^h^h, you’ll jump to that line in the other window.

^H^h

^h^h isn’t specific to either tests or shell-mode. It works anywhere there’s a line in Kernel#caller format.

Here’s the code:


(defun ruby-visit-source ()
  "If the current line contains text like '../src/program.rb:34', visit
that file in the other window and position point on that line."
  (interactive)
  (let* ((start-boundary (save-excursion (beginning-of-line) (point)))
         (regexp (concat "([ tnr"'([< {]|^)" ; non file chars or
                                                      ; effective
                                                      ; beginning of file
                         "(.+.rb):([0-9]+)")) ; file.rb:NNN
         (matchp (save-excursion
                  (end-of-line)
                  ;; if two matches on line, the second is most likely
                  ;; to be useful, so search backward.
                  (re-search-backward regexp start-boundary t))))
    (cond (matchp
           (let ((file (buffer-substring (match-beginning 2)
                                         (match-end 2)))
                 (line (buffer-substring (match-beginning 3)
                                         (match-end 3))))
             ; Windows: Find-file doesn't seem to work with Cygwin
             ; /// format or the odd /cygdrive// format
             (if (or (string-match “//(.)(.*)” file)
                     (string-match “/cygdrive/(.)(.*)” file))
                 (setq file
                       (concat (substring file
                                          (match-beginning 1)
                                          (match-end 1))
                               “:”
                               (substring file
                                          (match-beginning 2)
                                          (match-end 2)))))

             (find-file-other-window file)
             (goto-line (string-to-int line))))
          (t
           (error “No ruby location on line.”)))))

;; I bind the above to ^h^h, an odd choice, because that’s easy to
;; type after reaching the line with ^p or ^n.
(global-set-key “^h^h” ‘ruby-visit-source)    

Leave a Reply

You must be logged in to post a comment.