1

After using M-x find-grep I have a list of files with position information in a compile buffer. Now I want to visit the files to check, which can be done with <RET>, calling compile-goto-error to switch/open file into buffer at given position. Emphasize on visit, I want to quickly leave the visited buffer by typing q.

I looked into the source of compile-goto-error and added the view-mode line with progn around the (setq compilation-current-error (point)) clueless as I am like this:

(defun my-compile-goto-error (&optional event)
  "Visit the source for the error message at point.
Use this command in a compilation log buffer."
  (interactive (list last-input-event))
  (if event (posn-set-point (event-end event)))
  (or (compilation-buffer-p (current-buffer))
      (error "Not in a compilation buffer"))
  (compilation--ensure-parse (point))
  (if (get-text-property (point) 'compilation-directory)
      (dired-other-window
       (car (get-text-property (point) 'compilation-directory)))
    (progn
      (setq compilation-current-error (point))
      (unless view-mode (view-mode t)))
    (next-error-internal)))

However, this works only every second time, with or without the line (unless view-mode (view-mode t))

How can I force compile-goto-error to open source-file in view-mode?

tinlyx
  • 1,276
  • 1
  • 12
  • 27
Juha
  • 13
  • 5

1 Answers1

0

You run view-mode before next-error-internal, which is the function that parses the error list, finds the next one, extracts the location information and visits the file. You need to run view-mode after next-error-internal, at the very end of the function.

Additionally, you need to ensure that view-mode runs in the correct buffer. This works out of the box in Emacs 27, but not in Emacs 26, where next-error-internal keeps the compilation output buffer as current. The source code buffer is displayed after compile-goto-error because compilation-goto-locus displays it in a window and selects this window, but that only causes the buffer to become current after the interactive function returns. So either run view-mode from a next-error-hook (but that would make it harder to not run view-mode all the time) or run it with the displayed buffer as current.

Since you don't need to change the way compile-goto-error works at all, just call it. The only thing you need to copy from the code of compile-goto-error is the argument specifications. (You could use the advice mechanism to avoid copying them but for what you're doing here that would be far more complicated.)

(defun compile-view-error (&optional event)
  "Like `compile-goto-error', but visit the file in view mode."
  (interactive (list last-input-event))
  (compile-goto-error event)
  (with-current-buffer (window-buffer)
    (view-mode t)))