Automatially Balance Your Emacs Windows

July 2023

Emacs windows easily get unbalanced.

After calling split-window-right twice, there are three windows. Rather than being all the same size, two of them take up a quarter of the frame each, and the third is half as big as the frame.

Three windows, of different sizes.

Or, if there are already three equally-sized windows, closing one window leaves one of the remaining windows twice as big as the other.

Two windows, of different sizes.

To me, that's unbalanced.

I want the windows to be the same size. Whether I got to two windows by starting at one and opening another, or starting at three and closing one, those two windows should have the same layout.

Two balanced windows.

So I'd manually balance them. Every time I opened or closed a window, I'd press C-x + to run #'balance-windows. Then, all the windows would be the same size, no matter if I'd just opened or closed one.

Three balanced windows.

Then I realized that no matter how many windows are open, I want them to be the same size. This is manual work! Too much manual work. Why doesn't Emacs do that for me?

I wrote some code. Now it does.

(seq-doseq (fn (list #'split-window #'delete-window))
  (advice-add fn
              #'(lambda (&rest args) (balance-windows))))

This is a straightforward use of Emacs's powerful advice functionality. Every time the window configuration is changed, we call the function balance windows, to keep all the windows equally sized.

And then everything is in balance.


A kind stranger wrote in about the variable window-combination-resize.

If this variable is t, splitting a window tries to get the space proportionally from all windows in the same combination.

I think this is relatively confusing, but it does seem to do what we want. So the fix code is updated to:

(setf window-combination-resize t)

So things are still in balance, but lighter. If confusing.

If you want to hear when I publish more, sign up for my mailing list!


    < An Improved Emacs Search
    tag: emacs


    Announcing caser.el, a package to camelCase, dash-case, and snake_case text >