aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2017-10-13 15:13:14 +0100
committerJoão Távora2017-11-03 16:13:35 +0000
commit2a973edeacefcabb9fd8024188b7e167f0f9a9b6 (patch)
tree2e772d100244902f0dee7d0f8c5c053b29a4937c
parent78e9065e9f090ea9c10f89495eab9f8069597b74 (diff)
downloademacs-2a973edeacefcabb9fd8024188b7e167f0f9a9b6.tar.gz
emacs-2a973edeacefcabb9fd8024188b7e167f0f9a9b6.zip
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.
-rw-r--r--lisp/progmodes/xref.el69
1 files changed, 48 insertions, 21 deletions
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 3dbf65ef6f5..ee23bc7a64e 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -448,43 +448,68 @@ If SELECT is non-nil, select the target window."
448 (when xref-w 448 (when xref-w
449 (set-window-dedicated-p xref-w xref-w-dedicated))))) 449 (set-window-dedicated-p xref-w xref-w-dedicated)))))
450 450
451(defun xref--show-pos-in-buf (pos buf select) 451(defvar-local xref--original-window-intent nil
452 (let ((xref-buf (current-buffer)) 452 "Original window-switching intent before xref buffer creation.")
453 win) 453
454(defvar-local xref--original-window nil
455 "The original window this xref buffer was created from.")
456
457(defun xref--show-pos-in-buf (pos buf)
458 "Goto and display position POS of buffer BUF in a window.
459Honor `xref--original-window-intent', run `xref-after-jump-hook'
460and finally return the window."
461 (let* ((xref-buf (current-buffer))
462 (pop-up-frames
463 (or (eq xref--original-window-intent 'frame)
464 pop-up-frames))
465 (action
466 (cond ((memq
467 xref--original-window-intent
468 '(window frame))
469 t)
470 ((and
471 (window-live-p xref--original-window)
472 (or (not (window-dedicated-p xref--original-window))
473 (eq (window-buffer xref--original-window) buf)))
474 `(,(lambda (buf _alist)
475 (set-window-buffer xref--original-window buf)
476 xref--original-window))))))
454 (with-selected-window 477 (with-selected-window
455 (xref--with-dedicated-window 478 (with-selected-window
456 (display-buffer buf)) 479 ;; Just before `display-buffer', place ourselves in the
480 ;; original window to suggest preserving it. Of course, if
481 ;; user has deleted the original window, all bets are off,
482 ;; just use the selected one.
483 (or (and (window-live-p xref--original-window)
484 xref--original-window)
485 (selected-window))
486 (display-buffer buf action))
457 (xref--goto-char pos) 487 (xref--goto-char pos)
458 (run-hooks 'xref-after-jump-hook) 488 (run-hooks 'xref-after-jump-hook)
459 (let ((buf (current-buffer))) 489 (let ((buf (current-buffer)))
460 (setq win (selected-window))
461 (with-current-buffer xref-buf 490 (with-current-buffer xref-buf
462 (setq-local other-window-scroll-buffer buf)))) 491 (setq-local other-window-scroll-buffer buf)))
463 (when select 492 (selected-window))))
464 (select-window win))))
465 493
466(defun xref--show-location (location &optional select) 494(defun xref--show-location (location &optional select)
467 (condition-case err 495 (condition-case err
468 (let* ((marker (xref-location-marker location)) 496 (let* ((marker (xref-location-marker location))
469 (buf (marker-buffer marker))) 497 (buf (marker-buffer marker)))
470 (xref--show-pos-in-buf marker buf select)) 498 (cond (select
499 (select-window (xref--show-pos-in-buf marker buf)))
500 (t
501 (save-selected-window
502 (xref--with-dedicated-window
503 (xref--show-pos-in-buf marker buf))))))
471 (user-error (message (error-message-string err))))) 504 (user-error (message (error-message-string err)))))
472 505
473(defvar-local xref--window nil
474 "The original window this xref buffer was created from.")
475
476(defun xref-show-location-at-point () 506(defun xref-show-location-at-point ()
477 "Display the source of xref at point in the appropriate window, if any." 507 "Display the source of xref at point in the appropriate window, if any."
478 (interactive) 508 (interactive)
479 (let* ((xref (xref--item-at-point)) 509 (let* ((xref (xref--item-at-point))
480 (xref--current-item xref)) 510 (xref--current-item xref))
481 (when xref 511 (when xref
482 ;; Try to avoid the window the current xref buffer was 512 (xref--show-location (xref-item-location xref)))))
483 ;; originally created from.
484 (if (window-live-p xref--window)
485 (with-selected-window xref--window
486 (xref--show-location (xref-item-location xref)))
487 (xref--show-location (xref-item-location xref))))))
488 513
489(defun xref-next-line () 514(defun xref-next-line ()
490 "Move to the next xref and display its source in the appropriate window." 515 "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 ...)) ...)."
726 (xref--xref-buffer-mode) 751 (xref--xref-buffer-mode)
727 (pop-to-buffer (current-buffer)) 752 (pop-to-buffer (current-buffer))
728 (goto-char (point-min)) 753 (goto-char (point-min))
729 (setq xref--window (assoc-default 'window alist)) 754 (setq xref--original-window (assoc-default 'window alist)
755 xref--original-window-intent (assoc-default 'display-action alist))
730 (current-buffer))))) 756 (current-buffer)))))
731 757
732 758
@@ -753,7 +779,8 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
753 (t 779 (t
754 (xref-push-marker-stack) 780 (xref-push-marker-stack)
755 (funcall xref-show-xrefs-function xrefs 781 (funcall xref-show-xrefs-function xrefs
756 `((window . ,(selected-window))))))) 782 `((window . ,(selected-window))
783 (display-action . ,display-action))))))
757 784
758(defun xref--prompt-p (command) 785(defun xref--prompt-p (command)
759 (or (eq xref-prompt-for-identifier t) 786 (or (eq xref-prompt-for-identifier t)