aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew White <mehw.is.me@inventati.org>2021-08-24 21:16:09 +0000
committerMatthew White <mehw.is.me@inventati.org>2021-10-20 23:23:31 +0200
commit2fea154c45ac2fc17a4cbe1741d6454760d87716 (patch)
tree9320260835a799220b0682234493ef439228923c
parent91419fb5997de269ec74170a5383074c8ee32166 (diff)
persp-remove-buffer: bury buffer walking windows in one way loop
A one way loop, with pre-defined start and end, prevents any infinite ping-pong. This is not just syntactic sugar. In a "while buried buffer found in window" loop, there is the risk that when the buffer is buried in one window, it may be un-buried in another (for "mystic" reasons) and the loop will never end.
-rw-r--r--CHANGELOG.md1
-rw-r--r--perspective.el26
2 files changed, 16 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 20cae94..b69a34d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
+- `persp-remove-buffer`: when burying a buffer, walk windows rather than using a while loop, since the former isn't prone to infinite loops.
- `make-persp`: document that executing BODY saves/restores the `current-buffer`.
- `persp-set-buffer`: follow the coding style of `persp-add-buffer`.
diff --git a/perspective.el b/perspective.el
index 784bab2..559f714 100644
--- a/perspective.el
+++ b/perspective.el
@@ -857,17 +857,21 @@ See also `persp-switch' and `persp-add-buffer'."
((not (persp-buffer-in-other-p buffer))
(kill-buffer buffer))
;; Make the buffer go away if we can see it.
- ((get-buffer-window buffer)
- (let ((window (get-buffer-window buffer)))
- (while window
- ;; `with-selected-window' restores the `current-buffer'.
- ;; If the current buffer is buried, it should not be the
- ;; next current buffer. Remember to fix it later.
- (with-selected-window window (bury-buffer))
- (let ((new-window (get-buffer-window buffer)))
- ;; If `window' is still selected even after being buried, exit
- ;; the loop because otherwise it will go on infinitely.
- (setq window (unless (eq window new-window) new-window))))))
+ ((let (buffer-in-any-window)
+ (walk-windows (lambda (window)
+ (when (eq buffer (window-buffer window))
+ (setq buffer-in-any-window t)
+ ;; Burying the current buffer should also
+ ;; act as an `unrecord-window-buffer'.
+ (with-selected-window window (bury-buffer)))))
+ (let ((window (get-buffer-window buffer)))
+ (when window
+ (error "Buried buffer %s found in window %s, but it shouldn't"
+ buffer window)))
+ ;; `with-selected-window' restores the `current-buffer'.
+ ;; If the current buffer is buried, it should not be the
+ ;; next current buffer. Remember to fix it later.
+ buffer-in-any-window))
(t (bury-buffer buffer)))
;; If the `current-buffer' was buried in `with-selected-window', set
;; the real current buffer, since `with-selected-window' restored it