Subject: bug#20489: 25.0.50; next-error-find-buffer chooses non-current buffer without good reason

From: Juri Linkov <[email-masked]>
Date: Fri, 02 Mar 2018 00:58:10 +0200

> But this requires a feature that is not yet implemented, namely
> a customization like ‘display-buffer-from-alist’ to match the source
> buffer name (that was the current buffer before navigation) instead
> of the target buffer (the buffer to display) like ‘display-buffer-alist’
> currently specifies.

Actually no new feature is needed, ‘display-buffer-alist’ is powerful enough,
and this can be easily implemented with a few lines of code:

1. next-error for *xref* to reuse the same window:

(push '(display-buffer-condition-next-error
        display-buffer-same-window)
      display-buffer-alist)

(defun display-buffer-condition-next-error (_buffer-name _action)
  (memq this-command '(next-error previous-error)))

2. with e.g. two *grep* windows, typing RET to select the right locus window:

(push '(display-buffer-condition-from-next-error-buffer
        display-buffer-in-next-error-last-window
        (inhibit-same-window . t))
      display-buffer-alist)

(defun display-buffer-condition-from-next-error-buffer (_buffer-name _action)
  (string-match-p "\\`\\*\\(compilation\\|grep\\|Occur\\)\\*\\(\\|<[0-9]+>\\)\\'"
		  (buffer-name (current-buffer))))

(defun display-buffer-in-next-error-last-window (buffer alist)
  "Return a window used to display the last next-error buffer."
  (let* ((window (car (delq nil
          (mapcar (lambda (w) (when (and (local-variable-p 'next-error-last-buffer
                                                           (window-buffer w))
                                         (eq (current-buffer)
                                             (buffer-local-value
                                              'next-error-last-buffer
                                              (window-buffer w))))
                                w))
                  (window-list-1 nil 'nomini))))))
    (when (window-live-p window)
      window
      (prog1 (window--display-buffer buffer window 'reuse alist)
        (unless (cdr (assq 'inhibit-switch-frame alist))
          (window--maybe-raise-frame (window-frame window)))))))