| CHANGELOG.org | ||
| COPYING | ||
| modus-operandi-theme.el | ||
| modus-vivendi-theme.el | ||
| README.org | ||
Modus Themes for GNU Emacs
Overview
This is a set of accessible themes for GNU Emacs. The contrast ratio between foreground and background values should always be >= 7:1, which conforms with the WCAG AAA accessibility standard. This is the highest standard of its kind.
The Modus themes project consists of two standalone items, one where dark text is cast on a light backdrop (Modus Operandi) and another where light text is displayed against a dark background (Modus Vivendi).
Check the Wiki page with the screen shots. Also note that I demo these themes in my Emacs-related screen casts (though older videos contain earlier, "alpha" versions).
Install and auto-load
Install the packages
I maintain Modus Operandi (light theme) and Modus Vivendi (dark) as standalone packages in ELPA, MELPA, and MELPA Stable.
Just run:
M-x package-install RET modus-operandi-theme RET
And/or:
M-x package-install RET modus-vivendi-theme RET
To be clear, that sequence means:
- press `Meta-X'
- type `package-install'
- hit the Return key
- type the name of the package
- hit Return to confirm your choice
With `use-package'
For a declarative approach with use-package, you can write something
like this:
(use-package modus-operandi-theme
:ensure t)
(use-package modus-vivendi-theme
:ensure t)
Manual installation method
Download the files in this repository ending in *-theme.el and place
them in an appropriate directory, such as ~/.emacs.d/themes/. To make
sure the filesystem path of your choice is read by Emacs, insert the
following in your initialisation file:
(add-to-list 'custom-theme-load-path "~/.emacs.d/themes/")
Load automatically
To load the theme from your Emacs initialisation file use the relevant snippet:
(load-theme 'modus-operandi t) ; Light theme
(load-theme 'modus-vivendi t) ; Dark theme
Make sure to remove any other theme that is being loaded, otherwise you might run into unexpected issues.
Customisation options
Both of the Modus themes expose some variables that allow users to tweak the look of the theme. By default, all variables are deactivated, meaning that you need to explicitly opt in.
This is what is available right now (use the ones appropriate to the theme of your choice):
;; Choose to render more code constructs in slanted text (italics). The
;; default, shown below, is to not use italics, unless it is absolutely
;; necessary.
(setq modus-operandi-theme-slanted-constructs nil)
(setq modus-vivendi-theme-slanted-constructs nil)
;; Opt to display some additional code constructs in bold. The default,
;; shown below, is to use bold weight only where necessary.
(setq modus-operandi-theme-bold-constructs nil)
(setq modus-vivendi-theme-bold-constructs nil)
;; Use proportionately-spaced fonts (variable-pitch) for headings. The
;; default is to use whatever font the user has selected, typically a
;; monospaced typeface.
(setq modus-operandi-theme-proportional-fonts nil)
(setq modus-vivendi-theme-proportional-fonts nil)
;; Whether headings should be scaled or have the same height as body
;; text. The default is to keep everything the same as the base size.
(setq modus-operandi-theme-scale-headings nil)
(setq modus-vivendi-theme-scale-headings nil)
;; Font scale that should apply to headings. These are the default values.
(setq modus-operandi-theme-scale-1 1.05)
(setq modus-operandi-theme-scale-2 1.1)
(setq modus-operandi-theme-scale-3 1.15)
(setq modus-operandi-theme-scale-4 1.2)
(setq modus-vivendi-theme-scale-1 1.05)
(setq modus-vivendi-theme-scale-2 1.1)
(setq modus-vivendi-theme-scale-3 1.15)
(setq modus-vivendi-theme-scale-4 1.2)
;; Make the fringes visible. This renders them in a different
;; background than the main buffer.
(setq modus-operandi-theme-visible-fringes nil)
(setq modus-vivendi-theme-visible-fringes nil)
;; Use a distinct background for Org's source blocks and extend their
;; headings until the edge of the window (the "extend" part is for Emacs
;; versions >= 27, whereas before they would extend anyhow). The
;; default is to use the same background as the rest of the buffer,
;; while beginning and end lines do not extend to the end of the window
;; (again, the extend is for Emacs 27 or higher).
(setq modus-operandi-theme-distinct-org-blocks nil)
(setq modus-vivendi-theme-distinct-org-blocks nil)
NOTE that all customisation options must be declared before loading the theme, else they will not be parsed and have no effect.
Face coverage
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.
Full support
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
- annotate
- anzu
- apropos
- apt-sources-list
- artbollocks-mode
- auctex and TeX
- auto-dim-other-buffers
- avy
- bm
- breakpoint (provided by built-in gdb-mi.el)
- buffer-expose
- calendar and diary
- calfw
- centaur-tabs
- change-log and log-view (
vc-print-logandvc-print-root-log) - cider
- column-enforce-mode
- company-mode*
- company-posframe
- compilation-mode
- completions
- counsel*
- counsel-css
- counsel-notmuch
- counsel-org-capture-string
- cov
- custom (
M-x customize) - dap-mode
- dashboard (emacs-dashboard)
- deadgrep
- define-word
- deft
- diff-hl
- diff-mode
- dim-autoload
- dired
- dired-async
- dired-git
- dired-git-info
- dired-narrow
- dired-subtree
- diredfl
- disk-usage
- doom-modeline
- dynamic-ruler
- easy-jekyll
- easy-kill
- ebdb
- ediff
- eldoc-box
- elfeed
- elfeed-score
- emms
- enhanced-ruby-mode
- epa
- equake
- erc
- ert
- eshell
- evil* (evil-mode)
- evil-goggles
- evil-visual-mark-mode
- eww
- eyebrowse
- fancy-dabbrev
- flycheck
- flycheck-indicator
- flycheck-posframe
- flymake
- flyspell
- flyspell-correct
- freeze-it
- frog-menu
- focus
- fold-this
- font-lock (generic syntax highlighting)
- fountain (fountain-mode)
- geiser
- git
- git-gutter (and variants)
- git-lens
- git-timemachine
- git-walktree
- gnus
- helm* (also see section below on Helm's grep-related functions)
- helm-ls-git
- helm-switch-shell
- helm-xref
- highlight-blocks
- highlight-defined
- highlight-escape-sequences (
hes-mode) - highlight-numbers
- highlight-thing
- hl-fill-column
- hl-line-mode
- hl-todo
- hydra
- ido-mode
- iedit
- imenu-list
- info
- info-colors
- interaction-log
- ioccur
- isearch, occur, etc.
- ivy*
- ivy-posframe
- jira (org-jira)
- js2-mode
- julia
- jupyter
- kaocha-runner
- keycast
- line numbers (
display-line-numbers-modeand global variant) - lsp-mode
- lsp-ui
- magit
- markdown-mode
- markup-faces (
adoc-mode) - mentor
- messages
- modeline
- mood-line
- mu4e
- mu4e-conversation
- multiple-cursors
- neotree
- num3-mode
- org*
- org-journal
- org-noter
- org-pomodoro
- org-recur
- org-roam
- org-superstar
- org-treescope
- origami
- outline-mode
- outline-minor-faces
- package (
M-x list-packages) - paradox
- paren-face
- pass
- persp-mode
- perspective
- powerline
- powerline-evil
- proced
- prodigy
- rainbow-blocks
- rainbow-identifiers
- rainbow-delimiters
- regexp-builder (also known as
re-builder) - rg (rg.el)
- ripgrep
- rmail
- ruler-mode
- sallet
- selectrum
- sesman
- shell-script-mode
- show-paren-mode
- side-notes
- skewer-mode
- smart-mode-line
- smartparens
- smerge
- speedbar
- stripes
- suggest
- swiper
- sx
- symbol-overlay
- syslog-mode
- telephone-line
- term
- transient (pop-up windows like Magit's)
- treemacs
- undo-tree
- vc (built-in mode line status for version control)
- vc-annotate (
C-x v g) - visual-regexp
- volatile-highlights
- web-mode
- wgrep
- which-function-mode
- which-key
- whitespace-mode
- window-divider-mode
- writegood-mode
- xah-elisp-mode
- xref
- xterm-color (and ansi-colors)
- yaml-mode
- ztree
Plus many other miscellaneous faces that are provided by the out-of-the-box Emacs distribution.
Covered but not styled explicitly
These do not require any extra styles because they are configured to inherit from some basic faces. Please confirm.
- comint
- bongo
- edit-indirect
Help needed
These are face groups that I am aware of but do not know how to access or do not actively use. I generally need to see how a face looks in its context before assessing its aesthetics or specific requirements.
Use M-x list-faces-display to get these.
- tty-menu
Note that the themes do provide support for org-mode, but some of
these interfaces have been decided based on indirect experience. If you
encounter anything that does not "feel right", please let me know.
Will NOT be supported
I have thus far identified a single package that does fit into the overarching objective of this project: solaire. It basically tries to cast a less intense background on the main file-visiting buffers, so that secondary elements like sidebars can have the default (pure white/black) background.
I will only support this package if it ever supports the inverse effect: less intense colours (but still accessible) for supportive interfaces and the intended styles for the content you are actually working on.
Note for HELM users of grep or grep-like functions
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
helm-grep.el library (view a library with M-x find-library).
Face used to highlight grep matches. Have no effect when grep backend use "–color="
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 customisation 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 colour number 1 (red) from the already-supported array of
ansi-color-names-vector.
I presented some screen shots of this in issue 21.
Note on VC-ANNOTATE-BACKGROUND-MODE
Due to the unique way vc-annotate (C-x v g) applies colours, support for
its background mode (vc-annotate-background-mode) is disabled at the
theme level.
Normally, such a drastic measure should not belong in a theme: assuming the user's preferences is bad practice. However, it has been deemed necessary in the interest of preserving colour contrast accessibility while still supporting a useful built-in tool.
If there actually is a way to avoid such a course of action, without prejudice to the accessibility standard of this project, then please report as much (or contribute as per the information in the Contributing section).
Contributing
A few tasks you can help me with, sorted from the most probable to the least likely:
- 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 colour palette.
- Help expand this document or any other piece of documentation.
It would be great if your feedback also includes some screenshots, GIFs, or short videos. Though this is not a requirement.
Whatever you do, please 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 colours. If a compromise is ever necessary between aesthetics and accessibility, it shall always be made in the interest of the latter.
Code contributions require copyright assignment to the FSF
I accept code contributions as well (send merge requests!). But for any major contribution (more than 15 lines, or so), you need to make a copyright assignment to the Free Software Foundation. This is necessary because the themes are distributed through the official GNU ELPA repository and the FSF must be in a position to enforce the GNU General Public License.
Copyright assignment is a simple process that I had to follow as well. Check the request form. You must send 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 should all happen via email and take about a week.
I encourage you to go through this process. You only need to do it once. It will allow you to make contributions to Emacs in general.
Meta
If you interested in the principles that govern the development of this project, read my article On the design of the Modus themes (2020-03-17).
COPYING
The Modus Themes are distributed under the terms of the GNU General Public License version 3 or, at your choice, any later version. See the COPYING file distributed in the project's Git repository.