[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 956b13c: xref: Keep track of temporary buffers
From: |
Dmitry Gutov |
Subject: |
[Emacs-diffs] master 956b13c: xref: Keep track of temporary buffers |
Date: |
Wed, 21 Jan 2015 06:44:06 +0000 |
branch: master
commit 956b13c527dc6ac5443ea4d9706faa3a845b8562
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>
xref: Keep track of temporary buffers
Fixes: debbugs:19466
xref: Keep track of temporary buffers.
* lisp/progmodes/xref.el (xref--temporary-buffers, xref--selected)
(xref--inhibit-mark-selected): New variables.
(xref--mark-selected): New function.
(xref--show-location): Maybe add the buffer to
`xref--temporary-buffers', add `xref--mark-selected' to
`buffer-list-update-hook' there.
(xref--window): Add docstring.
(xref-quit): Rename from `xref--quit'. Update both references.
Add KILL argument. When it's non-nil, kill the temporary buffers
that haven't been selected by the user.
(xref--show-xref-buffer): Change the second argument to alist,
extract the values for `xref--window' and
`xref--temporary-buffers' from it. Add `xref--mark-selected' to
`buffer-list-update-hook' to each buffer in the list.
(xref--show-xrefs): Move the logic of calling `xref-find-function'
here. Save the difference between buffer lists before and after
it's called as "temporary buffers", and `pass it to
`xref-show-xrefs-function'.
(xref--find-definitions, xref-find-references)
(xref-find-apropos): Update accordingly.
---
lisp/ChangeLog | 24 +++++++++++
lisp/progmodes/xref.el | 109 +++++++++++++++++++++++++++++++++---------------
2 files changed, 99 insertions(+), 34 deletions(-)
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c843bdd..1c71008 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,27 @@
+2015-01-21 Dmitry Gutov <address@hidden>
+
+ xref: Keep track of temporary buffers (bug#19466).
+ * progmodes/xref.el (xref--temporary-buffers, xref--selected)
+ (xref--inhibit-mark-selected): New variables.
+ (xref--mark-selected): New function.
+ (xref--show-location): Maybe add the buffer to
+ `xref--temporary-buffers', add `xref--mark-selected' to
+ `buffer-list-update-hook' there.
+ (xref--window): Add docstring.
+ (xref-quit): Rename from `xref--quit'. Update both references.
+ Add KILL argument. When it's non-nil, kill the temporary buffers
+ that haven't been selected by the user.
+ (xref--show-xref-buffer): Change the second argument to alist,
+ extract the values for `xref--window' and
+ `xref--temporary-buffers' from it. Add `xref--mark-selected' to
+ `buffer-list-update-hook' to each buffer in the list.
+ (xref--show-xrefs): Move the logic of calling `xref-find-function'
+ here. Save the difference between buffer lists before and after
+ it's called as "temporary buffers", and `pass it to
+ `xref-show-xrefs-function'.
+ (xref--find-definitions, xref-find-references)
+ (xref-find-apropos): Update accordingly.
+
2015-01-20 Artur Malabarba <address@hidden>
* emacs-lisp/package.el (package-dir-info): Fix `while' logic.
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 92144cf..1174a60 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -339,6 +339,20 @@ WINDOW controls how the buffer is displayed:
(defvar-local xref--display-history nil
"List of pairs (BUFFER . WINDOW), for temporarily displayed buffers.")
+(defvar-local xref--temporary-buffers nil
+ "List of buffers created by xref code.")
+
+(defvar-local xref--selected nil
+ "t if the current buffer has ever been selected.
+Used for temporary buffers.")
+
+(defvar xref--inhibit-mark-selected nil)
+
+(defun xref--mark-selected ()
+ (unless xref--inhibit-mark-selected
+ (setq xref--selected t))
+ (remove-hook 'buffer-list-update-hook #'xref--mark-selected t))
+
(defun xref--save-to-history (buf win)
(let ((restore (window-parameter win 'quit-restore)))
;; Save the new entry if the window displayed another buffer
@@ -359,8 +373,16 @@ WINDOW controls how the buffer is displayed:
(defun xref--show-location (location)
(condition-case err
- (let ((xref-buf (current-buffer)))
+ (let ((xref-buf (current-buffer))
+ (bl (buffer-list))
+ (xref--inhibit-mark-selected t))
(xref--goto-location location)
+ (let ((buf (current-buffer)))
+ (unless (memq buf bl)
+ ;; Newly created.
+ (add-hook 'buffer-list-update-hook #'xref--mark-selected nil t)
+ (with-current-buffer xref-buf
+ (push buf xref--temporary-buffers))))
(xref--display-position (point) t 1 xref-buf))
(user-error (message (error-message-string err)))))
@@ -386,7 +408,8 @@ WINDOW controls how the buffer is displayed:
(defun xref--location-at-point ()
(get-text-property (point) 'xref-location))
-(defvar-local xref--window nil)
+(defvar-local xref--window nil
+ "ACTION argument to call `display-buffer' with.")
(defun xref-goto-xref ()
"Jump to the xref on the current line and bury the xref buffer."
@@ -395,7 +418,7 @@ WINDOW controls how the buffer is displayed:
(let ((loc (or (xref--location-at-point)
(user-error "No reference at point")))
(window xref--window))
- (xref--quit)
+ (xref-quit)
(xref--pop-to-location loc window)))
(define-derived-mode xref--xref-buffer-mode fundamental-mode "XREF"
@@ -403,7 +426,7 @@ WINDOW controls how the buffer is displayed:
(setq buffer-read-only t))
(let ((map xref--xref-buffer-mode-map))
- (define-key map (kbd "q") #'xref--quit)
+ (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)
@@ -413,17 +436,31 @@ 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)
+(defun xref-quit (&optional kill)
+ "Perform cleanup, then quit the current window.
+The cleanup consists of burying all temporarily displayed
+buffers, and if KILL is non-nil, of killing all buffers that were
+created in the process of showing xrefs.
+
+Exceptions are made for buffers switched to by the user in the
+meantime, and other window configuration changes. These are
+preserved."
+ (interactive "P")a
(let ((window (selected-window))
(history xref--display-history))
(setq xref--display-history nil)
+ (when kill
+ (let ((xref--inhibit-mark-selected t)
+ kill-buffer-query-functions)
+ (dolist (buf xref--temporary-buffers)
+ (unless (buffer-local-value 'xref--selected buf)
+ (kill-buffer buf)))
+ (setq xref--temporary-buffers 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)))
+ (quit-window kill window)))
(defconst xref-buffer-name "*xref*"
"The name of the buffer to show xrefs.")
@@ -471,7 +508,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(xref-location-group (xref--xref-location x)))
#'equal))
-(defun xref--show-xref-buffer (xrefs window)
+(defun xref--show-xref-buffer (xrefs alist)
(let ((xref-alist (xref--analyze xrefs)))
(with-current-buffer (get-buffer-create xref-buffer-name)
(let ((inhibit-read-only t))
@@ -480,7 +517,11 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(xref--xref-buffer-mode)
(pop-to-buffer (current-buffer))
(goto-char (point-min))
- (setq xref--window window)
+ (setq xref--window (assoc-default 'window alist))
+ (setq xref--temporary-buffers (assoc-default 'temporary-buffers alist))
+ (dolist (buf xref--temporary-buffers)
+ (with-current-buffer buf
+ (add-hook 'buffer-list-update-hook #'xref--mark-selected nil t)))
(current-buffer)))))
@@ -493,16 +534,21 @@ Return an alist of the form ((FILENAME . (XREF ...))
...)."
(defvar xref-show-xrefs-function 'xref--show-xref-buffer
"Function to display a list of xrefs.")
-(defun xref--show-xrefs (id kind xrefs window)
- (cond
- ((null xrefs)
- (user-error "No known %s for: %s" kind id))
- ((not (cdr xrefs))
- (xref-push-marker-stack)
- (xref--pop-to-location (xref--xref-location (car xrefs)) window))
- (t
- (xref-push-marker-stack)
- (funcall xref-show-xrefs-function xrefs window))))
+(defun xref--show-xrefs (input kind arg window)
+ (let* ((bl (buffer-list))
+ (xrefs (funcall xref-find-function kind arg))
+ (tb (cl-set-difference (buffer-list) bl)))
+ (cond
+ ((null xrefs)
+ (user-error "No known %s for: %s" (symbol-name kind) input))
+ ((not (cdr xrefs))
+ (xref-push-marker-stack)
+ (xref--pop-to-location (xref--xref-location (car xrefs)) window))
+ (t
+ (xref-push-marker-stack)
+ (funcall xref-show-xrefs-function xrefs
+ `((window . ,window)
+ (temporary-buffers . ,tb)))))))
(defun xref--read-identifier (prompt)
"Return the identifier at point or read it from the minibuffer."
@@ -517,9 +563,7 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
;;; Commands
(defun xref--find-definitions (id window)
- (xref--show-xrefs id "definitions"
- (funcall xref-find-function 'definitions id)
- window))
+ (xref--show-xrefs id 'definitions id window))
;;;###autoload
(defun xref-find-definitions (identifier)
@@ -546,9 +590,7 @@ prompt for it."
"Find references to the identifier at point.
With prefix argument, prompt for the identifier."
(interactive (list (xref--read-identifier "Find references of: ")))
- (xref--show-xrefs identifier "references"
- (funcall xref-find-function 'references identifier)
- nil))
+ (xref--show-xrefs identifier 'references identifier nil))
;;;###autoload
(defun xref-find-apropos (pattern)
@@ -557,14 +599,13 @@ The argument has the same meaning as in `apropos'."
(interactive (list (read-from-minibuffer
"Search for pattern (word list or regexp): ")))
(require 'apropos)
- (xref--show-xrefs pattern "apropos"
- (funcall xref-find-function 'apropos
- (apropos-parse-pattern
- (if (string-equal (regexp-quote pattern) pattern)
- ;; Split into words
- (or (split-string pattern "[ \t]+" t)
- (user-error "No word list given"))
- pattern)))
+ (xref--show-xrefs pattern 'apropos
+ (apropos-parse-pattern
+ (if (string-equal (regexp-quote pattern) pattern)
+ ;; Split into words
+ (or (split-string pattern "[ \t]+" t)
+ (user-error "No word list given"))
+ pattern))
nil))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 956b13c: xref: Keep track of temporary buffers,
Dmitry Gutov <=