Add doom/kill-project-buffers command
Prompts for an open project and kills all its buffers. This is useful for closing `.emacs.d` in an effort to get some *billable* work done. Added `doom-fixup-windows` and `doom-kill-buffer(s)-fixup-windows` helper functions for leaving affected windows on a real buffer or the fallback buffer. Fixed `doom/kill-this-buffer-in-all-windows` to properly "fixup" windows.
This commit is contained in:
parent
e83a6cbaa1
commit
fe6dfb08b6
|
@ -56,17 +56,32 @@ scratch buffer. See `doom-fallback-buffer-name' to change this."
|
|||
(defalias 'doom-buffer-list #'buffer-list)
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-project-buffer-list ()
|
||||
"Return a list of buffers belonging to the current project.
|
||||
(defun doom-project-buffer-list (&optional project)
|
||||
"Return a list of buffers belonging to the specified PROJECT.
|
||||
|
||||
If PROJECT is nil, default to the current project.
|
||||
|
||||
If no project is active, return all buffers."
|
||||
(let ((buffers (doom-buffer-list)))
|
||||
(if-let* ((project-root (doom-project-root)))
|
||||
(if-let* ((project-root
|
||||
(if project (expand-file-name project)
|
||||
(doom-project-root))))
|
||||
(cl-loop for buf in buffers
|
||||
if (projectile-project-buffer-p buf project-root)
|
||||
collect buf)
|
||||
buffers)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-open-projects ()
|
||||
"Return a list of projects with open buffers."
|
||||
(cl-loop with projects = (make-hash-table :test 'equal :size 8)
|
||||
for buffer in (doom-buffer-list)
|
||||
if (buffer-live-p buffer)
|
||||
if (doom-real-buffer-p buffer)
|
||||
if (with-current-buffer buffer (doom-project-root))
|
||||
do (puthash (abbreviate-file-name it) t projects)
|
||||
finally return (hash-table-keys projects)))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-dired-buffer-p (buf)
|
||||
"Returns non-nil if BUF is a dired buffer."
|
||||
|
@ -181,6 +196,36 @@ If DERIVED-P, test with `derived-mode-p', otherwise use `eq'."
|
|||
(delete-window window)))
|
||||
(kill-buffer buffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-fixup-windows (windows)
|
||||
"Ensure that each of WINDOWS is showing a real buffer or the fallback buffer."
|
||||
(dolist (window windows)
|
||||
(with-selected-window window
|
||||
(when (doom-unreal-buffer-p (window-buffer))
|
||||
(previous-buffer)
|
||||
(when (doom-unreal-buffer-p (window-buffer))
|
||||
(switch-to-buffer (doom-fallback-buffer)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-kill-buffer-fixup-windows (buffer)
|
||||
"Kill the BUFFER and ensure all the windows it was displayed in have switched
|
||||
to a real buffer or the fallback buffer."
|
||||
(let ((windows (get-buffer-window-list buffer)))
|
||||
(kill-buffer buffer)
|
||||
(doom-fixup-windows (cl-remove-if-not #'window-live-p windows))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-kill-buffers-fixup-windows (buffers)
|
||||
"Kill the BUFFERS and ensure all the windows they were displayed in have
|
||||
switched to a real buffer or the fallback buffer."
|
||||
(let ((seen-windows (make-hash-table :test 'eq :size 8)))
|
||||
(dolist (buffer buffers)
|
||||
(let ((windows (get-buffer-window-list buffer)))
|
||||
(kill-buffer buffer)
|
||||
(dolist (window (cl-remove-if-not #'window-live-p windows))
|
||||
(puthash window t seen-windows))))
|
||||
(doom-fixup-windows (hash-table-keys seen-windows))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-kill-matching-buffers (pattern &optional buffer-list)
|
||||
"Kill all buffers (in current workspace OR in BUFFER-LIST) that match the
|
||||
|
@ -240,21 +285,16 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
|||
;;;###autoload
|
||||
(defun doom/kill-this-buffer-in-all-windows (buffer &optional dont-save)
|
||||
"Kill BUFFER globally and ensure all windows previously showing this buffer
|
||||
have switched to a real buffer.
|
||||
have switched to a real buffer or the fallback buffer.
|
||||
|
||||
If DONT-SAVE, don't prompt to save modified buffers (discarding their changes)."
|
||||
(interactive
|
||||
(list (current-buffer) current-prefix-arg))
|
||||
(cl-assert (bufferp buffer) t)
|
||||
(let ((windows (get-buffer-window-list buffer nil t)))
|
||||
(when (and (buffer-modified-p buffer) dont-save)
|
||||
(with-current-buffer buffer
|
||||
(set-buffer-modified-p nil)))
|
||||
(kill-buffer buffer)
|
||||
(cl-loop for win in windows
|
||||
if (and (window-live-p win)
|
||||
(doom-unreal-buffer-p (window-buffer win)))
|
||||
do (with-selected-window win (previous-buffer)))))
|
||||
(when (and (buffer-modified-p buffer) dont-save)
|
||||
(with-current-buffer buffer
|
||||
(set-buffer-modified-p nil)))
|
||||
(doom-kill-buffer-fixup-windows buffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-all-buffers (&optional project-p)
|
||||
|
@ -319,3 +359,25 @@ current project."
|
|||
(message "Killed %d buffer(s)"
|
||||
(- (length buffers)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffers)))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/kill-project-buffers (project)
|
||||
"Kill buffers for the specified PROJECT."
|
||||
(interactive
|
||||
(list (if-let* ((open-projects (doom-open-projects)))
|
||||
(completing-read
|
||||
"Kill buffers for project: " open-projects
|
||||
nil t nil nil
|
||||
(if-let* ((project-root (doom-project-root))
|
||||
(project-root (abbreviate-file-name project-root))
|
||||
((member project-root open-projects)))
|
||||
project-root))
|
||||
(message "No projects are open!")
|
||||
nil)))
|
||||
(when project
|
||||
(let ((buffers (doom-project-buffer-list project)))
|
||||
(doom-kill-buffers-fixup-windows buffers)
|
||||
(when (called-interactively-p 'interactive)
|
||||
(message "Killed %d buffer(s)"
|
||||
(- (length buffers)
|
||||
(length (cl-remove-if-not #'buffer-live-p buffers))))))))
|
||||
|
|
Loading…
Reference in New Issue
Block a user