diff options
| author | João Távora | 2017-10-13 15:13:14 +0100 |
|---|---|---|
| committer | João Távora | 2017-11-03 16:13:35 +0000 |
| commit | 2a973edeacefcabb9fd8024188b7e167f0f9a9b6 (patch) | |
| tree | 2e772d100244902f0dee7d0f8c5c053b29a4937c | |
| parent | 78e9065e9f090ea9c10f89495eab9f8069597b74 (diff) | |
| download | emacs-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.el | 69 |
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. | ||
| 459 | Honor `xref--original-window-intent', run `xref-after-jump-hook' | ||
| 460 | and 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) |