From 36bfd6947f8671eb279d8aa8f2976ada24361dec Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Mon, 19 Jan 2015 04:19:32 +0200 Subject: [PATCH] Use quit-window to hide buffers temporarily displayed by xref * lisp/progmodes/xref.el (xref--display-history): New variable. (xref--window-configuration): Remove. (xref--save-to-history): New function. (xref--display-position): Use it. Add new argument. (xref--restore-window-configuration): Remove. (xref--show-location, xref-show-location-at-point): Update accordingly. (xref--xref-buffer-mode): Don't use `pre-command-hook'. (xref--quit): New command. (xref-goto-xref): Use it. (xref--xref-buffer-mode-map): Bind `q' to it. --- lisp/ChangeLog | 14 ++++++++++++ lisp/progmodes/xref.el | 50 ++++++++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index d84e83158c2..39d9436b3f1 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,17 @@ +2015-01-19 Dmitry Gutov + + * progmodes/xref.el (xref--display-history): New variable. + (xref--window-configuration): Remove. + (xref--save-to-history): New function. + (xref--display-position): Use it. Add new argument. + (xref--restore-window-configuration): Remove. + (xref--show-location, xref-show-location-at-point): Update + accordingly. + (xref--xref-buffer-mode): Don't use `pre-command-hook'. + (xref--quit): New command. + (xref-goto-xref): Use it. + (xref--xref-buffer-mode-map): Bind `q' to it. + 2015-01-18 Dmitry Gutov * progmodes/xref.el (xref-goto-xref): Perform the jump even inside diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 59da5793295..4431cb5d3b3 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -51,6 +51,7 @@ (require 'cl-lib) (require 'eieio) (require 'ring) +(require 'pcase) (defgroup xref nil "Cross-referencing commands" :group 'tools) @@ -333,19 +334,31 @@ 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 + "List of pairs (BUFFER . WINDOW), for temporarily displayed buffers.") -(defun xref--display-position (pos other-window recenter-arg) - ;; show the location, but don't hijack focus. +(defun xref--save-to-history (buf win) + (let ((restore (window-parameter win 'quit-restore))) + ;; Save the new entry if the window displayed another buffer + ;; previously. + (when (and restore (not (eq (car restore) 'same))) + (push (cons buf win) 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 ((buf (current-buffer)) + (win (selected-window))) + (with-current-buffer xref-buf + (xref--save-to-history buf win))))) (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 () @@ -353,14 +366,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) @@ -385,16 +392,15 @@ WINDOW controls how the buffer is displayed: (let ((loc (or (xref--location-at-point) (error "No reference at point"))) (window xref--window)) - (quit-window) + (xref--quit) (xref--pop-to-location loc window))) (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) @@ -404,6 +410,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.") -- 2.39.5