Subject: Re: bug#30646: 27.0.50; Occur next-error and recentering bug

From: Juri Linkov <[email-masked]>
Date: Wed, 28 Feb 2018 23:06:37 +0200

> M-x set-variable RET next-error-recenter RET (4) RET
> M-x occur, use something that gives results (e.g. ';;' in the scratch
> buffer)
> M-g M-n
>
> This signals an error
> next-error: ‘recenter’ing a window that does not display current-buffer.
>
> Stack trace is
>
> Debugger entered--Lisp error: (error "‘recenter’ing a window that does not
> display current-buffer.")
>   recenter((4))
>   next-error(nil)
>   funcall-interactively(next-error nil)
>   call-interactively(next-error nil nil)
>   command-execute(next-error)

I don't know why ‘recenter’ doesn't support a non-selected window, but
moving the ‘recenter’ call outside of ‘with-current-buffer’ seems to do
the right thing.  Incidentally, we are discussing a related issue in
bug#20489, that might bring a better fix than this:

diff --git a/lisp/simple.el b/lisp/simple.el
index b7ad6eb..9b1720c 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -282,20 +282,20 @@ next-error
   (when (setq next-error-last-buffer (next-error-find-buffer))
     ;; we know here that next-error-function is a valid symbol we can funcall
     (with-current-buffer next-error-last-buffer
-      (funcall next-error-function (prefix-numeric-value arg) reset)
-      (when next-error-recenter
-        (recenter next-error-recenter))
-      (run-hooks 'next-error-hook))))
+      (funcall next-error-function (prefix-numeric-value arg) reset))
+    (when next-error-recenter
+      (recenter next-error-recenter))
+    (run-hooks 'next-error-hook)))
 
 (defun next-error-internal ()
   "Visit the source code corresponding to the `next-error' message at point."
   (setq next-error-last-buffer (current-buffer))
   ;; we know here that next-error-function is a valid symbol we can funcall
   (with-current-buffer next-error-last-buffer
-    (funcall next-error-function 0 nil)
-    (when next-error-recenter
-      (recenter next-error-recenter))
-    (run-hooks 'next-error-hook)))
+    (funcall next-error-function 0 nil))
+  (when next-error-recenter
+    (recenter next-error-recenter))
+  (run-hooks 'next-error-hook))
 
 (defalias 'goto-next-locus 'next-error)
 (defalias 'next-match 'next-error)