2009-02-05

switching buffers

In emacs, it's natural to have many buffers open: a couple of buffers you
work on, maybe a buffer with help, maybe some for e-mail, IRC, your
todo-list. Then, some general ones like *scratch*, and some generated ones
like *Completions* and *Messages*.


Note, elsewhere, we discuss managing all those buffer; here it's about
switching between them.

Some other programs use tabs to switch between buffers – and this is
possible with emacs too. However, this gets impractical quickly when you have
a lot of buffers open. And, more importantly, tabs (and menus) work best when
you use a mouse for navigation – but many emacs-users feel mouse usage
impairs their efficiency, and prefer to do their buffers-switching using the
keyboard.



iswitchb

To switch buffers with the keyboard in plain-vanilla emacs, you'd type C-x b
(Ctrl-X and then b). After doing that, the minibuffer (the area under
the modeline (statusbar)) will say something like:

Switch to buffer (default *scratch*):


You then type the beginning of the name of the buffer that you'd like to
switch to, with Tab-completion available. This all works fine, but it may
require some more typing than you'd like. Also, the completions will only be
visible after you push Tab. Because you this all the time, it quickly gets
annoying. To make it work better, there is iswitchb-mode, which you can
activate with M-x iswitchb-mode, or by putting


(iswitchb-mode t)


in your .emacs. With iswitchb-mode (which overtakes C-x b), the
completions are visible in the minibuffer itself, and typing any substring
(not just the beginning) of a buffer name will select it, something like:

iswitch {*Messages*,*scratch*,*Completions*,test.txt,foo.html}

Typing fo will move foo.html to the start of the list; pressing Enter

switches to the buffer at the start of the list. You can also rotate the items
in list with C-s and C-r. iswitchb-mode is such a great improvement that
I wonder why it's not the default.

ido

Some people wanted to use the kind of auto-completion that iswitch-mode
offers elsewhere as well, for example to open (eh, 'visit') a file. For this
reason, a supercharged replacement for iswitchb-mode was developed:
ido. This mode allows for autocompletion for both opening files and
switching buffers.

So, when opening a file (C-x C-f), you get:


Find file: ~/Desktop {test.html | notes.org | Leesmap/ | Documents/ | ...}

As with iswitchb, if you type some characters, your list of matches
('prospects') will shrink to the ones with matching substrings.

You can customize it in many ways; my customizations (.emacs) look something
like this:


;; ido makes competing buffers and finding files easier
;; http://www.emacswiki.org/cgi-bin/wiki/InteractivelyDoThings
(require 'ido) 
(ido-mode 'both) ;; for buffers and files
(setq 
  ido-save-directory-list-file "~/.emacs.d/cache/ido.last"

  ido-ignore-buffers ;; ignore these guys
  '("\\` " "^\*Mess" "^\*Back" ".*Completion" "^\*Ido" "^\*trace"

     "^\*compilation" "^\*GTAGS" "^session\.*" "^\*")
  ido-work-directory-list '("~/" "~/Desktop" "~/Documents" "~src")
  ido-case-fold  t                 ; be case-insensitive

  ido-enable-last-directory-history t ; remember last used dirs
  ido-max-work-directory-list 30   ; should be enough
  ido-max-work-file-list      50   ; remember many
  ido-use-filename-at-point nil    ; don't use filename at point (annoying)
  ido-use-url-at-point nil         ; don't use url at point (annoying)

  ido-enable-flex-matching nil     ; don't try to be too smart
  ido-max-prospects 8              ; don't spam my minibuffer
  ido-confirm-unique-completion t) ; wait for RET, even with unique completion

;; when using ido, the confirmation is rather annoying...
 (setq confirm-nonexistent-file-or-buffer nil)


I won't go through all of these – they are pretty well documented (just move
the cursor to the variables and enter C-h v).


icicles

If even ido is not enough for you, and you want almost magical completion
everywhere in emacs, the icicles-package may be something for you. icicles
is not included in the normal emacs package, so it takes some more time to
set up. Icicles adds autocompletion for just about anything; this is one reason
why many pages in EmacsWiki refer to some way that icicles could make things
better.


I have to admit that icicles scares me a bit. It's infinitely configurable,
but I found it hard to get it to do just what I want – which is basically
'do-as-ido', and then explore the many other features from there on. Still,
I guess I should spend some time to master it.

Of course there are more ways to switch buffers. In an earlier entry, I
already discussed switching buffer with Ctrl-Tab. Another way is to define
some key-bindings for often-used buffers, for example:


(global-set-key (kbd "<f5>")  ;make F5 switch to *scratch*     
  (lambda()(interactive)(switch-to-buffer "*scratch*")))
(global-set-key (kbd "<f6>") ; make F6 switch to .emacs; create if needed

  (lambda()(interactive)(find-file "~/.emacs"))) 

As often in emacs, there are many ways to do something. It may seem a bit
silly to spent so much energy on such a mundane activity as switching
buffers. However, as mentioned, emacs-users are picky about maintaining their
'flow', so all the tweaking might be worth it.

13 comments:

elarson said...

There is also anything.el. I personally though it was too slow because it needs an entire buffer (as opposed to the mini-buffer), but I liked the idea.

Anonymous said...

I've been using swbuff.el for a few years now, and really like it. I have it bound to C-PgUp and C-PgDn.

Anonymous said...

Nitpick: Check spelling of icicles - just so that google can pick up your nice post with relevant keywords.

Thanks!

djcb said...

@Anonymous: thanks, fixed.

Anonymous said...

You probably don't want to quote that final lambda as it won't get compiled. Leave it unquoted or quote with #'

djcb said...

@Anonymous: subtle :) thanks, fixed.

Phil said...

ido-mode actually does everything that iswitchb offers; I'm pretty sure iswitchb is deprecated in favour of ido now.

Anonymous said...

Icicles is probably not as popular as you say. Its many mentions on Emacs Wiki are more often because the author puts them everywhere.

Anonymous said...

What exactly is

ido-work-directory-list

good for?

The documentation just says it's the list of 'actual working directories.' I've noticed no difference when playing around with its value, though.

memnon said...

Just one important note:
If using Ido, and it just keeps completing when you want to stop, press C-f.

Wei Hu said...

The document on ido-everywhere says setting this variable directly does not take effect.

djcb said...

@Wei Hu: indeed; I recently noticed that. Fixed it. Thanks.

Anonymous said...

Hello!

I think there is some mistake in your ido mode configuration. You should activate ido mode *after* you set all the variables. If i activate it before the "ido-max work-directory-list" and "ido-max-work-file-list" won't update from ido.last, therefore history feature gone useless. But if i activate after, all is ok!
Useful key combination: when you're open a file in ido, and it can't be found in the current directory, you should press M-s to merge the history list with the current directory.