Center Buffer Text in Emacs

Emacs with text far on the left

Does this image look familiar? I always found Emacs’ tendency to stuck buffer text on the far left of a window annoying, particularly on large screens where it doesn’t just look ugly but also forces you to keep your head twisted to the left to follow the buffer text.

Luckily Visual Fill Column Mode comes to the rescue. The purpose of this mode is to make buffer text wrap on the fill-column even in buffers that don’t use hard wrapping and typically have Visual Line Mode active—hence the name of this mode. By default it inherits Emacs’ left-wing tendency—which I’d absolutely agree, politically, but it just doesn’t make for a nice UI.

However there’s a flag that makes Visual Fill Column Mode center text. My use package configuration looks as follows1:

(use-package visual-fill-column
  :ensure t
  :defer t
  :bind (("C-c t v" . visual-fill-column-mode))
  (dolist (hook '(visual-line-mode-hook
    (add-hook hook #'visual-fill-column-mode))
  :config (setq-default visual-fill-column-center-text t
                        visual-fill-column-fringes-outside-margins nil))

The key is visual-fill-column-center-text which does, well, exactly what the name says and beautifully centers buffer text:

visual-fill-column-fringes-outside-margins in turn moves the fringes to the window borders far from the text. By default the option is on, keeping helpful icons from Flycheck or diff-hl far away from the actual text, but I’d like information close with the actual text.

I use setq-default to change the options as both are buffer-local variables.

As with many things UI-related in Emacs, the implementation is a dirty hack: It extends the window margins to cover the empty area of the buffer. As hacks are hacks there are a couple of issues; for instance text scale adjustments go unnoticed at first: Visual Fill Column has no chance to intercept text-scale-adjust or similar functions to recompute the margins so the alignment will be off after changing the text scale until the next redisplay.

But generally Visual Fill Column Mode works perfect, and is now the default for all buffers in my Emacs, even if they don’t use visual-line-mode.

By the way, Visual Fill is a by-product of Writeroom Mode which is a nice mode for distracting-free writing where the whole UI of the buffer is reduced, even more than Emacs’ normal UI. Take a look at it, too, if you like the idea.

Update (Oct 09, 2016): Mention visual-fill-column-fringes-outside-margins.

  1. In this form :defer t is technically redundant, because :bind generally implies :defer t. I prefer an explicit :defer t however, because I can never remember which forms imply :defer t. Also, a decade of using Python code has really etched the Zen Of Python in my mind— “Explicit is better than implicit”—so I always found the implicit :defer t of use-package to be one of its less brilliant features.