summaryrefslogtreecommitdiff
path: root/lisp/progmodes/xref.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/xref.el')
-rw-r--r--lisp/progmodes/xref.el46
1 files changed, 31 insertions, 15 deletions
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index b822619f783..b79b12f685f 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -332,19 +332,30 @@ WINDOW controls how the buffer is displayed:
;; The xref buffer is used to display a set of xrefs.
-(defvar-local xref--window-configuration nil)
+(defvar-local xref--display-history nil)
-(defun xref--display-position (pos other-window recenter-arg)
- ;; show the location, but don't hijack focus.
+(defun xref--history-pushnew (value)
+ (unless (equal value (car xref--display-history))
+ (push value xref--display-history)))
+
+(defun xref--display-position (pos other-window recenter-arg xref-buf)
+ ;; Show the location, but don't hijack focus.
(with-selected-window (display-buffer (current-buffer) other-window)
(goto-char pos)
- (recenter recenter-arg)))
+ (recenter recenter-arg)
+ (let ((val (cons (current-buffer) (selected-window)))
+ (rest (window-parameter nil 'quit-restore)))
+ ;; Save the new entry if the window displayed another buffer
+ ;; previously.
+ (when (and rest (not (eq (car rest) 'same)))
+ (with-current-buffer xref-buf
+ (xref--history-pushnew val))))))
(defun xref--show-location (location)
(condition-case err
- (progn
+ (let ((xref-buf (current-buffer)))
(xref--goto-location location)
- (xref--display-position (point) t 1))
+ (xref--display-position (point) t 1 xref-buf))
(user-error (message (error-message-string err)))))
(defun xref-show-location-at-point ()
@@ -352,14 +363,8 @@ WINDOW controls how the buffer is displayed:
(interactive)
(let ((loc (xref--location-at-point)))
(when loc
- (setq xref--window-configuration (current-window-configuration))
(xref--show-location loc))))
-(defun xref--restore-window-configuration ()
- (when xref--window-configuration
- (set-window-configuration xref--window-configuration)
- (setq xref--window-configuration nil)))
-
(defun xref-next-line ()
"Move to the next xref and display its source in the other window."
(interactive)
@@ -388,11 +393,10 @@ WINDOW controls how the buffer is displayed:
(define-derived-mode xref--xref-buffer-mode fundamental-mode "XREF"
"Mode for displaying cross-references."
- (setq buffer-read-only t)
- (add-hook 'pre-command-hook #'xref--restore-window-configuration nil t))
+ (setq buffer-read-only t))
(let ((map xref--xref-buffer-mode-map))
- (define-key map (kbd "q") #'quit-window)
+ (define-key map (kbd "q") #'xref--quit)
(define-key map (kbd "n") #'xref-next-line)
(define-key map (kbd "p") #'xref-prev-line)
(define-key map (kbd "RET") #'xref-goto-xref)
@@ -402,6 +406,18 @@ WINDOW controls how the buffer is displayed:
(define-key map (kbd ".") #'xref-next-line)
(define-key map (kbd ",") #'xref-prev-line))
+(defun xref--quit ()
+ "Quit all windows in `xref--display-history', then quit current window."
+ (interactive)
+ (let ((window (selected-window))
+ (history xref--display-history))
+ (setq xref--display-history nil)
+ (pcase-dolist (`(,buf . ,win) history)
+ (when (and (window-live-p win)
+ (eq buf (window-buffer win)))
+ (quit-window nil win)))
+ (quit-window nil window)))
+
(defconst xref-buffer-name "*xref*"
"The name of the buffer to show xrefs.")