6

My fonts setup is

(setq default-frame-alist '((font . "DejaVu Sans Mono-10"))) 

(defun my-emoji-fonts ()
  (set-fontset-font t 'symbol "Twemoji")
  (set-fontset-font t 'symbol "Noto Color Emoji" nil 'append)
  (set-fontset-font t 'symbol "Symbola" nil 'append))
(if (daemonp)
    (add-hook 'server-after-make-frame-hook #'my-emoji-fonts)
  (my-emoji-fonts))

With it most emoji display nice and coloured, except those for which DejaVu provides its own glyph, then that overrides the coloured one. How can I avoid that?

enter image description here
U+1F682 and U+2615. They don't let me sleep :/

describe-char reports that the train is displayed with ftcrhb:-GOOG-Twemoji-normal-normal-normal-*-16-*-*-*-m-0-iso10646-1 (#x3C6), while the coffee uses ftcrhb:-PfEd-DejaVu Sans Mono-normal-normal-normal-*-16-*-*-*-m-0-iso10646-1 (#xA6C).


Solution

Turned out to be more complicated than I had thought. First, I had to turn off use-default-font-for-symbols in order to make Emacs honor the fontsets. (I use the first person because I don't feel like saying "do this and that". I got it working by trial and error.) This allows an Emoji font to override the default one when both provide glyphs for the same character:

(setq use-default-font-for-symbols nil)

Now however all greek letters, mathematical symbols and so on had switched to Twemoji or Symbola. I didn't want that, so I what I had to do was

  • restore DejaVu Sans Mono as the main symbols font;
  • make Twemoji override DejaVu for some specified character ranges;
  • finally, make Symbola act like a font of last resort.

The only arrangement of set-fontset-font with which I was able to pull it off is this:

(defun my-emoji-fonts ()
  (set-fontset-font t 'unicode (face-attribute 'default :family))
  (set-fontset-font t '(#x2300 . #x27e7) "Twemoji")
  (set-fontset-font t '(#x2300 . #x27e7) "Noto Color Emoji" nil 'append)
  (set-fontset-font t '(#x27F0 . #x1FAFF) "Twemoji")
  (set-fontset-font t '(#x27F0 . #x1FAFF) "Noto Color Emoji" nil 'append)
  (set-fontset-font t 'unicode "Symbola" nil 'append))

I chose the range from #x2300 to #x1FAFF but had to break it in correspondence of #x27e8 and x27e9 (i.e. ⟨ and ⟩) because I noticed that Symbola was overriding those two specific characters, though they are available in DejaVu Sans Mono. Thanks zzkt and rpluim for helping me out.

2 Answers 2

4

You want to set use-default-font-for-symbols to nil

C-h v use-default-font-for-symbols:

use-default-font-for-symbols is a variable defined in `src/fontset.c'.
Its value is t

  Probably introduced at or before Emacs version 25.2.

Documentation:
If non-nil, use the default face's font for symbols and punctuation.

By default, Emacs will try to use the default face's font for
displaying symbol and punctuation characters, disregarding the
fontsets, if the default font can display the character.
Set this to nil to make Emacs honor the fontsets instead.
1
  • This is the key to unlock the flexibility given by fontsets. See zzkt's answer for how to put it to use. Commented Dec 3, 2020 at 19:01
3

You can define the Unicode ranges used for each font if you want more control over how particular glyphs or blocks are displayed. Rather than setting the default-frame-alist you could try setting a default font, then adding specific ranges after setting it...

Depending on your language environment and coding systems (see also list-character-sets), you can change the default font in a few different ways...

(set-face-font 'default "DejaVu Sans Mono 10")

which can then be modified if required...

(set-face-attribute 'default nil 
                    :family "DejaVu Sans Mono" 
                    :weight 'medium :height 100)

set-fontset-font can be used to override or add extra character sets...

(set-fontset-font "fontset-default"
                  nil  
                  (font-spec :family "DejaVu Sans Mono 10"))

then defining the relevant fonts for specific unicode blocks...

(set-fontset-font t #xFE0F spec-1)                ;; Variation Selector 16
(set-fontset-font t '(#x1F1E6 . #x1F1FF) spec-2)  ;; Regional Indicator Syms
(set-fontset-font t '(#x1F3FB . #x1F3FF) spec-3)  ;; Emoji Modifiers
(set-fontset-font t '(#x1F700 . #x1F77F) spec-4)  ;; Alchemical Symbols

etc...

5
  • Have you tested setting the default font with (set-fontset-font "fontset-default" 'unicode (font-spec :family "DejaVu Sans Mono-10"))? It doesn't work for me. Fedora's default is Inconsolata and it doesn't change. Commented Dec 2, 2020 at 16:00
  • it works for me on Debian and macOS. could be your language environment? anyway I've added a few other ways to set the default...
    – zzkt
    Commented Dec 2, 2020 at 20:56
  • Btw, why do you advise against setting the default font in default-frame-alist? For me it doesn't seem to make any difference how I set it. Commented Dec 3, 2020 at 19:04
  • it might just be superstition (or some unexpected frame hooks) on my part.
    – zzkt
    Commented Dec 4, 2020 at 10:18
  • Haha ok :-) ‎‎‏‏‎ ‎ Commented Dec 4, 2020 at 11:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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