9

I have a buffer with content like:

src/file4.rs:9
src/file4.rs:33
src/file4.rs:64

I'd like to be able to put my cursor on a line and jump to the appropriate file / line in the other window, just like compilation-mode would. However, this buffer contains files/lines that I've generated via other means, it is not the output of a script.

Shepmaster
  • 267
  • 1
  • 6
  • Are those relative paths? – Dan Feb 22 '15 at 21:40
  • @Dan Yes, but I can easily tweak them to be absolute. – Shepmaster Feb 22 '15 at 21:41
  • 2
    See also `next-error-function` and command `next-error`. The idea is that you can define a suitable `next-error-function` value for your buffer/mode, and then take advantage of everything Emacs provides for `next-error`. – Drew Feb 23 '15 at 00:33

2 Answers2

9

You can actually re-use compilation mode without doing much work. Say, for example, you are saving the file you generate into foo.errors.

  1. Add -*- mode: compilation -*- in the first line.
  2. Format your errors, for example, like this: <path to file>: line <line number>: (this is covered by this entry (bash "^\\([^: \n\t]+\\): line \\([0-9]+\\):" 1 2) in the compilation-error-regexp-alist-alist.
  3. When you load up the buffer, the compilation mode will be set automatically, and the lines in the format above will be highlighted. When you press RET on them, the file under point will be opened on the line specified.

You can also set the directory in the local variables but its unnecessary, if the path to the file is absolute or you will always use paths relative to the foo.errors.

wvxvw
  • 11,222
  • 2
  • 30
  • 55
4

Here's a command I whipped up (note that the regexp is not particularly sophisticated). I can't really test it, unfortunately, so you may have to tinker with it.

(defun jump-to-file-and-line ()
  "Reads a line in the form FILENAME:LINE and, assuming a
relative path, opens that file in another window and jumps to the
line."
  (interactive)
  (let ((line (buffer-substring-no-properties (point-at-bol) (point-at-eol))))
    (string-match "\\(.*\\):\\([0-9]+\\)" line)
    (let ((file (match-string 1 line))
          (lnum (match-string 2 line)))
      (when (and file (file-exists-p (concat default-directory file)))
        (find-file-other-window (concat default-directory file))
        (and lnum (goto-line (string-to-number lnum)))))))
Dan
  • 32,584
  • 6
  • 98
  • 168