Monday, December 17, 2012

Sane font setup with dynamic-fonts

If you share your emacs initialization amongst several computers, and each has their own fonts, then things aren't so straightforward. You have two basic choices. The simplest is to not configure fonts at all, and just set up some appropriate fonts in your custom.el file that is local to your computer. The other is to engage in a complicated guessing game, matching the system type with likely fonts, or perhaps by checking for fonts and then setting.

Fortunately for us, there's a better way! (Cue emacs informercial intro music). dynamic-fonts is a package from the Roland Walker available on an ELPA that fixes this for you.
Using it, you don't have to do much of anything except:

(require 'dynamic-fonts)


Update: This is what is in the documentation, but the documentation is not always correct.  This will not work with emacs started in daemon mode.  A better way is:

(require 'dynamic-fonts)
;; If we started with a frame, just setup the fonts, otherwise wait until
;; we make a frame.
(if initial-window-system
  (add-to-list 'after-make-frame-functions
               (lambda (frame) (dynamic-fonts-setup))))

But even this doesn't seem to work on the Mac.  I don't know why yet.

This sets up both a preferred proportional and monospace font. You should probably set it to the fonts you like in order of preference, although there are reasonable lists already pre-populated.  I'd recommend setting these font preferences in your machine-agnostic customization file ( ~/.emacs.d/init.el for me).

(setq dynamic-fonts-preferred-proportional-fonts
      '("Source Sans Pro" "DejaVu Sans" "Helvetica"))

(setq dynamic-fonts-preferred-monospace-fonts
      '("Source Code Pro" "Inconsolata" "Monaco" "Consolas" "Menlo"
        "DejaVu Sans Mono" "Droid Sans Mono Pro" "Droid Sans Mono"))

This should come before the dynamic-fonts-setup call. These fonts are listed in order of preference. They should contain enough fonts that all systems will have at least one of them.  I don't know whether my list has that property, but I suppose if I ever end up with bad fonts, I can fix the issue in either my computer or my font list.

This package is such a good idea. One of the things I'd like to do with my emacs customization is to similarly extract any good ideas into packages which I put on github. This would force me to write much better solutions than I would have written otherwise, or else remove those solutions entirely in favor of another package.


Anonymous said...

So how do I get away from system fonts and point to /dir/dir/xxx.otf instead please?

Andrew Hyatt said...

On what system? On GNU/Linux I usually put my fonts under ~/.fonts, and it works from there. Basically, find out how to get your OS aware of your fonts, and then emacs should also be aware of them, either immediately or after a restart.