emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 733a6776f9d: Merge remote-tracking branch 'origin/master


From: Po Lu
Subject: feature/android 733a6776f9d: Merge remote-tracking branch 'origin/master' into feature/android
Date: Tue, 30 May 2023 07:16:50 -0400 (EDT)

branch: feature/android
commit 733a6776f9d665e5fd99bcc2a65c84c4360e277c
Merge: 9e52188628e f8a79c0055f
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Merge remote-tracking branch 'origin/master' into feature/android
---
 admin/notes/emba                                   |   7 +-
 doc/misc/erc.texi                                  |  54 ++-
 doc/misc/modus-themes.org                          | 400 +++++++++++++++++----
 etc/ERC-NEWS                                       |  30 +-
 etc/NEWS                                           |  11 +-
 etc/themes/modus-operandi-deuteranopia-theme.el    |  47 ++-
 etc/themes/modus-operandi-theme.el                 |  35 +-
 etc/themes/modus-operandi-tinted-theme.el          |  35 +-
 ...theme.el => modus-operandi-tritanopia-theme.el} | 257 +++++++------
 etc/themes/modus-themes.el                         | 385 +++++++++++++++-----
 etc/themes/modus-vivendi-deuteranopia-theme.el     |  49 ++-
 etc/themes/modus-vivendi-theme.el                  |  33 +-
 etc/themes/modus-vivendi-tinted-theme.el           |  33 +-
 ...-theme.el => modus-vivendi-tritanopia-theme.el} | 260 ++++++++------
 lisp/emacs-lisp/comp-cstr.el                       |  31 +-
 lisp/emacs-lisp/comp.el                            |  38 +-
 lisp/erc/erc-button.el                             |   7 +-
 lisp/erc/erc-log.el                                |  17 +-
 lisp/erc/erc-stamp.el                              |  16 +
 lisp/erc/erc-truncate.el                           |  21 +-
 lisp/erc/erc.el                                    |  96 ++++-
 test/infra/Dockerfile.emba                         |  56 +++
 test/infra/gitlab-ci.yml                           |  35 ++
 test/lisp/erc/erc-scenarios-log.el                 | 207 +++++++++++
 test/lisp/erc/erc-tests.el                         |  99 +++++
 25 files changed, 1734 insertions(+), 525 deletions(-)

diff --git a/admin/notes/emba b/admin/notes/emba
index c88b422a4fa..1f87a99ddc0 100644
--- a/admin/notes/emba
+++ b/admin/notes/emba
@@ -97,15 +97,16 @@ recent Emacs branch, and apply the command
 This creates the Debian-based image emacs-inotify, based on the
 instructions in the file Dockerfile.emba.  This image is good for the
 majority of tests.  However, there are also other image build
-instructions like emacs-filenotify-gio, emacs-eglot, emacs-gnustep and
-emacs-native-comp-speed{0,1,2}.  Use the appropriate one.
+instructions like emacs-filenotify-gio, emacs-eglot,
+emacs-tree-sitter, emacs-gnustep and emacs-native-comp-speed{0,1,2}.
+Use the appropriate one.
 
 The image contains a directory "/checkout", which is a copy of your
 local Emacs git repository.  Emacs has been built in this directory
 via "make bootstrap".  In order to use the image, start a container
 like
 
-  docker run --interactive --env EMACS_EMBA_CI=1 --name emacs-inotify \
+  docker run --interactive --tty --env EMACS_EMBA_CI=1 --name emacs-inotify \
     emacs-inotify /bin/sh -i
 
 In this container, change the current directory to "/checkout".  Now
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index 1f343fc8529..14c6a457654 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -2,7 +2,7 @@
 @c %**start of header
 @setfilename ../../info/erc.info
 @settitle ERC Manual
-@set ERCVER 5.5
+@set ERCVER 5.6
 @set ERCDIST as distributed with Emacs @value{EMACSVER}
 @include docstyle.texi
 @syncodeindex fn cp
@@ -611,6 +611,7 @@ And unlike global toggles, none of these ever mutates
 Integrations
 
 * URL::                         Opening IRC URLs in ERC.
+* SOCKS::                       Connecting to IRC with a SOCKS proxy.
 * auth-source::                 Retrieving auth-source entries with ERC.
 
 @end detailmenu
@@ -1252,6 +1253,57 @@ need a function as well:
 @noindent
 Users on Emacs 28 and below may need to use @code{browse-url} instead.
 
+@anchor{SOCKS}
+@subsection SOCKS
+@cindex SOCKS
+
+People wanting to connect to IRC through a @acronym{SOCKS} proxy are
+most likely interested in doing so over @acronym{TOR} (The Onion
+Router).  If that's @emph{not} you, please adapt these instructions
+accordingly.  Otherwise, keep in mind that support for Tor is
+experimental and thus insufficient for safeguarding a user's identity
+and location, especially in the case of targeted individuals.
+
+ERC's preferred Tor setup works by accessing a local Tor service
+through the built-in @file{socks.el} library that ships with Emacs.
+Other means of accessing Tor, such as via @command{torsocks}, are not
+supported.  Before getting started, check that your Tor service is up
+and running.  You can do that with the following command:
+
+@example
+curl --proxy socks5h://localhost:9050 https://check.torproject.org | \
+  grep 'Congratulations'
+@end example
+
+Networks and servers differ in how they expose Tor endpoints.  In all
+cases, you'll want to first set the option @code{socks-server} to
+something appropriate, like @code{("tor" "127.0.0.1" 9050 5)}.  For
+some networks, setting @code{erc-server-connect-function} to
+@code{socks-open-network-stream} might be enough.  Others, like
+@samp{Libera.Chat}, involve additional setup.  At the time of writing,
+connecting to @samp{Libera.Chat} requires both @acronym{TLS} and a
+non-@samp{PLAIN} @acronym{SASL} mechanism (@pxref{SASL}).  One way to
+achieve that is by using the @samp{EXTERNAL} mechanism, as shown in
+the following example:
+
+@lisp
+(require 'erc)
+(require 'socks)
+
+(let* ((socks-password "")
+       (socks-server '("tor" "localhost" 9050 5))
+       (erc-modules (cons 'sasl erc-modules))
+       (erc-sasl-mechanism 'external)
+       (erc-server-connect-function #'erc-open-socks-tls-stream))
+  (erc-tls
+   :server "libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion"
+   :port 6697
+   :nick "jrh"
+   :user "jrandomhacker"
+   :full-name "J. Random Hacker"
+   :client-certificate (list "/home/jrh/key.pem" "/home/jrh/cert.pem")))
+@end lisp
+
 @node auth-source
 @subsection auth-source
 @cindex auth-source
diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org
index 47d3e6c03e3..7809bd03918 100644
--- a/doc/misc/modus-themes.org
+++ b/doc/misc/modus-themes.org
@@ -4,9 +4,9 @@
 #+language:              en
 #+options:               ':t toc:nil author:t email:t num:t
 #+startup:               content
-#+macro:                 stable-version 4.1.0
-#+macro:                 release-date 2023-02-22
-#+macro:                 development-version 4.2.0-dev
+#+macro:                 stable-version 4.2.0
+#+macro:                 release-date 2023-05-30
+#+macro:                 development-version 4.3.0-dev
 #+macro:                 file @@texinfo:@file{@@$1@@texinfo:}@@
 #+macro:                 space @@texinfo:@: @@
 #+macro:                 kbd @@texinfo:@kbd{@@$1@@texinfo:}@@
@@ -77,7 +77,7 @@ combinations of background and foreground values.  For small 
sized
 text, this corresponds to the WCAG AAA standard, which specifies a
 minimum rate of distance in relative luminance of 7:1.
 
-The Modus themes consist of six themes, divided into three subgroups.
+The Modus themes consist of eight themes, divided into four subgroups.
 
 - Main themes :: ~modus-operandi~ is the project's main light theme,
   while ~modus-vivendi~ is its dark counterpart.  These two themes are
@@ -101,15 +101,23 @@ The Modus themes consist of six themes, divided into 
three subgroups.
   users with deueteranopia or deuteranomaly (mostly yellow and blue
   hues).
 
+- Tritanopia themes :: ~modus-operandi-tritanopia~ and its counterpart
+  ~modus-vivendi-tritanopia~ are optimized for users with blue-yellow
+  color deficiency.  The idea is the same as with the deuteranopia
+  variants: color coding relies only on hues that are accessible to
+  people with tritanopia or tritanomaly, namely, shades of red and
+  cyan.
+
 To ensure that users have a consistently accessible experience, the
 themes strive to achieve as close to full face coverage as possible,
 while still targeting a curated list of well-maintained packages
 ([[#h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19][Face coverage]]).
 
-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.
+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
+usability and stylistic considerations, we will always opt for the
+former.
 
 Starting with version 0.12.0 and onwards, the themes are built into GNU
 Emacs.
@@ -441,6 +449,8 @@ 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.
 
+[[#h:aabcada6-810d-4eee-b34a-d2a9c301824d][Make the themes look like what the 
maintainer uses]]
+
 ** Differences between loading and enabling
 :properties:
 :custom_id: h:e68560b3-7fb0-42bc-a151-e015948f8a35
@@ -1066,6 +1076,9 @@ palette variable is =THEME-NAME-palette-overrides=, thus 
yielding:
 #+vindex: modus-operandi-tinted-palette-overrides
 + ~modus-operandi-tinted-palette-overrides~
 
+#+vindex: modus-operandi-tritanopia-palette-overrides
++ ~modus-operandi-tritanopia-palette-overrides~
+
 #+vindex: modus-vivendi-palette-overrides
 + ~modus-vivendi-palette-overrides~
 
@@ -1075,6 +1088,9 @@ palette variable is =THEME-NAME-palette-overrides=, thus 
yielding:
 #+vindex: modus-vivendi-tinted-palette-overrides
 + ~modus-vivendi-tinted-palette-overrides~
 
+#+vindex: modus-vivendi-tritanopia-palette-overrides
++ ~modus-vivendi-tritanopia-palette-overrides~
+
 Theme-specific overrides take precedence over the shared ones.  It is
 strongly advised that shared overrides do NOT alter color values, as
 those will not be appropriate for both dark and light themes.  Common
@@ -1123,7 +1139,7 @@ For example, the ~modus-operandi-palette~ is like this:
 #+end_src
 
 The ~modus-operandi-palette-overrides~ targets the entries that need
-to be changed.  For example, to make the main foreground colour a dark
+to be changed.  For example, to make the main foreground color a dark
 gray instead of pure black, use a shade of red for comments, and apply
 a cyan hue to keywords:
 
@@ -1153,15 +1169,30 @@ Named colors can be previewed, such as with the command
 For a video tutorial that users of all skill levels can approach,
 watch: https://protesilaos.com/codelog/2022-12-17-modus-themes-v4-demo/.
 
-*** Palette override presets
+* 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".
+
+** Palette override presets
 :PROPERTIES:
 :CUSTOM_ID: h:b0bc811c-227e-42ec-bf67-15e1f41eb7bc
 :END:
 
 This section shows how to refashion the themes by opting in to the
 stylistic presets we provide.  Those presets override the default
-color mappings to amplify or tone down the overall coloration of the
-them.
+color mappings to amplify, tone down, or refashion the overall
+coloration of the themes.
 
 To make almost all aspects of the themes less intense, use this:
 
@@ -1187,6 +1218,18 @@ The ~modus-themes-preset-overrides-intense~ makes many 
background
 colors accented instead of gray and increases coloration in a number
 of places.  Colors stand out more and are made easier to spot.
 
+#+vindex: modus-themes-preset-overrides-cooler
+#+vindex: modus-themes-preset-overrides-warmer
+For some stylistic variation try the "cooler" and "warmer" presets:
+
+#+begin_src emacs-lisp
+;; This:
+(setq modus-themes-common-palette-overrides 
modus-themes-preset-overrides-cooler)
+
+;; Or:
+(setq modus-themes-common-palette-overrides 
modus-themes-preset-overrides-warmer)
+#+end_src
+
 Note that the user is not limited to those presets.  The system of
 overrides we provide makes it possible to tweak the value of each
 individual named color and to change how values are assigned to
@@ -1214,7 +1257,7 @@ the general idea (extra space for didactic purposes):
         ,@modus-themes-preset-overrides-intense))
 #+end_src
 
-*** Stylistic variants using palette overrides
+** Stylistic variants using palette overrides
 :PROPERTIES:
 :CUSTOM_ID: h:df1199d8-eaba-47db-805d-6b568a577bf3
 :END:
@@ -1226,7 +1269,7 @@ to take effect.  To apply overrides at startup simply 
define them
 before the call that loads the theme.  Remember that we also provide
 presets that are easier to apply 
([[#h:b0bc811c-227e-42ec-bf67-15e1f41eb7bc][Palette override presets]]).
 
-**** Make the mode line borderless
+*** Make the mode line borderless
 :PROPERTIES:
 :CUSTOM_ID: h:80ddba52-e188-411f-8cc0-480ebd75befe
 :END:
@@ -1263,7 +1306,7 @@ set their color to that of the underlying background.
         (border-mode-line-inactive bg-mode-line-inactive)))
 #+end_src
 
-**** Make the active mode line colorful
+*** Make the active mode line colorful
 :PROPERTIES:
 :CUSTOM_ID: h:e8d781be-eefc-4a81-ac4e-5ed156190df7
 :END:
@@ -1307,7 +1350,7 @@ have a blue mode line for ~modus-operandi~ and a red one 
for
         (border-mode-line-active bg-red-subtle)))
 #+end_src
 
-**** Make the tab bar more or less colorful
+*** Make the tab bar more or less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:096658d7-a0bd-4a99-b6dc-9b20a20cda37
 :END:
@@ -1359,7 +1402,7 @@ manual.
         (bg-tab-other bg-cyan-subtle)))
 #+end_src
 
-**** Make the fringe invisible or another color
+*** Make the fringe invisible or another color
 :PROPERTIES:
 :CUSTOM_ID: h:c312dcac-36b6-4a1f-b1f5-ab1c9abe27b0
 :END:
@@ -1393,7 +1436,7 @@ or continuation lines.
       '((fringe bg-blue-nuanced)))
 #+end_src
 
-**** Make links use subtle or no underlines
+*** Make links use subtle or no underlines
 :PROPERTIES:
 :CUSTOM_ID: h:6c1d1dea-5cbf-4d92-b7bb-570a7a23ffe9
 :END:
@@ -1417,7 +1460,7 @@ that underline mappings can read correctly.
         (underline-link-symbolic unspecified)))
 #+end_src
 
-**** Make prompts more or less colorful
+*** Make prompts more or less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:bd75b43a-0bf1-45e7-b8b4-20944ca8b7f8
 :END:
@@ -1454,7 +1497,7 @@ block we show how to add or remove color from prompts.
         (bg-prompt bg-yellow-subtle))) ; try to replace "subtle" with "intense"
 #+end_src
 
-**** Make completion matches more or less colorful
+*** Make completion matches more or less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:d959f789-0517-4636-8780-18123f936f91
 :END:
@@ -1541,7 +1584,7 @@ colors to two:
 
 The user can mix and match to their liking.
 
-**** Make comments yellow and strings green
+*** Make comments yellow and strings green
 :PROPERTIES:
 :CUSTOM_ID: h:26f53daa-0065-48dc-88ab-6a718d16cd95
 :END:
@@ -1584,7 +1627,7 @@ reproduce the effect, but also how to tweak it to one's 
liking.
         (string yellow-cooler)))
 #+end_src
 
-**** Make code syntax use the old alt-syntax style
+*** Make code syntax use the old alt-syntax style
 :PROPERTIES:
 :CUSTOM_ID: h:c8767172-bf11-4c96-81dc-e736c464fc9c
 :END:
@@ -1669,7 +1712,7 @@ The user can always mix and match styles to their liking.
 
 [[#h:943063da-7b27-4ba4-9afe-f8fe77652fd1][Make use of alternative styles for 
code syntax]].
 
-**** Make use of alternative styles for code syntax
+*** Make use of alternative styles for code syntax
 :PROPERTIES:
 :CUSTOM_ID: h:943063da-7b27-4ba4-9afe-f8fe77652fd1
 :END:
@@ -1760,7 +1803,7 @@ theme palette.
         (variable cyan-warmer)))
 #+end_src
 
-**** Make matching parenthesis more or less intense
+*** Make matching parenthesis more or less intense
 :PROPERTIES:
 :CUSTOM_ID: h:259cf8f5-48ec-4b13-8a69-5d6387094468
 :END:
@@ -1790,7 +1833,7 @@ to enable underlines for those highlights.
         (underline-paren-match fg-main)))
 #+end_src
 
-**** Make box buttons more or less gray
+*** Make box buttons more or less gray
 :PROPERTIES:
 :CUSTOM_ID: h:4f6b6ca3-f5bb-4830-8312-baa232305360
 :END:
@@ -1818,7 +1861,7 @@ inactive ones.
         (fg-button-inactive "gray50")))
 #+end_src
 
-**** Make TODO and DONE more or less intense
+*** Make TODO and DONE more or less intense
 :PROPERTIES:
 :CUSTOM_ID: h:b57bb50b-a863-4ea8-bb38-6de2275fa868
 :END:
@@ -1858,7 +1901,7 @@ to subdue them.
       '((prose-done fg-dim)))
 #+end_src
 
-**** Make headings more or less colorful
+*** Make headings more or less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:11297984-85ea-4678-abe9-a73aeab4676a
 :END:
@@ -1915,7 +1958,7 @@ match styles at will.
         (overline-heading-1 border)))
 #+end_src
 
-**** Make Org agenda more or less colorful
+*** Make Org agenda more or less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:a5af0452-a50f-481d-bf60-d8143f98105f
 :END:
@@ -1980,7 +2023,25 @@ A third example that makes the agenda more blue:
         (date-weekend fg-dim)))
 #+end_src
 
-**** Make inline code in prose use alternative styles
+Yet another example that also affects =DONE= and =TODO= keywords:
+
+#+begin_src emacs-lisp
+;; Change dates to a set of more subtle combinations.  Deadlines are a
+;; shade of magenta, scheduled dates are a shade of green that
+;; complements that of the deadlines, weekday headings use the main
+;; foreground color while weekends are a shade of gray.  The DONE
+;; keyword is a faint blue-gray while TODO is yellow.
+(setq modus-themes-common-palette-overrides
+      '((date-deadline magenta-warmer)
+        (date-scheduled green-cooler)
+        (date-weekday fg-main)
+        (date-event fg-dim)
+        (date-now blue)
+        (prose-done fg-alt)
+        (prose-todo yellow)))
+#+end_src
+
+*** Make inline code in prose use alternative styles
 :PROPERTIES:
 :CUSTOM_ID: h:bb5b396f-5532-4d52-ab13-149ca24854f1
 :END:
@@ -2039,7 +2100,7 @@ do not show every possible permutation.
         (prose-verbatim red-warmer)))
 #+end_src
 
-**** Make mail citations and headers more or less colorful
+*** Make mail citations and headers more or less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:7da7a4ad-5d3a-4f11-9796-5a1abed0f0c4
 :END:
@@ -2108,7 +2169,7 @@ We thus have the following:
         (mail-other green)))
 #+end_src
 
-**** Make the region preserve text colors, plus other styles
+*** Make the region preserve text colors, plus other styles
 :PROPERTIES:
 :CUSTOM_ID: h:c8605d37-66e1-42aa-986e-d7514c3af6fe
 :END:
@@ -2148,7 +2209,7 @@ with an appropriate foreground value.
         (fg-region fg-main)))
 #+end_src
 
-**** Make mouse highlights more or less colorful
+*** Make mouse highlights more or less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:b5cab69d-d7cb-451c-8ff9-1f545ceb6caf
 :END:
@@ -2177,7 +2238,7 @@ mapping that covers mouse hover effects and related 
highlights:
       '((bg-hover bg-green-subtle)))
 #+end_src
 
-**** Make language underlines less colorful
+*** Make language underlines less colorful
 :PROPERTIES:
 :CUSTOM_ID: h:03dbd5af-6bae-475e-85a2-cec189f69598
 :END:
@@ -2210,7 +2271,7 @@ by code linters and prose spell checkers.
         (underline-note green-intense)))
 #+end_src
 
-**** Make line numbers use alternative styles
+*** Make line numbers use alternative styles
 :PROPERTIES:
 :CUSTOM_ID: h:b6466f51-cb58-4007-9ebe-53a27af655c7
 :END:
@@ -2252,7 +2313,7 @@ this section we show how to affect the 
~display-line-numbers-mode~.
         (bg-line-number-active bg-cyan-intense)))
 #+end_src
 
-**** Make diffs use only a foreground
+*** Make diffs use only a foreground
 :PROPERTIES:
 :CUSTOM_ID: h:b3761482-bcbf-4990-a41e-4866fb9dad15
 :END:
@@ -2268,7 +2329,7 @@ adjustments for them by overriding their palettes 
directly instead of
 just using the "common" overrides.
 
 #+begin_src emacs-lisp
-;; Diffs with only foreground colours.  Word-wise ("refined") diffs
+;; Diffs with only foreground colors.  Word-wise ("refined") diffs
 ;; have a gray background to draw attention to themselves.
 (setq modus-themes-common-palette-overrides
       '((bg-added           unspecified)
@@ -2316,7 +2377,7 @@ just using the "common" overrides.
         (fg-removed-intense yellow-intense)))
 #+end_src
 
-**** Make deuteranopia diffs red and blue instead of yellow and blue
+*** Make deuteranopia diffs red and blue instead of yellow and blue
 :PROPERTIES:
 :CUSTOM_ID: h:16389ea1-4cb6-4b18-9409-384324113541
 :END:
@@ -2367,20 +2428,110 @@ respectively.  This is achieved by overriding the 
"changed" and
         (fg-removed-intense "#ff9095")))
 #+end_src
 
-* Advanced customization
-:properties:
-:custom_id: h:f4651d55-8c07-46aa-b52b-bed1e53463bb
-:end:
+*** Make the themes look like what the maintainer uses
+:PROPERTIES:
+:CUSTOM_ID: h:aabcada6-810d-4eee-b34a-d2a9c301824d
+: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]]).
+Based on what we have learnt from the previous sections of this
+manual, here is what Protesilaos uses:
 
