dealing with many buffers: ibuffer

If you are like me, you'll open a lot of buffers in emacs. There may be a couple of buffers with source code, a few for e-mail. org-mode will open buffers for all your agenda files. Then, maybe an info page, a few ERC-channels, a couple of special emacs buffers such as **Messages** and **scratch**. So, in a moderately busy emacs session there may 30-40 buffers open, and after a day or so there can be many more.

With so many buffers, it can be hard to quickly find the one you are looking for - and clearly a one-tab-per-buffer (like Firefox uses) would not work very well either.

So, what can we do instead? Here, on emacs-fu, we discussed this a couple of
times already:

  • using ido-mode, you can quickly switch to buffers by typing a subset of
    their name
  • using elscreen to step through buffer configurations (this comes close to a
    workable tab-like solution)

These are really useful tools. What's still missing though, is a way to get an overview of all buffers. For that, emacs provide buffer-menu, normally bound to C-x C-b. It lists all your buffers, and you can interact with them in a way similar to dired, e.g. you can switch to a buffer by moving the point (cursor) to the buffer and pressing Return. Or you mark buffers for deletion by pressing d when point is on the buffer, and then press x to kill them all.

Very useful. But if you really have a lot of buffers, just having a long list of them may still be a bit hard to deal with. For that, there is ibuffer, which allows you to put your buffers in different categories -- which can even overlap. Emacs ships ibuffer since version 22, so you'll probably already have it.

Using a setup like the following, you can put your buffers in categories; each buffer is shown only once (apparently, the first match), and you can match on mode (the Emacs-mode of the buffer), name (the buffer name), filename (the full path to the file being visited, if any), and a couple of others (see EmacsWiki).

(require 'ibuffer) 
(setq ibuffer-saved-filter-groups
  (quote (("default"      
            ("Org" ;; all org-related buffers
              (mode . org-mode))  
              (or  ;; mail-related buffers
               (mode . message-mode)
               (mode . mail-mode)
               ;; etc.; all your mail related modes
              (filename . "src/myproject1/"))
              (filename . "src/myproject2/"))
            ("Programming" ;; prog stuff not already in MyProjectX
                (mode . c-mode)
                (mode . perl-mode)
                (mode . python-mode)
                (mode . emacs-lisp-mode)
                ;; etc
            ("ERC"   (mode . erc-mode))))))

(add-hook 'ibuffer-mode-hook
  (lambda ()
    (ibuffer-switch-to-saved-filter-groups "default")))
If you like ibuffer, you can even override the buffer-menu key binding for
(global-set-key (kbd "C-x C-b") 'ibuffer)
As with buffer-menu, you can do various funky things with those buffers, and also filter them further; see the documentation. I am mostly using it for its buffer-navigational qualities, and it's good at that.


l0st3d said...

For really large amounts of buffers, I use eproject (http://github.com/jrockway/eproject) which is a very non-invasive, emacs-ish and useful way to keep track of files in a project. It also plays well with ibuffer mode, and binds C-c C-b to "show me all the buffers in this project in an ibuffer", giving you all the features you mention for just your project. So for when you have 400+ buffers open, it's invaluable ;)

djcb said...

@l0st3d: I have been planning to play around with eproject for a while now; I
should reserve some time for it.

SETH said...

I've been using ibuffer for awhile but had no idea it could do this. Thanks, this is great!

Anonymous said...

Greate blog! I don't know if this is the right place to ask for help, but I'm an Elisp illiterate, and I find buffers like *Completions*, and *Compilation* to be annoying. How can I have Emacs kill them by default once I'm done with them?

I've found a code at the emacs wiki that hides the compilation-window if there were no errors, and this is it (I commented out the stuff that gave smiley's for fail/success):

(defun notify-compilation-result(buffer msg)
"Notify that the compilation is finished,
close the *compilation* buffer if the compilation is successful,
and set the focus back to Emacs frame"
(if (string-match "^finished" msg)
(delete-windows-on buffer)
;(tooltip-show "\n Compilation Successful :-) \n "))
;(tooltip-show "\n Compilation Failed :-( \n "))
(setq current-frame (car (car (cdr (current-frame-configuration)))))
(select-frame-set-input-focus current-frame)
(add-to-list 'compilation-finish-functions

Now, how can I modify this to KILL instead of hide?

djcb said...

@Anonymous: you could use Midnight Mode (http://www.emacswiki.org/emacs/MidnightMode) to clear up unneeded buffers

p4bl0 said...

Thanks, i started using ibuffer today (system and network courses are a great time to hack some elisp).

Here is my config : git diff @ gitorious

marc said...

I have around 250 buffers and I recommend using (setq ido-enable-flex-matching t) and (require 'uniquify). Those two lines make jumpinp from one buffer to another seamless. And I believe it could scale to a lot more buffers without issues.

Steve Purcell said...

Since this was the article that got me interested in ibuffer's grouping features (thanks djcb!), I thought it'd be a good place to mention what I hacked with it: automatic grouping of buffers by parent VC project.


I'm already finding it the most helpful grouping of buffers, since almost all files I edit are under version control. Additionally, the library supports the optional display of vc status in an ibuffer column.

Anonymous said...

Hi..sorry but what theme are you using in the code example in this article?..thanks

djcb said...

@Anomymous: theme is called 'zenburn', I've written about elsewhere in emacs-fu, just search :)