How to best change face settings: `custom-set-faces!` or `set-face-attribute`

I’m currently learning about altering faces in Emacs. I’ve seen code from others on the internet using set-face-attribute. On the other hand, Doom talks about using its custom-set-faces! macro.

I am setting up a function to toggle the size of org headings. Is it best to use custom-set-faces! for this? I’m curious because whenever I run code using it I get another function added on to doom-customize-theme-hook and I wonder about efficiency when doing it many times. Are there any drawbacks to the macro?

Many thanks.

It’s a bit tricky. I normally recommend custom-set-faces! because it’s the easiest option for static user configuration, but the toggle you’re describing isn’t static.

I’d recommend you use set-face-attribute for this; it’s a more low-level interface for adjusting faces. You just have to be aware that you’ll lose your settings if you change your theme. Something like this would work around that:

(defvar my-org-headers
  '((org-level-1 . 1.3)
    (org-level-2 . 1.2)
    (org-level-3 . 1.1)))

(defun my/toggle-org-headers ()
  (interactive)
  (dolist (spec my-org-headers)
    (let ((face (car spec))
          (height (cdr spec)))
      (set-face-attribute
       face nil :height
       (if (equal (face-attribute face :height) height)
           'unspecified
         height)))))

I’m sitting on a refactor of the macro to stop this from happening, but even then, set-face-* is the better choice for this particular problem.

1 Like

Excellent, thank you!

As a side question, I also notice that custom-set-faces! puts code into custom.el inside my private config directory. Removing the face settings from my config.el doesn’t remove them from custom.el and they are still in effect (after restarting emacs). Is this intended?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.