1

Following an article called Emacs, fonts and fontsets I was revising my font setup. I ended with the following code:

(defun font-exists-p (font)
  "Comprueba si una tipografía existe. Sacado de https://redd.it/1xe7vr"
  (if (member font (font-family-list))
      t
    nil))

(defun font-pt-to-height (pt)
  "Transforma una altura en puntos (pt) a altura de face-attribute."
  ;; el valor es de 1/10pt, por tanto 100 seria equivalente a 10pt, etc.
  (* pt 10))

(defun font-setup (frame)
  ;; tipografia por defecto
  (cond ((font-exists-p "Fira Code")
         (set-face-attribute 'default frame :family "Monospace" :height (font-pt-to-height 13) :font "Fira Code")))
  (cond ((font-exists-p "Apple Color Emoji")
         (set-fontset-font t 'symbol (font-spec :family "Apple Color Emoji") frame 'prepend))
        ((font-exists-p "Symbola")
         (set-fontset-font t 'symbol (font-spec :size 20 :name "Symbola") frame 'prepend))))

(add-hook 'after-make-frame-functions #'font-setup t)
(add-hook 'emacs-startup-hook (lambda () (font-setup nil)))

but for some reason Emacs ran as a daemon keeps the defaults, see this screenshot:

customize-face for 'default showing the font to be DejaVu Sans Mono

If I manually run (font-setup nil) the default face change to what I want which is Fira Code (customize-face confirms to me the change to the default face happened)

I would like for my font setup configuration to be applied on the first frame and all the following frames.

  • 1
    emacs server is sometimes started before other services (i.e. xft-font-server) are up, so please check if your calls to font-exists-p fails. You could do that by inserting some (message ..) calls and later looking at *Messages* buffer. – jue Nov 27 '19 at 7:52
  • @jue I made a small modification to that function and a warning is issued when (font-family-list) returns a "falsy" value and indeed the function is called. Maybe this is a matter of wrapping things inside a with-eval-after-load or something – shackra Nov 27 '19 at 17:38
  • Surely it is possible to fix that from within emacs, but a clean solution would start emacs server after the required OS services are up. This depends on your operating system, you didn't specify your used one. – jue Nov 28 '19 at 15:17
  • From your profile, I suspect that your init system is systemd, so have a look here: stackoverflow.com/questions/21830670/… – jue Nov 28 '19 at 15:21
1

It seems this issue has affected many users over the years, I implemented this workaround:

(defun fc-list ()
  "Genera una lista de tipografías disponibles usando fc-list"
  (if (executable-find "fc-list")
      (split-string (shell-command-to-string "fc-list --format='%{family[0]}\n' | sort | uniq") "\n")
    (progn
      (warn "fc-list command is not available")
      nil)))

and modified my font-exists-p function as following:

(defun font-exists-p (font)
  "Comprueba si una tipografía existe. Código parcialmente sacado de https://redd.it/1xe7vr"
  (let ((font-list (or (font-family-list) (fc-list))))
    (if (member font font-list)
        t
      nil)))

and then glue it all together:

(defun font-setup (&optional frame)
  (cond ((font-exists-p "Fira Code")
         (set-face-attribute 'default frame :height (font-pt-to-height 13) :font "Fira Code")))
  (cond ((font-exists-p "Apple Color Emoji")
         (set-fontset-font t 'symbol (font-spec :family "Apple Color Emoji") frame 'prepend))
        ((font-exists-p "Symbola")
         (set-fontset-font t 'symbol (font-spec :size 20 :name "Symbola") frame 'prepend))))

(defun font-setup-frame (frame)
  "configura la tipografía por cada nuevo marco FRAME creado."
  (select-frame frame)
  (when (display-graphic-p)
    (font-setup frame)))

(if (daemonp)
    (add-hook 'after-make-frame-functions #'font-setup-frame)
  (font-setup))

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.