Subject: bug#76565: 30.1; emacs xref: cannot jump back to the previous position when `xref-history-storage' is set to `xref-window-local-history'

From: Dmitry Gutov <[email-masked]>
Date: Thu, 27 Feb 2025 05:51:47 +0200

Hi!

On 25/02/2025 16:36, Guoyu Ou wrote:
> I installed emacs 30.1 from debian sid, and found that xref cannot jump
> back to the previous position when `xref-history-storage` is set to
> `xref-window-local-history`. It works in emacs 29.4 with xref 1.6.3.
> 
> ### settings and tests
> 
> The following is my `~/.emacs`:
> 
> ```lisp
> (when (>= emacs-major-version 29)
>    (setq xref-history-storage 'xref-window-local-history))
> ```

Thanks for the report. It seems like a regression from fixing bug#65631.

Here's a patch that addresses it.

I'm not 100% convinced it this direction, though, (things are getting 
more complex) so it would be great if it you could try it out and see if 
there are any other scenarios that worked for you before, that still are 
not good with this patch applied.

diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index a318d3393ed..e3f7562aadc 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1521,31 +1521,36 @@ xref--show-xrefs
                     xrefs
                   (setq xrefs 'called-already)))))))
   (let ((cb (current-buffer))
-        (pt (point)))
+        (pt (point))
+        (win (selected-window)))
     (prog1
         (funcall xref-show-xrefs-function fetcher
-                 `((window . ,(selected-window))
+                 `((window . ,win)
                    (display-action . ,display-action)
                    (auto-jump . ,xref-auto-jump-to-first-xref)))
-      (xref--push-markers cb pt))))
+      (xref--push-markers cb pt win))))
 
 (defun xref--show-defs (xrefs display-action)
   (let ((cb (current-buffer))
-        (pt (point)))
+        (pt (point))
+        (win (selected-window)))
     (prog1
         (funcall xref-show-definitions-function xrefs
-                 `((window . ,(selected-window))
+                 `((window . ,win)
                    (display-action . ,display-action)
                    (auto-jump . ,xref-auto-jump-to-first-definition)))
-      (xref--push-markers cb pt))))
+      (xref--push-markers cb pt win))))
 
-(defun xref--push-markers (buf pt)
+(defun xref--push-markers (buf pt win)
   (when (buffer-live-p buf)
-    (save-excursion
-      (with-no-warnings (set-buffer buf))
-      (goto-char pt)
-      (unless (region-active-p) (push-mark nil t))
-      (xref-push-marker-stack))))
+    (save-window-excursion
+      (when (window-live-p win)
+        (select-window win))
+      (save-excursion
+        (with-no-warnings (set-buffer buf))
+        (goto-char pt)
+        (unless (region-active-p) (push-mark nil t))
+        (xref-push-marker-stack)))))
 
 (defun xref--prompt-p (command)
   (or (eq xref-prompt-for-identifier t)