Commit 2a973ede authored by João Távora's avatar João Távora

Honor window-switching intents in xref-find-definitions (bug#28814)

When there is more than one xref to jump to, and an *xref* window
appears to help the user choose, the original intent to open a
definition in another window or frame is remembered when the choice to
go to or show a reference is finally made.

* lisp/progmodes/xref.el (xref--show-pos-in-buf): Rewrite.
(xref--original-window-intent): New variable.
(xref--original-window): Rename from xref--window and move up
here for clarity.
(xref--show-pos-in-buf): Rewrite.  Don't take SELECT arg here.
(xref--show-location): Handle window selection decision here.
(xref--window): Rename to xref--original-window.
(xref-show-location-at-point): Don't attempt window management here.
(xref--show-xrefs): Ensure display-action intent is saved.
parent 78e9065e
......@@ -448,43 +448,68 @@ If SELECT is non-nil, select the target window."
(when xref-w
(set-window-dedicated-p xref-w xref-w-dedicated)))))
(defun xref--show-pos-in-buf (pos buf select)
(let ((xref-buf (current-buffer))
(defvar-local xref--original-window-intent nil
"Original window-switching intent before xref buffer creation.")
(defvar-local xref--original-window nil
"The original window this xref buffer was created from.")
(defun xref--show-pos-in-buf (pos buf)
"Goto and display position POS of buffer BUF in a window.
Honor `xref--original-window-intent', run `xref-after-jump-hook'
and finally return the window."
(let* ((xref-buf (current-buffer))
(or (eq xref--original-window-intent 'frame)
(cond ((memq
'(window frame))
(window-live-p xref--original-window)
(or (not (window-dedicated-p xref--original-window))
(eq (window-buffer xref--original-window) buf)))
`(,(lambda (buf _alist)
(set-window-buffer xref--original-window buf)
(display-buffer buf))
;; Just before `display-buffer', place ourselves in the
;; original window to suggest preserving it. Of course, if
;; user has deleted the original window, all bets are off,
;; just use the selected one.
(or (and (window-live-p xref--original-window)
(display-buffer buf action))
(xref--goto-char pos)
(run-hooks 'xref-after-jump-hook)
(let ((buf (current-buffer)))
(setq win (selected-window))
(with-current-buffer xref-buf
(setq-local other-window-scroll-buffer buf))))
(when select
(select-window win))))
(setq-local other-window-scroll-buffer buf)))
(defun xref--show-location (location &optional select)
(condition-case err
(let* ((marker (xref-location-marker location))
(buf (marker-buffer marker)))
(xref--show-pos-in-buf marker buf select))
(cond (select
(select-window (xref--show-pos-in-buf marker buf)))
(xref--show-pos-in-buf marker buf))))))
(user-error (message (error-message-string err)))))
(defvar-local xref--window nil
"The original window this xref buffer was created from.")
(defun xref-show-location-at-point ()
"Display the source of xref at point in the appropriate window, if any."
(let* ((xref (xref--item-at-point))
(xref--current-item xref))
(when xref
;; Try to avoid the window the current xref buffer was
;; originally created from.
(if (window-live-p xref--window)
(with-selected-window xref--window
(xref--show-location (xref-item-location xref)))
(xref--show-location (xref-item-location xref))))))
(xref--show-location (xref-item-location xref)))))
(defun xref-next-line ()
"Move to the next xref and display its source in the appropriate window."
......@@ -726,7 +751,8 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(pop-to-buffer (current-buffer))
(goto-char (point-min))
(setq xref--window (assoc-default 'window alist))
(setq xref--original-window (assoc-default 'window alist)
xref--original-window-intent (assoc-default 'display-action alist))
......@@ -753,7 +779,8 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(funcall xref-show-xrefs-function xrefs
`((window . ,(selected-window)))))))
`((window . ,(selected-window))
(display-action . ,display-action))))))
(defun xref--prompt-p (command)
(or (eq xref-prompt-for-identifier t)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment