Close all buffers besides the current one in Emacs

Viewed 35779

How do I close all but the current buffer in Emacs? Similar to "Close other tabs" feature in modern web browsers?

10 Answers

You can like this one as well - kill all buffers except current one, *Messages* and *scratch* (which are handy to have, I call them "toolkit"), close redundant windows as well, living you which one window which current buffer.

(defun my/kill-all-buffers-except-toolbox ()
  "Kill all buffers except current one and toolkit (*Messages*, *scratch*). Close other windows."
  (interactive)
  (mapc 'kill-buffer (remove-if
                       (lambda (x)
                         (or
                           (eq x (current-buffer))
                           (member (buffer-name x) '("*Messages*" "*scratch*"))))
                       (buffer-list)))
  (delete-other-windows))

I've use crux-kill-other-buffers for some months.

But I want dired buffers get deleted too. @Euge's and @wenjun.yan's answers solve this. But it will delete special buffers (e.g *git-credential-cache--daemon*, *scratch*, helm operation, and etc). So I came up with this (current) solution.

(defun aza-kill-other-buffers ()
  "Kill all buffers but current buffer and special buffers"
  (interactive)
  (dolist (buffer (delq (current-buffer) (buffer-list)))
    (let ((name (buffer-name buffer)))
      (when (and name (not (string-equal name ""))
             (/= (aref name 0) ?\s)
             (string-match "^[^\*]" name))
        (funcall 'kill-buffer buffer)))))

Inspired from kill-matching-buffers. You can add more condition on other buffer-name to exclude, if you want to.

Hope it helps :)

I've used one of the solutions in this list for years, but now I have a new one of my own.

(defun kill-all-file-buffers ()
  "Kills all buffers that are open to files. Does not kill
modified buffers or special buffers."
  (interactive)
  (mapc 'kill-buffer (cl-loop for buffer being the buffers
                              when (and (buffer-file-name buffer)
                                        (not (buffer-modified-p buffer)))
                              unless (eq buffer (current-buffer))
                              collect buffer)))

cl-loop has buffers built in as a collection that you can iterate over. It gives you a chance to parse out anything you don't want to close. Here, I've made sure that it doesn't close anything you've modified, and it uses buffer-file-name instead of just buffer-name so it doesn't kill special buffers. I also added an 'unless' to take out the current buffer (though you could obviously add it to the 'when', I just thought this was clearer).

But for an even more generic solution, we can define this as a macro, and pass in a function that will apply to all these buffers.

(defmacro operate-on-file-buffers (func)
  "Takes any function that takes a single buffer as an argument
and applies that to all open file buffers that haven't been
modified, and aren't the current one."
  `(mapc ,func (cl-loop for buffer being the buffers
                            when (and (buffer-file-name buffer)
                                      (not (buffer-modified-p buffer)))
                            unless (eq buffer (current-buffer))
                            collect buffer)))

Now if you want to kill all buffers that match this, you can call it like this

(operate-on-file-buffers 'kill-buffer)
Related