The examples here are for large scale operations. For simple, one-off tweaks, you may prefer the approach documented in the previous section (Case-by-case face specs using the themes’ palette).
The modus-themes-with-colors
macro lets you retrieve multiple color
values by employing the backquote/backtick and comma notation. The
values are stored in the alists modus-themes-operandi-colors
and
modus-themes-vivendi-colors
, while the macro always queries that of the
active Modus theme (preview the current palette with the command
modus-themes-list-colors
).
Visualize the active Modus theme’s palette.
Here is an abstract example that just returns a list of color values
while modus-operandi
is enabled:
(modus-themes-with-colors (list fg-main blue-faint magenta magenta-alt-other cyan-alt-other fg-special-cold blue-alt magenta-faint cyan fg-main green-faint red-alt-faint blue-alt-faint fg-special-warm cyan-alt blue)) ;; => ;; ("#000000" "#002f88" "#721045" "#5317ac" ;; "#005a5f" "#093060" "#2544bb" "#752f50" ;; "#00538b" "#000000" "#104410" "#702f00" ;; "#003f78" "#5d3026" "#30517f" "#0031a9")
Getting a list of colors may have its applications, though what you are
most likely interested in is how to use those variables to configure
several faces at once. To do so we can rely on the built-in
custom-set-faces
function, which sets face specifications for the
special user
theme. That “theme” gets applied on top of regular themes
like modus-operandi
and modus-vivendi
.
This is how it works:
(modus-themes-with-colors (custom-set-faces `(cursor ((,class :background ,blue))) `(mode-line ((,class :background ,yellow-nuanced-bg :foreground ,yellow-nuanced-fg))) `(mode-line-inactive ((,class :background ,blue-nuanced-bg :foreground ,blue-nuanced-fg)))))
The above snippet will immediately refashion the faces it names once it
is evaluated. However, if you switch between the Modus themes, say,
from modus-operandi
to modus-vivendi
, the colors will not get updated to
match those of the new theme. To make things work across the themes, we
need to employ the same technique we discussed in the previous section,
namely, to pass our changes at the post-theme-load phase via a hook.
The themes provide the modus-themes-after-load-theme-hook
, which gets
called from modus-themes-load-operandi
, modus-themes-load-vivendi
, as
well as the command modus-themes-toggle
. With this knowledge, you can
wrap the macro in a function and then assign that function to the hook.
Thus:
(defun my-modus-themes-custom-faces () (modus-themes-with-colors (custom-set-faces `(cursor ((,class :background ,blue))) `(mode-line ((,class :background ,yellow-nuanced-bg :foreground ,yellow-nuanced-fg))) `(mode-line-inactive ((,class :background ,blue-nuanced-bg :foreground ,blue-nuanced-fg)))))) (add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
A theme-agnostic hook for theme loading.
To discover the faces defined by all loaded libraries, you may do
M-x list-faces-display. Be warned that when you :inherit
a face
you are introducing an implicit dependency, so try to avoid doing so for
libraries other than the built-in faces.el (or at least understand
that things may break if you inherit from a yet-to-be-loaded face).
Also bear in mind that these examples are meant to work with the Modus themes. If you are cycling between multiple themes you may encounter unforeseen issues, such as the colors of the Modus themes being applied to a non-Modus item.
Finally, note that you can still use other functions where those make
sense. For example, the modus-themes-color-alts
that was discussed in
the previous section. Adapt the above example like this:
... (modus-themes-with-colors (custom-set-faces `(cursor ((,class :background ,(modus-themes-color-alts 'blue 'green)))) ...))