-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".
+#+begin_src emacs-lisp
+;; Always reload the theme for changes to take effect!
+
+(setq modus-themes-custom-auto-reload nil
+      modus-themes-to-toggle '(modus-operandi modus-vivendi)
+      modus-themes-mixed-fonts t
+      modus-themes-variable-pitch-ui nil
+      modus-themes-italic-constructs t
+      modus-themes-bold-constructs nil
+      modus-themes-org-blocks nil
+      modus-themes-completions '((t . (extrabold)))
+      modus-themes-prompts nil
+      modus-themes-headings
+      '((agenda-structure . (variable-pitch light 2.2))
+        (agenda-date . (variable-pitch regular 1.3))
+        (t . (regular 1.15))))
+
+(setq modus-themes-common-palette-overrides
+      '((cursor magenta-cooler)
+        ;; Make the fringe invisible.
+        (fringe unspecified)
+        ;; Make line numbers less intense and add a shade of cyan
+        ;; for the current line number.
+        (fg-line-number-inactive "gray50")
+        (fg-line-number-active cyan-cooler)
+        (bg-line-number-inactive unspecified)
+        (bg-line-number-active unspecified)
+        ;; Make the current line of `hl-line-mode' a fine shade of
+        ;; gray (though also see my `lin' package).
+        (bg-hl-line bg-dim)
+        ;; Make the region have a cyan-green background with no
+        ;; specific foreground (use foreground of underlying text).
+        ;; "bg-sage" refers to Salvia officinalis, else the common
+        ;; sage.
+        (bg-region bg-sage)
+        (fg-region unspecified)
+        ;; Make matching parentheses a shade of magenta.  It
+        ;; complements the region nicely.
+        (bg-paren-match bg-magenta-intense)
+        ;; Make email citations faint and neutral, reducing the
+        ;; default four colors to two; make mail headers cyan-blue.
+        (mail-cite-0 fg-dim)
+        (mail-cite-1 blue-faint)
+        (mail-cite-2 fg-dim)
+        (mail-cite-3 blue-faint)
+        (mail-part cyan-warmer)
+        (mail-recipient blue-warmer)
+        (mail-subject magenta-cooler)
+        (mail-other cyan-warmer)
+        ;; Change dates to a set of more subtle combinations.
+        (date-deadline magenta-cooler)
+        (date-scheduled magenta)
+        (date-weekday fg-main)
+        (date-event fg-dim)
+        (date-now blue-faint)
+        ;; Make tags (Org) less colorful and tables look the same as
+        ;; the default foreground.
+        (prose-done cyan-cooler)
+        (prose-tag fg-dim)
+        (prose-table fg-main)
+        ;; Make headings less colorful (though I never use deeply
+        ;; nested headings).
+        (fg-heading-2 blue-faint)
+        (fg-heading-3 magenta-faint)
+        (fg-heading-4 blue-faint)
+        (fg-heading-5 magenta-faint)
+        (fg-heading-6 blue-faint)
+        (fg-heading-7 magenta-faint)
+        (fg-heading-8 blue-faint)
+        ;; Make the active mode line a fine shade of lavender
+        ;; (purple) and tone down the gray of the inactive mode
+        ;; lines.
+        (bg-mode-line-active bg-lavender)
+        (border-mode-line-active bg-lavender)
+
+        (bg-mode-line-inactive bg-dim)
+        (border-mode-line-inactive bg-inactive)
+        ;; Make the prompts a shade of magenta, to fit in nicely with
+        ;; the overall blue-cyan-purple style of the other overrides.
+        ;; Add a nuanced background as well.
+        (bg-prompt bg-magenta-nuanced)
+        (fg-prompt magenta-cooler)
+        ;; Tweak some more constructs for stylistic constistency.
+        (name blue-warmer)
+        (identifier magenta-faint)
+        (keybind magenta-cooler)
+        (accent-0 magenta-cooler)
+        (accent-1 cyan-cooler)
+        (accent-2 blue-warmer)
+        (accent-3 red-cooler)))
+
+;; Make the active mode line have a pseudo 3D effect (this assumes
+;; you are using the default mode line and not an extra package).
+(custom-set-faces
+ '(mode-line ((t :box (:style released-button)))))
+#+end_src
 
 ** More accurate colors in terminal emulators
 :PROPERTIES:
@@ -2584,8 +2735,9 @@ for palette overrides.  Else it reads only the default 
palette.
 
 [[#h:34c7a691-19bb-4037-8d2f-67a07edab150][Option for palette overrides]].
 
-With optional =THEME= as a symbol among ~modus-themes-items~, use the
-palette of that item.  Else use the current Modus theme.
+With optional =THEME= as a symbol among ~modus-themes-items~ (alias
+~modus-themes-collection~), use the palette of that item.  Else use
+the current Modus theme.
 
 If =COLOR= is not present in the palette, this function returns the
 ~unspecified~ symbol, which is safe when used as a face attribute's
@@ -3479,6 +3631,90 @@ In this document, we cover 
~modus-themes-after-load-theme-hook~ though
 the user can replace it with ~after-enable-theme-hook~ should they
 need to (provided they understand the implications).
 
+** Use more spacious margins or padding in Emacs frames
+:PROPERTIES:
+:CUSTOM_ID: h:43bcb5d0-e25f-470f-828c-662cee9e21f1
+:END:
+
+By default, Emacs frames try to maximize the number of characters that
+fit in the current visible portion of the buffer.  Users may prefer to
+have some extra padding instead.  This can make Emacs frames look more
+pleasant, but also make it easier to identify the currently active
+window.
+
+The way to implement such padding is two-fold:
+
+1. In the =early-init.el= file instruct Emacs to use a higher value
+   for the ~internal-border-width~ of all frames, as well as for the
+   ~right-divider-width~.  The former concerns the outer boundaries of
+   Emacs frames, while the latter pertains to dividers between Emacs
+   windows.
+
+2. Make the relevant faces invisible by changing the value of their
+   relevant attributes to that of the current theme's main background.
+
+The parameters of Emacs frames are specified in the variables
+~initial-frame-alist~ and ~default-frame-alist~.  The "initial frame"
+refers to the first frame that appears on Emacs startup.  The
+"default" refers to the fallback values that apply to all other frames
+that Emacs creates (unless those are explicitly overridden by a
+bespoke ~make-frame~ call).
+
+In detail, first we use the same values for the two frame alist variables:
+
+#+begin_src emacs-lisp
+;; This must go in the early-init.el so that it applies to the initial
+;; frame.
+(dolist (var '(default-frame-alist initial-frame-alist))
+  (add-to-list var '(right-divider-width . 20))
+  (add-to-list var '(internal-border-width . 20)))
+#+end_src
+
+What the ~dolist~ does is to call ~add-to-list~ for the two variables
+we specify there.  This economizes on typing.
+
+Then we define a function that makes the relevant faces invisible.
+The reason we do this with a function is so we can hook it to the
+"post load" phase of a theme, thus applying the new background value
+(otherwise you keep the old background, which likely means that the
+faces will no longer be invisible).
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-invisible-dividers ()
+  "Make window dividers invisible.
+Add this to the `modus-themes-post-load-hook'."
+  (let ((bg (face-background 'default)))
+    (custom-set-faces
+     `(fringe ((t :background ,bg :foreground ,bg)))
+     `(window-divider ((t :background ,bg :foreground ,bg)))
+     `(window-divider-first-pixel ((t :background ,bg :foreground ,bg)))
+     `(window-divider-last-pixel ((t :background ,bg :foreground ,bg))))))
+
+(add-hook 'modus-themes-post-load-hook #'my-modus-themes-invisible-dividers)
+#+end_src
+
+The above will work only for themes that belong to the Modus family.
+For users of Emacs version 29 or higher, there exists a theme-agnostic
+hook that takes a function with one argument---that of the theme---and
+calls in the the "post enable" phase of theme loading.  Here is the
+above snippet, with the necessary tweaks:
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-invisible-dividers (_theme)
+  "Make window dividers for THEME invisible."
+  (let ((bg (face-background 'default)))
+    (custom-set-faces
+     `(fringe ((t :background ,bg :foreground ,bg)))
+     `(window-divider ((t :background ,bg :foreground ,bg)))
+     `(window-divider-first-pixel ((t :background ,bg :foreground ,bg)))
+     `(window-divider-last-pixel ((t :background ,bg :foreground ,bg))))))
+
+(add-hook 'enable-theme-functions #'my-modus-themes-invisible-dividers)
+#+end_src
+
+Users of older versions of Emacs can read the entry herein about
+defining their own theme-agnostic hook 
([[#h:86f6906b-f090-46cc-9816-1fe8aeb38776][A theme-agnostic hook for theme 
loading]]).
+
 ** Custom hl-todo colors
 :PROPERTIES:
 :CUSTOM_ID: h:2ef83a21-2f0a-441e-9634-473feb940743
@@ -3636,7 +3872,7 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + csv-mode
 + ctrlf
 + custom (what you get with {{{kbd(M-x customize)}}})
-- dashboard
++ dashboard
 + deadgrep
 + deft
 + devdocs
@@ -3651,6 +3887,7 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + dired-narrow
 + dired-subtree
 + diredfl
++ disk-usage
 + display-fill-column-indicator-mode
 + doom-modeline
 + ediff
@@ -3715,6 +3952,8 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + ivy*
 + ivy-posframe
 + jira (org-jira)
++ jit-spell
++ jinx
 + journalctl-mode
 + js2-mode
 + julia
@@ -3733,7 +3972,6 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + minimap
 + mode-line
 + mood-line
-+ moody
 + mpdel
 + mu4e
 + multiple-cursors
@@ -3780,6 +4018,7 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + rg (rg.el)
 + ripgrep
 + rmail
++ rst-mode
 + ruler-mode
 + sesman
 + shell-script-mode
@@ -3969,9 +4208,9 @@ length elsewhere in this manual:
      ;; Doom should not be implementing such hacks because themes
      ;; cannot support them:
      ;; 
<https://protesilaos.com/codelog/2022-08-04-doom-git-gutter-modus-themes/>.
-     `(git-gutter-fr:added ((,c :foreground ,bg-added-intense)))
-     `(git-gutter-fr:deleted ((,c :foreground ,bg-removed-intense)))
-     `(git-gutter-fr:modified ((,c :foreground ,bg-changed-intense))))))
+     `(git-gutter-fr:added ((,c :foreground ,bg-added-fringe)))
+     `(git-gutter-fr:deleted ((,c :foreground ,bg-removed-fringe)))
+     `(git-gutter-fr:modified ((,c :foreground ,bg-changed-fringe))))))
 
 (add-hook 'modus-themes-after-load-theme-hook #'my-modus-themes-custom-faces)
 #+end_src
@@ -4941,9 +5180,10 @@ 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
-yellow+blue variants ([[#h:f0f3dbcb-602d-40cf-b918-8f929c441baf][Overview]]).
+of the needs of users with red-green/blue-yellow color deficiency
+(deuteranopia and tritanopia) by avoiding red+green color coding
+paradigms and/or by providing yellow+blue variants for deuteranopia
+and red+cyan for tritanopia 
([[#h:f0f3dbcb-602d-40cf-b918-8f929c441baf][Overview]]).
 
 The latter criterion is the "je ne sais quoi" of the artistic aspect of
 the themes, which is partially fleshed out in this manual.
@@ -5099,13 +5339,14 @@ The Modus themes are a collective effort.  Every bit of 
work matters.
 + Contributions to code or documentation :: Aleksei Gusev, 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č, Sergey Nichiporchik, Stephen Gildea,
-  Shreyas Ragavan, Stefan Kangas, Utkarsh Singh, Vincent Murphy,
-  Xinglu Chen, Yuanchen Xie, okamsn.
+  Daniel Mendler, David Edmondson, Eli Zaretskii, Fritz Grabo, Gautier
+  Ponsinet, Illia Ostapyshyn, Kévin Le Gouguec, Koen van Greevenbroek,
+  Kostadin Ninev, Madhavan Krishnan, Manuel Giraud, Markus Beppler,
+  Matthew Stevenson, Mauro Aranda, Nacho Barrientos, Nicolas De
+  Jaeghere, Paul David, Philip Kaludercic, Pierre Téchoueyres, Rudolf
+  Adamkovič, Sergey Nichiporchik, Shreyas Ragavan, Stefan Kangas,
+  Stephen Gildea, Steve Downey, Tomasz Hołubowicz, Utkarsh Singh,
+  Vincent Murphy, Xinglu Chen, Yuanchen Xie, okamsn.
 
 + Ideas and user feedback :: Aaron Jensen, Adam Porter, Adam Spiers,
   Adrian Manea, Aleksei Pirogov, Alex Griffin, Alex Koen, Alex
@@ -5127,19 +5368,20 @@ The Modus themes are a collective effort.  Every bit of 
work matters.
   Bestley, Mark Burton, Mark Simpson, Marko Kocic, Markus Beppler,
   Matt Armstrong, Matthias Fuchs, Mattias Engdegård, 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, Russell Sim, Ryan Phillips, Rytis Paškauskas,
-  Rudolf Adamkovič, Sam Kleinman, Samuel Culpepper, Saša Janiška,
-  Shreyas Ragavan, Simon Pugnet, Tassilo Horn, Thanos Apollo, Thibaut
-  Verron, Thomas Heartman, Togan Muftuoglu, Tony Zorman, Trey Merkley,
-  Tomasz Hołubowicz, Toon Claes, Uri Sharf, Utkarsh Singh, Vincent
-  Foley, Zoltan Kiraly.  As well as users: Ben, CsBigDataHub1, Emacs
-  Contrib, Eugene, Fourchaux, Fredrik, Moesasji, Nick, Summer Emacs,
-  TheBlob42, TitusMu, Trey, bepolymathe, bit9tream, bangedorrunt,
-  derek-upham, doolio, fleimgruber, gitrj95, iSeeU, jixiuf, okamsn,
-  pRot0ta1p, soaringbird, tumashu, wakamenod.
+  Murilo Pereira, Nicky van Foreest, Nicolas De Jaeghere, Nicolas
+  Semrau, Oliver Epper, Pablo Stafforini, Paul Poloskov, Pengji Zhang,
+  Pete Kazmier, Peter Wu, Philip Kaludercic, Pierre Téchoueyres,
+  Przemysław Kryger, Robert Hepple, Roman Rudakov, Russell Sim, Ryan
+  Phillips, Rytis Paškauskas, Rudolf Adamkovič, Sam Kleinman, Samuel
+  Culpepper, Saša Janiška, Shreyas Ragavan, Simon Pugnet, Steve
+  Downey, Tassilo Horn, Thanos Apollo, Thibaut Verron, Thomas
+  Heartman, Togan Muftuoglu, Tony Zorman, Trey Merkley, Tomasz
+  Hołubowicz, Toon Claes, Uri Sharf, Utkarsh Singh, Vincent Foley,
+  Zoltan Kiraly.  As well as users: Ben, CsBigDataHub1, Emacs Contrib,
+  Eugene, Fourchaux, Fredrik, Moesasji, Nick, Summer Emacs, TheBlob42,
+  TitusMu, Trey, bepolymathe, bit9tream, bangedorrunt, derek-upham,
+  doolio, fleimgruber, gitrj95, iSeeU, jixiuf, okamsn, pRot0ta1p,
+  soaringbird, tumashu, wakamenod.
 
 + Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii,
   Glenn Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index d257bdcbf51..e9ec9e2caab 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -131,14 +131,26 @@ been restored with a slightly revised role contingent on 
a few
 assumptions explained in its doc string.  For clarity, it has been
 renamed 'erc-ensure-target-buffer-on-privmsg'.
 
+** Improved interplay between buffer truncation and message logging.
+While most of these improvements are subtle, some affect everyday use.
+For example, users of the 'truncate' module may notice that truncation
+now happens between messages rather than arbitrary lines.  And those
+with the default 'erc-insert-timestamp-left-and-right' for their
+'erc-insert-timestamp-function' will see date stamps reprinted after
+every "/CLEAR" but omitted from any logs.  One notable casualty of
+these changes has been the deprecation of the ancient option
+'erc-truncate-buffer-on-save'.  Users of the 'log' module can achieve
+the same effect by issuing a "/CLEAR" at the prompt.
+
 ** Miscellaneous UX changes.
 Some minor quality-of-life niceties have finally made their way to
 ERC.  For example, the function 'erc-echo-timestamp' is now
 interactive and can be invoked on any message to view its timestamp in
 the echo area.  The command 'erc-button-previous' now moves to the
-beginning instead of the end of buttons.  And the 'irccontrols' module
-now supports additional colors and special handling for "spoilers"
-(hidden text).
+beginning instead of the end of buttons.  A new command, 'erc-news',
+can now be invoked to visit this very file.  And the 'irccontrols'
+module now supports additional colors and special handling for
+"spoilers" (hidden text).
 
 ** Changes in the library API.
 
@@ -215,12 +227,12 @@ changes are encouraged to voice their concerns on the bug 
list.
 *** Miscellaneous changes
 Two helper macros from GNU ELPA's Compat library are now available to
 third-party modules as 'erc-compat-call' and 'erc-compat-function'.
-In the area of buttons, 'Info-goto-node' has been supplanted by plain
-old 'info' in 'erc-button-alist', and the bracketed "<URL:...>"
-pattern entry has been removed because it was more or less redundant.
-And the "TAB" key is now bound to a new command, 'erc-tab', that only
-calls 'completion-at-point' when point is in the input area and
-module-specific commands, like 'erc-button-next', otherwise.
+In 'erc-button-alist', 'Info-goto-node' has been supplanted by plain
+old 'info', and the "<URL:...>" entry has been removed because it was
+more or less redundant.  In all ERC buffers, the "<TAB>" key is now
+bound to a new command, 'erc-tab', that calls 'completion-at-point'
+inside the input area and otherwise dispatches module-specific
+commands, like 'erc-button-next'.
 
 
 * Changes in ERC 5.5
diff --git a/etc/NEWS b/etc/NEWS
index 314ace50dbf..c19e1658a01 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -425,15 +425,16 @@ A major mode based on the tree-sitter library for editing 
Elixir
 files.
 
 ---
-** The highly accessible Modus themes collection has six items.
+** The highly accessible Modus themes collection has eight items.
 The 'modus-operandi' and 'modus-vivendi' are the main themes that have
 been part of Emacs since version 28.  The former is light, the latter
 dark.  In addition to these, we now have 'modus-operandi-tinted' and
 'modus-vivendi-tinted' for easier legibility, as well as
-'modus-operandi-deuteranopia' and 'modus-vivendi-deuteranopia' to
-cover the needs of users with red-green color deficiency.  The Info
-manual "(modus-themes) Top" describes the details and showcases all
-their customization options.
+'modus-operandi-deuteranopia', 'modus-vivendi-deuteranopia',
+'modus-operandi-tritanopia', and 'modus-vivendi-tritanopia' to cover
+the needs of users with red-green or blue-yellow color deficiency.
+The Info manual "(modus-themes) Top" describes the details and
+showcases all their customization options.
 
 
 * Incompatible Lisp Changes in Emacs 30.1
diff --git a/etc/themes/modus-operandi-deuteranopia-theme.el 
b/etc/themes/modus-operandi-deuteranopia-theme.el
index fff62e3da9f..5817d8f674c 100644
--- a/etc/themes/modus-operandi-deuteranopia-theme.el
+++ b/etc/themes/modus-operandi-deuteranopia-theme.el
@@ -1,4 +1,4 @@
-;;; modus-operandi-deuteranopia-theme.el --- Elegant, highly legible and 
customizable light theme -*- lexical-binding:t -*-
+;;; modus-operandi-deuteranopia-theme.el --- Deuteranopia-optimized theme with 
a white background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -44,7 +44,7 @@
     (require 'modus-themes))
 
   (deftheme modus-operandi-deuteranopia
-    "Elegant, highly legible and customizable light theme.
+    "Deuteranopia-optimized theme with a white background.
 This variant is optimized for users with red-green color
 deficiency (deuteranopia).  It conforms with the highest
 legibility standard for color contrast between background and
@@ -77,9 +77,9 @@ standard).")
       (green-cooler    "#00663f")
       (green-faint     "#2a5045")
       (green-intense   "#008900")
-      (yellow          "#7b5000")
-      (yellow-warmer   "#884900")
-      (yellow-cooler   "#7a4f2f")
+      (yellow          "#695500")
+      (yellow-warmer   "#973300")
+      (yellow-cooler   "#77492f")
       (yellow-faint    "#624416")
       (yellow-intense  "#808000")
       (blue            "#0031a9")
@@ -139,10 +139,10 @@ standard).")
 
 ;;; Graphs
 
-      (bg-graph-red-0     "#b0b029")
+      (bg-graph-red-0     "#d0b029")
       (bg-graph-red-1     "#e0cab4")
-      (bg-graph-green-0   "#90b7c0")
-      (bg-graph-green-1   "#a3dfe5")
+      (bg-graph-green-0   "#8ad080")
+      (bg-graph-green-1   "#afdfa5")
       (bg-graph-yellow-0  "#ffcf00")
       (bg-graph-yellow-1  "#f9ff00")
       (bg-graph-blue-0    "#7f9fff")
@@ -223,17 +223,24 @@ standard).")
       (identifier yellow-faint)
 
       (err yellow-warmer)
-      (warning yellow-cooler)
+      (warning yellow)
       (info blue)
 
       (underline-err yellow-intense)
       (underline-warning magenta-faint)
       (underline-note cyan)
 
+      (bg-prominent-err bg-yellow-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-magenta-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
+
 ;;;; Code mappings
 
       (builtin magenta-warmer)
-      (comment yellow)
+      (comment yellow-cooler)
       (constant blue-cooler)
       (docstring green-faint)
       (docmarkup magenta-faint)
@@ -278,6 +285,7 @@ standard).")
       (date-event fg-alt)
       (date-holiday yellow-warmer)
       (date-now blue-faint)
+      (date-range fg-alt)
       (date-scheduled yellow-cooler)
       (date-weekday cyan)
       (date-weekend yellow-faint)
@@ -307,13 +315,22 @@ standard).")
 
       (mail-cite-0 blue-warmer)
       (mail-cite-1 yellow)
-      (mail-cite-2 blue-cooler)
+      (mail-cite-2 cyan-faint)
       (mail-cite-3 yellow-faint)
       (mail-part blue)
       (mail-recipient blue)
-      (mail-subject yellow-warmer)
+      (mail-subject yellow-cooler)
       (mail-other cyan-faint)
 
+;;;; Mark mappings
+
+      (bg-mark-delete bg-yellow-subtle)
+      (fg-mark-delete yellow)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-magenta-subtle)
+      (fg-mark-other magenta)
+
 ;;;; Prompt mappings
 
       (fg-prompt blue)
@@ -344,6 +361,12 @@ standard).")
       (rainbow-7 yellow-faint)
       (rainbow-8 cyan)
 
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+      (bg-space-err bg-yellow-intense)
+
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
diff --git a/etc/themes/modus-operandi-theme.el 
b/etc/themes/modus-operandi-theme.el
index 0705f926de6..9a69e3290b7 100644
--- a/etc/themes/modus-operandi-theme.el
+++ b/etc/themes/modus-operandi-theme.el
@@ -1,4 +1,4 @@
-;;; modus-operandi-theme.el --- Elegant, highly legible and customizable light 
theme -*- lexical-binding:t -*-
+;;; modus-operandi-theme.el --- Elegant, highly legible theme with a white 
background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -44,7 +44,7 @@
     (require 'modus-themes))
 
   (deftheme modus-operandi
-    "Elegant, highly legible and customizable light theme.
+    "Elegant, highly legible theme with a white background.
 Conforms with the highest legibility standard for color contrast
 between background and foreground in any given piece of text,
 which corresponds to a minimum contrast in relative luminance of
@@ -139,11 +139,11 @@ which corresponds to a minimum contrast in relative 
luminance of
 
       (bg-graph-red-0     "#ef7969")
       (bg-graph-red-1     "#ffaab4")
-      (bg-graph-green-0   "#4faa09")
-      (bg-graph-green-1   "#8fef00")
+      (bg-graph-green-0   "#2fe029")
+      (bg-graph-green-1   "#75ef30")
       (bg-graph-yellow-0  "#ffcf00")
       (bg-graph-yellow-1  "#f9ff00")
-      (bg-graph-blue-0    "#7090ff")
+      (bg-graph-blue-0    "#7f90ff")
       (bg-graph-blue-1    "#9fc6ff")
       (bg-graph-magenta-0 "#e07fff")
       (bg-graph-magenta-1 "#fad0ff")
@@ -228,6 +228,13 @@ which corresponds to a minimum contrast in relative 
luminance of
       (underline-warning yellow-intense)
       (underline-note cyan-intense)
 
+      (bg-prominent-err bg-red-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-yellow-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
+
 ;;;; Code mappings
 
       (builtin magenta-warmer)
@@ -274,8 +281,9 @@ which corresponds to a minimum contrast in relative 
luminance of
       (date-common cyan)
       (date-deadline red)
       (date-event fg-alt)
-      (date-holiday magenta)
+      (date-holiday red-cooler)
       (date-now fg-main)
+      (date-range fg-alt)
       (date-scheduled yellow-warmer)
       (date-weekday cyan)
       (date-weekend red-faint)
@@ -312,6 +320,15 @@ which corresponds to a minimum contrast in relative 
luminance of
       (mail-subject magenta-warmer)
       (mail-other magenta-faint)
 
+;;;; Mark mappings
+
+      (bg-mark-delete bg-red-subtle)
+      (fg-mark-delete red)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-yellow-subtle)
+      (fg-mark-other yellow)
+
 ;;;; Prompt mappings
 
       (fg-prompt cyan-cooler)
@@ -342,6 +359,12 @@ which corresponds to a minimum contrast in relative 
luminance of
       (rainbow-7 blue-warmer)
       (rainbow-8 magenta-warmer)
 
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+      (bg-space-err bg-red-intense)
+
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
diff --git a/etc/themes/modus-operandi-tinted-theme.el 
b/etc/themes/modus-operandi-tinted-theme.el
index 4bb820cf686..341a7d29e84 100644
--- a/etc/themes/modus-operandi-tinted-theme.el
+++ b/etc/themes/modus-operandi-tinted-theme.el
@@ -1,4 +1,4 @@
-;;; modus-operandi-tinted-theme.el --- Elegant, highly legible and 
customizable light theme -*- lexical-binding:t -*-
+;;; modus-operandi-tinted-theme.el --- Elegant, highly legible theme with a 
light ochre background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -43,7 +43,7 @@
     (require 'modus-themes))
 
   (deftheme modus-operandi-tinted
-    "Elegant, highly legible and customizable light theme.
+    "Elegant, highly legible theme with a light ochre background.
 Conforms with the highest legibility standard for color contrast
 between background and foreground in any given piece of text,
 which corresponds to a minimum contrast in relative luminance of
@@ -138,11 +138,11 @@ which corresponds to a minimum contrast in relative 
luminance of
 
       (bg-graph-red-0     "#ef7969")
       (bg-graph-red-1     "#ffaab4")
-      (bg-graph-green-0   "#4faa09")
-      (bg-graph-green-1   "#8fef00")
+      (bg-graph-green-0   "#2fe029")
+      (bg-graph-green-1   "#75ef30")
       (bg-graph-yellow-0  "#ffcf00")
       (bg-graph-yellow-1  "#f9ff00")
-      (bg-graph-blue-0    "#7090ff")
+      (bg-graph-blue-0    "#7f90ff")
       (bg-graph-blue-1    "#9fc6ff")
       (bg-graph-magenta-0 "#e07fff")
       (bg-graph-magenta-1 "#fad0ff")
@@ -227,6 +227,13 @@ which corresponds to a minimum contrast in relative 
luminance of
       (underline-warning yellow-intense)
       (underline-note cyan-intense)
 
+      (bg-prominent-err bg-red-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-yellow-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
+
 ;;;; Code mappings
 
       (builtin magenta-warmer)
@@ -273,8 +280,9 @@ which corresponds to a minimum contrast in relative 
luminance of
       (date-common cyan)
       (date-deadline red)
       (date-event fg-alt)
-      (date-holiday magenta)
+      (date-holiday red-cooler)
       (date-now fg-main)
+      (date-range fg-alt)
       (date-scheduled yellow-warmer)
       (date-weekday cyan)
       (date-weekend red-faint)
@@ -311,6 +319,15 @@ which corresponds to a minimum contrast in relative 
luminance of
       (mail-subject magenta-warmer)
       (mail-other magenta-faint)
 
+;;;; Mark mappings
+
+      (bg-mark-delete bg-red-subtle)
+      (fg-mark-delete red)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-yellow-subtle)
+      (fg-mark-other yellow)
+
 ;;;; Prompt mappings
 
       (fg-prompt cyan-cooler)
@@ -341,6 +358,12 @@ which corresponds to a minimum contrast in relative 
luminance of
       (rainbow-7 blue-warmer)
       (rainbow-8 magenta-warmer)
 
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+      (bg-space-err bg-red-intense)
+
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
diff --git a/etc/themes/modus-operandi-theme.el 
b/etc/themes/modus-operandi-tritanopia-theme.el
similarity index 62%
copy from etc/themes/modus-operandi-theme.el
copy to etc/themes/modus-operandi-tritanopia-theme.el
index 0705f926de6..5d143fa7514 100644
--- a/etc/themes/modus-operandi-theme.el
+++ b/etc/themes/modus-operandi-tritanopia-theme.el
@@ -1,4 +1,4 @@
-;;; modus-operandi-theme.el --- Elegant, highly legible and customizable light 
theme -*- lexical-binding:t -*-
+;;; modus-operandi-tritanopia-theme.el --- Tritanopia-optimized theme with a 
white background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -43,14 +43,16 @@
                (require-theme 'modus-themes t))
     (require 'modus-themes))
 
-  (deftheme modus-operandi
-    "Elegant, highly legible and customizable light theme.
-Conforms with the highest legibility standard for color contrast
-between background and foreground in any given piece of text,
-which corresponds to a minimum contrast in relative luminance of
-7:1 (WCAG AAA standard).")
+  (deftheme modus-operandi-tritanopia
+    "Tritanopia-optimized theme with a white background.
+This variant is optimized for users with blue-yellow color
+deficiency (tritanopia).  It conforms with the highest
+legibility standard for color contrast between background and
+foreground in any given piece of text, which corresponds to a
+minimum contrast in relative luminance of 7:1 (WCAG AAA
+standard).")
 
-  (defconst modus-operandi-palette
+  (defconst modus-operandi-tritanopia-palette
     '(
 ;;; Basic values
 
@@ -66,18 +68,18 @@ which corresponds to a minimum contrast in relative 
luminance of
 ;;; Common accent foregrounds
 
       (red             "#a60000")
-      (red-warmer      "#972500")
+      (red-warmer      "#b21100")
       (red-cooler      "#a0132f")
-      (red-faint       "#7f0000")
+      (red-faint       "#702000")
       (red-intense     "#d00000")
       (green           "#006800")
       (green-warmer    "#316500")
       (green-cooler    "#00663f")
       (green-faint     "#2a5045")
       (green-intense   "#008900")
-      (yellow          "#6f5500")
-      (yellow-warmer   "#884900")
-      (yellow-cooler   "#7a4f2f")
+      (yellow          "#695500")
+      (yellow-warmer   "#973300")
+      (yellow-cooler   "#77492f")
       (yellow-faint    "#624416")
       (yellow-intense  "#808000")
       (blue            "#0031a9")
@@ -89,11 +91,11 @@ which corresponds to a minimum contrast in relative 
luminance of
       (magenta-warmer  "#8f0075")
       (magenta-cooler  "#531ab6")
       (magenta-faint   "#7c318f")
-      (magenta-intense "#dd22dd")
+      (magenta-intense "#cd22bd")
       (cyan            "#005e8b")
       (cyan-warmer     "#3f578f")
       (cyan-cooler     "#005f5f")
-      (cyan-faint      "#005077")
+      (cyan-faint      "#004f5f")
       (cyan-intense    "#008899")
 
 ;;; Uncommon accent foregrounds
@@ -139,40 +141,40 @@ which corresponds to a minimum contrast in relative 
luminance of
 
       (bg-graph-red-0     "#ef7969")
       (bg-graph-red-1     "#ffaab4")
-      (bg-graph-green-0   "#4faa09")
-      (bg-graph-green-1   "#8fef00")
-      (bg-graph-yellow-0  "#ffcf00")
-      (bg-graph-yellow-1  "#f9ff00")
-      (bg-graph-blue-0    "#7090ff")
-      (bg-graph-blue-1    "#9fc6ff")
-      (bg-graph-magenta-0 "#e07fff")
-      (bg-graph-magenta-1 "#fad0ff")
-      (bg-graph-cyan-0    "#70d3f0")
+      (bg-graph-green-0   "#70c3b0")
+      (bg-graph-green-1   "#a3dfe5")
+      (bg-graph-yellow-0  "#d99f9f")
+      (bg-graph-yellow-1  "#ffb58f")
+      (bg-graph-blue-0    "#80a0df")
+      (bg-graph-blue-1    "#9fcaff")
+      (bg-graph-magenta-0 "#efafcf")
+      (bg-graph-magenta-1 "#ffdaef")
+      (bg-graph-cyan-0    "#7fd3ed")
       (bg-graph-cyan-1    "#afefff")
 
 ;;; Special purpose
 
-      (bg-completion       "#c0deff")
-      (bg-hover            "#94d4ff")
-      (bg-hover-secondary  "#f5d0a0")
-      (bg-hl-line          "#dae5ec")
+      (bg-completion       "#afdfef")
+      (bg-hover            "#ffafbc")
+      (bg-hover-secondary  "#9fdfff")
+      (bg-hl-line          "#dfeaec")
       (bg-region           "#bdbdbd")
       (fg-region           "#000000")
 
-      (bg-char-0 "#7feaff")
-      (bg-char-1 "#ffaaff")
-      (bg-char-2 "#dff000")
+      (bg-char-0 "#ff8a5f")
+      (bg-char-1 "#bf7aff")
+      (bg-char-2 "#7fe0e0")
 
-      (bg-mode-line-active        "#c8c8c8")
-      (fg-mode-line-active        "#000000")
-      (border-mode-line-active    "#5a5a5a")
+      (bg-mode-line-active        "#afe0f2")
+      (fg-mode-line-active        "#0f0f0f")
+      (border-mode-line-active    "#2f4f44")
       (bg-mode-line-inactive      "#e6e6e6")
       (fg-mode-line-inactive      "#585858")
       (border-mode-line-inactive  "#a3a3a3")
 
-      (modeline-err     "#7f0000")
-      (modeline-warning "#5f0070")
-      (modeline-info    "#002580")
+      (modeline-err     "#8f0000")
+      (modeline-warning "#6f306f")
+      (modeline-info    "#00445f")
 
       (bg-tab-bar      "#dfdfdf")
       (bg-tab-current  "#ffffff")
@@ -180,19 +182,19 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;; Diffs
 
-      (bg-added           "#c1f2d1")
-      (bg-added-faint     "#d8f8e1")
-      (bg-added-refine    "#aee5be")
-      (bg-added-fringe    "#6cc06c")
-      (fg-added           "#005000")
-      (fg-added-intense   "#006700")
+      (bg-added           "#b5e7ff")
+      (bg-added-faint     "#c6f6ff")
+      (bg-added-refine    "#9adcef")
+      (bg-added-fringe    "#1782cc")
+      (fg-added           "#005079")
+      (fg-added-intense   "#0043aa")
 
-      (bg-changed         "#ffdfa9")
-      (bg-changed-faint   "#ffefbf")
-      (bg-changed-refine  "#fac090")
-      (bg-changed-fringe  "#d7c20a")
-      (fg-changed         "#553d00")
-      (fg-changed-intense "#655000")
+      (bg-changed         "#eecfdf")
+      (bg-changed-faint   "#f0dde5")
+      (bg-changed-refine  "#e0b0d0")
+      (bg-changed-fringe  "#9f6ab0")
+      (fg-changed         "#6f1343")
+      (fg-changed-intense "#7f0f9f")
 
       (bg-removed         "#ffd8d5")
       (bg-removed-faint   "#ffe9e9")
@@ -214,42 +216,49 @@ which corresponds to a minimum contrast in relative 
luminance of
 ;;;; General mappings
 
       (fringe bg-dim)
-      (cursor fg-main)
+      (cursor red-intense)
 
-      (keybind blue-cooler)
-      (name magenta)
-      (identifier yellow-cooler)
+      (keybind red)
+      (name red-cooler)
+      (identifier red-faint)
 
-      (err red)
-      (warning yellow-warmer)
-      (info cyan-cooler)
+      (err red-warmer)
+      (warning magenta)
+      (info cyan)
 
       (underline-err red-intense)
-      (underline-warning yellow-intense)
+      (underline-warning magenta-intense)
       (underline-note cyan-intense)
 
+      (bg-prominent-err bg-red-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-magenta-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
+
 ;;;; Code mappings
 
-      (builtin magenta-warmer)
-      (comment fg-dim)
-      (constant blue-cooler)
-      (docstring green-faint)
+      (builtin magenta)
+      (comment red-faint)
+      (constant green-cooler)
+      (docstring fg-alt)
       (docmarkup magenta-faint)
-      (fnname magenta)
-      (keyword magenta-cooler)
-      (preprocessor red-cooler)
-      (string blue-warmer)
-      (type cyan-cooler)
-      (variable cyan)
-      (rx-construct green-cooler)
+      (fnname cyan-warmer)
+      (keyword red-cooler)
+      (preprocessor red-warmer)
+      (string cyan)
+      (type blue-warmer)
+      (variable cyan-cooler)
+      (rx-construct red)
       (rx-backslash magenta)
 
 ;;;; Accent mappings
 
-      (accent-0 blue)
-      (accent-1 magenta-warmer)
-      (accent-2 cyan)
-      (accent-3 red)
+      (accent-0 cyan)
+      (accent-1 red-warmer)
+      (accent-2 cyan-cooler)
+      (accent-3 magenta)
 
 ;;;; Button mappings
 
@@ -260,10 +269,10 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Completion mappings
 
-      (fg-completion-match-0 blue)
-      (fg-completion-match-1 magenta-warmer)
-      (fg-completion-match-2 cyan)
-      (fg-completion-match-3 red)
+      (fg-completion-match-0 cyan)
+      (fg-completion-match-1 red-warmer)
+      (fg-completion-match-2 magenta)
+      (fg-completion-match-3 cyan-cooler)
       (bg-completion-match-0 unspecified)
       (bg-completion-match-1 unspecified)
       (bg-completion-match-2 unspecified)
@@ -271,12 +280,13 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Date mappings
 
-      (date-common cyan)
+      (date-common cyan-cooler)
       (date-deadline red)
       (date-event fg-alt)
-      (date-holiday magenta)
+      (date-holiday red)
       (date-now fg-main)
-      (date-scheduled yellow-warmer)
+      (date-range fg-alt)
+      (date-scheduled magenta)
       (date-weekday cyan)
       (date-weekend red-faint)
 
@@ -289,13 +299,13 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Link mappings
 
-      (fg-link blue-warmer)
+      (fg-link cyan)
       (bg-link unspecified)
-      (underline-link blue-warmer)
+      (underline-link cyan)
 
-      (fg-link-symbolic cyan)
+      (fg-link-symbolic cyan-cooler)
       (bg-link-symbolic unspecified)
-      (underline-link-symbolic cyan)
+      (underline-link-symbolic cyan-cooler)
 
       (fg-link-visited magenta)
       (bg-link-visited unspecified)
@@ -303,14 +313,23 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Mail mappings
 
-      (mail-cite-0 blue-faint)
-      (mail-cite-1 yellow-warmer)
-      (mail-cite-2 cyan-cooler)
-      (mail-cite-3 red-cooler)
-      (mail-part cyan)
-      (mail-recipient magenta-cooler)
-      (mail-subject magenta-warmer)
-      (mail-other magenta-faint)
+      (mail-cite-0 cyan-faint)
+      (mail-cite-1 red-faint)
+      (mail-cite-2 magenta-warmer)
+      (mail-cite-3 cyan-warmer)
+      (mail-part cyan-cooler)
+      (mail-recipient cyan)
+      (mail-subject red-cooler)
+      (mail-other cyan)
+
+;;;; Mark mappings
+
+      (bg-mark-delete bg-red-subtle)
+      (fg-mark-delete red)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-magenta-subtle)
+      (fg-mark-other magenta)
 
 ;;;; Prompt mappings
 
@@ -320,37 +339,43 @@ which corresponds to a minimum contrast in relative 
luminance of
 ;;;; Prose mappings
 
       (prose-block fg-dim)
-      (prose-code green-cooler)
-      (prose-done green)
-      (prose-macro magenta-cooler)
+      (prose-code cyan)
+      (prose-done cyan)
+      (prose-macro red-warmer)
       (prose-metadata fg-dim)
       (prose-metadata-value fg-alt)
       (prose-table fg-alt)
-      (prose-tag magenta-faint)
+      (prose-tag fg-alt)
       (prose-todo red)
       (prose-verbatim magenta-warmer)
 
 ;;;; Rainbow mappings
 
-      (rainbow-0 fg-main)
-      (rainbow-1 magenta-intense)
-      (rainbow-2 cyan-intense)
-      (rainbow-3 red-warmer)
-      (rainbow-4 yellow-intense)
-      (rainbow-5 magenta-cooler)
-      (rainbow-6 green-intense)
-      (rainbow-7 blue-warmer)
-      (rainbow-8 magenta-warmer)
+      (rainbow-0 cyan)
+      (rainbow-1 red)
+      (rainbow-2 cyan-warmer)
+      (rainbow-3 red-cooler)
+      (rainbow-4 cyan-cooler)
+      (rainbow-5 magenta)
+      (rainbow-6 cyan-faint)
+      (rainbow-7 magenta-faint)
+      (rainbow-8 red-faint)
+
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+      (bg-space-err bg-red-intense)
 
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
       (fg-heading-1 fg-main)
-      (fg-heading-2 yellow-faint)
-      (fg-heading-3 fg-alt)
+      (fg-heading-2 red-faint)
+      (fg-heading-3 cyan-faint)
       (fg-heading-4 magenta)
       (fg-heading-5 green-faint)
-      (fg-heading-6 red-faint)
+      (fg-heading-6 magenta-faint)
       (fg-heading-7 cyan-warmer)
       (fg-heading-8 fg-dim)
 
@@ -373,7 +398,7 @@ which corresponds to a minimum contrast in relative 
luminance of
       (overline-heading-6 unspecified)
       (overline-heading-7 unspecified)
       (overline-heading-8 unspecified))
-    "The entire palette of the `modus-operandi' theme.
+    "The entire palette of the `modus-operandi-tritanopia' theme.
 
 Named colors have the form (COLOR-NAME HEX-VALUE) with the former
 as a symbol and the latter as a string.
@@ -382,8 +407,8 @@ Semantic color mappings have the form (MAPPING-NAME 
COLOR-NAME)
 with both as symbols.  The latter is a named color that already
 exists in the palette and is associated with a HEX-VALUE.")
 
-  (defcustom modus-operandi-palette-overrides nil
-    "Overrides for `modus-operandi-palette'.
+  (defcustom modus-operandi-tritanopia-palette-overrides nil
+    "Overrides for `modus-operandi-tritanopia-palette'.
 
 Mirror the elements of the aforementioned palette, overriding
 their value.
@@ -405,13 +430,13 @@ represents."
     :initialize #'custom-initialize-default
     :link '(info-link "(modus-themes) Palette overrides"))
 
-  (modus-themes-theme modus-operandi
-                      modus-operandi-palette
-                      modus-operandi-palette-overrides)
+  (modus-themes-theme modus-operandi-tritanopia
+                      modus-operandi-tritanopia-palette
+                      modus-operandi-tritanopia-palette-overrides)
 
-  (provide-theme 'modus-operandi))
+  (provide-theme 'modus-operandi-tritanopia))
 
 ;;;###theme-autoload
-(put 'modus-operandi 'theme-properties '(:background-mode light :kind 
color-scheme :family modus))
+(put 'modus-operandi-tritanopia 'theme-properties '(:background-mode light 
:kind color-scheme :family modus))
 
-;;; modus-operandi-theme.el ends here
+;;; modus-operandi-tritanopia-theme.el ends here
diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el
index 805f25b458f..43c10043bc5 100644
--- a/etc/themes/modus-themes.el
+++ b/etc/themes/modus-themes.el
@@ -6,7 +6,7 @@
 ;; Maintainer: Modus-Themes Development <~protesilaos/modus-themes@lists.sr.ht>
 ;; URL: https://git.sr.ht/~protesilaos/modus-themes
 ;; Mailing-List: https://lists.sr.ht/~protesilaos/modus-themes
-;; Version: 4.1.0
+;; Version: 4.2.0
 ;; Package-Requires: ((emacs "27.1"))
 ;; Keywords: faces, theme, accessibility
 
@@ -45,14 +45,15 @@
   "User options for the Modus themes.
 The Modus themes conform with the WCAG AAA standard for color
 contrast between background and foreground combinations (a
-minimum contrast of 7:1---the highest standard of its kind).  The
-themes also strive to empower users with red-green color
-deficiency: this is achieved through customization variables that
-replace all relevant instances of green with blue, as well as the
-overall design of the themes which relies mostly on colors that
-cover the blue-cyan-magenta side of the spectrum."
+minimum contrast of 7:1---the highest standard of its kind).
+
+The Modus themes collection includes themes that are optimized
+for people with red-green or blue-yellow color
+deficiency (deuteranopia or tritanopia, respectively)."
   :group 'faces
   :link '(info-link "(modus-themes) Top")
+  :link '(url-link :tag "Homepage" 
"https://protesilaos.com/emacs/modus-themes";)
+  :link '(url-link :tag "Sample pictures" 
"https://protesilaos.com/emacs/modus-themes-pictures";)
   :prefix "modus-themes-"
   :tag "Modus Themes")
 
@@ -60,6 +61,8 @@ cover the blue-cyan-magenta side of the spectrum."
   "Faces defined by the Modus themes."
   :group 'modus-themes
   :link '(info-link "(modus-themes) Top")
+  :link '(url-link :tag "Homepage" 
"https://protesilaos.com/emacs/modus-themes";)
+  :link '(url-link :tag "Sample pictures" 
"https://protesilaos.com/emacs/modus-themes-pictures";)
   :prefix "modus-themes-"
   :tag "Modus Themes Faces")
 
