Next: Face coverage, Previous: Advanced customization, Up: Modus themes for GNU Emacs [Index]
This section concerns package developers or advanced users.
The Modus themes can be used as the basis for another theme. The
ef-themes and standard-themes packages (also by Protesilaos), are
two such case. Developers may build on top of Modus to benefit from
the extensive customization of the Modus themes and the fact that they
are part of core Emacs. Note that because the ef-themes and
standard-themes existed before they were redone on top of Modus,
they have to provide lots of compatibility aliases. Whereas a new
theme can be as simple as a single file that only calls
modus-themes-theme. This manual covers everything in detail with
examples that can be copy-pasted directly, both for private use or to
create a new package (Complete example of a Modus derivative theme).
A theme exists in a file whose directory is in the custom-theme-load-path.
The theme file is named ‘NAME-theme.el’. For example, the modus-operandi
theme is in the file ‘modus-operandi-theme.el’. A theme object can be
instantiated with the function modus-themes-theme. This function takes care to
(i) declare the theme, (ii) add to it relevant theme-properties, (iii) register
it in the modus-themes-registered-items, (iv) make it work with all the faces
and customizations documented in this manual, and (v) provide-theme the theme.
Concretely, modus-themes-theme expects the following mandatory arguments:
The name of the new theme as a symbol, like modus-operandi.
The collection this theme is a member of as a symbol,
like modus-themes.
A string describing the theme.
The symbol ‘dark’ or ‘light’, in reference to the theme’s background color.
The symbol of a variable containing a palette with
named colors and semantic mappings, like modus-operandi-palette. A
palette that does not have at least all the entries of a default
Modus palette will eventually not work properly because some face
definition will expect a given color. Though the macro does not
impose any check in this regard.
The symbol of a user-defined extension to the ‘CORE-PALETTE’, commensurate with it, though with arbitrary entries. This can be nil, a fully fledged palette, or a short list of entries. Any colors defined therein are treated the same as the ‘CORE-PALETTE’ and can, in practice, be used to apply distinct styles to the ‘CUSTOM-FACES’ and ‘CUSTOM-VARIABLES’ (more below).
The symbol of a palette that contains overrides for the above two palettes. It is functionally equivalent to the ‘USER-PALETTE’, except it is meant to be customized by the end user. Its value can also be nil.
The symbol of a variable with list of
face definitions like those in modus-themes-faces, to extend or
modify what core Modus defines. If provided, they override whatever
definition is present in modus-themes-faces in case of a conflict.
Derivative themes can thus deviate from the style of core Modus,
wherever necessary.
The symbol of a variable with a list
of custom variables (typically user options) like those defined in
modus-themes-custom-variables. They also override the core Modus
definitions in case of a conflict.
This is an example of a theme that builds on top of modus-operandi,
passing all the mandatory arguments, but not the optional ones:
(modus-themes-theme 'ef-summer 'ef-themes "Legible light warm pink theme with magenta, purple, gold, cyan colors." 'light 'modus-operandi-palette 'ef-summer-palette 'ef-summer-palette-overrides)
Here we notice how ef-summer has modus-operandi-palette as its
‘CORE-PALETTE’. This means that if the ef-summer-palette lacks some
entry, the theme will still work and it will inherit the style of
modus-operandi for that specific element.
The modus-themes-theme macro does not try to be smart about the
arguments it is given. It will thus not make any attempt to test if
the variables are bound, nor will it declare any customization
options. In the above example, the ef-summer-palette-overrides is a
user option that is declared in that theme’s file.
In addition to defining their own colors, themes can provide an
entirely custom list of face definitions and customization options.
This mirrors the style of modus-themes-faces and
modus-themes-custom-variables, as already noted. For example, the
standard-themes have a pseudo-3D style for their active mode line.
They are declared in this way:
(modus-themes-theme 'standard-dark 'standard-themes "Like the unthemed dark Emacs, but more consistent." 'dark 'modus-vivendi-palette 'standard-dark-palette 'standard-dard-palette-overrides 'standard-themes-custom-faces) ; NOTE the additional optional argument
The standard-themes-custom-faces in this example specifies a list of
face definitions like this:
;; Simplified example for illustration purposes (defconst standard-themes-custom-faces '( `(mode-line ((,c :box (:style released-button :color ,border-mode-line-active))))))
Custom faces passed in this way can still define their semantic
palette mappings, as illustrated herein where border-mode-line-active
corresponds to some named color in the palette of the active theme.
Next: Face coverage, Previous: Advanced customization, Up: Modus themes for GNU Emacs [Index]