KillingBuffers

This page is about functions that delete, or “kill” buffers. The standard command to kill a buffer is ‘kill-buffer’. This page goes beyond ‘kill-buffer’.

Note: “killing” a buffer has nothing to do with killing text. After you kill (aka “cut”) text, you can yank (aka “paste”) it back again. After you “kill” a buffer, it is gone forever.

Kill Buffer and Delete Its Windows

Command ‘kill-buffer-and-its-windows’, available in library Lisp:misc-cmds.el, kills the buffer and deletes all of its windows. The default buffer to kill is ‘current-buffer’. The argument to the command may be either a buffer or its name (a string).

This command is especially useful as a replacement for command ‘kill-buffer’ when using Emacs Frames – see OneOnOneEmacs. Used with other frame-oriented functions, it also deletes the frame if the buffer is alone in the frame.

Motivation:

Note: You can use ‘substitute-key-definition’ to replace all key bindings for ‘kill-buffer’ with bindings to ‘kill-buffer-and-its-windows’:

   (substitute-key-definition 'kill-buffer 'kill-buffer-and-its-windows global-map)

Kill Other Buffers

Here is a simple function that kills all buffers, except the current one.

    (defun kill-other-buffers ()
      "Kill all other buffers."
      (interactive)
      (mapc 'kill-buffer (delq (current-buffer) (buffer-list))))

Kill All Dired Buffers

Simple, One-Off Command

Here is a simple, one-off command to kill all dired buffers:

    (defun kill-all-dired-buffers ()
      "Kill all dired buffers."
      (interactive)
      (save-excursion
        (let ((count 0))
          (dolist (buffer (buffer-list))
            (set-buffer buffer)
            (when (equal major-mode 'dired-mode)
              (setq count (1+ count))
              (kill-buffer buffer)))
          (message "Killed %i dired buffer(s)." count))))

(Here is a more efficient ‘kill-dired-buffers which does not require switching to every buffer alive, by making use of ‘buffer-local-value)

    (defun kill-dired-buffers ()
	 (interactive)
	 (mapc (lambda (buffer) 
           (when (eq 'dired-mode (buffer-local-value 'major-mode buffer)) 
             (kill-buffer buffer))) 
         (buffer-list)))

To use this for BSBufferSelection, consider the following keybinding:

    (define-key bs-mode-map (kbd "D D") 'kill-all-dired-buffers)

See also: KillKey

Close and Kill Buffer in a Pane

Many times a temporary window comes up for help or compilation results, auto complete, buffer list, etc. To close that one has to switch to the other window and kill the buffer. After killing the buffer, another buffer gets shown in that window and so we need to close the window to restore the original buffer with full size.

These two functions solve this problem. You can bind your un-used keys to these functions for quick access.

    (defun close-and-kill-this-pane ()
      "If there are multiple windows, then close this pane and kill the buffer in it also."
      (interactive)
      (kill-this-buffer)
      (if (not (one-window-p))
          (delete-window)))
    (defun close-and-kill-next-pane ()
      "If there are multiple windows, then close the other pane and kill the buffer in it also."
      (interactive)
      (other-window 1)
      (kill-this-buffer)
      (if (not (one-window-p))
          (delete-window)))

Using IbufferMode

Killing all Dired buffers is easy with IbufferMode: simply type C-x C-b * / D yes RET.

Using Icicles

Here’s one way to kill Dired buffers using Icicles.

  1. Define a command that kills one (or more) Dired buffers.
  2. Call it. Use Completion or cycling to choose a Dired buffer to kill. Or use `C-!’ to kill them all.

Here’s how to define a command that lets you do that. You need:

  (icicle-define-command
   kill-dired-buffer                      ; Command name
   "Kill one or more Dired buffers"       ; Doc string
   kill-buffer                            ; Function to perform the action
   "Kill Dired buffer: "                  ; Prompt
   (mapcar (lambda (buf) (list (buffer-name buf))) (buffer-list)) ; Completions
   (lambda (bufcons) (save-excursion      ; Predicate: Dired mode?
                       (set-buffer (car bufcons))
                       (equal major-mode 'dired-mode)))
   t)                                     ; Existing buffers only

Moral Of The Story?

How does the Icicles version compare with the other methods described above?

There is a place for specialized user interfaces, and a place for a more common, uniform UI. If IbufferMode (just as an example) is especially well designed to manage buffers, then why not learn its interface and use it? On the other hand, if the same interface can be used for operations of all kinds on all kinds of objects, and if those operations are simple enough to perform, then less learning is needed.

For instance, to give you an idea of how “simple” it is to learn the `* / D’ incantation shown above (in UsingIbufferMode), here are a few of the bindings for IbufferMode (about 1/4 of those listed in the ‘ibuffer-mode’ doc string). These are just the keys for marking buffers. The second part of the incantation, ‘D’, is listed in a separate section, on keys for operating on marked buffers. The KeySequences follow a logical pattern, but there is still a lot to learn.

      'm' - Mark the buffer at point.
      't' - Unmark all currently marked buffers, and mark all unmarked buffers.
      'u' - Unmark the buffer at point.
      'DEL' - Unmark the buffer at point, and move to the previous line.
      '* *' - Unmark all marked buffers.
      '* M' - Mark buffers by major mode.
      '* u' - Mark all "unsaved" buffers.
              This means that the buffer is modified, and has an associated file.
      '* m' - Mark all modified buffers,
              regardless of whether or not they have an associated file.
      '* s' - Mark all buffers whose name begins and
              ends with '*'.
      '* e' - Mark all buffers which have
              an associated file, but that file doesn't currently exist.
      '* r' - Mark all read-only buffers.
      '* /' - Mark buffers in `dired' mode.
      '* h' - Mark buffers in `help-mode', `apropos-mode', etc.
      '.' - Mark buffers older than `ibuffer-old-time'.
      'd' - Mark the buffer at point for deletion.
      '% n' - Mark buffers by their name, using a regexp.
      '% m' - Mark buffers by their major mode, using a regexp.
      '% f' - Mark buffers by their filename, using a regexp.

The aim in pointing this out is not to trash IbufferMode – not at all. It’s just to ponder the notion of simplicity of use.

At some point, of course, there is a trade-off:

The question for the second approach is, “How flexible and general is the mold?” A hammer is a good, general tool – the key is to recognize when a hammer is no longer appropriate for the task at hand. – DrewAdams

Replacement for kill-this-buffer

Here’s a function that you can use instead of kill-this-buffer, but which prevents some buffers to be killed by mistake :

    ;; you can modify that list, to fit your needs
    (setq not-to-kill-buffer-list '("*scratch*" "#emacs" "*Messages*" "irc.freenode.net:6667"))
    (defun kill-buffer-but-not-some ()
      (interactive)
      (if (member (buffer-name (current-buffer)) not-to-kill-buffer-list)
          (bury-buffer)
        (kill-buffer (current-buffer))))

Use IswitchBuffers to kill buffers

When you enter IswitchBuffers, press C-k to kill selected buffer. I always use this method to kill certain buffers. – Anonymous

Protecting buffers

To protect buffers from being killed, see ProtectingBuffers.

Auto clear up your huge buffer list every 2 hours

There is a MidnightMode to clear unused buffers at midnight. I find that I need a more aggressive clear up. Here is what I use to auto kill buffers not active for more than 15 minutes every 2 hours.

;;; midnight mode

(require 'midnight)

;;kill buffers if they were last disabled more than this seconds ago
(setq clean-buffer-list-delay-special 900)

(defvar clean-buffer-list-timer nil
  "Stores clean-buffer-list timer if there is one. You can disable clean-buffer-list by (cancel-timer clean-buffer-list-timer).")

;; run clean-buffer-list every 2 hours
(setq clean-buffer-list-timer (run-at-time t 7200 'clean-buffer-list))

;; kill everything, clean-buffer-list is very intelligent at not killing
;; unsaved buffer.
(setq clean-buffer-list-kill-regexps '("^.*$"))

;; keep these buffer untouched
;; prevent append multiple times
(defvar clean-buffer-list-kill-never-buffer-names-init
  clean-buffer-list-kill-never-buffer-names
  "Init value for clean-buffer-list-kill-never-buffer-names")
(setq clean-buffer-list-kill-never-buffer-names
      (append
       '("*Messages*" "*cmd*" "*scratch*" "*w3m*" "*w3m-cache*" "*Inferior Octave*")
       clean-buffer-list-kill-never-buffer-names-init))

;; prevent append multiple times
(defvar clean-buffer-list-kill-never-regexps-init
  clean-buffer-list-kill-never-regexps
  "Init value for clean-buffer-list-kill-never-regexps")
;; append to *-init instead of itself
(setq clean-buffer-list-kill-never-regexps
      (append '("^\\*EMMS Playlist\\*.*$")
	      clean-buffer-list-kill-never-regexps-init))

Killing Buffers with Anything

Anything is a candidate selection framework.

Start with M-x anything-kill-buffers, narrow the list by typing some patterns(multiple patterns are space-delimited string), select with up/down/pgup/pgdown/C-p/C-n/C-v/M-v, choose with enter, With TAB actions can be selected if the selected buffer has more than one possible action. With C-z kills buffer without quitting anything session.

Killing Buffers of asynchronous processes with dying-mode

Say, you want to kill buffers for asynchronous processes by default 10 minutes after the corresponding process exits. For that purpose you can use dying-mode from dying.el and the code below in your .emacs file.

You can set the default lifetime of the buffer after the process exits with the variable dying-default-lifetime. If you consider the process output to be important to you for a longer time than dying-default-lifetime you can switch off dying-mode within the lifetime of the process buffer or prolong the lifetime of the buffer.

(require 'dying)

(unless (fboundp 'start-process-orig)
  (fset 'start-process-orig (symbol-function 'start-process)))

(fset 'start-process
      (append
       (list 'lambda
	     '(name buffer program &rest program-args)
	     (concat (let ((s (documentation 'start-process))) (substring s 0 (string-match "\n\n.*\\'" s)))
	       "\nAfter finishing the process the process buffer goes into dying-mode."))
       '((let ((ret (apply 'start-process-orig name buffer program program-args)))
	   (if ret
	       (set-process-sentinel ret
				     '(lambda (proc event)
					(when (and (eq (process-status proc) 'exit)
						   (process-buffer proc))
					  (with-current-buffer (process-buffer proc)
					    (dying-mode t)))))) ret))))

(defadvice shell-command-sentinel (after shell-command-sentinel-dying-mode (proc event) activate)
  "The original shell-command-sentinel prevents insertion of a termination message into the process buffer itself.
The advice starts dying-mode after the process exits."
  (when (and (eq (process-status proc) 'exit)
	     (process-buffer proc))
    (with-current-buffer (process-buffer proc)
      (dying-mode t))))

Killing Buffers with PRED

Q: As the save-some-buffers function does, is there any good way to kill some buffers with PRED? IMO, It must be very useful and flexible, because the PRED may check the major-mode, size of buffer, file name, etc.

A: kill-some-buffers together with buffer-list and remove-if or remove-if-not should do the trick. Run it with M-:. Example:

(kill-some-buffers (remove-if-not '(lambda (x) (with-current-buffer x (eq major-mode 'org-mode))) (buffer-list)))

CategoryCommands OneOnOneEmacs CategoryBufferSwitching