keeping related buffers together with elscreen

I wrote about switching buffers a couple of times. Switching buffers is one of the things I do a lot when using emacs – switching between e-mail, IRC and some blog entry. Or simply between a couple of source files in a project.

With some of the tricks mentioned, switching buffers can be made pretty easy.

However, what about programs that consist of multiple buffers? For example, my e-mail program (Wanderlust) splits the screen in separate buffers with mail headers, mail folders and the contents of one message. The same for fancy debugging with gdb, or simply when I have split my screen in two (C-x 2) to view two files at the same time. When I then try to switch buffers, only one of the related buffers will be switched – which is usually not what I want.

I'd like to treat a set of related buffers plus their screen layout as a logical unit.

There are different ways to do that in emacs. One obvious way is to use multiple frames (windows). But I prefer to keep everything in one - and I found the that the easiest solution is elscreen.

Installation is simple; download from here, and follow the instructions in the package. I've set up some easy key-bindings in my .emacs:

(load "elscreen" "ElScreen" )

;; F9 creates a new elscreen, shift-F9 kills it
(global-set-key (kbd "<f9>"    ) 'elscreen-create)
(global-set-key (kbd "S-<f9>"  ) 'elscreen-kill)  

;; Windowskey+PgUP/PgDown switches between elscreens
(global-set-key (kbd "<s-prior>") 'elscreen-previous) 
(global-set-key (kbd "<s-next>")  'elscreen-next) 

Now, whenever I want to switch to a new task, say, read e-mail, I press F9, and a new elscreen will appear (it's visible as a sort-of 'tab' at the top of your screen), and start e-mail there. I can then switch to other elscreens, and all of them maintain their buffers and window layout. I have found this very useful. There are some more tricks, and some add-on packages, but this should give you a good start.

There is one small item on my todo-list. Example: when I push M-x wl, emacs automatically switches to the Wanderlust-buffer – or starts it. Now, when using elscreen, I'd like to automatically switch to the correct screen instead of switching the current buffer.


ustunozgur said...

WinnerMode is nice too!


Steven Hansen said...

Sweet, thanks for posting this. What would be really nice is if when you opened a new "tab" elscreen would logically group buffers opened specifically to a tab.

Say I've opened buffers [1, 2, 3, 4, 5] under tab1 and buffers [6, 7, 8, 9, 10] under tab2. I've I'm in tab1 and do run the show all buffers command, it only shows 1-5

Alex said...

Is there any way to configure the frame where the tablist of elscreen is shown? I using ecb and the tabs are shown in the direcotry browser, that is a bit unusefull because it is only very small an it can only show one or two tabs.

Any way to change this? Or any other module that works nicer with ecb?

djcb said...

@ustunozgur: indeed; I have been using that as well.

@Steven Hansen: well, I think elscreen is about remembering how to show a particular buffer. what you are describing is partitioning the buffer list into logical groups. That's interesting, but might not be such a good fit for elscreen.

@Alex: well, you can toggle displaying the tabs or not, by default with C-z T. I don't know about an ecb-specific module.

vinhdizzo said...

After reading some of your blog entries regarding elscreen, i decided to give it a try. However, it doesn't work for me. I'm on a Mac OS X and running Emacs App (v23; compiled with --with-nextstep).

I installed apel into ~/elisp (emu and apel) and copied elscreen.el into the same location. In my .emacs, I put:
(add-to-list 'load-path "~/elisp/apel")
(add-to-list 'load-path "~/elisp/emu")
(load "elscreen" "ElScreen" t)

However, when i start emacs or run the last line, i get:
Wrong type argument: consp, nil

Tried googling and it didn't yield anything useful. Now, are you running elscreen using emacs 23? I actually tried it on my carbon emacs (22) as well, but same error. Any pointers?

djcb said...

@vinhdizzo: hmmmm... i am using emacs 23 (on linux) and it works without this problem.

if you evaluate:
(setq debug-on-error t)

before the load, you should get a bit more information about the exact location of the error.

some people seem to be able to run elscreen on macosx though; http://1stein.org/tag/elscreen/

Good luck!

vinhdizzo said...
This comment has been removed by a blog administrator.
djcb said...

@vinhdizzo: hmmm... you probably should contact the elscreen author, it seems like a bug. For some reason uses the code for emacs <= 21.3.50 it seems.

Anyway, you can try to comment out the offending lines (lines 1266-1274 in my version), maybe that will make it work for you.

Unknown said...

trying to load elscreen v1.46 in the official Windows GNU emacs 23.1 release. elscreen.el complains about two missing files: alist.el and static.el. Which packages am I missing?

djcb said...

@bruno: i think it's 'apel'

vinhdizzo said...

@djcb i was debugging doremi on my emacs as well, and drew adams helped me solve my error.

1. start emacs with emacs -Q (without all the packages)
2. load the new package from your .emacs via eval-region. see if u still get errors.

i did this for elscreen as well and i didnt get any errors. after some investigation, it figured out i had some conflict with my multi-term. i moved my elscreen loading earlier in my .emacs file and everything was good! thanks!

Unknown said...

@djcb: elscreen does indeed depend on "apel". Thanks for the prompt reply, I can now load elscreen.el

Anonymous said...

You might also be interested in mtorus which kind of combines this post and the one titled "jumping back to past locations".


Evolve said...

elscreen is a nice package and thanks for the tip on "apel".

Unfortunately, it seems to mess up the coding system for mail buffers ... I keep getting a coding system mismatch when using this mode and mailing something using gnus.

Anonymous said...

@Steve Hansen

How about http://www.emacswiki.org/emacs/ElscreenSeparateBufferLists ?