TL;DR: What's a simple way to reliably say: use Consolas as the default font, FreeMono for the characters unsupported by Consolas, and Symbola for characters unsupported by both?

Since my main programming font does not cover all the mathematical symbols I need, I initially set up font fallback as shown below:

(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)

Unfortunately this also changed the font for some of the character that my main font supports, so I changed it to

(set-fontset-font t 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)

If my understanding is correct, this should ensure that characters that Consolas cannot handle are handled by FreeMono, unless FreeMono doesn't have them, in which case they should be displayed using Symbola. It is also my understanding that t does the same as "fontset-default" above.

Unfortunately, there were still cases where the right font wasn't selected; I found that changing to

(set-fontset-font t 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font t 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font t 'unicode (font-spec :name "Symbola") nil 'append)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font "fontset-startup" 'unicode (font-spec :name "Symbola") nil 'append)

worked better, but not always: changing the font size using

(set-face-attribute 'default nil :height some-size)

caused the fallbacks to be ignored, due to new fontsets being created.

My current solution is to do

(set-fontset-font fontset 'unicode (font-spec :name "Consolas") nil)
(set-fontset-font fontset 'unicode (font-spec :name "FreeMono") nil 'append)
(set-fontset-font fontset 'unicode (font-spec :name "Symbola") nil 'append)

on each fontset (fontset-list), after each font size change.

What's the proper way to set font fallback?

Note: for testing purposes, here are a few math characters: ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ⟿⟹⊥⊤⊢
References: Emacs manual on fontsets and on modifying fontsets

  • 2
    I have a thought which not really solves your problem, but –– if you need the mathematical etc. symbols for theoremes and scientific documents, why don't you use TeX and AucTeX for that? It would make hassling with X (or Mac or Windows, depending on what you run) font fallbacks unnecessary and provide you with high quality documents and snippets (eg. for org mode). – user17303 Oct 25 '17 at 5:28
  • afterthought: a UTF-8 font with a full character set should remove your problem entirely (eg. GNU Unifont), and when there's the choice between fancy font and the glyphs required, I'd choose the latter. – user17303 Oct 25 '17 at 13:02
  • 2
    @kuli You are too pessimistic. See github.com/cpitclaudel/monospacifier – Ista Oct 30 '17 at 12:50
  • I cannot remember where I read it, but I believe Eli Zaretskii responded to a similar question somewhere. You are thinking about fontset in the wrong way. Emacs does not actually check for every character it displays whether a font knows how to display it or not. That would be too computationally intensive. So there is no "fallback" mechanism per se. You should set your default font and then modify the default fontset manually in certain ranges to display using different fonts. This procedure is manual or maybe the package unicode can help. – GenaU Jan 8 at 10:57
  • @GenaU I may be misunderstanding, but Emacs does check; just not every font, only the ones that appear in a fontset. – Clément Jan 10 at 20:35

For those who are not able to read Emacs' documentation.

Font Selection

Before Emacs can draw a character on a graphical display, it must select a “font” for that character. Normally, Emacs automatically chooses a font based on the faces assigned to that character—specifically, the face attributes ‘:family’, ‘:weight’, ‘:slant’, and ‘:width’. The choice of font also depends on the character to be displayed; some fonts can only display a limited set of characters. If no available font exactly fits the requirements, Emacs looks for the “closest matching font”. The variables in this section control how Emacs makes this selection.


Specifically tested using characters in the question, checking characters with
describe-character. Each character uses one of the free fonts: Consolas, FreeMono, Symbola. Setting frame font to Consola by set-frame-font.

14 upvotes so far, answer downvoted, and EU science still can't resolve that mistery.

| improve this answer | |
  • Thanks! Did you consider posting this as a response to my comment above, rather that a separate answer? – Clément Jan 17 '19 at 18:55
  • 1
    (I should clarify that I tested too, on Emacs 26, and your answer doesn't seem to work: I used (setq face-font-family-alternatives '(("Consolas" "FreeMono" "Symbola"))), then M-x set-frame-font RET Consolas RET; the characters use a mix of Consolas and Segoe UI Symbol) – Clément Jan 17 '19 at 19:00
  • I tested on Manjaro Arch Linux this sequence: ℕ𝓟⧺×≠≥≤±¬∨∧∃∀λ⟿⟹⊥⊤⊢; I didn't test what happens if some font is not installed. It can be possible. Because font names are entered manually, not from a list of existing ones. – Alexandr Karbivnichiy Jan 17 '19 at 19:51
  • I tested with all the fonts in the list installed, in emacs -Q. – Clément Jan 18 '19 at 17:33
  • @Clément emacs -Q option impiles a lot: --no-x-resources. Maybe the problem lies in it. For me, Consolas start only from this char: "×". And first two "ℕ𝓟" FreeMono and Symbola. – Alexandr Karbivnichiy Jan 18 '19 at 21:08

M-x customize-variable face-font-family-alternatives

There's a list that looks something like:

(("Monospace" "courier" "fixed")
 ("Monospace Serif" "Courier 10 Pitch" "Consolas" "Courier Std" "FreeMono" "courier" "fixed")
 ("courier" "CMU Typewriter Text" "fixed")
 ("Sans Serif" "helv" "helvetica" "arial" "fixed")
 ("helv" "helvetica" "arial" "fixed"))

Add your sequence in customize buffer interface:

("Consolas" "FreeMono" "Symbola")

If a given family is specified but does not exist, this variable specifies alternative font families to try. Each element should have this form:


If FAMILY is specified but not available, Emacs will try the other families given in ALTERNATE-FAMILIES, one by one, until it finds a family that does exist.

How to use face-font-family-alternatives:

In you buffer: M-x set-frame-font

Choose a font from the list. Chosen font will define what font search sequence from face-font-family-alternatives to use. In this example Consolas.

To check what font family was used to display a character: M-x describe-char

| improve this answer | |
  • Thanks! But I don't think this answers the question. AFAICT, the configuration you suggested will use FreeMono if the Consolas font is not available, but it won't fallback to FreeMono for characters not supported by Consolas. – Clément Jan 16 '19 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.