How do I close all but the current buffer in Emacs? Similar to "Close other tabs" feature in modern web browsers?
11 Answers
For a more manual approach, you can list all buffers with C-x C-b, mark buffers in the list for deletion with d, and then use x to remove them.
I also recommend replacing list-buffers with the more advanced ibuffer: (global-set-key (kbd "C-x C-b") 'ibuffer)
. The above will work with ibuffer, but you could also do this:
m (mark the buffer you want to keep)
t (toggle marks)
D (kill all marked buffers)
I also use this snippet from the Emacs Wiki, which would further streamline this manual approach:
;; Ensure ibuffer opens with point at the current buffer's entry.
(defadvice ibuffer
(around ibuffer-point-to-most-recent) ()
"Open ibuffer with cursor pointed to most recent buffer name."
(let ((recent-buffer-name (buffer-name)))
ad-do-it
(ibuffer-jump-to-buffer recent-buffer-name)))
(ad-activate 'ibuffer)

- 71,335
- 11
- 153
- 198
-
How can I return from `ibuffer`? @phils – alper May 02 '20 at 01:05
-
1I'm not sure what you're asking, but maybe `q`? Use `C-h m` to learn keybindings, just as with any other mode. – phils May 02 '20 at 12:03
From EmacsWiki: Killing Buffers:
(defun kill-other-buffers ()
"Kill all other buffers."
(interactive)
(mapc 'kill-buffer
(delq (current-buffer)
(remove-if-not 'buffer-file-name (buffer-list)))))
Edit: updated with feedback from Gilles

- 81,433
- 63
- 146
- 187
-
3
-
dired buffers don't set `buffer-file-name` and thus the call to `remove-if-not` in the above example will preserve dired buffers (as well as scratch buffer, term buffers, help buffers, etc, anything not visiting a file). I can't think of an easy test that would close both file buffers and dired buffers, you'd need basically a whole second invocation of mapc with a different test for dired buffers. – robru Jan 16 '15 at 01:42
-
a simple modification to kill also dired buffers `(defun kill-other-buffers () "Kill all other buffers." (interactive) (mapc 'kill-buffer (delq (current-buffer) (remove-if-not '(lambda (x) (or (buffer-file-name x) (eq 'dired-mode (buffer-local-value 'major-mode x)))) (buffer-list)))))` – frinkr Apr 02 '15 at 08:31
-
It looks like in this video the man is able to do that. He opens a new Slime buffer whilst closing the GNU buffers and others. Do you have any idea how he does that? https://www.youtube.com/watch?v=BKFcznZ28BE&t=310s – MadPhysicist Oct 06 '17 at 00:19
-
Replacing `cl-remove-if-not` with `remove-if-not` works but this does not kill `*helm..` buffers – alper May 04 '20 at 14:29
There isn't a way directly in emacs to do this.
You could write a function to do this. The following will close all the buffers:
(defun close-all-buffers () (interactive) (mapc 'kill-buffer (buffer-list)))

- 9,673
- 6
- 31
- 51
-
5
-
1`(delete (current-buffer) (buffer-list))` should give you a buffer list that you can map `kill-buffer` across and avoid killing the current buffer. – NickD Nov 03 '20 at 14:13
-
There is a built in command m-x kill-some-buffers
(I'm using 24.3.50) In my nextstep gui (not tried in a terminal but sure it's similar) you can then approve which buffers to kill.

- 9,489
- 5
- 46
- 56
(defun only-current-buffer ()
(interactive)
(let ((tobe-killed (cdr (buffer-list (current-buffer)))))
(while tobe-killed
(kill-buffer (car tobe-killed))
(setq tobe-killed (cdr tobe-killed)))))
It works as you expected.
And after reading @Starkey's answer, I think this will be better:
(defun only-current-buffer ()
(interactive)
(mapc 'kill-buffer (cdr (buffer-list (current-buffer)))))
(buffer-list (current-buffer)) will return a list that contains all the existing buffers, with the current buffer at the head of the list.
This is my first answer on StackOverflow. Hope it helps :)

- 618
- 9
- 15
-
2And this my friends is how elegant solutions arise from people sharing their ideas – Chris Clark Dec 19 '17 at 19:46
-
I don;t know if the spec for `buffer-list` changed over the years, but `(buffer-list (current-buffer))` to work as the answer above indicates will *NOT* work. Do `C-h f buffer-list RET` for the current spec. – NickD Nov 03 '20 at 14:17
I found this solution to be the simplest one. This deletes every buffer except the current one. You have to add this code to your .emacs
file
(defun kill-other-buffers ()
"Kill all other buffers."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
Of course, then you use it with M-x kill-other-buffers
RET or you paste the following code in the .emacs
file too and then just press C-xC-b
(global-set-key (kbd "C-x C-b") 'kill-other-buffers)

- 699
- 10
- 14
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))

- 327
- 3
- 10
-
1`(string-equal (buffer-name) (buffer-name x))` is the same as `(eq x (current-buffer))`, just less efficient. The remaining `or` can be simplified to `(member (buffer-name x) '("*Messages*" "*scratch*"))` – Stefan Mar 22 '19 at 02:13
-
Now that cl is deprecated (defines `remove-if`), is there an alternative approach? This has been extremely useful... – sgmoye Jan 06 '23 at 13:57
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 :)

- 1,805
- 2
- 20
- 28
-
See [this](https://github.com/azzamsa/emacs.d/blob/master/aza-packages/aza-scripts.el) for my improved solution. – azzamsa Sep 23 '18 at 00:23
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)

- 1,881
- 2
- 12
- 11
(defun px/kill-other-buffers ()
"Kill all other buffers."
(interactive)
(mapc (lambda (buffer)
(when (and (buffer-file-name buffer) (not (eq buffer (current-buffer))))
(kill-buffer buffer)))
(buffer-list)))

- 8,049
- 4
- 57
- 83
This is what you want:
C-x 1
source: https://blasphemousbits.wordpress.com/2007/05/04/learning-emacs-part-4-buffers-windows-and-frames/

- 10,654
- 2
- 52
- 51
-
2I think the reason you got down-voted was that OP is asking to close other *buffers*, not *windows*. Emacs terminology can be a bit confusing. – fengshaun Jan 31 '20 at 07:22