mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-23 07:19:15 +00:00
6682 lines
255 KiB
Org Mode
6682 lines
255 KiB
Org Mode
#+title: Modus themes for GNU Emacs
|
||
#+author: Protesilaos Stavrou
|
||
#+email: info@protesilaos.com
|
||
#+language: en
|
||
#+options: ':t toc:nil author:t email:t num:t
|
||
#+startup: content
|
||
#+macro: stable-version 3.0.0
|
||
#+macro: release-date 2022-10-28
|
||
#+macro: development-version 3.1.0-dev
|
||
#+macro: file @@texinfo:@file{@@$1@@texinfo:}@@
|
||
#+macro: space @@texinfo:@: @@
|
||
#+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@
|
||
#+texinfo_filename: modus-themes.info
|
||
#+texinfo_dir_category: Emacs misc features
|
||
#+texinfo_dir_title: Modus Themes: (modus-themes)
|
||
#+texinfo_dir_desc: Elegant, highly legible and customizable themes
|
||
#+texinfo_header: @set MAINTAINERSITE @uref{https://protesilaos.com,maintainer webpage}
|
||
#+texinfo_header: @set MAINTAINER Protesilaos Stavrou
|
||
#+texinfo_header: @set MAINTAINEREMAIL @email{info@protesilaos.com}
|
||
#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:info@protesilaos.com,contact the maintainer}
|
||
|
||
#+texinfo: @insertcopying
|
||
|
||
This manual, written by Protesilaos Stavrou, describes the customization
|
||
options for the ~modus-operandi~ and ~modus-vivendi~ themes, and provides
|
||
every other piece of information pertinent to them.
|
||
|
||
The documentation furnished herein corresponds to stable version
|
||
{{{stable-version}}}, released on {{{release-date}}}. Any reference to a newer
|
||
feature which does not yet form part of the latest tagged commit, is
|
||
explicitly marked as such.
|
||
|
||
Current development target is {{{development-version}}}.
|
||
+ Homepage: https://protesilaos.com/emacs/modus-themes.
|
||
+ Git repository: https://git.sr.ht/~protesilaos/modus-themes.
|
||
+ Mailing list: https://lists.sr.ht/~protesilaos/modus-themes.
|
||
+ Backronym: My Old Display Unexpectedly Sharpened ... themes
|
||
|
||
#+toc: headlines 8 insert TOC here, with eight headline levels
|
||
|
||
* COPYING
|
||
:properties:
|
||
:copying: t
|
||
:custom_id: h:b14c3fcb-13dd-4144-9d92-2c58b3ed16d3
|
||
:end:
|
||
|
||
Copyright (C) 2020-2023 Free Software Foundation, Inc.
|
||
|
||
#+begin_quote
|
||
Permission is granted to copy, distribute and/or modify this document
|
||
under the terms of the GNU Free Documentation License, Version 1.3 or
|
||
any later version published by the Free Software Foundation; with no
|
||
Invariant Sections, with the Front-Cover Texts being “A GNU Manual,” and
|
||
with the Back-Cover Texts as in (a) below. A copy of the license is
|
||
included in the section entitled “GNU Free Documentation License.”
|
||
|
||
(a) The FSF’s Back-Cover Text is: “You have the freedom to copy and
|
||
modify this GNU manual.”
|
||
#+end_quote
|
||
|
||
* Overview
|
||
:properties:
|
||
:custom_id: h:f0f3dbcb-602d-40cf-b918-8f929c441baf
|
||
:end:
|
||
|
||
The Modus themes are designed for accessible readability. They conform
|
||
with the highest standard for color contrast between any given
|
||
combination of background and foreground values. This corresponds to
|
||
the WCAG AAA standard, which specifies a minimum rate of distance in
|
||
relative luminance of 7:1.
|
||
|
||
Modus Operandi (~modus-operandi~) is a light theme, while Modus Vivendi
|
||
(~modus-vivendi~) is dark. Each theme's color palette is designed to meet
|
||
the needs of the numerous interfaces that are possible in the Emacs
|
||
computing environment.
|
||
|
||
The overarching objective of this project is to always offer accessible
|
||
color combinations. There shall never be a compromise on this
|
||
principle. If there arises an inescapable trade-off between readability
|
||
and stylistic considerations, we will always opt for the former.
|
||
|
||
To ensure that users have a consistently accessible experience, the
|
||
themes strive to achieve as close to full face coverage as possible
|
||
([[#h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19][Face coverage]]).
|
||
|
||
Furthermore, the themes are designed to empower users with red-green
|
||
color deficiency (deuteranopia). This is achieved in three ways:
|
||
|
||
1. The conformance with the highest legibility standard means that text
|
||
is always readable no matter the perception of its hue.
|
||
|
||
2. Most contexts use colors on the blue-cyan-magenta-purple side of the
|
||
spectrum. Put differently, green and/or red are seldom used, thus
|
||
minimizing the potential for confusion.
|
||
|
||
[[#h:0b26cb47-9733-4cb1-87d9-50850cb0386e][Why are colors mostly variants of blue, magenta, cyan?]].
|
||
|
||
3. In contexts where a red/green color-coding is unavoidable, we provide
|
||
a universal toggle to customize the themes so that a red/blue scheme
|
||
is used instead.
|
||
|
||
[[#h:3ed03a48-20d8-4ce7-b214-0eb7e4c79abe][Option for red-green color deficiency or deuteranopia]].
|
||
|
||
Starting with version 0.12.0 and onwards, the themes are built into GNU
|
||
Emacs.
|
||
|
||
** How do the themes look like
|
||
:properties:
|
||
:custom_id: h:69b92089-069c-4ba1-9d94-cc3415fc4f87
|
||
:end:
|
||
#+cindex: Screenshots
|
||
|
||
Check the web page with [[https://protesilaos.com/emacs/modus-themes-pictures/][the screen shots]]. There are lots of scenarios
|
||
on display that draw attention to details and important aspects in the
|
||
design of the themes. They also showcase the numerous customization
|
||
options.
|
||
|
||
[[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization options]].
|
||
|
||
** Learn about the latest changes
|
||
:properties:
|
||
:custom_id: h:2cc37c36-6c1a-48b2-a010-1050b270ee18
|
||
:end:
|
||
#+cindex: Changelog
|
||
|
||
Please refer to the [[https://protesilaos.com/emacs/modus-themes-changelog][web page with the change log]]. It is comprehensive
|
||
and covers everything that goes into every tagged release of the themes.
|
||
|
||
* Installation
|
||
:properties:
|
||
:custom_id: h:1af85373-7f81-4c35-af25-afcef490c111
|
||
:end:
|
||
|
||
The Modus themes are distributed with Emacs starting with version 28.1.
|
||
On older versions of Emacs, they can be installed using Emacs' package
|
||
manager or manually from their code repository. There also exist
|
||
packages for distributions of GNU/Linux.
|
||
|
||
** Install manually from source
|
||
:properties:
|
||
:custom_id: h:da3414b7-1426-46b8-8e76-47b845b76fd0
|
||
:end:
|
||
|
||
In the following example, we are assuming that your Emacs files are
|
||
stored in =~/.emacs.d= and that you want to place the Modus themes in
|
||
=~/.emacs.d/modus-themes=.
|
||
|
||
1. Get the source and store it in the desired path by running the
|
||
following in the command line shell:
|
||
|
||
: $ git clone https://gitlab.com/protesilaos/modus-themes.git ~/.emacs.d/modus-themes
|
||
|
||
2. Add that path to your known Elisp libraries' list, by placing this
|
||
snippet of Emacs Lisp in your init file (e.g. {{{file(init.el)}}}):
|
||
|
||
#+begin_src emacs-lisp
|
||
(add-to-list 'load-path "~/.emacs.d/modus-themes")
|
||
#+end_src
|
||
|
||
The themes are now ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]].
|
||
|
||
** Install from the archives
|
||
:properties:
|
||
:custom_id: h:c4b10085-149f-43e2-bd4d-347f33aee054
|
||
:end:
|
||
|
||
The ~modus-themes~ package is available from the GNU ELPA archive, which
|
||
is configured by default.
|
||
|
||
Prior to querying any package archive, make sure to update the index,
|
||
with {{{kbd(M-x package-refresh-contents)}}}. Then all you need to do
|
||
is type {{{kbd(M-x package-install)}}} and specify the ~modus-themes~.
|
||
|
||
Once installed, the themes are ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]].
|
||
|
||
** Install on GNU/Linux
|
||
:properties:
|
||
:custom_id: h:da640eb1-95dd-4e86-bb4e-1027b27885f0
|
||
:end:
|
||
|
||
The themes are also available from the archives of some distributions of
|
||
GNU/Linux. These should correspond to a tagged release rather than
|
||
building directly from the latest Git commit. It all depends on the
|
||
distro's packaging policies.
|
||
|
||
*** Debian 11 Bullseye
|
||
:properties:
|
||
:custom_id: h:7e570360-9ee6-4bc5-8c04-9dc11418a3e4
|
||
:end:
|
||
|
||
The themes are part of Debian 11 Bullseye. Get them with:
|
||
|
||
#+begin_src sh
|
||
sudo apt install elpa-modus-themes
|
||
#+end_src
|
||
|
||
They are now ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]].
|
||
|
||
NOTE that Debian's package is severely out-of-date as of this writing
|
||
2022-07-24 09:57 +0300.
|
||
|
||
*** GNU Guix
|
||
:properties:
|
||
:custom_id: h:a4ca52cd-869f-46a5-9e16-4d9665f5b88e
|
||
:end:
|
||
|
||
Users of Guix can get the themes with this command:
|
||
|
||
#+begin_src sh
|
||
guix package -i emacs-modus-themes
|
||
#+end_src
|
||
|
||
They are now ready to be used: [[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]].
|
||
|
||
** Dealing with byte compilation errors
|
||
:properties:
|
||
:custom_id: h:e6268471-e847-4c9d-998f-49a83257b7f1
|
||
:end:
|
||
|
||
From time to time, we receive bug reports pertaining to errors with byte
|
||
compilation. These seldom have to do with faulty code in the themes: it
|
||
might be a shortcoming of =package.el=, some regression in the current
|
||
development target of Emacs, a misconfiguration in an otherwise exotic
|
||
setup, and the like.
|
||
|
||
The common solution with a stable version of Emacs is to:
|
||
|
||
1. Delete the =modus-themes= package.
|
||
2. Close the current Emacs session.
|
||
3. Install the =modus-themes= again.
|
||
|
||
For those building Emacs directly from source, the solution may involve
|
||
reverting to an earlier commit in emacs.git.
|
||
|
||
At any rate, if you encounter such an issue please report it: we will
|
||
either fix the bug on our end if it is truly ours, or help forward it to
|
||
the relevant upstream maintainer. Whatever you do, please understand
|
||
that a build failure does not mean we are necessarily doing something
|
||
wrong.
|
||
|
||
[[#h:6536c8d5-3f98-43ab-a787-b94120e735e8][Issues you can help with]].
|
||
|
||
* Enable and load
|
||
:properties:
|
||
:custom_id: h:3f3c3728-1b34-437d-9d0c-b110f5b161a9
|
||
:end:
|
||
#+findex: modus-themes-load-themes
|
||
#+findex: modus-themes-toggle
|
||
#+findex: modus-themes-load-operandi
|
||
#+findex: modus-themes-load-vivendi
|
||
#+cindex: Essential configuration
|
||
#+vindex: modus-themes-after-load-theme-hook
|
||
|
||
Users of the built-in themes cannot ~require~ the package as usual
|
||
because there is no package to speak of. Instead, things are simpler as
|
||
all one needs is to load the theme of their preference by adding either
|
||
form to their init file:
|
||
|
||
#+begin_src emacs-lisp
|
||
(load-theme 'modus-operandi) ; Light theme
|
||
(load-theme 'modus-vivendi) ; Dark theme
|
||
#+end_src
|
||
|
||
Users of packaged variants of the themes must add a few more lines to
|
||
ensure that everything works as intended. First, one has to require the
|
||
main library before loading either theme:
|
||
|
||
#+begin_src emacs-lisp
|
||
(require 'modus-themes)
|
||
#+end_src
|
||
|
||
Then it is recommended to load the individual theme files with the
|
||
helper function ~modus-themes-load-themes~:
|
||
|
||
#+begin_src emacs-lisp
|
||
;; Load the theme files before enabling a theme (else you get an error).
|
||
(modus-themes-load-themes)
|
||
#+end_src
|
||
|
||
Once the libraries that define the themes are enabled, one can activate
|
||
a theme with either of the following expressions:
|
||
|
||
#+begin_src emacs-lisp
|
||
(modus-themes-load-operandi) ; Light theme
|
||
;; OR
|
||
(modus-themes-load-vivendi) ; Dark theme
|
||
#+end_src
|
||
|
||
Changes to the available customization options must always be evaluated
|
||
before loading a theme ([[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]). An exception to this
|
||
norm is when using the various Custom interfaces or with commands like
|
||
{{{kbd(M-x customize-set-variable)}}}, which can optionally
|
||
automatically reload the theme ([[#h:9001527a-4e2c-43e0-98e8-3ef72d770639][Option for inhibiting theme reload]]).
|
||
|
||
This is how a basic setup could look like:
|
||
|
||
#+begin_src emacs-lisp
|
||
;;; For the built-in themes which cannot use `require':
|
||
;; Add all your customizations prior to loading the themes
|
||
(setq modus-themes-italic-constructs t
|
||
modus-themes-bold-constructs nil
|
||
modus-themes-region '(bg-only no-extend))
|
||
|
||
;; Load the theme of your choice:
|
||
(load-theme 'modus-operandi) ;; OR (load-theme 'modus-vivendi)
|
||
|
||
(define-key global-map (kbd "<f5>") #'modus-themes-toggle)
|
||
|
||
|
||
|
||
;;; For packaged versions which must use `require':
|
||
(require 'modus-themes)
|
||
|
||
;; Add all your customizations prior to loading the themes
|
||
(setq modus-themes-italic-constructs t
|
||
modus-themes-bold-constructs nil
|
||
modus-themes-region '(bg-only no-extend))
|
||
|
||
;; Load the theme files before enabling a theme
|
||
(modus-themes-load-themes)
|
||
|
||
;; Load the theme of your choice:
|
||
(modus-themes-load-operandi) ;; OR (modus-themes-load-vivendi)
|
||
|
||
(define-key global-map (kbd "<f5>") #'modus-themes-toggle)
|
||
#+end_src
|
||
|
||
[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration with and without use-package]].
|
||
|
||
With those granted, bear in mind a couple of technical points on
|
||
~modus-themes-load-operandi~ and ~modus-themes-load-vivendi~, as well as
|
||
~modus-themes-toggle~ which relies on them:
|
||
|
||
1. Those functions call ~load-theme~. Some users prefer to opt for ~enable-theme~ instead ([[#h:e68560b3-7fb0-42bc-a151-e015948f8a35][Differences between loading and enabling]]).
|
||
|
||
2. The functions will run the ~modus-themes-after-load-theme-hook~ as
|
||
their final step. This can be employed for bespoke configurations
|
||
([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]]). Experienced users may not wish to rely on
|
||
such a hook and the functions that run it: they may prefer a custom
|
||
solution ([[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]]).
|
||
|
||
** Sample configuration with and without use-package
|
||
:properties:
|
||
:custom_id: h:e979734c-a9e1-4373-9365-0f2cd36107b8
|
||
:end:
|
||
#+cindex: use-package configuration
|
||
#+cindex: sample configuration
|
||
|
||
It is common for Emacs users to rely on ~use-package~ for declaring
|
||
package configurations in their setup. We use this as an example:
|
||
|
||
#+begin_src emacs-lisp
|
||
;;; For the built-in themes which cannot use `require':
|
||
(use-package emacs
|
||
:init
|
||
;; Add all your customizations prior to loading the themes
|
||
(setq modus-themes-italic-constructs t
|
||
modus-themes-bold-constructs nil
|
||
modus-themes-region '(bg-only no-extend))
|
||
:config
|
||
;; Load the theme of your choice:
|
||
(load-theme 'modus-operandi) ;; OR (load-theme 'modus-vivendi)
|
||
:bind ("<f5>" . modus-themes-toggle))
|
||
|
||
|
||
|
||
;;; For packaged versions which must use `require':
|
||
(use-package modus-themes
|
||
:ensure
|
||
:init
|
||
;; Add all your customizations prior to loading the themes
|
||
(setq modus-themes-italic-constructs t
|
||
modus-themes-bold-constructs nil
|
||
modus-themes-region '(bg-only no-extend))
|
||
|
||
;; Load the theme files before enabling a theme
|
||
(modus-themes-load-themes)
|
||
:config
|
||
;; Load the theme of your choice:
|
||
(modus-themes-load-operandi) ;; OR (modus-themes-load-vivendi)
|
||
:bind ("<f5>" . modus-themes-toggle))
|
||
#+end_src
|
||
|
||
The same without ~use-package~:
|
||
|
||
#+begin_src emacs-lisp
|
||
;;; For the built-in themes which cannot use `require':
|
||
;; Add all your customizations prior to loading the themes
|
||
(setq modus-themes-italic-constructs t
|
||
modus-themes-bold-constructs nil
|
||
modus-themes-region '(bg-only no-extend))
|
||
|
||
;; Load the theme of your choice:
|
||
(load-theme 'modus-operandi) ;; OR (load-theme 'modus-vivendi)
|
||
|
||
(define-key global-map (kbd "<f5>") #'modus-themes-toggle)
|
||
|
||
|
||
|
||
;;; For packaged versions which must use `require':
|
||
(require 'modus-themes)
|
||
|
||
;; Add all your customizations prior to loading the themes
|
||
(setq modus-themes-italic-constructs t
|
||
modus-themes-bold-constructs nil
|
||
modus-themes-region '(bg-only no-extend))
|
||
|
||
;; Load the theme files before enabling a theme
|
||
(modus-themes-load-themes)
|
||
|
||
;; Load the theme of your choice:
|
||
(modus-themes-load-operandi) ;; OR (modus-themes-load-vivendi)
|
||
|
||
(define-key global-map (kbd "<f5>") #'modus-themes-toggle)
|
||
#+end_src
|
||
|
||
[[#h:e68560b3-7fb0-42bc-a151-e015948f8a35][Differences between loading and enabling]].
|
||
|
||
Note: make sure not to customize the variable ~custom-theme-load-path~
|
||
or ~custom-theme-directory~ after the themes' package declaration. That
|
||
will lead to failures in loading the files. If either or both of those
|
||
variables need to be changed, their values should be defined before the
|
||
package declaration of the themes.
|
||
|
||
** Differences between loading and enabling
|
||
:properties:
|
||
:custom_id: h:e68560b3-7fb0-42bc-a151-e015948f8a35
|
||
:end:
|
||
#+cindex: load-theme VS enable-theme
|
||
|
||
The reason we recommend ~load-theme~ instead of the other option of
|
||
~enable-theme~ is that the former does a kind of "reset" on the face
|
||
specs. It quite literally loads (or reloads) the theme. Whereas the
|
||
latter simply puts an already loaded theme at the top of the list of
|
||
enabled items, re-using whatever state was last loaded.
|
||
|
||
As such, ~load-theme~ reads all customizations that may happen during
|
||
any given Emacs session: even after the initial setup of a theme.
|
||
Examples are calls to ~custom-set-faces~, as well as new values assigned
|
||
to the options the Modus themes provide ([[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]).
|
||
|
||
Our tests show that ~enable-theme~ does not read such variables anew, so
|
||
it might appear to the unsuspecting user that the themes are somehow
|
||
broken whenever they try to assign a new value to a customization option
|
||
or some face.
|
||
|
||
This "reset" that ~load-theme~ brings about does, however, come at the
|
||
cost of being somewhat slower than ~enable-theme~. Users who have a
|
||
stable setup and who seldom update their variables during a given Emacs
|
||
session, are better off using something like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(require 'modus-themes)
|
||
(load-theme 'modus-operandi t t)
|
||
(load-theme 'modus-vivendi t t)
|
||
|
||
(enable-theme 'modus-operandi) ;; OR (enable-theme 'modus-vivendi)
|
||
#+end_src
|
||
|
||
[[#h:b40aca50-a3b2-4c43-be58-2c26fcd14237][Toggle themes without reloading them]].
|
||
|
||
[[#h:e979734c-a9e1-4373-9365-0f2cd36107b8][Sample configuration with and without use-package]].
|
||
|
||
With the above granted, other sections of the manual discuss how to
|
||
configure custom faces, where ~load-theme~ is expected, though
|
||
~enable-theme~ could still apply in stable setups:
|
||
|
||
[[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Case-by-case face specs using the themes' palette]].
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
* Customization Options
|
||
:properties:
|
||
:custom_id: h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f
|
||
:end:
|
||
|
||
The Modus themes are highly configurable, though they should work well
|
||
without any further tweaks. By default, all customization options are
|
||
set to nil, unless otherwise noted in this manual.
|
||
|
||
Remember that all customization options must be evaluated before loading
|
||
a theme ([[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]). If the theme is already active, it must be
|
||
reloaded for changes in user options to come into force.
|
||
|
||
Below is a summary of what you will learn in the subsequent sections of
|
||
this manual.
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-italic-constructs t
|
||
modus-themes-bold-constructs nil
|
||
modus-themes-mixed-fonts nil
|
||
modus-themes-subtle-line-numbers nil
|
||
modus-themes-intense-mouseovers nil
|
||
modus-themes-deuteranopia t
|
||
modus-themes-tabs-accented t
|
||
modus-themes-variable-pitch-ui nil
|
||
modus-themes-inhibit-reload t ; only applies to `customize-set-variable' and related
|
||
|
||
modus-themes-fringes nil ; {nil,'subtle,'intense}
|
||
|
||
;; Options for `modus-themes-lang-checkers' are either nil (the
|
||
;; default), or a list of properties that may include any of those
|
||
;; symbols: `straight-underline', `text-also', `background',
|
||
;; `intense' OR `faint'.
|
||
modus-themes-lang-checkers nil
|
||
|
||
;; Options for `modus-themes-mode-line' are either nil, or a list
|
||
;; that can combine any of `3d' OR `moody', `borderless',
|
||
;; `accented', a natural number for extra padding (or a cons cell
|
||
;; of padding and NATNUM), and a floating point for the height of
|
||
;; the text relative to the base font size (or a cons cell of
|
||
;; height and FLOAT)
|
||
modus-themes-mode-line '(accented borderless (padding . 4) (height . 0.9))
|
||
|
||
;; Same as above:
|
||
;; modus-themes-mode-line '(accented borderless 4 0.9)
|
||
|
||
;; Options for `modus-themes-markup' are either nil, or a list
|
||
;; that can combine any of `bold', `italic', `background',
|
||
;; `intense'.
|
||
modus-themes-markup '(background italic)
|
||
|
||
;; Options for `modus-themes-syntax' are either nil (the default),
|
||
;; or a list of properties that may include any of those symbols:
|
||
;; `faint', `yellow-comments', `green-strings', `alt-syntax'
|
||
modus-themes-syntax nil
|
||
|
||
;; Options for `modus-themes-hl-line' are either nil (the default),
|
||
;; or a list of properties that may include any of those symbols:
|
||
;; `accented', `underline', `intense'
|
||
modus-themes-hl-line '(underline accented)
|
||
|
||
;; Options for `modus-themes-paren-match' are either nil (the
|
||
;; default), or a list of properties that may include any of those
|
||
;; symbols: `bold', `intense', `underline'
|
||
modus-themes-paren-match '(bold intense)
|
||
|
||
;; Options for `modus-themes-links' are either nil (the default),
|
||
;; or a list of properties that may include any of those symbols:
|
||
;; `neutral-underline' OR `no-underline', `faint' OR `no-color',
|
||
;; `bold', `italic', `background'
|
||
modus-themes-links '(neutral-underline background)
|
||
|
||
;; Options for `modus-themes-box-buttons' are either nil (the
|
||
;; default), or a list that can combine any of `flat', `accented',
|
||
;; `faint', `variable-pitch', `underline', `all-buttons', the
|
||
;; symbol of any font weight as listed in `modus-themes-weights',
|
||
;; and a floating point number (e.g. 0.9) for the height of the
|
||
;; button's text.
|
||
modus-themes-box-buttons '(variable-pitch flat faint 0.9)
|
||
|
||
;; Options for `modus-themes-prompts' are either nil (the
|
||
;; default), or a list of properties that may include any of those
|
||
;; symbols: `background', `bold', `gray', `intense', `italic'
|
||
modus-themes-prompts '(intense bold)
|
||
|
||
;; The `modus-themes-completions' is an alist that reads three
|
||
;; keys: `matches', `selection', `popup'. Each accepts a nil
|
||
;; value (or empty list) or a list of properties that can include
|
||
;; any of the following (for WEIGHT read further below):
|
||
;;
|
||
;; `matches' - `background', `intense', `underline', `italic', WEIGHT
|
||
;; `selection' - `accented', `intense', `underline', `italic', `text-also' WEIGHT
|
||
;; `popup' - same as `selected'
|
||
;; `t' - applies to any key not explicitly referenced (check docs)
|
||
;;
|
||
;; WEIGHT is a symbol such as `semibold', `light', or anything
|
||
;; covered in `modus-themes-weights'. Bold is used in the absence
|
||
;; of an explicit WEIGHT.
|
||
modus-themes-completions '((matches . (extrabold))
|
||
(selection . (semibold accented))
|
||
(popup . (accented intense)))
|
||
|
||
modus-themes-mail-citations nil ; {nil,'intense,'faint,'monochrome}
|
||
|
||
;; Options for `modus-themes-region' are either nil (the default),
|
||
;; or a list of properties that may include any of those symbols:
|
||
;; `no-extend', `bg-only', `accented'
|
||
modus-themes-region '(bg-only no-extend)
|
||
|
||
;; Options for `modus-themes-diffs': nil, 'desaturated, 'bg-only
|
||
modus-themes-diffs 'desaturated
|
||
|
||
modus-themes-org-blocks 'gray-background ; {nil,'gray-background,'tinted-background}
|
||
|
||
modus-themes-org-agenda ; this is an alist: read the manual or its doc string
|
||
'((header-block . (variable-pitch 1.3))
|
||
(header-date . (grayscale workaholic bold-today 1.1))
|
||
(event . (accented varied))
|
||
(scheduled . uniform)
|
||
(habit . traffic-light))
|
||
|
||
modus-themes-headings ; this is an alist: read the manual or its doc string
|
||
'((1 . (overline background variable-pitch 1.3))
|
||
(2 . (rainbow overline 1.1))
|
||
(t . (semibold))))
|
||
#+end_src
|
||
|
||
** Option for inhibiting theme reload
|
||
:properties:
|
||
:alt_title: Custom reload theme
|
||
:description: Toggle auto-reload of the theme when setting custom variables
|
||
:custom_id: h:9001527a-4e2c-43e0-98e8-3ef72d770639
|
||
:end:
|
||
#+vindex: modus-themes-inhibit-reload
|
||
|
||
Brief: Toggle reloading of the active theme when an option is changed
|
||
through the Customize UI.
|
||
|
||
Symbol: ~modus-themes-inhibit-reload~ (=boolean= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~
|
||
2. ~t~ (default)
|
||
|
||
By default, customizing a theme-related user option through the Custom
|
||
interfaces or with {{{kbd(M-x customize-set-variable)}}} will not reload the
|
||
currently active Modus theme.
|
||
|
||
Enable this behavior by setting this variable to ~nil~.
|
||
|
||
Regardless of this option, the active theme must be reloaded for changes
|
||
to user options to take effect ([[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]).
|
||
|
||
** Option for red-green color deficiency or deuteranopia
|
||
:properties:
|
||
:alt_title: Deuteranopia style
|
||
:description: Toggle red/blue color-coding instead of red/green
|
||
:custom_id: h:3ed03a48-20d8-4ce7-b214-0eb7e4c79abe
|
||
:end:
|
||
#+vindex: modus-themes-deuteranopia
|
||
|
||
Brief: When non-~nil~ use red/blue color-coding instead of red/green,
|
||
where appropriate.
|
||
|
||
Symbol: ~modus-themes-deuteranopia~ (=boolean= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~t~
|
||
|
||
This is to account for red-green color deficiency, also know as
|
||
deuteranopia and variants. It applies to all contexts where there can
|
||
be a color-coded distinction between failure or success, a to-do or done
|
||
state, a mark for deletion versus a mark for selection (e.g. in Dired),
|
||
current and lazily highlighted search matches, removed lines in diffs as
|
||
opposed to added ones, and so on.
|
||
|
||
Note that this does not change all colors throughout the active theme,
|
||
but only applies to cases that have color-coding significance. For
|
||
example, regular code syntax highlighting is not affected. There is no
|
||
such need because of the themes' overarching commitment to the highest
|
||
legibility standard, which ensures that text is readable regardless of
|
||
hue, as well as the predominance of colors on the
|
||
blue-cyan-magenta-purple side of the spectrum.
|
||
|
||
[[#h:0b26cb47-9733-4cb1-87d9-50850cb0386e][Why are colors mostly variants of blue, magenta, cyan?]].
|
||
|
||
** Option for more bold constructs
|
||
:properties:
|
||
:alt_title: Bold constructs
|
||
:description: Toggle bold constructs in code
|
||
:custom_id: h:b25714f6-0fbe-41f6-89b5-6912d304091e
|
||
:end:
|
||
#+vindex: modus-themes-bold-constructs
|
||
|
||
Brief: Use bold for code syntax highlighting and related.
|
||
|
||
Symbol: ~modus-themes-bold-constructs~ (=boolean= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~t~
|
||
|
||
The default is to use a bold typographic weight only when it is
|
||
required.
|
||
|
||
With a non-~nil~ value (~t~) display several syntactic constructs in bold
|
||
weight. This concerns keywords and other important aspects of code
|
||
syntax. It also affects certain mode line indicators and command-line
|
||
prompts.
|
||
|
||
Advanced users may also want to configure the exact attributes of the
|
||
~bold~ face.
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
** Option for more italic constructs
|
||
:properties:
|
||
:alt_title: Italic constructs
|
||
:description: Toggle italic font constructs in code
|
||
:custom_id: h:977c900d-0d6d-4dbb-82d9-c2aae69543d6
|
||
:end:
|
||
#+vindex: modus-themes-italic-constructs
|
||
|
||
Brief: Use italics for code syntax highlighting and related.
|
||
|
||
Symbol: ~modus-themes-italic-constructs~ (=boolean= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~t~
|
||
|
||
The default is to not use slanted text forms (italics) unless it is
|
||
absolutely necessary.
|
||
|
||
With a non-~nil~ value (~t~) choose to render more faces in italics. This
|
||
typically affects documentation strings and code comments.
|
||
|
||
Advanced users may also want to configure the exact attributes of the
|
||
~italic~ face.
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
** Option for syntax highlighting
|
||
:properties:
|
||
:alt_title: Syntax styles
|
||
:description: Choose the overall aesthetic of code syntax
|
||
:custom_id: h:c119d7b2-fcd4-4e44-890e-5e25733d5e52
|
||
:end:
|
||
#+vindex: modus-themes-syntax
|
||
|
||
Brief: Set the overall style of code syntax highlighting.
|
||
|
||
Symbol: ~modus-themes-syntax~ (=choice= type, list of properties)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
+ ~faint~
|
||
+ ~yellow-comments~
|
||
+ ~green-strings~
|
||
+ ~alt-syntax~
|
||
|
||
The default (a ~nil~ value or an empty list) is to use a balanced
|
||
combination of colors on the cyan-blue-magenta side of the spectrum.
|
||
There is little to no use of greens, yellows, and reds. Comments are
|
||
gray, strings are blue colored, doc strings are a shade of cyan, while
|
||
color combinations are designed to avoid exaggerations.
|
||
|
||
The property ~faint~ fades the saturation of all applicable colors, where
|
||
that is possible or appropriate.
|
||
|
||
The property ~yellow-comments~ applies a yellow color to comments.
|
||
|
||
The property ~green-strings~ applies a green color to strings and a green
|
||
tint to doc strings.
|
||
|
||
The property ~alt-syntax~ changes the combination of colors beyond strings
|
||
and comments, so that the effective palette is broadened to provide
|
||
greater variety relative to the default.
|
||
|
||
Combinations of any of those properties are expressed as a list, like in
|
||
these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(faint)
|
||
(green-strings yellow-comments)
|
||
(alt-syntax green-strings yellow-comments)
|
||
(faint alt-syntax green-strings yellow-comments)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-syntax '(faint alt-syntax))
|
||
#+end_src
|
||
|
||
Independent of this variable, users may also control the use of a bold
|
||
weight or italic text: ~modus-themes-bold-constructs~ and
|
||
~modus-themes-italic-constructs~.
|
||
|
||
[[#h:b25714f6-0fbe-41f6-89b5-6912d304091e][Option for more bold constructs]].
|
||
|
||
[[#h:977c900d-0d6d-4dbb-82d9-c2aae69543d6][Option for more italic constructs]].
|
||
|
||
** Option for font mixing
|
||
:properties:
|
||
:alt_title: Mixed fonts
|
||
:description: Toggle mixing of font families
|
||
:custom_id: h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b
|
||
:end:
|
||
#+vindex: modus-themes-mixed-fonts
|
||
|
||
Brief: Toggle the use of monospaced fonts for spacing-sensitive
|
||
constructs (affects font families).
|
||
|
||
Symbol: ~modus-themes-mixed-fonts~ (=boolean= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~t~
|
||
|
||
When set to non-~nil~ (~t~), configure some spacing-sensitive faces like Org
|
||
tables and code blocks to always inherit from the ~fixed-pitch~ face.
|
||
This is to ensure that certain constructs like code blocks and tables
|
||
remain monospaced even when users opt for a mode that remaps typeface
|
||
families, such as the built-in {{{kbd(M-x variable-pitch-mode)}}}. Otherwise
|
||
the layout would appear broken, due to how spacing is done.
|
||
|
||
For a consistent experience, user may need to specify the font family of
|
||
the ~fixed-pitch~ face.
|
||
|
||
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
|
||
|
||
Furthermore, users may prefer to use another package for handling mixed
|
||
typeface configurations, rather than letting the theme do it, perhaps
|
||
because a purpose-specific package has extra functionality. Two
|
||
possible options are ~org-variable-pitch~ and ~mixed-pitch~.
|
||
|
||
** Option for links
|
||
:properties:
|
||
:alt_title: Link styles
|
||
:description: Choose among several styles, with or without underline
|
||
:custom_id: h:5808be52-361a-4d18-88fd-90129d206f9b
|
||
:end:
|
||
#+vindex: modus-themes-links
|
||
|
||
Brief: Control the style of links to web pages, files, buffers...
|
||
|
||
Symbol: ~modus-themes-links~ (=choice= type, list of properties)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
+ Underline style:
|
||
- ~neutral-underline~
|
||
- ~no-underline~
|
||
+ Text coloration:
|
||
- ~faint~
|
||
- ~no-color~
|
||
+ ~bold~
|
||
+ ~italic~
|
||
+ ~background~
|
||
|
||
The default (a ~nil~ value or an empty list) is a prominent text color,
|
||
typically blue, with an underline of the same color.
|
||
|
||
For the style of the underline, a ~neutral-underline~ property turns the
|
||
color of the line into a subtle gray, while the ~no-underline~ property
|
||
removes the line altogether. If both of those are set, the latter takes
|
||
precedence.
|
||
|
||
For text coloration, a ~faint~ property desaturates the color of the text
|
||
and the underline, unless the underline is affected by the
|
||
aforementioned properties. While a ~no-color~ property removes the color
|
||
from the text. If both of those are set, the latter takes precedence.
|
||
|
||
A ~bold~ property applies a heavy typographic weight to the text of the
|
||
link.
|
||
|
||
An ~italic~ property adds a slant to the link's text (italic or oblique
|
||
forms, depending on the typeface).
|
||
|
||
A ~background~ property applies a subtle tinted background color.
|
||
|
||
In case both ~no-underline~ and ~no-color~ are set, then a subtle gray
|
||
background is applied to all links. This can still be combined with the
|
||
~bold~ and ~italic~ properties.
|
||
|
||
Combinations of any of those properties are expressed as a list,
|
||
like in these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(faint)
|
||
(no-underline faint)
|
||
(no-color no-underline bold)
|
||
(italic bold background no-color no-underline)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-links '(neutral-underline background))
|
||
#+end_src
|
||
|
||
The placement of the underline, meaning its proximity to the text, is
|
||
controlled by ~x-use-underline-position-properties~,
|
||
~x-underline-at-descent-line~, ~underline-minimum-offset~. Please refer to
|
||
their documentation strings.
|
||
|
||
** Option for box buttons
|
||
:properties:
|
||
:alt_title: Box buttons
|
||
:description: Choose among several styles for buttons
|
||
:custom_id: h:8b85f711-ff40-45b0-b7fc-4727503cd2ec
|
||
:end:
|
||
#+vindex: modus-themes-box-buttons
|
||
|
||
Brief: Control the style of buttons in the Custom UI and related.
|
||
|
||
Symbol: ~modus-themes-box-buttons~ (=choice= type, list of properties)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
+ ~flat~
|
||
+ ~accented~
|
||
+ ~faint~
|
||
+ ~variable-pitch~
|
||
+ ~underline~
|
||
+ A font weight, which must be supported by the underlying typeface:
|
||
- ~thin~
|
||
- ~ultralight~
|
||
- ~extralight~
|
||
- ~light~
|
||
- ~semilight~
|
||
- ~regular~
|
||
- ~medium~
|
||
- ~semibold~
|
||
- ~bold~
|
||
- ~heavy~
|
||
- ~extrabold~
|
||
- ~ultrabold~
|
||
+ A floating point as a height multiple of the default or a cons cell in
|
||
the form of =(height . FLOAT)=
|
||
+ ~all-buttons~
|
||
|
||
The default (a ~nil~ value or an empty list) is a gray background
|
||
combined with a pseudo three-dimensional effect.
|
||
|
||
The ~flat~ property makes the button two dimensional.
|
||
|
||
The ~accented~ property changes the background from gray to an accent
|
||
color.
|
||
|
||
The ~faint~ property reduces the overall coloration.
|
||
|
||
The ~variable-pitch~ property applies a proportionately spaced typeface
|
||
to the button~s text.
|
||
|
||
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
|
||
|
||
The ~underline~ property draws a line below the affected text and
|
||
removes whatever box effect. This is optimal when Emacs runs inside a
|
||
terminal emulator ([[#h:fbb5e254-afd6-4313-bb05-93b3b4f67358][More accurate colors in terminal emulators]]). If
|
||
~flat~ and ~underline~ are defined together, the latter takes
|
||
precedence.
|
||
|
||
The symbol of a weight attribute adjusts the font of the button
|
||
accordingly, such as ~light~, ~semibold~, etc. Valid symbols are
|
||
defined in the variable ~modus-themes-weights~.
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
A number, expressed as a floating point (e.g. =0.9=), adjusts the height
|
||
of the button's text to that many times the base font size. The default
|
||
height is the same as =1.0=, though it need not be explicitly stated.
|
||
Instead of a floating point, an acceptable value can be in the form of a
|
||
cons cell like =(height . FLOAT)= or =(height FLOAT)=, where FLOAT is
|
||
the given number.
|
||
|
||
The ~all-buttons~ property extends the box button effect (or the
|
||
aforementioned properties) to the faces of the generic widget library.
|
||
By default, those do not look like the buttons of the Custom UI as they
|
||
are ordinary text wrapped in square brackets.
|
||
|
||
Combinations of any of those properties are expressed as a list,
|
||
like in these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(flat)
|
||
(variable-pitch flat)
|
||
(variable-pitch flat semibold 0.9)
|
||
(variable-pitch flat semibold (height 0.9)) ; same as above
|
||
(variable-pitch flat semibold (height . 0.9)) ; same as above
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-box-buttons '(variable-pitch flat 0.9))
|
||
#+end_src
|
||
|
||
** Option for command prompt styles
|
||
:properties:
|
||
:alt_title: Command prompts
|
||
:description: Choose among plain, subtle, or intense prompts
|
||
:custom_id: h:db5a9a7c-2928-4a28-b0f0-6f2b9bd52ba1
|
||
:end:
|
||
#+vindex: modus-themes-prompts
|
||
|
||
Brief: Control the style of command prompts (e.g. minibuffer, shell, IRC
|
||
clients).
|
||
|
||
Symbol: ~modus-themes-prompts~ (=choice= type, list of properties)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
+ ~background~
|
||
+ ~bold~
|
||
+ ~gray~
|
||
+ ~intense~
|
||
+ ~italic~
|
||
|
||
The default (a ~nil~ value or an empty list) means to only use a subtle
|
||
accented foreground color.
|
||
|
||
The property ~background~ applies a background color to the prompt's text.
|
||
By default, this is a subtle accented value.
|
||
|
||
The property ~intense~ makes the foreground color more prominent. If the
|
||
~background~ property is also set, it amplifies the value of the
|
||
background as well.
|
||
|
||
The property ~gray~ changes the prompt's colors to grayscale. This
|
||
affects the foreground and, if the ~background~ property is also set, the
|
||
background. Its effect is subtle, unless it is combined with the
|
||
~intense~ property.
|
||
|
||
The property ~bold~ makes the text use a bold typographic weight.
|
||
Similarly, ~italic~ adds a slant to the font's forms (italic or oblique
|
||
forms, depending on the typeface).
|
||
|
||
Combinations of any of those properties are expressed as a list, like in
|
||
these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(intense)
|
||
(bold intense)
|
||
(intense bold gray)
|
||
(intense background gray bold)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-prompts '(background gray))
|
||
#+end_src
|
||
|
||
** Option for mode line presentation
|
||
:properties:
|
||
:alt_title: Mode line
|
||
:description: Choose among several styles, with or without borders
|
||
:custom_id: h:27943af6-d950-42d0-bc23-106e43f50a24
|
||
:end:
|
||
#+vindex: modus-themes-mode-line
|
||
|
||
Brief: Control the style of the mode lines.
|
||
|
||
Symbol: ~modus-themes-mode-line~ (=choice= type, list of properties)
|
||
|
||
Possible values, which can be expressed as a list of combinations of box
|
||
effect, color, and border visibility:
|
||
+ Overall style:
|
||
- ~3d~
|
||
- ~moody~
|
||
+ ~accented~
|
||
+ ~borderless~
|
||
+ A natural number > 1 for extra padding or a cons cell in the form of ~(padding . NATNUM)~.
|
||
+ A floating point to set the height of the mode line's text. It can
|
||
also be a cons cell in the form of ~(height . FLOAT)~.
|
||
|
||
The default (a ~nil~ value or an empty list) is a two-dimensional
|
||
rectangle with a border around it. The active and the inactive mode
|
||
lines use different shades of grayscale values for the background,
|
||
foreground, border.
|
||
|
||
The ~3d~ property applies a three-dimensional effect to the active mode
|
||
line. The inactive mode lines remain two-dimensional and are toned down
|
||
a bit, relative to the default style.
|
||
|
||
The ~moody~ property optimizes the mode line for use with the library of
|
||
the same name (hereinafter referred to as 'Moody'). In practice, it
|
||
removes the box effect and replaces it with underline and overline
|
||
properties. It also tones down the inactive mode lines. Despite its
|
||
intended purpose, this option can also be used without the Moody library
|
||
(please consult the themes' manual on this point for more details). If
|
||
both ~3d~ and ~moody~ properties are set, the latter takes precedence.
|
||
|
||
The ~borderless~ property removes the color of the borders. It does not
|
||
actually remove the borders, but only makes their color the same as the
|
||
background, effectively creating some padding.
|
||
|
||
The ~accented~ property ensures that the active mode line uses a colored
|
||
background instead of the standard shade of gray.
|
||
|
||
A positive integer (natural number or natnum) applies a padding effect
|
||
of NATNUM pixels at the boundaries of the mode lines. The default value
|
||
is 1 and does not need to be specified explicitly. The padding has no
|
||
effect when the ~moody~ property is also used, because Moody already
|
||
applies its own tweaks. To ensure that the underline is placed at the
|
||
bottom of the mode line, set ~x-underline-at-descent-line~ to non-~nil~
|
||
(this is not needed when the ~borderless~ property is also set). For
|
||
users on Emacs 29, the ~x-use-underline-position-properties~ variable must
|
||
also be set to nil.
|
||
|
||
The padding can also be expressed as a cons cell in the form of
|
||
=(padding . NATNUM)= or =(padding NATNUM)= where the key is constant and
|
||
NATNUM is the desired natural number.
|
||
|
||
A floating point applies an adjusted height to the mode line's text as a
|
||
multiple of the main font size. The default rate is 1.0 and does not
|
||
need to be specified. Apart from a floating point, the height may also
|
||
be expressed as a cons cell in the form of =(height . FLOAT)= or
|
||
=(height FLOAT)= where the key is constant and the FLOAT is the desired
|
||
number.
|
||
|
||
Combinations of any of those properties are expressed as a list, like in
|
||
these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(accented)
|
||
(borderless 3d)
|
||
(moody accented borderless)
|
||
#+end_src
|
||
|
||
Same as above, using the padding and height as an example (these
|
||
all yield the same result):
|
||
|
||
#+begin_src emacs-lisp
|
||
(accented borderless 4 0.9)
|
||
(accented borderless (padding . 4) (height . 0.9))
|
||
(accented borderless (padding 4) (height 0.9))
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-mode-line '(borderless accented))
|
||
#+end_src
|
||
|
||
Note that Moody does not expose any faces that the themes could style
|
||
directly. Instead it re-purposes existing ones to render its tabs and
|
||
ribbons. As such, there may be cases where the contrast ratio falls
|
||
below the 7:1 target that the themes conform with (WCAG AAA). To hedge
|
||
against this, we configure a fallback foreground for the ~moody~ property,
|
||
which will come into effect when the background of the mode line changes
|
||
to something less accessible, such as Moody ribbons (read the doc string
|
||
of ~set-face-attribute~, specifically ~:distant-foreground~). This fallback
|
||
is activated when Emacs determines that the background and foreground of
|
||
the given construct are too close to each other in terms of color
|
||
distance. In practice, users will need to experiment with the variable
|
||
~face-near-same-color-threshold~ to trigger the effect. We find that a
|
||
value of =45000= shall suffice, contrary to the default =30000=. Though for
|
||
the combinations that involve the ~accented~ and ~moody~ properties, as
|
||
mentioned above, that should be raised up to =70000=. Do not set it too
|
||
high, because it has the adverse effect of always overriding the default
|
||
colors (which have been carefully designed to be highly accessible).
|
||
|
||
Furthermore, because Moody expects an underline and overline instead of
|
||
a box style, it is strongly advised to set ~x-underline-at-descent-line~
|
||
to a non-~nil~ value.
|
||
|
||
Finally, note that various packages which heavily modify the mode line,
|
||
such as =doom-modeline=, =nano-modeline=, =powerline=, =spaceline= may not look
|
||
as intended with all possible combinations of this user option.
|
||
|
||
** Option for accented background in tab interfaces
|
||
:properties:
|
||
:alt_title: Tab style
|
||
:description: Toggle accented background for tabs
|
||
:custom_id: h:27cef8f5-dc4e-4c93-ba41-b899e650d936
|
||
:end:
|
||
#+vindex: modus-themes-tabs-accented
|
||
|
||
Brief: Toggle accent colors for tabbed interfaces.
|
||
|
||
Symbol: ~modus-themes-tabs-accented~ (=boolean= type)
|
||
|
||
Possible values:
|
||
+ ~nil~ (default)
|
||
+ ~t~
|
||
|
||
By default, all tab interfaces use backgrounds which are shades of gray.
|
||
When this option is set to non-~nil~, the backgrounds become colorful.
|
||
|
||
This affects the built-in ~tab-bar-mode~ and ~tab-line-mode~, as well as the
|
||
Centaur tabs package.
|
||
|
||
** Option for completion framework aesthetics
|
||
:properties:
|
||
:alt_title: Completion UIs
|
||
:description: Choose among several styles for completion UIs
|
||
:custom_id: h:f1c20c02-7b34-4c35-9c65-99170efb2882
|
||
:end:
|
||
#+vindex: modus-themes-completions
|
||
|
||
Brief: Set the overall style of completion framework interfaces.
|
||
|
||
Symbol: ~modus-themes-completions~ (=alist= type properties)
|
||
|
||
This affects Company, Corfu, Flx, Helm, Icomplete/Fido, Ido, Ivy,
|
||
Orderless, Selectrum, Vertico. The value is an alist that takes the
|
||
form of a =(KEY . PROPERTIES)= combination. =KEY= is a symbol, while
|
||
=PROPERTIES= is a list. Here is a sample, followed by a description
|
||
of the particularities:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-completions
|
||
'((matches . (extrabold background intense))
|
||
(selection . (semibold accented intense))
|
||
(popup . (accented))))
|
||
#+end_src
|
||
|
||
The ~matches~ key refers to the highlighted characters that correspond
|
||
to the user's input. When its properties are ~nil~ or an empty list,
|
||
matching characters in the user interface will have a bold weight and
|
||
a colored foreground. The list of properties may include any of the
|
||
following symbols regardless of the order they may appear in:
|
||
|
||
- ~background~ to add a background color;
|
||
|
||
- ~intense~ to increase the overall coloration (also amplifies
|
||
the ~background~, if present);
|
||
|
||
- ~underline~ to draw a line below the characters;
|
||
|
||
- ~italic~ to use a slanted font (italic or oblique forms);
|
||
|
||
- The symbol of a font weight attribute such as ~light~, ~semibold~, et
|
||
cetera. Valid symbols are defined in the ~modus-themes-weights~
|
||
variable. The absence of a weight means that bold will be used.
|
||
|
||
The ~selection~ key applies to the current line or currently matched
|
||
candidate, depending on the specifics of the user interface. When its
|
||
properties are ~nil~ or an empty list, it has a subtle gray background,
|
||
a bold weight, and the base foreground value for the text. The list
|
||
of properties it accepts is as follows (order is not significant):
|
||
|
||
- ~accented~ to make the background colorful instead of gray;
|
||
|
||
- ~text-also~ to apply extra color to the text of the selected line;
|
||
|
||
- ~intense~ to increase the overall coloration;
|
||
|
||
- ~underline~ to draw a line below the characters;
|
||
|
||
- ~italic~ to use a slanted font (italic or oblique forms);
|
||
|
||
- The symbol of a font weight attribute such as ~light~, ~semibold~, et
|
||
cetera. Valid symbols are defined in the ~modus-themes-weights~
|
||
variable. The absence of a weight means that bold will be used.
|
||
|
||
The ~popup~ key takes the same values as ~selection~. The only
|
||
difference is that it applies specifically to user interfaces that
|
||
display an inline popup and thus have slightly different styling
|
||
requirements than the minibuffer. The two prominent packages are
|
||
=company= and =corfu=.
|
||
|
||
Apart from specifying each key separately, a fallback list is accepted.
|
||
This is only useful when the desired aesthetic is the same across all
|
||
keys that are not explicitly referenced. For example, this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-completions
|
||
'((t . (extrabold intense))))
|
||
#+end_src
|
||
|
||
Is the same as:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-completions
|
||
'((matches . (extrabold intense))
|
||
(selection . (extrabold intense))
|
||
(popup . (extrabold intense))))
|
||
#+end_src
|
||
|
||
In the case of the fallback, any property that does not apply to the
|
||
corresponding key is simply ignored (~matches~ does not have ~accented~
|
||
and ~text-also~, while ~selection~ and ~popup~ do not have
|
||
~background~).
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
Also refer to the documentation of the ~orderless~ package for its
|
||
intersection with ~company~ (if you choose to use those in tandem).
|
||
|
||
** Option for mail citations
|
||
:properties:
|
||
:alt_title: Mail citations
|
||
:description: Choose among colorful, desaturated, monochrome citations
|
||
:custom_id: h:5a12765d-0ba0-4a75-ab11-e35d3bbb317d
|
||
:end:
|
||
#+vindex: modus-themes-mail-citations
|
||
|
||
Brief: Set the overall style of citations/quotes when composing
|
||
emails.
|
||
|
||
Symbol: ~modus-themes-mail-citations~ (=choice= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~intense~
|
||
3. ~faint~
|
||
4. ~monochrome~
|
||
|
||
By default (a ~nil~ value) citations are styled with contrasting hues to
|
||
denote their depth. Colors are easy to tell apart because they
|
||
complement each other, but they otherwise are not very prominent.
|
||
|
||
Option ~intense~ is similar to the default in terms of using contrasting
|
||
and complementary hues, but applies more saturated colors.
|
||
|
||
Option ~faint~ maintains the same color-based distinction between citation
|
||
levels though the colors it uses have subtle differences between them.
|
||
|
||
Option ~monochrome~ turns all quotes into a shade of gray.
|
||
|
||
Whatever the value assigned to this variable, citations in emails are
|
||
controlled by typographic elements or indentation, which the themes do
|
||
not touch.
|
||
|
||
** Option for fringe visibility
|
||
:properties:
|
||
:alt_title: Fringes
|
||
:description: Choose among invisible, subtle, or intense fringe styles
|
||
:custom_id: h:1983c3fc-74f6-44f3-b917-967c403bebae
|
||
:end:
|
||
#+vindex: modus-themes-fringes
|
||
|
||
Brief: Control the overall coloration of the fringes.
|
||
|
||
Symbol: ~modus-themes-fringes~ (=choice= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~
|
||
2. ~subtle~
|
||
3. ~intense~
|
||
|
||
When the value is nil, do not apply a distinct background color.
|
||
|
||
With a value of ~subtle~ use a gray background color that is
|
||
visible yet close to the main background color.
|
||
|
||
With ~intense~ use a more pronounced gray background color.
|
||
|
||
** Option for language checkers
|
||
:properties:
|
||
:alt_title: Language checkers
|
||
:description: Control the style of language checkers/linters
|
||
:custom_id: h:4b13743a-8ebf-4d2c-a043-cceba10b1eb4
|
||
:end:
|
||
#+vindex: modus-themes-lang-checkers
|
||
|
||
Brief: Control the style of in-buffer warnings and errors produced by
|
||
spell checkers, code linters, and the like.
|
||
|
||
Symbol: ~modus-themes-lang-checkers~ (=choice= type, list of properties)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
+ ~straight-underline~
|
||
+ ~text-also~
|
||
+ ~background~
|
||
+ Overall coloration:
|
||
- ~intense~
|
||
- ~faint~
|
||
|
||
The default (a ~nil~ value or an empty list) applies a color-coded
|
||
underline to the affected text, while it leaves the original foreground
|
||
intact. If the display spec of Emacs has support for it, the
|
||
underline's style is that of a wave, otherwise it is a straight line.
|
||
|
||
The property ~straight-underline~ ensures that the underline under the
|
||
affected text is always drawn as a straight line.
|
||
|
||
The property ~text-also~ applies the same color of the underline to the
|
||
affected text.
|
||
|
||
The property ~background~ adds a color-coded background.
|
||
|
||
The property ~intense~ amplifies the applicable colors if ~background~
|
||
and/or ~text-also~ are set. If ~intense~ is set on its own, then it implies
|
||
~text-also~.
|
||
|
||
The property ~faint~ uses nuanced colors for the underline and for the
|
||
foreground when ~text-also~ is included. If both ~faint~ and ~intense~ are
|
||
specified, the former takes precedence.
|
||
|
||
Combinations of any of those properties can be expressed in a list, as
|
||
in those examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(background)
|
||
(straight-underline intense)
|
||
(background text-also straight-underline)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-lang-checkers '(text-also background))
|
||
#+end_src
|
||
|
||
NOTE: The placement of the straight underline, though not the wave
|
||
style, is controlled by the built-in variables ~underline-minimum-offset~,
|
||
~x-underline-at-descent-line~, ~x-use-underline-position-properties~.
|
||
|
||
To disable fringe indicators for Flymake or Flycheck, refer to variables
|
||
~flymake-fringe-indicator-position~ and ~flycheck-indication-mode~,
|
||
respectively.
|
||
|
||
** Option for line highlighting
|
||
:properties:
|
||
:alt_title: Line highlighting
|
||
:description: Choose style of current line (hl-line-mode)
|
||
:custom_id: h:1dba1cfe-d079-4c13-a810-f768e8789177
|
||
:end:
|
||
#+vindex: modus-themes-hl-line
|
||
|
||
Brief: Control the style of the current line of ~hl-line-mode~.
|
||
|
||
Symbol: ~modus-themes-hl-line~ (=choice= type, list of properties)
|
||
|
||
The value is a list of properties, each designated by a symbol. With
|
||
a ~nil~ value, or an empty list, the style is a subtle gray background
|
||
color.
|
||
|
||
Possible properties are the following symbols:
|
||
+ ~accented~
|
||
+ ~intense~
|
||
+ ~underline~
|
||
|
||
The property ~accented~ changes the background to a colored variant.
|
||
|
||
An ~underline~ property draws a line below the highlighted area. Its
|
||
color is similar to the background, so gray by default or an accent
|
||
color when ~accented~ is also set.
|
||
|
||
An ~intense~ property amplifies the colors in use, which may be both the
|
||
background and the underline.
|
||
|
||
Combinations of any of those properties are expressed as a list, like in
|
||
these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(intense)
|
||
(underline intense)
|
||
(accented intense underline)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-hl-line '(underline accented))
|
||
#+end_src
|
||
|
||
Set ~x-underline-at-descent-line~ to a non-~nil~ value so that the
|
||
placement of the underline coincides with the lower boundary of the
|
||
colored background.
|
||
|
||
This style affects several packages that enable ~hl-line-mode~, such as
|
||
=elfeed=, =notmuch=, and =mu4e=.
|
||
|
||
[ Also check the =lin= package on GNU ELPA (by the author of the
|
||
modus-themes) for a stylistic enhancement to ~hl-line-mode~. ]
|
||
|
||
** Option for line numbers
|
||
:properties:
|
||
:alt_title: Line numbers
|
||
:description: Toggle subtle style for line numbers
|
||
:custom_id: h:8c4a6230-2e43-4aa2-a631-3b7179392e09
|
||
:end:
|
||
#+vindex: modus-themes-subtle-line-numbers
|
||
|
||
Brief: Toggle subtle line numbers.
|
||
|
||
Symbol: ~modus-themes-subtle-line-numbers~ (=boolean= type)
|
||
|
||
Possible value:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~t~
|
||
|
||
The default style for ~display-line-numbers-mode~ and its global variant
|
||
is to apply a subtle gray background to the line numbers. The current
|
||
line has a more pronounced background and foreground combination to
|
||
bring more attention to itself.
|
||
|
||
Similarly, the faces for ~display-line-numbers-major-tick~ and its
|
||
counterpart ~display-line-numbers-minor-tick~ use appropriate styles that
|
||
involve a bespoke background and foreground combination.
|
||
|
||
With a non-~nil~ value (~t~), line numbers have no background of their own.
|
||
Instead they retain the primary background of the theme, blending with
|
||
the rest of the buffer. Foreground values for all relevant faces are
|
||
updated to accommodate this aesthetic.
|
||
|
||
** Option for mouseover effects
|
||
:properties:
|
||
:alt_title: Mouse hover effects
|
||
:description: Toggle intense style for mouseover highlights
|
||
:custom_id: h:9b869620-fcc5-4b5f-9ab8-225d73b7f22f
|
||
:end:
|
||
#+vindex: modus-themes-intense-mouseovers
|
||
|
||
Brief: Toggle intense mouse hover effects.
|
||
|
||
Symbol: ~modus-themes-intense-mouseovers~ (=boolean= type)
|
||
|
||
Possible value:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~t~
|
||
|
||
By default all mouseover effects apply a highlight with a subtle colored
|
||
background. When non-~nil~, these have a more pronounced effect.
|
||
|
||
Note that this affects the generic ~highlight~ which, strictly speaking,
|
||
is not limited to mouse usage.
|
||
|
||
** Option for markup style in Org and others
|
||
:properties:
|
||
:alt_title: Markup
|
||
:description: Choose style for markup in Org and others
|
||
:custom_id: h:9d9a4e64-99ac-4018-8f66-3051b9c43fd7
|
||
:end:
|
||
#+vindex: modus-themes-markup
|
||
|
||
Brief: Choose style of markup in Org, Markdown, and others (affects
|
||
constructs such as Org's ==verbatim== and =~code~=).
|
||
|
||
Symbol: ~modus-themes-markup~ (=boolean= type)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
|
||
1. ~bold~
|
||
2. ~italic~
|
||
3. ~background~
|
||
4. ~intense~
|
||
|
||
The ~italic~ property applies a typographic slant (italics).
|
||
|
||
The ~bold~ property applies a heavier typographic weight.
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
The ~background~ property adds a background color. The background is a
|
||
shade of gray, unless the ~intense~ property is also set.
|
||
|
||
The ~intense~ property amplifies the existing coloration. When
|
||
~background~ is used, the background color is enhanced as well and
|
||
becomes tinted instead of being gray.
|
||
|
||
Combinations of any of those properties are expressed as a list,
|
||
like in these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(bold)
|
||
(bold italic)
|
||
(bold italic intense)
|
||
(bold italic intense background)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-markup '(bold italic))
|
||
#+end_src
|
||
|
||
Also check the variables ~org-hide-emphasis-markers~,
|
||
~org-hide-macro-markers~.
|
||
|
||
** Option for parenthesis matching
|
||
:properties:
|
||
:alt_title: Matching parentheses
|
||
:description: Choose between various styles for matching delimiters/parentheses
|
||
:custom_id: h:e66a7e4d-a512-4bc7-9f86-fbbb5923bf37
|
||
:end:
|
||
#+vindex: modus-themes-paren-match
|
||
|
||
Brief: Control the style of matching delimiters produced by
|
||
~show-paren-mode~.
|
||
|
||
Symbol: ~modus-themes-paren-match~ (=choice= type, list of properties)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
+ ~bold~
|
||
+ ~intense~
|
||
+ ~underline~
|
||
|
||
The default (a ~nil~ value or an empty list) is a subtle background color.
|
||
|
||
The ~bold~ property adds a bold weight to the characters of the matching
|
||
delimiters.
|
||
|
||
The ~intense~ property applies a more prominent background color to the
|
||
delimiters.
|
||
|
||
The ~underline~ property draws a straight line under the affected text.
|
||
|
||
Combinations of any of those properties are expressed as a list, like in
|
||
these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(bold)
|
||
(underline intense)
|
||
(bold intense underline)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-paren-match '(bold intense))
|
||
#+end_src
|
||
|
||
This customization variable affects the built-in ~show-paren-mode~ and the
|
||
=smartparens= package.
|
||
|
||
** Option for active region
|
||
:properties:
|
||
:alt_title: Active region
|
||
:description: Choose between various styles for the active region
|
||
:custom_id: h:60798063-b4ad-45ea-b9a7-ff7b5c0ab74c
|
||
:end:
|
||
#+vindex: modus-themes-region
|
||
|
||
Brief: Control the style of the region.
|
||
|
||
Symbol: ~modus-themes-region~ (=choice= type, list of properties)
|
||
|
||
Possible values are expressed as a list of properties (default is ~nil~ or
|
||
an empty list). The list can include any of the following symbols:
|
||
+ ~no-extend~
|
||
+ ~bg-only~
|
||
+ ~accented~
|
||
|
||
The default (a ~nil~ value or an empty list) is a prominent gray
|
||
background that overrides all foreground colors in the area it
|
||
encompasses. Its reach extends to the edge of the window.
|
||
|
||
The ~no-extend~ property limits the region to the end of the line, so that
|
||
it does not reach the edge of the window.
|
||
|
||
The ~bg-only~ property makes the region's background color more subtle to
|
||
allow the underlying text to retain its foreground colors.
|
||
|
||
The ~accented~ property applies a more colorful background to the region.
|
||
|
||
Combinations of any of those properties are expressed as a list, like in
|
||
these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(no-extend)
|
||
(bg-only accented)
|
||
(accented bg-only no-extend)
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-region '(bg-only no-extend))
|
||
#+end_src
|
||
|
||
** Option for diff buffer looks
|
||
:properties:
|
||
:alt_title: Diffs
|
||
:description: Choose among intense, desaturated, or background-only diffs
|
||
:custom_id: h:ea7ac54f-5827-49bd-b09f-62424b3b6427
|
||
:end:
|
||
#+vindex: modus-themes-diffs
|
||
|
||
Brief: Set the overall style of diffs.
|
||
|
||
Symbol: ~modus-themes-diffs~ (=choice= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~desaturated~
|
||
3. ~bg-only~
|
||
|
||
The default (~nil~) uses fairly intense color combinations for diffs, by
|
||
applying prominently colored backgrounds, with appropriately tinted
|
||
foregrounds.
|
||
|
||
Option ~desaturated~ follows the same principles as with the default
|
||
(~nil~), though it tones down all relevant colors.
|
||
|
||
Option ~bg-only~ applies a background but does not override the text's
|
||
foreground. This makes it suitable for a non-~nil~ value passed to
|
||
~diff-font-lock-syntax~ (note: Magit does not support syntax highlighting
|
||
in diffs---last checked on 2021-12-02).
|
||
|
||
When the user option ~modus-themes-deuteranopia~ is non-~nil~, all diffs
|
||
will use a red/blue color-coding system instead of the standard
|
||
red/green. Other stylistic changes are made in the interest of
|
||
optimizing for such a use-case.
|
||
|
||
[[#h:3ed03a48-20d8-4ce7-b214-0eb7e4c79abe][Option for red-green color deficiency or deuteranopia]].
|
||
|
||
In versions before =2.0.0= there was an option for foreground-only diffs.
|
||
This is no longer supported at the theme level because there are cases
|
||
where the perceived contrast and overall contextuality were not good
|
||
enough although the applied colors were technically above the 7:1
|
||
contrast threshold.
|
||
|
||
[[#h:e2aed9eb-5e1e-45ec-bbd7-bc4faeab3236][Diffs with only the foreground]].
|
||
|
||
[[#h:b0b31802-0216-427e-b071-1a47adcfe608][Ediff without diff color-coding]].
|
||
|
||
** Option for org-mode block styles
|
||
:properties:
|
||
:alt_title: Org mode blocks
|
||
:description: Choose among plain, gray, or tinted backgrounds
|
||
:custom_id: h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2
|
||
:end:
|
||
#+vindex: modus-themes-org-blocks
|
||
|
||
Brief: Set the overall style of Org code blocks, quotes, and the like.
|
||
|
||
Symbol: ~modus-themes-org-blocks~ (=choice= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~gray-background~ (value ~grayscale~ exists for backward compatibility)
|
||
3. ~tinted-background~ (value ~rainbow~ exists for backward compatibility)
|
||
|
||
Nil (the default) means that the block has no background of its own: it
|
||
uses the one that applies to the rest of the buffer. In this case, the
|
||
delimiter lines have a gray color for their text, making them look
|
||
exactly like all other Org properties.
|
||
|
||
Option ~gray-background~ applies a subtle gray background to the block's
|
||
contents. It also affects the begin and end lines of the block as they
|
||
get another shade of gray as their background, which differentiates them
|
||
from the contents of the block. All background colors extend to the
|
||
edge of the window, giving the area a rectangular, "blocky"
|
||
presentation.
|
||
|
||
Option ~tinted-background~ uses a slightly colored background for the
|
||
contents of the block. The exact color will depend on the programming
|
||
language and is controlled by the variable ~org-src-block-faces~ (refer to
|
||
the theme's source code for the current association list). For this to
|
||
take effect, the Org buffer needs to be restarted with ~org-mode-restart~.
|
||
In this scenario, it may be better to inhibit the extension of the
|
||
delimiter lines' background to the edge of the window because Org does
|
||
not provide a mechanism to update their colors depending on the contents
|
||
of the block. Disable the extension of such backgrounds by setting
|
||
~org-fontify-whole-block-delimiter-line~ to nil.
|
||
|
||
Code blocks use their major mode's colors only when the variable
|
||
~org-src-fontify-natively~ is non-~nil~. While quote/verse blocks require
|
||
setting ~org-fontify-quote-and-verse-blocks~ to a non-~nil~ value.
|
||
|
||
[[#h:f44cc6e3-b0f1-4a5e-8a90-9e48fa557b50][Update Org block delimiter fontification]].
|
||
|
||
Older versions of the themes provided options ~grayscale~ (or ~greyscale~)
|
||
and ~rainbow~. Those will continue to work as they are aliases for
|
||
~gray-background~ and ~tinted-background~, respectively.
|
||
|
||
** Option for Org agenda constructs
|
||
:properties:
|
||
:alt_title: Org agenda
|
||
:description: Control each element in the presentation of the agenda
|
||
:custom_id: h:68f481bc-5904-4725-a3e6-d7ecfa7c3dbc
|
||
:end:
|
||
#+vindex: modus-themes-org-agenda
|
||
|
||
Brief: Control the style of the Org agenda. Multiple parameters are
|
||
available, each with its own options.
|
||
|
||
Symbol: ~modus-themes-org-agenda~ (=alist= type, multiple styles)
|
||
|
||
This is an alist that accepts a =(key . value)= combination. Some values
|
||
are specified as a list. Here is a sample, followed by a description of
|
||
all possible combinations:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-org-agenda
|
||
'((header-block . (variable-pitch 1.5))
|
||
(header-date . (grayscale workaholic bold-today 1.2))
|
||
(event . (accented italic varied))
|
||
(scheduled . uniform)
|
||
(habit . traffic-light)))
|
||
#+end_src
|
||
|
||
A ~header-block~ key applies to elements that concern the headings which
|
||
demarcate blocks in the structure of the agenda. By default (a ~nil~
|
||
value) those are rendered in a bold typographic weight, plus a height
|
||
that is slightly taller than the default font size. Acceptable values
|
||
come in the form of a list that can include either or both of those
|
||
properties:
|
||
|
||
- ~variable-pitch~ to use a proportionately spaced typeface;
|
||
|
||
- A number as a floating point (e.g. 1.5) to set the height of the text
|
||
to that many times the default font height. A float of 1.0 or the
|
||
symbol ~no-scale~ have the same effect of making the font the same
|
||
height as the rest of the buffer. When neither a number nor
|
||
`no-scale' are present, the default is a small increase in height (a
|
||
value of 1.15).
|
||
|
||
Instead of a floating point, an acceptable value can be in the form of
|
||
a cons cell like =(height . FLOAT)= or =(height FLOAT)=, where FLOAT
|
||
is the given number.
|
||
|
||
- The symbol of a weight attribute adjusts the font of the heading
|
||
accordingly, such as ~light~, ~semibold~, etc. Valid symbols are
|
||
defined in the variable ~modus-themes-weights~. The absence of a
|
||
weight means that bold will be used by virtue of inheriting the ~bold~
|
||
face.
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
In case both a number and ~no-scale~ are in the list, the latter takes
|
||
precedence. If two numbers are specified, the first one is applied.
|
||
|
||
Example usage:
|
||
|
||
#+begin_src emacs-lisp
|
||
(header-block . nil)
|
||
(header-block . (1.5))
|
||
(header-block . (no-scale))
|
||
(header-block . (variable-pitch 1.5))
|
||
(header-block . (variable-pitch 1.5 semibold))
|
||
#+end_src
|
||
|
||
A ~header-date~ key covers date headings. Dates use only a foreground
|
||
color by default (a ~nil~ value), with weekdays and weekends having a
|
||
slight difference in hueness. The current date has an added gray
|
||
background. This key accepts a list of values that can include any of
|
||
the following properties:
|
||
|
||
- ~grayscale~ to make weekdays use the main foreground color and
|
||
weekends a more subtle gray;
|
||
|
||
- ~workaholic~ to make weekdays and weekends look the same in
|
||
terms of color;
|
||
|
||
- ~bold-today~ to apply a bold typographic weight to the current
|
||
date;
|
||
|
||
- ~bold-all~ to render all date headings in a bold weight;
|
||
|
||
- ~underline-today~ applies an underline to the current date while
|
||
removing the background it has by default;
|
||
|
||
- A number as a floating point (e.g. 1.2) to set the height of the text
|
||
to that many times the default font height. The default is the same
|
||
as the base font height (the equivalent of 1.0). Instead of a
|
||
floating point, an acceptable value can be in the form of a cons cell
|
||
like =(height . FLOAT)= or =(height FLOAT)=, where FLOAT is the given
|
||
number.
|
||
|
||
For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(header-date . nil)
|
||
(header-date . (workaholic))
|
||
(header-date . (grayscale bold-all))
|
||
(header-date . (grayscale workaholic))
|
||
(header-date . (grayscale workaholic bold-today))
|
||
(header-date . (grayscale workaholic bold-today scale-heading))
|
||
#+end_src
|
||
|
||
An ~event~ key covers (i) headings with a plain time stamp that are
|
||
shown on the agenda, also known as events, (ii) entries imported from
|
||
the diary, and (iii) other items that derive from a symbolic expression
|
||
or sexp (phases of the moon, holidays, etc.). By default all those look
|
||
the same and have a subtle foreground color (the default is a ~nil~ value
|
||
or an empty list). This key accepts a list of properties. Those are:
|
||
|
||
- ~accented~ applies an accent value to the event's foreground,
|
||
replacing the original gray. It makes all entries stand out more.
|
||
- ~italic~ adds a slant to the font's forms (italic or oblique forms,
|
||
depending on the typeface).
|
||
- ~varied~ differentiates between events with a plain time stamp and
|
||
entries that are generated from either the diary or a symbolic
|
||
expression. It generally puts more emphasis on events. When ~varied~
|
||
is combined with ~accented~, it makes only events use an accent color,
|
||
while diary/sexp entries retain their original subtle foreground.
|
||
When ~varied~ is used in tandem with ~italic~, it applies a slant only
|
||
to diary and sexp entries, not events. And when ~varied~ is the sole
|
||
property passed to the ~event~ key, it has the same meaning as the
|
||
list (italic varied). The combination of ~varied~, ~accented~, ~italic~ covers all of the aforementioned cases.
|
||
|
||
For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(event . nil)
|
||
(event . (italic))
|
||
(event . (accented italic))
|
||
(event . (accented italic varied))
|
||
#+end_src
|
||
|
||
A ~scheduled~ key applies to tasks with a scheduled date. By default (a
|
||
~nil~ value), those use varying shades of yellow to denote (i) a past or
|
||
current date and (ii) a future date. Valid values are symbols:
|
||
|
||
- ~nil~ (default);
|
||
- ~uniform~ to make all scheduled dates the same color;
|
||
- ~rainbow~ to use contrasting colors for past, present, future
|
||
scheduled dates.
|
||
|
||
For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(scheduled . nil)
|
||
(scheduled . uniform)
|
||
(scheduled . rainbow)
|
||
#+end_src
|
||
|
||
A ~habit~ key applies to the ~org-habit~ graph. All possible value are
|
||
passed as a symbol. Those are:
|
||
|
||
- The default (~nil~) is meant to conform with the original aesthetic of ~org-habit~. It employs all four color codes that correspond to the
|
||
org-habit states---clear, ready, alert, and overdue---while
|
||
distinguishing between their present and future variants. This
|
||
results in a total of eight colors in use: red, yellow, green, blue,
|
||
in tinted and shaded versions. They cover the full set of information
|
||
provided by the ~org-habit~ consistency graph.
|
||
- ~simplified~ is like the default except that it removes the dichotomy
|
||
between current and future variants by applying uniform color-coded
|
||
values. It applies a total of four colors: red, yellow, green, blue.
|
||
They produce a simplified consistency graph that is more legible (or
|
||
less busy) than the default. The intent is to shift focus towards the
|
||
distinction between the four states of a habit task, rather than each
|
||
state's present/future outlook.
|
||
- ~traffic-light~ further reduces the available colors to red, yellow, and
|
||
green. As in ~simplified~, present and future variants appear
|
||
uniformly, but differently from it, the ~clear~ state is rendered in a
|
||
green hue, instead of the original blue. This is meant to capture the
|
||
use-case where a habit task being too early is less important than it
|
||
being too late. The difference between ready and clear states is
|
||
attenuated by painting both of them using shades of green. This
|
||
option thus highlights the alert and overdue states.
|
||
- When ~modus-themes-deuteranopia~ is non-~nil~ the exact style of the habit
|
||
graph adapts to the needs of users with red-green color deficiency by
|
||
substituting every instance of green with blue or cyan (depending on
|
||
the specifics).
|
||
|
||
[[#h:3ed03a48-20d8-4ce7-b214-0eb7e4c79abe][Option for red-green color deficiency or deuteranopia]].
|
||
|
||
For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(habit . nil)
|
||
(habit . simplified)
|
||
(habit . traffic-light)
|
||
#+end_src
|
||
|
||
Putting it all together, the alist can look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
'((header-block . (1.5 variable-pitch))
|
||
(header-date . (grayscale workaholic bold-today))
|
||
(event . (accented varied))
|
||
(scheduled . uniform)
|
||
(habit . traffic-light))
|
||
|
||
;; Or else:
|
||
(setq modus-themes-org-agenda
|
||
'((header-block . (1.5 variable-pitch))
|
||
(header-date . (grayscale workaholic bold-today))
|
||
(event . (accented varied))
|
||
(scheduled . uniform)
|
||
(habit . traffic-light)))
|
||
#+end_src
|
||
|
||
** Option for the headings' overall style
|
||
:properties:
|
||
:alt_title: Heading styles
|
||
:description: Choose among several styles, also per heading level
|
||
:custom_id: h:271eff19-97aa-4090-9415-a6463c2f9ae1
|
||
:end:
|
||
#+vindex: modus-themes-headings
|
||
|
||
Brief: Heading styles with optional list of values for levels 0-8.
|
||
|
||
Symbol: ~modus-themes-headings~ (=alist= type, multiple properties)
|
||
|
||
This is an alist that accepts a =(key . list-of-values)= combination.
|
||
The key is either a number, representing the heading's level (0-8) or t,
|
||
which pertains to the fallback style.
|
||
|
||
Level 0 is a special heading: it is used for what counts as a document
|
||
title or equivalent, such as the =#+title= construct we find in Org
|
||
files. Levels 1-8 are regular headings.
|
||
|
||
The list of values covers symbols that refer to properties, as described
|
||
below. Here is a complete sample, followed by a presentation of all
|
||
available properties:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-headings
|
||
'((1 . (background overline variable-pitch 1.5))
|
||
(2 . (overline rainbow 1.3))
|
||
(3 . (overline 1.1))
|
||
(t . (monochrome))))
|
||
#+end_src
|
||
|
||
Properties:
|
||
+ ~rainbow~
|
||
+ ~overline~
|
||
+ ~background~
|
||
+ ~monochrome~
|
||
+ A font weight, which must be supported by the underlying typeface:
|
||
- ~thin~
|
||
- ~ultralight~
|
||
- ~extralight~
|
||
- ~light~
|
||
- ~semilight~
|
||
- ~regular~
|
||
- ~medium~
|
||
- ~semibold~
|
||
- ~bold~
|
||
- ~heavy~
|
||
- ~extrabold~
|
||
- ~ultrabold~
|
||
+ ~no-bold~ (deprecated alias of a ~regular~ weight)
|
||
+ A floating point as a height multiple of the default or a cons cell in
|
||
the form of =(height . FLOAT)=.
|
||
|
||
By default (a ~nil~ value for this variable), all headings have a bold
|
||
typographic weight and use a desaturated text color.
|
||
|
||
A ~rainbow~ property makes the text color more saturated.
|
||
|
||
An ~overline~ property draws a line above the area of the heading.
|
||
|
||
A ~background~ property adds a subtle tinted color to the background of
|
||
the heading.
|
||
|
||
A ~monochrome~ property makes the heading the same as the base color,
|
||
which is that of the ~default~ face's foreground. When ~background~ is also
|
||
set, ~monochrome~ changes its color to gray. If both ~monochrome~ and
|
||
~rainbow~ are set, the former takes precedence.
|
||
|
||
A ~variable-pitch~ property changes the font family of the heading to that
|
||
of the ~variable-pitch~ face (normally a proportionately spaced typeface).
|
||
|
||
The symbol of a weight attribute adjusts the font of the heading
|
||
accordingly, such as ~light~, ~semibold~, etc. Valid symbols are
|
||
defined in the variable ~modus-themes-weights~. The absence of a weight
|
||
means that bold will be used by virtue of inheriting the ~bold~ face.
|
||
For backward compatibility, the ~no-bold~ value is accepted, though
|
||
users are encouraged to specify a ~regular~ weight instead.
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
A number, expressed as a floating point (e.g. 1.5), adjusts the height
|
||
of the heading to that many times the base font size. The default
|
||
height is the same as 1.0, though it need not be explicitly stated.
|
||
Instead of a floating point, an acceptable value can be in the form of a
|
||
cons cell like =(height . FLOAT)= or =(height FLOAT)=, where FLOAT is
|
||
the given number.
|
||
|
||
Combinations of any of those properties are expressed as a list, like in
|
||
these examples:
|
||
|
||
#+begin_src emacs-lisp
|
||
(semibold)
|
||
(rainbow background)
|
||
(overline monochrome semibold 1.3)
|
||
(overline monochrome semibold (height 1.3)) ; same as above
|
||
(overline monochrome semibold (height . 1.3)) ; same as above
|
||
#+end_src
|
||
|
||
The order in which the properties are set is not significant.
|
||
|
||
In user configuration files the form may look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-headings
|
||
'((1 . (background overline rainbow 1.5))
|
||
(2 . (background overline 1.3))
|
||
(t . (overline semibold))))
|
||
#+end_src
|
||
|
||
When defining the styles per heading level, it is possible to pass a
|
||
non-~nil~ value (~t~) instead of a list of properties. This will retain the
|
||
original aesthetic for that level. For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-headings
|
||
'((1 . t) ; keep the default style
|
||
(2 . (background overline))
|
||
(t . (rainbow)))) ; style for all other headings
|
||
|
||
(setq modus-themes-headings
|
||
'((1 . (background overline))
|
||
(2 . (rainbow semibold))
|
||
(t . t))) ; default style for all other levels
|
||
#+end_src
|
||
|
||
For Org users, the extent of the heading depends on the variable
|
||
~org-fontify-whole-heading-line~. This affects the ~overline~ and
|
||
~background~ properties. Depending on the version of Org, there may be
|
||
others, such as ~org-fontify-done-headline~.
|
||
|
||
** Option for variable-pitch font in UI elements
|
||
:properties:
|
||
:alt_title: UI typeface
|
||
:description: Toggle the use of variable-pitch across the User Interface
|
||
:custom_id: h:16cf666c-5e65-424c-a855-7ea8a4a1fcac
|
||
:end:
|
||
#+vindex: modus-themes-variable-pitch-ui
|
||
|
||
Brief: Toggle the use of proportionately spaced (~variable-pitch~) fonts
|
||
in the User Interface.
|
||
|
||
Symbol: ~modus-themes-variable-pitch-ui~ (=boolean= type)
|
||
|
||
Possible values:
|
||
|
||
1. ~nil~ (default)
|
||
2. ~t~
|
||
|
||
This option concerns User Interface elements that are under the direct
|
||
control of Emacs. In particular: the mode line, header line, tab bar,
|
||
and tab line.
|
||
|
||
The default is to use the same font as the rest of Emacs, which usually
|
||
is a monospaced family.
|
||
|
||
With a non-~nil~ value (~t~) apply a proportionately spaced typeface. This
|
||
is done by assigning the ~variable-pitch~ face to the relevant items.
|
||
|
||
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
|
||
|
||
* Advanced customization
|
||
:properties:
|
||
:custom_id: h:f4651d55-8c07-46aa-b52b-bed1e53463bb
|
||
:end:
|
||
|
||
Unlike the predefined customization options which follow a clear pattern
|
||
of allowing the user to quickly specify their preference, the themes
|
||
also provide a more flexible, albeit difficult, mechanism to control
|
||
things with precision ([[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]).
|
||
|
||
This section is of interest only to users who are prepared to maintain
|
||
their own local tweaks and who are willing to deal with any possible
|
||
incompatibilities between versioned releases of the themes. As such,
|
||
they are labeled as "do-it-yourself" or "DIY".
|
||
|
||
** More accurate colors in terminal emulators
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:fbb5e254-afd6-4313-bb05-93b3b4f67358
|
||
:END:
|
||
#+cindex: Color accuracy of terminal emulators
|
||
|
||
[ This is based on partial information. Please help verify and/or
|
||
expand these findings. ]
|
||
|
||
The graphical version of Emacs can reproduce color values accurately.
|
||
Whereas things get more tricky when Emacs is used in a terminal
|
||
emulator, because the terminals' own capabilities determine the number
|
||
of colors that may be displayed: the Modus themes don't look as good in
|
||
that case.
|
||
|
||
There is, however, a way to instruct supported terminal emulators to use
|
||
more accurate colors. In a shell prompt type =toe -a | grep direct= to
|
||
get a list of relevant terminfo entries. There should be items such as
|
||
=xterm-direct=, =alacritty-direct=, =kitty-direct=. Once you find the one
|
||
that corresponds to your terminal, call Emacs with an environment
|
||
variable like =TERM=xterm-direct=. Example that can be adapted to shell
|
||
aliases:
|
||
|
||
: TERM=xterm-direct emacsclient -nw
|
||
|
||
Another example that can be bound to a key:
|
||
|
||
: TERM=xterm-direct uxterm -e emacsclient -nw
|
||
|
||
** Range of color with terminal emulators
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:6b8211b0-d11b-4c00-9543-4685ec3b742f
|
||
:END:
|
||
#+cindex: Pure white and pure black in terminal emulators
|
||
|
||
[ This is based on partial information. Please help verify and/or
|
||
expand these findings. ]
|
||
|
||
When Emacs runs in a non-windowed session its color reproduction
|
||
capacity is framed or determined by the underlying terminal emulator
|
||
([[#h:fbb5e254-afd6-4313-bb05-93b3b4f67358][More accurate colors in terminal emulators]]). Emacs cannot produce a
|
||
color that lies outside the range of what the terminal's color palette
|
||
renders possible.
|
||
|
||
This is immediately noticeable when the terminal's first 16 codes do not
|
||
include a pure black value for the =termcol0= entry and a pure white for
|
||
=termcol15=. Emacs cannot set the correct background (white for
|
||
~modus-operandi~; black for ~modus-vivendi~) or foreground (inverse of
|
||
the background). It thus falls back to the closest approximation, which
|
||
seldom is appropriate for the purposes of the Modus themes.
|
||
|
||
In such a case, the user is expected to update their terminal's color
|
||
palette such as by adapting these resources:
|
||
|
||
#+begin_src emacs-lisp
|
||
! Theme: modus-operandi
|
||
! Description: XTerm port of modus-operandi (Modus themes for GNU Emacs)
|
||
! Author: Protesilaos Stavrou, <https://protesilaos.com>
|
||
xterm*background: #ffffff
|
||
xterm*foreground: #000000
|
||
xterm*color0: #000000
|
||
xterm*color1: #a60000
|
||
xterm*color2: #005e00
|
||
xterm*color3: #813e00
|
||
xterm*color4: #0031a9
|
||
xterm*color5: #721045
|
||
xterm*color6: #00538b
|
||
xterm*color7: #bfbfbf
|
||
xterm*color8: #595959
|
||
xterm*color9: #972500
|
||
xterm*color10: #315b00
|
||
xterm*color11: #70480f
|
||
xterm*color12: #2544bb
|
||
xterm*color13: #5317ac
|
||
xterm*color14: #005a5f
|
||
xterm*color15: #ffffff
|
||
|
||
! Theme: modus-vivendi
|
||
! Description: XTerm port of modus-vivendi (Modus themes for GNU Emacs)
|
||
! Author: Protesilaos Stavrou, <https://protesilaos.com>
|
||
xterm*background: #000000
|
||
xterm*foreground: #ffffff
|
||
xterm*color0: #000000
|
||
xterm*color1: #ff8059
|
||
xterm*color2: #44bc44
|
||
xterm*color3: #d0bc00
|
||
xterm*color4: #2fafff
|
||
xterm*color5: #feacd0
|
||
xterm*color6: #00d3d0
|
||
xterm*color7: #bfbfbf
|
||
xterm*color8: #595959
|
||
xterm*color9: #ef8b50
|
||
xterm*color10: #70b900
|
||
xterm*color11: #c0c530
|
||
xterm*color12: #79a8ff
|
||
xterm*color13: #b6a0ff
|
||
xterm*color14: #6ae4b9
|
||
xterm*color15: #ffffff
|
||
#+end_src
|
||
|
||
** Visualize the active Modus theme's palette
|
||
:properties:
|
||
:custom_id: h:f4d4b71b-2ca5-4c3d-b0b4-9bfd7aa7fb4d
|
||
:end:
|
||
#+findex: modus-themes-list-colors
|
||
#+findex: modus-themes-list-colors-current
|
||
#+cindex: Preview color values
|
||
|
||
The command ~modus-themes-list-colors~ prompts for a choice between
|
||
=modus-operandi= and =modus-vivendi= to produce a help buffer that shows a
|
||
preview of each variable in the given theme's color palette. The
|
||
command ~modus-themes-list-colors-current~ skips the prompt, using the
|
||
current Modus theme.
|
||
|
||
Each row shows a foreground and background coloration using the
|
||
underlying value it references. For example a line with =#a60000= (a
|
||
shade of red) will show red text followed by a stripe with that same
|
||
color as a backdrop.
|
||
|
||
The name of the buffer describes the given Modus theme. It is thus
|
||
called =*modus-operandi-list-colors*= or =*modus-vivendi-list-colors*=.
|
||
|
||
** Per-theme customization settings
|
||
:properties:
|
||
:custom_id: h:a897b302-8e10-4a26-beab-3caaee1e1193
|
||
:end:
|
||
|
||
If you prefer to maintain different customization options between the
|
||
two themes, it is best you write your own functions that first set those
|
||
options and then load the relevant theme. The following code does
|
||
exactly that by simply differentiating the two themes on the choice of
|
||
bold constructs in code syntax (enabled for one, disabled for the
|
||
other).
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-demo-modus-operandi ()
|
||
(interactive)
|
||
(setq modus-themes-bold-constructs t) ; ENABLE bold
|
||
(modus-themes-load-operandi))
|
||
|
||
(defun my-demo-modus-vivendi ()
|
||
(interactive)
|
||
(setq modus-themes-bold-constructs nil) ; DISABLE bold
|
||
(modus-themes-load-vivendi))
|
||
|
||
(defun my-demo-modus-themes-toggle ()
|
||
(if (eq (car custom-enabled-themes) 'modus-operandi)
|
||
(my-demo-modus-vivendi)
|
||
(my-demo-modus-operandi)))
|
||
#+end_src
|
||
|
||
Then assign ~my-demo-modus-themes-toggle~ to a key instead of the
|
||
equivalent the themes provide.
|
||
|
||
For a more elaborate design, it is better to inspect the source code of
|
||
~modus-themes-toggle~ and relevant functions.
|
||
|
||
** Case-by-case face specs using the themes' palette
|
||
:properties:
|
||
:custom_id: h:1487c631-f4fe-490d-8d58-d72ffa3bd474
|
||
:end:
|
||
#+findex: modus-themes-color
|
||
#+findex: modus-themes-color-alts
|
||
#+cindex: Extracting individual colors
|
||
|
||
This section is about tweaking individual faces. If you plan to do
|
||
things at scale, consult the next section: [[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Set multiple faces]].
|
||
|
||
We already covered in previous sections how to toggle between the themes
|
||
and how to configure options prior to loading. We also explained that
|
||
some of the functions made available to users will fire up a hook that
|
||
can be used to pass tweaks in the post-theme-load phase.
|
||
|
||
Now assume you wish to change a single face, say, the ~cursor~. And you
|
||
would like to get the standard "blue" color value of the active Modus
|
||
theme, whether it is Modus Operandi or Modus Vivendi. To do that, you
|
||
can use the ~modus-themes-color~ function. It accepts a symbol that is
|
||
associated with a color in ~modus-themes-operandi-colors~ and
|
||
~modus-themes-vivendi-colors~. Like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(modus-themes-color 'blue)
|
||
#+end_src
|
||
|
||
The function always extracts the color value of the active Modus theme.
|
||
|
||
#+begin_src emacs-lisp
|
||
(progn
|
||
(load-theme 'modus-operandi t)
|
||
(modus-themes-color 'blue)) ; "#0031a9" for `modus-operandi'
|
||
|
||
(progn
|
||
(load-theme 'modus-vivendi t)
|
||
(modus-themes-color 'blue)) ; "#2fafff" for `modus-vivendi'
|
||
#+end_src
|
||
|
||
Do {{{kbd(C-h v)}}} on the aforementioned variables to check all the available
|
||
symbols that can be passed to this function. Or simply invoke the
|
||
command ~modus-themes-list-colors~ to produce a buffer with a preview of
|
||
each entry in the palette.
|
||
|
||
[[#h:f4d4b71b-2ca5-4c3d-b0b4-9bfd7aa7fb4d][Visualize the active Modus theme's palette]].
|
||
|
||
With that granted, let us expand the example to actually change the
|
||
~cursor~ face's background property. We employ the built-in function of
|
||
~set-face-attribute~:
|
||
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'cursor nil :background (modus-themes-color 'blue))
|
||
#+end_src
|
||
|
||
If you evaluate this form, your cursor will become blue. But if you
|
||
change themes, such as with ~modus-themes-toggle~, your edits will be
|
||
lost, because the newly loaded theme will override the ~:background~
|
||
attribute you had assigned to that face.
|
||
|
||
For such changes to persist, we need to make them after loading the
|
||
theme. So we rely on ~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~. Here is a sample function that
|
||
tweaks two faces and then gets added to the hook:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(set-face-attribute 'cursor nil :background (modus-themes-color 'blue))
|
||
(set-face-attribute 'font-lock-type-face nil :foreground (modus-themes-color 'magenta-alt)))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
[[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]].
|
||
|
||
Using this principle, it is possible to override the styles of faces
|
||
without having to find color values for each case.
|
||
|
||
Another application is to control the precise weight for bold
|
||
constructs. This is particularly useful if your typeface has several
|
||
variants such as "heavy", "extrabold", "semibold". All you have to do
|
||
is edit the ~bold~ face. For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'bold nil :weight 'semibold)
|
||
#+end_src
|
||
|
||
Remember to use the custom function and hook combo we demonstrated
|
||
above. Because the themes do not hard-wire a specific weight, this
|
||
simple form is enough to change the weight of all bold constructs
|
||
throughout the interface.
|
||
|
||
Finally, there are cases where you want to tweak colors though wish to
|
||
apply different ones to each theme, say, a blue hue for Modus Operandi
|
||
and a shade of red for Modus Vivendi. To this end, we provide
|
||
~modus-themes-color-alts~ as a convenience function to save you from the
|
||
trouble of writing separate wrappers for each theme. It still returns a
|
||
single value by querying either of ~modus-themes-operandi-colors~ and
|
||
~modus-themes-vivendi-colors~, only here you pass the two keys you want,
|
||
first for ~modus-operandi~ then ~modus-vivendi~.
|
||
|
||
Take the previous example with the ~cursor~ face:
|
||
|
||
#+begin_src emacs-lisp
|
||
;; Blue for `modus-operandi' and red for `modus-vivendi'
|
||
(set-face-attribute 'cursor nil :background (modus-themes-color-alts 'blue 'red))
|
||
#+end_src
|
||
|
||
** Face specs at scale using the themes' palette
|
||
:properties:
|
||
:custom_id: h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae
|
||
:end:
|
||
#+findex: modus-themes-with-colors
|
||
#+cindex: Extracting colors en masse
|
||
|
||
The examples here are for large scale operations. For simple, one-off
|
||
tweaks, you may prefer the approach documented in the previous section
|
||
([[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][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~).
|
||
|
||
[[#h:f4d4b71b-2ca5-4c3d-b0b4-9bfd7aa7fb4d][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:
|
||
|
||
#+begin_src emacs-lisp
|
||
(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")
|
||
#+end_src
|
||
|
||
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:
|
||
|
||
#+begin_src emacs-lisp
|
||
(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)))))
|
||
#+end_src
|
||
|
||
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:
|
||
|
||
#+begin_src emacs-lisp
|
||
(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)
|
||
#+end_src
|
||
|
||
[[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]].
|
||
|
||
To discover the faces defined by all loaded libraries, you may do
|
||
{{{kbd(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 {{{file(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:
|
||
|
||
#+begin_src emacs-lisp
|
||
...
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(cursor ((,class :background ,(modus-themes-color-alts 'blue 'green))))
|
||
...))
|
||
#+end_src
|
||
|
||
** Remap face with local value
|
||
:properties:
|
||
:custom_id: h:7a93cb6f-4eca-4d56-a85c-9dcd813d6b0f
|
||
:end:
|
||
#+cindex: Remapping faces
|
||
|
||
There are cases where we need to change the buffer-local attributes of a
|
||
face. This might be because we have our own minor mode that re-uses a
|
||
face for a particular purpose, such as a line selection tool that
|
||
activates ~hl-line-mode~, but we wish to keep it distinct from other
|
||
buffers. This is where ~face-remap-add-relative~ can be applied and may
|
||
be combined with ~modus-themes-with-colors~ to deliver consistent results.
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
In this example we will write a simple interactive function that adjusts
|
||
the background color of the ~region~ face. This is the sample code:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defvar my-rainbow-region-colors
|
||
(modus-themes-with-colors
|
||
`((red . ,red-subtle-bg)
|
||
(green . ,green-subtle-bg)
|
||
(yellow . ,yellow-subtle-bg)
|
||
(blue . ,blue-subtle-bg)
|
||
(magenta . ,magenta-subtle-bg)
|
||
(cyan . ,cyan-subtle-bg)))
|
||
"Sample list of color values for `my-rainbow-region'.")
|
||
|
||
(defun my-rainbow-region (color)
|
||
"Remap buffer-local attribute of `region' using COLOR."
|
||
(interactive
|
||
(list
|
||
(completing-read "Pick a color: " my-rainbow-region-colors)))
|
||
(face-remap-add-relative
|
||
'region
|
||
`( :background ,(alist-get (intern color) my-rainbow-region-colors)
|
||
:foreground ,(face-attribute 'default :foreground))))
|
||
#+end_src
|
||
|
||
When ~my-rainbow-region~ is called interactively, it prompts for a color
|
||
to use. The list of candidates is drawn from the car of each
|
||
association in ~my-rainbow-region-colors~ (so "red", "green", etc.).
|
||
|
||
To extend this principle, we may write wrapper functions that pass a
|
||
color directly. Those can be useful in tandem with hooks. Consider
|
||
this example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-rainbow-region-magenta ()
|
||
(my-rainbow-region 'magenta))
|
||
|
||
(add-hook 'diff-mode-hook #'my-rainbow-region-magenta)
|
||
#+end_src
|
||
|
||
Whenever we enter a ~diff-mode~ buffer, we now get a magenta-colored
|
||
region.
|
||
|
||
Perhaps you may wish to generalize those findings in to a set of
|
||
functions that also accept an arbitrary face. We shall leave the
|
||
experimentation up to you.
|
||
|
||
** Cycle through arbitrary colors
|
||
:properties:
|
||
:custom_id: h:77dc4a30-b96a-4849-85a8-fee3c2995305
|
||
:end:
|
||
#+cindex: Cycle colors
|
||
|
||
Users may opt to customize individual faces of the themes to accommodate
|
||
their particular needs. One such case is with the color intensity of
|
||
comments, specifically the foreground of ~font-lock-comment-face~. The
|
||
Modus themes set that to a readable value, in accordance with their
|
||
accessibility objective, though users may prefer to lower the overall
|
||
contrast on an on-demand basis.
|
||
|
||
One way to achieve this is to design a command that cycles through three
|
||
distinct levels of intensity, though the following can be adapted to any
|
||
kind of cyclic behavior, such as to switch between red, green, and blue.
|
||
|
||
In the following example, we employ the ~modus-themes-color~ function
|
||
which reads a symbol that represents an entry in the active theme's
|
||
color palette ([[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Case-by-case face specs using the themes' palette]]).
|
||
Those are stored in ~my-modus-themes-comment-colors~.
|
||
|
||
#+begin_src emacs-lisp
|
||
(defvar my-modus-themes-comment-colors
|
||
;; We are abusing the palette here, as those colors have their own
|
||
;; purpose in the palette, so please ignore the semantics of their
|
||
;; names.
|
||
'((low . bg-region)
|
||
(medium . bg-tab-inactive-alt)
|
||
(high . fg-alt))
|
||
"Alist of levels of intensity mapped to color palette entries.
|
||
The entries are found in `modus-themes-operandi-colors' or
|
||
`modus-themes-vivendi-colors'.")
|
||
|
||
(defvar my-modus-themes--adjust-comment-color-state nil
|
||
"The cyclic state of `my-modus-themes-adjust-comment-color'.
|
||
For internal use.")
|
||
|
||
(defun my-modus-themes--comment-foreground (degree state)
|
||
"Set `font-lock-comment-face' foreground.
|
||
Use `my-modus-themes-comment-colors' to extract the color value
|
||
for each level of intensity.
|
||
|
||
This is complementary to `my-modus-themes-adjust-comment-color'."
|
||
(let ((palette-colors my-modus-themes-comment-colors))
|
||
(set-face-foreground
|
||
'font-lock-comment-face
|
||
(modus-themes-color (alist-get degree palette-colors)))
|
||
(setq my-modus-themes--adjust-comment-color-state state)
|
||
(message "Comments are set to %s contrast" degree)))
|
||
|
||
(defun my-modus-themes-adjust-comment-color ()
|
||
"Cycle through levels of intensity for comments.
|
||
The levels are determined by `my-modus-themes-comment-colors'."
|
||
(interactive)
|
||
(pcase my-modus-themes--adjust-comment-color-state
|
||
('nil
|
||
(my-modus-themes--comment-foreground 'low 1))
|
||
(1
|
||
(my-modus-themes--comment-foreground 'medium 2))
|
||
(_
|
||
(my-modus-themes--comment-foreground 'high nil))))
|
||
#+end_src
|
||
|
||
With the above, {{{kbd(M-x my-modus-themes-adjust-comment-color)}}} will cycle
|
||
through the three levels of intensity that have been specified.
|
||
|
||
Another approach is to not read from the active theme's color palette
|
||
and instead provide explicit color values, either in hexadecimal RGB
|
||
notation (like =#123456=) or as the names that are displayed in the output
|
||
of {{{kbd(M-x list-colors-display)}}}. In this case, the alist with the
|
||
colors will have to account for the active theme, so as to set the
|
||
appropriate colors. While this introduces a bit more complexity, it
|
||
ultimately offers greater flexibility on the choice of colors for such a
|
||
niche functionality (so there is no need to abuse the palette of the
|
||
active Modus theme):
|
||
|
||
#+begin_src emacs-lisp
|
||
(defvar my-modus-themes-comment-colors
|
||
'((light . ((low . "gray75")
|
||
(medium . "gray50")
|
||
(high . "#505050"))) ; the default for `modus-operandi'
|
||
|
||
(dark . ((low . "gray25")
|
||
(medium . "gray50")
|
||
(high . "#a8a8a8")))) ; the default for `modus-vivendi'
|
||
"Alist of levels of intensity mapped to color values.
|
||
For such colors, consult the command `list-colors-display'. Pass
|
||
the name of a color or its hex value.")
|
||
|
||
(defvar my-modus-themes--adjust-comment-color-state nil
|
||
"The cyclic state of `my-modus-themes-adjust-comment-color'.
|
||
For internal use.")
|
||
|
||
(defun my-modus-themes--comment-foreground (degree state)
|
||
"Set `font-lock-comment-face' foreground.
|
||
Use `my-modus-themes-comment-colors' to extract the color value
|
||
for each level of intensity.
|
||
|
||
This is complementary to `my-modus-themes-adjust-comment-color'."
|
||
(let* ((colors my-modus-themes-comment-colors)
|
||
(levels (pcase (car custom-enabled-themes)
|
||
('modus-operandi (alist-get 'light colors))
|
||
('modus-vivendi (alist-get 'dark colors)))))
|
||
(set-face-foreground
|
||
'font-lock-comment-face
|
||
(alist-get degree levels))
|
||
(setq my-modus-themes--adjust-comment-color-state state)
|
||
(message "Comments are set to %s contrast" degree)))
|
||
|
||
(defun my-modus-themes-adjust-comment-color ()
|
||
"Cycle through levels of intensity for comments.
|
||
The levels are determined by `my-modus-themes-comment-colors'."
|
||
(interactive)
|
||
(pcase my-modus-themes--adjust-comment-color-state
|
||
('nil
|
||
(my-modus-themes--comment-foreground 'low 1))
|
||
(1
|
||
(my-modus-themes--comment-foreground 'medium 2))
|
||
(_
|
||
(my-modus-themes--comment-foreground 'high nil))))
|
||
#+end_src
|
||
|
||
The effect of the above configurations on ~font-lock-comment-face~ is
|
||
global. To make it buffer-local, one must tweak the code to employ the
|
||
function ~face-remap-add-relative~ ([[#h:7a93cb6f-4eca-4d56-a85c-9dcd813d6b0f][Remap face with local value]]).
|
||
|
||
So this form in ~my-modus-themes--comment-foreground~:
|
||
|
||
#+begin_src emacs-lisp
|
||
;; example 1
|
||
(...
|
||
(set-face-foreground
|
||
'font-lock-comment-face
|
||
(modus-themes-color (alist-get degree palette-colors)))
|
||
...)
|
||
|
||
;; example 2
|
||
(...
|
||
(set-face-foreground
|
||
'font-lock-comment-face
|
||
(alist-get degree levels))
|
||
...)
|
||
#+end_src
|
||
|
||
Must become this:
|
||
|
||
#+begin_src emacs-lisp
|
||
;; example 1
|
||
(...
|
||
(face-remap-add-relative
|
||
'font-lock-comment-face
|
||
`(:foreground ,(modus-themes-color (alist-get degree palette-colors))))
|
||
...)
|
||
|
||
;; example 2
|
||
(...
|
||
(face-remap-add-relative
|
||
'font-lock-comment-face
|
||
`(:foreground ,(alist-get degree levels)))
|
||
...)
|
||
#+end_src
|
||
|
||
** Override colors
|
||
:properties:
|
||
:custom_id: h:307d95dd-8dbd-4ece-a543-10ae86f155a6
|
||
:end:
|
||
#+vindex: modus-themes-operandi-color-overrides
|
||
#+vindex: modus-themes-vivendi-color-overrides
|
||
#+cindex: Change a theme's colors
|
||
|
||
The themes provide a mechanism for overriding their color values. This
|
||
is controlled by the variables ~modus-themes-operandi-color-overrides~ and
|
||
~modus-themes-vivendi-color-overrides~, which are alists that should
|
||
mirror a subset of the associations in ~modus-themes-operandi-colors~ and
|
||
~modus-themes-vivendi-colors~ respectively. As with all customizations,
|
||
overriding must be done before loading the affected theme.
|
||
|
||
[[#h:f4d4b71b-2ca5-4c3d-b0b4-9bfd7aa7fb4d][Visualize the active Modus theme's palette]].
|
||
|
||
Let us approach the present topic one step at a time. Here is a
|
||
simplified excerpt of the default palette for Modus Operandi with some
|
||
basic background values that apply to buffers and the mode line
|
||
(remember to inspect the actual value to find out all the associations
|
||
that can be overridden):
|
||
|
||
#+begin_src emacs-lisp
|
||
(defconst modus-themes-operandi-colors
|
||
'((bg-main . "#ffffff")
|
||
(bg-dim . "#f8f8f8")
|
||
(bg-alt . "#f0f0f0")
|
||
(bg-active . "#d7d7d7")
|
||
(bg-inactive . "#efefef")))
|
||
#+end_src
|
||
|
||
As one can tell, we bind a key to a hexadecimal RGB color value. Now
|
||
say we wish to override those specific values and have our changes
|
||
propagate to all faces that use those keys. We could write something
|
||
like this, which adds a subtle ocher tint:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-operandi-color-overrides
|
||
'((bg-main . "#fefcf4")
|
||
(bg-dim . "#faf6ef")
|
||
(bg-alt . "#f7efe5")
|
||
(bg-active . "#e8dfd1")
|
||
(bg-inactive . "#f6ece5")))
|
||
#+end_src
|
||
|
||
Once this is evaluated, any subsequent loading of ~modus-operandi~ will
|
||
use those values instead of the defaults. No further intervention is
|
||
required.
|
||
|
||
To reset the changes, we apply this and reload the theme:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq modus-themes-operandi-color-overrides nil)
|
||
#+end_src
|
||
|
||
Users who wish to leverage such a mechanism can opt to implement it
|
||
on-demand by means of a global minor mode. The following snippet covers
|
||
both themes and expands to some more associations in the palette:
|
||
|
||
#+begin_src emacs-lisp
|
||
(define-minor-mode my-modus-themes-tinted
|
||
"Tweak some Modus themes colors."
|
||
:init-value nil
|
||
:global t
|
||
(if my-modus-themes-tinted
|
||
(setq modus-themes-operandi-color-overrides
|
||
'((bg-main . "#fefcf4")
|
||
(bg-dim . "#faf6ef")
|
||
(bg-alt . "#f7efe5")
|
||
(bg-hl-line . "#f4f0e3")
|
||
(bg-active . "#e8dfd1")
|
||
(bg-inactive . "#f6ece5")
|
||
(bg-region . "#c6bab1")
|
||
(bg-header . "#ede3e0")
|
||
(bg-tab-active . "#fdf6eb")
|
||
(bg-tab-inactive . "#c8bab8"))
|
||
modus-themes-vivendi-color-overrides
|
||
'((bg-main . "#100b17")
|
||
(bg-dim . "#161129")
|
||
(bg-alt . "#181732")
|
||
(bg-hl-line . "#191628")
|
||
(bg-active . "#282e46")
|
||
(bg-inactive . "#1a1e39")
|
||
(bg-region . "#393a53")
|
||
(bg-header . "#202037")
|
||
(bg-tab-active . "#120f18")
|
||
(bg-tab-inactive . "#3a3a5a")))
|
||
(setq modus-themes-operandi-color-overrides nil
|
||
modus-themes-vivendi-color-overrides nil)))
|
||
#+end_src
|
||
|
||
A more neutral style for ~modus-themes-operandi-color-overrides~ can
|
||
look like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
'((bg-main . "#f7f7f7")
|
||
(bg-dim . "#f2f2f2")
|
||
(bg-alt . "#e8e8e8")
|
||
(bg-hl-line . "#eaeaef")
|
||
(bg-active . "#e0e0e0")
|
||
(bg-inactive . "#e6e6e6")
|
||
(bg-region . "#b5b5b5")
|
||
(bg-header . "#e4e4e4")
|
||
(bg-tab-active . "#f5f5f5")
|
||
(bg-tab-inactive . "#c0c0c0"))
|
||
#+end_src
|
||
|
||
With those in place, one can use {{{kbd(M-x my-modus-themes-tinted)}}}
|
||
and then load the Modus theme of their choice. The new palette subset
|
||
will come into effect: subtle ocher tints (or shades of gray) for Modus
|
||
Operandi and night sky blue shades for Modus Vivendi. Switching between
|
||
the two themes, such as with {{{kbd(M-x modus-themes-toggle)}}} will
|
||
also use the overrides.
|
||
|
||
Given that this is a user-level customization, one is free to implement
|
||
whatever color values they desire, even if the possible combinations
|
||
fall below the minimum 7:1 contrast ratio that governs the design of the
|
||
themes (the WCAG AAA legibility standard). Alternatively, this can also
|
||
be done programmatically ([[#h:4589acdc-2505-41fc-9f5e-699cfc45ab00][Override color saturation]]).
|
||
|
||
The above are expanded into a fully fledged derivative elsewhere in this
|
||
document ([[#h:736c0ff5-8c9c-4565-82cf-989e57d07d4a][Override colors completely]]).
|
||
|
||
For manual interventions it is advised to inspect the source code of
|
||
~modus-themes-operandi-colors~ and ~modus-themes-vivendi-colors~ for the
|
||
inline commentary: it explains what the intended use of each palette
|
||
subset is.
|
||
|
||
Furthermore, users may benefit from the ~modus-themes-contrast~ function
|
||
that we provide: [[#h:02e25930-e71a-493d-828a-8907fc80f874][test color combinations]]. It measures the contrast
|
||
ratio between two color values, so it can help in overriding the palette
|
||
(or a subset thereof) without making the end result inaccessible.
|
||
|
||
** Override color saturation
|
||
:properties:
|
||
:custom_id: h:4589acdc-2505-41fc-9f5e-699cfc45ab00
|
||
:end:
|
||
#+cindex: Change a theme's color saturation
|
||
|
||
In the previous section we documented how one can override color values
|
||
manually ([[#h:307d95dd-8dbd-4ece-a543-10ae86f155a6][Override colors]]). Here we use a programmatic approach which
|
||
leverages the built-in ~color-saturate-name~ function to adjust the
|
||
saturation of all color values used by the active Modus theme. Our goal
|
||
is to prepare a counterpart of the active theme's palette that holds
|
||
modified color values, adjusted for a percent change in saturation. A
|
||
positive number amplifies the effect, while a negative one will move
|
||
towards a grayscale spectrum.
|
||
|
||
We start with a function that can be either called from Lisp or invoked
|
||
interactively. In the former scenario, we pass to it the rate of change
|
||
we want. While in the latter, a minibuffer prompt asks for a number to
|
||
apply the desired effect. In either case, we intend to assign anew the
|
||
value of ~modus-themes-operandi-color-overrides~ (light theme) and the
|
||
same for ~modus-themes-vivendi-color-overrides~ (dark theme).
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-saturate (percent)
|
||
"Saturate current Modus theme palette overrides by PERCENT."
|
||
(interactive
|
||
(list (read-number "Saturation by percent: ")))
|
||
(let* ((theme (modus-themes--current-theme))
|
||
(palette (pcase theme
|
||
('modus-operandi modus-themes-operandi-colors)
|
||
('modus-vivendi modus-themes-vivendi-colors)
|
||
(_ (error "No Modus theme is active"))))
|
||
(overrides (pcase theme
|
||
('modus-operandi 'modus-themes-operandi-color-overrides)
|
||
('modus-vivendi 'modus-themes-vivendi-color-overrides)
|
||
(_ (error "No Modus theme is active")))))
|
||
(let (name cons colors)
|
||
(dolist (cons palette)
|
||
(setq name (color-saturate-name (cdr cons) percent))
|
||
(setq name (format "%s" name))
|
||
(setq cons `(,(car cons) . ,name))
|
||
(push cons colors))
|
||
(set overrides colors))
|
||
(pcase theme
|
||
('modus-operandi (modus-themes-load-operandi))
|
||
('modus-vivendi (modus-themes-load-vivendi)))))
|
||
|
||
;; sample Elisp calls (or call `my-modus-themes-saturate' interactively)
|
||
(my-modus-themes-saturate 50)
|
||
(my-modus-themes-saturate -75)
|
||
#+end_src
|
||
|
||
Using the above has an immediate effect, as it reloads the active Modus
|
||
theme.
|
||
|
||
The =my-modus-themes-saturate= function stores new color values in the
|
||
variables ~modus-themes-operandi-color-overrides~ and
|
||
~modus-themes-vivendi-color-overrides~, meaning that it undoes changes
|
||
implemented by the user on individual colors. To have both automatic
|
||
saturation adjustment across the board and retain per-case edits to the
|
||
palette, some tweaks to the above function are required. For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defvar my-modus-themes-vivendi-extra-color-overrides
|
||
'((fg-main . "#ead0c0")
|
||
(bg-main . "#050515"))
|
||
"My bespoke colors for `modus-vivendi'.")
|
||
|
||
(defvar my-modus-themes-operandi-extra-color-overrides
|
||
'((fg-main . "#1a1a1a")
|
||
(bg-main . "#fefcf4"))
|
||
"My bespoke colors for `modus-operandi'.")
|
||
|
||
(defun my-modus-themes-saturate (percent)
|
||
"Saturate current Modus theme palette overrides by PERCENT.
|
||
Preserve the color values stored in
|
||
`my-modus-themes-operandi-extra-color-overrides',
|
||
`my-modus-themes-vivendi-extra-color-overrides'."
|
||
(interactive
|
||
(list (read-number "Saturation by percent: ")))
|
||
(let* ((theme (modus-themes--current-theme))
|
||
(palette (pcase theme
|
||
('modus-operandi modus-themes-operandi-colors)
|
||
('modus-vivendi modus-themes-vivendi-colors)
|
||
(_ (error "No Modus theme is active"))))
|
||
(overrides (pcase theme
|
||
('modus-operandi 'modus-themes-operandi-color-overrides)
|
||
('modus-vivendi 'modus-themes-vivendi-color-overrides)
|
||
(_ (error "No Modus theme is active"))))
|
||
(extra-overrides (pcase theme
|
||
('modus-operandi my-modus-themes-operandi-extra-color-overrides)
|
||
('modus-vivendi my-modus-themes-vivendi-extra-color-overrides)
|
||
(_ (error "No Modus theme is active")))))
|
||
(let (name cons colors)
|
||
(dolist (cons palette)
|
||
(setq name (color-saturate-name (cdr cons) percent))
|
||
(setq name (format "%s" name))
|
||
(setq cons `(,(car cons) . ,name))
|
||
(push cons colors))
|
||
(set overrides (append extra-overrides colors)))
|
||
(pcase theme
|
||
('modus-operandi (modus-themes-load-operandi))
|
||
('modus-vivendi (modus-themes-load-vivendi)))))
|
||
#+end_src
|
||
|
||
To disable the effect, one must reset the aforementioned variables of
|
||
the themes to ~nil~. Or specify a command for it, such as by taking
|
||
inspiration from the ~modus-themes-toggle~ we already provide:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-revert-overrides ()
|
||
"Reset palette overrides and reload active Modus theme."
|
||
(interactive)
|
||
(setq modus-themes-operandi-color-overrides nil
|
||
modus-themes-vivendi-color-overrides nil)
|
||
(pcase (modus-themes--current-theme)
|
||
('modus-operandi (modus-themes-load-operandi))
|
||
('modus-vivendi (modus-themes-load-vivendi))))
|
||
#+end_src
|
||
|
||
** Override colors through blending
|
||
:properties:
|
||
:custom_id: h:80c326bf-fe32-47b2-8c59-58022256fd6e
|
||
:end:
|
||
#+cindex: Change theme colors through blending
|
||
|
||
This is yet another method of overriding color values.
|
||
|
||
[[#h:307d95dd-8dbd-4ece-a543-10ae86f155a6][Override colors]].
|
||
|
||
[[#h:4589acdc-2505-41fc-9f5e-699cfc45ab00][Override color saturation]].
|
||
|
||
Building on ideas and concepts from the previous sections, this method
|
||
blends the entire palette at once with the chosen colors. The function
|
||
~my-modus-themes-interpolate~ blends two colors, taking a value from the
|
||
themes and mixing it with a user-defined color to arrive at a midpoint.
|
||
This scales to all background and foreground colors with the help of the
|
||
~my-modus-themes-tint-palette~ function.
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq my-modus-operandi-bg-blend "#fbf1c7"
|
||
my-modus-operandi-fg-blend "#3a6084"
|
||
my-modus-vivendi-bg-blend "#3a4042"
|
||
my-modus-vivendi-fg-blend "#d7b765")
|
||
|
||
;; Adapted from the `kurecolor-interpolate' function of kurecolor.el
|
||
(defun my-modus-themes-interpolate (color1 color2)
|
||
(cl-destructuring-bind (r g b)
|
||
(mapcar #'(lambda (n) (* (/ n 2) 255.0))
|
||
(cl-mapcar '+ (color-name-to-rgb color1) (color-name-to-rgb color2)))
|
||
(format "#%02X%02X%02X" r g b)))
|
||
|
||
(defun my-modus-themes-tint-palette (palette bg-blend fg-blend)
|
||
"Modify Modus PALETTE programmatically and return a new palette.
|
||
Blend background colors with BG-BLEND and foreground colors with FG-BLEND."
|
||
(let (name cons colors)
|
||
(dolist (cons palette)
|
||
(let ((blend (if (string-match "bg" (symbol-name (car cons)))
|
||
bg-blend
|
||
fg-blend)))
|
||
(setq name (my-modus-themes-interpolate (cdr cons) blend)))
|
||
(setq name (format "%s" name))
|
||
(setq cons `(,(car cons) . ,name))
|
||
(push cons colors))
|
||
colors))
|
||
|
||
(define-minor-mode modus-themes-tinted-mode
|
||
"Tweak some Modus themes colors."
|
||
:init-value nil
|
||
:global t
|
||
(if modus-themes-tinted-mode
|
||
(setq modus-themes-operandi-color-overrides
|
||
(my-modus-themes-tint-palette modus-themes-operandi-colors
|
||
my-modus-operandi-bg-blend
|
||
my-modus-operandi-fg-blend)
|
||
modus-themes-vivendi-color-overrides
|
||
(my-modus-themes-tint-palette modus-themes-vivendi-colors
|
||
my-modus-vivendi-bg-blend
|
||
my-modus-vivendi-fg-blend))
|
||
(setq modus-themes-operandi-color-overrides nil
|
||
modus-themes-vivendi-color-overrides nil)))
|
||
|
||
(modus-themes-tinted-mode 1)
|
||
#+end_src
|
||
|
||
** Override colors completely
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:736c0ff5-8c9c-4565-82cf-989e57d07d4a
|
||
:END:
|
||
|
||
Based on the ideas we have already covered in these sections, the
|
||
following code block provides a complete, bespoke pair of color palettes
|
||
which override the defaults. They are implemented as a minor mode, as
|
||
explained before ([[#h:307d95dd-8dbd-4ece-a543-10ae86f155a6][Override colors]]). We call them "Summertime" for
|
||
convenience.
|
||
|
||
#+begin_src emacs-lisp
|
||
;; Read the relevant blog post:
|
||
;; <https://protesilaos.com/codelog/2022-07-26-modus-themes-color-override-demo/>
|
||
(define-minor-mode modus-themes-summertime
|
||
"Refashion the Modus themes by overriding their colors.
|
||
|
||
This is a complete technology demonstration to show how to
|
||
manually override the colors of the Modus themes. I have taken
|
||
good care of those overrides to make them work as a fully fledged
|
||
color scheme that is compatible with all user options of the
|
||
Modus themes.
|
||
|
||
These overrides are usable by those who (i) like something more
|
||
fancy than the comparatively austere looks of the Modus themes,
|
||
and (ii) can cope with a lower contrast ratio.
|
||
|
||
The overrides are set up as a minor mode, so that the user can
|
||
activate the effect on demand. Those who want to load the
|
||
overrides at all times can either add them directly to their
|
||
configuration or enable `modus-themes-summertime' BEFORE loading
|
||
either of the Modus themes (if the overrides are evaluated after
|
||
the theme, the theme must be reloaded).
|
||
|
||
Remember that all changes to theme-related variables require a
|
||
reload of the theme to take effect (the Modus themes have lots of
|
||
user options, apart from those overrides).
|
||
|
||
The `modus-themes-summertime' IS NOT an official extension to the
|
||
Modus themes and DOES NOT comply with its lofty accessibility
|
||
standards. It is included in the official manual as guidance for
|
||
those who want to make use of the color overriding facility we
|
||
provide."
|
||
:init-value nil
|
||
:global t
|
||
(if modus-themes-summertime
|
||
(setq modus-themes-operandi-color-overrides
|
||
'((bg-main . "#fff0f2")
|
||
(bg-dim . "#fbe6ef")
|
||
(bg-alt . "#f5dae6")
|
||
(bg-hl-line . "#fad8e3")
|
||
(bg-active . "#efcadf")
|
||
(bg-inactive . "#f3ddef")
|
||
(bg-active-accent . "#ffbbef")
|
||
(bg-region . "#dfc5d1")
|
||
(bg-region-accent . "#efbfef")
|
||
(bg-region-accent-subtle . "#ffd6ef")
|
||
(bg-header . "#edd3e0")
|
||
(bg-tab-active . "#ffeff2")
|
||
(bg-tab-inactive . "#f8d3ef")
|
||
(bg-tab-inactive-accent . "#ffd9f5")
|
||
(bg-tab-inactive-alt . "#e5c0d5")
|
||
(bg-tab-inactive-alt-accent . "#f3cce0")
|
||
(fg-main . "#543f78")
|
||
(fg-dim . "#5f476f")
|
||
(fg-alt . "#7f6f99")
|
||
(fg-unfocused . "#8f6f9f")
|
||
(fg-active . "#563068")
|
||
(fg-inactive . "#8a5698")
|
||
(fg-docstring . "#5f5fa7")
|
||
(fg-comment-yellow . "#a9534f")
|
||
(fg-escape-char-construct . "#8b207f")
|
||
(fg-escape-char-backslash . "#a06d00")
|
||
(bg-special-cold . "#d3e0f4")
|
||
(bg-special-faint-cold . "#e0efff")
|
||
(bg-special-mild . "#c4ede0")
|
||
(bg-special-faint-mild . "#e0f0ea")
|
||
(bg-special-warm . "#efd0c4")
|
||
(bg-special-faint-warm . "#ffe4da")
|
||
(bg-special-calm . "#f0d3ea")
|
||
(bg-special-faint-calm . "#fadff9")
|
||
(fg-special-cold . "#405fb8")
|
||
(fg-special-mild . "#407f74")
|
||
(fg-special-warm . "#9d6f4f")
|
||
(fg-special-calm . "#af509f")
|
||
(bg-completion . "#ffc5e5")
|
||
(bg-completion-subtle . "#f7cfef")
|
||
(red . "#ed2f44")
|
||
(red-alt . "#e0403d")
|
||
(red-alt-other . "#e04059")
|
||
(red-faint . "#ed4f44")
|
||
(red-alt-faint . "#e0603d")
|
||
(red-alt-other-faint . "#e06059")
|
||
(green . "#217a3c")
|
||
(green-alt . "#417a1c")
|
||
(green-alt-other . "#006f3c")
|
||
(green-faint . "#318a4c")
|
||
(green-alt-faint . "#518a2c")
|
||
(green-alt-other-faint . "#20885c")
|
||
(yellow . "#b06202")
|
||
(yellow-alt . "#a95642")
|
||
(yellow-alt-other . "#a06f42")
|
||
(yellow-faint . "#b07232")
|
||
(yellow-alt-faint . "#a96642")
|
||
(yellow-alt-other-faint . "#a08042")
|
||
(blue . "#275ccf")
|
||
(blue-alt . "#475cc0")
|
||
(blue-alt-other . "#3340ef")
|
||
(blue-faint . "#476ce0")
|
||
(blue-alt-faint . "#575ccf")
|
||
(blue-alt-other-faint . "#3f60d7")
|
||
(magenta . "#bf317f")
|
||
(magenta-alt . "#d033c0")
|
||
(magenta-alt-other . "#844fe4")
|
||
(magenta-faint . "#bf517f")
|
||
(magenta-alt-faint . "#d053c0")
|
||
(magenta-alt-other-faint . "#846fe4")
|
||
(cyan . "#007a9f")
|
||
(cyan-alt . "#3f709f")
|
||
(cyan-alt-other . "#107f7f")
|
||
(cyan-faint . "#108aaf")
|
||
(cyan-alt-faint . "#3f80af")
|
||
(cyan-alt-other-faint . "#3088af")
|
||
(red-active . "#cd2f44")
|
||
(green-active . "#116a6c")
|
||
(yellow-active . "#993602")
|
||
(blue-active . "#475ccf")
|
||
(magenta-active . "#7f2ccf")
|
||
(cyan-active . "#007a8f")
|
||
(red-nuanced-bg . "#ffdbd0")
|
||
(red-nuanced-fg . "#ed6f74")
|
||
(green-nuanced-bg . "#dcf0dd")
|
||
(green-nuanced-fg . "#3f9a4c")
|
||
(yellow-nuanced-bg . "#fff3aa")
|
||
(yellow-nuanced-fg . "#b47232")
|
||
(blue-nuanced-bg . "#e3e3ff")
|
||
(blue-nuanced-fg . "#201f6f")
|
||
(magenta-nuanced-bg . "#fdd0ff")
|
||
(magenta-nuanced-fg . "#c0527f")
|
||
(cyan-nuanced-bg . "#dbefff")
|
||
(cyan-nuanced-fg . "#0f3f60")
|
||
(bg-diff-heading . "#b7cfe0")
|
||
(fg-diff-heading . "#041645")
|
||
(bg-diff-added . "#d6f0d6")
|
||
(fg-diff-added . "#004520")
|
||
(bg-diff-changed . "#fcefcf")
|
||
(fg-diff-changed . "#524200")
|
||
(bg-diff-removed . "#ffe0ef")
|
||
(fg-diff-removed . "#891626")
|
||
(bg-diff-refine-added . "#84cfa4")
|
||
(fg-diff-refine-added . "#002a00")
|
||
(bg-diff-refine-changed . "#cccf8f")
|
||
(fg-diff-refine-changed . "#302010")
|
||
(bg-diff-refine-removed . "#da92b0")
|
||
(fg-diff-refine-removed . "#500010")
|
||
(bg-diff-focus-added . "#a6e5c6")
|
||
(fg-diff-focus-added . "#002c00")
|
||
(bg-diff-focus-changed . "#ecdfbf")
|
||
(fg-diff-focus-changed . "#392900")
|
||
(bg-diff-focus-removed . "#efbbcf")
|
||
(fg-diff-focus-removed . "#5a0010"))
|
||
modus-themes-vivendi-color-overrides
|
||
'((bg-main . "#25152a")
|
||
(bg-dim . "#2a1930")
|
||
(bg-alt . "#382443")
|
||
(bg-hl-line . "#332650")
|
||
(bg-active . "#463358")
|
||
(bg-inactive . "#2d1f3a")
|
||
(bg-active-accent . "#50308f")
|
||
(bg-region . "#5d4a67")
|
||
(bg-region-accent . "#60509f")
|
||
(bg-region-accent-subtle . "#3f285f")
|
||
(bg-header . "#3a2543")
|
||
(bg-tab-active . "#26162f")
|
||
(bg-tab-inactive . "#362647")
|
||
(bg-tab-inactive-accent . "#36265a")
|
||
(bg-tab-inactive-alt . "#3e2f5a")
|
||
(bg-tab-inactive-alt-accent . "#3e2f6f")
|
||
(fg-main . "#debfe0")
|
||
(fg-dim . "#d0b0da")
|
||
(fg-alt . "#ae85af")
|
||
(fg-unfocused . "#8e7f9f")
|
||
(fg-active . "#cfbfef")
|
||
(fg-inactive . "#b0a0c0")
|
||
(fg-docstring . "#c8d9f7")
|
||
(fg-comment-yellow . "#cf9a70")
|
||
(fg-escape-char-construct . "#ff75aa")
|
||
(fg-escape-char-backslash . "#dbab40")
|
||
(bg-special-cold . "#2a3f58")
|
||
(bg-special-faint-cold . "#1e283f")
|
||
(bg-special-mild . "#0f3f31")
|
||
(bg-special-faint-mild . "#0f281f")
|
||
(bg-special-warm . "#44331f")
|
||
(bg-special-faint-warm . "#372213")
|
||
(bg-special-calm . "#4a314f")
|
||
(bg-special-faint-calm . "#3a223f")
|
||
(fg-special-cold . "#c0b0ff")
|
||
(fg-special-mild . "#bfe0cf")
|
||
(fg-special-warm . "#edc0a6")
|
||
(fg-special-calm . "#ff9fdf")
|
||
(bg-completion . "#502d70")
|
||
(bg-completion-subtle . "#451d65")
|
||
(red . "#ff5f6f")
|
||
(red-alt . "#ff8f6d")
|
||
(red-alt-other . "#ff6f9d")
|
||
(red-faint . "#ffa0a0")
|
||
(red-alt-faint . "#f5aa80")
|
||
(red-alt-other-faint . "#ff9fbf")
|
||
(green . "#51ca5c")
|
||
(green-alt . "#71ca3c")
|
||
(green-alt-other . "#51ca9c")
|
||
(green-faint . "#78bf78")
|
||
(green-alt-faint . "#99b56f")
|
||
(green-alt-other-faint . "#88bf99")
|
||
(yellow . "#f0b262")
|
||
(yellow-alt . "#f0e242")
|
||
(yellow-alt-other . "#d0a272")
|
||
(yellow-faint . "#d2b580")
|
||
(yellow-alt-faint . "#cabf77")
|
||
(yellow-alt-other-faint . "#d0ba95")
|
||
(blue . "#778cff")
|
||
(blue-alt . "#8f90ff")
|
||
(blue-alt-other . "#8380ff")
|
||
(blue-faint . "#82b0ec")
|
||
(blue-alt-faint . "#a0acef")
|
||
(blue-alt-other-faint . "#80b2f0")
|
||
(magenta . "#ff70cf")
|
||
(magenta-alt . "#ff77f0")
|
||
(magenta-alt-other . "#ca7fff")
|
||
(magenta-faint . "#e0b2d6")
|
||
(magenta-alt-faint . "#ef9fe4")
|
||
(magenta-alt-other-faint . "#cfa6ff")
|
||
(cyan . "#30cacf")
|
||
(cyan-alt . "#60caff")
|
||
(cyan-alt-other . "#40b79f")
|
||
(cyan-faint . "#90c4ed")
|
||
(cyan-alt-faint . "#a0bfdf")
|
||
(cyan-alt-other-faint . "#a4d0bb")
|
||
(red-active . "#ff6059")
|
||
(green-active . "#64dc64")
|
||
(yellow-active . "#ffac80")
|
||
(blue-active . "#4fafff")
|
||
(magenta-active . "#cf88ff")
|
||
(cyan-active . "#50d3d0")
|
||
(red-nuanced-bg . "#440a1f")
|
||
(red-nuanced-fg . "#ffcccc")
|
||
(green-nuanced-bg . "#002904")
|
||
(green-nuanced-fg . "#b8e2b8")
|
||
(yellow-nuanced-bg . "#422000")
|
||
(yellow-nuanced-fg . "#dfdfb0")
|
||
(blue-nuanced-bg . "#1f1f5f")
|
||
(blue-nuanced-fg . "#bfd9ff")
|
||
(magenta-nuanced-bg . "#431641")
|
||
(magenta-nuanced-fg . "#e5cfef")
|
||
(cyan-nuanced-bg . "#042f49")
|
||
(cyan-nuanced-fg . "#a8e5e5")
|
||
(bg-diff-heading . "#304466")
|
||
(fg-diff-heading . "#dae7ff")
|
||
(bg-diff-added . "#0a383a")
|
||
(fg-diff-added . "#94ba94")
|
||
(bg-diff-changed . "#2a2000")
|
||
(fg-diff-changed . "#b0ba9f")
|
||
(bg-diff-removed . "#50163f")
|
||
(fg-diff-removed . "#c6adaa")
|
||
(bg-diff-refine-added . "#006a46")
|
||
(fg-diff-refine-added . "#e0f6e0")
|
||
(bg-diff-refine-changed . "#585800")
|
||
(fg-diff-refine-changed . "#ffffcc")
|
||
(bg-diff-refine-removed . "#952838")
|
||
(fg-diff-refine-removed . "#ffd9eb")
|
||
(bg-diff-focus-added . "#1d4c3f")
|
||
(fg-diff-focus-added . "#b4dfb4")
|
||
(bg-diff-focus-changed . "#424200")
|
||
(fg-diff-focus-changed . "#d0daaf")
|
||
(bg-diff-focus-removed . "#6f0f39")
|
||
(fg-diff-focus-removed . "#eebdba")))
|
||
(setq modus-themes-operandi-color-overrides nil
|
||
modus-themes-vivendi-color-overrides nil)))
|
||
#+end_src
|
||
|
||
** Font configurations for Org and others
|
||
:properties:
|
||
:custom_id: h:defcf4fc-8fa8-4c29-b12e-7119582cc929
|
||
:end:
|
||
#+cindex: Font configurations
|
||
|
||
The themes are designed to optionally cope well with mixed font
|
||
configurations. This mostly concerns ~org-mode~ and ~markdown-mode~, though
|
||
expect to find it elsewhere like in ~Info-mode~.
|
||
|
||
[[#h:115e6c23-ee35-4a16-8cef-e2fcbb08e28b][Option for font mixing]].
|
||
|
||
In practice it means that the user can safely opt for a more
|
||
prose-friendly proportionately spaced typeface as their default, while
|
||
spacing-sensitive elements like tables and inline code always use a
|
||
monospaced font, by inheriting from the ~fixed-pitch~ face.
|
||
|
||
Users can try the built-in {{{kbd(M-x variable-pitch-mode)}}} to see the
|
||
effect in action.
|
||
|
||
To make everything use your desired font families, you need to configure
|
||
the ~variable-pitch~ (proportional spacing) and ~fixed-pitch~ (monospaced)
|
||
faces respectively. It may also be convenient to set your main typeface
|
||
by configuring the ~default~ face the same way.
|
||
|
||
[ The =fontaine= package on GNU ELPA (by the author of the modus-themes)
|
||
is designed to handle this case. ]
|
||
|
||
Put something like this in your initialization file (also consider
|
||
reading the doc string of ~set-face-attribute~):
|
||
|
||
#+begin_src emacs-lisp
|
||
;; Main typeface
|
||
(set-face-attribute 'default nil :family "DejaVu Sans Mono" :height 110)
|
||
|
||
;; Proportionately spaced typeface
|
||
(set-face-attribute 'variable-pitch nil :family "DejaVu Serif" :height 1.0)
|
||
|
||
;; Monospaced typeface
|
||
(set-face-attribute 'fixed-pitch nil :family "DejaVu Sans Mono" :height 1.5)
|
||
#+end_src
|
||
|
||
Or employ the ~face-attribute~ function to read an existing value, such as
|
||
if you want to make ~fixed-pitch~ use the font family of the ~default~ face:
|
||
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'fixed-pitch nil :family (face-attribute 'default :family))
|
||
#+end_src
|
||
|
||
The next section shows how to make those work in a more elaborate setup
|
||
that is robust to changes between the Modus themes.
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
Note the differences in the ~:height~ property. The ~default~ face must
|
||
specify an absolute value, which is the point size × 10. So if you want
|
||
to use a font at point size =11=, you set the height to =110=.[fn:: ~:height~
|
||
values do not need to be rounded to multiples of ten: the likes of =115=
|
||
are perfectly valid—some typefaces will change to account for those
|
||
finer increments.] Whereas every other face must either not specify a
|
||
height or have a value that is relative to the default, represented as a
|
||
floating point. If you use an integer, then that means an absolute
|
||
height. This is of paramount importance: it ensures that all fonts can
|
||
scale gracefully when using something like the ~text-scale-adjust~ command
|
||
which only operates on the base font size (i.e. the ~default~ face's
|
||
absolute height).
|
||
|
||
[[#h:e6c5451f-6763-4be7-8fdb-b4706a422a4c][Note for EWW and Elfeed fonts]].
|
||
|
||
** Configure bold and italic faces
|
||
:properties:
|
||
:custom_id: h:2793a224-2109-4f61-a106-721c57c01375
|
||
:end:
|
||
#+cindex: Bold and italic fonts
|
||
|
||
The Modus themes do not hardcode a ~:weight~ or ~:slant~ attribute in the
|
||
thousands of faces they cover. Instead, they configure the generic
|
||
faces called ~bold~ and ~italic~ to use the appropriate styles and then
|
||
instruct all relevant faces that require emphasis to inherit from them.
|
||
|
||
This practically means that users can change the particularities of what
|
||
it means for a construct to be bold/italic, by tweaking the ~bold~ and
|
||
~italic~ faces. Cases where that can be useful include:
|
||
+ The default typeface does not have a variant with slanted glyphs
|
||
(e.g. Fira Mono/Code as of this writing on 2021-07-07), so the user
|
||
wants to add another family for the italics, such as Hack.
|
||
|
||
+ The typeface of choice provides a multitude of weights and the user
|
||
prefers the light one by default. To prevent the bold weight from
|
||
being too heavy compared to the light one, they opt to make ~bold~ use a
|
||
semibold weight.
|
||
|
||
+ The typeface distinguishes between oblique and italic forms by
|
||
providing different font variants (the former are just slanted
|
||
versions of the upright forms, while the latter have distinguishing
|
||
features as well). In this case, the user wants to specify the font
|
||
that applies to the ~italic~ face.
|
||
|
||
To achieve those effects, one must first be sure that the fonts they use
|
||
have support for those features. It then is a matter of following the
|
||
instructions for all typeface tweaks.
|
||
|
||
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
|
||
|
||
In this example, we set the default font family to Fira Code, while we
|
||
choose to render italics in the Hack typeface (obviously you need to
|
||
pick fonts that work well together):
|
||
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'default nil :family "Fira Code" :height 110)
|
||
(set-face-attribute 'italic nil :family "Hack")
|
||
#+end_src
|
||
|
||
And here we play with different weights, using Source Code Pro:
|
||
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'default nil :family "Source Code Pro" :height 110 :weight 'light)
|
||
(set-face-attribute 'bold nil :weight 'semibold)
|
||
#+end_src
|
||
|
||
To reset the font family, one can use this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(set-face-attribute 'italic nil :family 'unspecified)
|
||
#+end_src
|
||
|
||
To ensure that the effects persist after switching between the Modus
|
||
themes (such as with {{{kbd(M-x modus-themes-toggle)}}}), the user needs to
|
||
write their configurations to a function and pass it to the
|
||
~modus-themes-after-load-theme-hook~. This is necessary because themes
|
||
set the styles of faces upon activation, overriding prior values where
|
||
conflicts occur between the previous and the current states (otherwise
|
||
changing themes would not be possible).
|
||
|
||
[[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme loading]].
|
||
|
||
This is a minimal setup to preserve font configurations across theme
|
||
load phases. For a more permanent setup, it is better to rely on the
|
||
~custom-set-faces~ function: ~set-face-attribute~ works just fine, though it
|
||
probably is better suited for quick previews or for smaller scale
|
||
operations (~custom-set-faces~ follows the format used in the source code
|
||
of the themes, which can make it easier to redefine faces in bulk).
|
||
|
||
#+begin_src emacs-lisp
|
||
;; our generic function
|
||
(defun my-modes-themes-bold-italic-faces ()
|
||
(set-face-attribute 'default nil :family "Source Code Pro" :height 110)
|
||
(set-face-attribute 'bold nil :weight 'semibold))
|
||
|
||
;; or use this if you configure a lot of face and attributes and
|
||
;; especially if you plan to use `modus-themes-with-colors', as shown
|
||
;; elsewhere in the manual
|
||
(defun my-modes-themes-bold-italic-faces ()
|
||
(custom-set-faces
|
||
'(default ((t :family "Source Code Pro" :height 110)))
|
||
'(bold ((t :weight semibold)))))
|
||
|
||
;; and here is the hook
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modes-themes-bold-italic-faces)
|
||
#+end_src
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
** Custom Org todo keyword and priority faces
|
||
:properties:
|
||
:custom_id: h:89f0678d-c5c3-4a57-a526-668b2bb2d7ad
|
||
:end:
|
||
#+cindex: Org custom todo faces
|
||
|
||
Users of ~org-mode~ have the option to configure various keywords and
|
||
priority cookies to better match their workflow. User options are
|
||
~org-todo-keyword-faces~ and ~org-priority-faces~.
|
||
|
||
As those are meant to be custom faces, it is futile to have the themes
|
||
guess what each user wants to use, which keywords to target, and so on.
|
||
Instead, we can provide guidelines on how to customize things to one's
|
||
liking with the intent of retaining the overall aesthetic of the themes.
|
||
|
||
Please bear in mind that the end result of those is not controlled by
|
||
the active Modus theme but by how Org maps faces to its constructs.
|
||
Editing those while ~org-mode~ is active requires re-initialization of the
|
||
mode with {{{kbd(M-x org-mode-restart)}}} for changes to take effect.
|
||
|
||
Let us assume you wish to visually differentiate your keywords. You
|
||
have something like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-todo-keywords
|
||
'((sequence "TODO(t)" "|" "DONE(D)" "CANCEL(C)")
|
||
(sequence "MEET(m)" "|" "MET(M)")
|
||
(sequence "STUDY(s)" "|" "STUDIED(S)")
|
||
(sequence "WRITE(w)" "|" "WROTE(W)")))
|
||
#+end_src
|
||
|
||
You could then use a variant of the following to inherit from a face
|
||
that uses the styles you want and also to preserve the properties
|
||
applied by the ~org-todo~ face (in case there is a difference between the
|
||
two):
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-todo-keyword-faces
|
||
'(("MEET" . '(bold org-todo))
|
||
("STUDY" . '(warning org-todo))
|
||
("WRITE" . '(shadow org-todo))))
|
||
#+end_src
|
||
|
||
This will refashion the keywords you specify, while letting the other
|
||
items in ~org-todo-keywords~ use their original styles (which are defined
|
||
in the ~org-todo~ and ~org-done~ faces).
|
||
|
||
If you want back the defaults, try specifying just the ~org-todo~ face:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-todo-keyword-faces
|
||
'(("MEET" . org-todo)
|
||
("STUDY" . org-todo)
|
||
("WRITE" . org-todo)))
|
||
#+end_src
|
||
|
||
When you inherit from multiple faces, you need to quote the list as
|
||
shown further above. The order is significant: the first entry is
|
||
applied on top of the second, overriding any properties that are
|
||
explicitly set for both of them: any property that is not specified is
|
||
not overridden, so, for example, if ~org-todo~ has a background and a
|
||
foreground, while ~font-lock-type-face~ only has a foreground, the merged
|
||
face will include the background of the former and the foreground of the
|
||
latter. If you do not want to blend multiple faces, you do not need a
|
||
quoted list. A pattern of =keyword . face= will suffice.
|
||
|
||
Both approaches can be used simultaneously, as illustrated in this
|
||
configuration of the priority cookies:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-priority-faces
|
||
'((?A . '(bold org-priority))
|
||
(?B . org-priority)
|
||
(?C . '(shadow org-priority))))
|
||
#+end_src
|
||
|
||
To find all the faces that are loaded in your current Emacs session, use
|
||
{{{kbd(M-x list-faces-display)}}}. Try {{{kbd(M-x describe-variable)}}} as well and
|
||
then specify the name of each of those Org variables demonstrated above.
|
||
Their documentation strings will offer you further guidance.
|
||
|
||
Recall that the themes let you retrieve a color from their palette. Do
|
||
it if you plan to control face attributes.
|
||
|
||
[[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Custom face specs using the themes' palette]].
|
||
|
||
[[#h:02e25930-e71a-493d-828a-8907fc80f874][Check color combinations]].
|
||
|
||
** Custom Org emphasis faces
|
||
:properties:
|
||
:custom_id: h:26026302-47f4-4471-9004-9665470e7029
|
||
:end:
|
||
#+cindex: Org custom emphasis faces
|
||
|
||
Org provides the user option ~org-emphasis-alist~ which associates a
|
||
character with a face, list of faces, or face attributes. The default
|
||
specification of that variable looks like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-emphasis-alist
|
||
'(("*" bold)
|
||
("/" italic)
|
||
("_" underline)
|
||
("=" org-verbatim verbatim)
|
||
("~" org-code verbatim)
|
||
("+" (:strike-through t))))
|
||
#+end_src
|
||
|
||
With the exception of ~org-verbatim~ and ~org-code~ faces, everything else
|
||
uses the corresponding type of emphasis: a bold typographic weight, or
|
||
italicized, underlined, and struck through text.
|
||
|
||
The best way for users to add some extra attributes, such as a
|
||
foreground color, is to define their own faces and assign them to the
|
||
given emphasis marker/character.
|
||
|
||
This is a custom face that extends the standard ~bold~ face with a red
|
||
foreground value (so it colorises the text in addition to the bold
|
||
weight):
|
||
|
||
#+begin_src emacs-lisp
|
||
(defface my-org-emphasis-bold
|
||
'((default :inherit bold)
|
||
(((class color) (min-colors 88) (background light))
|
||
:foreground "#a60000")
|
||
(((class color) (min-colors 88) (background dark))
|
||
:foreground "#ff8059"))
|
||
"My bold emphasis for Org.")
|
||
#+end_src
|
||
|
||
This face definition reads as follows:
|
||
|
||
+ Always inherit the ~bold~ face ([[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]]).
|
||
+ For versions of Emacs that support at least 88 colors (graphical
|
||
Emacs, for example) and use a light background, apply the =#a60000=
|
||
value.
|
||
+ For the same kind of Emacs that has a dark background use the =#ff8059=
|
||
color instead.
|
||
|
||
Same principle for how to extend ~italic~ and ~underline~ with, for example,
|
||
green and yellow hues, respectively:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defface my-org-emphasis-italic
|
||
'((default :inherit italic)
|
||
(((class color) (min-colors 88) (background light))
|
||
:foreground "#005e00")
|
||
(((class color) (min-colors 88) (background dark))
|
||
:foreground "#44bc44"))
|
||
"My italic emphasis for Org.")
|
||
|
||
(defface my-org-emphasis-underline
|
||
'((default :inherit underline)
|
||
(((class color) (min-colors 88) (background light))
|
||
:foreground "#813e00")
|
||
(((class color) (min-colors 88) (background dark))
|
||
:foreground "#d0bc00"))
|
||
"My underline emphasis for Org.")
|
||
#+end_src
|
||
|
||
In the case of a strike-through effect, we have no generic face to
|
||
inherit from, so we can write it as follows to also change the
|
||
foreground to a more subtle gray:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defface my-org-emphasis-strike-through
|
||
'((default :strike-through t)
|
||
(((class color) (min-colors 88) (background light))
|
||
:foreground "#505050")
|
||
(((class color) (min-colors 88) (background dark))
|
||
:foreground "#a8a8a8"))
|
||
"My strike-through emphasis for Org.")
|
||
#+end_src
|
||
|
||
Or we can just change the color of the line that strikes through the
|
||
text to, for example, a shade of red:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defface my-org-emphasis-strike-through
|
||
'((((class color) (min-colors 88) (background light))
|
||
:strike-through "#972500")
|
||
(((class color) (min-colors 88) (background dark))
|
||
:strike-through "#ef8b50"))
|
||
"My strike-through emphasis for Org.")
|
||
#+end_src
|
||
|
||
It is possible to combine those effects:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defface my-org-emphasis-strike-through
|
||
'((((class color) (min-colors 88) (background light))
|
||
:strike-through "#972500" :foreground "#505050")
|
||
(((class color) (min-colors 88) (background dark))
|
||
:strike-through "#ef8b50" :foreground "#a8a8a8"))
|
||
"My strike-through emphasis for Org.")
|
||
#+end_src
|
||
|
||
One may inspect the variables ~modus-themes-operandi-colors~ and
|
||
~modus-themes-vivendi-colors~ for possible color values. Or call the
|
||
command ~modus-themes-list-colors~ to show a buffer that previews each
|
||
entry in the palette.
|
||
|
||
[[#h:f4d4b71b-2ca5-4c3d-b0b4-9bfd7aa7fb4d][Visualize the active Modus theme's palette]].
|
||
|
||
Once we have defined the faces we need, we must update the
|
||
~org-emphasis-alist~. Given that ~org-verbatim~ and ~org-code~ are already
|
||
styled by the themes, it probably is best not to edit them:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-emphasis-alist
|
||
'(("*" my-org-emphasis-bold)
|
||
("/" my-org-emphasis-italic)
|
||
("_" my-org-emphasis-underline)
|
||
("=" org-verbatim verbatim)
|
||
("~" org-code verbatim)
|
||
("+" my-org-emphasis-strike-through)))
|
||
#+end_src
|
||
|
||
That's it! For changes to take effect in already visited Org files,
|
||
invoke {{{kbd(M-x org-mode-restart)}}}.
|
||
|
||
** Update Org block delimiter fontification
|
||
:properties:
|
||
:custom_id: h:f44cc6e3-b0f1-4a5e-8a90-9e48fa557b50
|
||
:end:
|
||
|
||
As noted in the section about ~modus-themes-org-blocks~, Org contains a
|
||
variable that determines whether the block's begin and end lines are
|
||
extended to the edge of the window ([[#h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2][Option for org-mode block styles]]).
|
||
The variable is ~org-fontify-whole-block-delimiter-line~.
|
||
|
||
Users who change the style of Org blocks from time to time may prefer to
|
||
automatically update delimiter line fontification, such as with the
|
||
following setup:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-org-fontify-block-delimiter-lines ()
|
||
"Match `org-fontify-whole-block-delimiter-line' to theme style.
|
||
Run this function at the post theme load phase, such as with the
|
||
`modus-themes-after-load-theme-hook'."
|
||
(if (eq modus-themes-org-blocks 'gray-background)
|
||
(setq org-fontify-whole-block-delimiter-line t)
|
||
(setq org-fontify-whole-block-delimiter-line nil)))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook
|
||
#'my-modus-themes-org-fontify-block-delimiter-lines)
|
||
#+end_src
|
||
|
||
Then {{{kbd(M-x org-mode-restart)}}} for changes to take effect, though manual
|
||
intervention can be circumvented by tweaking the function thus:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-org-fontify-block-delimiter-lines ()
|
||
"Match `org-fontify-whole-block-delimiter-line' to theme style.
|
||
Run this function at the post theme load phase, such as with the
|
||
`modus-themes-after-load-theme-hook'."
|
||
(if (eq modus-themes-org-blocks 'gray-background)
|
||
(setq org-fontify-whole-block-delimiter-line t)
|
||
(setq org-fontify-whole-block-delimiter-line nil))
|
||
(when (derived-mode-p 'org-mode)
|
||
(font-lock-flush)))
|
||
#+end_src
|
||
|
||
** Measure color contrast
|
||
:properties:
|
||
:custom_id: h:02e25930-e71a-493d-828a-8907fc80f874
|
||
:end:
|
||
#+findex: modus-themes-contrast
|
||
#+findex: modus-themes-wcag-formula
|
||
#+cindex: Color contrast
|
||
|
||
The themes provide the functions ~modus-themes-wcag-formula~ and
|
||
~modus-themes-contrast~. The former is a direct implementation of the
|
||
WCAG formula: <https://www.w3.org/TR/WCAG20-TECHS/G18.html>. It
|
||
calculates the relative luminance of a color value that is expressed in
|
||
hexadecimal RGB notation. While the latter function is just a
|
||
convenient wrapper for comparing the relative luminance between two
|
||
colors.
|
||
|
||
In practice, one needs to work only with ~modus-themes-contrast~. It
|
||
accepts two color values and returns their contrast ratio. Values range
|
||
from 1 to 21 (lowest to highest). The themes are designed to always be
|
||
equal or higher than 7 for each combination of background and foreground
|
||
that they use (this is the WCAG AAA standard---the most demanding of its
|
||
kind).
|
||
|
||
A couple of examples (rounded numbers):
|
||
|
||
#+begin_src emacs-lisp
|
||
;; Pure white with pure green
|
||
(modus-themes-contrast "#ffffff" "#00ff00")
|
||
;; => 1.37
|
||
;; That is an outright inaccessible combo
|
||
|
||
;; Pure black with pure green
|
||
(modus-themes-contrast "#000000" "#00ff00")
|
||
;; => 15.3
|
||
;; That is a highly accessible combo
|
||
#+end_src
|
||
|
||
It does not matter which color value comes first. The ratio is always
|
||
the same.
|
||
|
||
If one does not wish to read all the decimal points, it is possible to
|
||
try something like this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(format "%0.2f" (modus-themes-contrast "#000000" "#00ff00"))
|
||
#+end_src
|
||
|
||
While it is fine to perform such calculations on a case-by-case basis,
|
||
it is preferable to implement formulas and tables for more demanding
|
||
tasks. Such instruments are provided by ~org-mode~ or ~orgtbl-mode~, both
|
||
of which are built into Emacs. Below is such a table that derives the
|
||
contrast ratio of all colors in the first column (pure red, green, blue)
|
||
relative to the color specified in the first row of the second column
|
||
(pure white) and rounds the results:
|
||
|
||
#+begin_example
|
||
| | #ffffff |
|
||
|---------+---------|
|
||
| #ff0000 | 4.00 |
|
||
| #00ff00 | 1.37 |
|
||
| #0000ff | 8.59 |
|
||
#+tblfm: $2='(modus-themes-contrast $1 @1$2);%0.2f
|
||
#+end_example
|
||
|
||
To measure color contrast one needs to start from a known value. This
|
||
typically is the background. The Modus themes define an expanded
|
||
palette in large part because certain colors are only meant to be used
|
||
in combination with some others. Consult the source code for the
|
||
minutia and relevant commentary.
|
||
|
||
Such knowledge may prove valuable while attempting to override some of
|
||
the themes' colors: [[#h:307d95dd-8dbd-4ece-a543-10ae86f155a6][Override colors]].
|
||
|
||
** Load theme depending on time of day
|
||
:properties:
|
||
:custom_id: h:1d1ef4b4-8600-4a09-993c-6de3af0ddd26
|
||
:end:
|
||
|
||
While we do provide ~modus-themes-toggle~ to manually switch between the
|
||
themes, users may also set up their system to perform such a task
|
||
automatically at sunrise and sunset.
|
||
|
||
This can be accomplished by specifying the coordinates of one's location
|
||
using the built-in {{{file(solar.el)}}} and then configuring the =circadian=
|
||
package:
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package solar ; built-in
|
||
:config
|
||
(setq calendar-latitude 35.17
|
||
calendar-longitude 33.36))
|
||
|
||
(use-package circadian ; you need to install this
|
||
:ensure
|
||
:after solar
|
||
:config
|
||
(setq circadian-themes '((:sunrise . modus-operandi)
|
||
(:sunset . modus-vivendi)))
|
||
(circadian-setup))
|
||
#+end_src
|
||
|
||
** Backdrop for pdf-tools
|
||
:properties:
|
||
:custom_id: h:ff69dfe1-29c0-447a-915c-b5ff7c5509cd
|
||
:end:
|
||
#+cindex: Remapping pdf-tools backdrop
|
||
|
||
Most PDF files use a white background for their page, making it
|
||
impossible to discern the file's boundaries in the buffer while using
|
||
the Modus Operandi theme. To introduce a distinction between the
|
||
buffer's backdrop and the PDF page's background, the former must be
|
||
rendered as some shade of gray. Ideally, ~pdf-tools~ would provide a face
|
||
that the themes could support directly, though this does not seem to be
|
||
the case for the time being. We must thus employ the face remapping
|
||
technique that is documented elsewhere in this document to change the
|
||
buffer-local value of the ~default~ face.
|
||
|
||
[[#h:7a93cb6f-4eca-4d56-a85c-9dcd813d6b0f][Remap face with local value]].
|
||
|
||
To remap the buffer's backdrop, we start with a function like this one:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-pdf-tools-backdrop ()
|
||
(face-remap-add-relative
|
||
'default
|
||
`(:background ,(modus-themes-color 'bg-alt))))
|
||
|
||
(add-hook 'pdf-tools-enabled-hook #'my-pdf-tools-backdrop)
|
||
#+end_src
|
||
|
||
The idea is to assign that function to a hook that gets called when
|
||
~pdf-tools~ renders the document: ~pdf-tools-enabled-hook~. This is enough
|
||
when you only use one theme. However it has the downside of setting the
|
||
background color value only at render time. In other words, the face
|
||
remapping function does not get evaluated anew whenever the theme
|
||
changes, such as upon invoking {{{kbd(M-x modus-themes-toggle)}}}.
|
||
|
||
To have our face remapping adapt gracefully while switching between the
|
||
Modus themes, we need to also account for the current theme and control
|
||
the activation of ~pdf-view-midnight-minor-mode~. To which end we arrive
|
||
at something like the following, which builds on the above example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-pdf-tools-backdrop ()
|
||
(face-remap-add-relative
|
||
'default
|
||
`(:background ,(modus-themes-color 'bg-alt))))
|
||
|
||
(defun my-pdf-tools-midnight-mode-toggle ()
|
||
(when (derived-mode-p 'pdf-view-mode)
|
||
(if (eq (car custom-enabled-themes) 'modus-vivendi)
|
||
(pdf-view-midnight-minor-mode 1)
|
||
(pdf-view-midnight-minor-mode -1))
|
||
(my-pdf-tools-backdrop)))
|
||
|
||
(defun my-pdf-tools-themes-toggle ()
|
||
(mapc
|
||
(lambda (buf)
|
||
(with-current-buffer buf
|
||
(my-pdf-tools-midnight-mode-toggle)))
|
||
(buffer-list)))
|
||
|
||
(add-hook 'pdf-tools-enabled-hook #'my-pdf-tools-midnight-mode-toggle)
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-pdf-tools-themes-toggle)
|
||
#+end_src
|
||
|
||
With those in place, PDFs have a distinct backdrop for their page, while
|
||
buffers with major-mode as ~pdf-view-mode~ automatically switches to dark
|
||
mode when ~modus-themes-toggle~ is called.
|
||
|
||
** Decrease mode line height
|
||
:properties:
|
||
:custom_id: h:03be4438-dae1-4961-9596-60a307c070b5
|
||
:end:
|
||
#+cindex: Decrease mode line height
|
||
|
||
By default, the mode line of the Modus themes is set to 1 pixel width
|
||
for its =:box= attribute. In contrast, the mode line of stock Emacs is -1
|
||
pixel. This small difference is considered necessary for the purposes
|
||
of accessibility as our out-of-the-box design has a prominent color
|
||
around the mode line (a border) to make its boundaries clear. With a
|
||
negative width the border and the text on the mode line can feel a bit
|
||
more difficult to read under certain scenaria.
|
||
|
||
Furthermore, the user option ~modus-themes-mode-line~ ([[#h:27943af6-d950-42d0-bc23-106e43f50a24][Mode line]]) does not
|
||
allow for such a negative value because there are many edge cases that
|
||
simply make for a counter-intuitive set of possibilities, such as a =0=
|
||
value not being acceptable by the underlying face infrastructure, and
|
||
negative values greater than =-2= not being particularly usable.
|
||
|
||
For these reasons, users who wish to decrease the overall height of the
|
||
mode line must handle things on their own by implementing the methods
|
||
for face customization documented herein.
|
||
|
||
[[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Basic face customization]].
|
||
|
||
One such method is to create a function that configures the desired
|
||
faces and hook it to ~modus-themes-after-load-theme-hook~ so that it
|
||
persists while switching between the Modus themes with the command
|
||
~modus-themes-toggle~.
|
||
|
||
This one simply disables the box altogether, which will reduce the
|
||
height of the mode lines, but also remove their border:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(set-face-attribute 'mode-line nil :box nil)
|
||
(set-face-attribute 'mode-line-inactive nil :box nil))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
The above relies on the ~set-face-attribute~ function, though users who
|
||
plan to re-use colors from the theme and do so at scale are better off
|
||
with the more streamlined combination of the ~modus-themes-with-colors~
|
||
macro and ~custom-set-faces~.
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face customization at scale]].
|
||
|
||
As explained before in this document, this approach has a syntax that is
|
||
consistent with the source code of the themes, so it probably is easier
|
||
to re-use parts of the design.
|
||
|
||
The following emulates the stock Emacs style, while still using the
|
||
colors of the Modus themes (whichever attribute is not explicitly stated
|
||
is inherited from the underlying theme):
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(mode-line ((,class :box (:line-width -1 :style released-button))))
|
||
`(mode-line-inactive ((,class :box (:line-width -1 :color ,bg-region)))))))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
And this one is like the out-of-the-box style of the Modus themes, but
|
||
with the -1 height instead of 1:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(mode-line ((,class :box (:line-width -1 :color ,fg-alt))))
|
||
`(mode-line-inactive ((,class :box (:line-width -1 :color ,bg-region)))))))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
Finally, to also change the background color of the active mode line,
|
||
such as that it looks like the "accented" variant which is possible via
|
||
the user option ~modus-themes-mode-line~, the =:background= attribute needs
|
||
to be specified as well:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(mode-line ((,class :box (:line-width -1 :color ,fg-alt) :background ,bg-active-accent)))
|
||
`(mode-line-inactive ((,class :box (:line-width -1 :color ,bg-region)))))))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
** Toggle themes without reloading them
|
||
:properties:
|
||
:custom_id: h:b40aca50-a3b2-4c43-be58-2c26fcd14237
|
||
:end:
|
||
#+cindex: Switch themes without load-theme
|
||
|
||
Users who have a stable setup and who only ever need to toggle between
|
||
the themes without triggering a full reload, are better off defining
|
||
their own command which calls ~enable-theme~ instead of ~load-theme~:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-toggle ()
|
||
"Toggle between `modus-operandi' and `modus-vivendi' themes.
|
||
This uses `enable-theme' instead of the standard method of
|
||
`load-theme'. The technicalities are covered in the Modus themes
|
||
manual."
|
||
(interactive)
|
||
(pcase (modus-themes--current-theme)
|
||
('modus-operandi (progn (enable-theme 'modus-vivendi)
|
||
(disable-theme 'modus-operandi)))
|
||
('modus-vivendi (progn (enable-theme 'modus-operandi)
|
||
(disable-theme 'modus-vivendi)))
|
||
(_ (error "No Modus theme is loaded; evaluate `modus-themes-load-themes' first"))))
|
||
#+end_src
|
||
|
||
[[#h:e68560b3-7fb0-42bc-a151-e015948f8a35][Differences between loading and enabling]].
|
||
|
||
Recall that ~modus-themes-toggle~ uses ~load-theme~.
|
||
|
||
** A theme-agnostic hook for theme loading
|
||
:properties:
|
||
:custom_id: h:86f6906b-f090-46cc-9816-1fe8aeb38776
|
||
:end:
|
||
|
||
The themes are designed with the intent to be useful to Emacs users of
|
||
varying skill levels, from beginners to experts. This means that we try
|
||
to make things easier by not expecting anyone reading this document to
|
||
be proficient in Emacs Lisp or programming in general.
|
||
|
||
Such a case is with the use of the ~modus-themes-after-load-theme-hook~,
|
||
which runs after ~modus-themes-toggle~, ~modus-themes-load-operandi~, or
|
||
~modus-themes-load-vivendi~ is evaluated. We recommend using that hook
|
||
for advanced customizations, because (1) we know for sure that it is
|
||
available once the themes are loaded, and (2) anyone consulting this
|
||
manual, especially the sections on enabling and loading the themes, will
|
||
be in a good position to benefit from that hook.
|
||
|
||
Advanced users who have a need to switch between the Modus themes and
|
||
other items will find that such a hook does not meet their requirements:
|
||
it only works with the Modus themes and only with the aforementioned
|
||
functions.
|
||
|
||
A theme-agnostic setup can be configured thus:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defvar after-enable-theme-hook nil
|
||
"Normal hook run after enabling a theme.")
|
||
|
||
(defun run-after-enable-theme-hook (&rest _args)
|
||
"Run `after-enable-theme-hook'."
|
||
(run-hooks 'after-enable-theme-hook))
|
||
|
||
(advice-add 'enable-theme :after #'run-after-enable-theme-hook)
|
||
#+end_src
|
||
|
||
This creates the ~after-enable-theme-hook~ and makes it run after each
|
||
call to ~enable-theme~, which means that it will work for all themes and
|
||
also has the benefit that it does not depend on functions such as
|
||
~modus-themes-toggle~ and the others mentioned above. ~enable-theme~ is
|
||
called internally by ~load-theme~, so the hook works everywhere.
|
||
|
||
Now this specific piece of Elisp may be simple for experienced users,
|
||
but it is not easy to read for newcomers, including the author of the
|
||
Modus themes for the first several months of their time as an Emacs
|
||
user. Hence our hesitation to recommend it as part of the standard
|
||
setup of the Modus themes (it is generally a good idea to understand
|
||
what the implications are of advising a function).
|
||
|
||
** Diffs with only the foreground
|
||
:properties:
|
||
:custom_id: h:e2aed9eb-5e1e-45ec-bbd7-bc4faeab3236
|
||
:end:
|
||
#+cindex: Foreground-only diffs
|
||
|
||
Buffers that show differences between versions of a file or buffer, such
|
||
as in ~diff-mode~ and ~ediff~ always use color-coded background and
|
||
foreground combinations.
|
||
|
||
[[#h:ea7ac54f-5827-49bd-b09f-62424b3b6427][Option for diff buffer looks]].
|
||
|
||
User may, however, prefer a style that removes the color-coded
|
||
backgrounds from regular changes while keeping them for word-wise (aka
|
||
"refined") changes---backgrounds for word-wise diffs are helpful in
|
||
context. To make this happen, one can use the ~modus-themes-with-colors~
|
||
macro ([[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]]):
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(modus-themes-diff-added ((,class :background unspecified :foreground ,green))) ; OR ,blue for deuteranopia
|
||
`(modus-themes-diff-changed ((,class :background unspecified :foreground ,yellow)))
|
||
`(modus-themes-diff-removed ((,class :background unspecified :foreground ,red)))
|
||
|
||
`(modus-themes-diff-refine-added ((,class :background ,bg-diff-added :foreground ,fg-diff-added)))
|
||
;; `(modus-themes-diff-refine-added ((,class :background ,bg-diff-added-deuteran :foreground ,fg-diff-added-deuteran)))
|
||
`(modus-themes-diff-refine-changed ((,class :background ,bg-diff-changed :foreground ,fg-diff-changed)))
|
||
`(modus-themes-diff-refine-removed ((,class :background ,bg-diff-removed :foreground ,fg-diff-removed)))
|
||
|
||
`(modus-themes-diff-focus-added ((,class :background ,bg-dim :foreground ,green))) ; OR ,blue for deuteranopia
|
||
`(modus-themes-diff-focus-changed ((,class :background ,bg-dim :foreground ,yellow)))
|
||
`(modus-themes-diff-focus-removed ((,class :background ,bg-dim :foreground ,red)))
|
||
|
||
`(modus-themes-diff-heading ((,class :background ,bg-alt :foreground ,fg-main)))
|
||
|
||
`(diff-indicator-added ((,class :foreground ,green))) ; OR ,blue for deuteranopia
|
||
`(diff-indicator-changed ((,class :foreground ,yellow)))
|
||
`(diff-indicator-removed ((,class :foreground ,red)))
|
||
|
||
`(magit-diff-added ((,class :background unspecified :foreground ,green-faint)))
|
||
`(magit-diff-changed ((,class :background unspecified :foreground ,yellow-faint)))
|
||
`(magit-diff-removed ((,class :background unspecified :foreground ,red-faint)))
|
||
`(magit-diff-context-highlight ((,class :background ,bg-dim :foreground ,fg-dim))))))
|
||
|
||
;; This is so that the changes persist when switching between
|
||
;; `modus-operandi' and `modus-vivendi'.
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
This used to be an optional style of ~modus-themes-diffs~, but has been
|
||
removed since version =2.0.0= to ensure that the accessibility standard
|
||
and aesthetic quality of the themes is not compromised.
|
||
|
||
** Ediff without diff color-coding
|
||
:properties:
|
||
:custom_id: h:b0b31802-0216-427e-b071-1a47adcfe608
|
||
:end:
|
||
|
||
Ediff uses the same color-coding as ordinary diffs in ~diff-mode~, Magit,
|
||
etc. ([[#h:ea7ac54f-5827-49bd-b09f-62424b3b6427][Option for diff buffer looks]]). This is consistent with the
|
||
principle of least surprise.
|
||
|
||
Users may, however, prefer to treat Ediff differently on the premise
|
||
that it does not need any particular color-coding to show added or
|
||
removed lines/words: it does not use the =+= or =-= markers, after all.
|
||
|
||
This can be achieved by customizing the Ediff faces with color
|
||
combinations that do not carry the same connotations as those of diffs.
|
||
Consider this example, which leverages the ~modus-themes-with-colors~
|
||
macro ([[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]]):
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(ediff-current-diff-A ((,class :inherit unspecified :background ,bg-special-faint-cold :foreground ,fg-special-cold)))
|
||
`(ediff-current-diff-B ((,class :inherit unspecified :background ,bg-special-faint-warm :foreground ,fg-special-warm)))
|
||
`(ediff-current-diff-C ((,class :inherit unspecified :background ,bg-special-faint-calm :foreground ,fg-special-calm)))
|
||
`(ediff-fine-diff-A ((,class :inherit unspecified :background ,bg-special-cold :foreground ,fg-special-cold)))
|
||
`(ediff-fine-diff-B ((,class :inherit unspecified :background ,bg-special-warm :foreground ,fg-special-warm)))
|
||
`(ediff-fine-diff-C ((,class :inherit unspecified :background ,bg-special-calm :foreground ,fg-special-calm))))))
|
||
|
||
;; This is so that the changes persist when switching between
|
||
;; `modus-operandi' and `modus-vivendi'.
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
Remove the =:foreground= and its value to preserve the underlying
|
||
coloration.
|
||
|
||
[[#h:f4d4b71b-2ca5-4c3d-b0b4-9bfd7aa7fb4d][Visualize the active Modus theme's palette]].
|
||
|
||
** Near-monochrome syntax highlighting
|
||
:properties:
|
||
:custom_id: h:c1f3fa8e-7a63-4a6f-baf3-a7febc0661f0
|
||
:end:
|
||
#+cindex: Monochrome code syntax
|
||
|
||
While the Modus themes do provide a user option to control the overall
|
||
style of syntax highlighting in programming major modes, they do not
|
||
cover the possibility of a monochromatic or near-monochromatic design
|
||
([[#h:c119d7b2-fcd4-4e44-890e-5e25733d5e52][Option for syntax highlighting]]). This is due to the multitude of
|
||
preferences involved: one may like comments to be styled with an accent
|
||
value, another may want certain constructs to be bold, a third may apply
|
||
italics to doc strings but not comments... The possibilities are
|
||
virtually endless. As such, this sort of design is best handled at the
|
||
user level in accordance with the information furnished elsewhere in
|
||
this manual.
|
||
|
||
[[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Case-by-case face specs using the themes' palette]].
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
The gist is that we want to override the font-lock faces. For our
|
||
changes to persist while switching between ~modus-operandi~ and
|
||
~modus-vivendi~ we wrap our face overrides in a function that we hook to
|
||
~modus-themes-after-load-theme-hook~.
|
||
|
||
Users who want to replicate the structure of the themes' source code are
|
||
advised to use the examples with ~custom-set-faces~. Those who prefer a
|
||
different approach can use the snippets which call ~set-face-attribute~.
|
||
Below are the code blocks.
|
||
|
||
The following uses a yellow accent value for comments and green hues for
|
||
strings. Regexp grouping constructs have color values that work in the
|
||
context of a green string. All other elements use the main foreground
|
||
color, except warnings such as the ~user-error~ function in Elisp
|
||
buffers which gets a subtle red tint (not to be confused with the
|
||
~warning~ face which is used for genuine warnings). Furthermore, notice
|
||
the ~modus-themes-bold~ and ~modus-themes-slant~ which apply the
|
||
preference set in the user options ~modus-themes-bold-constructs~ and
|
||
~modus-themes-italic-constructs~, respectively. Users who do not want
|
||
this conditionally must replace these faces with ~bold~ and ~italic~
|
||
respectively (or ~unspecified~ to disable the effect altogether).
|
||
|
||
#+begin_src emacs-lisp
|
||
;; This is the hook. It will not be replicated across all code samples.
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-subtle-syntax)
|
||
|
||
(defun my-modus-themes-subtle-syntax ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(font-lock-builtin-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-comment-delimiter-face ((,class :inherit font-lock-comment-face)))
|
||
`(font-lock-comment-face ((,class :inherit unspecified :foreground ,fg-comment-yellow)))
|
||
`(font-lock-constant-face ((,class :foreground unspecified)))
|
||
`(font-lock-doc-face ((,class :inherit modus-themes-slant :foreground ,fg-special-mild)))
|
||
`(font-lock-function-name-face ((,class :foreground unspecified)))
|
||
`(font-lock-keyword-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-negation-char-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-preprocessor-face ((,class :foreground unspecified)))
|
||
`(font-lock-regexp-grouping-backslash ((,class :inherit bold :foreground ,yellow)))
|
||
`(font-lock-regexp-grouping-construct ((,class :inherit bold :foreground ,blue-alt-other)))
|
||
`(font-lock-string-face ((,class :foreground ,green-alt-other)))
|
||
`(font-lock-type-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-variable-name-face ((,class :foreground unspecified)))
|
||
`(font-lock-warning-face ((,class :inherit modus-themes-bold :foreground ,red-nuanced-fg))))))
|
||
|
||
;; Same as above with `set-face-attribute' instead of `custom-set-faces'
|
||
(defun my-modus-themes-subtle-syntax ()
|
||
(modus-themes-with-colors
|
||
(set-face-attribute 'font-lock-builtin-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-comment-delimiter-face nil :inherit 'font-lock-comment-face)
|
||
(set-face-attribute 'font-lock-comment-face nil :inherit 'unspecified :foreground fg-comment-yellow)
|
||
(set-face-attribute 'font-lock-constant-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-doc-face nil :inherit 'modus-themes-slant :foreground fg-special-mild)
|
||
(set-face-attribute 'font-lock-function-name-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-keyword-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-negation-char-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-preprocessor-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-regexp-grouping-backslash nil :inherit 'bold :foreground yellow)
|
||
(set-face-attribute 'font-lock-regexp-grouping-construct nil :inherit 'bold :foreground blue-alt-other)
|
||
(set-face-attribute 'font-lock-string-face nil :foreground green-alt-other)
|
||
(set-face-attribute 'font-lock-type-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-variable-name-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-warning-face nil :inherit 'modus-themes-bold :foreground red-nuanced-fg)))
|
||
#+end_src
|
||
|
||
The following sample is the same as above, except strings are blue and
|
||
comments are gray. Regexp constructs are adapted accordingly.
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-subtle-syntax ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(font-lock-builtin-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-comment-delimiter-face ((,class :inherit font-lock-comment-face)))
|
||
`(font-lock-comment-face ((,class :inherit unspecified :foreground ,fg-alt)))
|
||
`(font-lock-constant-face ((,class :foreground unspecified)))
|
||
`(font-lock-doc-face ((,class :inherit modus-themes-slant :foreground ,fg-docstring)))
|
||
`(font-lock-function-name-face ((,class :foreground unspecified)))
|
||
`(font-lock-keyword-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-negation-char-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-preprocessor-face ((,class :foreground unspecified)))
|
||
`(font-lock-regexp-grouping-backslash ((,class :inherit bold :foreground ,fg-escape-char-backslash)))
|
||
`(font-lock-regexp-grouping-construct ((,class :inherit bold :foreground ,fg-escape-char-construct)))
|
||
`(font-lock-string-face ((,class :foreground ,blue-alt)))
|
||
`(font-lock-type-face ((,class :inherit modus-themes-bold :foreground unspecified)))
|
||
`(font-lock-variable-name-face ((,class :foreground unspecified)))
|
||
`(font-lock-warning-face ((,class :inherit modus-themes-bold :foreground ,red-nuanced-fg))))))
|
||
|
||
;; Same as above with `set-face-attribute' instead of `custom-set-faces'
|
||
(defun my-modus-themes-subtle-syntax ()
|
||
(modus-themes-with-colors
|
||
(set-face-attribute 'font-lock-builtin-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-comment-delimiter-face nil :inherit 'font-lock-comment-face)
|
||
(set-face-attribute 'font-lock-comment-face nil :inherit 'unspecified :foreground fg-alt)
|
||
(set-face-attribute 'font-lock-constant-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-doc-face nil :inherit 'modus-themes-slant :foreground fg-docstring)
|
||
(set-face-attribute 'font-lock-function-name-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-keyword-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-negation-char-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-preprocessor-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-regexp-grouping-backslash nil :inherit 'bold :foreground fg-escape-char-backslash)
|
||
(set-face-attribute 'font-lock-regexp-grouping-construct nil :inherit 'bold :foreground fg-escape-char-construct)
|
||
(set-face-attribute 'font-lock-string-face nil :foreground blue-alt)
|
||
(set-face-attribute 'font-lock-type-face nil :inherit 'modus-themes-bold :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-variable-name-face nil :foreground 'unspecified)
|
||
(set-face-attribute 'font-lock-warning-face nil :inherit 'modus-themes-bold :foreground red-nuanced-fg)))
|
||
#+end_src
|
||
|
||
** Custom hl-todo colors
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:2ef83a21-2f0a-441e-9634-473feb940743
|
||
:END:
|
||
|
||
The =hl-todo= package provides the user option ~hl-todo-keyword-faces~:
|
||
it specifies a pair of keyword and corresponding color value. The Modus
|
||
themes configure that option in the interest of legibility. While this
|
||
works for our purposes, users may still prefer to apply their custom
|
||
values, in which case the following approach is necessary:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-hl-todo-faces ()
|
||
(setq hl-todo-keyword-faces '(("TODO" . "#ff0000")
|
||
("HACK" . "#ffff00")
|
||
("XXX" . "#00ffff")
|
||
("NOTE" . "#ff00ff"))))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-hl-todo-faces)
|
||
#+end_src
|
||
|
||
Or include a ~let~ form, if needed:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-hl-todo-faces ()
|
||
(let ((red "#ff0000")
|
||
(blue "#0000ff"))
|
||
(setq hl-todo-keyword-faces `(("TODO" . ,blue)
|
||
("HACK" . ,red)
|
||
("XXX" . ,red)
|
||
("NOTE" . ,blue)))))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-hl-todo-faces)
|
||
#+end_src
|
||
|
||
Normally, we do not touch user options, though this is an exception:
|
||
otherwise the defaults are not always legible.
|
||
|
||
** Add support for solaire-mode
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:439c9e46-52e2-46be-b1dc-85841dd99671
|
||
:END:
|
||
|
||
The =solaire-mode= package dims the background of what it considers
|
||
ancillary "UI" buffers, such as the minibuffer and Dired buffers. The
|
||
Modus themes used to support Solaire on the premise that the user was
|
||
(i) opting in to it, (ii) understood why certain buffers were more gray,
|
||
and (iii) knew what other adjustments had to be made to prevent broken
|
||
visuals (e.g. the default style of the ~modus-themes-completions~ uses a
|
||
subtle gray background for the selection, which with Solaire becomes
|
||
practically invisible).
|
||
|
||
However, the assumption that users opt in to this feature does not
|
||
always hold true. There are cases where it is enabled by defaultsuch as
|
||
in the popular Doom Emacs configuration. Thus, the unsuspecting user
|
||
who loads ~modus-operandi~ or ~modus-vivendi~ without the requisite
|
||
customizations is getting a sub-par experience; an experience that we
|
||
did not intend and cannot genuinely fix.
|
||
|
||
Because the Modus themes are meant to work everywhere, we cannot make an
|
||
exception for Doom Emacs and/or Solaire users. Furthermore, we shall
|
||
not introduce hacks, such as by adding a check in all relevant faces to
|
||
be adjusted based on Solaire or whatever other package. Hacks of this
|
||
sort are unsustainable and penalize the entire userbase. Besides, the
|
||
themes are built into Emacs and we must keep their standard high.
|
||
|
||
The fundamental constraint with Solaire is that Emacs does not have a
|
||
real distinction between "content" and "UI" buffers. For themes to work
|
||
with Solaire, they need to be designed around that package. Such is an
|
||
arrangement that compromises on our accessibility standards and/or
|
||
hinders our efforts to provide the best possible experience while using
|
||
the Modus themes.
|
||
|
||
As such, =solaire-mode= is not---and will not be---supported by the
|
||
Modus themes (or any other of my themes, for that matter). Users who
|
||
want it must style the faces manually. Below is some sample code, based
|
||
on what we cover at length elsewhere in this manual:
|
||
|
||
[[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]].
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(solaire-default-face ((,class :inherit default :background ,bg-alt :foreground ,fg-dim)))
|
||
`(solaire-line-number-face ((,class :inherit solaire-default-face :foreground ,fg-unfocused)))
|
||
`(solaire-hl-line-face ((,class :background ,bg-active)))
|
||
`(solaire-org-hide-face ((,class :background ,bg-alt :foreground ,bg-alt))))))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
As always, re-load the theme for changes to take effect.
|
||
|
||
* Face coverage
|
||
:properties:
|
||
:custom_id: h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19
|
||
:end:
|
||
|
||
The Modus themes try to provide as close to full face coverage as
|
||
possible. This is necessary to ensure a consistently accessible reading
|
||
experience across all available interfaces.
|
||
|
||
** Full support for packages or face groups
|
||
:properties:
|
||
:alt_title: Supported packages
|
||
:description: Full list of covered face groups
|
||
:custom_id: h:60ed4275-60d6-49f8-9287-9a64e54bea0e
|
||
:end:
|
||
#+cindex: Explicitly supported packages
|
||
|
||
This list will always be updated to reflect the current state of the
|
||
project. The idea is to offer an overview of the known status of all
|
||
affected face groups. The items with an appended asterisk =*= tend to
|
||
have lots of extensions, so the "full support" may not be 100% true…
|
||
+ ace-window
|
||
+ alert
|
||
+ all-the-icons
|
||
+ all-the-icons-dired
|
||
+ all-the-icons-ibuffer
|
||
+ annotate
|
||
+ ansi-color
|
||
+ anzu
|
||
+ apropos
|
||
+ artbollocks-mode
|
||
+ auctex and TeX
|
||
+ auto-dim-other-buffers
|
||
+ avy
|
||
+ awesome-tray
|
||
+ bbdb
|
||
+ binder
|
||
+ bm
|
||
+ bongo
|
||
+ boon
|
||
+ bookmark
|
||
+ breakpoint (provided by the built-in {{{file(gdb-mi.el)}}} library)
|
||
+ calendar and diary
|
||
+ calfw
|
||
+ calibredb
|
||
+ centaur-tabs
|
||
+ cfrs
|
||
+ change-log and log-view (such as ~vc-print-log~, ~vc-print-root-log~)
|
||
+ chart
|
||
+ cider
|
||
+ circe
|
||
+ citar
|
||
+ color-rg
|
||
+ column-enforce-mode
|
||
+ company-mode*
|
||
+ company-posframe
|
||
+ compilation-mode
|
||
+ completions
|
||
+ consult
|
||
+ corfu
|
||
+ corfu-quick
|
||
+ counsel*
|
||
+ counsel-css
|
||
+ cov
|
||
+ cperl-mode
|
||
+ crontab-mode
|
||
+ css-mode
|
||
+ csv-mode
|
||
+ ctrlf
|
||
+ custom (what you get with {{{kbd(M-x customize)}}})
|
||
+ dap-mode
|
||
+ deadgrep
|
||
+ debbugs
|
||
+ deft
|
||
+ denote
|
||
+ devdocs
|
||
+ dictionary
|
||
+ diff-hl
|
||
+ diff-mode
|
||
+ dim-autoload
|
||
+ dir-treeview
|
||
+ dired
|
||
+ dired-async
|
||
+ dired-git
|
||
+ dired-git-info
|
||
+ dired-narrow
|
||
+ dired-subtree
|
||
+ diredfl
|
||
+ diredp (dired+)
|
||
+ display-fill-column-indicator-mode
|
||
+ doom-modeline
|
||
+ easy-jekyll
|
||
+ ebdb
|
||
+ ediff
|
||
+ ein (Emacs IPython Notebook)
|
||
+ eglot
|
||
+ el-search
|
||
+ eldoc-box
|
||
+ elfeed
|
||
+ elfeed-score
|
||
+ elpher
|
||
+ embark
|
||
+ ement
|
||
+ emms
|
||
+ enh-ruby-mode (enhanced-ruby-mode)
|
||
+ epa
|
||
+ equake
|
||
+ erc
|
||
+ eros
|
||
+ ert
|
||
+ eshell
|
||
+ eshell-fringe-status
|
||
+ eshell-git-prompt
|
||
+ eshell-prompt-extras (epe)
|
||
+ eshell-syntax-highlighting
|
||
+ evil* (evil-mode)
|
||
+ evil-goggles
|
||
+ evil-snipe
|
||
+ evil-visual-mark-mode
|
||
+ eww
|
||
+ exwm
|
||
+ eyebrowse
|
||
+ fancy-dabbrev
|
||
+ flycheck
|
||
+ flycheck-color-mode-line
|
||
+ flycheck-indicator
|
||
+ flycheck-posframe
|
||
+ flymake
|
||
+ flyspell
|
||
+ flx
|
||
+ freeze-it
|
||
+ focus
|
||
+ fold-this
|
||
+ font-lock (generic syntax highlighting)
|
||
+ forge
|
||
+ fountain (fountain-mode)
|
||
+ geiser
|
||
+ git-commit
|
||
+ git-gutter (and variants)
|
||
+ git-rebase
|
||
+ git-timemachine
|
||
+ gnus
|
||
+ gotest
|
||
+ golden-ratio-scroll-screen
|
||
+ helm*
|
||
+ helm-ls-git
|
||
+ helm-switch-shell
|
||
+ helm-xref
|
||
+ helpful
|
||
+ highlight-indentation
|
||
+ highlight-numbers
|
||
+ highlight-parentheses ([[#h:24bab397-dcb2-421d-aa6e-ec5bd622b913][Note on highlight-parentheses.el]])
|
||
+ highlight-thing
|
||
+ hl-defined
|
||
+ hl-fill-column
|
||
+ hl-line-mode
|
||
+ hl-todo
|
||
+ hydra
|
||
+ ibuffer
|
||
+ icomplete
|
||
+ icomplete-vertical
|
||
+ ido-mode
|
||
+ iedit
|
||
+ iflipb
|
||
+ image-dired
|
||
+ imenu-list
|
||
+ indium
|
||
+ info
|
||
+ info+ (info-plus)
|
||
+ info-colors
|
||
+ interaction-log
|
||
+ ioccur
|
||
+ isearch, occur, etc.
|
||
+ ivy*
|
||
+ ivy-posframe
|
||
+ jira (org-jira)
|
||
+ journalctl-mode
|
||
+ js2-mode
|
||
+ julia
|
||
+ jupyter
|
||
+ kaocha-runner
|
||
+ keycast
|
||
+ ledger-mode
|
||
+ leerzeichen
|
||
+ line numbers (~display-line-numbers-mode~ and global variant)
|
||
+ lsp-mode
|
||
+ lsp-ui
|
||
+ macrostep
|
||
+ magit
|
||
+ magit-imerge
|
||
+ make-mode
|
||
+ man
|
||
+ marginalia
|
||
+ markdown-mode
|
||
+ markup-faces (~adoc-mode~)
|
||
+ mentor
|
||
+ messages
|
||
+ mini-modeline
|
||
+ minimap
|
||
+ mmm-mode
|
||
+ mode-line
|
||
+ mood-line
|
||
+ moody
|
||
+ mpdel
|
||
+ mu4e
|
||
+ multiple-cursors
|
||
+ nano-modeline
|
||
+ neotree
|
||
+ notmuch
|
||
+ num3-mode
|
||
+ nxml-mode
|
||
+ olivetti
|
||
+ orderless
|
||
+ org*
|
||
+ org-journal
|
||
+ org-noter
|
||
+ org-pomodoro
|
||
+ org-recur
|
||
+ org-roam
|
||
+ org-superstar
|
||
+ org-table-sticky-header
|
||
+ org-tree-slide
|
||
+ origami
|
||
+ outline-mode
|
||
+ outline-minor-faces
|
||
+ package (what you get with {{{kbd(M-x list-packages)}}})
|
||
+ page-break-lines
|
||
+ pandoc-mode
|
||
+ paren-face
|
||
+ pass
|
||
+ pdf-tools
|
||
+ persp-mode
|
||
+ perspective
|
||
+ phi-grep
|
||
+ pomidor
|
||
+ popup
|
||
+ powerline
|
||
+ powerline-evil
|
||
+ prism ([[#h:a94272e0-99da-4149-9e80-11a7e67a2cf2][Note for prism.el]])
|
||
+ prescient
|
||
+ proced
|
||
+ prodigy
|
||
+ pulse
|
||
+ pyim
|
||
+ quick-peek
|
||
+ racket-mode
|
||
+ rainbow-blocks
|
||
+ rainbow-delimiters
|
||
+ rcirc
|
||
+ recursion-indicator
|
||
+ regexp-builder (also known as ~re-builder~)
|
||
+ rg (rg.el)
|
||
+ ripgrep
|
||
+ rmail
|
||
+ ruler-mode
|
||
+ selectrum
|
||
+ selectrum-prescient
|
||
+ semantic
|
||
+ sesman
|
||
+ shell-script-mode
|
||
+ shortdoc
|
||
+ show-paren-mode
|
||
+ shr
|
||
+ side-notes
|
||
+ sieve-mode
|
||
+ skewer-mode
|
||
+ slime (slbd)
|
||
+ sly
|
||
+ smart-mode-line
|
||
+ smartparens
|
||
+ smerge
|
||
+ spaceline
|
||
+ speedbar
|
||
+ spell-fu
|
||
+ stripes
|
||
+ suggest
|
||
+ switch-window
|
||
+ swiper
|
||
+ sx
|
||
+ symbol-overlay
|
||
+ syslog-mode
|
||
+ tab-bar-groups
|
||
+ tab-bar-mode
|
||
+ tab-line-mode
|
||
+ table (built-in {{{file(table.el)}}})
|
||
+ telega
|
||
+ telephone-line
|
||
+ terraform-mode
|
||
+ term
|
||
+ textsec
|
||
+ tomatinho
|
||
+ transient (pop-up windows such as Magit's)
|
||
+ trashed
|
||
+ tree-sitter
|
||
+ treemacs
|
||
+ tty-menu
|
||
+ tuareg
|
||
+ typescript
|
||
+ undo-tree
|
||
+ vc ({{{file(vc-dir.el)}}}, {{{file(vc-hooks.el)}}})
|
||
+ vertico
|
||
+ vertico-quick
|
||
+ vimish-fold
|
||
+ visible-mark
|
||
+ visual-regexp
|
||
+ vterm
|
||
+ vundo
|
||
+ wcheck-mode
|
||
+ web-mode
|
||
+ wgrep
|
||
+ which-function-mode
|
||
+ which-key
|
||
+ whitespace-mode
|
||
+ window-divider-mode
|
||
+ winum
|
||
+ writegood-mode
|
||
+ woman
|
||
+ xah-elisp-mode
|
||
+ xref
|
||
+ xterm-color (and ansi-colors)
|
||
+ yaml-mode
|
||
+ yasnippet
|
||
+ ztree
|
||
|
||
Plus many other miscellaneous faces that are provided by Emacs.
|
||
|
||
** Indirectly covered packages
|
||
:properties:
|
||
:custom_id: h:2cb359c7-3a84-4262-bab3-dcdc1d0034d7
|
||
:end:
|
||
#+cindex: Implicitly supported packages
|
||
|
||
These do not require any extra styles because they are configured to
|
||
inherit from some basic faces or their dependencies which are directly
|
||
supported by the themes.
|
||
+ ag
|
||
+ apt-sources-list
|
||
+ buffer-expose
|
||
+ bufler
|
||
+ counsel-notmuch
|
||
+ counsel-org-capture-string
|
||
+ dashboard (emacs-dashboard)
|
||
+ define-word
|
||
+ disk-usage
|
||
+ dtache
|
||
+ dynamic-ruler
|
||
+ easy-kill
|
||
+ edit-indirect
|
||
+ egerrit
|
||
+ elfeed-summary
|
||
+ evil-owl
|
||
+ flyspell-correct
|
||
+ fortran-mode
|
||
+ git-walktree
|
||
+ goggles
|
||
+ highlight-defined
|
||
+ highlight-escape-sequences (~hes-mode~)
|
||
+ i3wm-config-mode
|
||
+ minibuffer-line
|
||
+ no-emoji
|
||
+ org-remark
|
||
+ parrot
|
||
+ perl-mode
|
||
+ php-mode
|
||
+ rjsx-mode
|
||
+ side-hustle
|
||
+ spell-fu
|
||
+ swift-mode
|
||
+ tab-bar-echo-area
|
||
+ tide
|
||
+ undo-hl
|
||
+ vdiff
|
||
+ vertico-indexed
|
||
+ vertico-mouse
|
||
|
||
* Notes on individual packages
|
||
:properties:
|
||
:custom_id: h:4c4d901a-84d7-4f20-bd99-0808c2b06eba
|
||
:end:
|
||
|
||
This section covers information that may be of interest to users of
|
||
individual packages.
|
||
|
||
** Note on calendar.el weekday and weekend colors
|
||
:properties:
|
||
:custom_id: h:b2db46fb-32f4-44fd-8e11-d2b261cf51ae
|
||
:end:
|
||
|
||
By default, the {{{kbd(M-x calendar)}}} interface differentiates weekdays from
|
||
weekends by applying a gray color to the former and a faint red to the
|
||
latter. The idea for this approach is that the weekend should serve as
|
||
a subtle warning that no work is supposed to be done on that day, per
|
||
the design of traditional calendars.
|
||
|
||
Users who prefer all days to look the same can configure the variable
|
||
~calendar-weekend-days~ to either use gray of weekdays or the faint red of
|
||
weekends uniformly.
|
||
|
||
#+begin_src emacs-lisp
|
||
;; All are treated like weekdays (gray color)
|
||
(setq calendar-weekend-days nil)
|
||
|
||
;; All are treated like weekends (red-faint color)
|
||
(setq calendar-weekend-days (number-sequence 0 6))
|
||
|
||
;; The default marks the Saturday and Sunday as the weekend
|
||
(setq calendar-weekend-days '(0 6))
|
||
#+end_src
|
||
|
||
For changes to take effect, the Calendar buffer needs to be generated
|
||
anew.
|
||
|
||
** Note on git-gutter in Doom Emacs
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:a195e37c-e58c-4148-b254-8ba1ed8a731a
|
||
:END:
|
||
|
||
The =git-gutter= and =git-gutter-fr= packages default to drawing bitmaps
|
||
for the indicators they display (e.g. bitmap of a plus sign for added
|
||
lines). In Doom Emacs, these bitmaps are replaced with contiguous lines
|
||
which may look nicer, but require a change to the foreground of the
|
||
relevant faces to yield the desired color combinations.
|
||
|
||
Since this is Doom-specific, we urge users to apply changes in their
|
||
local setup. Below is some sample code, based on what we cover at
|
||
length elsewhere in this manual:
|
||
|
||
[[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]].
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-modus-themes-custom-faces ()
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
;; Replace green with blue if you use `modus-themes-deuteranopia'.
|
||
`(git-gutter-fr:added ((,class :foreground ,green-fringe-bg)))
|
||
`(git-gutter-fr:deleted ((,class :foreground ,red-fringe-bg)))
|
||
`(git-gutter-fr:modified ((,class :foreground ,yellow-fringe-bg))))))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
|
||
#+end_src
|
||
|
||
As always, re-load the theme for changes to take effect.
|
||
|
||
If the above does not work, try this instead:
|
||
|
||
#+begin_src emacs-lisp
|
||
(after! modus-themes
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
;; Replace green with blue if you use `modus-themes-deuteranopia'.
|
||
`(git-gutter-fr:added ((,class :foreground ,green-fringe-bg)))
|
||
`(git-gutter-fr:deleted ((,class :foreground ,red-fringe-bg)))
|
||
`(git-gutter-fr:modified ((,class :foreground ,yellow-fringe-bg))))))
|
||
#+end_src
|
||
|
||
Replace ~green-fringe-bg~ with ~blue-fringe-bg~ if you want to optimize
|
||
for red-green color deficiency.
|
||
|
||
[[#h:3ed03a48-20d8-4ce7-b214-0eb7e4c79abe][Option for red-green color deficiency or deuteranopia]].
|
||
|
||
** Note on php-mode multiline comments
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:d0a3157b-9c04-46e8-8742-5fb2a7ae8798
|
||
:END:
|
||
|
||
Depending on your build of Emacs and/or the environment it runs in,
|
||
multiline comments in PHP with the =php-mode= package use the
|
||
~font-lock-doc-face~ instead of ~font-lock-comment-face~.
|
||
|
||
This seems to make all comments use the appropriate face:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-multine-comments ()
|
||
(setq-local c-doc-face-name 'font-lock-comment-face))
|
||
|
||
(add-hook 'php-mode-hook #'my-multine-comments)
|
||
#+end_src
|
||
|
||
As always, re-load the theme for changes to take effect.
|
||
|
||
** Note on underlines in compilation buffers
|
||
:properties:
|
||
:custom_id: h:420f5a33-c7a9-4112-9b04-eaf2cbad96bd
|
||
:end:
|
||
|
||
Various buffers that produce compilation results or run tests on code
|
||
apply an underline to the file names they reference or to relevant
|
||
messages. Users may consider this unnecessary or excessive.
|
||
|
||
To outright disable the effect, use this (buffers need to be generated
|
||
anew):
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq compilation-message-face nil)
|
||
#+end_src
|
||
|
||
If some element of differentiation is still desired, a good option is to
|
||
render the affected text with the ~italic~ face:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq compilation-message-face 'italic)
|
||
#+end_src
|
||
|
||
[[#h:2793a224-2109-4f61-a106-721c57c01375][Configure bold and italic faces]].
|
||
|
||
** Note on inline Latex in Org buffers
|
||
:properties:
|
||
:custom_id: h:dd8478da-f56a-45cd-b199-b836c85c3c5a
|
||
:end:
|
||
|
||
Org can work with inline latex and related syntax. To actually fontify
|
||
those constructs, set the variable ~org-highlight-latex-and-related~ to
|
||
the desired list of values (per its doc string). For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq org-highlight-latex-and-related '(latex script))
|
||
#+end_src
|
||
|
||
Remember to use {{{kbd(M-x org-mode-restart)}}} for changes to take effect.
|
||
|
||
** Note on dimmer.el
|
||
:properties:
|
||
:custom_id: h:8eb4b758-d318-4480-9ead-357a571beb93
|
||
:end:
|
||
|
||
The {{{file(dimmer.el)}}} library by Neil Okamoto can be configured to
|
||
automatically dim the colors of inactive Emacs windows. To guarantee
|
||
consistent results with the Modus themes, we suggest some tweaks to the
|
||
default styles, such as in this minimal setup:
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package dimmer
|
||
:config
|
||
(setq dimmer-fraction 0.3)
|
||
(setq dimmer-adjustment-mode :foreground)
|
||
(setq dimmer-use-colorspace :rgb)
|
||
|
||
(dimmer-mode 1))
|
||
#+end_src
|
||
|
||
Of the above, we strongly recommend the RGB color space because it is
|
||
the one that remains faithful to the hueness of the colors used by the
|
||
themes. Whereas the default CIELAB space has a tendency to distort
|
||
colors in addition to applying the dim effect, which can be somewhat
|
||
disorienting.
|
||
|
||
The value of the ~dimmer-fraction~ has been selected empirically. Users
|
||
might prefer to tweak it further (increasing it makes the dim effect
|
||
more pronounced).
|
||
|
||
Changing the ~dimmer-adjustment-mode~ is a matter of preference. Though
|
||
because the Modus themes use black and white as their base colors, any
|
||
other value for that variable will turn the main background gray. This
|
||
inadvertently leads to the opposite of the intended utility of this
|
||
package: it draws too much attention to unfocused windows.
|
||
|
||
** Note on display-fill-column-indicator-mode
|
||
:properties:
|
||
:custom_id: h:2a602816-bc1b-45bf-9675-4cbbd7bf6cab
|
||
:end:
|
||
|
||
The ~display-fill-column-indicator-mode~ uses a typographic character to
|
||
draw its line. This has the downside of creating a dashed line. The
|
||
dashes are further apart depending on how tall the font's glyph height
|
||
is and what integer the ~line-spacing~ is set to.
|
||
|
||
At the theme level we eliminate this effect by making the character one
|
||
pixel tall: the line is contiguous. Users who prefer the dashed line
|
||
are advised to change the ~fill-column-indicator~ face, as explained
|
||
elsewhere in this document. For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(fill-column-indicator ((,class :foreground ,bg-active)))))
|
||
#+end_src
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
To make the line thicker, set the height to be equal to the base font
|
||
size instead of the one pixel we use. This is done by specifying a rate
|
||
instead of an absolute number, as in =:height 1.0= versus =:height 1=.
|
||
For example:
|
||
|
||
#+begin_src emacs-lisp
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(fill-column-indicator ((,class :height 1.0 :background ,bg-inactive :foreground ,bg-inactive)))))
|
||
#+end_src
|
||
|
||
** Note on highlight-parentheses.el
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:24bab397-dcb2-421d-aa6e-ec5bd622b913
|
||
:END:
|
||
|
||
The =highlight-parentheses= package provides contextual coloration of
|
||
surrounding parentheses, highlighting only those which are around the
|
||
point. The package expects users to customize the applicable colors on
|
||
their own by configuring certain variables.
|
||
|
||
To make the Modus themes work as expected with this, we need to use some
|
||
of the techniques that are discussed at length in the various
|
||
"Do-It-Yourself" (DIY) sections, which provide insight into the more
|
||
advanced customization options of the themes.
|
||
|
||
[[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]].
|
||
|
||
In the following example, we are assuming that the user wants to (i)
|
||
re-use color variables provided by the themes, (ii) be able to retain
|
||
their tweaks while switching between ~modus-operandi~ and ~modus-vivendi~,
|
||
and (iii) have the option to highlight either the foreground of the
|
||
parentheses or the background as well.
|
||
|
||
We start by defining our own variable, which will serve as a toggle
|
||
between foreground and background coloration styles:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defvar my-highlight-parentheses-use-background t
|
||
"Prefer `highlight-parentheses-background-colors'.")
|
||
#+end_src
|
||
|
||
Then we can update our preference with this:
|
||
|
||
#+begin_src emacs-lisp
|
||
;; Set to nil to disable backgrounds.
|
||
(setq my-highlight-parentheses-use-background nil)
|
||
#+end_src
|
||
|
||
To re-use colors from the themes, we must wrap our code in the
|
||
~modus-themes-with-colors~ macro. Our implementation must interface with
|
||
the variables ~highlight-parentheses-background-colors~ and/or
|
||
~highlight-parentheses-colors~.
|
||
|
||
So we can have something like this (the doc string of
|
||
~modus-themes-with-colors~ explains where the names of the colors can be
|
||
found):
|
||
|
||
#+begin_src emacs-lisp
|
||
(modus-themes-with-colors
|
||
;; Our preference for setting either background or foreground
|
||
;; styles, depending on `my-highlight-parentheses-use-background'.
|
||
(if my-highlight-parentheses-use-background
|
||
|
||
;; Here we set color combinations that involve both a background
|
||
;; and a foreground value.
|
||
(setq highlight-parentheses-background-colors (list cyan-refine-bg
|
||
magenta-refine-bg
|
||
green-refine-bg
|
||
yellow-refine-bg)
|
||
highlight-parentheses-colors (list cyan-refine-fg
|
||
magenta-refine-fg
|
||
green-refine-fg
|
||
yellow-refine-fg))
|
||
|
||
;; And here we pass only foreground colors while disabling any
|
||
;; backgrounds.
|
||
(setq highlight-parentheses-colors (list green-intense
|
||
magenta-intense
|
||
blue-intense
|
||
red-intense)
|
||
highlight-parentheses-background-colors nil)))
|
||
|
||
;; Include this if you also want to make the parentheses bold:
|
||
(set-face-attribute 'highlight-parentheses-highlight nil :inherit 'bold)
|
||
|
||
;; Our changes must be evaluated before enabling the relevant mode, so
|
||
;; this comes last.
|
||
(global-highlight-parentheses-mode 1)
|
||
#+end_src
|
||
|
||
For our changes to persist while switching between the Modus themes, we
|
||
need to include them in a function which can then get passed to
|
||
~modus-themes-after-load-theme-hook~. This is the complete
|
||
implementation:
|
||
|
||
#+begin_src emacs-lisp
|
||
;; Configurations for `highlight-parentheses':
|
||
(require 'highlight-parentheses)
|
||
|
||
(defvar my-highlight-parentheses-use-background t
|
||
"Prefer `highlight-parentheses-background-colors'.")
|
||
|
||
(setq my-highlight-parentheses-use-background nil) ; Set to nil to disable backgrounds
|
||
|
||
(defun my-modus-themes-highlight-parentheses ()
|
||
(modus-themes-with-colors
|
||
;; Our preference for setting either background or foreground
|
||
;; styles, depending on `my-highlight-parentheses-use-background'.
|
||
(if my-highlight-parentheses-use-background
|
||
|
||
;; Here we set color combinations that involve both a background
|
||
;; and a foreground value.
|
||
(setq highlight-parentheses-background-colors (list cyan-refine-bg
|
||
magenta-refine-bg
|
||
green-refine-bg
|
||
yellow-refine-bg)
|
||
highlight-parentheses-colors (list cyan-refine-fg
|
||
magenta-refine-fg
|
||
green-refine-fg
|
||
yellow-refine-fg))
|
||
|
||
;; And here we pass only foreground colors while disabling any
|
||
;; backgrounds.
|
||
(setq highlight-parentheses-colors (list green-intense
|
||
magenta-intense
|
||
blue-intense
|
||
red-intense)
|
||
highlight-parentheses-background-colors nil)))
|
||
|
||
;; Include this if you also want to make the parentheses bold:
|
||
(set-face-attribute 'highlight-parentheses-highlight nil :inherit 'bold)
|
||
|
||
;; Our changes must be evaluated before enabling the relevant mode, so
|
||
;; this comes last.
|
||
(global-highlight-parentheses-mode 1))
|
||
|
||
(add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-highlight-parentheses)
|
||
#+end_src
|
||
|
||
As always, re-load the theme for changes to take effect.
|
||
|
||
** Note on mmm-mode.el background colors
|
||
:properties:
|
||
:custom_id: h:99cf0d6c-e478-4e26-9932-3bf3427d13f6
|
||
:end:
|
||
|
||
The faces used by {{{file(mmm-mode.el)}}} are expected to have a colorful
|
||
background, while they should not touch any foreground value. The idea
|
||
is that they must not interfere with existing fontification. Those
|
||
background colors need to be distinct from each other, such as an
|
||
unambiguous red juxtaposed with a clear blue.
|
||
|
||
While this design may be internally consistent with the raison d'être of
|
||
that library, it inevitably produces inaccessible color combinations.
|
||
|
||
There are two competing goals at play:
|
||
|
||
1. Legibility of the text, understood as the contrast ratio between the
|
||
background and the foreground.
|
||
|
||
2. Semantic precision of each face which entails faithfulness to
|
||
color-coding of the underlying background.
|
||
|
||
As the Modus themes are designed with the express purpose of conforming
|
||
with the first point, we have to forgo the apparent color-coding of the
|
||
background elements. Instead we use subtle colors that do not undermine
|
||
the legibility of the affected text while they still offer a sense of
|
||
added context.
|
||
|
||
Users who might prefer to fall below the minimum 7:1 contrast ratio in
|
||
relative luminance (the accessibility target we conform with), can opt
|
||
to configure the relevant faces on their own.
|
||
|
||
[[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
This example uses more vivid background colors, though it comes at the
|
||
very high cost of degraded legibility.
|
||
|
||
#+begin_src emacs-lisp
|
||
(modus-themes-with-colors
|
||
(custom-set-faces
|
||
`(mmm-cleanup-submode-face ((,class :background ,yellow-refine-bg)))
|
||
`(mmm-code-submode-face ((,class :background ,bg-active)))
|
||
`(mmm-comment-submode-face ((,class :background ,blue-refine-bg)))
|
||
`(mmm-declaration-submode-face ((,class :background ,cyan-refine-bg)))
|
||
`(mmm-default-submode-face ((,class :background ,bg-alt)))
|
||
`(mmm-init-submode-face ((,class :background ,magenta-refine-bg)))
|
||
`(mmm-output-submode-face ((,class :background ,red-refine-bg)))
|
||
`(mmm-special-submode-face ((,class :background ,green-refine-bg)))))
|
||
#+end_src
|
||
|
||
** Note on prism.el
|
||
:properties:
|
||
:alt_title: Note for prism
|
||
:custom_id: h:a94272e0-99da-4149-9e80-11a7e67a2cf2
|
||
:end:
|
||
|
||
This package by Adam Porter, aka "alphapapa" or "github-alphapapa",
|
||
implements an alternative to the typical coloration of code. Instead of
|
||
highlighting the syntactic constructs, it applies color to different
|
||
levels of depth in the code structure.
|
||
|
||
As {{{file(prism.el)}}} offers a broad range of customizations, we cannot
|
||
style it directly at the theme level: that would run contrary to the
|
||
spirit of the package. Instead, we may offer preset color schemes.
|
||
Those should offer a starting point for users to adapt to their needs.
|
||
|
||
In the following code snippets, we employ the ~modus-themes-with-colors~
|
||
macro: [[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]].
|
||
|
||
These are the minimum recommended settings with 16 colors:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq prism-num-faces 16)
|
||
|
||
(prism-set-colors
|
||
:desaturations '(0) ; do not change---may lower the contrast ratio
|
||
:lightens '(0) ; same
|
||
:colors (modus-themes-with-colors
|
||
(list fg-main
|
||
magenta
|
||
cyan-alt-other
|
||
magenta-alt-other
|
||
blue
|
||
magenta-alt
|
||
cyan-alt
|
||
red-alt-other
|
||
green
|
||
fg-main
|
||
cyan
|
||
yellow
|
||
blue-alt
|
||
red-alt
|
||
green-alt-other
|
||
fg-special-warm)))
|
||
#+end_src
|
||
|
||
With 8 colors:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq prism-num-faces 8)
|
||
|
||
(prism-set-colors
|
||
:desaturations '(0) ; do not change---may lower the contrast ratio
|
||
:lightens '(0) ; same
|
||
:colors (modus-themes-with-colors
|
||
(list blue
|
||
magenta
|
||
magenta-alt-other
|
||
cyan-alt-other
|
||
fg-main
|
||
blue-alt
|
||
red-alt-other
|
||
cyan)))
|
||
#+end_src
|
||
|
||
And this is with 4 colors, which produces results that are the closest
|
||
to the themes' default aesthetic:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq prism-num-faces 4)
|
||
|
||
(prism-set-colors
|
||
:desaturations '(0) ; do not change---may lower the contrast ratio
|
||
:lightens '(0) ; same
|
||
:colors (modus-themes-with-colors
|
||
(list blue
|
||
magenta
|
||
magenta-alt-other
|
||
green-alt)))
|
||
#+end_src
|
||
|
||
If you need to apply desaturation and lightening, you can use what the
|
||
{{{file(prism.el)}}} documentation recommends, like this (adapting to the
|
||
examples with the 4, 8, 16 colors):
|
||
|
||
#+begin_src emacs-lisp
|
||
(prism-set-colors
|
||
:desaturations (cl-loop for i from 0 below 16 collect (* i 2.5))
|
||
:lightens (cl-loop for i from 0 below 16 collect (* i 2.5))
|
||
:colors (modus-themes-with-colors
|
||
(list fg-main
|
||
cyan-alt-other
|
||
magenta-alt-other
|
||
magenta)))
|
||
#+end_src
|
||
|
||
** Note on god-mode.el
|
||
:properties:
|
||
:alt_title: Note for god-mode
|
||
:custom_id: h:4da1d515-3e05-47ef-9e45-8251fc7e986a
|
||
:end:
|
||
|
||
The ~god-mode~ library does not provide faces that could be configured by
|
||
the Modus themes. Users who would like to get some visual feedback on
|
||
the status of {{{kbd(M-x god-mode)}}} are instead encouraged by upstream to
|
||
set up their own configurations, such as by changing the ~mode-line~ face
|
||
([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization]]). This is an adaptation of the approach
|
||
followed in the upstream README:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defun my-god-mode-update-mode-line ()
|
||
"Make `mode-line' blue if God local mode is active."
|
||
(modus-themes-with-colors
|
||
(if god-local-mode
|
||
(set-face-attribute 'mode-line nil
|
||
:foreground blue-active
|
||
:background bg-active-accent
|
||
:box blue)
|
||
(set-face-attribute 'mode-line nil
|
||
:foreground fg-active
|
||
:background bg-active
|
||
:box fg-alt))))
|
||
|
||
(add-hook 'post-command-hook 'my-god-mode-update-mode-line)
|
||
#+end_src
|
||
|
||
We employ the ~modus-themes-with-colors~ which provides access to color
|
||
variables defined by the active theme. Its use is covered elsewhere in
|
||
this manual ([[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the themes' palette]]). As for the
|
||
attributes that can be passed to each face, start by consulting the
|
||
documentation string of ~set-face-attribute~.
|
||
|
||
** Note on company-mode overlay pop-up
|
||
:properties:
|
||
:custom_id: h:20cef8c4-d11f-4053-8b2c-2872925780b1
|
||
:end:
|
||
|
||
By default, the ~company-mode~ pop-up that lists completion candidates is
|
||
drawn using an overlay. This creates alignment issues every time it is
|
||
placed above a piece of text that has a different height than the
|
||
default.
|
||
|
||
The solution recommended by the project's maintainer is to use an
|
||
alternative front-end for drawing the pop-up which draws child frames
|
||
instead of overlays.[fn::
|
||
https://github.com/company-mode/company-mode/issues/1010][fn::
|
||
https://github.com/tumashu/company-posframe/]
|
||
|
||
** Note on ERC escaped color sequences
|
||
:properties:
|
||
:custom_id: h:98bdf319-1e32-4469-8a01-771200fba65c
|
||
:end:
|
||
|
||
The built-in IRC client ~erc~ has the ability to colorize any text using
|
||
escape sequences that start with =^C= (inserted with {{{kbd(C-q C-c)}}}) and are
|
||
followed by a number for the foreground and background.[fn:: This page
|
||
explains the basics, though it is not specific to Emacs:
|
||
https://www.mirc.com/colors.html] Possible numbers are 0-15, with the
|
||
first entry being the foreground and the second the background,
|
||
separated by a comma. Like this =^C1,6=. The minimum setup is this:
|
||
|
||
#+begin_src emacs-lisp
|
||
(add-to-list 'erc-modules 'irccontrols)
|
||
(setq erc-interpret-controls-p t
|
||
erc-interpret-mirc-color t)
|
||
#+end_src
|
||
|
||
As this allows users the chance to make arbitrary combinations, it is
|
||
impossible to guarantee a consistently high contrast ratio. All we can
|
||
we do is provide guidance on the combinations that satisfy the
|
||
accessibility standard of the themes:
|
||
+ Modus Operandi :: Use foreground color 1 for all backgrounds from
|
||
2-15. Like so: {{{kbd(C-q C-c1,N)}}} where =N= is the background.
|
||
|
||
+ Modus Vivendi :: Use foreground color 0 for all backgrounds from
|
||
2-13. Use foreground =1= for backgrounds 14, 15.
|
||
|
||
Colors 0 and 1 are white and black respectively. So combine them
|
||
together, if you must.
|
||
|
||
** Note on powerline or spaceline
|
||
:properties:
|
||
:custom_id: h:9130a8ba-d8e3-41be-a58b-3cb1eb7b6d17
|
||
:end:
|
||
|
||
Both Powerline and Spaceline package users will likely need to use the
|
||
command ~powerline-reset~ whenever they make changes to their themes
|
||
and/or mode line setup.
|
||
|
||
** Note on SHR colors
|
||
:properties:
|
||
:custom_id: h:4cc767dc-ffef-4c5c-9f10-82eb7b8921bf
|
||
:end:
|
||
|
||
Emacs' HTML rendering library ({{{file(shr.el)}}}) may need explicit
|
||
configuration to respect the theme's colors instead of whatever
|
||
specifications the webpage provides.
|
||
|
||
Consult the doc string of ~shr-use-colors~.
|
||
|
||
** Note on SHR fonts
|
||
:properties:
|
||
:custom_id: h:e6c5451f-6763-4be7-8fdb-b4706a422a4c
|
||
:end:
|
||
#+cindex: Fonts in EWW, Elfeed, Ement, and SHR
|
||
|
||
By default, packages that build on top of the Simple HTML Remember (=shr=)
|
||
use proportionately spaced fonts. This is controlled by the user option
|
||
~shr-use-fonts~, which is set to non-~nil~ by default. To use the standard
|
||
font instead, set that variable to nil.
|
||
|
||
[[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and others]].
|
||
|
||
Packages affected by this are:
|
||
+ elfeed
|
||
+ ement
|
||
+ eww
|
||
|
||
This is a non-exhaustive list.
|
||
|
||
** Note on Ement colors and fonts
|
||
:properties:
|
||
:custom_id: h:8e636056-356c-4ca7-bc78-ebe61031f585
|
||
:end:
|
||
|
||
The =ement.el= library by Adam Porter (also known as "alphapapa") defaults
|
||
to a method of colorizing usernames in a rainbow style. This is
|
||
controlled by the user option ~ement-room-prism~ and can be disabled with:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq ement-room-prism nil)
|
||
#+end_src
|
||
|
||
The contrast ratio of these colors is governed by another user option:
|
||
~ement-room-prism-minimum-contrast~. By default, it is set to 6 which is
|
||
slightly below our nominal target. Try this instead:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq ement-room-prism-minimum-contrast 7)
|
||
#+end_src
|
||
|
||
With regard to fonts, Ement depends on =shr= ([[#h:e6c5451f-6763-4be7-8fdb-b4706a422a4c][Note on SHR fonts]]).
|
||
|
||
Since we are here, here is an excerpt from Ement's source code:
|
||
|
||
#+begin_src emacs-lisp
|
||
(defcustom ement-room-prism-minimum-contrast 6
|
||
"Attempt to enforce this minimum contrast ratio for user faces.
|
||
This should be a reasonable number from, e.g. 0-7 or so."
|
||
;; Prot would almost approve of this default. :) I would go all the way
|
||
;; to 7, but 6 already significantly dilutes the colors in some cases.
|
||
:type 'number)
|
||
#+end_src
|
||
|
||
Yes, I do approve of that default. Even a 4.5 (the WCAG AA rating)
|
||
would be a good baseline for many themes and/or user configurations.
|
||
Our target is the highest of the sort, though we do not demand that
|
||
everyone conforms with it.
|
||
|
||
** Note on Helm grep
|
||
:properties:
|
||
:custom_id: h:d28879a2-8e4b-4525-986e-14c0f873d229
|
||
:end:
|
||
|
||
There is one face from the Helm package that is meant to highlight the
|
||
matches of a grep or grep-like command (=ag= or =ripgrep=). It is
|
||
~helm-grep-match~. However, this face can only apply when the user does
|
||
not pass =--color=always= as a command-line option for their command.
|
||
|
||
Here is the docstring for that face, which is defined in the
|
||
{{{file(helm-grep.el)}}} library (you can always visit the source code with
|
||
{{{kbd(M-x find-library)}}}).
|
||
|
||
#+begin_quote
|
||
Face used to highlight grep matches. Have no effect when grep backend
|
||
use "--color="
|
||
#+end_quote
|
||
|
||
The user must either remove =--color= from the flags passed to the grep
|
||
function, or explicitly use =--color=never= (or equivalent). Helm
|
||
provides user-facing customization options for controlling the grep
|
||
function's parameters, such as ~helm-grep-default-command~ and
|
||
~helm-grep-git-grep-command~.
|
||
|
||
When =--color=always= is in effect, the grep output will use red text in
|
||
bold letter forms to present the matching part in the list of
|
||
candidates. That style still meets the contrast ratio target of >= 7:1
|
||
(accessibility standard WCAG AAA), because it draws the reference to
|
||
ANSI color number 1 (red) from the already-supported array of
|
||
~ansi-color-names-vector~.
|
||
|
||
** Note on pdf-tools link hints
|
||
:properties:
|
||
:custom_id: h:2659d13e-b1a5-416c-9a89-7c3ce3a76574
|
||
:end:
|
||
|
||
Hints are drawn by [[https://imagemagick.org/][ImageMagick]], not Emacs, i.e., ImageMagick doesn't
|
||
know about the hint face unless you tell ImageMagick about it. By
|
||
default, only the foreground and background color attributes are
|
||
passed. The below snippet adds to those the various font attributes. As
|
||
it queries various faces, specifically ~pdf-links-read-link~ and the faces
|
||
it inherits, it needs to be added to your initialization file after
|
||
you've customized any faces.
|
||
|
||
#+begin_src emacs-lisp
|
||
(use-package pdf-links
|
||
:config
|
||
(let ((spec
|
||
(apply #'append
|
||
(mapcar
|
||
(lambda (name)
|
||
(list name
|
||
(face-attribute 'pdf-links-read-link
|
||
name nil 'default)))
|
||
'(:family :width :weight :slant)))))
|
||
(setq pdf-links-read-link-convert-commands
|
||
`("-density" "96"
|
||
"-family" ,(plist-get spec :family)
|
||
"-stretch" ,(let* ((width (plist-get spec :width))
|
||
(name (symbol-name width)))
|
||
(replace-regexp-in-string "-" ""
|
||
(capitalize name)))
|
||
"-weight" ,(pcase (plist-get spec :weight)
|
||
('ultra-light "Thin")
|
||
('extra-light "ExtraLight")
|
||
('light "Light")
|
||
('semi-bold "SemiBold")
|
||
('bold "Bold")
|
||
('extra-bold "ExtraBold")
|
||
('ultra-bold "Black")
|
||
(_weight "Normal"))
|
||
"-style" ,(pcase (plist-get spec :slant)
|
||
('italic "Italic")
|
||
('oblique "Oblique")
|
||
(_slant "Normal"))
|
||
"-pointsize" "%P"
|
||
"-undercolor" "%f"
|
||
"-fill" "%b"
|
||
"-draw" "text %X,%Y '%c'"))))
|
||
#+end_src
|
||
|
||
** Note on the Notmuch logo
|
||
:properties:
|
||
:custom_id: h:636af312-54a5-4918-84a6-0698e85a3c6d
|
||
:end:
|
||
|
||
By default, the "hello" buffer of Notmuch includes a header with the
|
||
programs' logo and a couple of buttons. The logo has the effect of
|
||
enlarging the height of the line, which negatively impacts the shape of
|
||
those buttons. Disabling the logo fixes the problem:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq notmuch-show-logo nil)
|
||
#+end_src
|
||
|
||
** Note on goto-address-mode faces
|
||
:PROPERTIES:
|
||
:CUSTOM_ID: h:2d74236a-e41c-4616-8735-75f949a67334
|
||
:END:
|
||
|
||
The built-in ~goto-address-mode~ uses heuristics to identify URLs and
|
||
email addresses in the current buffer. It then applies a face to them
|
||
to change their style. Some packages, such as =notmuch=, use this
|
||
minor-mode automatically.
|
||
|
||
The faces are not declared with ~defface~, meaning that it is better
|
||
that the theme does not modify them. The user is thus encouraged to
|
||
consider including (or equivalent) this in their setup:
|
||
|
||
#+begin_src emacs-lisp
|
||
(setq goto-address-url-face 'link
|
||
goto-address-url-mouse-face 'highlight
|
||
goto-address-mail-face 'link
|
||
goto-address-mail-mouse-face 'highlight)
|
||
#+end_src
|
||
|
||
My personal preference is to set ~goto-address-mail-face~ to nil, as
|
||
it otherwise adds too much visual noise to the buffer (email addresses
|
||
stand out more, due to the use of the uncommon =@= character but also
|
||
because they are often enclosed in angled brackets).
|
||
|
||
* Frequently Asked Questions
|
||
:properties:
|
||
:custom_id: h:b3384767-30d3-4484-ba7f-081729f03a47
|
||
:end:
|
||
#+cindex: Frequently Asked Questions
|
||
|
||
In this section we provide answers related to some aspects of the Modus
|
||
themes' design and application.
|
||
|
||
** Is the contrast ratio about adjacent colors?
|
||
:properties:
|
||
:custom_id: h:5ce7ae2e-9348-4e55-b4cf-9302345b1826
|
||
:end:
|
||
#+cindex: Contrast between adjacent colors
|
||
|
||
The minimum contrast ratio in relative luminance that the themes conform
|
||
with always refers to any given combination of background and foreground
|
||
colors. If we have some blue colored text next to a magenta one, both
|
||
against a white background, we do not mean to imply that blue:magenta is
|
||
7:1 in terms of relative luminance. Rather, we state that blue:white
|
||
and magenta:white each are 7:1 or higher.
|
||
|
||
The point of reference is always the background. Because colors have
|
||
about the same minimum distance in luminance from their backdrop, they
|
||
necessarily are fairly close to each other in this measure. A possible
|
||
blue:magenta combination would naturally be around 1:1 in contrast of
|
||
the sort here considered.
|
||
|
||
To differentiate between sequential colors, we rely on hueness by
|
||
mapping contrasting hues to adjacent constructs, while avoiding
|
||
exaggerations. A blue next to a magenta can be told apart regardless of
|
||
their respective contrast ratio against their common background.
|
||
Exceptions would be tiny characters in arguably not so realistic cases,
|
||
such as two dots drawn side-by-side which for some reason would need to
|
||
be colored differently. They would still be legible though, which is
|
||
the primary objective of the Modus themes.
|
||
|
||
** What does it mean to avoid exaggerations?
|
||
:properties:
|
||
:custom_id: h:44284e1f-fab8-4c4f-92f0-544728a7c91e
|
||
:end:
|
||
#+cindex: Avoiding exaggerations in design
|
||
|
||
The Modus themes are designed with restraint, so that their default
|
||
looks do not overdo it with the application of color.
|
||
|
||
[[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]].
|
||
|
||
This is the non-quantifiable aspect of the themes' design: the artistic
|
||
part, if you will. There are a lot of cases where color can be used
|
||
inconsiderately, without accounting for layout, typographic, or other
|
||
properties of the presentation. For example, two headings with distinct
|
||
markers, such as leading asterisks in Org buffers, do not have to have
|
||
highly contrasting hues between them in order to be told apart: the
|
||
added element of contrast in hueness does not contribute significantly
|
||
more to the distinction between the headings than colors whose hues are
|
||
relatively closer to each other in the color space.
|
||
|
||
Exaggerations can be hard to anticipate or identify. Multiple shades of
|
||
blue and magenta in the same context may not seem optimal: one might
|
||
think that it would be better to use highly contrasting hues to ensure
|
||
that all colors stand out, such as by placing blue next to yellow, next
|
||
to magenta, and green. That would, however, be a case of design for its
|
||
own sake; a case where color is being applied without consideration of
|
||
its end results in the given context. Too many contrasting hues in
|
||
close proximity force an erratic rate to how the eye jumps from one
|
||
piece of text to the next. Whereas multiple shades of, say, blue and
|
||
magenta can suffice to tell things apart and avoid excess coloration: a
|
||
harmonious rhythm.
|
||
|
||
** Why are colors mostly variants of blue, magenta, cyan?
|
||
:properties:
|
||
:custom_id: h:0b26cb47-9733-4cb1-87d9-50850cb0386e
|
||
:end:
|
||
#+cindex: Innate color qualities of the palette
|
||
|
||
Due to the innate properties of color, some options are better than
|
||
others for the accessibility purposes of the themes, the stylistic
|
||
consistency between ~modus-operandi~ and ~modus-vivendi~, and the avoidance
|
||
of exaggerations in design.
|
||
|
||
[[#h:44284e1f-fab8-4c4f-92f0-544728a7c91e][What does it mean to avoid exaggerations?]]
|
||
|
||
What we describe as color is a function of three distinct channels of
|
||
light: red, green, blue. In hexadecimal RGB notation, a color value is
|
||
read as three pairs of red, green, and blue light: =#RRGGBB=. Of those
|
||
three, the most luminant is green, while the least luminant is blue.
|
||
|
||
The three basic colors represent each of the channels of light. They
|
||
can be intermixed to give us six colors: red and green derive yellow,
|
||
green and blue make cyan, red and blue turn into magenta.
|
||
|
||
We can test the luminance of each of those against white and black to
|
||
get a sense of how not all colors are equally good for accessibility
|
||
(white is =#ffffff=, which means that all three light channels are fully
|
||
luminated, while black is =#000000= meaning that no light is present
|
||
(notwithstanding display technology)).
|
||
|
||
#+begin_example
|
||
| Name | | #ffffff | #000000 |
|
||
|---------+---------+---------+---------|
|
||
| red | #ff0000 | 4.00 | 5.25 |
|
||
| yellow | #ffff00 | 1.07 | 19.56 |
|
||
| green | #00ff00 | 1.37 | 15.30 |
|
||
| cyan | #00ffff | 1.25 | 16.75 |
|
||
| blue | #0000ff | 8.59 | 2.44 |
|
||
| magenta | #ff00ff | 3.14 | 6.70 |
|
||
#+end_example
|
||
|
||
[[#h:02e25930-e71a-493d-828a-8907fc80f874][Measure color contrast]].
|
||
|
||
By reading this table we learn that every color that has a high level of
|
||
green light (green, yellow, cyan) is virtually unreadable against a
|
||
white background and, conversely, can be easily read against black.
|
||
|
||
We can then infer that red and blue, in different combinations, with
|
||
green acting as calibrator for luminance, will give us fairly moderate
|
||
colors that pass the 7:1 target. Blue with a bit of green produce
|
||
appropriate variants of cyan. Similarly, blue combined with some red
|
||
and hints of green give us suitable shades of purple.
|
||
|
||
Due to the need of maintaining some difference in hueness between
|
||
adjacent colors, it is not possible to make red, green, and yellow the
|
||
main colors, because blue cannot be used to control their luminance and,
|
||
thus the relevant space will shrink considerably.
|
||
|
||
[[#h:5ce7ae2e-9348-4e55-b4cf-9302345b1826][Is the contrast ratio about adjacent colors?]]
|
||
|
||
This phenomenon is best illustrated by the following table that measures
|
||
the relative luminance of shades of red, yellow, magenta against white:
|
||
|
||
#+begin_example
|
||
| | #ffffff |
|
||
|---------+---------|
|
||
| #990000 | 8.92 |
|
||
| #995500 | 5.75 |
|
||
| #990099 | 7.46 |
|
||
#+end_example
|
||
|
||
We notice that equal values of red and blue light in =#990099= (magenta
|
||
shade) do not lead to a considerable change in luminance compared with
|
||
=#990000= (red variant). Whereas less amount of green light in =#995500=
|
||
leads to a major drop in luminance relative to white. It follows that
|
||
using the green channel of light to calibrate the luminance of colors is
|
||
more effective than trying to do the same with either red or blue (the
|
||
latter is the least effective in that regard).
|
||
|
||
When we need to work with several colors, it is always better to have
|
||
sufficient manoeuvring space, especially since we cannot pick arbitrary
|
||
colors but only those that satisfy the accessibility objectives of the
|
||
themes.
|
||
|
||
As for why we do not mostly use green, yellow, cyan for the dark theme,
|
||
it is because those colors are far more luminant than their counterparts
|
||
on the other side of the spectrum, so to ensure that they all have about
|
||
the same contrast ratios we would have to alter their hueness
|
||
considerably. In short, the effect would not be optimal as it would
|
||
lead to exaggerations. Plus, it would make ~modus-vivendi~ look
|
||
completely different than ~modus-operandi~, to the effect that the two
|
||
could not be properly considered part of the same project.
|
||
|
||
** What is the best setup for legibility?
|
||
:properties:
|
||
:custom_id: h:f60cc2ae-129d-47c0-9849-4f6bbd87d8be
|
||
:end:
|
||
#+cindex: General setup for readability
|
||
|
||
The Modus themes can be conceptually simplified as combinations of color
|
||
values that account for relative luminance and inner harmony. Those
|
||
qualities do not guarantee that every end-user will have the same
|
||
experience, due to differences between people, but also because of
|
||
variances in hardware capabilities and configurations. For the purposes
|
||
of this document, we may only provide suggestions pertaining to the
|
||
latter case.
|
||
~modus-operandi~ is best used outdoors or in a room that either gets
|
||
direct sunlight or has plenty of light. Whereas ~modus-vivendi~ works
|
||
better when there is not a lot of sunshine or the room has a source of
|
||
light that is preferably a faint and/or warm one. It is possible to use
|
||
~modus-operandi~ at night and ~modus-vivendi~ during the day, though that
|
||
will depend on several variables, such as one's overall perception of
|
||
color, the paint on the walls and how that contributes to the impression
|
||
of lightness in the room, the sense of space within the eye's peripheral
|
||
vision, hardware specifications, and environmental factors.
|
||
|
||
In general, an additional source of light other than that of the monitor
|
||
can help reduce eye strain: the eyes are more relaxed when they do not
|
||
have to focus on one point to gather light.
|
||
|
||
The monitor's display settings must be accounted for. Gamma values, in
|
||
particular, need to be calibrated to neither amplify nor distort the
|
||
perception of black. Same principle for sharpness, brightness, and
|
||
contrast as determined by the hardware, which all have an effect on how
|
||
text is read on the screen.
|
||
|
||
There are software level methods on offer, such as the XrandR utility
|
||
for the X Window System (X.org), which can make gamma corrections for
|
||
each of the three channels of light (red, green, blue). For example:
|
||
|
||
: xrandr --output LVDS1 --brightness 1.0 --gamma 0.76:0.75:0.68
|
||
|
||
Typography is another variable. Some font families are blurry at small
|
||
point sizes. Others may have a regular weight that is lighter (thiner)
|
||
than that of their peers which may, under certain circumstances, cause a
|
||
halo effect around each glyph.
|
||
|
||
The gist is that legibility cannot be fully solved at the theme level.
|
||
The color combinations may have been optimized for accessibility, though
|
||
the remaining contributing factors in each case need to be considered in
|
||
full.
|
||
|
||
** Are these color schemes?
|
||
:properties:
|
||
:custom_id: h:a956dbd3-8fd2-4f5d-8b01-5f881268cf2b
|
||
:end:
|
||
#+cindex: Themes, not color schemes
|
||
|
||
No, the Modus themes are not color schemes.
|
||
|
||
A color scheme is a collection of colors. A good color scheme is a
|
||
combination of colors with an inner logic or abstract structure.
|
||
|
||
A theme is a set of patterns that are applied across different contexts.
|
||
A good theme is one that does so with consistency, though not
|
||
uniformity.
|
||
|
||
In practical terms, a color scheme is what one uses when, for example,
|
||
they edit the first sixteen escape sequences of a terminal emulator to
|
||
the hues of their preference. The terminal offers the option to choose,
|
||
say, the exact value of what counts as "red", but does not provide the
|
||
means to control where that is mapped to and whether it should also have
|
||
other qualities such as a bold weight for the underlying text or an
|
||
added background color. In contradistinction, Emacs uses constructs
|
||
known as "faces" which allow the user/developer to specify where a given
|
||
color will be used and whether it should be accompanied by other
|
||
typographic or stylistic attributes.
|
||
|
||
By configuring the multitude of faces on offer we thus control both
|
||
which colors are applied and how they appear in their context. When a
|
||
package wants to render each instance of "foo" with the "bar" face, it
|
||
is not requesting a specific color, which makes things considerably more
|
||
flexible as we can treat "bar" in its own right without necessarily
|
||
having to use some color value that we hardcoded somewhere.
|
||
|
||
Which brings us to the distinction between consistency and uniformity
|
||
where our goal is always the former: we want things to look similar
|
||
across all interfaces, but we must never force a visual identity where
|
||
that runs contrary to the functionality of the given interface. For
|
||
instance, all links are underlined by default yet there are cases such
|
||
as when viewing listings of emails in Gnus (and Mu4e, Notmuch) where (i)
|
||
it is already understood that one must follow the indicator or headline
|
||
to view its contents and (ii) underlining everything would make the
|
||
interface virtually unusable.
|
||
|
||
[[#h:5808be52-361a-4d18-88fd-90129d206f9b][Option for links]].
|
||
|
||
Again, one must exercise judgment in order to avoid discrimination,
|
||
where "discrimination" refers to:
|
||
+ The treatment of substantially different magnitudes as if they were of
|
||
the same class.
|
||
+ Or the treatment of the same class of magnitudes as if they were of a
|
||
different class.
|
||
|
||
(To treat similar things differently; to treat dissimilar things alike.)
|
||
|
||
If, in other words, one was to enforce uniformity without accounting for
|
||
the particular requirements of each case---the contextual demands for
|
||
usability beyond matters of color---they would be making a
|
||
not-so-obvious error of treating different cases as if they were the
|
||
same.
|
||
|
||
The Modus themes prioritize "thematic consistency" over abstract harmony
|
||
or regularity among their applicable colors. In concrete terms, we do
|
||
not claim that, say, our yellows are the best complements for our blues
|
||
because we generally avoid using complementary colors side-by-side, so
|
||
it is wrong to optimize for a decontextualised blue+yellow combination.
|
||
Not to imply that our colors do not work well together because they do,
|
||
just to clarify that consistency of context is what themes must strive
|
||
for, and that requires widening the scope of the design beyond the
|
||
particularities of a color scheme.
|
||
|
||
Long story short: color schemes and themes have different requirements.
|
||
Please do not conflate the two.
|
||
|
||
** Port the Modus themes to other platforms?
|
||
:properties:
|
||
:custom_id: h:7156b949-917d-488e-9a72-59f70d80729c
|
||
:end:
|
||
#+cindex: Porting the themes to other editors
|
||
|
||
There is no plan to port the themes to other platforms or text editors.
|
||
I (Protesilaos) only use GNU Emacs and thus cannot maintain code that
|
||
targets software I am either not familiar with or am not using on a
|
||
daily basis.
|
||
|
||
While it is possible to produce a simulacrum based on a given template,
|
||
doing so would run contrary to how this project is maintained where
|
||
details matter greatly.
|
||
|
||
Each program has its own requirements so it won't always be
|
||
possible---or indeed desirable---to have 1:1 correspondence between what
|
||
applies to Emacs and what should be done elsewhere. No port should ever
|
||
strive to be a faithful copy of the Emacs implementation, as no other
|
||
program is an Emacs equivalent, but instead try to follow the spirit of
|
||
the design. For example, some of the customization options accept a
|
||
list as their value, or an alist, which may not be possible to reproduce
|
||
on other platforms.
|
||
|
||
[[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization options]].
|
||
|
||
In other words, if something must be done differently on a certain
|
||
editor then that is acceptable so long as (i) the accessibility
|
||
standards are not compromised and (ii) the overall character of the
|
||
themes remains consistent.
|
||
|
||
The former criterion should be crystal clear as it pertains to the
|
||
scientific foundations of the themes: high legibility and taking care of
|
||
the needs of users with red-green color deficiency (deuteranopia) by
|
||
avoiding red+green color coding paradigms and/or by providing red+blue
|
||
variants.
|
||
|
||
The latter criterion is the "je ne sais quoi" of the artistic aspect of
|
||
the themes, which is partially fleshed out in this manual.
|
||
|
||
[[#h:b3384767-30d3-4484-ba7f-081729f03a47][Frequently Asked Questions]].
|
||
|
||
With regard to the artistic aspect (where "art" qua skill may amount to
|
||
an imprecise science), there is no hard-and-fast rule in effect as it
|
||
requires one to exercise discretion and make decisions based on
|
||
context-dependent information or constraints. As is true with most
|
||
things in life, when in doubt, do not cling on to the letter of the law
|
||
but try to understand its spirit.
|
||
|
||
For a trivial example: the curly underline that Emacs draws for spelling
|
||
errors is thinner than, e.g., what a graphical web browser has, so if I
|
||
was to design for an editor than has a thicker curly underline I would
|
||
make the applicable colors less intense to counterbalance the
|
||
typographic intensity of the added thickness.
|
||
|
||
With those granted, if anyone is willing to develop a port of the
|
||
themes, they are welcome to contact me and I will do my best to help
|
||
them in their efforts.
|
||
|
||
* Contributing
|
||
:properties:
|
||
:custom_id: h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1
|
||
:end:
|
||
|
||
This section documents the canonical sources of the themes and the ways
|
||
in which you can contribute to their ongoing development.
|
||
|
||
** Sources of the themes
|
||
:properties:
|
||
:custom_id: h:89504f1c-c9a1-4bd9-ab39-78fd0eddb47c
|
||
:end:
|
||
#+cindex: Sources of the themes
|
||
|
||
The ~modus-operandi~ and ~modus-vivendi~ themes are built into Emacs 28.
|
||
|
||
The source code of the themes is [[https://git.sr.ht/~protesilaos/modus-themes][available on SourceHut]]. Or check the
|
||
[[https://gitlab.com/protesilaos/modus-themes/][GitLab mirror (former main source)]] and the [[https://github.com/protesilaos/modus-themes/][GitHub mirror]].
|
||
|
||
An HTML version of this manual is provided as an extension of the
|
||
[[https://protesilaos.com/emacs/modus-themes/][author's personal website]] (does not rely on any non-free code).
|
||
|
||
** Issues you can help with
|
||
:properties:
|
||
:custom_id: h:6536c8d5-3f98-43ab-a787-b94120e735e8
|
||
:end:
|
||
#+cindex: Contributing
|
||
|
||
#+findex: modus-themes-report-bug
|
||
A few tasks you can help with by sending an email to the general
|
||
[[https://lists.sr.ht/~protesilaos/modus-themes][modus-themes public mailing list]] (or use the command
|
||
~modus-themes-report-bug~).
|
||
+ Suggest refinements to packages that are covered.
|
||
+ Report packages not covered thus far.
|
||
+ Report bugs, inconsistencies, shortcomings.
|
||
+ Help expand the documentation of covered-but-not-styled packages.
|
||
+ Suggest refinements to the color palette.
|
||
+ Help expand this document or any other piece of documentation.
|
||
+ Send patches for code refinements (if you need, ask me for help with
|
||
Git---we all start out as beginners).
|
||
|
||
[[#h:111773e2-f26f-4b68-8c4f-9794ca6b9633][Patches require copyright assignment to the FSF]].
|
||
|
||
It is preferable that your feedback includes some screenshots, GIFs, or
|
||
short videos, as well as further instructions to reproduce a given
|
||
setup. Though this is not a requirement.
|
||
|
||
#+findex: modus-themes-version
|
||
Also consider mentioning the version of the themes you are using, such
|
||
as by invoking the command ~modus-themes-version~.
|
||
|
||
Whatever you do, bear in mind the overarching objective of the Modus
|
||
themes: to keep a contrast ratio that is greater or equal to 7:1 between
|
||
background and foreground colors. If a compromise is ever necessary
|
||
between aesthetics and accessibility, it shall always be made in the
|
||
interest of the latter.
|
||
|
||
** Patches require copyright assignment to the FSF
|
||
:properties:
|
||
:custom_id: h:111773e2-f26f-4b68-8c4f-9794ca6b9633
|
||
:end:
|
||
|
||
Code contributions are most welcome. For any major edit (more than 15
|
||
lines, or so, in aggregate per person), you need to make a copyright
|
||
assignment to the Free Software Foundation. This is necessary because
|
||
the themes are part of the upstream Emacs distribution: the FSF must at
|
||
all times be in a position to enforce the GNU General Public License.
|
||
|
||
Copyright assignment is a simple process. Check the request form below
|
||
(please adapt it accordingly). You must write an email to the address
|
||
mentioned in the form and then wait for the FSF to send you a legal
|
||
agreement. Sign the document and file it back to them. This could all
|
||
happen via email and take about a week. You are encouraged to go
|
||
through this process. You only need to do it once. It will allow you
|
||
to make contributions to Emacs in general.
|
||
|
||
#+begin_example text
|
||
Please email the following information to assign@gnu.org, and we
|
||
will send you the assignment form for your past and future changes.
|
||
|
||
Please use your full legal name (in ASCII characters) as the subject
|
||
line of the message.
|
||
|
||
REQUEST: SEND FORM FOR PAST AND FUTURE CHANGES
|
||
|
||
[What is the name of the program or package you're contributing to?]
|
||
|
||
GNU Emacs
|
||
|
||
[Did you copy any files or text written by someone else in these changes?
|
||
Even if that material is free software, we need to know about it.]
|
||
|
||
Copied a few snippets from the same files I edited. Their author,
|
||
Protesilaos Stavrou, has already assigned copyright to the Free Software
|
||
Foundation.
|
||
|
||
[Do you have an employer who might have a basis to claim to own
|
||
your changes? Do you attend a school which might make such a claim?]
|
||
|
||
|
||
[For the copyright registration, what country are you a citizen of?]
|
||
|
||
|
||
[What year were you born?]
|
||
|
||
|
||
[Please write your email address here.]
|
||
|
||
|
||
[Please write your postal address here.]
|
||
|
||
|
||
|
||
|
||
|
||
[Which files have you changed so far, and which new files have you written
|
||
so far?]
|
||
|
||
#+end_example
|
||
|
||
* Acknowledgements
|
||
:properties:
|
||
:custom_id: h:95c3da23-217f-404e-b5f3-56c75760ebcf
|
||
:end:
|
||
#+cindex: Contributors
|
||
|
||
The Modus themes are a collective effort. Every bit of work matters.
|
||
+ Author/maintainer :: Protesilaos Stavrou.
|
||
|
||
+ Contributions to code or documentation :: Alex Griffin, Anders
|
||
Johansson, Antonio Ruiz, Basil L.{{{space()}}} Contovounesios, Björn
|
||
Lindström, Carlo Zancanaro, Christian Tietze, Daniel Mendler, Eli
|
||
Zaretskii, Fritz Grabo, Illia Ostapyshyn, Kévin Le Gouguec, Koen van
|
||
Greevenbroek, Kostadin Ninev, Madhavan Krishnan, Manuel Giraud,
|
||
Markus Beppler, Matthew Stevenson, Mauro Aranda, Nicolas De
|
||
Jaeghere, Paul David, Philip Kaludercic, Pierre Téchoueyres, Rudolf
|
||
Adamkovič, Stephen Gildea, Shreyas Ragavan, Stefan Kangas, Utkarsh
|
||
Singh, Vincent Murphy, Xinglu Chen, Yuanchen Xie, okamsn.
|
||
+ Ideas and user feedback :: Aaron Jensen, Adam Porter, Adam Spiers,
|
||
Adrian Manea, Alex Griffin, Alex Koen, Alex Peitsinis, Alexey
|
||
Shmalko, Alok Singh, Anders Johansson, André Alexandre Gomes, Andrew
|
||
Tropin, Antonio Hernández Blas, Arif Rezai, Augusto Stoffel, Basil
|
||
L.{{{space()}}} Contovounesios, Burgess Chang, Christian Tietze,
|
||
Christopher Dimech, Christopher League, Damien Cassou, Daniel
|
||
Mendler, Dario Gjorgjevski, David Edmondson, Davor Rotim, Divan
|
||
Santana, Eliraz Kedmi, Emanuele Michele Alberto Monterosso, Farasha
|
||
Euker, Feng Shu, Gautier Ponsinet, Gerry Agbobada, Gianluca Recchia,
|
||
Gonçalo Marrafa, Guilherme Semente, Gustavo Barros, Hörmetjan
|
||
Yiltiz, Ilja Kocken, Iris Garcia, Ivan Popovych, Jeremy Friesen,
|
||
Jerry Zhang, Johannes Grødem, John Haman, Jonas Collberg, Jorge
|
||
Morais, Joshua O'Connor, Julio C. Villasante, Kenta Usami, Kevin
|
||
Fleming, Kévin Le Gouguec, Kevin Kainan Li, Kostadin Ninev, Len
|
||
Trigg, Lennart C. Karssen, Luis Miguel Castañeda, Magne Hov, Manuel
|
||
Uberti, Mark Bestley, Mark Burton, Mark Simpson, Markus Beppler,
|
||
Matt Armstrong, Matthias Fuchs, Mauro Aranda, Maxime Tréca, Michael
|
||
Goldenberg, Morgan Smith, Morgan Willcock, Murilo Pereira, Nicky van
|
||
Foreest, Nicolas De Jaeghere, Pablo Stafforini, Paul Poloskov,
|
||
Pengji Zhang, Pete Kazmier, Peter Wu, Philip Kaludercic, Pierre
|
||
Téchoueyres, Przemysław Kryger, Robert Hepple, Roman Rudakov, Ryan
|
||
Phillips, Rytis Paškauskas, Rudolf Adamkovič, Sam Kleinman, Samuel
|
||
Culpepper, Saša Janiška, Shreyas Ragavan, Simon Pugnet, Tassilo
|
||
Horn, Thibaut Verron, Thomas Heartman, Togan Muftuoglu, Tony Zorman,
|
||
Trey Merkley, Tomasz Hołubowicz, Toon Claes, Uri Sharf, Utkarsh
|
||
Singh, Vincent Foley. As well as users: Ben, CsBigDataHub1, Emacs
|
||
Contrib, Eugene, Fourchaux, Fredrik, Moesasji, Nick, Summer Emacs,
|
||
TheBlob42, Trey, bepolymathe, bit9tream, derek-upham, doolio,
|
||
fleimgruber, gitrj95, iSeeU, jixiuf, okamsn, pRot0ta1p.
|
||
|
||
+ Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii,
|
||
Glenn Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core
|
||
Emacs), Stefan Monnier (GNU Elpa), André Alexandre Gomes, Andrew
|
||
Tropin, Dimakakos Dimos, Morgan Smith, Nicolas Goaziou (Guix), Dhavan
|
||
Vaidya (Debian).
|
||
|
||
+ Inspiration for certain features :: Bozhidar Batsov (zenburn-theme),
|
||
Fabrice Niessen (leuven-theme).
|
||
|
||
Special thanks (from A-Z) to Daniel Mendler, Gustavo Barros, Manuel
|
||
Uberti, Nicolas De Jaeghere, and Omar Antolín Camarena for their long
|
||
time contributions and insightful commentary on key aspects of the
|
||
themes' design and/or aspects of their functionality.
|
||
|
||
All errors are my own.
|
||
|
||
* Other notes about the project
|
||
:properties:
|
||
:custom_id: h:13752581-4378-478c-af17-165b6e76bc1b
|
||
:end:
|
||
#+cindex: Development notes
|
||
|
||
If you are curious about the principles that govern the development of
|
||
this project read the essay [[https://protesilaos.com/codelog/2020-03-17-design-modus-themes-emacs/][On the design of the Modus themes]]
|
||
(2020-03-17).
|
||
|
||
Here are some more publications for those interested in the kind of work
|
||
that goes into this project (sometimes the commits also include details
|
||
of this sort):
|
||
+ [[https://protesilaos.com/codelog/2020-05-10-modus-operandi-palette-review/][Modus Operandi theme subtle palette review]] (2020-05-10)
|
||
+ [[https://protesilaos.com/codelog/2020-06-13-modus-vivendi-palette-review/][Modus Vivendi theme subtle palette review]] (2020-06-13)
|
||
+ [[https://protesilaos.com/codelog/2020-07-04-modus-themes-faint-colours/][Modus themes: new "faint syntax" option]] (2020-07-04)
|
||
+ [[https://protesilaos.com/codelog/2020-07-08-modus-themes-nuanced-colours/][Modus themes: major review of "nuanced" colours]] (2020-07-08)
|
||
+ [[https://protesilaos.com/codelog/2020-09-14-modus-themes-review-blues/][Modus themes: review of blue colours]] (2020-09-14)
|
||
+ [[https://protesilaos.com/codelog/2020-12-27-modus-themes-review-rainbow-delimiters/][Modus themes: review rainbow-delimiters faces]] (2020-12-27)
|
||
+ [[https://protesilaos.com/codelog/2021-01-11-modus-themes-review-select-faint-colours/][Modus themes: review of select "faint" colours]] (2021-01-11)
|
||
+ [[https://protesilaos.com/codelog/2021-02-25-modus-themes-diffs-deuteranopia/][The Modus themes now cover deuteranopia in diffs]] (2021-02-25)
|
||
+ [[https://protesilaos.com/codelog/2021-06-02-modus-themes-org-agenda/][Introducing the variable modus-themes-org-agenda]] (2021-06-02)
|
||
+ [[https://protesilaos.com/codelog/2022-01-02-review-modus-themes-org-habit-colours/][Modus themes: review of the org-habit graph colours]] (2022-01-02)
|
||
+ [[https://protesilaos.com/codelog/2022-01-03-modus-themes-port-faq/][Re: VSCode or Vim ports of the Emacs modus-themes?]] (2022-01-03)
|
||
+ [[https://protesilaos.com/codelog/2022-04-20-modus-themes-case-study-avy/][Modus themes: case study on Avy faces and colour combinations]] (2022-04-20)
|
||
+ [[https://protesilaos.com/codelog/2022-04-21-modus-themes-colour-theory/][Emacs: colour theory and techniques used in the Modus themes]] (2022-04-21)
|
||
|
||
And here are the canonical sources of this project:
|
||
|
||
+ Manual :: <https://protesilaos.com/emacs/modus-themes>
|
||
+ Change Log :: <https://protesilaos.com/emacs/modus-themes-changelog>
|
||
+ Screenshots :: <https://protesilaos.com/emacs/modus-themes-pictures>
|
||
+ Git repository :: https://git.sr.ht/~protesilaos/modus-themes
|
||
+ Mailing list :: https://lists.sr.ht/~protesilaos/modus-themes
|
||
|
||
* GNU Free Documentation License
|
||
:properties:
|
||
:appendix: t
|
||
:custom_id: h:3077c3d2-7f90-4228-8f0a-73124f4026f6
|
||
:end:
|
||
|
||
#+texinfo: @include doclicense.texi
|
||
|
||
#+begin_export html
|
||
<pre>
|
||
|
||
GNU Free Documentation License
|
||
Version 1.3, 3 November 2008
|
||
|
||
|
||
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
|
||
<https://fsf.org/>
|
||
Everyone is permitted to copy and distribute verbatim copies
|
||
of this license document, but changing it is not allowed.
|
||
|
||
0. PREAMBLE
|
||
|
||
The purpose of this License is to make a manual, textbook, or other
|
||
functional and useful document "free" in the sense of freedom: to
|
||
assure everyone the effective freedom to copy and redistribute it,
|
||
with or without modifying it, either commercially or noncommercially.
|
||
Secondarily, this License preserves for the author and publisher a way
|
||
to get credit for their work, while not being considered responsible
|
||
for modifications made by others.
|
||
|
||
This License is a kind of "copyleft", which means that derivative
|
||
works of the document must themselves be free in the same sense. It
|
||
complements the GNU General Public License, which is a copyleft
|
||
license designed for free software.
|
||
|
||
We have designed this License in order to use it for manuals for free
|
||
software, because free software needs free documentation: a free
|
||
program should come with manuals providing the same freedoms that the
|
||
software does. But this License is not limited to software manuals;
|
||
it can be used for any textual work, regardless of subject matter or
|
||
whether it is published as a printed book. We recommend this License
|
||
principally for works whose purpose is instruction or reference.
|
||
|
||
|
||
1. APPLICABILITY AND DEFINITIONS
|
||
|
||
This License applies to any manual or other work, in any medium, that
|
||
contains a notice placed by the copyright holder saying it can be
|
||
distributed under the terms of this License. Such a notice grants a
|
||
world-wide, royalty-free license, unlimited in duration, to use that
|
||
work under the conditions stated herein. The "Document", below,
|
||
refers to any such manual or work. Any member of the public is a
|
||
licensee, and is addressed as "you". You accept the license if you
|
||
copy, modify or distribute the work in a way requiring permission
|
||
under copyright law.
|
||
|
||
A "Modified Version" of the Document means any work containing the
|
||
Document or a portion of it, either copied verbatim, or with
|
||
modifications and/or translated into another language.
|
||
|
||
A "Secondary Section" is a named appendix or a front-matter section of
|
||
the Document that deals exclusively with the relationship of the
|
||
publishers or authors of the Document to the Document's overall
|
||
subject (or to related matters) and contains nothing that could fall
|
||
directly within that overall subject. (Thus, if the Document is in
|
||
part a textbook of mathematics, a Secondary Section may not explain
|
||
any mathematics.) The relationship could be a matter of historical
|
||
connection with the subject or with related matters, or of legal,
|
||
commercial, philosophical, ethical or political position regarding
|
||
them.
|
||
|
||
The "Invariant Sections" are certain Secondary Sections whose titles
|
||
are designated, as being those of Invariant Sections, in the notice
|
||
that says that the Document is released under this License. If a
|
||
section does not fit the above definition of Secondary then it is not
|
||
allowed to be designated as Invariant. The Document may contain zero
|
||
Invariant Sections. If the Document does not identify any Invariant
|
||
Sections then there are none.
|
||
|
||
The "Cover Texts" are certain short passages of text that are listed,
|
||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||
the Document is released under this License. A Front-Cover Text may
|
||
be at most 5 words, and a Back-Cover Text may be at most 25 words.
|
||
|
||
A "Transparent" copy of the Document means a machine-readable copy,
|
||
represented in a format whose specification is available to the
|
||
general public, that is suitable for revising the document
|
||
straightforwardly with generic text editors or (for images composed of
|
||
pixels) generic paint programs or (for drawings) some widely available
|
||
drawing editor, and that is suitable for input to text formatters or
|
||
for automatic translation to a variety of formats suitable for input
|
||
to text formatters. A copy made in an otherwise Transparent file
|
||
format whose markup, or absence of markup, has been arranged to thwart
|
||
or discourage subsequent modification by readers is not Transparent.
|
||
An image format is not Transparent if used for any substantial amount
|
||
of text. A copy that is not "Transparent" is called "Opaque".
|
||
|
||
Examples of suitable formats for Transparent copies include plain
|
||
ASCII without markup, Texinfo input format, LaTeX input format, SGML
|
||
or XML using a publicly available DTD, and standard-conforming simple
|
||
HTML, PostScript or PDF designed for human modification. Examples of
|
||
transparent image formats include PNG, XCF and JPG. Opaque formats
|
||
include proprietary formats that can be read and edited only by
|
||
proprietary word processors, SGML or XML for which the DTD and/or
|
||
processing tools are not generally available, and the
|
||
machine-generated HTML, PostScript or PDF produced by some word
|
||
processors for output purposes only.
|
||
|
||
The "Title Page" means, for a printed book, the title page itself,
|
||
plus such following pages as are needed to hold, legibly, the material
|
||
this License requires to appear in the title page. For works in
|
||
formats which do not have any title page as such, "Title Page" means
|
||
the text near the most prominent appearance of the work's title,
|
||
preceding the beginning of the body of the text.
|
||
|
||
The "publisher" means any person or entity that distributes copies of
|
||
the Document to the public.
|
||
|
||
A section "Entitled XYZ" means a named subunit of the Document whose
|
||
title either is precisely XYZ or contains XYZ in parentheses following
|
||
text that translates XYZ in another language. (Here XYZ stands for a
|
||
specific section name mentioned below, such as "Acknowledgements",
|
||
"Dedications", "Endorsements", or "History".) To "Preserve the Title"
|
||
of such a section when you modify the Document means that it remains a
|
||
section "Entitled XYZ" according to this definition.
|
||
|
||
The Document may include Warranty Disclaimers next to the notice which
|
||
states that this License applies to the Document. These Warranty
|
||
Disclaimers are considered to be included by reference in this
|
||
License, but only as regards disclaiming warranties: any other
|
||
implication that these Warranty Disclaimers may have is void and has
|
||
no effect on the meaning of this License.
|
||
|
||
2. VERBATIM COPYING
|
||
|
||
You may copy and distribute the Document in any medium, either
|
||
commercially or noncommercially, provided that this License, the
|
||
copyright notices, and the license notice saying this License applies
|
||
to the Document are reproduced in all copies, and that you add no
|
||
other conditions whatsoever to those of this License. You may not use
|
||
technical measures to obstruct or control the reading or further
|
||
copying of the copies you make or distribute. However, you may accept
|
||
compensation in exchange for copies. If you distribute a large enough
|
||
number of copies you must also follow the conditions in section 3.
|
||
|
||
You may also lend copies, under the same conditions stated above, and
|
||
you may publicly display copies.
|
||
|
||
|
||
3. COPYING IN QUANTITY
|
||
|
||
If you publish printed copies (or copies in media that commonly have
|
||
printed covers) of the Document, numbering more than 100, and the
|
||
Document's license notice requires Cover Texts, you must enclose the
|
||
copies in covers that carry, clearly and legibly, all these Cover
|
||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||
the back cover. Both covers must also clearly and legibly identify
|
||
you as the publisher of these copies. The front cover must present
|
||
the full title with all words of the title equally prominent and
|
||
visible. You may add other material on the covers in addition.
|
||
Copying with changes limited to the covers, as long as they preserve
|
||
the title of the Document and satisfy these conditions, can be treated
|
||
as verbatim copying in other respects.
|
||
|
||
If the required texts for either cover are too voluminous to fit
|
||
legibly, you should put the first ones listed (as many as fit
|
||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||
pages.
|
||
|
||
If you publish or distribute Opaque copies of the Document numbering
|
||
more than 100, you must either include a machine-readable Transparent
|
||
copy along with each Opaque copy, or state in or with each Opaque copy
|
||
a computer-network location from which the general network-using
|
||
public has access to download using public-standard network protocols
|
||
a complete Transparent copy of the Document, free of added material.
|
||
If you use the latter option, you must take reasonably prudent steps,
|
||
when you begin distribution of Opaque copies in quantity, to ensure
|
||
that this Transparent copy will remain thus accessible at the stated
|
||
location until at least one year after the last time you distribute an
|
||
Opaque copy (directly or through your agents or retailers) of that
|
||
edition to the public.
|
||
|
||
It is requested, but not required, that you contact the authors of the
|
||
Document well before redistributing any large number of copies, to
|
||
give them a chance to provide you with an updated version of the
|
||
Document.
|
||
|
||
|
||
4. MODIFICATIONS
|
||
|
||
You may copy and distribute a Modified Version of the Document under
|
||
the conditions of sections 2 and 3 above, provided that you release
|
||
the Modified Version under precisely this License, with the Modified
|
||
Version filling the role of the Document, thus licensing distribution
|
||
and modification of the Modified Version to whoever possesses a copy
|
||
of it. In addition, you must do these things in the Modified Version:
|
||
|
||
A. Use in the Title Page (and on the covers, if any) a title distinct
|
||
from that of the Document, and from those of previous versions
|
||
(which should, if there were any, be listed in the History section
|
||
of the Document). You may use the same title as a previous version
|
||
if the original publisher of that version gives permission.
|
||
B. List on the Title Page, as authors, one or more persons or entities
|
||
responsible for authorship of the modifications in the Modified
|
||
Version, together with at least five of the principal authors of the
|
||
Document (all of its principal authors, if it has fewer than five),
|
||
unless they release you from this requirement.
|
||
C. State on the Title page the name of the publisher of the
|
||
Modified Version, as the publisher.
|
||
D. Preserve all the copyright notices of the Document.
|
||
E. Add an appropriate copyright notice for your modifications
|
||
adjacent to the other copyright notices.
|
||
F. Include, immediately after the copyright notices, a license notice
|
||
giving the public permission to use the Modified Version under the
|
||
terms of this License, in the form shown in the Addendum below.
|
||
G. Preserve in that license notice the full lists of Invariant Sections
|
||
and required Cover Texts given in the Document's license notice.
|
||
H. Include an unaltered copy of this License.
|
||
I. Preserve the section Entitled "History", Preserve its Title, and add
|
||
to it an item stating at least the title, year, new authors, and
|
||
publisher of the Modified Version as given on the Title Page. If
|
||
there is no section Entitled "History" in the Document, create one
|
||
stating the title, year, authors, and publisher of the Document as
|
||
given on its Title Page, then add an item describing the Modified
|
||
Version as stated in the previous sentence.
|
||
J. Preserve the network location, if any, given in the Document for
|
||
public access to a Transparent copy of the Document, and likewise
|
||
the network locations given in the Document for previous versions
|
||
it was based on. These may be placed in the "History" section.
|
||
You may omit a network location for a work that was published at
|
||
least four years before the Document itself, or if the original
|
||
publisher of the version it refers to gives permission.
|
||
K. For any section Entitled "Acknowledgements" or "Dedications",
|
||
Preserve the Title of the section, and preserve in the section all
|
||
the substance and tone of each of the contributor acknowledgements
|
||
and/or dedications given therein.
|
||
L. Preserve all the Invariant Sections of the Document,
|
||
unaltered in their text and in their titles. Section numbers
|
||
or the equivalent are not considered part of the section titles.
|
||
M. Delete any section Entitled "Endorsements". Such a section
|
||
may not be included in the Modified Version.
|
||
N. Do not retitle any existing section to be Entitled "Endorsements"
|
||
or to conflict in title with any Invariant Section.
|
||
O. Preserve any Warranty Disclaimers.
|
||
|
||
If the Modified Version includes new front-matter sections or
|
||
appendices that qualify as Secondary Sections and contain no material
|
||
copied from the Document, you may at your option designate some or all
|
||
of these sections as invariant. To do this, add their titles to the
|
||
list of Invariant Sections in the Modified Version's license notice.
|
||
These titles must be distinct from any other section titles.
|
||
|
||
You may add a section Entitled "Endorsements", provided it contains
|
||
nothing but endorsements of your Modified Version by various
|
||
parties--for example, statements of peer review or that the text has
|
||
been approved by an organization as the authoritative definition of a
|
||
standard.
|
||
|
||
You may add a passage of up to five words as a Front-Cover Text, and a
|
||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||
of Cover Texts in the Modified Version. Only one passage of
|
||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||
through arrangements made by) any one entity. If the Document already
|
||
includes a cover text for the same cover, previously added by you or
|
||
by arrangement made by the same entity you are acting on behalf of,
|
||
you may not add another; but you may replace the old one, on explicit
|
||
permission from the previous publisher that added the old one.
|
||
|
||
The author(s) and publisher(s) of the Document do not by this License
|
||
give permission to use their names for publicity for or to assert or
|
||
imply endorsement of any Modified Version.
|
||
|
||
|
||
5. COMBINING DOCUMENTS
|
||
|
||
You may combine the Document with other documents released under this
|
||
License, under the terms defined in section 4 above for modified
|
||
versions, provided that you include in the combination all of the
|
||
Invariant Sections of all of the original documents, unmodified, and
|
||
list them all as Invariant Sections of your combined work in its
|
||
license notice, and that you preserve all their Warranty Disclaimers.
|
||
|
||
The combined work need only contain one copy of this License, and
|
||
multiple identical Invariant Sections may be replaced with a single
|
||
copy. If there are multiple Invariant Sections with the same name but
|
||
different contents, make the title of each such section unique by
|
||
adding at the end of it, in parentheses, the name of the original
|
||
author or publisher of that section if known, or else a unique number.
|
||
Make the same adjustment to the section titles in the list of
|
||
Invariant Sections in the license notice of the combined work.
|
||
|
||
In the combination, you must combine any sections Entitled "History"
|
||
in the various original documents, forming one section Entitled
|
||
"History"; likewise combine any sections Entitled "Acknowledgements",
|
||
and any sections Entitled "Dedications". You must delete all sections
|
||
Entitled "Endorsements".
|
||
|
||
|
||
6. COLLECTIONS OF DOCUMENTS
|
||
|
||
You may make a collection consisting of the Document and other
|
||
documents released under this License, and replace the individual
|
||
copies of this License in the various documents with a single copy
|
||
that is included in the collection, provided that you follow the rules
|
||
of this License for verbatim copying of each of the documents in all
|
||
other respects.
|
||
|
||
You may extract a single document from such a collection, and
|
||
distribute it individually under this License, provided you insert a
|
||
copy of this License into the extracted document, and follow this
|
||
License in all other respects regarding verbatim copying of that
|
||
document.
|
||
|
||
|
||
7. AGGREGATION WITH INDEPENDENT WORKS
|
||
|
||
A compilation of the Document or its derivatives with other separate
|
||
and independent documents or works, in or on a volume of a storage or
|
||
distribution medium, is called an "aggregate" if the copyright
|
||
resulting from the compilation is not used to limit the legal rights
|
||
of the compilation's users beyond what the individual works permit.
|
||
When the Document is included in an aggregate, this License does not
|
||
apply to the other works in the aggregate which are not themselves
|
||
derivative works of the Document.
|
||
|
||
If the Cover Text requirement of section 3 is applicable to these
|
||
copies of the Document, then if the Document is less than one half of
|
||
the entire aggregate, the Document's Cover Texts may be placed on
|
||
covers that bracket the Document within the aggregate, or the
|
||
electronic equivalent of covers if the Document is in electronic form.
|
||
Otherwise they must appear on printed covers that bracket the whole
|
||
aggregate.
|
||
|
||
|
||
8. TRANSLATION
|
||
|
||
Translation is considered a kind of modification, so you may
|
||
distribute translations of the Document under the terms of section 4.
|
||
Replacing Invariant Sections with translations requires special
|
||
permission from their copyright holders, but you may include
|
||
translations of some or all Invariant Sections in addition to the
|
||
original versions of these Invariant Sections. You may include a
|
||
translation of this License, and all the license notices in the
|
||
Document, and any Warranty Disclaimers, provided that you also include
|
||
the original English version of this License and the original versions
|
||
of those notices and disclaimers. In case of a disagreement between
|
||
the translation and the original version of this License or a notice
|
||
or disclaimer, the original version will prevail.
|
||
|
||
If a section in the Document is Entitled "Acknowledgements",
|
||
"Dedications", or "History", the requirement (section 4) to Preserve
|
||
its Title (section 1) will typically require changing the actual
|
||
title.
|
||
|
||
|
||
9. TERMINATION
|
||
|
||
You may not copy, modify, sublicense, or distribute the Document
|
||
except as expressly provided under this License. Any attempt
|
||
otherwise to copy, modify, sublicense, or distribute it is void, and
|
||
will automatically terminate your rights under this License.
|
||
|
||
However, if you cease all violation of this License, then your license
|
||
from a particular copyright holder is reinstated (a) provisionally,
|
||
unless and until the copyright holder explicitly and finally
|
||
terminates your license, and (b) permanently, if the copyright holder
|
||
fails to notify you of the violation by some reasonable means prior to
|
||
60 days after the cessation.
|
||
|
||
Moreover, your license from a particular copyright holder is
|
||
reinstated permanently if the copyright holder notifies you of the
|
||
violation by some reasonable means, this is the first time you have
|
||
received notice of violation of this License (for any work) from that
|
||
copyright holder, and you cure the violation prior to 30 days after
|
||
your receipt of the notice.
|
||
|
||
Termination of your rights under this section does not terminate the
|
||
licenses of parties who have received copies or rights from you under
|
||
this License. If your rights have been terminated and not permanently
|
||
reinstated, receipt of a copy of some or all of the same material does
|
||
not give you any rights to use it.
|
||
|
||
|
||
10. FUTURE REVISIONS OF THIS LICENSE
|
||
|
||
The Free Software Foundation may publish new, revised versions of the
|
||
GNU Free Documentation License from time to time. Such new versions
|
||
will be similar in spirit to the present version, but may differ in
|
||
detail to address new problems or concerns. See
|
||
https://www.gnu.org/licenses/.
|
||
|
||
Each version of the License is given a distinguishing version number.
|
||
If the Document specifies that a particular numbered version of this
|
||
License "or any later version" applies to it, you have the option of
|
||
following the terms and conditions either of that specified version or
|
||
of any later version that has been published (not as a draft) by the
|
||
Free Software Foundation. If the Document does not specify a version
|
||
number of this License, you may choose any version ever published (not
|
||
as a draft) by the Free Software Foundation. If the Document
|
||
specifies that a proxy can decide which future versions of this
|
||
License can be used, that proxy's public statement of acceptance of a
|
||
version permanently authorizes you to choose that version for the
|
||
Document.
|
||
|
||
11. RELICENSING
|
||
|
||
"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
|
||
World Wide Web server that publishes copyrightable works and also
|
||
provides prominent facilities for anybody to edit those works. A
|
||
public wiki that anybody can edit is an example of such a server. A
|
||
"Massive Multiauthor Collaboration" (or "MMC") contained in the site
|
||
means any set of copyrightable works thus published on the MMC site.
|
||
|
||
"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
|
||
license published by Creative Commons Corporation, a not-for-profit
|
||
corporation with a principal place of business in San Francisco,
|
||
California, as well as future copyleft versions of that license
|
||
published by that same organization.
|
||
|
||
"Incorporate" means to publish or republish a Document, in whole or in
|
||
part, as part of another Document.
|
||
|
||
An MMC is "eligible for relicensing" if it is licensed under this
|
||
License, and if all works that were first published under this License
|
||
somewhere other than this MMC, and subsequently incorporated in whole or
|
||
in part into the MMC, (1) had no cover texts or invariant sections, and
|
||
(2) were thus incorporated prior to November 1, 2008.
|
||
|
||
The operator of an MMC Site may republish an MMC contained in the site
|
||
under CC-BY-SA on the same site at any time before August 1, 2009,
|
||
provided the MMC is eligible for relicensing.
|
||
|
||
|
||
ADDENDUM: How to use this License for your documents
|
||
|
||
To use this License in a document you have written, include a copy of
|
||
the License in the document and put the following copyright and
|
||
license notices just after the title page:
|
||
|
||
Copyright (c) YEAR YOUR NAME.
|
||
Permission is granted to copy, distribute and/or modify this document
|
||
under the terms of the GNU Free Documentation License, Version 1.3
|
||
or any later version published by the Free Software Foundation;
|
||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||
A copy of the license is included in the section entitled "GNU
|
||
Free Documentation License".
|
||
|
||
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
|
||
replace the "with...Texts." line with this:
|
||
|
||
with the Invariant Sections being LIST THEIR TITLES, with the
|
||
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
|
||
|
||
If you have Invariant Sections without Cover Texts, or some other
|
||
combination of the three, merge those two alternatives to suit the
|
||
situation.
|
||
|
||
If your document contains nontrivial examples of program code, we
|
||
recommend releasing these examples in parallel under your choice of
|
||
free software license, such as the GNU General Public License,
|
||
to permit their use in free software.
|
||
</pre>
|
||
#+end_export
|
||
|
||
#+html: <!--
|
||
|
||
* Indices
|
||
:properties:
|
||
:custom_id: h:55104b26-8e94-46cf-9975-43ea00316489
|
||
:end:
|
||
|
||
** Function index
|
||
:properties:
|
||
:index: fn
|
||
:custom_id: h:6bec5005-529c-4521-ae05-3d990baffb5b
|
||
:end:
|
||
|
||
** Variable index
|
||
:properties:
|
||
:index: vr
|
||
:custom_id: h:16ad8df6-b015-40a9-9259-03d4f7a23ee4
|
||
:end:
|
||
|
||
** Concept index
|
||
:properties:
|
||
:index: cp
|
||
:custom_id: h:6aa7a656-884b-4c39-b759-087e412eec13
|
||
:end:
|
||
|
||
#+html: -->
|