Subject: Re: bug#32607: 27.0.50; pop-to-buffer in next-error-no-select

From: Stefan Monnier <[email-masked]>
Date: Thu, 13 Sep 2018 21:34:24 -0400

>> Indeed.  I guess for this reason next-error-no-select might want to
>> let-bind display-buffer-overriding-action to something like
>> (nil (inhibit-same-window . t)) during the call to next-error.
>
> Then the same overriding should be applied to both:
>
> diff --git a/lisp/simple.el b/lisp/simple.el
> index ffd7fcc067..17ebcb2e16 100644
> --- a/lisp/simple.el
> +++ b/lisp/simple.el
> @@ -383,9 +383,10 @@ next-error-no-select
>  Finds and highlights the source line like \\[next-error], but does not
>  select the source buffer."
>    (interactive "p")
> -  (let ((next-error-highlight next-error-highlight-no-select))
> +  (let ((next-error-highlight next-error-highlight-no-select)
> +        (display-buffer-overriding-action '(nil (inhibit-same-window . t))))
>      (next-error n))
> -  (let ((display-buffer-overriding-action '(display-buffer-reuse-window)))
> +  (let ((display-buffer-overriding-action '(nil (inhibit-same-window . t))))
>      ;; Override user customization such as display-buffer-same-window
>      ;; and use display-buffer-reuse-window to ensure next-error-last-buffer
>      ;; is displayed somewhere, not necessarily in the same window (bug#32607).
>      (pop-to-buffer next-error-last-buffer)

The first inhibit-same-window should hopefully make the
second unnecessary.  If the first fails to do its job or somehow
indirectly causes the original buffer not to be displayed in the
original window, I'm not really sure what we should do about it.
IOW, for the second part I'm not sure either of
display-buffer-reuse-window or inhibit-same-window is clearly superior
to the other.

Maybe to get closer to "the ideal", we should go for something like:

    (let* ((orig-window (selected-window))
           (orig-buf (window-buffer orig-window)))
      (let ((next-error-highlight next-error-highlight-no-select)
            (display-buffer-overriding-action '(nil (inhibit-same-window . t))))
        (next-error n))
      (cond
       ((eql (window-buffer orig-window) next-error-last-buffer)
        ;; inhibit-same-window did its job, we can just return to the original
        ;; window.
        (select-window orig-window))
       ((eql orig-buf next-error-last-buffer)
        ;; Somehow the original window was affected by `next-error`, so
        ;; we need to work harder to bring the buffer back.
        (select-window orig-window)
        (pop-to-buffer-same-window next-error-last-buffer))
       (t
        ;; Something weird is going on.  We don't really know where we were
        ;; (orig-window was not showing the buffer where we were supposed
        ;; to "stay"), so let's just try and keep both buffers displayed
        ;; while at the same time trying not to gratuitously creating new
        ;; windows either.
        (let ((display-buffer-overriding-action '(display-buffer-reuse-window
                                                  (inhibit-same-window . t))))
          (pop-to-buffer next-error-last-buffer)))))

But maybe we should instead trust inhibit-same-window to do its job and
go for a simple:

      (save-selected-window
        (let ((next-error-highlight next-error-highlight-no-select)
              (display-buffer-overriding-action
               '(nil (inhibit-same-window . t))))
          (next-error n)))

-- Stefan