aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--perspective.el38
2 files changed, 39 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d497da..bc3257a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
+- `persp-forget-buffer`: disassociate buffer with perspective without the risk of killing it. This balances `persp-add-buffer`. Newly created buffers via `get-buffer-create` are rogue buffers not found in any perspective, this function allows to get back to that state.
- `persp-maybe-kill-buffer`: designed as `kill-buffer-query-functions` hook to keep a perspective's last left buffer from being killed.
- `persp-get-buffer-names`: get any perspective's list of live buffers.
- `persp-get-buffers`: get any perspective's list of buffers.
diff --git a/perspective.el b/perspective.el
index 28a812b..3c2b5a1 100644
--- a/perspective.el
+++ b/perspective.el
@@ -911,6 +911,44 @@ See also `persp-remove-buffer'."
(persp-remove-buffer buffer)))
nil)))))
+(defun persp-forget-buffer (buffer)
+ "Disassociate BUFFER with the current perspective.
+If BUFFER isn't in any perspective, then it is in limbo.
+
+See also `persp-add-buffer' and `persp-remove-buffer'."
+ (interactive
+ (list (funcall persp-interactive-completion-function "Disassociate buffer with perspective: " (persp-current-buffer-names))))
+ (setq buffer (when buffer (get-buffer buffer)))
+ (cond ((not (buffer-live-p buffer)))
+ ;; Do not disassociate a perspective's last left buffer or one
+ ;; that's not part of the current perspective.
+ ((or (not (persp-is-current-buffer buffer))
+ (and (memq 'persp-maybe-kill-buffer kill-buffer-query-functions)
+ (not (remove (buffer-name buffer) (persp-current-buffer-names)))))
+ (setq buffer nil))
+ ;; Make the buffer go away if we can see it.
+ ((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
+ ;; as the next current buffer after processing its body.
+ (set-buffer (window-buffer))
+ (setf (persp-current-buffers) (remq buffer (persp-current-buffers))))
+
(defun persp-remove-buffer (buffer)
"Disassociate BUFFER with the current perspective.