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.

3
  • Are those relative paths?
    – Dan
    Feb 22, 2015 at 21:40
  • @Dan Yes, but I can easily tweak them to be absolute.
    – Shepmaster
    Feb 22, 2015 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, 2015 at 0:33

2 Answers 2

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.

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)))))))
3
  • I also used local-set-key to bind Enter to the function.
    – Shepmaster
    Feb 22, 2015 at 22:04
  • Of course, I really want the full power of being able to jump to the next / previous location and maybe some highlighting, but I'll call that scope creep!
    – Shepmaster
    Feb 22, 2015 at 22:09
  • Really nice, just to mention that forward-line function is preferred to goto-line function.
    – Nsukami _
    Feb 24, 2015 at 22:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.