How I Learned to Stop Worrying and Love Ibuffer

Table of Contents

1. Preface

As someone who migrated from more "normal" editors to Emacs, one of the first things that I wanted was a tabbar, which Emacs notably does not ship with. I spent a lot of time configuring tabbar to my liking, but it always felt "wrong" especially when seeing that most Emacsers weren't using tabbar. After almost 2 years of using tabbar, I finally decided to stop using it and try out the native buffer switching paradigm, and I don't miss tabs at all. Hopefully, this post will help explain my journey, so others don't have to be as lost as I did!

2. tabbar.el

Tabs don't work very well from a conceptual standpoint in Emacs, and prevent you from using Emacs to it's full potential. When using Emacs, you will likely have many more buffers than horizontal space on your screen. I currently have 70 Buffers open (and I can have many more on a long-running session), and that simply won't fit. In order to even consider tabbar, some filtering and grouping is required.

My solution to this was to create sorting functions which would:

  1. Create new groups for every projectile project, and one for leftover buffers
  2. Sort the buffers based on their full path, so similar files are automatically placed close to each other.

tabs-files.png

This works, but it has a couple problems. It's a bit slow/buggy (probably because of things I introduced), it dosen't scale well within a project, and it breaks most third party usage of the header line. I also found it was very hard to get to buffers that weren't part of the project I was visiting (as I wasn't relying on *-switch-buffer).

3. Workflows

At least for me, there's a couple of different flows when I switch buffers:

  1. I want to switch quickly between two related buffers
  2. I know the filename of the buffer I want to switch to
  3. I don't know what buffer I need, and I iterate through tabs until I find what I want.
  4. I forgot the name of the file I want, but I will know it when I see it.

3.1. Tabbed

I personally find that switching between two buffers is the most common switch action I do, so that needs to be as quick as possible. I solved this with a sorting algorithm, trying to get related files as close as possible, and using left/right tab to switch between them.

I switched between buffers by name by searching for it's name in the tabbar, then clicking or using tab left/right until I got there.

The iteration flow fits very well in the tabbed workflow, just iterate through the tabs until you find what you want.

Tabs work well in the recognition flow as well, as you can see the files at the top of the window and hold left/right or click on the desired one.

3.2. Emacs Commands

Since switching between two buffers is so important, I bound M-o to other-buffer. I quickly found myself switching to unrelated buffers, so I bound it to projectile-project-buffers-other-buffer, and configured projectile to ignore some classes of buffers, like irc, compilations, or tags. This ends up being much less thinking than left/right, even in the optimal case where they end up right next to each other.

Switching between buffers is much faster with Emacs buffer selection than through tabs. A bonus is that C-x b <RET> will go to the last buffer, (which is a fallback if the buffer I want is not the 'most related buffer' but really the last buffer viewed. I recommend setting up ido, ivy, or helm to make switching more of a breeze if you don't know the exact name.

The last flow is really bad practice. Even in the tabbed workflow it's mostly a waste of time, and removing tabs forced me to stop doing this. I replaced this with project wide searches (in my case counsel-rg) and tag jumps (projectile-find-tag). I'd recommend trying to find any alternative besides blindly cycling through your tabs. If I really need this, I'll use ibuffer.

When I want to get an overview of all the buffers open, I use ibuffer (which I bound to M-i). To limit it to only buffers relevant to the current project, I use projectile-ibuffer. By default, this is sorted by visit time, so you'll see more important buffers at the top. Ibuffer has many advantages over tabs as well, such as batch operations, but I won't go into them for now.

4. Closing Thoughts

After only a couple days on my new workflow, I was cured of my tabbar addiction! Considering how much I relied on tabs before, that shocked me. I found a few other surprising things:

  1. I spent less time cleaning up unused tabs, as they didn't clutter my tabbar anymore. This means the undo tree stuck around, and was very helpful at times. I use midnight.el to cleanup buffers that remain untouched for a couple days.
  2. I didn't realize how much brainpower I was allocating to decide whether to go left/right in my tabbar when switching tabs. After switching, it felt like buffer switching became a lot "lighter".
  3. I found myself relying on the stacking behavior of popup buffers in Emacs a lot more. I feel more comfortable with letting things popup, knowing that they'll come back if I press q a bunch of times. Previously, I would allocate a new window for such popups.
  4. I found it incredibly liberating to C-x b <topic> to go to a certain IRC channel (over having a group for them, and tabbing through). Combined with tracking, it made processing IRC buffers much more efficient than I could have imagined. I use this so much, I bound M-b to switch buffer so it's a bit faster.
  5. I still prefer the tabbed workflow in the browser. I think this is because I almost never know which tab I'd like to switch to in a browser. I suppose I still have more workflow work to do…

If you're in the same situation as me, and have some concerns about keeping tabs, feel free to contact me by opening an issue and I'll add a section about it! :)

ibuffer-demo.gif

5. Navigation

Author: Jay Kamat

Published: 2018-05-07

Emacs 28.2 (Org mode 9.5.5)