diff options
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | perspective.el | 38 |
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. |
