aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--perspective.el43
-rw-r--r--test/test-perspective.el37
3 files changed, 65 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2720880..b90c9af 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed
- Temporary `switch-to-buffer` displays with non-nil `norecord` no longer add the displayed buffer to the current perspective. This fixes `consult-buffer` preview importing previewed buffers ([#225](https://github.com/nex3/perspective-el/issues/225)).
+- `persp-maybe-kill-buffer`: improve performance by avoiding switching perspectives and rebuilding buffer-name lists ([#226](https://github.com/nex3/perspective-el/issues/226)).
### Added
diff --git a/perspective.el b/perspective.el
index 1145dc0..8bee8d9 100644
--- a/perspective.el
+++ b/perspective.el
@@ -1040,42 +1040,53 @@ See also `persp-remove-buffer'."
(persp-protect
(let* ((buffer (current-buffer))
(bufstr (buffer-name buffer))
- candidates-for-removal candidates-for-keeping)
+ (current-name (persp-current-name))
+ (ignore-rx (persp--make-ignore-buffer-rx))
+ current-persp-removal-needed
+ candidates-for-removal
+ candidates-for-keeping)
;; XXX: For performance reasons, always allow killing off obviously
;; temporary buffers. According to Emacs convention, these buffers' names
;; start with a space.
(when (string-match-p (rx string-start (one-or-more blank)) bufstr)
(cl-return-from persp-maybe-kill-buffer t))
- (dolist (name (persp-names))
- (let ((buffer-names (persp-get-buffer-names name)))
- (when (member bufstr buffer-names)
- (if (cdr buffer-names)
- (push name candidates-for-removal)
- ;; We use a list for debugging purposes, a simple bool
- ;; can suffice for what we are doing here.
- (push name candidates-for-keeping)))))
+ (maphash
+ (lambda (name persp)
+ (let ((buffers (persp-buffers persp)))
+ (when (memq buffer buffers)
+ (if (cl-loop for other-buffer in buffers
+ thereis (and (not (eq other-buffer buffer))
+ (buffer-live-p other-buffer)
+ (not (string-match-p ignore-rx
+ (buffer-name other-buffer)))))
+ (if (equal name current-name)
+ (setq current-persp-removal-needed t)
+ (push name candidates-for-removal))
+ ;; We use a list for debugging purposes, a simple bool
+ ;; can suffice for what we are doing here.
+ (push name candidates-for-keeping)))))
+ (perspectives-hash))
(cond
;; When there aren't perspectives with the buffer as the only
;; buffer, it can be killed safely. Also cleanup killed ones
;; found in perspectives listing the buffer to be killed.
((not candidates-for-keeping)
- ;; Switching to a perspective that isn't the current, should
- ;; automatically cleanup previously killed buffers which are
- ;; still in the perspective's list of buffers. Removing the
- ;; buffer to be killed should also keep the list clean.
(dolist (name candidates-for-removal)
(with-perspective name
- ;; remove the buffer that has to be killed from the list
- (setf (persp-current-buffers) (remq buffer (persp-current-buffers)))))
+ (persp-forget-buffer buffer)))
+ (when current-persp-removal-needed
+ (setf (persp-current-buffers) (remq buffer (persp-current-buffers))))
t)
;; When a perspective have the buffer as the only buffer, the
;; buffer should not be killed, but removed from perspectives
;; that have more than one buffer. Those perspectives should
;; forget about the buffer.
- (candidates-for-removal
+ ((or candidates-for-removal current-persp-removal-needed)
(dolist (name candidates-for-removal)
(with-perspective name
(persp-forget-buffer buffer)))
+ (when current-persp-removal-needed
+ (persp-forget-buffer buffer))
nil)))))
(defun persp-forget-buffer (buffer)
diff --git a/test/test-perspective.el b/test/test-perspective.el
index fbf2917..c4f1331 100644
--- a/test/test-perspective.el
+++ b/test/test-perspective.el
@@ -24,6 +24,7 @@
;; Set feature flag(s):
(customize-set-variable 'persp-feature-flag-prevent-killing-last-buffer-in-perspective t)
+(customize-set-variable 'persp-suppress-no-prefix-key-warning t)
(defun persp-test-interesting-buffer? (buf)
"Return t if BUF is a non-temporary buffer (i.e., lacks
@@ -2130,6 +2131,42 @@ buffers into any perspective."
(should-not (persp-is-current-buffer dummy-buffer))
(should (persp-test-buffer-in-persps dummy-buffer "A")))))
+(ert-deftest basic-persp-maybe-kill-buffer-ignores-unrelated-perspectives ()
+ "Test that unrelated perspectives do not affect `persp-maybe-kill-buffer'."
+ (persp-test-with-persp
+ (persp-test-with-temp-buffers (dummy-buffer other-buffer)
+ (switch-to-buffer dummy-buffer)
+ (should (persp-test-buffer-in-persps dummy-buffer "main"))
+ (persp-switch "A")
+ (switch-to-buffer other-buffer)
+ (should (persp-test-buffer-in-persps other-buffer "A"))
+ (should-not (persp-is-current-buffer dummy-buffer))
+ (persp-switch "main")
+ (should (kill-buffer dummy-buffer))
+ (should-not (buffer-live-p dummy-buffer))
+ (should-not (persp-test-buffer-in-persps dummy-buffer))
+ (should (persp-test-buffer-in-persps other-buffer "A")))))
+
+(ert-deftest basic-persp-maybe-kill-buffer-preserves-last-buffer ()
+ "Test that `persp-maybe-kill-buffer' preserves a perspective's last buffer."
+ (persp-test-with-persp
+ (let ((ido-ignore-buffers '("^\\*scratch\\*")))
+ (persp-test-with-temp-buffers (dummy-buffer helper-buffer)
+ (switch-to-buffer dummy-buffer)
+ (should (persp-test-buffer-in-persps dummy-buffer "main"))
+ (persp-switch "A")
+ (switch-to-buffer dummy-buffer)
+ (should (persp-test-buffer-in-persps dummy-buffer "main" "A"))
+ (persp-switch "main")
+ (switch-to-buffer helper-buffer)
+ (should (persp-test-buffer-in-persps helper-buffer "main"))
+ (switch-to-buffer dummy-buffer)
+ (should-not (kill-buffer dummy-buffer))
+ (should (buffer-live-p dummy-buffer))
+ (should (persp-test-buffer-in-persps dummy-buffer "A"))
+ (should-not (persp-is-current-buffer dummy-buffer))
+ (should (persp-test-buffer-in-persps helper-buffer "main"))))))
+
(ert-deftest basic-persp-switch-to-buffer*-imports-by-default ()
"Test that `persp-switch-to-buffer*' imports other-perspective buffers by default."
(persp-test-with-persp