🏆 I provide private lessons on Emacs, Linux, and Life in general: https://protesilaos.com/coach/. Lessons continue throughout the year.

Emacs: modus-themes version 4.4.0

I just published the latest stable release of the Modus themes. The change log entry is reproduced further below. For any questions, feel welcome to contact me.

I will soon install the changes in emacs.git so please wait a little longer for the updates to trickle down to you.


Before I cover the changes, a brief note about the canonical source of the modus-themes source code and corresponding documentation.

The modus-themes are built into Emacs, as of version 28, but they are not developed in emacs.git: I maintain my own Git repository (https://github.com/protesilaos/modus-themes) and sync with emacs.git whenever I publish a new version, such as this one. This means that my code is often ahead of the one in the Emacs tree (including the master branch). Similarly, the official manual, which is hosted on my website (https://protesilaos.com/emacs/modus-themes), covers topics not found in the corresponding gnu.org web pages.

In the opening section of the manual I include references to the canonical sources, but I still get comments about GNU web pages that I do not control. Please check those links before reporting issues that I can do nothing about.

No more SourceHut

Development continues on GitHub with GitLab as a mirror. I explained my reasons here: https://protesilaos.com/codelog/2024-01-27-sourcehut-no-more/.

This is a change that affects all my Emacs packages.

Code blocks now have a background by default

The user option modus-themes-org-blocks is obsolete. All code blocks now have a subtle grey background out-of-the-box. The block delimiter lines, such as the #+begin_src in Org mode, use the same background as the block’s contents. This produces a style that (i) is easy to notice and (ii) employs minimal colouration. Furthermore, we no longer have any discrepancy between Org and similar modes like Markdown.

Every theme has relevant semantic palette mappings to affect the underlying faces:

  • bg-prose-block-delimiter
  • fg-prose-block-delimiter
  • bg-prose-block-contents

The old prose-block is now renamed to fg-prose-block-delimiter. Please update any such references in your configuration file.

Users can customise those either for all themes via the user option modus-themes-common-palette-overrides or on a per-theme basis with something like modus-operandi-palette-overrides. The manual includes ready-to-use code samples that showcases the numerous permutations made possible by these new mappings: https://protesilaos.com/emacs/modus-themes#h:f44cc6e3-b0f1-4a5e-8a90-9e48fa557b50.

The old option to affect the user option org-src-block-faces as to have a different background for each specified programming language is no longer available. The previous design was inflexible, as I was hardcoding values for a few languages. Whereas it is better to empower the user with the choice of language->colour association. The manual shows how to do this: https://protesilaos.com/emacs/modus-themes#h:8c842804-43b7-4287-b4e9-8c07d04d1f89.

More semantic mappings more inline code in prose-centric modes

For Org, Markdown, and related we have semantic palette mappings that target inline code constructs. For example, in Org we can have text inside of tilde signs to mark it up as code. In prior versions, the mappings were limited to just a foreground, but now they cover background values as well. By default, these background do not have a colour associated with them, meaning that the out-of-the-box aesthetic is the same as before. Users simply have more power at their disposal to tweak the theme to their liking.

Here are the names of those mappings:

  • bg-prose-code
  • fg-prose-code
  • bg-prose-macro
  • fg-prose-macro
  • bg-prose-verbatim
  • fg-prose-verbatim

The old prose-code, prose-macro, and prose-verbatim are named fg-prose-code, fg-prose-macro, fg-prose-verbatim. Please update any such references in your configuration file.

The manual shows lots of examples on how to benefit from these optional backgrounds: https://protesilaos.com/emacs/modus-themes#h:bb5b396f-5532-4d52-ab13-149ca24854f1.

No colour-coding for transient.el buffers.

In a recent version of transient.el, there is a new user option that applies colour-coding to keys (e.g. we see those while using magit): transient-semantic-coloring. This option is enabled by default, changing the previous style that was used as a reference for all my designs.

The idea with such colour coding is to indicate when a key continues to display the transient, exits with a given action, and the like. For our purposes this interface cannot work:

  • We need some place to teach users what each colour means, as there are no indicators of any sort to help them (whereas, say, in diff buffers we have the plus and minus signs).

  • Not all hues are suitable for highlighting a single character. In light themes, for example, green and yellow colours are awkward choices for the requirements of this interface where the key must be clearly visible. But when we introduce multiple colours, each with their own meaning, we will not be able to avoid those hues.

  • The style of key bindings is not limited to transient.el. We find them when we invoke M-x, do M-x describe-bindings, while using the which-key package, and many more. If we are to change how transient.el shows key bindings, then we have to retain the same visual cues for other contexts. Otherwise, everything is inconsistent.

  • All themes must use the same colours to preserve the colour coding, thus removing an important aspect of their presentation.

  • This whole paradigm does not work for themes that are optimised for users with colour deficiency, due to the reduced number of suitable hues. With deuteranopia, for example, we can only rely on yellow and blue: since yellow is not optimal for single key highlights against a light backdrop, blue is the only hue that works in such a context.

The modus-themes will never support transient-semantic-coloring. All relevant faces use the style of standard key bindings.

Themes can enforce user option values, but I have decided to change the faces instead to better communicate my intent. If a user wants semantic colouring, they can change the faces to whatever they like.

I understand this is a radical measure, though it is the best I can do given the circumstances. If transient.el where to have accompanying characters that better denote what each key does (e.g. the plus sign is for keys that continue the transient), then I am happy to apply appropriate colours to those and reconsider the aforementioned.

Semantic mappings for active arguments and values

In various interfaces such as of eldoc-mode and transient.el there are highlights for the current argument or argument value. These now have corresponding semantic palette mappings and are thus styled uniformly (and can be overridden accordingly). The mappings are:

  • bg-active-argument
  • fg-active-argument
  • bg-active-value
  • fg-active-value

A semantic mapping for formulas in tables

The prose-table-formula applies to inline formula expressions in plain text tables. Org mode uses those, as does the minor mode orgtbl-mode. The inline formula is meant to stand out from the rest of the table, without exaggerations.

Matching parentheses have semantic mappings for their foreground too

By default, Emacs will highlight the matching (opening or closing) delimiter when the cursor is next to it. This is useful in Lisp programming modes, for example, as we can quickly get a sense of where an expression starts and ends.

The themes now provide mappings for the foreground of those delimiters. This means that users can either change the combination of background and foreground or opt to only display a foreground value for a more minimal look.

As always, the manual shows concrete examples: https://protesilaos.com/emacs/modus-themes#h:259cf8f5-48ec-4b13-8a69-5d6387094468.

Search highlights have their own semantic mappings

This makes it easier to differentiate their style on a per-theme basis, which I do for all the Modus themes. It also gives users the option to override the colours. The mappings:

  • bg-search-current
  • bg-search-lazy
  • bg-search-replace
  • bg-search-rx-group-0
  • bg-search-rx-group-1
  • bg-search-rx-group-2
  • bg-search-rx-group-3

Stylistic tweaks to modus-operandi-tinted

The modus-operandi-theme uses a light ochre background, which gives a warmer feel than the pure white background of modus-operandi. To better contribute to this warmth, I made some tweaks to common elements:

  1. The cursor has a red hue as before, but the value is a bit more intense now. This makes it easier to spot in contexts where text is already “warm”, like close to an Org TODO keyword or in programming mode comments.

  2. All key bindings have a red hue instead of blue. We can notice the effect in Help mode buffers that mention where a command is bound, while using which-key-mode, in transient.el buffers, in minibuffer completion annotations, and more.

These are in addition to many nuances already built into modus-operandi-tinted.

I hope that existing users will appreciate these tweaks. We anyway have the option to override any entry in the palette, though I suggest you give these a chance before enacting any changes.

Stylistic tweaks to modus-vivendi-tinted

Same principle here as with the above set of changes. Namely:

  1. The cursor uses a more intense magenta background to be easier to spot.

  2. Key bindings are purple instead of blue to better complement the aesthetics of this theme.

  3. The background highlight applied to matching parentheses (per show-paren-mode) is grey-cyan instead of cyan.

Again, we can override everything but please try those for a little while.

The olivetti-fringe is visible when needed

This is subject to the user option olivetty-style, which can be set to the value of fancy to produce a page-like effect.

Thanks to Dhavan Vaidya and Gautier Ponsinet for bringing this matter to my attention on the now-discontinued mailing list: https://lists.sr.ht/~protesilaos/modus-themes/%3Cm2a5qzpi3y.fsf%40muon.local.mail-host-address-is-not-set%3E

A more subtle style for the consult-preview-insertion face

The default value of that face inherits from the region face. This is fine in some cases, though not when the user calls consult-outline in a buffer with hidden text (e.g. Org folded headings). There the background is applied to the entire heading’s surface area, which is too distracting while cycling through completion candidates and inspecting the preview.

Simpler imenu-list with four colours

The imenu-list defines two sets of faces which apply to same heading levels but differ on whether the heading has subheadings or not. Before, we would colourise those differently, which could be confusing. Now they look the same, which is fine because the interface has additional markup to show when subheadings are present.

Thanks to ltmsyvag for pointing this out in issue 95: https://github.com/protesilaos/modus-themes/issues/95.

Implicit buttons in Gnus are no longer underlined

Gnus buttonises text that it considers actionable. The exact functionality depends on the context, but it basically does stuff like add a quick way to write a new message to a given email address. These buttons can be mistaken for links, so I am removing their underline to avoid any possible confusion.

The message-separator face is less intense

In message/email composition buffers, there is a line that distinguishes headers from the body of the message. By default, it reads --text follows this line-- and will now have a subtle grey background. The idea is to not stress the distinction between headers and body, as this line’s verbosity is already enough to call attention to it when we add a subtle background.

Recalibrated all “nuanced” background values

Each theme has a subset of slightly accented background named bg-{red,green,blue,yellow,magenta,cyan}-nuanced. These have slightly different values to be more consistent in terms of their intensity.

The debbugs package is now supported

Thanks to Gautier Ponsinet for sending me the relevant patch to my personal email. I made further stylistic changes on top.

The ztree package is covered as well

It produces a diff between two directories and thus needs appropriate colours.

Added support for xterm-color and rustic-mode

These are basically reusing styles we already support for other terminal emulators. Thanks to Tony Zorman for the contribution, which was done in pull request 99: https://github.com/protesilaos/modus-themes/pull/99.

Org checkboxes are monospaced when modus-themes-mixed-fonts is non-nil

The user option modus-themes-mixed-fonts makes specing-sensitive elements use a monospaced font (specifically, the font family of the fixed-pitch face). This lets the user set a more prose-friendly style without visually breaking snippets that rely on fixed width spacing. A prose-friendly style is done by making the default font a proportionately spaced one, or by enabling variable-pitch-mode in the current buffer.

For this case, we now cover Org checkboxes as well to avoid misalignments in checklists.

Thanks to Gautier Ponsinet for discussing this with me via email and sending the relevant patch.

More code samples in the manual

The manual documents everything about the customisation options provided by the themes, as well as relevant do-it-yourself code samples. I now include more examples and better explain how to hook those either to the enable-theme-functions or the modus-themes-after-load-theme-hook. If something is not clear or not covered at all, please let me know and I will help you do what you want.

Miscellaneous

  • All cl- snippets are removed from the source code. We did not really need them and I rewrote the code accordingly. This is not a value judgement against Common Lisp patterns in Emacs Lisp (I do not mind them): it is just a matter of removing a dependency for things that can easily be done differently.

  • The keycast-key inherits the bold face if the user option modus-themes-bold-constructs is set to a non-nil value.

  • The read-multiple-choice-face now has a cooler hue than the one it had before. This way it is not mistaken for a warning.

  • The appt-notification face uses a foreground value that is better suited for the modeline, where this indicator appears.

  • The header-line-highlight draws a box around it. This makes the mouse hover effect easier to spot.

  • The shr-mark face is now covered as well. It uses an appropriate background colour.

  • The mct-highlight-candidate face is covered and has an appropriate style for the minibuffer completions.

  • The completions-highlight face (Emacs 29) is also supported to ensure stylistic consistency between the minibuffer interfaces covered by the themes.

  • Flagged and deleted messages in mu4e and notmuch use different hues to not conflate the two.

  • Fixed the spelling of “colour” to “color” in the manual because core Emacs uses the latter…