@@ -128,6 +131,14 @@ cover the blue-cyan-magenta side of the spectrum."
    :version "30.1"
    :group 'modus-themes-faces))
 
+(dolist (scope '(note warning error))
+  (custom-declare-face
+   (intern (format "modus-themes-prominent-%s" scope))
+   nil (format "Prominent notification of type %s." scope)
+   :package-version '(modus-themes . "4.2.0")
+   :version "30.1"
+   :group 'modus-themes-faces))
+
 (dolist (scope '(current lazy))
   (custom-declare-face
    (intern (format "modus-themes-search-%s" scope))
@@ -360,10 +371,14 @@ set this variable to a nil value."
   :type 'boolean
   :link '(info-link "(modus-themes) Disable other themes"))
 
+(defvaralias 'modus-themes-collection 'modus-themes-items
+  "Alias of `modus-themes-items'.")
+
 (defconst modus-themes-items
   '( modus-operandi modus-vivendi
      modus-operandi-tinted modus-vivendi-tinted
-     modus-operandi-deuteranopia modus-vivendi-deuteranopia)
+     modus-operandi-deuteranopia modus-vivendi-deuteranopia
+     modus-operandi-tritanopia modus-vivendi-tritanopia)
   "Symbols of the Modus themes.")
 
 (defcustom modus-themes-to-toggle '(modus-operandi modus-vivendi)
@@ -928,12 +943,17 @@ colorful/intense.  Grays are toned down, gray backgrounds 
are
 removed from some contexts, and almost all accent colors are
 desaturated.
 
+All the preset overrides the themes provide (including this one):
+
+- `modus-themes-preset-overrides-faint'
+- `modus-themes-preset-overrides-intense'
+- `modus-themes-preset-overrides-cooler'
+- `modus-themes-preset-overrides-warmer'
+
 To set a preset, assign its symbol without a quote as the value
 of the `modus-themes-common-palette-overrides' or as the value of
 theme-specific options such as `modus-operandi-palette-overrides'.
 
-Also see `modus-themes-preset-overrides-intense'.
-
 For overriding named colors and/or semantic color mappings read
 Info node `(modus-themes) Option for palette overrides'.")
 
@@ -957,6 +977,7 @@ Info node `(modus-themes) Option for palette overrides'.")
     (date-event blue)
     (date-holiday magenta-warmer)
     (date-now blue-faint)
+    (date-range blue)
     (date-scheduled yellow-warmer)
     (date-weekday fg-main)
     (date-weekend red-faint)
@@ -1016,11 +1037,124 @@ This changes many parts of the theme to make them look 
more
 colorful/intense.  Many background colors are accented and
 coloration is increased to pop out more.
 
+All the preset overrides the themes provide (including this one):
+
+- `modus-themes-preset-overrides-faint'
+- `modus-themes-preset-overrides-intense'
+- `modus-themes-preset-overrides-cooler'
+- `modus-themes-preset-overrides-warmer'
+
 To set a preset, assign its symbol without a quote as the value
 of the `modus-themes-common-palette-overrides' or as the value of
 theme-specific options such as `modus-operandi-palette-overrides'.
 
-Also see `modus-themes-preset-overrides-faint'.
+For overriding named colors and/or semantic color mappings read
+Info node `(modus-themes) Option for palette overrides'.")
+
+(defvar modus-themes-preset-overrides-cooler
+  '((fg-prompt blue-cooler)
+
+    (builtin magenta-faint)
+    (constant blue-cooler)
+    (fnname cyan-cooler)
+    (keyword magenta-cooler)
+    (preprocessor blue)
+    (string blue-warmer)
+    (type green-cooler)
+    (variable cyan)
+    (rx-construct blue-cooler)
+    (rx-backslash red)
+
+    (name blue-warmer)
+    (identifier magenta-faint)
+
+    (date-deadline magenta-cooler)
+    (date-scheduled yellow-cooler)
+    (date-weekday blue-faint)
+    (date-weekend red-faint)
+
+    (mail-cite-0 blue-faint)
+    (mail-cite-1 cyan-cooler)
+    (mail-cite-2 magenta-faint)
+    (mail-cite-3 yellow-cooler)
+    (mail-part cyan)
+    (mail-recipient blue-warmer)
+    (mail-subject magenta-cooler)
+    (mail-other blue)
+
+    (prose-tag fg-dim)
+    (prose-verbatim blue-cooler))
+  "Preset of palette overrides with cooler colors.
+
+This changes parts of the palette to use more blue and
+blue-tinted colors.
+
+All the preset overrides the themes provide (including this one):
+
+- `modus-themes-preset-overrides-faint'
+- `modus-themes-preset-overrides-intense'
+- `modus-themes-preset-overrides-cooler'
+- `modus-themes-preset-overrides-warmer'
+
+To set a preset, assign its symbol without a quote as the value
+of the `modus-themes-common-palette-overrides' or as the value of
+theme-specific options such as `modus-operandi-palette-overrides'.
+
+For overriding named colors and/or semantic color mappings read
+Info node `(modus-themes) Option for palette overrides'.")
+
+(defvar modus-themes-preset-overrides-warmer
+  '((fg-prompt magenta-warmer)
+
+    (builtin magenta)
+    (constant blue-warmer)
+    (fnname magenta-cooler)
+    (keyword magenta-warmer)
+    (preprocessor red-cooler)
+    (string olive)
+    (type cyan-cooler)
+    (variable cyan)
+    (rx-construct blue-cooler)
+    (rx-backslash red-warmer)
+
+    (name blue-warmer)
+    (identifier magenta)
+    (keybind magenta-warmer)
+
+    (accent-0 magenta-warmer)
+    (accent-1 cyan)
+    (accent-2 blue-warmer)
+    (accent-3 red-cooler)
+
+    (date-common cyan-cooler)
+    (date-holiday magenta-warmer)
+
+    (mail-cite-0 magenta-faint)
+    (mail-cite-1 cyan-cooler)
+    (mail-cite-2 green-warmer)
+    (mail-cite-3 red-faint)
+    (mail-part cyan)
+    (mail-recipient magenta)
+    (mail-subject blue-warmer)
+    (mail-other magenta-warmer)
+
+    (prose-macro red-cooler)
+    (prose-tag fg-dim))
+  "Preset of palette overrides with warmer colors.
+
+This changes many parts of the theme to use warmer colors,
+including green and yellow.
+
+All the preset overrides the themes provide (including this one):
+
+- `modus-themes-preset-overrides-faint'
+- `modus-themes-preset-overrides-intense'
+- `modus-themes-preset-overrides-cooler'
+- `modus-themes-preset-overrides-warmer'
+
+To set a preset, assign its symbol without a quote as the value
+of the `modus-themes-common-palette-overrides' or as the value of
+theme-specific options such as `modus-operandi-palette-overrides'.
 
 For overriding named colors and/or semantic color mappings read
 Info node `(modus-themes) Option for palette overrides'.")
@@ -1123,10 +1257,13 @@ Which themes are disabled is determined by the user 
option
 `modus-themes-disable-other-themes'.
 
 Run the `modus-themes-after-load-theme-hook' as the final step
-after loading the THEME."
+after loading the THEME.
+
+Return THEME."
   (modus-themes--disable-themes)
   (load-theme theme :no-confirm)
-  (run-hooks 'modus-themes-after-load-theme-hook))
+  (run-hooks 'modus-themes-after-load-theme-hook)
+  theme)
 
 (defun modus-themes--retrieve-palette-value (color palette)
   "Return COLOR from PALETTE.
@@ -1183,14 +1320,19 @@ symbol, which is safe when used as a face attribute's 
value."
 (defvar modus-themes--select-theme-history nil
   "Minibuffer history of `modus-themes--select-prompt'.")
 
+(defun modus-themes--annotate-theme (theme)
+  "Return completion annotation for THEME."
+  (format " -- %s" (car (split-string (get (intern theme) 
'theme-documentation) "\\."))))
+
 (defun modus-themes--select-prompt ()
   "Minibuffer prompt to select a Modus theme."
-  (intern
-   (completing-read
-    "Select Modus theme: "
-    (modus-themes--list-known-themes)
-    nil t nil
-    'modus-themes--select-theme-history)))
+  (let ((completion-extra-properties `(:annotation-function 
,#'modus-themes--annotate-theme)))
+    (intern
+     (completing-read
+      "Select Modus theme: "
+      (modus-themes--list-known-themes)
+      nil t nil
+      'modus-themes--select-theme-history))))
 
 ;;;###autoload
 (defun modus-themes-select (theme)
@@ -1278,7 +1420,8 @@ color mappings of the palette, instead of its named 
colors."
 (defun modus-themes--list-colors-prompt ()
   "Prompt for Modus theme.
 Helper function for `modus-themes-list-colors'."
-  (let ((def (format "%s" (modus-themes--current-theme))))
+  (let ((def (format "%s" (modus-themes--current-theme)))
+        (completion-extra-properties `(:annotation-function 
,#'modus-themes--annotate-theme)))
     (completing-read
      (format "Use palette from theme [%s]: " def)
      (modus-themes--list-known-themes) nil t nil
@@ -1544,9 +1687,9 @@ FG and BG are the main colors."
     `(modus-themes-intense-cyan ((,c :background ,bg-cyan-intense :foreground 
,fg-main)))
 ;;;;; mark indicators
     ;; color combinations intended for Dired, Ibuffer, or equivalent
-    `(modus-themes-mark-alt ((,c :inherit bold :background ,bg-yellow-subtle 
:foreground ,yellow)))
-    `(modus-themes-mark-del ((,c :inherit bold :background ,bg-red-subtle 
:foreground ,red)))
-    `(modus-themes-mark-sel ((,c :inherit bold :background ,bg-cyan-subtle 
:foreground ,cyan)))
+    `(modus-themes-mark-alt ((,c :inherit bold :background ,bg-mark-other 
:foreground ,fg-mark-other)))
+    `(modus-themes-mark-del ((,c :inherit bold :background ,bg-mark-delete 
:foreground ,fg-mark-delete)))
+    `(modus-themes-mark-sel ((,c :inherit bold :background ,bg-mark-select 
:foreground ,fg-mark-select)))
 ;;;;; heading levels
     ;; styles for regular headings used in Org, Markdown, Info, etc.
     `(modus-themes-heading-0 ((,c ,@(modus-themes--heading 0 fg-heading-0 
bg-heading-0 overline-heading-0))))
@@ -1562,6 +1705,10 @@ FG and BG are the main colors."
     `(modus-themes-lang-error ((,c :underline (:style wave :color 
,underline-err))))
     `(modus-themes-lang-note ((,c :underline (:style wave :color 
,underline-note))))
     `(modus-themes-lang-warning ((,c :underline (:style wave :color 
,underline-warning))))
+;;;;; prominent semantic notes
+    `(modus-themes-prominent-error ((,c :background ,bg-prominent-err 
:foreground ,fg-prominent-err)))
+    `(modus-themes-prominent-note ((,c :background ,bg-prominent-note 
:foreground ,fg-prominent-note)))
+    `(modus-themes-prominent-warning ((,c :background ,bg-prominent-warning 
:foreground ,fg-prominent-warning)))
 ;;;;; markup
     `(modus-themes-prose-code ((,c :inherit modus-themes-fixed-pitch 
:foreground ,prose-code)))
     `(modus-themes-prose-macro ((,c :inherit modus-themes-fixed-pitch 
:foreground ,prose-macro)))
@@ -1581,7 +1728,10 @@ FG and BG are the main colors."
     `(modus-themes-slant ((,c ,@(modus-themes--slant))))
     `(modus-themes-ui-variable-pitch ((,c 
,@(modus-themes--variable-pitch-ui))))
 ;;;;; other custom faces
-    `(modus-themes-button ((,c :inherit variable-pitch :box ,border 
:background ,bg-button-active :foreground ,fg-button-active)))
+    `(modus-themes-button ((,c :inherit variable-pitch
+                               :box (:line-width 1 :color ,border :style 
released-button)
+                               :background ,bg-button-active
+                               :foreground ,fg-button-active)))
     `(modus-themes-key-binding ((,c :inherit (bold modus-themes-fixed-pitch) 
:foreground ,keybind)))
     `(modus-themes-prompt ((,c ,@(modus-themes--prompt fg-prompt bg-prompt))))
     `(modus-themes-reset-soft ((,c :background ,bg-main :foreground ,fg-main
@@ -1592,9 +1742,9 @@ FG and BG are the main colors."
     `(default ((,c :background ,bg-main :foreground ,fg-main)))
     `(cursor ((,c :background ,cursor)))
     `(fringe ((,c :background ,fringe :foreground ,fg-main)))
-    `(menu ((,c :background ,bg-tab-bar :foreground ,fg-main)))
-    `(scroll-bar ((,c :background ,fringe :foreground ,fg-dim)))
-    `(tool-bar ((,c :background ,bg-tab-bar :foreground ,fg-main)))
+    `(menu ((,c :background ,bg-dim :foreground ,fg-main)))
+    `(scroll-bar ((,c :background ,bg-dim :foreground ,fg-dim)))
+    `(tool-bar ((,c :background ,bg-dim :foreground ,fg-main)))
     `(vertical-border ((,c :foreground ,border)))
 ;;;;; basic and/or ungrouped styles
     `(bold ((,c :weight bold)))
@@ -1625,8 +1775,8 @@ FG and BG are the main colors."
     `(minibuffer-prompt ((,c :inherit modus-themes-prompt)))
     `(mm-command-output ((,c :foreground ,mail-part)))
     `(mm-uu-extract ((,c :foreground ,mail-part)))
-    `(next-error ((,c :inherit modus-themes-subtle-red :extend t)))
-    `(pgtk-im-0 ((,c :inherit modus-themes-intense-cyan)))
+    `(next-error ((,c :inherit modus-themes-prominent-error :extend t)))
+    `(pgtk-im-0 ((,c :inherit modus-themes-prominent-note)))
     `(read-multiple-choice-face ((,c :inherit (bold modus-themes-mark-alt))))
     `(rectangle-preview ((,c :inherit secondary-selection)))
     `(region ((,c :background ,bg-region :foreground ,fg-region)))
@@ -1634,7 +1784,7 @@ FG and BG are the main colors."
     `(separator-line ((,c :underline ,bg-active)))
     `(shadow ((,c :foreground ,fg-dim)))
     `(success ((,c :inherit bold :foreground ,info)))
-    `(trailing-whitespace ((,c :background ,bg-red-intense)))
+    `(trailing-whitespace ((,c :background ,bg-space-err)))
     `(warning ((,c :inherit bold :foreground ,warning)))
 ;;;;; buttons, links, widgets
     `(button ((,c :background ,bg-link :foreground ,fg-link :underline 
,underline-link)))
@@ -1738,7 +1888,7 @@ FG and BG are the main colors."
     `(anzu-match-3 ((,c :inherit modus-themes-subtle-yellow)))
     `(anzu-mode-line ((,c :inherit bold)))
     `(anzu-mode-line-no-match ((,c :inherit error)))
-    `(anzu-replace-highlight ((,c :inherit modus-themes-intense-red :underline 
t)))
+    `(anzu-replace-highlight ((,c :inherit modus-themes-prominent-error 
:underline t)))
     `(anzu-replace-to ((,c :inherit modus-themes-search-current)))
 ;;;;; auctex and Tex
     `(font-latex-bold-face ((,c :inherit bold)))
@@ -1775,12 +1925,12 @@ FG and BG are the main colors."
     `(aw-background-face ((,c :foreground "gray50")))
     `(aw-key-face ((,c :inherit modus-themes-key-binding)))
     `(aw-leading-char-face ((,c :inherit (bold modus-themes-reset-soft) 
:height 1.5 :foreground ,red-intense)))
-    `(aw-minibuffer-leading-char-face ((,c :inherit (modus-themes-intense-red 
bold))))
+    `(aw-minibuffer-leading-char-face ((,c :inherit modus-themes-key-binding)))
     `(aw-mode-line-face ((,c :inherit bold)))
 ;;;;; binder
-    `(binder-sidebar-highlight ((,c :inherit modus-themes-subtle-cyan)))
+    `(binder-sidebar-highlight ((,c :inherit modus-themes-hl-line)))
     `(binder-sidebar-marked ((,c :inherit modus-themes-mark-sel)))
-    `(binder-sidebar-missing ((,c :inherit modus-themes-subtle-red)))
+    `(binder-sidebar-missing ((,c :inherit modus-themes-mark-del)))
     `(binder-sidebar-tags ((,c :foreground ,variable)))
 ;;;;; bongo
     `(bongo-album-title (( )))
@@ -1807,13 +1957,13 @@ FG and BG are the main colors."
     `(calendar-today ((,c :inherit bold :underline t)))
     `(calendar-weekday-header ((,c :foreground ,date-weekday)))
     `(calendar-weekend-header ((,c :foreground ,date-weekend)))
-    `(diary ((,c :background ,bg-dim :foreground ,accent-0)))
-    `(diary-anniversary ((,c :foreground ,accent-1)))
+    `(diary ((,c :foreground ,date-common)))
+    `(diary-anniversary ((,c :foreground ,date-holiday)))
     `(diary-time ((,c :foreground ,date-common)))
     `(holiday ((,c :foreground ,date-holiday)))
 ;;;;; calibredb
     ;; NOTE 2022-12-27: Calibredb needs to be reviewed.  I had to
-    ;; change the applicable colours for the transition to
+    ;; change the applicable colors for the transition to
     ;; modus-themes version 4, but I cannot test this currently (it
     ;; depends on an external program).
     `(calibredb-archive-face ((,c :foreground ,accent-3)))
@@ -1890,7 +2040,7 @@ FG and BG are the main colors."
 ;;;;; clojure-mode
     `(clojure-keyword-face ((,c :inherit font-lock-builtin-face)))
 ;;;;; column-enforce-mode
-    `(column-enforce-face ((,c :inherit modus-themes-intense-yellow)))
+    `(column-enforce-face ((,c :inherit modus-themes-prominent-error)))
 ;;;;; company-mode
     `(company-echo-common ((,c :inherit modus-themes-completion-match-0)))
     `(company-preview ((,c :background ,bg-dim :foreground ,fg-dim)))
@@ -2051,7 +2201,7 @@ FG and BG are the main colors."
 ;;;;; dired-git-info
     `(dgi-commit-message-face ((,c :foreground ,docstring)))
 ;;;;; dired-narrow
-    `(dired-narrow-blink ((,c :inherit (modus-themes-subtle-cyan bold))))
+    `(dired-narrow-blink ((,c :inherit (modus-themes-prominent-warning bold))))
 ;;;;; dired-subtree
     ;; remove backgrounds from dired-subtree faces, else they break
     ;; dired-{flagged,marked} and any other face that sets a background
@@ -2089,6 +2239,12 @@ FG and BG are the main colors."
     `(diredfl-symlink ((,c :inherit dired-symlink)))
     `(diredfl-tagged-autofile-name ((,c :inherit (diredfl-autofile-name 
dired-marked))))
     `(diredfl-write-priv ((,c :foreground ,accent-0)))
+;;;;; disk-usage
+    `(disk-usage-inaccessible ((,c :inherit error)))
+    `(disk-usage-percent ((,c :foreground ,accent-0)))
+    `(disk-usage-size ((,c :foreground ,accent-1)))
+    `(disk-usage-symlink ((,c :inherit dired-symlink)))
+    `(disk-usage-symlink-directory ((,c :inherit dired-symlink)))
 ;;;;; display-fill-column-indicator-mode
     `(fill-column-indicator ((,c :height 1 :background ,bg-active :foreground 
,bg-active)))
 ;;;;; doom-modeline
@@ -2128,7 +2284,7 @@ FG and BG are the main colors."
     `(doom-modeline-warning ((,c :inherit warning)))
 ;;;;; ediff
     `(ediff-current-diff-A ((,c :background ,bg-removed :foreground 
,fg-removed)))
-    `(ediff-current-diff-Ancestor ((,c :background ,bg-region))) ; TODO 
2022-11-29: Needs review
+    `(ediff-current-diff-Ancestor ((,c :background ,bg-region)))
     `(ediff-current-diff-B ((,c :background ,bg-added :foreground ,fg-added)))
     `(ediff-current-diff-C ((,c :background ,bg-changed :foreground 
,fg-changed)))
     `(ediff-even-diff-A ((,c :background ,bg-diff-context)))
@@ -2152,6 +2308,7 @@ FG and BG are the main colors."
     `(ein:notification-tab-normal ((,c :underline t)))
 ;;;;; eglot
     `(eglot-mode-line ((,c :inherit modus-themes-bold :foreground 
,modeline-info)))
+    `(eglot-diagnostic-tag-unnecessary-face ((,c :inherit 
modus-themes-lang-note)))
 ;;;;; el-search
     `(el-search-highlight-in-prompt-face ((,c :inherit italic)))
     `(el-search-match ((,c :inherit modus-themes-search-current)))
@@ -2236,7 +2393,7 @@ FG and BG are the main colors."
     `(erc-button ((,c :inherit button)))
     `(erc-command-indicator-face ((,c :inherit bold :foreground ,accent-3)))
     `(erc-current-nick-face ((,c :inherit match)))
-    `(erc-dangerous-host-face ((,c :inherit modus-themes-intense-red)))
+    `(erc-dangerous-host-face ((,c :inherit error)))
     `(erc-direct-msg-face ((,c :inherit shadow)))
     `(erc-error-face ((,c :inherit error)))
     `(erc-fool-face ((,c :inherit shadow)))
@@ -2254,8 +2411,8 @@ FG and BG are the main colors."
     `(erc-timestamp-face ((,c :foreground ,date-common)))
     `(erc-underline-face ((,c :underline t)))
 ;;;;; ert
-    `(ert-test-result-expected ((,c :inherit modus-themes-intense-cyan)))
-    `(ert-test-result-unexpected ((,c :inherit modus-themes-intense-red)))
+    `(ert-test-result-expected ((,c :inherit modus-themes-prominent-note)))
+    `(ert-test-result-unexpected ((,c :inherit modus-themes-prominent-error)))
 ;;;;; eshell
     `(eshell-ls-archive ((,c :foreground ,accent-2)))
     `(eshell-ls-backup ((,c :inherit shadow)))
@@ -2277,7 +2434,7 @@ FG and BG are the main colors."
     `(evil-ex-info ((,c :inherit font-lock-type-face)))
     `(evil-ex-lazy-highlight ((,c :inherit modus-themes-search-lazy)))
     `(evil-ex-search ((,c :inherit modus-themes-search-current)))
-    `(evil-ex-substitute-matches ((,c :inherit modus-themes-intense-yellow 
:underline t)))
+    `(evil-ex-substitute-matches ((,c :inherit modus-themes-prominent-error 
:underline t)))
     `(evil-ex-substitute-replacement ((,c :inherit 
modus-themes-search-current)))
 ;;;;; eww
     `(eww-invalid-certificate ((,c :foreground ,err)))
@@ -2292,9 +2449,9 @@ FG and BG are the main colors."
     `(eyebrowse-mode-line-active ((,c :inherit mode-line-emphasis)))
 ;;;;; flycheck
     `(flycheck-error ((,c :inherit modus-themes-lang-error)))
-    `(flycheck-fringe-error ((,c :inherit modus-themes-intense-red)))
-    `(flycheck-fringe-info ((,c :inherit modus-themes-intense-cyan)))
-    `(flycheck-fringe-warning ((,c :inherit modus-themes-intense-yellow)))
+    `(flycheck-fringe-error ((,c :inherit modus-themes-prominent-error)))
+    `(flycheck-fringe-info ((,c :inherit modus-themes-prominent-note)))
+    `(flycheck-fringe-warning ((,c :inherit modus-themes-prominent-warning)))
     `(flycheck-info ((,c :inherit modus-themes-lang-note)))
     `(flycheck-warning ((,c :inherit modus-themes-lang-warning)))
 ;;;;; flycheck-color-mode-line
@@ -2310,9 +2467,16 @@ FG and BG are the main colors."
     `(flycheck-indicator-success ((,c :inherit success)))
     `(flycheck-indicator-warning ((,c :inherit warning)))
 ;;;;; flymake
+    `(flymake-end-of-line-diagnostics-face ((,c :inherit modus-themes-slant 
:height 0.85 :box ,border)))
     `(flymake-error ((,c :inherit modus-themes-lang-error)))
+    `(flymake-error-echo ((,c :inherit error)))
+    `(flymake-error-echo-at-eol ((,c :inherit 
flymake-end-of-line-diagnostics-face :foreground ,err)))
     `(flymake-note ((,c :inherit modus-themes-lang-note)))
+    `(flymake-note-echo ((,c :inherit success)))
+    `(flymake-note-echo-at-eol ((,c :inherit 
flymake-end-of-line-diagnostics-face :foreground ,info)))
     `(flymake-warning ((,c :inherit modus-themes-lang-warning)))
+    `(flymake-warning-echo ((,c :inherit warning)))
+    `(flymake-note-echo-at-eol ((,c :inherit 
flymake-end-of-line-diagnostics-face :foreground ,warning)))
 ;;;;; flyspell
     `(flyspell-duplicate ((,c :inherit modus-themes-lang-warning)))
     `(flyspell-incorrect ((,c :inherit modus-themes-lang-error)))
@@ -2531,16 +2695,16 @@ FG and BG are the main colors."
     `(ido-subdir ((,c :foreground ,accent-0)))
     `(ido-virtual ((,c :foreground ,accent-1)))
 ;;;;; iedit
-    `(iedit-occurrence ((,c :inherit modus-themes-intense-blue)))
-    `(iedit-read-only-occurrence ((,c :inherit modus-themes-intense-yellow)))
+    `(iedit-occurrence ((,c :inherit modus-themes-search-lazy)))
+    `(iedit-read-only-occurrence ((,c :inherit modus-themes-search-current)))
 ;;;;; iflipb
     `(iflipb-current-buffer-face ((,c :inherit bold :foreground ,name)))
     `(iflipb-other-buffer-face ((,c :inherit shadow)))
 ;;;;; image-dired
-    `(image-dired-thumb-flagged ((,c :inherit modus-themes-intense-red)))
+    `(image-dired-thumb-flagged ((,c :inherit modus-themes-mark-del :box 
(:line-width -3))))
     `(image-dired-thumb-header-file-name ((,c :inherit bold)))
     `(image-dired-thumb-header-file-size ((,c :foreground ,constant)))
-    `(image-dired-thumb-mark ((,c :inherit modus-themes-intense-cyan)))
+    `(image-dired-thumb-mark ((,c :inherit modus-themes-mark-sel :box 
(:line-width -3))))
 ;;;;; imenu-list
     `(imenu-list-entry-face-0 ((,c :foreground ,fg-heading-0)))
     `(imenu-list-entry-face-1 ((,c :foreground ,fg-heading-1)))
@@ -2564,7 +2728,7 @@ FG and BG are the main colors."
     `(info-header-xref ((,c :foreground ,fg-link)))
     `(info-index-match ((,c :inherit match)))
     `(info-menu-header ((,c :inherit bold)))
-    `(info-menu-star ((,c :foreground ,red-intense)))
+    `(info-menu-star ((,c :inherit error)))
     `(info-node ((,c :inherit bold)))
     `(info-title-1 ((,c :inherit modus-themes-heading-1)))
     `(info-title-2 ((,c :inherit modus-themes-heading-2)))
@@ -2613,12 +2777,12 @@ FG and BG are the main colors."
     `(ioccur-title-face ((,c :inherit bold :foreground ,name)))
 ;;;;; isearch, occur, and the like
     `(isearch ((,c :inherit modus-themes-search-current)))
-    `(isearch-fail ((,c :inherit modus-themes-intense-red)))
+    `(isearch-fail ((,c :inherit modus-themes-prominent-error)))
     `(isearch-group-1 ((,c :inherit modus-themes-intense-blue)))
     `(isearch-group-2 ((,c :inherit modus-themes-intense-magenta)))
     `(lazy-highlight ((,c :inherit modus-themes-search-lazy)))
     `(match ((,c :background ,bg-magenta-subtle :foreground ,fg-main)))
-    `(query-replace ((,c :inherit modus-themes-intense-red)))
+    `(query-replace ((,c :inherit modus-themes-prominent-error)))
 ;;;;; ivy
     `(ivy-action ((,c :inherit modus-themes-key-binding)))
     `(ivy-confirm-face ((,c :inherit success)))
@@ -2644,6 +2808,10 @@ FG and BG are the main colors."
     `(jiralib-link-filter-face ((,c :underline t)))
     `(jiralib-link-issue-face ((,c :underline t)))
     `(jiralib-link-project-face ((,c :underline t)))
+;;;;; jit-spell
+    `(jit-spell-misspelling ((,c :inherit modus-themes-lang-error)))
+;;;;; jinx
+    `(jinx-misspelled ((,c :inherit modus-themes-lang-warning)))
 ;;;;; journalctl-mode
     `(journalctl-error-face ((,c :inherit error)))
     `(journalctl-finished-face ((,c :inherit success)))
@@ -3044,6 +3212,7 @@ FG and BG are the main colors."
     `(orderless-match-face-2 ((,c :inherit modus-themes-completion-match-2)))
     `(orderless-match-face-3 ((,c :inherit modus-themes-completion-match-3)))
 ;;;;; org
+    `(org-agenda-calendar-daterange ((,c :foreground ,date-range)))
     `(org-agenda-calendar-event ((,c :foreground ,date-event)))
     `(org-agenda-calendar-sexp ((,c :inherit (modus-themes-slant 
org-agenda-calendar-event))))
     `(org-agenda-clocking ((,c :inherit modus-themes-mark-alt)))
@@ -3211,6 +3380,24 @@ FG and BG are the main colors."
     `(persp-face-lighter-nil-persp ((,c :inherit bold)))
 ;;;;; perspective
     `(persp-selected-face ((,c :inherit bold :foreground ,name)))
+;;;;; proced
+    `(proced-cpu ((,c :foreground ,keyword)))
+    `(proced-emacs-pid ((,c :foreground ,identifier :underline t)))
+    `(proced-executable ((,c :foreground ,name)))
+    `(proced-interruptible-sleep-status-code ((,c :inherit shadow)))
+    `(proced-mem ((,c :foreground ,type)))
+    `(proced-memory-high-usage ((,c :foreground ,err)))
+    `(proced-memory-low-usage ((,c :foreground ,info)))
+    `(proced-memory-medium-usage ((,c :foreground ,warning)))
+    `(proced-pgrp ((,c :inherit proced-pid)))
+    `(proced-pid ((,c :foreground ,identifier)))
+    `(proced-ppid ((,c :inherit proced-pid)))
+    `(proced-run-status-code ((,c :inherit success)))
+    `(proced-sess ((,c :inherit proced-pid)))
+    `(proced-session-leader-pid ((,c :inherit bold :foreground ,identifier)))
+    `(proced-time-colon (( )))
+    `(proced-uninterruptible-sleep-status-code ((,c :inherit error)))
+    `(proced-user (( )))
 ;;;;; popup
     `(popup-face ((,c :background ,bg-inactive :foreground ,fg-main)))
     `(popup-isearch-match ((,c :inherit modus-themes-search-current)))
@@ -3229,13 +3416,13 @@ FG and BG are the main colors."
     `(powerline-inactive2 ((,c :inherit mode-line-inactive)))
 ;;;;; powerline-evil
     `(powerline-evil-base-face ((,c :background ,fg-main :foreground 
,bg-main)))
-    `(powerline-evil-emacs-face ((,c :inherit modus-themes-intense-magenta)))
-    `(powerline-evil-insert-face ((,c :inherit modus-themes-intense-green)))
-    `(powerline-evil-motion-face ((,c :inherit modus-themes-intense-blue)))
-    `(powerline-evil-normal-face ((,c :background ,fg-alt :foreground 
,bg-main)))
-    `(powerline-evil-operator-face ((,c :inherit modus-themes-intense-yellow)))
-    `(powerline-evil-replace-face ((,c :inherit modus-themes-intense-red)))
-    `(powerline-evil-visual-face ((,c :inherit modus-themes-intense-cyan)))
+    `(powerline-evil-emacs-face ((,c :inherit bold :background ,bg-main)))
+    `(powerline-evil-insert-face ((,c :inherit success :background ,bg-main)))
+    `(powerline-evil-motion-face ((,c :inherit italic :background ,bg-main)))
+    `(powerline-evil-normal-face ((,c :background ,bg-main :foreground 
,fg-alt)))
+    `(powerline-evil-operator-face ((,c :inherit warning :background 
,bg-main)))
+    `(powerline-evil-replace-face ((,c :inherit error :background ,bg-main)))
+    `(powerline-evil-visual-face ((,c :inherit bold :background ,bg-main)))
 ;;;;; prescient
     `(prescient-primary-highlight ((,c :inherit 
modus-themes-completion-match-0)))
     `(prescient-secondary-highlight ((,c :inherit 
modus-themes-completion-match-1)))
@@ -3258,7 +3445,7 @@ FG and BG are the main colors."
     `(quick-peek-border-face ((,c :background ,border :height 1)))
     `(quick-peek-padding-face ((,c :background ,bg-inactive :height 0.15)))
 ;;;;; rainbow-delimiters
-    `(rainbow-delimiters-base-error-face ((,c :inherit 
modus-themes-subtle-red)))
+    `(rainbow-delimiters-base-error-face ((,c :inherit 
modus-themes-prominent-error)))
     `(rainbow-delimiters-base-face ((,c :foreground ,fg-main)))
     `(rainbow-delimiters-depth-1-face ((,c :foreground ,rainbow-0)))
     `(rainbow-delimiters-depth-2-face ((,c :foreground ,rainbow-1)))
@@ -3269,8 +3456,8 @@ FG and BG are the main colors."
     `(rainbow-delimiters-depth-7-face ((,c :foreground ,rainbow-6)))
     `(rainbow-delimiters-depth-8-face ((,c :foreground ,rainbow-7)))
     `(rainbow-delimiters-depth-9-face ((,c :foreground ,rainbow-8)))
-    `(rainbow-delimiters-mismatched-face ((,c :inherit (bold 
modus-themes-intense-yellow))))
-    `(rainbow-delimiters-unmatched-face ((,c :inherit (bold 
modus-themes-intense-red))))
+    `(rainbow-delimiters-mismatched-face ((,c :inherit (bold 
modus-themes-prominent-warning))))
+    `(rainbow-delimiters-unmatched-face ((,c :inherit (bold 
modus-themes-prominent-error))))
 ;;;;; rcirc
     `(rcirc-bright-nick ((,c :inherit bold :foreground ,accent-2)))
     `(rcirc-dim-nick ((,c :inherit shadow)))
@@ -3316,6 +3503,13 @@ FG and BG are the main colors."
 ;;;;; rmail
     `(rmail-header-name ((,c :inherit bold)))
     `(rmail-highlight ((,c :inherit bold :foreground ,mail-other)))
+;;;;; rst-mode
+    `(rst-level-1 ((,c :inherit modus-themes-heading-1)))
+    `(rst-level-2 ((,c :inherit modus-themes-heading-2)))
+    `(rst-level-3 ((,c :inherit modus-themes-heading-3)))
+    `(rst-level-4 ((,c :inherit modus-themes-heading-4)))
+    `(rst-level-5 ((,c :inherit modus-themes-heading-5)))
+    `(rst-level-6 ((,c :inherit modus-themes-heading-6)))
 ;;;;; ruler-mode
     `(ruler-mode-column-number ((,c :inherit ruler-mode-default)))
     `(ruler-mode-comment-column ((,c :inherit ruler-mode-default :foreground 
,red)))
@@ -3342,7 +3536,7 @@ FG and BG are the main colors."
 ;;;;; show-paren-mode
     `(show-paren-match ((,c :background ,bg-paren-match :foreground ,fg-main 
:underline ,underline-paren-match)))
     `(show-paren-match-expression ((,c :background ,bg-paren-expression)))
-    `(show-paren-mismatch ((,c :inherit modus-themes-intense-red)))
+    `(show-paren-mismatch ((,c :inherit modus-themes-prominent-error)))
 ;;;;; shr
     `(shr-abbreviation ((,c :inherit modus-themes-lang-note)))
     `(shr-code ((,c :inherit modus-themes-prose-verbatim)))
@@ -3352,7 +3546,7 @@ FG and BG are the main colors."
     `(shr-h4 ((,c :inherit modus-themes-heading-4)))
     `(shr-h5 ((,c :inherit modus-themes-heading-5)))
     `(shr-h6 ((,c :inherit modus-themes-heading-6)))
-    `(shr-selected-link ((,c :inherit modus-themes-subtle-red)))
+    `(shr-selected-link ((,c :inherit modus-themes-mark-sel)))
 ;;;;; side-notes
     `(side-notes ((,c :background ,bg-dim :foreground ,fg-dim)))
 ;;;;; sieve-mode
@@ -3404,7 +3598,7 @@ FG and BG are the main colors."
     `(sml/name-filling ((,c :inherit warning)))
     `(sml/not-modified ((,c :inherit sml/global)))
     `(sml/numbers-separator ((,c :inherit sml/global)))
-    `(sml/outside-modified ((,c :inherit modus-themes-intense-red)))
+    `(sml/outside-modified ((,c :inherit modus-themes-prominent-error)))
     `(sml/position-percentage ((,c :inherit sml/global)))
     `(sml/prefix ((,c :foreground ,fg-alt)))
     `(sml/process ((,c :inherit sml/prefix)))
@@ -3418,7 +3612,7 @@ FG and BG are the main colors."
 ;;;;; smerge
     `(smerge-base ((,c :inherit diff-changed)))
     `(smerge-lower ((,c :inherit diff-added)))
-    `(smerge-markers ((,c :inherit diff-heading)))
+    `(smerge-markers ((,c :inherit diff-header)))
     `(smerge-refined-added ((,c :inherit diff-refine-added)))
     `(smerge-refined-changed (()))
     `(smerge-refined-removed ((,c :inherit diff-refine-removed)))
@@ -3533,7 +3727,7 @@ FG and BG are the main colors."
     ;; have to do this with `eldoc-highlight-function-argument'.
     (list 'transient-argument `((,c :inherit (bold modus-themes-mark-alt))))
     `(transient-blue ((,c :inherit bold :foreground ,blue)))
-    `(transient-disabled-suffix ((,c :inherit modus-themes-intense-red)))
+    `(transient-disabled-suffix ((,c :inherit modus-themes-mark-del)))
     `(transient-enabled-suffix ((,c :inherit modus-themes-subtle-cyan)))
     `(transient-heading ((,c :inherit bold :foreground ,fg-main)))
     `(transient-inactive-argument ((,c :inherit shadow)))
@@ -3653,19 +3847,22 @@ FG and BG are the main colors."
     `(vr/match-1 ((,c :inherit modus-themes-intense-yellow)))
     `(vr/match-separator-face ((,c :inherit bold :background ,bg-active)))
 ;;;;; vterm
-    `(vterm-color-black ((,c :background "gray35" :foreground "gray35")))
-    `(vterm-color-blue ((,c :background ,blue :foreground ,blue)))
-    `(vterm-color-cyan ((,c :background ,cyan :foreground ,cyan)))
+    `(vterm-color-black ((,c :background "gray35" :foreground "black")))
+    `(vterm-color-blue ((,c :background ,blue-warmer :foreground ,blue)))
+    `(vterm-color-cyan ((,c :background ,cyan-cooler :foreground ,cyan)))
     `(vterm-color-default ((,c :background ,bg-main :foreground ,fg-main)))
-    `(vterm-color-green ((,c :background ,green :foreground ,green)))
+    `(vterm-color-green ((,c :background ,green-cooler :foreground ,green)))
     `(vterm-color-inverse-video ((,c :background ,bg-main :inverse-video t)))
-    `(vterm-color-magenta ((,c :background ,magenta :foreground ,magenta)))
-    `(vterm-color-red ((,c :background ,red :foreground ,red)))
+    `(vterm-color-magenta ((,c :background ,magenta-cooler :foreground 
,magenta)))
+    `(vterm-color-red ((,c :background ,red-warmer :foreground ,red)))
     `(vterm-color-underline ((,c :underline t)))
-    `(vterm-color-white ((,c :background "gray65" :foreground "gray65")))
-    `(vterm-color-yellow ((,c :background ,yellow :foreground ,yellow)))
+    `(vterm-color-white ((,c :background "white" :foreground "gray65")))
+    `(vterm-color-yellow ((,c :background ,yellow-warmer :foreground ,yellow)))
 ;;;;; vundo
-    `(vundo-highlight ((,c :inherit (bold vundo-node) :foreground 
,red-intense)))
+    `(vundo-default ((,c :inherit shadow)))
+    `(vundo-highlight ((,c :inherit (bold vundo-node) :foreground ,red)))
+    `(vundo-last-saved ((,c :inherit (bold vundo-node) :foreground ,blue)))
+    `(vundo-saved ((,c :inherit vundo-node :foreground ,blue-intense)))
 ;;;;; wcheck-mode
     `(wcheck-default-face ((,c :foreground ,red :underline t)))
 ;;;;; web-mode
@@ -3697,7 +3894,7 @@ FG and BG are the main colors."
     `(web-mode-current-column-highlight-face ((,c :background ,bg-inactive)))
     `(web-mode-current-element-highlight-face ((,c :inherit 
modus-themes-cyan-subtle)))
     `(web-mode-doctype-face ((,c :inherit font-lock-doc-face)))
-    `(web-mode-error-face ((,c :inherit modus-themes-intense-red)))
+    `(web-mode-error-face ((,c :inherit error)))
     `(web-mode-filter-face ((,c :inherit font-lock-function-name-face)))
     `(web-mode-folded-face ((,c :underline t)))
     `(web-mode-function-call-face ((,c :inherit font-lock-function-name-face)))
@@ -3735,7 +3932,7 @@ FG and BG are the main colors."
     `(web-mode-type-face ((,c :inherit font-lock-builtin-face)))
     `(web-mode-underline-face ((,c :underline t)))
     `(web-mode-variable-name-face ((,c :inherit font-lock-variable-name-face)))
-    `(web-mode-warning-face ((,c :inherit font-lock-warning-face)))
+    `(web-mode-warning-face ((,c :inherit warning)))
     `(web-mode-whitespace-face ((,c :background ,bg-inactive)))
 ;;;;; wgrep
     `(wgrep-delete-face ((,c :inherit warning)))
@@ -3747,7 +3944,7 @@ FG and BG are the main colors."
     `(which-func ((,c :inherit bold :foreground ,modeline-info)))
 ;;;;; which-key
     `(which-key-command-description-face ((,c :foreground ,fg-main)))
-    `(which-key-group-description-face ((,c :foreground ,err)))
+    `(which-key-group-description-face ((,c :foreground ,keyword)))
     `(which-key-highlighted-command-face ((,c :foreground ,warning :underline 
t)))
     `(which-key-key-face ((,c :inherit modus-themes-key-binding)))
     `(which-key-local-map-description-face ((,c :foreground ,fg-main)))
@@ -3755,24 +3952,24 @@ FG and BG are the main colors."
     `(which-key-separator-face ((,c :inherit shadow)))
     `(which-key-special-key-face ((,c :inherit error)))
 ;;;;; whitespace-mode
-    `(whitespace-big-indent ((,c :inherit modus-themes-subtle-red)))
+    `(whitespace-big-indent ((,c :background ,bg-space-err)))
     `(whitespace-empty ((,c :inherit modus-themes-intense-magenta)))
-    `(whitespace-hspace ((,c :background ,bg-dim :foreground ,fg-dim)))
-    `(whitespace-indentation ((,c :background ,bg-dim :foreground ,fg-dim)))
-    `(whitespace-line ((,c :inherit modus-themes-subtle-yellow)))
-    `(whitespace-newline ((,c :background ,bg-dim :foreground ,fg-dim)))
-    `(whitespace-space ((,c :background ,bg-dim :foreground ,fg-dim)))
+    `(whitespace-hspace ((,c :background ,bg-space :foreground ,fg-space)))
+    `(whitespace-indentation ((,c :background ,bg-space :foreground 
,fg-space)))
+    `(whitespace-line ((,c :background ,bg-space :foreground ,warning)))
+    `(whitespace-newline ((,c :background ,bg-space :foreground ,fg-space)))
+    `(whitespace-space ((,c :background ,bg-space :foreground ,fg-space)))
     `(whitespace-space-after-tab ((,c :inherit modus-themes-subtle-magenta)))
     `(whitespace-space-before-tab ((,c :inherit modus-themes-subtle-cyan)))
-    `(whitespace-tab ((,c :background ,bg-dim :foreground ,fg-dim)))
-    `(whitespace-trailing ((,c :inherit modus-themes-intense-red)))
+    `(whitespace-tab ((,c :background ,bg-space :foreground ,fg-space)))
+    `(whitespace-trailing ((,c :background ,bg-space-err)))
 ;;;;; window-divider-mode
     `(window-divider ((,c :foreground ,border)))
     `(window-divider-first-pixel ((,c :foreground ,bg-inactive)))
     `(window-divider-last-pixel ((,c :foreground ,bg-inactive)))
 ;;;;; widget
     `(widget-button ((,c :inherit bold :foreground ,fg-link)))
-    `(widget-button-pressed ((,c :inherit widget-buton :foreground 
,fg-link-visited)))
+    `(widget-button-pressed ((,c :inherit widget-button :foreground 
,fg-link-visited)))
     `(widget-documentation ((,c :inherit font-lock-doc-face)))
     `(widget-field ((,c :background ,bg-inactive :foreground ,fg-main :extend 
nil)))
     `(widget-inactive ((,c :background ,bg-button-inactive :foreground 
,fg-button-inactive)))
@@ -3792,7 +3989,7 @@ FG and BG are the main colors."
     `(xah-elisp-command-face ((,c :inherit font-lock-type-face)))
     `(xah-elisp-dollar-symbol ((,c :inherit font-lock-variable-name-face)))
 ;;;;; yaml-mode
-    `(yaml-tab-face ((,c :inherit modus-themes-intense-red)))
+    `(yaml-tab-face ((,c :background ,bg-space-err)))
 ;;;;; yasnippet
     `(yas-field-highlight-face ((,c :inherit highlight))))
   "Face specs for use with `modus-themes-theme'.")
@@ -3809,9 +4006,9 @@ FG and BG are the main colors."
 ;;;; exwm
     `(exwm-floating-border-color ,border)
 ;;;; flymake fringe indicators
-    `(flymake-error-bitmap '(flymake-double-exclamation-mark 
modus-themes-intense-red))
-    `(flymake-warning-bitmap '(exclamation-mark modus-themes-intense-yellow))
-    `(flymake-note-bitmap '(exclamation-mark modus-themes-intense-cyan))
+    `(flymake-error-bitmap '(flymake-double-exclamation-mark 
modus-themes-prominent-error))
+    `(flymake-warning-bitmap '(exclamation-mark 
modus-themes-prominent-warning))
+    `(flymake-note-bitmap '(exclamation-mark modus-themes-prominent-note))
 ;;;; highlight-changes
     `(highlight-changes-colors nil)
     `(highlight-changes-face-list '(success warning error bold bold-italic))
diff --git a/etc/themes/modus-vivendi-deuteranopia-theme.el 
b/etc/themes/modus-vivendi-deuteranopia-theme.el
index 57241c59b96..60c3c62b38f 100644
--- a/etc/themes/modus-vivendi-deuteranopia-theme.el
+++ b/etc/themes/modus-vivendi-deuteranopia-theme.el
@@ -1,4 +1,4 @@
-;;; modus-vivendi-deuteranopia-theme.el --- Elegant, highly legible and 
customizable dark theme -*- lexical-binding:t -*-
+;;; modus-vivendi-deuteranopia-theme.el --- Deuteranopia-optimized theme with 
a black background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -43,7 +43,7 @@
     (require 'modus-themes))
 
   (deftheme modus-vivendi-deuteranopia
-    "Elegant, highly legible and customizable dark theme.
+    "Deuteranopia-optimized theme with a black background.
 This variant is optimized for users with red-green color
 deficiency (deuteranopia).  It conforms with the highest
 legibility standard for color contrast between background and
@@ -76,9 +76,9 @@ standard).")
       (green-cooler    "#00c06f")
       (green-faint     "#88ca9f")
       (green-intense   "#44df44")
-      (yellow          "#d0bc00")
-      (yellow-warmer   "#fec43f")
-      (yellow-cooler   "#dfaf7a")
+      (yellow          "#cabf00")
+      (yellow-warmer   "#ffa00f")
+      (yellow-cooler   "#d8af7a")
       (yellow-faint    "#d2b580")
       (yellow-intense  "#efef00")
       (blue            "#2fafff")
@@ -138,13 +138,13 @@ standard).")
 
 ;;; Graphs
 
-      (bg-graph-red-0     "#705c3c")
-      (bg-graph-red-1     "#504420")
-      (bg-graph-green-0   "#4f666f")
-      (bg-graph-green-1   "#204840")
+      (bg-graph-red-0     "#bf6000")
+      (bg-graph-red-1     "#733500")
+      (bg-graph-green-0   "#6fbf8f")
+      (bg-graph-green-1   "#2f5f4f")
       (bg-graph-yellow-0  "#c1c00a")
-      (bg-graph-yellow-1  "#6f6f00")
-      (bg-graph-blue-0    "#2fafef")
+      (bg-graph-yellow-1  "#7f6640")
+      (bg-graph-blue-0    "#0f90ef")
       (bg-graph-blue-1    "#1f2f8f")
       (bg-graph-magenta-0 "#7f7f8e")
       (bg-graph-magenta-1 "#4f4f5f")
@@ -222,13 +222,20 @@ standard).")
       (identifier yellow-faint)
 
       (err yellow-warmer)
-      (warning yellow-cooler)
+      (warning yellow)
       (info blue)
 
       (underline-err yellow-intense)
       (underline-warning magenta-faint)
       (underline-note cyan)
 
+      (bg-prominent-err bg-yellow-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-magenta-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
+
 ;;;; Code mappings
 
       (builtin magenta-warmer)
@@ -277,6 +284,7 @@ standard).")
       (date-event fg-alt)
       (date-holiday yellow-warmer)
       (date-now blue-faint)
+      (date-range fg-alt)
       (date-scheduled yellow-cooler)
       (date-weekday cyan)
       (date-weekend yellow-faint)
@@ -306,13 +314,22 @@ standard).")
 
       (mail-cite-0 blue-warmer)
       (mail-cite-1 yellow-cooler)
-      (mail-cite-2 blue-cooler)
+      (mail-cite-2 cyan-faint)
       (mail-cite-3 yellow)
       (mail-part blue)
       (mail-recipient blue)
       (mail-subject yellow-warmer)
       (mail-other cyan-faint)
 
+;;;; Mark mappings
+
+      (bg-mark-delete bg-yellow-subtle)
+      (fg-mark-delete yellow)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-magenta-subtle)
+      (fg-mark-other magenta-warmer)
+
 ;;;; Prompt mappings
 
       (fg-prompt blue)
@@ -343,6 +360,12 @@ standard).")
       (rainbow-7 blue-faint)
       (rainbow-8 magenta-faint)
 
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+      (bg-space-err bg-yellow-intense)
+
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
diff --git a/etc/themes/modus-vivendi-theme.el 
b/etc/themes/modus-vivendi-theme.el
index 5012f8fb7f8..70dd0f78675 100644
--- a/etc/themes/modus-vivendi-theme.el
+++ b/etc/themes/modus-vivendi-theme.el
@@ -1,4 +1,4 @@
-;;; modus-vivendi-theme.el --- Elegant, highly legible and customizable dark 
theme -*- lexical-binding:t -*-
+;;; modus-vivendi-theme.el --- Elegant, highly legible theme with a black 
background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -43,7 +43,7 @@
     (require 'modus-themes))
 
   (deftheme modus-vivendi
-    "Elegant, highly legible and customizable dark theme.
+    "Elegant, highly legible theme with a black background.
 Conforms with the highest legibility standard for color contrast
 between background and foreground in any given piece of text,
 which corresponds to a minimum contrast in relative luminance of
@@ -138,10 +138,10 @@ which corresponds to a minimum contrast in relative 
luminance of
 
       (bg-graph-red-0     "#b52c2c")
       (bg-graph-red-1     "#702020")
-      (bg-graph-green-0   "#4fd100")
+      (bg-graph-green-0   "#0fed00")
       (bg-graph-green-1   "#007800")
       (bg-graph-yellow-0  "#f1e00a")
-      (bg-graph-yellow-1  "#b08600")
+      (bg-graph-yellow-1  "#b08940")
       (bg-graph-blue-0    "#2fafef")
       (bg-graph-blue-1    "#1f2f8f")
       (bg-graph-magenta-0 "#bf94fe")
@@ -227,6 +227,13 @@ which corresponds to a minimum contrast in relative 
luminance of
       (underline-warning yellow)
       (underline-note cyan)
 
+      (bg-prominent-err bg-red-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-yellow-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
+
 ;;;; Code mappings
 
       (builtin magenta-warmer)
@@ -273,8 +280,9 @@ which corresponds to a minimum contrast in relative 
luminance of
       (date-common cyan)
       (date-deadline red)
       (date-event fg-alt)
-      (date-holiday magenta)
+      (date-holiday red-cooler)
       (date-now fg-main)
+      (date-range fg-alt)
       (date-scheduled yellow-warmer)
       (date-weekday cyan)
       (date-weekend red-faint)
@@ -311,6 +319,15 @@ which corresponds to a minimum contrast in relative 
luminance of
       (mail-subject magenta-warmer)
       (mail-other magenta-faint)
 
+;;;; Mark mappings
+
+      (bg-mark-delete bg-red-subtle)
+      (fg-mark-delete red-cooler)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-yellow-subtle)
+      (fg-mark-other yellow)
+
 ;;;; Prompt mappings
 
       (fg-prompt cyan-cooler)
@@ -341,6 +358,12 @@ which corresponds to a minimum contrast in relative 
luminance of
       (rainbow-7 blue-warmer)
       (rainbow-8 magenta-warmer)
 
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+      (bg-space-err bg-red-intense)
+
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
diff --git a/etc/themes/modus-vivendi-tinted-theme.el 
b/etc/themes/modus-vivendi-tinted-theme.el
index 79e7fc9e3d8..b6443bdf6cc 100644
--- a/etc/themes/modus-vivendi-tinted-theme.el
+++ b/etc/themes/modus-vivendi-tinted-theme.el
@@ -1,4 +1,4 @@
-;;; modus-vivendi-tinted-theme.el --- Elegant, highly legible and customizable 
dark theme -*- lexical-binding:t -*-
+;;; modus-vivendi-tinted-theme.el --- Elegant, highly legible theme with a 
night sky background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -43,7 +43,7 @@
     (require 'modus-themes))
 
   (deftheme modus-vivendi-tinted
-    "Elegant, highly legible and customizable dark theme.
+    "Elegant, highly legible theme with a night sky background.
 Conforms with the highest legibility standard for color contrast
 between background and foreground in any given piece of text,
 which corresponds to a minimum contrast in relative luminance of
@@ -132,10 +132,10 @@ which corresponds to a minimum contrast in relative 
luminance of
 
       (bg-graph-red-0     "#b52c2c")
       (bg-graph-red-1     "#702020")
-      (bg-graph-green-0   "#4fd100")
+      (bg-graph-green-0   "#0fed00")
       (bg-graph-green-1   "#007800")
       (bg-graph-yellow-0  "#f1e00a")
-      (bg-graph-yellow-1  "#b08600")
+      (bg-graph-yellow-1  "#b08940")
       (bg-graph-blue-0    "#2fafef")
       (bg-graph-blue-1    "#1f2f8f")
       (bg-graph-magenta-0 "#bf94fe")
@@ -227,6 +227,13 @@ which corresponds to a minimum contrast in relative 
luminance of
       (underline-warning yellow)
       (underline-note cyan)
 
+      (bg-prominent-err bg-red-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-yellow-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
+
 ;;;; Code mappings
 
       (builtin magenta-warmer)
@@ -273,8 +280,9 @@ which corresponds to a minimum contrast in relative 
luminance of
       (date-common cyan)
       (date-deadline red)
       (date-event fg-alt)
-      (date-holiday magenta)
+      (date-holiday red-cooler)
       (date-now fg-main)
+      (date-range fg-alt)
       (date-scheduled yellow-warmer)
       (date-weekday cyan)
       (date-weekend red-faint)
@@ -311,10 +319,20 @@ which corresponds to a minimum contrast in relative 
luminance of
       (mail-subject magenta-warmer)
       (mail-other magenta-faint)
 
+;;;; Mark mappings
+
+      (bg-mark-delete bg-red-subtle)
+      (fg-mark-delete red-cooler)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-yellow-subtle)
+      (fg-mark-other yellow)
+
 ;;;; Prompt mappings
 
       (fg-prompt cyan-cooler)
       (bg-prompt unspecified)
+      (bg-space-err bg-red-intense)
 
 ;;;; Prose mappings
 
@@ -341,6 +359,11 @@ which corresponds to a minimum contrast in relative 
luminance of
       (rainbow-7 blue-warmer)
       (rainbow-8 magenta-warmer)
 
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
diff --git a/etc/themes/modus-vivendi-theme.el 
b/etc/themes/modus-vivendi-tritanopia-theme.el
similarity index 62%
copy from etc/themes/modus-vivendi-theme.el
copy to etc/themes/modus-vivendi-tritanopia-theme.el
index 5012f8fb7f8..0d09989e2a7 100644
--- a/etc/themes/modus-vivendi-theme.el
+++ b/etc/themes/modus-vivendi-tritanopia-theme.el
@@ -1,4 +1,4 @@
-;;; modus-vivendi-theme.el --- Elegant, highly legible and customizable dark 
theme -*- lexical-binding:t -*-
+;;; modus-vivendi-tritanopia-theme.el --- Tritanopia-optimized theme with a 
black background -*- lexical-binding:t -*-
 
 ;; Copyright (C) 2019-2023  Free Software Foundation, Inc.
 
@@ -42,14 +42,16 @@
                (require-theme 'modus-themes t))
     (require 'modus-themes))
 
-  (deftheme modus-vivendi
-    "Elegant, highly legible and customizable dark theme.
-Conforms with the highest legibility standard for color contrast
-between background and foreground in any given piece of text,
-which corresponds to a minimum contrast in relative luminance of
-7:1 (WCAG AAA standard).")
+  (deftheme modus-vivendi-tritanopia
+    "Tritanopia-optimized theme with a black background.
+This variant is optimized for users with blue-yellow color
+deficiency (tritanopia).  It conforms with the highest
+legibility standard for color contrast between background and
+foreground in any given piece of text, which corresponds to a
+minimum contrast in relative luminance of 7:1 (WCAG AAA
+standard).")
 
-  (defconst modus-vivendi-palette
+  (defconst modus-vivendi-tritanopia-palette
     '(
 ;;; Basic values
 
@@ -65,18 +67,18 @@ which corresponds to a minimum contrast in relative 
luminance of
 ;;; Common accent foregrounds
 
       (red             "#ff5f59")
-      (red-warmer      "#ff6b55")
-      (red-cooler      "#ff7f9f")
-      (red-faint       "#ff9580")
+      (red-warmer      "#ff6740")
+      (red-cooler      "#ff6f9f")
+      (red-faint       "#ff9070")
       (red-intense     "#ff5f5f")
       (green           "#44bc44")
       (green-warmer    "#70b900")
       (green-cooler    "#00c06f")
       (green-faint     "#88ca9f")
       (green-intense   "#44df44")
-      (yellow          "#d0bc00")
-      (yellow-warmer   "#fec43f")
-      (yellow-cooler   "#dfaf7a")
+      (yellow          "#cabf00")
+      (yellow-warmer   "#ffa00f")
+      (yellow-cooler   "#d8af7a")
       (yellow-faint    "#d2b580")
       (yellow-intense  "#efef00")
       (blue            "#2fafff")
@@ -88,11 +90,11 @@ which corresponds to a minimum contrast in relative 
luminance of
       (magenta-warmer  "#f78fe7")
       (magenta-cooler  "#b6a0ff")
       (magenta-faint   "#caa6df")
-      (magenta-intense "#ff66ff")
+      (magenta-intense "#ef7fff")
       (cyan            "#00d3d0")
-      (cyan-warmer     "#4ae2f0")
+      (cyan-warmer     "#4ae2ff")
       (cyan-cooler     "#6ae4b9")
-      (cyan-faint      "#9ac8e0")
+      (cyan-faint      "#7fdbdf")
       (cyan-intense    "#00eff0")
 
 ;;; Uncommon accent foregrounds
@@ -138,40 +140,40 @@ which corresponds to a minimum contrast in relative 
luminance of
 
       (bg-graph-red-0     "#b52c2c")
       (bg-graph-red-1     "#702020")
-      (bg-graph-green-0   "#4fd100")
-      (bg-graph-green-1   "#007800")
-      (bg-graph-yellow-0  "#f1e00a")
-      (bg-graph-yellow-1  "#b08600")
-      (bg-graph-blue-0    "#2fafef")
-      (bg-graph-blue-1    "#1f2f8f")
-      (bg-graph-magenta-0 "#bf94fe")
-      (bg-graph-magenta-1 "#5f509f")
-      (bg-graph-cyan-0    "#47dfea")
+      (bg-graph-green-0   "#afd1c0")
+      (bg-graph-green-1   "#607a8f")
+      (bg-graph-yellow-0  "#facfd6")
+      (bg-graph-yellow-1  "#b57b85")
+      (bg-graph-blue-0    "#4f9fdf")
+      (bg-graph-blue-1    "#004559")
+      (bg-graph-magenta-0 "#b6427f")
+      (bg-graph-magenta-1 "#7f506f")
+      (bg-graph-cyan-0    "#57dfea")
       (bg-graph-cyan-1    "#00808f")
 
 ;;; Special purpose
 
-      (bg-completion       "#2f447f")
-      (bg-hover            "#004f70")
-      (bg-hover-secondary  "#654a39")
+      (bg-completion       "#004253")
+      (bg-hover            "#8e3e3b")
+      (bg-hover-secondary  "#00405f")
       (bg-hl-line          "#2f3849")
       (bg-region           "#5a5a5a")
       (fg-region           "#ffffff")
 
-      (bg-char-0 "#0050af")
-      (bg-char-1 "#7f1f7f")
-      (bg-char-2 "#625a00")
+      (bg-char-0 "#922a00")
+      (bg-char-1 "#4f3f7f")
+      (bg-char-2 "#00709f")
 
-      (bg-mode-line-active        "#505050")
-      (fg-mode-line-active        "#ffffff")
-      (border-mode-line-active    "#959595")
+      (bg-mode-line-active        "#003c52")
+      (fg-mode-line-active        "#f0f0f0")
+      (border-mode-line-active    "#5f8fb4")
       (bg-mode-line-inactive      "#2d2d2d")
       (fg-mode-line-inactive      "#969696")
       (border-mode-line-inactive  "#606060")
 
-      (modeline-err     "#ffa9bf")
-      (modeline-warning "#dfcf43")
-      (modeline-info    "#9fefff")
+      (modeline-err     "#ff7fbf")
+      (modeline-warning "#df9f93")
+      (modeline-info    "#4fcfef")
 
       (bg-tab-bar      "#313131")
       (bg-tab-current  "#000000")
@@ -179,19 +181,19 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;; Diffs
 
-      (bg-added           "#00381f")
-      (bg-added-faint     "#002910")
-      (bg-added-refine    "#034f2f")
-      (bg-added-fringe    "#237f3f")
-      (fg-added           "#a0e0a0")
-      (fg-added-intense   "#80e080")
+      (bg-added           "#004254")
+      (bg-added-faint     "#003042")
+      (bg-added-refine    "#004f7f")
+      (bg-added-fringe    "#008fcf")
+      (fg-added           "#9fdfdf")
+      (fg-added-intense   "#50c0ef")
 
-      (bg-changed         "#363300")
-      (bg-changed-faint   "#2a1f00")
-      (bg-changed-refine  "#4a4a00")
-      (bg-changed-fringe  "#8a7a00")
-      (fg-changed         "#efef80")
-      (fg-changed-intense "#c0b05f")
+      (bg-changed         "#2f123f")
+      (bg-changed-faint   "#1f022f")
+      (bg-changed-refine  "#3f325f")
+      (bg-changed-fringe  "#7f55a0")
+      (fg-changed         "#e3cfff")
+      (fg-changed-intense "#cf9fe2")
 
       (bg-removed         "#4f1119")
       (bg-removed-faint   "#380a0f")
@@ -213,42 +215,49 @@ which corresponds to a minimum contrast in relative 
luminance of
 ;;;; General mappings
 
       (fringe bg-dim)
-      (cursor fg-main)
+      (cursor red-intense)
 
-      (keybind blue-cooler)
-      (name magenta)
-      (identifier yellow-faint)
+      (keybind red)
+      (name red-cooler)
+      (identifier red-faint)
 
-      (err red)
-      (warning yellow-warmer)
-      (info cyan-cooler)
+      (err red-warmer)
+      (warning magenta)
+      (info cyan)
 
       (underline-err red-intense)
-      (underline-warning yellow)
-      (underline-note cyan)
+      (underline-warning magenta-intense)
+      (underline-note cyan-intense)
+
+      (bg-prominent-err bg-red-intense)
+      (fg-prominent-err fg-main)
+      (bg-prominent-warning bg-magenta-intense)
+      (fg-prominent-warning fg-main)
+      (bg-prominent-note bg-cyan-intense)
+      (fg-prominent-note fg-main)
 
 ;;;; Code mappings
 
-      (builtin magenta-warmer)
-      (comment fg-dim)
-      (constant blue-cooler)
-      (docstring cyan-faint)
+      (builtin magenta)
+      (comment red-faint)
+      (constant green-faint)
+      (docstring fg-alt)
       (docmarkup magenta-faint)
-      (fnname magenta)
-      (keyword magenta-cooler)
-      (preprocessor red-cooler)
-      (string blue-warmer)
-      (type cyan-cooler)
-      (variable cyan)
-      (rx-construct green-cooler)
+      (fnname cyan-warmer)
+      (keyword red-cooler)
+      (preprocessor red-warmer)
+      (string cyan)
+      (type blue-warmer)
+      (variable cyan-cooler)
+      (rx-construct red)
       (rx-backslash magenta)
 
 ;;;; Accent mappings
 
-      (accent-0 blue-cooler)
-      (accent-1 magenta-warmer)
+      (accent-0 cyan)
+      (accent-1 red-warmer)
       (accent-2 cyan-cooler)
-      (accent-3 yellow)
+      (accent-3 magenta)
 
 ;;;; Button mappings
 
@@ -259,10 +268,10 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Completion mappings
 
-      (fg-completion-match-0 blue-cooler)
-      (fg-completion-match-1 magenta-warmer)
-      (fg-completion-match-2 cyan-cooler)
-      (fg-completion-match-3 yellow)
+      (fg-completion-match-0 cyan)
+      (fg-completion-match-1 red-warmer)
+      (fg-completion-match-2 magenta)
+      (fg-completion-match-3 cyan-cooler)
       (bg-completion-match-0 unspecified)
       (bg-completion-match-1 unspecified)
       (bg-completion-match-2 unspecified)
@@ -270,12 +279,13 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Date mappings
 
-      (date-common cyan)
+      (date-common cyan-cooler)
       (date-deadline red)
       (date-event fg-alt)
-      (date-holiday magenta)
+      (date-holiday red-intense)
       (date-now fg-main)
-      (date-scheduled yellow-warmer)
+      (date-range fg-alt)
+      (date-scheduled magenta)
       (date-weekday cyan)
       (date-weekend red-faint)
 
@@ -288,13 +298,13 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Link mappings
 
-      (fg-link blue-warmer)
+      (fg-link cyan)
       (bg-link unspecified)
-      (underline-link blue-warmer)
+      (underline-link cyan)
 
-      (fg-link-symbolic cyan)
+      (fg-link-symbolic cyan-cooler)
       (bg-link-symbolic unspecified)
-      (underline-link-symbolic cyan)
+      (underline-link-symbolic cyan-cooler)
 
       (fg-link-visited magenta)
       (bg-link-visited unspecified)
@@ -302,14 +312,23 @@ which corresponds to a minimum contrast in relative 
luminance of
 
 ;;;; Mail mappings
 
-      (mail-cite-0 blue-warmer)
-      (mail-cite-1 yellow-cooler)
-      (mail-cite-2 cyan-cooler)
-      (mail-cite-3 red-cooler)
-      (mail-part blue)
-      (mail-recipient magenta-cooler)
-      (mail-subject magenta-warmer)
-      (mail-other magenta-faint)
+      (mail-cite-0 cyan-faint)
+      (mail-cite-1 red-faint)
+      (mail-cite-2 magenta-warmer)
+      (mail-cite-3 cyan-warmer)
+      (mail-part cyan-cooler)
+      (mail-recipient cyan)
+      (mail-subject red-cooler)
+      (mail-other cyan)
+
+;;;; Mark mappings
+
+      (bg-mark-delete bg-red-subtle)
+      (fg-mark-delete red)
+      (bg-mark-select bg-cyan-subtle)
+      (fg-mark-select cyan)
+      (bg-mark-other bg-magenta-subtle)
+      (fg-mark-other magenta-warmer)
 
 ;;;; Prompt mappings
 
@@ -319,37 +338,43 @@ which corresponds to a minimum contrast in relative 
luminance of
 ;;;; Prose mappings
 
       (prose-block fg-dim)
-      (prose-code cyan-cooler)
-      (prose-done green)
-      (prose-macro magenta-cooler)
+      (prose-code cyan)
+      (prose-done cyan)
+      (prose-macro red-warmer)
       (prose-metadata fg-dim)
       (prose-metadata-value fg-alt)
       (prose-table fg-alt)
-      (prose-tag magenta-faint)
+      (prose-tag fg-alt)
       (prose-todo red)
       (prose-verbatim magenta-warmer)
 
 ;;;; Rainbow mappings
 
-      (rainbow-0 fg-main)
-      (rainbow-1 magenta-intense)
-      (rainbow-2 cyan-intense)
-      (rainbow-3 red-warmer)
-      (rainbow-4 yellow-intense)
-      (rainbow-5 magenta-cooler)
-      (rainbow-6 green-intense)
-      (rainbow-7 blue-warmer)
-      (rainbow-8 magenta-warmer)
+      (rainbow-0 cyan)
+      (rainbow-1 red)
+      (rainbow-2 cyan-warmer)
+      (rainbow-3 red-cooler)
+      (rainbow-4 cyan-cooler)
+      (rainbow-5 magenta)
+      (rainbow-6 cyan-faint)
+      (rainbow-7 magenta-faint)
+      (rainbow-8 red-faint)
+
+;;;; Space mappings
+
+      (bg-space unspecified)
+      (fg-space border)
+      (bg-space-err bg-red-intense)
 
 ;;;; Heading mappings
 
       (fg-heading-0 cyan-cooler)
       (fg-heading-1 fg-main)
-      (fg-heading-2 yellow-faint)
-      (fg-heading-3 blue-faint)
+      (fg-heading-2 red-faint)
+      (fg-heading-3 cyan-faint)
       (fg-heading-4 magenta)
       (fg-heading-5 green-faint)
-      (fg-heading-6 red-faint)
+      (fg-heading-6 magenta-faint)
       (fg-heading-7 cyan-faint)
       (fg-heading-8 fg-dim)
 
@@ -372,7 +397,7 @@ which corresponds to a minimum contrast in relative 
luminance of
       (overline-heading-6 unspecified)
       (overline-heading-7 unspecified)
       (overline-heading-8 unspecified))
-    "The entire palette of the `modus-vivendi' theme.
+    "The entire palette of the `modus-vivendi-tritanopia' theme.
 
 Named colors have the form (COLOR-NAME HEX-VALUE) with the former
 as a symbol and the latter as a string.
@@ -381,9 +406,8 @@ Semantic color mappings have the form (MAPPING-NAME 
COLOR-NAME)
 with both as symbols.  The latter is a named color that already
 exists in the palette and is associated with a HEX-VALUE.")
 
-
-  (defcustom modus-vivendi-palette-overrides nil
-    "Overrides for `modus-vivendi-palette'.
+  (defcustom modus-vivendi-tritanopia-palette-overrides nil
+    "Overrides for `modus-vivendi-tritanopia-palette'.
 
 Mirror the elements of the aforementioned palette, overriding
 their value.
@@ -405,13 +429,13 @@ represents."
     :initialize #'custom-initialize-default
     :link '(info-link "(modus-themes) Palette overrides"))
 
-  (modus-themes-theme modus-vivendi
-                      modus-vivendi-palette
-                      modus-vivendi-palette-overrides)
+  (modus-themes-theme modus-vivendi-tritanopia
+                      modus-vivendi-tritanopia-palette
+                      modus-vivendi-tritanopia-palette-overrides)
 
-  (provide-theme 'modus-vivendi))
+  (provide-theme 'modus-vivendi-tritanopia))
 
 ;;;###theme-autoload
-(put 'modus-vivendi 'theme-properties '(:background-mode dark :kind 
color-scheme :family modus))
+(put 'modus-vivendi-tritanopia 'theme-properties '(:background-mode dark :kind 
color-scheme :family modus))
 
-;;; modus-vivendi-theme.el ends here
+;;; modus-vivendi-tritanopia-theme.el ends here
diff --git a/lisp/emacs-lisp/comp-cstr.el b/lisp/emacs-lisp/comp-cstr.el
index e9132552506..416ca7f11b0 100644
--- a/lisp/emacs-lisp/comp-cstr.el
+++ b/lisp/emacs-lisp/comp-cstr.el
@@ -102,17 +102,23 @@ Integer values are handled in the `range' slot.")
               obarray)
     res))
 
+(defun comp--compute-typeof-types ()
+  (append comp--typeof-builtin-types
+          (mapcar #'comp--cl-class-hierarchy (comp--all-classes))))
+
+(defun comp--compute--pred-type-h ()
+  (cl-loop with h = (make-hash-table :test #'eq)
+          for class-name in (comp--all-classes)
+           for pred = (get class-name 'cl-deftype-satisfies)
+           when pred
+             do (puthash pred class-name h)
+          finally return h))
+
 (cl-defstruct comp-cstr-ctxt
-  (typeof-types (append comp--typeof-builtin-types
-                        (mapcar #'comp--cl-class-hierarchy 
(comp--all-classes)))
+  (typeof-types (comp--compute-typeof-types)
                 :type list
                 :documentation "Type hierarchy.")
-  (pred-type-h (cl-loop with h = (make-hash-table :test #'eq)
-                       for class-name in (comp--all-classes)
-                        for pred = (get class-name 'cl-deftype-satisfies)
-                        when pred
-                          do (puthash pred class-name h)
-                       finally return h)
+  (pred-type-h (comp--compute--pred-type-h)
                :type hash-table
                :documentation "Hash pred -> type.")
   (union-typesets-mem (make-hash-table :test #'equal) :type hash-table
@@ -135,6 +141,15 @@ Integer values are handled in the `range' slot.")
                     :documentation "Serve memoization for
 `intersection-mem'."))
 
+(defun comp-cstr-ctxt-update-type-slots (ctxt)
+  "Update the type related slots of CTXT.
+This must run after byte compilation in order to account for user
+defined types."
+  (setf (comp-cstr-ctxt-typeof-types ctxt)
+        (comp--compute-typeof-types))
+  (setf (comp-cstr-ctxt-pred-type-h ctxt)
+        (comp--compute--pred-type-h)))
+
 (defmacro with-comp-cstr-accessors (&rest body)
   "Define some quick accessor to reduce code vergosity in BODY."
   (declare (debug (form body))
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 0556e69051d..ec51f805c2b 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -1431,11 +1431,13 @@ clashes."
   "Byte-compile and spill the LAP representation for INPUT.
 If INPUT is a symbol, it is the function-name to be compiled.
 If INPUT is a string, it is the filename to be compiled."
-  (let ((byte-native-compiling t)
-        (byte-to-native-lambdas-h (make-hash-table :test #'eq))
-        (byte-to-native-top-level-forms ())
-        (byte-to-native-plist-environment ()))
-    (comp-spill-lap-function input)))
+  (let* ((byte-native-compiling t)
+         (byte-to-native-lambdas-h (make-hash-table :test #'eq))
+         (byte-to-native-top-level-forms ())
+         (byte-to-native-plist-environment ())
+         (res (comp-spill-lap-function input)))
+    (comp-cstr-ctxt-update-type-slots comp-ctxt)
+    res))
 
 
 ;;; Limplification pass specific code.
@@ -2548,19 +2550,19 @@ TARGET-BB-SYM is the symbol name of the target block."
     for insns-seq on (comp-block-insns b)
     do
     (pcase insns-seq
-      ;; (`((set ,(and (pred comp-mvar-p) mvar-tested-copy)
-      ;;         ,(and (pred comp-mvar-p) mvar-tested))
-      ;;    (set ,(and (pred comp-mvar-p) mvar-1)
-      ;;         (call type-of ,(and (pred comp-mvar-p) mvar-tested-copy)))
-      ;;    (set ,(and (pred comp-mvar-p) mvar-2)
-      ;;         (call symbol-value ,(and (pred comp-cstr-cl-tag-p) mvar-tag)))
-      ;;    (set ,(and (pred comp-mvar-p) mvar-3)
-      ;;         (call memq ,(and (pred comp-mvar-p) mvar-1) ,(and (pred 
comp-mvar-p) mvar-2)))
-      ;;    (cond-jump ,(and (pred comp-mvar-p) mvar-3) ,(pred comp-mvar-p) 
,bb1 ,bb2))
-      ;;  (push  `(assume ,mvar-tested ,(make-comp-mvar :type 
(comp-cstr-cl-tag mvar-tag)))
-      ;;         (comp-block-insns (comp-add-cond-cstrs-target-block b bb2)))
-      ;;  (push  `(assume ,mvar-tested ,(make-comp-mvar :type 
(comp-cstr-cl-tag mvar-tag) :neg t))
-      ;;         (comp-block-insns (comp-add-cond-cstrs-target-block b bb1))))
+      (`((set ,(and (pred comp-mvar-p) mvar-tested-copy)
+              ,(and (pred comp-mvar-p) mvar-tested))
+         (set ,(and (pred comp-mvar-p) mvar-1)
+              (call type-of ,(and (pred comp-mvar-p) mvar-tested-copy)))
+         (set ,(and (pred comp-mvar-p) mvar-2)
+              (call symbol-value ,(and (pred comp-cstr-cl-tag-p) mvar-tag)))
+         (set ,(and (pred comp-mvar-p) mvar-3)
+              (call memq ,(and (pred comp-mvar-p) mvar-1) ,(and (pred 
comp-mvar-p) mvar-2)))
+         (cond-jump ,(and (pred comp-mvar-p) mvar-3) ,(pred comp-mvar-p) ,bb1 
,bb2))
+       (push  `(assume ,mvar-tested ,(make-comp-mvar :type (comp-cstr-cl-tag 
mvar-tag)))
+              (comp-block-insns (comp-add-cond-cstrs-target-block b bb2)))
+       (push  `(assume ,mvar-tested ,(make-comp-mvar :type (comp-cstr-cl-tag 
mvar-tag) :neg t))
+              (comp-block-insns (comp-add-cond-cstrs-target-block b bb1))))
       (`((set ,(and (pred comp-mvar-p) cmp-res)
               (,(pred comp-call-op-p)
                ,(and (or (pred comp-equality-fun-p)
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 4307dc3b860..33b93ff6744 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -128,6 +128,7 @@ longer than `erc-fill-column'."
   ;; things hard to maintain.
   '((nicknames 0 erc-button-buttonize-nicks erc-nick-popup 0)
     (erc-button-url-regexp 0 t browse-url-button-open-url 0)
+    ;; ("<URL: *\\([^<> ]+\\) *>" 0 t browse-url-button-open-url 1)
 ;;; ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3)
     ;; emacs internal
     ("[`‘]\\([a-zA-Z][-a-zA-Z_0-9!*<=>+]+\\)['’]"
@@ -629,15 +630,13 @@ greater than `point-min' with a text property of 
`erc-callback'.")
   "Go to the ARGth next button."
   (declare (advertised-calling-convention (arg) "30.1"))
   (interactive "p")
-  (setq arg (pcase arg ((pred listp) (prefix-numeric-value arg)) (_ arg)))
-  (erc--button-next arg))
+  (erc--button-next (or arg 1)))
 
 (defun erc-button-previous (&optional arg)
   "Go to ARGth previous button."
   (declare (advertised-calling-convention (arg) "30.1"))
   (interactive "p")
-  (setq arg (pcase arg ((pred listp) (prefix-numeric-value arg)) (_ arg)))
-  (erc--button-next (- arg)))
+  (erc--button-next (- (or arg 1))))
 
 (defun erc-button-previous-of-nick (arg)
   "Go to ARGth previous button for nick at point."
diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el
index 2b58a7c56ed..d3106da4017 100644
--- a/lisp/erc/erc-log.el
+++ b/lisp/erc/erc-log.el
@@ -124,6 +124,7 @@ custom function which returns the directory part and set
 (defcustom erc-truncate-buffer-on-save nil
   "Erase the contents of any ERC (channel, query, server) buffer when it is 
saved."
   :type 'boolean)
+(make-obsolete 'erc-truncate-buffer-on-save 'erc-cmd-CLEAR "30.1")
 
 (defcustom erc-enable-logging t
   "If non-nil, ERC will log IRC conversations.
@@ -230,6 +231,7 @@ also be a predicate function.  To only log when you are not 
set away, use:
    (add-hook 'erc-part-hook #'erc-conditional-save-buffer)
    ;; append, so that 'erc-initialize-log-marker runs first
    (add-hook 'erc-connect-pre-hook #'erc-log-setup-logging 'append)
+   (add-hook 'erc--pre-clear-functions #'erc-save-buffer-in-logs)
    (dolist (buffer (erc-buffer-list))
      (erc-log-setup-logging buffer))
    (erc--modify-local-map t "C-c C-l" #'erc-save-buffer-in-logs))
@@ -242,6 +244,7 @@ also be a predicate function.  To only log when you are not 
set away, use:
    (remove-hook 'erc-quit-hook #'erc-conditional-save-queries)
    (remove-hook 'erc-part-hook #'erc-conditional-save-buffer)
    (remove-hook 'erc-connect-pre-hook #'erc-log-setup-logging)
+   (remove-hook 'erc--pre-clear-functions #'erc-save-buffer-in-logs)
    (dolist (buffer (erc-buffer-list))
      (erc-log-disable-logging buffer))
    (erc--modify-local-map nil "C-c C-l" #'erc-save-buffer-in-logs)))
@@ -301,6 +304,8 @@ Returns nil if `erc-server-buffer-p' returns t."
   (dolist (buffer (erc-buffer-list))
     (erc-save-buffer-in-logs buffer)))
 
+(defvar erc-log--save-in-progress-p nil)
+
 ;;;###autoload
 (defun erc-logging-enabled (&optional buffer)
   "Return non-nil if logging is enabled for BUFFER.
@@ -310,6 +315,7 @@ is writable (it will be created as necessary) and
 `erc-enable-logging' returns a non-nil value."
   (or buffer (setq buffer (current-buffer)))
   (and erc-log-channels-directory
+       (not erc-log--save-in-progress-p)
        (or (functionp erc-log-channels-directory)
           (erc-directory-writable-p erc-log-channels-directory))
        (if (functionp erc-enable-logging)
@@ -399,7 +405,7 @@ automatically.
 You can save every individual message by putting this function on
 `erc-insert-post-hook'."
   (interactive)
-  (or buffer (setq buffer (current-buffer)))
+  (unless (bufferp buffer) (setq buffer (current-buffer)))
   (when (erc-logging-enabled buffer)
     (let ((file (erc-current-logfile buffer))
           (coding-system erc-log-file-coding-system))
@@ -423,10 +429,11 @@ You can save every individual message by putting this 
function on
                    (write-region start end file t 'nomessage))))
              (if (and erc-truncate-buffer-on-save
                       (called-interactively-p 'interactive))
-                 (progn
-                   (let ((inhibit-read-only t)) (erase-buffer))
-                   (move-marker erc-last-saved-position (point-max))
-                   (erc-display-prompt))
+                  (let ((erc-log--save-in-progress-p t))
+                    (erc-cmd-CLEAR)
+                    (erc-button--display-error-notice-with-keys
+                     (erc-server-buffer) "Option `%s' is deprecated."
+                     " Use /CLEAR instead." 'erc-truncate-buffer-on-save))
                (move-marker erc-last-saved-position
                             ;; If we place erc-last-saved-position at
                             ;; erc-insert-marker, because text gets
diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el
index 9191bbe5a2a..500f6f3c0c9 100644
--- a/lisp/erc/erc-stamp.el
+++ b/lisp/erc/erc-stamp.el
@@ -166,12 +166,14 @@ from entering them and instead jump over them."
    (add-hook 'erc-insert-modify-hook #'erc-add-timestamp t)
    (add-hook 'erc-send-modify-hook #'erc-add-timestamp t)
    (add-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect)
+   (add-hook 'erc--pre-clear-functions #'erc-stamp--reset-on-clear)
    (unless erc--updating-modules-p
      (erc-buffer-filter #'erc-munge-invisibility-spec)))
   ((remove-hook 'erc-mode-hook #'erc-munge-invisibility-spec)
    (remove-hook 'erc-insert-modify-hook #'erc-add-timestamp)
    (remove-hook 'erc-send-modify-hook #'erc-add-timestamp)
    (remove-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect)
+   (remove-hook 'erc--pre-clear-functions #'erc-stamp--reset-on-clear)
    (erc-with-all-buffers-of-server nil nil
      (kill-local-variable 'erc-timestamp-last-inserted)
      (kill-local-variable 'erc-timestamp-last-inserted-left)
@@ -584,6 +586,20 @@ enabled when the message was inserted."
 (defun erc--echo-ts-csf (_window _before dir)
   (erc-echo-timestamp dir (get-text-property (point) 'erc-timestamp)))
 
+(defun erc-stamp--update-saved-position (&rest _)
+  (remove-function (local 'erc-stamp--insert-date-function)
+                   #'erc-stamp--update-saved-position)
+  (move-marker erc-last-saved-position (1- (point))))
+
+(defun erc-stamp--reset-on-clear (pos)
+  "Forget last-inserted stamps when POS is at insert marker."
+  (when (= pos (1- erc-insert-marker))
+    (add-function :after (local 'erc-stamp--insert-date-function)
+                  #'erc-stamp--update-saved-position)
+    (setq erc-timestamp-last-inserted nil
+          erc-timestamp-last-inserted-left nil
+          erc-timestamp-last-inserted-right nil)))
+
 (provide 'erc-stamp)
 
 ;;; erc-stamp.el ends here
diff --git a/lisp/erc/erc-truncate.el b/lisp/erc/erc-truncate.el
index b8fd4ae2e14..8430a68d92b 100644
--- a/lisp/erc/erc-truncate.el
+++ b/lisp/erc/erc-truncate.el
@@ -50,9 +50,9 @@ This prevents the query buffer from getting too large, which 
can
 bring any grown Emacs to its knees after a few days worth of
 tracking heavy-traffic channels."
   ;;enable
-  ((add-hook 'erc-insert-post-hook #'erc-truncate-buffer))
+  ((add-hook 'erc-insert-done-hook #'erc-truncate-buffer))
   ;; disable
-  ((remove-hook 'erc-insert-post-hook #'erc-truncate-buffer)))
+  ((remove-hook 'erc-insert-done-hook #'erc-truncate-buffer)))
 
 ;;;###autoload
 (defun erc-truncate-buffer-to-size (size &optional buffer)
@@ -75,9 +75,11 @@ region is logged if `erc-logging-enabled' returns non-nil."
       (save-restriction
        (widen)
        (let ((end (- erc-insert-marker size)))
-         ;; truncate at line boundaries
+          ;; Truncate at message boundary (formerly line boundary
+          ;; before 5.6).
          (goto-char end)
-         (beginning-of-line)
+          (goto-char (or (previous-single-property-change (point) 'erc-command)
+                         (pos-bol)))
          (setq end (point))
          ;; try to save the current buffer using
          ;; `erc-save-buffer-in-logs'.  We use this, in case the
@@ -91,10 +93,7 @@ region is logged if `erc-logging-enabled' returns non-nil."
          ;; (not (memq 'erc-save-buffer-in-logs
          ;;             erc-insert-post-hook))
          ;; Comments?
-         (when (and (boundp 'erc-enable-logging)
-                    erc-enable-logging
-                    (erc-logging-enabled buffer))
-           (erc-save-buffer-in-logs))
+          (run-hook-with-args 'erc--pre-clear-functions end)
          ;; disable undoing for the truncating
          (buffer-disable-undo)
          (let ((inhibit-read-only t))
@@ -103,10 +102,10 @@ region is logged if `erc-logging-enabled' returns 
non-nil."
 
 ;;;###autoload
 (defun erc-truncate-buffer ()
-  "Truncates the current buffer to `erc-max-buffer-size'.
-Meant to be used in hooks, like `erc-insert-post-hook'."
+  "Truncate current buffer to `erc-max-buffer-size'."
   (interactive)
-  (erc-truncate-buffer-to-size erc-max-buffer-size))
+  (save-excursion
+    (erc-truncate-buffer-to-size erc-max-buffer-size)))
 
 (provide 'erc-truncate)
 ;;; erc-truncate.el ends here
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 495e25212ce..5a91285c1d1 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -144,6 +144,8 @@ concerning buffers."
 (declare-function word-at-point "thingatpt" (&optional no-properties))
 (autoload 'word-at-point "thingatpt") ; for hl-nicks
 
+(declare-function gnutls-negotiate "gnutls" (&rest rest))
+(declare-function socks-open-network-stream "socks" (name buffer host service))
 (declare-function url-host "url-parse" (cl-x))
 (declare-function url-password "url-parse" (cl-x))
 (declare-function url-portspec "url-parse" (cl-x))
@@ -2598,6 +2600,22 @@ PARAMETERS should be a sequence of keywords and values, 
per
     (setq args `(,name ,buffer ,host ,port ,@p))
     (apply #'open-network-stream args)))
 
+(defun erc-open-socks-tls-stream (name buffer host service &rest parameters)
+  "Connect to an IRC server via SOCKS proxy over TLS.
+Bind `erc-server-connect-function' to this function around calls
+to `erc-tls'.  See `erc-open-network-stream' for the meaning of
+NAME and BUFFER.  HOST should be a \".onion\" URL, SERVICE a TLS
+port number, and PARAMETERS a sequence of key/value pairs, per
+`open-network-stream'.  See Info node `(erc) SOCKS' for more
+info."
+  (require 'gnutls)
+  (require 'socks)
+  (let ((proc (socks-open-network-stream name buffer host service))
+        (cert-info (plist-get parameters :client-certificate)))
+    (gnutls-negotiate :process proc
+                      :hostname host
+                      :keylist (and cert-info (list cert-info)))))
+
 ;;; Displaying error messages
 
 (defun erc-error (&rest args)
@@ -2787,6 +2805,18 @@ this option to nil."
           (cl-assert (< erc-insert-marker erc-input-marker))
           (cl-assert (= (field-end erc-insert-marker) erc-input-marker)))))
 
+(defun erc--refresh-prompt ()
+  "Re-render ERC's prompt when the option `erc-prompt' is a function."
+  (erc--assert-input-bounds)
+  (when (functionp erc-prompt)
+    (save-excursion
+      (goto-char erc-insert-marker)
+      ;; Avoid `erc-prompt' (the named function), which appends a
+      ;; space, and `erc-display-prompt', which propertizes all but
+      ;; that space.
+      (insert-and-inherit (funcall erc-prompt))
+      (delete-region (point) (1- erc-input-marker)))))
+
 (defun erc-display-line-1 (string buffer)
   "Display STRING in `erc-mode' BUFFER.
 Auxiliary function used in `erc-display-line'.  The line gets filtered to
@@ -2830,7 +2860,7 @@ If STRING is nil, the function does nothing."
                   (when erc-remove-parsed-property
                     (remove-text-properties (point-min) (point-max)
                                             '(erc-parsed nil))))
-                (erc--assert-input-bounds)))))
+                (erc--refresh-prompt)))))
         (run-hooks 'erc-insert-done-hook)
         (erc-update-undo-list (- (or (marker-position erc-insert-marker)
                                      (point-max))
@@ -3406,10 +3436,17 @@ If no USER argument is specified, list the contents of 
`erc-ignore-list'."
       (erc-with-server-buffer
         (setq erc-ignore-list (delete user erc-ignore-list))))))
 
+(defvar erc--pre-clear-functions nil
+  "Abnormal hook run when truncating buffers.
+Called with position indicating boundary of interval to be excised.")
+
 (defun erc-cmd-CLEAR ()
   "Clear the window content."
   (let ((inhibit-read-only t))
-    (delete-region (point-min) (line-beginning-position)))
+    (run-hook-with-args 'erc--pre-clear-functions (1- erc-insert-marker))
+    ;; Ostensibly, `line-beginning-position' is for use in lisp code.
+    (delete-region (point-min) (min (line-beginning-position)
+                                    (1- erc-insert-marker))))
   t)
 (put 'erc-cmd-CLEAR 'process-not-needed t)
 
@@ -4755,11 +4792,11 @@ This places `point' just after the prompt, or at the 
beginning of the line."
   "Functions to try when user hits \\`TAB' outside of input area.
 Called with a numeric prefix arg.")
 
-(defun erc-tab (&optional arg)
+(defun erc-tab (arg)
   "Call `completion-at-point' when typing in the input area.
-Otherwise call members of `erc--tab-functions' with raw prefix
-ARG until one of them returns non-nil."
-  (interactive "P")
+Otherwise call members of `erc--tab-functions' with a numeric
+prefix ARG until one of them returns non-nil."
+  (interactive "p")
   (if (>= (point) erc-input-marker)
       (completion-at-point)
     (run-hook-with-args-until-success 'erc--tab-functions arg)))
@@ -6452,7 +6489,7 @@ Return non-nil only if we actually send anything."
           (narrow-to-region insert-position (point))
           (run-hooks 'erc-send-modify-hook)
           (run-hooks 'erc-send-post-hook))
-        (erc--assert-input-bounds)))))
+        (erc--refresh-prompt)))))
 
 (defun erc-command-symbol (command)
   "Return the ERC command symbol for COMMAND if it exists and is bound."
@@ -7410,6 +7447,51 @@ If BUFFER is nil, update the mode line in all ERC 
buffers."
     (goto-char (point-min))
     (insert "X-Debbugs-CC: emacs-erc@gnu.org\n")))
 
+(defconst erc--news-url
+  "https://git.savannah.gnu.org/cgit/emacs.git/plain/etc/ERC-NEWS";)
+
+(defvar erc--news-temp-file nil)
+
+(defun erc-news (arg)
+  "Show ERC news in a manner similar to `view-emacs-news'.
+With ARG, download and display the latest revision, which may
+contain more up-to-date information, even for older versions."
+  (interactive "P")
+  (find-file
+   (or (and arg erc--news-temp-file
+            (time-less-p (current-time) (car erc--news-temp-file))
+            (cdr erc--news-temp-file))
+       (and arg
+            (with-current-buffer (url-retrieve-synchronously erc--news-url)
+              (goto-char (point-min))
+              (search-forward "200 OK" (pos-eol))
+              (search-forward "\n\n")
+              (delete-region (point-min) (point))
+              (let ((tempfile (make-temp-file "erc-news.")))
+                (write-region (point-min) (point-max) tempfile)
+                (kill-buffer)
+                (cdr (setq erc--news-temp-file
+                           (cons (time-add (current-time) (* 60 60 12))
+                                 tempfile))))))
+       (and-let* ((file (or (eval-when-compile (macroexp-file-name))
+                            (locate-library "erc")))
+                  (dir (file-name-directory file))
+                  (adjacent (expand-file-name "ERC-NEWS" dir))
+                  ((file-exists-p adjacent)))
+         adjacent)
+       (expand-file-name "ERC-NEWS" data-directory)))
+  (when (fboundp 'emacs-news-view-mode)
+    (emacs-news-view-mode))
+  (let ((v (mapcar #'number-to-string
+                   (seq-take-while #'natnump (version-to-list erc-version)))))
+    (while (and v
+                (goto-char (point-min))
+                (not (search-forward (concat "\014\n* Changes in ERC "
+                                             (string-join v "."))
+                                     nil t)))
+      (setq v (butlast v))))
+  (beginning-of-line))
+
 (defun erc-port-to-string (p)
   "Convert port P to a string.
 P may be an integer or a service name."
diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba
index 689573236da..5141c8919b1 100644
--- a/test/infra/Dockerfile.emba
+++ b/test/infra/Dockerfile.emba
@@ -83,6 +83,62 @@ RUN ./autogen.sh autoconf
 RUN ./configure
 RUN make bootstrap
 
+# Debian bullseye doesn't provide proper packages.  So we use Debian
+# sid for this.
+FROM debian:sid as emacs-tree-sitter
+
+# This corresponds to emacs-base.
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
+      libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev \
+      libdbus-1-dev libacl1-dev acl git texinfo gdb \
+    && rm -rf /var/lib/apt/lists/*
+
+# Install tree-sitter library.
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
+      libtree-sitter0 libtree-sitter-dev \
+    && rm -rf /var/lib/apt/lists/*
+
+COPY . /checkout
+WORKDIR /checkout
+RUN ./autogen.sh autoconf
+RUN ./configure --with-tree-sitter
+RUN make bootstrap
+
+# Install language grammars.
+RUN mkdir /usr/local/lib/tree-sitter
+RUN git config --global http.sslverify "false"
+# See https://github.com/emacs-tree-sitter/tree-sitter-langs/tree/master/repos
+RUN src/emacs -Q --batch \
+    --eval '(setq \
+      treesit-extra-load-path (list "/usr/local/lib/tree-sitter") \
+      treesit-language-source-alist \
+      (quote ((bash "https://github.com/tree-sitter/tree-sitter-bash";) \
+      (c "https://github.com/tree-sitter/tree-sitter-c";) \
+      (cmake "https://github.com/uyha/tree-sitter-cmake";) \
+      (cpp "https://github.com/tree-sitter/tree-sitter-cpp";) \
+      (css "https://github.com/tree-sitter/tree-sitter-css";) \
+      (elisp "https://github.com/Wilfred/tree-sitter-elisp";) \
+      (elixir "https://github.com/elixir-lang/tree-sitter-elixir";) \
+      (java "https://github.com/tree-sitter/tree-sitter-java";) \
+      (go "https://github.com/tree-sitter/tree-sitter-go";) \
+      (gomod "https://github.com/camdencheek/tree-sitter-go-mod";) \
+      (heex "https://github.com/phoenixframework/tree-sitter-heex";) \
+      (html "https://github.com/tree-sitter/tree-sitter-html";) \
+      (javascript "https://github.com/tree-sitter/tree-sitter-javascript"; 
"master" "src") \
+      (json "https://github.com/tree-sitter/tree-sitter-json";) \
+      (make "https://github.com/alemuller/tree-sitter-make";) \
+      (markdown "https://github.com/ikatyang/tree-sitter-markdown";) \
+      (python "https://github.com/tree-sitter/tree-sitter-python";) \
+      (ruby "https://github.com/tree-sitter/tree-sitter-ruby";) \
+      (toml "https://github.com/tree-sitter/tree-sitter-toml";) \
+      (tsx "https://github.com/tree-sitter/tree-sitter-typescript"; "master" 
"tsx/src") \
+      (typescript "https://github.com/tree-sitter/tree-sitter-typescript"; 
"master" "typescript/src") \
+      (yaml "https://github.com/ikatyang/tree-sitter-yaml";))))' \
+    --eval '(dolist (lang (mapcar (quote car) treesit-language-source-alist)) \
+      (treesit-install-language-grammar lang "/usr/local/lib/tree-sitter"))'
+
 FROM emacs-base as emacs-gnustep
 
 RUN apt-get update && \
diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml
index d1fef0187d4..9a862dcba3c 100644
--- a/test/infra/gitlab-ci.yml
+++ b/test/infra/gitlab-ci.yml
@@ -176,6 +176,16 @@ default:
         - test/infra/*
         - test/lisp/progmodes/eglot-tests.el
 
+.tree-sitter-template:
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "web"'
+    - if: '$CI_PIPELINE_SOURCE == "schedule"'
+      changes:
+        - "**.in"
+        - lisp/progmodes/*-ts-mode.el
+        - test/infra/*
+        - test/lisp/progmodes/*-ts-mode-tests.el
+
 .native-comp-template:
   rules:
     - if: '$CI_PIPELINE_SOURCE == "web"'
@@ -256,6 +266,31 @@ test-eglot:
     # This is needed in order to get a JUnit test report.
     make_params: '-k -C test check-expensive 
LOGFILES="lisp/progmodes/eglot-tests.log"'
 
+build-image-tree-sitter:
+  stage: platform-images
+  extends: [.job-template, .build-template, .tree-sitter-template]
+  variables:
+    target: emacs-tree-sitter
+
+test-tree-sitter:
+  stage: platforms
+  extends: [.job-template, .test-template, .tree-sitter-template]
+  needs:
+    - job: build-image-tree-sitter
+      optional: true
+  variables:
+    target: emacs-tree-sitter
+    # This is needed in order to get a JUnit test report.
+    files: >-
+      lisp/progmodes/c-ts-mode-tests.log
+      lisp/progmodes/elixir-ts-mode-tests.log
+      lisp/progmodes/go-ts-mode-tests.log
+      lisp/progmodes/heex-ts-mode-tests.log
+      lisp/progmodes/java-ts-mode-tests.log
+      lisp/progmodes/ruby-ts-mode-tests.log
+      lisp/progmodes/typescript-ts-mode-tests.log
+    make_params: '-k -C test check-expensive 
LD_LIBRARY_PATH=/usr/local/lib/tree-sitter LOGFILES="$files"'
+
 build-image-gnustep:
   stage: platform-images
   extends: [.job-template, .build-template, .gnustep-template]
diff --git a/test/lisp/erc/erc-scenarios-log.el 
b/test/lisp/erc/erc-scenarios-log.el
new file mode 100644
index 00000000000..c37e6b323aa
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-log.el
@@ -0,0 +1,207 @@
+;;; erc-scenarios-log.el --- erc-log scenarios -*- lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert-x)
+(eval-and-compile
+  (let ((load-path (cons (ert-resource-directory) load-path)))
+    (require 'erc-scenarios-common)))
+
+(require 'erc-log)
+(require 'erc-truncate)
+
+(defvar erc-timestamp-format-left)
+
+(ert-deftest erc-scenarios-log--kill-hook ()
+  :tags '(:expensive-test)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/assoc/bouncer-history")
+       (dumb-server (erc-d-run "localhost" t 'foonet))
+       (tempdir (make-temp-file "erc-tests-log." t nil nil))
+       (erc-log-channels-directory tempdir)
+       (erc-modules (cons 'log erc-modules))
+       (port (process-contact dumb-server :service))
+       (logfile (expand-file-name (format "#chan!tester@127.0.0.1:%d.txt" port)
+                                  tempdir))
+       (erc-server-flood-penalty 0.1)
+       (expect (erc-d-t-make-expecter)))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :password "foonet:changeme"
+                                :full-name "tester")
+        (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+        (funcall expect 5 "foonet")))
+
+    (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+      (funcall expect 10 "was created on")
+      (funcall expect 10 "please your lordship")
+      (with-current-buffer "foonet"
+        (delete-process erc-server-process)
+        (funcall expect 5 "failed"))
+      (should-not (file-exists-p logfile))
+      (kill-buffer)
+      (should (file-exists-p logfile)))
+
+    (with-temp-buffer
+      (insert-file-contents logfile)
+      (funcall expect 1 "You have joined")
+      (funcall expect 1 "Playback Complete.")
+      (funcall expect 1 "please your lordship"))
+
+    (erc-log-mode -1)
+    (if noninteractive
+        (delete-directory tempdir :recursive)
+      (add-hook 'kill-emacs-hook
+                (lambda () (delete-directory tempdir :recursive))))))
+
+;; This shows that, in addition to truncating the buffer, /clear also
+;; syncs the log.
+
+(ert-deftest erc-scenarios-log--clear-stamp ()
+  :tags '(:expensive-test)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/assoc/bouncer-history")
+       (dumb-server (erc-d-run "localhost" t 'foonet))
+       (tempdir (make-temp-file "erc-tests-log." t nil nil))
+       (erc-log-channels-directory tempdir)
+       (erc-modules (cons 'log erc-modules))
+       (erc-timestamp-format-left "\n[%a %b %e %Y @@STAMP@@]\n")
+       (port (process-contact dumb-server :service))
+       (logfile (expand-file-name (format "#chan!tester@127.0.0.1:%d.txt" port)
+                                  tempdir))
+       (erc-server-flood-penalty 0.1)
+       (expect (erc-d-t-make-expecter)))
+
+    (unless noninteractive
+      (add-hook 'kill-emacs-hook
+                (lambda () (delete-directory tempdir :recursive))))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :password "foonet:changeme"
+                                :full-name "tester")
+        (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+        (funcall expect 5 "foonet")))
+
+    (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+      (funcall expect 10 "@@STAMP@@")
+      (funcall expect 10 "Grows, lives")
+      (should-not (file-exists-p logfile))
+      (goto-char (point-max))
+      (erc-cmd-CLEAR)
+      (should (file-exists-p logfile))
+      (funcall expect 10 "please your lordship")
+      (ert-info ("Buffer truncated")
+        (goto-char (point-min))
+        (funcall expect 10 "@@STAMP@@" (point)) ; reset
+        (funcall expect -0.1 "Grows, lives")
+        (funcall expect 1 "For these two")))
+
+    (ert-info ("Current contents saved")
+      (with-temp-buffer
+        (insert-file-contents logfile)
+        (funcall expect 1 "@@STAMP@@")
+        (funcall expect 1 "You have joined")
+        (funcall expect 1 "Playback Complete.")
+        (funcall expect 1 "Grows, lives")
+        (funcall expect -0.01 "please your lordship")))
+
+    (ert-info ("Remainder saved, timestamp printed when option non-nil")
+      (with-current-buffer "foonet"
+        (delete-process erc-server-process)
+        (funcall expect 5 "failed"))
+      (kill-buffer "#chan")
+      (with-temp-buffer
+        (insert-file-contents logfile)
+        (funcall expect 1 "@@STAMP@@")
+        (funcall expect 1 "Grows, lives")
+        (funcall expect -0.01 "@@STAMP@@")
+        (forward-line 1) ; no blank, no timestamp
+        (should (looking-at (rx "<bob> alice: For these two hours,")))
+        (funcall expect 1 "please your lordship")))
+
+    (erc-log-mode -1)
+    (when noninteractive (delete-directory tempdir :recursive))))
+
+(ert-deftest erc-scenarios-log--truncate ()
+  :tags '(:expensive-test)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/assoc/bouncer-history")
+       (dumb-server (erc-d-run "localhost" t 'foonet))
+       (tempdir (make-temp-file "erc-tests-log." t nil nil))
+       (erc-log-channels-directory tempdir)
+       (erc-modules (cons 'truncate (cons 'log erc-modules)))
+       (erc-max-buffer-size 512)
+       (port (process-contact dumb-server :service))
+       (logchan (expand-file-name (format "#chan!tester@127.0.0.1:%d.txt" port)
+                                  tempdir))
+       (logserv (expand-file-name
+                 (format "127.0.0.1:%d!tester@127.0.0.1:%d.txt" port port)
+                 tempdir))
+       (erc-server-flood-penalty 0.1)
+       (expect (erc-d-t-make-expecter)))
+
+    (unless noninteractive
+      (add-hook 'kill-emacs-hook
+                (lambda () (delete-directory tempdir :recursive))))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :password "foonet:changeme"
+                                :full-name "tester")
+        (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+        (should-not (file-exists-p logserv))
+        (should-not (file-exists-p logchan))
+        (funcall expect 10 "*** MAXLIST=beI:60")
+        (should (= (pos-bol) (point-min)))
+        (should (file-exists-p logserv))))
+
+    (ert-info ("Log file ahead of truncation point")
+      ;; Log contains lines still present in buffer.
+      (with-temp-buffer
+        (insert-file-contents logserv)
+        (funcall expect 10 "*** MAXLIST=beI:60")))
+
+    (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+      (funcall expect 10 "please your lordship")
+      (should (file-exists-p logchan))
+      (funcall expect -0.1 "[07:04:37] alice: Here," (point-min)))
+
+    (ert-info ("Log ahead of truncation point")
+      (with-temp-buffer
+        (insert-file-contents logchan)
+        (funcall expect 1 "You have joined")
+        (funcall expect 1 "[07:04:37] alice: Here,")
+        (funcall expect 1 "loathed enemy")
+        (funcall expect -0.1 "please your lordship")))
+
+    (erc-log-mode -1)
+    (when noninteractive (delete-directory tempdir :recursive))))
+
+;;; erc-scenarios-log.el ends here
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index b624186d88d..1c75f35e1b5 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -269,6 +269,105 @@
       (kill-buffer "bob")
       (kill-buffer "ServNet"))))
 
+(ert-deftest erc--refresh-prompt ()
+  (let* ((counter 0)
+         (erc-prompt (lambda ()
+                       (format "%s %d>"
+                               (erc-format-target-and/or-network)
+                               (cl-incf counter))))
+         erc-accidental-paste-threshold-seconds
+         erc-insert-modify-hook
+         erc--input-review-functions
+         erc-send-completed-hook)
+
+    (ert-info ("Server buffer")
+      (with-current-buffer (get-buffer-create "ServNet")
+        (erc-tests--send-prep)
+        (goto-char erc-insert-marker)
+        (should (looking-at-p "ServNet 3>"))
+        (erc-tests--set-fake-server-process "sleep" "1")
+        (set-process-sentinel erc-server-process #'ignore)
+        (setq erc-network 'ServNet
+              erc-server-current-nick "tester"
+              erc-networks--id (erc-networks--id-create nil)
+              erc-server-users (make-hash-table :test 'equal))
+        (set-process-query-on-exit-flag erc-server-process nil)
+        ;; Incoming message redraws prompt
+        (erc-display-message nil 'notice nil "Welcome")
+        (should (looking-at-p "ServNet 4>"))
+        ;; Say something
+        (save-excursion (goto-char erc-input-marker)
+                        (insert "Howdy")
+                        (erc-send-current-line)
+                        (forward-line -1)
+                        (should (looking-at "No target"))
+                        (forward-line -1)
+                        (should (looking-at "<tester> Howdy")))
+        (should (looking-at-p "ServNet 6>"))
+        ;; Space after prompt is unpropertized
+        (should (get-text-property (1- erc-input-marker) 'erc-prompt))
+        (should-not (get-text-property erc-input-marker 'erc-prompt))
+        ;; No sign of old prompts
+        (save-excursion
+          (goto-char (point-min))
+          (should-not (search-forward (rx (any "3-5") ">") nil t)))))
+
+    (ert-info ("Channel buffer")
+      (with-current-buffer (get-buffer-create "#chan")
+        (erc-tests--send-prep)
+        (goto-char erc-insert-marker)
+        (should (looking-at-p "#chan 9>"))
+        (setq erc-server-process (buffer-local-value 'erc-server-process
+                                                     (get-buffer "ServNet"))
+              erc-networks--id (erc-with-server-buffer erc-networks--id)
+              erc--target (erc--target-from-string "#chan")
+              erc-default-recipients (list "#chan")
+              erc-channel-users (make-hash-table :test 'equal))
+        (erc-update-current-channel-member "alice" "alice")
+        (erc-update-current-channel-member "bob" "bob")
+        (erc-update-current-channel-member "tester" "tester")
+        (erc-display-message nil nil (current-buffer)
+                             (erc-format-privmessage "alice" "Hi" nil t))
+        (should (looking-at-p "#chan@ServNet 10>"))
+        (save-excursion (goto-char erc-input-marker)
+                        (insert "Howdy")
+                        (erc-send-current-line)
+                        (forward-line -1)
+                        (should (looking-at "<tester> Howdy")))
+        (should (looking-at-p "#chan@ServNet 11>"))
+        (save-excursion (goto-char erc-input-marker)
+                        (insert "/query bob")
+                        (erc-send-current-line))
+        ;; Query does not redraw (nor /help, only message input)
+        (should (looking-at-p "#chan@ServNet 11>"))
+        ;; No sign of old prompts
+        (save-excursion
+          (goto-char (point-min))
+          (should-not (search-forward (rx (or "9" "10") ">") nil t)))))
+
+    (ert-info ("Query buffer")
+      (with-current-buffer (get-buffer "bob")
+        (goto-char erc-insert-marker)
+        (should (looking-at-p "bob@ServNet 14>"))
+        (erc-display-message nil nil (current-buffer)
+                             (erc-format-privmessage "bob" "Hi" nil t))
+        (should (looking-at-p "bob@ServNet 15>"))
+        (save-excursion (goto-char erc-input-marker)
+                        (insert "Howdy")
+                        (erc-send-current-line)
+                        (forward-line -1)
+                        (should (looking-at "<tester> Howdy")))
+        (should (looking-at-p "bob@ServNet 16>"))
+        ;; No sign of old prompts
+        (save-excursion
+          (goto-char (point-min))
+          (should-not (search-forward (rx (or "14" "15") ">") nil t)))))
+
+    (when noninteractive
+      (kill-buffer "#chan")
+      (kill-buffer "bob")
+      (kill-buffer "ServNet"))))
+
 (ert-deftest erc--initialize-markers ()
   (let ((proc (start-process "true" (current-buffer) "true"))
         erc-modules



reply via email to

[Prev in Thread] Current Thread [Next in Thread]