Emacs: Automatically Adjust Font Size When Frame Width Changes

| Comments

I get annoyed when I resize Emacs, and the window becomes narrower than 80 columns. I’ve had a solution to this problem floating around my head for years, but I just haven’t run into this situation often enough to implement an automated solution. On those rare occasions, it’s just been easy enough to hit a key to change the font size.

Narrow Emacs frames have become more annoying for me recently, so I figured it was about time to create an elisp function that would set the font size based on the width of my Emacs frame. In my case, this turned out to be quite simple. I’m not a fan of tiling window managers—I’ve tried a few, but they always felt uncomfortable.

Emacs at Two Fonts Sizes

I attacked this problem from the other direction. I use the Sawfish window manager, and I have some handy customizations that divide my monitors into columns. These columns aren’t of equal width. My 1080p laptop has a narrow column on the left and a wide column on the right. The 1440p monitors on my desktop have a wide column in the center with narrow column on either side.

These columns are roughly the same width on my desktop and laptop—the desktop just gets an extra column on each monitor. The narrow columns automatically tile vertically, and they’re just wide enough to fit an 80-column terminal window with a comfortably font size.

I have convenient key bindings to push the focused window into any of these columns on either monitor, but I also have some automation that moves new windows into appropriate places—Firefox in the wide column, Thunderbird in the narrow column on the left, and Pidgin chat windows get stacked in the narrow column on the right.

On my desktop, Emacs goes in the wide column in the center of my second monitor. It is usually flanked by several terminal windows. Emacs and my terminal windows both use the Solarized color theme and Inconsolata for their font, but I prefer Emacs to have a larger font size. This is fine, until I decide to push Emacs into one of the narrow columns. Sometimes I actually have two Emacs frames open at the same time. Other times I’m reviewing proofreading notes that I’ve received from my editor—LibreOffice often requires the wider column for the editing notes to be large enough to read.

(defun pjr-font-scale-on-frame-width ()
  (if (< (frame-width) 76)
      (text-scale-set -1.1)
    (text-scale-set 0))

(add-hook 'window-configuration-change-hook 'pjr-font-scale-on-frame-width)

At my usual font size, the Emacs frame isn’t much more than 60 characters wide in my narrow columns. As I said, this is easy enough to fix manually, but I’m sick of doing things manually. If my office lights can shut off automatically when Steam launches a game, then surely Emacs can change my font size automatically as well!

My use case is quite simple, since I only need to use two different font sizes. I hooked a function into Emacs that runs any time the window configuration is changed. If the frame is less than 76 characters wide, it scales down the font. Under any other circumstances, it sets the font to the default size.