branch: externals/modus-themes
commit c94938ff794d043447ed4ffe9b55f1031039f667
Author: Protesilaos Stavrou <[email protected]>
Commit: Protesilaos Stavrou <[email protected]>
Greatly expand the manual with complete examples of creating Modus
derivatives
This covers the basic and more advanced use cases. It also is for both
private use and making new packages.
---
doc/modus-themes.info | 588 +++++++++++++++++++++++++++++++++++++-------------
doc/modus-themes.org | 278 +++++++++++++++++++++++-
2 files changed, 711 insertions(+), 155 deletions(-)
diff --git a/doc/modus-themes.info b/doc/modus-themes.info
index 35b8c47ab5..c6c7ed4dc2 100644
--- a/doc/modus-themes.info
+++ b/doc/modus-themes.info
@@ -188,9 +188,16 @@ DIY Use a hook at the post-load-theme phase
Build on top of the Modus themes
+* Complete example of a Modus derivative theme::
* Determine what counts as a Modus theme::
* Create convenience commands to load a derivative theme::
+Complete example of a Modus derivative theme
+
+* Complete example of a package that is derived from Modus::
+* Complete example of a private theme derived from Modus::
+* Complete example of a custom theme with its own palette::
+
Face coverage
* Supported packages:: Full list of covered face groups
@@ -4317,11 +4324,17 @@ 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 do so to benefit from the extensive
-customization of the Modus themes and the fact that they are part of
-core Emacs.
-
- A new theme exists in a file whose directory is in the
+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
+(*note 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
@@ -4429,18 +4442,283 @@ corresponds to some named color in the palette of the
active theme.
* Menu:
+* Complete example of a Modus derivative theme::
* Determine what counts as a Modus theme::
* Create convenience commands to load a derivative theme::
-File: modus-themes.info, Node: Determine what counts as a Modus theme, Next:
Create convenience commands to load a derivative theme, Up: Build on top of
the Modus themes
+File: modus-themes.info, Node: Complete example of a Modus derivative theme,
Next: Determine what counts as a Modus theme, Up: Build on top of the Modus
themes
+
+8.1 Complete example of a Modus derivative theme
+================================================
+
+[ For more context: *note Build on top of the Modus themes::. ]
+
+ In this section, we show how to define a new Modus derivative theme.
+In its simplest form, a theme is a file called ‘NAME-theme.el’ in a
+directory that is part of the ‘custom-theme-load-path’. We show how to
+do this for a package and for a private configuration:
+
+ • *note Complete example of a package that is derived from Modus::
+ • *note Complete example of a private theme derived from Modus::
+
+* Menu:
+
+* Complete example of a package that is derived from Modus::
+* Complete example of a private theme derived from Modus::
+* Complete example of a custom theme with its own palette::
+
+
+File: modus-themes.info, Node: Complete example of a package that is derived
from Modus, Next: Complete example of a private theme derived from Modus, Up:
Complete example of a Modus derivative theme
+
+8.1.1 Complete example of a package that is derived from Modus
+--------------------------------------------------------------
+
+For package developers, the following snippet needs to be included in
+each theme file (*note Complete example of a private theme derived from
+Modus::):
+
+ ;;;; Add themes from this package to the `custom-theme-load-path'
+
+ ;;;###autoload
+ (when load-file-name
+ (let ((dir (file-name-directory load-file-name)))
+ (add-to-list 'custom-theme-load-path dir)))
+
+ If the package provides many themes, then the above snippet can be
+included in a shared file that is then loaded via ‘require’ in the
+individual theme files.
+
+ For example, the family of themes that includes ‘prot-light-theme.el’
+and ‘prot-dark-theme.el’ has a shared library which is ‘prot-themes.el’
+and therein we find at least the following:
+
+ ;; Package headers here for prot-themes.el...
+
+ ;; Any other shared definitions...
+
+ ;;;; Add themes from this package to the `custom-theme-load-path'
+
+ ;;;###autoload
+ (when load-file-name
+ (let ((dir (file-name-directory load-file-name)))
+ (add-to-list 'custom-theme-load-path dir)))
+
+ (provide 'prot-themes)
+ ;;; prot-themes.el ends here
+
+ Then each individual theme can look like this (*note Complete example
+of a custom theme with its own palette::):
+
+ (require 'prot-themes)
+
+ (modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ nil
+ nil)
+
+ The contents of such a package will be of this form:
+
+‘prot-themes.el’
+ Common file with all the shared definitions.
+‘prot-light-theme.el’
+ The light theme.
+‘prot-dark-theme.el’
+ The dark theme.
+
+ The shared file can be skipped if the only piece of common code is
+the aforementioned snippet about the ‘custom-theme-load-path’. Simply
+add that snippet to the bottom of each theme file, like this:
+
+ (modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ nil
+ nil)
+
+ ;;;###autoload
+ (when load-file-name
+ (let ((dir (file-name-directory load-file-name)))
+ (add-to-list 'custom-theme-load-path dir)))
+
+ The package is then a collection of ‘NAME-theme.el’ files and nothing
+more.
+
+ In principle, a package derived from Modus does not need to define
+any commands or user options. What is shown in this section is enough.
+Packages such as the ‘ef-themes’ and ‘standard-themes’ are exceptions
+because they existed for years before they were based on Modus and must
+remain backward compatible.
+
+
+File: modus-themes.info, Node: Complete example of a private theme derived
from Modus, Next: Complete example of a custom theme with its own palette,
Prev: Complete example of a package that is derived from Modus, Up: Complete
example of a Modus derivative theme
+
+8.1.2 Complete example of a private theme derived from Modus
+------------------------------------------------------------
+
+If your derivative theme is not going to be distributed as a package
+(*note Complete example of a package that is derived from Modus::), then
+create a directory where all custom themes are stored and add it to the
+‘custom-theme-load-path’. For example, the ‘my-custom-themes’ directory
+can be included thus somewhere in the Emacs initialization file:
+
+ (add-to-list 'custom-theme-load-path (locate-user-emacs-file
"my-custom-themes/"))
+
+ The function ‘locate-user-emacs-file’ takes care to return a path
+relative to where the user's init file is. If, say, we have
+‘~/.emacs.d/init.el’ then we get ‘~/.emacs.d/my-custom-themes/’.
+
+ Create the directory in that path. Then for each derivative Modus
+theme, write a new file of the form ‘NAME-theme.el’. If, for instance,
+your theme is named ‘prot-light’ the file is called
+‘prot-light-theme.el’.
+
+ At minimum, the contents of a theme file are these (*note Complete
+example of a custom theme with its own palette::):
+
+ (modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ nil
+ nil)
+
+
+File: modus-themes.info, Node: Complete example of a custom theme with its
own palette, Prev: Complete example of a private theme derived from Modus,
Up: Complete example of a Modus derivative theme
+
+8.1.3 Complete example of a custom theme with its own palette
+-------------------------------------------------------------
+
+It is a good idea for a derivative theme to use as its core palette one
+of those defined in the ‘modus-themes’, such as
+‘modus-operandi-palette’. This guarantees that all core palette
+definitions are inherited by the derivative theme.
+
+ The derivative may then add its own colors to the user palette, which
+will override the core palette in such of a conflict (*note Preview
+theme colors::).
+
+ The core and user palettes are among the arguments passed to the
+‘modus-themes-theme’ functions, as explained elsewhere in this manual
+(*note Build on top of the Modus themes::).
+
+ In the following example, we are defining the ‘prot-light’ theme in
+the ‘prot-light-theme.el’ file. This theme declares itself as belonging
+to the ‘prot-themes’ family. It is based on the
+‘modus-operandi-palette’ but then defines its own palette, the
+‘prot-light-palette’ with entries that take precedence over whatever
+equivalent is in the ‘modus-operandi-palette’.
+
+ (defvar prot-light-palette
+ '((cursor "#ff0000")
+ (bg-main "#f0e0d0")
+ (fg-main "#202020"))
+ "Like `modus-operandi-palette'.")
+
+ (modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ 'prot-light-palette
+ nil)
+
+ The above is a complete theme which is like ‘modus-operandi’ except
+for those three color definitions specified in the ‘prot-light-palette’.
+There is no limit to how comprehensive the user palette is.
+
+ Depending on the requirements, this theme can make itself further
+customizable by the end user via theme-specific palette overrides. In
+this case, we have the addition of a user option, which we could call
+anything though it makes sense to name it consistently like
+‘prot-light-palette-overrides’.
+
+ (defvar prot-light-palette
+ '((cursor "#ff0000")
+ (bg-main "#f0e0d0")
+ (fg-main "#202020"))
+ "Like `modus-operandi-palette'.")
+
+ (defcustom prot-light-palette-overrides nil
+ "Overrides for the `prot-light' theme."
+ :type '(repeat (list symbol (choice symbol string)))
+ :link '(info-link "(modus-themes) Palette overrides"))
+
+ (modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ 'prot-light-palette
+ 'prot-light-palette-overrides)
+
+ In the above example, we have our ‘prot-light’ theme which is like
+‘modus-operandi’ except three colors and which can now be customized
+further by the user via the ‘prot-light-palette-overrides’ (*note Option
+for palette overrides: Palette overrides.).
+
+ Finally, a derivative theme can specify its own settings for custom
+faces and variables. This is generally not needed, but is provided as
+an option for maximum flexibility. In the following example, the
+‘prot-light’ theme has its own face definitions in addition to all the
+aforementioned:
+
+ (defvar prot-light-palette
+ '((cursor "#ff0000")
+ (bg-main "#f0e0d0")
+ (fg-main "#202020"))
+ "Like `modus-operandi-palette'.")
+
+ (defcustom prot-light-palette-overrides nil
+ "Overrides for the `prot-light' theme."
+ :type '(repeat (list symbol (choice symbol string)))
+ :link '(info-link "(modus-themes) Palette overrides"))
+
+ (defvar prot-light-custom-faces
+ '(
+ `(region ((,c :background ,bg-ochre :foreground ,unspecified :extend
nil)))
+ `(font-lock-keyword-face ((,c :inherit italic :foreground ,keyword))))
+ "Custom faces that deviate from---or complement---those in the Modus
themes.")
+
+ (modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ 'prot-light-palette
+ 'prot-light-palette-overrides
+ 'prot-light-custom-faces)
+
+ The custom faces can name a color from the given theme's palette. In
+this example, ‘bg-ochre’ comes from the ‘modus-operandi-palette’ though
+it would work the same way if, say, ‘prot-light-palette’ defined
+‘bg-soil’ and then referenced it in ‘prot-light-custom-faces’.
+
+
+File: modus-themes.info, Node: Determine what counts as a Modus theme, Next:
Create convenience commands to load a derivative theme, Prev: Complete example
of a Modus derivative theme, Up: Build on top of the Modus themes
-8.1 Determine what counts as a Modus theme
+8.2 Determine what counts as a Modus theme
==========================================
-Once the theme is instantiated, it will be listed in the return value of
-the function ‘modus-themes-get-all-known-themes’. This function accepts
-an optional argument to filter themes by their given family, as
+[ NOTE: Users of many Modus derivatives do not need to do anything of
+what is described herein. Just enable the
+‘modus-themes-include-derivatives-mode’. ]
+
+ Once the theme is instantiated, it will be listed in the return value
+of the function ‘modus-themes-get-all-known-themes’. This function
+accepts an optional argument to filter themes by their given family, as
specified at the time of the theme's reification (*note Build on top of
the Modus themes::).
@@ -4501,10 +4779,14 @@ on.
File: modus-themes.info, Node: Create convenience commands to load a
derivative theme, Prev: Determine what counts as a Modus theme, Up: Build on
top of the Modus themes
-8.2 Create convenience commands to load a derivative theme
+8.3 Create convenience commands to load a derivative theme
==========================================================
-In the previous section, we explored the mechanics of the
+[ NOTE: Users of many Modus derivatives do not need to do anything of
+what is described herein. Just enable the
+‘modus-themes-include-derivatives-mode’. ]
+
+ In the previous section, we explored the mechanics of the
‘modus-themes-get-themes’ (*note Determine what counts as a Modus
theme::). Independent of that method, developers can use the macro
‘modus-themes-define-derivative-command’ to define small wrappers for
@@ -6701,17 +6983,17 @@ B.1 Function index
* modus-themes-contrast: DIY Measure color contrast.
(line 6)
* modus-themes-define-derivative-command: Create convenience commands to load
a derivative theme.
- (line 6)
+ (line 10)
* modus-themes-get-all-known-themes: Determine what counts as a Modus
theme.
- (line 6)
+ (line 10)
* modus-themes-get-color-value: Get a single color from the palette
with modus-themes-get-color-value.
(line 6)
* modus-themes-get-themes: Option for which themes to rotate.
(line 17)
* modus-themes-get-themes <1>: Determine what counts as a Modus
theme.
- (line 12)
+ (line 16)
* modus-themes-include-derivatives-mode: Determine what counts as a Modus
theme.
- (line 43)
+ (line 47)
* modus-themes-list-colors: Preview theme colors. (line 6)
* modus-themes-list-colors-current: Preview theme colors. (line 11)
* modus-themes-load-random: Enable and load. (line 94)
@@ -6742,7 +7024,7 @@ B.1 Function index
* modus-themes-select <1>: Enable and load. (line 94)
* modus-themes-select <2>: Disable other themes. (line 15)
* modus-themes-theme: Build on top of the Modus themes.
- (line 14)
+ (line 20)
* modus-themes-toggle: Enable and load. (line 94)
* modus-themes-toggle <1>: Disable other themes. (line 15)
* modus-themes-toggle <2>: Option for which themes to toggle.
@@ -6762,7 +7044,7 @@ B.2 Variable index
* Menu:
* ~modus-themes-define-derivative-command-known-suffixes~: Create convenience
commands to load a derivative theme.
- (line 19)
+ (line 23)
* modus-operandi-deuteranopia-palette-overrides: Palette overrides.
(line 30)
* modus-operandi-deuteranopia-palette-user: Palette extension. (line 24)
@@ -6779,10 +7061,10 @@ B.2 Variable index
* modus-themes-common-palette-user: Palette extension. (line 16)
* modus-themes-completions: Completion UIs. (line 6)
* modus-themes-custom-variables: Build on top of the Modus themes.
- (line 62)
+ (line 68)
* modus-themes-disable-other-themes: Disable other themes. (line 6)
* modus-themes-faces: Build on top of the Modus themes.
- (line 56)
+ (line 62)
* modus-themes-headings: Heading styles. (line 6)
* modus-themes-italic-constructs: Italic constructs. (line 6)
* modus-themes-items: Option for which themes to rotate.
@@ -6802,7 +7084,7 @@ B.2 Variable index
(line 6)
* modus-themes-prompts: Command prompts. (line 6)
* modus-themes-registered-items: Build on top of the Modus themes.
- (line 14)
+ (line 20)
* modus-themes-to-rotate: Option for which themes to rotate.
(line 9)
* modus-themes-to-toggle: Option for which themes to toggle.
@@ -6888,136 +7170,140 @@ B.3 Concept index
Tag Table:
Node: Top874
-Node: Overview8763
-Node: How do the themes look like11529
-Node: Learn about the latest changes11888
-Node: Installation12276
-Node: Install manually from source13187
-Node: Install from the archives14010
-Node: Install on GNU/Linux14609
-Node: Debian 11 Bullseye15100
-Node: GNU Guix15508
-Node: Dealing with byte compilation errors15791
-Node: Enable and load16949
-Node: The require-theme for built-in Emacs themes20944
-Node: Sample configuration21861
-Node: Differences between loading and enabling24137
-Node: Customization options26202
-Node: Disable other themes29971
-Node: Bold constructs31245
-Node: Italic constructs32117
-Node: Option for which themes to toggle32945
-Node: Option for which themes to rotate33708
-Node: Mixed fonts34705
-Node: Command prompts35759
-Node: Completion UIs37600
-Node: Org mode blocks40449
-Node: Heading styles41092
-Node: UI typeface45518
-Node: Palette overrides46491
-Node: Palette extension50848
-Node: Preview theme colors53324
-Node: Commands for the preview palette buffer54979
-Node: Use colors from the Modus themes palette57057
-Node: Get a single color from the palette with
modus-themes-get-color-value57921
-Node: Use theme colors in code with modus-themes-with-colors60282
-Node: Advanced customization62536
-Node: DIY Palette override presets64314
-Node: DIY Add support for engrave-faces67148
-Node: DIY Stylistic variants using palette overrides77131
-Node: DIY Make the mode line borderless79190
-Node: DIY Make the active mode line colorful80565
-Node: DIY Make the tab bar more or less colorful82783
-Node: DIY Make the fringe invisible or another color84720
-Node: DIY Make links use subtle or no underlines85917
-Node: DIY Make prompts more or less colorful87035
-Node: DIY Make completion matches more or less colorful88358
-Node: DIY Make comments yellow and strings green91917
-Node: DIY Make code syntax use the old alt-syntax style93624
-Node: DIY Make use of alternative styles for code syntax96737
-Node: DIY Make matching parenthesis more or less intense100199
-Node: DIY Make box buttons more or less gray101571
-Node: DIY Make TODO and DONE more or less intense102584
-Node: DIY Make headings more or less colorful104085
-Node: DIY Make Org block colors more or less colorful106202
-Node: DIY Make Org agenda more or less colorful110574
-Node: DIY Make inline code in prose use alternative styles113749
-Node: DIY Make mail citations and headers more or less colorful115989
-Node: DIY Make the region preserve text colors plus other styles118389
-Node: DIY Make mouse highlights more or less colorful119945
-Node: DIY Make language underlines less colorful120958
-Node: DIY Make line numbers use alternative styles122110
-Node: DIY Make diffs use only a foreground123753
-Node: DIY Make deuteranopia diffs red and blue instead of yellow and
blue126640
-Node: DIY More accurate colors in terminal emulators129112
-Node: DIY Range of color with terminal emulators130420
-Node: DIY Per-theme customization settings133207
-Node: DIY Do not extend the region background134640
-Node: DIY Add padding to the mode line135438
-Node: DIY Remap face with local value138366
-Node: DIY Font configurations for Org and others140905
-Ref: DIY Font configurations for Org and others-Footnote-1143888
-Node: DIY Configure bold and italic faces144075
-Node: DIY Custom Org todo keyword and priority faces148697
-Node: DIY Custom Org emphasis faces152438
-Node: DIY Use colored Org source blocks per language157315
-Node: DIY Measure color contrast161955
-Node: DIY Load theme depending on time of day164672
-Node: DIY Backdrop for pdf-tools165700
-Node: DIY Toggle themes without reloading them168861
-Node: DIY Use more spacious margins or padding in Emacs frames170170
-Node: DIY Custom hl-todo colors174407
-Node: DIY Add support for solaire-mode176224
-Node: DIY Add support for meow-mode179316
-Node: DIY Add support for combobulate181126
-Node: DIY Use a hook at the post-load-theme phase184749
-Node: DIY A theme-agnostic hook for theme loading186870
-Node: Build on top of the Modus themes189501
-Node: Determine what counts as a Modus theme195158
-Node: Create convenience commands to load a derivative theme198350
-Node: Face coverage200402
-Node: Supported packages200864
-Node: Indirectly covered packages206680
-Node: Notes on individual packages208036
-Node: Note on calendarel weekday and weekend colors209138
-Node: Note on git-gutter in Doom Emacs210288
-Node: Note on php-mode multiline comments212790
-Node: Note on underlines in compilation buffers213552
-Node: Note on inline Latex in Org buffers214426
-Node: Note on dimmerel215038
-Node: Note on display-fill-column-indicator-mode216525
-Node: Note on highlight-parenthesesel217978
-Node: Note on mmm-modeel background colors224057
-Node: Note for prism226411
-Node: Note on company-mode overlay pop-up229625
-Ref: Note on company-mode overlay pop-up-Footnote-1230355
-Ref: Note on company-mode overlay pop-up-Footnote-2230422
-Node: Note on ERC escaped color sequences230477
-Ref: Note on ERC escaped color sequences-Footnote-1231907
-Node: Note on powerline or spaceline232017
-Node: Note on SHR colors232433
-Node: Note on SHR fonts232855
-Node: Note on Ement colors and fonts233544
-Node: Note on pdf-tools link hints235050
-Node: Note on the Notmuch logo237508
-Node: Note on goto-address-mode faces238042
-Node: Frequently Asked Questions239162
-Node: Is the contrast ratio about adjacent colors?239793
-Node: What does it mean to avoid exaggerations?241302
-Node: Why are colors mostly variants of blue magenta cyan?243152
-Node: What is the best setup for legibility?247486
-Node: Are these color schemes?250128
-Node: Port the Modus themes to other platforms?253782
-Node: Contributing256616
-Node: Sources of the themes257015
-Node: Issues you can help with257911
-Node: Patches require copyright assignment to the FSF259303
-Node: Acknowledgements261525
-Node: GNU Free Documentation License266081
-Node: Indices291244
-Node: Function index291423
-Node: Variable index295618
-Node: Concept index299981
+Node: Overview9039
+Node: How do the themes look like11805
+Node: Learn about the latest changes12164
+Node: Installation12552
+Node: Install manually from source13463
+Node: Install from the archives14286
+Node: Install on GNU/Linux14885
+Node: Debian 11 Bullseye15376
+Node: GNU Guix15784
+Node: Dealing with byte compilation errors16067
+Node: Enable and load17225
+Node: The require-theme for built-in Emacs themes21220
+Node: Sample configuration22137
+Node: Differences between loading and enabling24413
+Node: Customization options26478
+Node: Disable other themes30247
+Node: Bold constructs31521
+Node: Italic constructs32393
+Node: Option for which themes to toggle33221
+Node: Option for which themes to rotate33984
+Node: Mixed fonts34981
+Node: Command prompts36035
+Node: Completion UIs37876
+Node: Org mode blocks40725
+Node: Heading styles41368
+Node: UI typeface45794
+Node: Palette overrides46767
+Node: Palette extension51124
+Node: Preview theme colors53600
+Node: Commands for the preview palette buffer55255
+Node: Use colors from the Modus themes palette57333
+Node: Get a single color from the palette with
modus-themes-get-color-value58197
+Node: Use theme colors in code with modus-themes-with-colors60558
+Node: Advanced customization62812
+Node: DIY Palette override presets64590
+Node: DIY Add support for engrave-faces67424
+Node: DIY Stylistic variants using palette overrides77407
+Node: DIY Make the mode line borderless79466
+Node: DIY Make the active mode line colorful80841
+Node: DIY Make the tab bar more or less colorful83059
+Node: DIY Make the fringe invisible or another color84996
+Node: DIY Make links use subtle or no underlines86193
+Node: DIY Make prompts more or less colorful87311
+Node: DIY Make completion matches more or less colorful88634
+Node: DIY Make comments yellow and strings green92193
+Node: DIY Make code syntax use the old alt-syntax style93900
+Node: DIY Make use of alternative styles for code syntax97013
+Node: DIY Make matching parenthesis more or less intense100475
+Node: DIY Make box buttons more or less gray101847
+Node: DIY Make TODO and DONE more or less intense102860
+Node: DIY Make headings more or less colorful104361
+Node: DIY Make Org block colors more or less colorful106478
+Node: DIY Make Org agenda more or less colorful110850
+Node: DIY Make inline code in prose use alternative styles114025
+Node: DIY Make mail citations and headers more or less colorful116265
+Node: DIY Make the region preserve text colors plus other styles118665
+Node: DIY Make mouse highlights more or less colorful120221
+Node: DIY Make language underlines less colorful121234
+Node: DIY Make line numbers use alternative styles122386
+Node: DIY Make diffs use only a foreground124029
+Node: DIY Make deuteranopia diffs red and blue instead of yellow and
blue126916
+Node: DIY More accurate colors in terminal emulators129388
+Node: DIY Range of color with terminal emulators130696
+Node: DIY Per-theme customization settings133483
+Node: DIY Do not extend the region background134916
+Node: DIY Add padding to the mode line135714
+Node: DIY Remap face with local value138642
+Node: DIY Font configurations for Org and others141181
+Ref: DIY Font configurations for Org and others-Footnote-1144164
+Node: DIY Configure bold and italic faces144351
+Node: DIY Custom Org todo keyword and priority faces148973
+Node: DIY Custom Org emphasis faces152714
+Node: DIY Use colored Org source blocks per language157591
+Node: DIY Measure color contrast162231
+Node: DIY Load theme depending on time of day164948
+Node: DIY Backdrop for pdf-tools165976
+Node: DIY Toggle themes without reloading them169137
+Node: DIY Use more spacious margins or padding in Emacs frames170446
+Node: DIY Custom hl-todo colors174683
+Node: DIY Add support for solaire-mode176500
+Node: DIY Add support for meow-mode179592
+Node: DIY Add support for combobulate181402
+Node: DIY Use a hook at the post-load-theme phase185025
+Node: DIY A theme-agnostic hook for theme loading187146
+Node: Build on top of the Modus themes189777
+Node: Complete example of a Modus derivative theme195950
+Node: Complete example of a package that is derived from Modus196890
+Node: Complete example of a private theme derived from Modus199829
+Node: Complete example of a custom theme with its own palette201395
+Node: Determine what counts as a Modus theme205936
+Node: Create convenience commands to load a derivative theme209346
+Node: Face coverage211563
+Node: Supported packages212025
+Node: Indirectly covered packages217841
+Node: Notes on individual packages219197
+Node: Note on calendarel weekday and weekend colors220299
+Node: Note on git-gutter in Doom Emacs221449
+Node: Note on php-mode multiline comments223951
+Node: Note on underlines in compilation buffers224713
+Node: Note on inline Latex in Org buffers225587
+Node: Note on dimmerel226199
+Node: Note on display-fill-column-indicator-mode227686
+Node: Note on highlight-parenthesesel229139
+Node: Note on mmm-modeel background colors235218
+Node: Note for prism237572
+Node: Note on company-mode overlay pop-up240786
+Ref: Note on company-mode overlay pop-up-Footnote-1241516
+Ref: Note on company-mode overlay pop-up-Footnote-2241583
+Node: Note on ERC escaped color sequences241638
+Ref: Note on ERC escaped color sequences-Footnote-1243068
+Node: Note on powerline or spaceline243178
+Node: Note on SHR colors243594
+Node: Note on SHR fonts244016
+Node: Note on Ement colors and fonts244705
+Node: Note on pdf-tools link hints246211
+Node: Note on the Notmuch logo248669
+Node: Note on goto-address-mode faces249203
+Node: Frequently Asked Questions250323
+Node: Is the contrast ratio about adjacent colors?250954
+Node: What does it mean to avoid exaggerations?252463
+Node: Why are colors mostly variants of blue magenta cyan?254313
+Node: What is the best setup for legibility?258647
+Node: Are these color schemes?261289
+Node: Port the Modus themes to other platforms?264943
+Node: Contributing267777
+Node: Sources of the themes268176
+Node: Issues you can help with269072
+Node: Patches require copyright assignment to the FSF270464
+Node: Acknowledgements272686
+Node: GNU Free Documentation License277242
+Node: Indices302405
+Node: Function index302584
+Node: Variable index306779
+Node: Concept index311142
End Tag Table
diff --git a/doc/modus-themes.org b/doc/modus-themes.org
index 4398350557..1bdfcc9866 100644
--- a/doc/modus-themes.org
+++ b/doc/modus-themes.org
@@ -4163,13 +4163,19 @@ 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 do so to benefit from the extensive
-customization of the Modus themes and the fact that they are part of
-core Emacs.
+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 ([[#h:bd47fea9-416d-481e-a504-82850b8c2a58][Complete
example of a Modus derivative theme]]).
#+findex: modus-themes-theme
#+vindex: modus-themes-registered-items
-A new theme exists in a file whose directory is in the
~custom-theme-load-path~.
+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
@@ -4272,11 +4278,272 @@ 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.
+** Complete example of a Modus derivative theme
+:PROPERTIES:
+:CUSTOM_ID: h:bd47fea9-416d-481e-a504-82850b8c2a58
+:END:
+
+[ For more context: [[#h:86eb375b-9be4-43ce-879a-0686a524a63b][Build on top of
the Modus themes]]. ]
+
+In this section, we show how to define a new Modus derivative theme.
+In its simplest form, a theme is a file called =NAME-theme.el= in a
+directory that is part of the ~custom-theme-load-path~. We show how to
+do this for a package and for a private configuration:
+
+- [[#h:f2757848-ea41-4cd7-a04d-7e650555a59b][Complete example of a package
that is derived from Modus]]
+- [[#h:48e391a6-831b-48ec-b92d-4e7e6871b043][Complete example of a private
theme derived from Modus]]
+
+*** Complete example of a package that is derived from Modus
+:PROPERTIES:
+:CUSTOM_ID: h:f2757848-ea41-4cd7-a04d-7e650555a59b
+:END:
+
+For package developers, the following snippet needs to be included in
+each theme file ([[#h:48e391a6-831b-48ec-b92d-4e7e6871b043][Complete example
of a private theme derived from Modus]]):
+
+#+begin_src emacs-lisp
+;;;; Add themes from this package to the `custom-theme-load-path'
+
+;;;###autoload
+(when load-file-name
+ (let ((dir (file-name-directory load-file-name)))
+ (add-to-list 'custom-theme-load-path dir)))
+#+end_src
+
+If the package provides many themes, then the above snippet can be
+included in a shared file that is then loaded via ~require~ in the
+individual theme files.
+
+For example, the family of themes that includes =prot-light-theme.el=
+and =prot-dark-theme.el= has a shared library which is
+=prot-themes.el= and therein we find at least the following:
+
+#+begin_src emacs-lisp
+;; Package headers here for prot-themes.el...
+
+;; Any other shared definitions...
+
+;;;; Add themes from this package to the `custom-theme-load-path'
+
+;;;###autoload
+(when load-file-name
+ (let ((dir (file-name-directory load-file-name)))
+ (add-to-list 'custom-theme-load-path dir)))
+
+(provide 'prot-themes)
+;;; prot-themes.el ends here
+#+end_src
+
+Then each individual theme can look like this
([[#h:ca3031b5-5f7a-46d4-bc83-e84e8bed038c][Complete example of a custom theme
with its own palette]]):
+
+#+begin_src emacs-lisp
+(require 'prot-themes)
+
+(modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ nil
+ nil)
+#+end_src
+
+The contents of such a package will be of this form:
+
+- =prot-themes.el= :: Common file with all the shared definitions.
+- =prot-light-theme.el= :: The light theme.
+- =prot-dark-theme.el= :: The dark theme.
+
+The shared file can be skipped if the only piece of common code is
+the aforementioned snippet about the ~custom-theme-load-path~. Simply
+add that snippet to the bottom of each theme file, like this:
+
+#+begin_src emacs-lisp
+(modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ nil
+ nil)
+
+;;;###autoload
+(when load-file-name
+ (let ((dir (file-name-directory load-file-name)))
+ (add-to-list 'custom-theme-load-path dir)))
+#+end_src
+
+The package is then a collection of =NAME-theme.el= files and nothing more.
+
+In principle, a package derived from Modus does not need to define any
+commands or user options. What is shown in this section is enough.
+Packages such as the ~ef-themes~ and ~standard-themes~ are exceptions
+because they existed for years before they were based on Modus and
+must remain backward compatible.
+
+*** Complete example of a private theme derived from Modus
+:PROPERTIES:
+:CUSTOM_ID: h:48e391a6-831b-48ec-b92d-4e7e6871b043
+:END:
+
+If your derivative theme is not going to be distributed as a package
+([[#h:f2757848-ea41-4cd7-a04d-7e650555a59b][Complete example of a package that
is derived from Modus]]), then
+create a directory where all custom themes are stored and add it to
+the ~custom-theme-load-path~. For example, the =my-custom-themes=
+directory can be included thus somewhere in the Emacs initialization
+file:
+
+#+begin_src emacs-lisp
+(add-to-list 'custom-theme-load-path (locate-user-emacs-file
"my-custom-themes/"))
+#+end_src
+
+The function ~locate-user-emacs-file~ takes care to return a path
+relative to where the user's init file is. If, say, we have
+=~/.emacs.d/init.el= then we get =~/.emacs.d/my-custom-themes/=.
+
+Create the directory in that path. Then for each derivative Modus
+theme, write a new file of the form =NAME-theme.el=. If, for instance,
+your theme is named =prot-light= the file is called =prot-light-theme.el=.
+
+At minimum, the contents of a theme file are these
([[#h:ca3031b5-5f7a-46d4-bc83-e84e8bed038c][Complete example of a custom theme
with its own palette]]):
+
+#+begin_src emacs-lisp
+(modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ nil
+ nil)
+#+end_src
+
+*** Complete example of a custom theme with its own palette
+:PROPERTIES:
+:CUSTOM_ID: h:ca3031b5-5f7a-46d4-bc83-e84e8bed038c
+:END:
+
+It is a good idea for a derivative theme to use as its core palette
+one of those defined in the ~modus-themes~, such as ~modus-operandi-palette~.
+This guarantees that all core palette definitions are inherited by the
+derivative theme.
+
+The derivative may then add its own colors to the user palette, which
+will override the core palette in such of a conflict
([[#h:f4d4b71b-2ca5-4c3d-b0b4-9bfd7aa7fb4d][Preview theme colors]]).
+
+The core and user palettes are among the arguments passed to the
+~modus-themes-theme~ functions, as explained elsewhere in this manual
+([[#h:86eb375b-9be4-43ce-879a-0686a524a63b][Build on top of the Modus
themes]]).
+
+In the following example, we are defining the ~prot-light~ theme in
+the =prot-light-theme.el= file. This theme declares itself as
+belonging to the =prot-themes= family. It is based on the
+~modus-operandi-palette~ but then defines its own palette, the
+~prot-light-palette~ with entries that take precedence over whatever
+equivalent is in the ~modus-operandi-palette~.
+
+#+begin_src emacs-lisp
+(defvar prot-light-palette
+ '((cursor "#ff0000")
+ (bg-main "#f0e0d0")
+ (fg-main "#202020"))
+ "Like `modus-operandi-palette'.")
+
+(modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ 'prot-light-palette
+ nil)
+#+end_src
+
+The above is a complete theme which is like ~modus-operandi~ except
+for those three color definitions specified in the ~prot-light-palette~.
+There is no limit to how comprehensive the user palette is.
+
+Depending on the requirements, this theme can make itself further
+customizable by the end user via theme-specific palette overrides. In
+this case, we have the addition of a user option, which we could call
+anything though it makes sense to name it consistently like
~prot-light-palette-overrides~.
+
+#+begin_src emacs-lisp
+(defvar prot-light-palette
+ '((cursor "#ff0000")
+ (bg-main "#f0e0d0")
+ (fg-main "#202020"))
+ "Like `modus-operandi-palette'.")
+
+(defcustom prot-light-palette-overrides nil
+ "Overrides for the `prot-light' theme."
+ :type '(repeat (list symbol (choice symbol string)))
+ :link '(info-link "(modus-themes) Palette overrides"))
+
+(modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ 'prot-light-palette
+ 'prot-light-palette-overrides)
+#+end_src
+
+In the above example, we have our ~prot-light~ theme which is like
+~modus-operandi~ except three colors and which can now be customized
+further by the user via the ~prot-light-palette-overrides~
([[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]]).
+
+Finally, a derivative theme can specify its own settings for custom
+faces and variables. This is generally not needed, but is provided as
+an option for maximum flexibility. In the following example, the
+~prot-light~ theme has its own face definitions in addition to all the
+aforementioned:
+
+#+begin_src emacs-lisp
+(defvar prot-light-palette
+ '((cursor "#ff0000")
+ (bg-main "#f0e0d0")
+ (fg-main "#202020"))
+ "Like `modus-operandi-palette'.")
+
+(defcustom prot-light-palette-overrides nil
+ "Overrides for the `prot-light' theme."
+ :type '(repeat (list symbol (choice symbol string)))
+ :link '(info-link "(modus-themes) Palette overrides"))
+
+(defvar prot-light-custom-faces
+ '(
+ `(region ((,c :background ,bg-ochre :foreground ,unspecified :extend nil)))
+ `(font-lock-keyword-face ((,c :inherit italic :foreground ,keyword))))
+ "Custom faces that deviate from---or complement---those in the Modus
themes.")
+
+(modus-themes-theme
+ 'prot-light
+ 'prot-themes
+ "My demo `prot-light' theme."
+ 'light
+ 'modus-operandi-palette
+ 'prot-light-palette
+ 'prot-light-palette-overrides
+ 'prot-light-custom-faces)
+#+end_src
+
+The custom faces can name a color from the given theme's palette. In
+this example, =bg-ochre= comes from the ~modus-operandi-palette~
+though it would work the same way if, say, ~prot-light-palette~
+defined ~bg-soil~ and then referenced it in ~prot-light-custom-faces~.
+
** Determine what counts as a Modus theme
:PROPERTIES:
:CUSTOM_ID: h:412e3017-81fe-4a95-97a6-225de1867757
:END:
+[ NOTE: Users of many Modus derivatives do not need to do anything of
+ what is described herein. Just enable the
~modus-themes-include-derivatives-mode~. ]
+
#+findex: modus-themes-get-all-known-themes
Once the theme is instantiated, it will be listed in the return value
of the function ~modus-themes-get-all-known-themes~. This function
@@ -4350,6 +4617,9 @@ accordingly."
:CUSTOM_ID: h:6bfbb4d6-2f23-4d06-827a-8b9a91507a02
:END:
+[ NOTE: Users of many Modus derivatives do not need to do anything of
+ what is described herein. Just enable the
~modus-themes-include-derivatives-mode~. ]
+
#+findex: modus-themes-define-derivative-command
In the previous section, we explored the mechanics of the
~modus-themes-get-themes~
([[#h:412e3017-81fe-4a95-97a6-225de1867757][Determine what counts as a Modus
theme]]).