emacs-diffs
[Top][All Lists]
Advanced

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

feature/pgtk 67ae4b6: Merge branch 'master' of git.sv.gnu.org:/srv/git/e


From: Yuuki Harano
Subject: feature/pgtk 67ae4b6: Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Date: Sat, 29 May 2021 05:06:27 -0400 (EDT)

branch: feature/pgtk
commit 67ae4b6271233559271f7a7158ba0e059b643ba5
Merge: 67a4c8b e3fc16f
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Yuuki Harano <masm+github@masm11.me>

    Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
---
 Makefile.in                                        |   14 +-
 admin/emake                                        |    4 +-
 configure.ac                                       |    5 +-
 doc/emacs/emacs.texi                               |    2 +
 doc/emacs/frames.texi                              |    5 +-
 doc/emacs/maintaining.texi                         |  173 +++
 doc/emacs/mini.texi                                |    8 +-
 doc/lispref/compile.texi                           |    5 +-
 doc/lispref/display.texi                           |    5 +-
 doc/lispref/minibuf.texi                           |   10 +
 doc/lispref/numbers.texi                           |    3 +-
 doc/misc/cc-mode.texi                              |  236 ++--
 doc/misc/modus-themes.org                          |  893 +++++++++++++--
 etc/NEWS                                           |   56 +-
 etc/{emacs.appdata.xml => emacs.metainfo.xml}      |   25 +-
 etc/themes/modus-operandi-theme.el                 |    2 +-
 etc/themes/modus-themes.el                         | 1198 +++++++++++---------
 etc/themes/modus-vivendi-theme.el                  |    2 +-
 etc/tutorials/TUTORIAL.sv                          |    2 +-
 lib/Makefile.in                                    |    4 +-
 lisp/bookmark.el                                   |   19 +-
 lisp/cedet/pulse.el                                |    3 +-
 lisp/dired-aux.el                                  |   47 +-
 lisp/dired-x.el                                    |   12 +-
 lisp/emacs-lisp/byte-opt.el                        |   69 +-
 lisp/emacs-lisp/cl-macs.el                         |    3 +-
 lisp/emacs-lisp/comp.el                            |    2 +-
 lisp/emacs-lisp/copyright.el                       |   14 +-
 lisp/emacs-lisp/rx.el                              |    7 +-
 lisp/emacs-lisp/shortdoc.el                        |   10 +-
 lisp/emacs-lisp/subr-x.el                          |    8 +-
 lisp/erc/erc-services.el                           |   14 +-
 lisp/faces.el                                      |    2 +-
 lisp/files.el                                      |    7 +-
 lisp/find-file.el                                  |   14 +-
 lisp/gnus/gnus-fun.el                              |   11 +-
 lisp/gnus/gnus-search.el                           |    7 +-
 lisp/gnus/gnus-util.el                             |   55 -
 lisp/gnus/nnimap.el                                |    4 +-
 lisp/help.el                                       |   43 +-
 lisp/international/mule-cmds.el                    |   57 +-
 lisp/international/quail.el                        |   75 +-
 lisp/isearch.el                                    |    4 +
 lisp/kmacro.el                                     |   26 +-
 lisp/mail/rmail.el                                 |    2 +-
 lisp/minibuffer.el                                 |  357 ++++--
 lisp/net/ange-ftp.el                               |    6 +-
 lisp/net/tramp-archive.el                          |   13 +-
 lisp/net/tramp-cache.el                            |    3 +-
 lisp/net/tramp-gvfs.el                             |    2 +-
 lisp/net/tramp-integration.el                      |   16 +-
 lisp/net/tramp-sh.el                               |    4 +-
 lisp/net/tramp-sudoedit.el                         |    2 +-
 lisp/net/tramp.el                                  |    8 +-
 lisp/outline.el                                    |    6 +-
 lisp/play/morse.el                                 |    4 +-
 lisp/progmodes/bug-reference.el                    |  120 +-
 lisp/progmodes/cc-mode.el                          |    2 +-
 lisp/progmodes/hideshow.el                         |    6 +-
 lisp/progmodes/modula2.el                          |    5 +-
 lisp/progmodes/octave.el                           |    3 +-
 lisp/progmodes/project.el                          |    5 +-
 lisp/progmodes/python.el                           |    7 +-
 lisp/progmodes/ruby-mode.el                        |   10 +
 lisp/progmodes/scheme.el                           |    5 +-
 lisp/progmodes/sql.el                              |   41 +-
 lisp/progmodes/xref.el                             |   18 +-
 lisp/ps-mule.el                                    |    4 +-
 lisp/simple.el                                     |   52 +-
 lisp/startup.el                                    |    3 +
 lisp/subr.el                                       |    6 +
 lisp/term/xterm.el                                 |   20 +-
 lisp/transient.el                                  |   13 +-
 lisp/vc/diff-mode.el                               |   21 +-
 lisp/vc/ediff-diff.el                              |    5 +-
 lisp/window.el                                     |    9 +-
 nt/mingw-cfg.site                                  |    5 +-
 src/Makefile.in                                    |    2 +-
 src/buffer.c                                       |    8 +-
 src/character.c                                    |   52 +-
 src/comp.c                                         |   22 +-
 src/composite.c                                    |   10 +-
 src/composite.h                                    |    4 +
 src/conf_post.h                                    |   31 +-
 src/editfns.c                                      |    4 +-
 src/fileio.c                                       |   16 +-
 src/fns.c                                          |   18 +-
 src/fringe.c                                       |    5 +-
 src/gmalloc.c                                      |   32 +-
 src/keyboard.c                                     |   13 -
 src/lread.c                                        |   10 +-
 src/process.c                                      |   29 +-
 src/sysdep.c                                       |   84 +-
 src/w32.c                                          |   39 +
 src/w32.h                                          |    1 +
 test/README                                        |    3 +
 test/infra/Dockerfile.emba                         |   15 +
 test/infra/gitlab-ci.yml                           |  115 +-
 .../emacs-lisp/bytecomp-resources/bc-test-alpha.el |    9 +
 .../emacs-lisp/bytecomp-resources/bc-test-beta.el  |    6 +
 test/lisp/emacs-lisp/bytecomp-tests.el             |   18 +
 test/lisp/emacs-lisp/copyright-tests.el            |    4 +
 test/lisp/emacs-lisp/shortdoc-tests.el             |   45 +
 test/lisp/gnus/gnus-util-tests.el                  |   37 -
 test/lisp/help-tests.el                            |    5 +
 test/lisp/net/tramp-archive-tests.el               |   46 +-
 test/lisp/progmodes/python-tests.el                |   24 +
 test/lisp/vc/diff-mode-tests.el                    |  142 +++
 test/manual/etags/README                           |   60 +
 test/src/lread-tests.el                            |   67 ++
 110 files changed, 3350 insertions(+), 1574 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 71f761e..2aba179 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -185,8 +185,8 @@ x_default_search_path=@x_default_search_path@
 # Where the etc/emacs.desktop file is to be installed.
 desktopdir=$(datarootdir)/applications
 
-# Where the etc/emacs.appdata.xml file is to be installed.
-appdatadir=$(datarootdir)/metainfo
+# Where the etc/emacs.metainfo.xml file is to be installed.
+metainfodir=$(datarootdir)/metainfo
 
 # Where the etc/emacs.service file is to be installed.
 # The system value (typically /usr/lib/systemd/user) can be
@@ -728,11 +728,11 @@ install-etc:
          ${srcdir}/etc/emacsclient.desktop > $${tmp}; \
        ${INSTALL_DATA} $${tmp} 
"$(DESTDIR)${desktopdir}/$${client_name}.desktop"; \
        rm -f $${tmp}
-       umask 022; ${MKDIR_P} "$(DESTDIR)${appdatadir}"
-       tmp=etc/emacs.tmpappdata; rm -f $${tmp}; \
+       umask 022; ${MKDIR_P} "$(DESTDIR)${metainfodir}"
+       tmp=etc/emacs.tmpmetainfo; rm -f $${tmp}; \
        sed -e "s/emacs\.desktop/${EMACS_NAME}.desktop/" \
-         ${srcdir}/etc/emacs.appdata.xml > $${tmp}; \
-       ${INSTALL_DATA} $${tmp} 
"$(DESTDIR)${appdatadir}/${EMACS_NAME}.appdata.xml"; \
+         ${srcdir}/etc/emacs.metainfo.xml > $${tmp}; \
+       ${INSTALL_DATA} $${tmp} 
"$(DESTDIR)${metainfodir}/${EMACS_NAME}.metainfo.xml"; \
        rm -f $${tmp}
        umask 022; $(MKDIR_P) "$(DESTDIR)$(systemdunitdir)"
        tmp=etc/emacs.tmpservice; rm -f $${tmp}; \
@@ -818,7 +818,7 @@ uninstall: uninstall-$(NTDIR) uninstall-doc 
uninstall-gsettings-schemas
             "hicolor/scalable/mimetypes/${EMACS_NAME}-document23.svg"; \
        fi)
        -rm -f "$(DESTDIR)${desktopdir}/${EMACS_NAME}.desktop"
-       -rm -f "$(DESTDIR)${appdatadir}/${EMACS_NAME}.appdata.xml"
+       -rm -f "$(DESTDIR)${metainfodir}/${EMACS_NAME}.metainfo.xml"
        -rm -f "$(DESTDIR)$(systemdunitdir)/${EMACS_NAME}.service"
   ifneq (,$(use_gamedir))
        for file in snake-scores tetris-scores; do \
diff --git a/admin/emake b/admin/emake
index 29dc151..bdaabc0 100755
--- a/admin/emake
+++ b/admin/emake
@@ -32,7 +32,9 @@ s#^./temacs.*#  \\& #
 egrep --line-buffered -v "^make|\
 ^Loading|\
 SCRAPE|\
-INFO.*Scraping.*[.]\$|\
+INFO.*Scraping.*[.] ?\$|\
+INFO.*Scraping.*done\$|\
+GEN.*etc/DOC|\
 ^Waiting for git|\
 ^Finding pointers|\
 ^Using load-path|\
diff --git a/configure.ac b/configure.ac
index 61b747b..39f9ada 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2285,6 +2285,9 @@ doug_lea_malloc=$emacs_cv_var_doug_lea_malloc
 hybrid_malloc=
 system_malloc=yes
 
+dnl This must be before the test of $ac_cv_func_sbrk below.
+AC_CHECK_FUNCS_ONCE([sbrk])
+
 test $with_unexec = yes &&
 case "$opsys" in
   ## darwin ld insists on the use of malloc routines in the System framework.
@@ -4752,7 +4755,7 @@ AC_CHECK_HEADERS(valgrind/valgrind.h)
 
 AC_CHECK_MEMBERS([struct unipair.unicode], [], [], [[#include <linux/kd.h>]])
 
-AC_CHECK_FUNCS_ONCE([__lsan_ignore_object sbrk])
+AC_CHECK_FUNCS_ONCE([__lsan_ignore_object])
 
 AC_FUNC_FORK
 
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index e0de3bb..9f64456 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -795,6 +795,8 @@ Maintaining Large Programs
 @ifnottex
 * Emerge::              A convenient way of merging two versions of a program.
 @end ifnottex
+* Bug Reference::       Highlighting references to bug reports and browsing
+                          them in their issue trackers.
 
 Version Control
 
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index e1a4e64..70615f6 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -614,7 +614,10 @@ If you are running Emacs on the GNOME desktop, you can 
tell Emacs to
 use the default system font by setting the variable
 @code{font-use-system-font} to @code{t} (the default is @code{nil}).
 For this to work, Emacs must have been compiled with support for
-Gsettings (or the older Gconf).
+Gsettings (or the older Gconf).  (To be specific, the Gsettings
+configuration names used are
+@samp{org.gnome.desktop.interface monospace-font-name} and
+@samp{org.gnome.desktop.interface font-name}.)
 
 @item
 Use the command line option @samp{-fn} (or @samp{--font}).  @xref{Font
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 0065098..a91bfac 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -32,6 +32,10 @@ symbols (a.k.a.@: ``identifiers'') and their references.
 A mode for merging changes to program sources made on separate
 branches of development.
 @end ifnottex
+
+@item
+A minor-mode for highlighting bug references and visiting the
+referenced bug reports in their issue tracker.
 @end itemize
 
 If you are maintaining a large Lisp program, then in addition to the
@@ -49,6 +53,8 @@ Lisp Regression Testing}).
 @ifnottex
 * Emerge::              A convenient way of merging two versions of a program.
 @end ifnottex
+* Bug Reference::       Highlighting references to bug reports and browsing
+                          them in their issue trackers.
 @end menu
 
 @node Version Control
@@ -3053,3 +3059,170 @@ the target should be built.
 @ifnottex
 @include emerge-xtra.texi
 @end ifnottex
+
+
+@node Bug Reference
+@section Bug Reference
+@cindex bug reference
+
+Most projects with a certain amount of users track bug reports in some
+issue tracking software which assigns each report a unique and short
+number or identifier.  Those are used to reference a given bug, e.g.,
+in a source code comment above the code fixing some bug, in
+documentation files, or in discussions on some mailinglist or IRC
+channel.
+
+@findex bug-reference-mode
+@findex bug-reference-prog-mode
+  The minor modes @code{bug-reference-mode} and
+@code{bug-reference-prog-mode} highlight such bug references and make
+it possible to follow them to the corresponding bug report on the
+project's issue tracker.  @code{bug-reference-prog-mode} is a variant
+of @code{bug-reference-mode} which highlights bug references only
+inside source code comments and strings.
+
+@vindex bug-reference-bug-regexp
+@vindex bug-reference-url-format
+  For its working, bug reference mode needs to know the syntax of bug
+references (@code{bug-reference-bug-regexp}), and the URL of the
+tracker where bug reports can be looked up
+(@code{bug-reference-url-format}).  Since those are typically
+different from project to project, it makes sense to specify them in
+@pxref{Directory Variables} or @pxref{File Variables}.
+
+For example, let's assume in our project, we usually write references
+to bug reports as bug#1234, or Bug-1234 and that this bug's page on
+the issue tracker is @url{https://project.org/issues/1234}, then
+these local variables section would do.
+
+@smallexample
+;; Local Variables:
+;; bug-reference-bug-regexp: "\\([Bb]ug[#-]\\)\\([0-9]+\\)"
+;; bug-reference-url-format: "https://project.org/issues/%s";
+;; End:
+@end smallexample
+
+The string captured by the second regexp group in
+@code{bug-reference-bug-regexp} is used to replace the @code{%s}
+template in the @code{bug-reference-url-format}.
+
+Note that @code{bug-reference-url-format} may also be a function in
+order to cater for more complex scenarios, e.g., when the part before
+the actual bug number has to be used to distinguish between issues and
+merge requests where each of them has a different URL.
+
+
+@heading Automatic Setup
+
+@vindex bug-reference-auto-setup-functions
+If @code{bug-reference-mode} is activated,
+@code{bug-reference-mode-hook} has been run and still
+@code{bug-reference-bug-regexp}, and @code{bug-reference-url-format}
+aren't both set, it'll try to setup suitable values for these two
+variables itself by calling the functions in
+@code{bug-reference-auto-setup-functions} one after the other until
+one is able to set the variables.
+
+@vindex bug-reference-setup-from-vc-alist
+@vindex bug-reference-setup-from-mail-alist
+@vindex bug-reference-setup-from-irc-alist
+  Right now, there are three types of setup functions.
+@enumerate
+@item
+Setup for version-controlled files configurable by the variable
+@code{bug-reference-setup-from-vc-alist}.  The default is able to
+setup GNU projects where @url{https://debbugs.gnu.org} is used as
+issue tracker, Github projects where both bugs and pull requests are
+referenced using the @code{#42} notation, and GitLab projects where
+bugs are references with @code{#17}, too, but merge requests use the
+@code{!18} notation.
+
+@item
+Setup for email guessing from mail folder/mbox names, and mail header
+values configurable by the variable
+@code{bug-reference-setup-from-mail-alist}.  The built-in news- and
+mailreader @ref{Gnus} and @ref{Rmail} are supported.
+
+@item
+Setup for IRC channels configurable by the variable
+@code{bug-reference-setup-from-irc-alist}.  The built-in IRC clients
+Rcirc, @xref{Top, Rcirc,, rcirc, The Rcirc Manual}, and ERC,
+@xref{Top, ERC,, erc, The ERC Manual}, are supported.
+@end enumerate
+
+For almost all of those modes, it's enough to simply enable
+@code{bug-reference-mode}, only Rmail requires a slightly different
+setup.
+
+@smallexample
+;; Use VC-based setup if file is under version control.
+(add-hook 'prog-mode-hook #'bug-reference-prog-mode)
+
+;; Gnus (summary & article buffers)
+(add-hook 'gnus-mode-hook #'bug-reference-mode)
+
+;; Rmail
+(add-hook 'rmail-show-message-hook #'bug-reference-mode-force-auto-setup)
+
+;; Rcirc
+(add-hook 'rcirc-mode-hook #'bug-reference-mode)
+
+;; ERC
+(add-hook 'erc-mode-hook #'bug-reference-mode)
+@end smallexample
+
+In the Rmail case, instead of the mode hook, the
+@code{rmail-show-message-hook} has to be used in combination with the
+function @code{bug-reference-mode-force-auto-setup} which activates
+@code{bug-reference-mode} and forces auto-setup.  The reason is that
+with Rmail all messages reside in the same buffer but the setup needs
+to be performed whenever another messages is displayed.
+
+
+@heading Adding support for third-party packages
+
+@vindex bug-reference-auto-setup-functions
+Adding support for bug-reference' auto-setup is usually quite
+straight-forward: write a setup function of zero arguments which
+gathers the required information (e.g., List-Id/To/From/Cc mail header
+values in the case of a MUA), and then calls one of the following
+helper functions:
+@itemize @bullet
+@item
+@code{bug-reference-maybe-setup-from-vc} which does the setup
+according to @code{bug-reference-setup-from-vc-alist},
+
+@item
+@code{bug-reference-maybe-setup-from-mail} which does the setup
+according to @code{bug-reference-setup-from-mail-alist},
+
+@item
+and @code{bug-reference-maybe-setup-from-irc} which does the setup
+according to @code{bug-reference-setup-from-irc-alist}.
+@end itemize
+A setup function should return non-nil if it could setup bug-reference
+mode which is the case if the last thing the function does is calling
+one of the helper functions above.
+
+Finally, the setup function has to be added to
+@code{bug-reference-auto-setup-functions}.
+
+Note that these auto-setup functions should check as a first step if
+they are applicable, e.g., by checking the @code{major-mode} value.
+
+
+@heading Integration with the debbugs package
+
+@findex debbugs-browse-mode
+If your project's issues are tracked on the server
+@url{https://debbugs.gnu.org}, you can browse and reply to reports
+directly in Emacs using the @code{debbugs} package, which can be
+downloaded via the Package Menu (@pxref{Packages}).  This package adds
+the minor mode @code{debbugs-browse-mode}, which can be activated on
+top of @code{bug-reference-mode} and @code{bug-reference-prog-mode} as
+follows:
+
+@smallexample
+(add-hook 'bug-reference-mode-hook 'debbugs-browse-mode)
+(add-hook 'bug-reference-prog-mode-hook 'debbugs-browse-mode)
+@end smallexample
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 03db669..2fdb1e7 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -374,9 +374,9 @@ used with the completion list:
 @itemx @key{prior}
 Typing @kbd{M-v}, while in the minibuffer, selects the window showing
 the completion list (@code{switch-to-completions}).  This paves the
-way for using the commands below.  @key{PageUp} or @key{prior} does
-the same.  You can also select the window in other ways
-(@pxref{Windows}).
+way for using the commands below.  @key{PageUp}, @key{prior} and
+@kbd{M-g M-c} does the same.  You can also select the window in other
+ways (@pxref{Windows}).
 
 @findex choose-completion
 @item @key{RET}
@@ -388,12 +388,14 @@ point (@code{choose-completion}).
 @findex next-completion
 @item @key{TAB}
 @item @key{RIGHT}
+@item @key{n}
 While in the completion list buffer, these keys move point to the
 following completion alternative (@code{next-completion}).
 
 @findex previous-completion
 @item @key{S-TAB}
 @item @key{LEFT}
+@item @key{p}
 While in the completion list buffer, these keys move point to the
 previous completion alternative (@code{previous-completion}).
 
diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi
index ee31b17..f48f4f4 100644
--- a/doc/lispref/compile.texi
+++ b/doc/lispref/compile.texi
@@ -1028,7 +1028,10 @@ execution unit.
 @defopt native-comp-async-report-warnings-errors
 If this variable's value is non-@code{nil}, warnings and errors from
 asynchronous native-compilation subprocesses are reported in the main
-Emacs session.  The default is @code{t}.
+Emacs session in a buffer named @file{*Warnings*}.  The default value
+@code{t} means display the resulting buffer.  To log warnings without
+popping up the @file{*Warnings*} buffer, set this variable to
+@code{silent}.
 @end defopt
 
 @defopt native-comp-async-query-on-exit
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 228c940..2ed03f6 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -7615,7 +7615,7 @@ Chars}.
   The above display conventions apply even when there is a display
 table, for any character whose entry in the active display table is
 @code{nil}.  Thus, when you set up a display table, you need only
-specify the characters for which you want special behavior.
+specify the characters for which you want special display behavior.
 
   The following variables affect how certain characters are displayed
 on the screen.  Since they change the number of columns the characters
@@ -7649,7 +7649,8 @@ command @code{tab-to-tab-stop}.  @xref{Indent Tabs}.
 (@pxref{Char-Tables}), with @code{display-table} as its subtype, which
 is used to override the usual character display conventions.  This
 section describes how to make, inspect, and assign elements to a
-display table object.
+display table object.  The next section (@pxref{Active Display Table})
+describes the various standard display tables and their precedence.
 
 @defun make-display-table
 This creates and returns a display table.  The table initially has
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index 145eee8..196dd99 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -1943,6 +1943,16 @@ the completion string in the @file{*Completions*} 
buffer, and
 a suffix displayed after the completion string.  This function
 takes priority over @code{annotation-function}.
 
+@item group-function
+The value should be a function for grouping the completion candidates.
+The function must take two arguments, @var{completion}, which is a
+completion candidate and @var{transform}, which is a boolean flag.  If
+@var{transform} is @code{nil}, the function must return the group
+title of the group to which the candidate belongs.  The returned title
+can also be @code{nil}.  Otherwise the function must return the
+transformed candidate.  The transformation can for example remove a
+redundant prefix, which is displayed in the group title.
+
 @item display-sort-function
 The value should be a function for sorting completions.  The function
 should take one argument, a list of completion strings, and return a
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index 4c5f7212..d28e158 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -237,7 +237,8 @@ precede the number and its exponent.  For example, 
@samp{1500.0},
 @samp{+15e2}, @samp{15.0e+2}, @samp{+1500000e-3}, and @samp{.15e4} are
 five ways of writing a floating-point number whose value is 1500.
 They are all equivalent.  Like Common Lisp, Emacs Lisp requires at
-least one digit after any decimal point in a floating-point number;
+least one digit after a decimal point in a floating-point number that
+does not have an exponent;
 @samp{1500.} is an integer, not a floating-point number.
 
   Emacs Lisp treats @code{-0.0} as numerically equal to ordinary zero
diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index 24ab4b7..98ded68 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -219,10 +219,9 @@ or can be downloaded from 
@url{https://savannah.gnu.org/projects/emacs/}.
 @summarycontents
 @contents
 
-@node    Top, Introduction, (dir), (dir)
-@comment node-name, next, previous, up
 
 @ifnottex
+@node    Top
 @top @ccmode{}
 
 @ccmode{} is a GNU Emacs mode for editing files containing C, C++,
@@ -360,8 +359,7 @@ Custom Macros
 @end detailmenu
 @end menu
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Introduction, Overview, Top, Top
-@comment node-name, next, previous, up
+@node    Introduction
 @chapter Introduction
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -420,7 +418,7 @@ also like to thank all the @ccmode{} victims who help 
enormously
 during the early beta stages of @ccmode{}'s development.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Overview, Getting Started, Introduction, Top
+@node    Overview
 @comment  node-name,  next,  previous,  up@cindex organization of the manual
 @chapter Overview of the Manual
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -489,8 +487,7 @@ project: whether for updating @ccmode{} or submitting bug 
reports.
 Finally, there are the customary indices.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Getting Started, Commands, Overview, Top
-@comment node-name, next, previous, up
+@node    Getting Started
 @chapter Getting Started
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -601,8 +598,7 @@ where @samp{XX} is the minor release number.
 @end deffn
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Commands, Font Locking, Getting Started, Top
-@comment node-name, next, previous, up
+@node    Commands
 @chapter Commands
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -638,7 +634,7 @@ structures.
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Indentation Commands, Comment Commands, Commands, Commands
+@node    Indentation Commands
 @comment node-name, next, previous,up
 @section Indentation Commands
 @cindex indentation
@@ -817,8 +813,7 @@ often (in seconds) progress messages are to be displayed.
 @end defopt
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Comment Commands, Movement Commands, Indentation Commands, Commands
-@comment node-name, next, previous, up
+@node    Comment Commands
 @section Comment Commands
 @cindex comments (insertion of)
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -886,8 +881,7 @@ lines.
 @end table
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Movement Commands, Filling and Breaking, Comment Commands, Commands
-@comment node-name, next, previous, up
+@node    Movement Commands
 @section Movement Commands
 @cindex movement
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -1042,7 +1036,7 @@ Movement}.  They might be removed from a future release 
of @ccmode{}.
 @end table
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Filling and Breaking, Minor Modes, Movement Commands, Commands
+@node    Filling and Breaking
 @comment  node-name,  next,  previous,  up
 @section Filling and Line Breaking Commands
 @cindex text filling
@@ -1136,8 +1130,7 @@ line break.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Minor Modes, Electric Keys, Filling and Breaking, Commands
-@comment node-name, next, previous, up
+@node    Minor Modes
 @section Minor Modes
 @cindex Minor Modes
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -1257,8 +1250,7 @@ value will turn it (or them) off.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Electric Keys, Auto-newlines, Minor Modes, Commands
-@comment node-name, next, previous, up
+@node    Electric Keys
 @section Electric Keys and Keywords
 @cindex electric characters
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -1437,8 +1429,7 @@ modes except IDL mode, since CORBA IDL doesn't have any 
statements.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Auto-newlines, Hungry WS Deletion, Electric Keys, Commands
-@comment node-name, next, previous, up
+@node    Auto-newlines
 @section Auto-newline Insertion
 @cindex auto-newline
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -1493,8 +1484,7 @@ clean-ups listed by key.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Hungry WS Deletion, Subword Movement, Auto-newlines, Commands
-@comment node-name, next, previous, up
+@node    Hungry WS Deletion
 @section Hungry Deletion of Whitespace
 @cindex hungry-deletion
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -1651,8 +1641,7 @@ trouble with this in GNU Emacs.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Subword Movement, Other Commands, Hungry WS Deletion, Commands
-@comment node-name, next, previous, up
+@node    Subword Movement
 @section Subword Movement and Editing
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -1744,8 +1733,7 @@ As a bonus, you can also use @code{subword-mode} in 
non-@ccmode{}
 buffers by typing @kbd{M-x subword-mode}.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Other Commands,  , Subword Movement, Commands
-@comment node-name, next, previous, up
+@node    Other Commands
 @section Other Commands
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -1842,8 +1830,7 @@ ask for help in the standard (X)Emacs forums.
 @end table
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Font Locking, Config Basics, Commands, Top
-@comment node-name, next, previous, up
+@node    Font Locking
 @chapter Font Locking
 @cindex font locking
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -1874,8 +1861,7 @@ sections apply to the other languages.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Font Locking Preliminaries, Faces, Font Locking, Font Locking
-@comment node-name, next, previous, up
+@node    Font Locking Preliminaries
 @section Font Locking Preliminaries
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -1972,8 +1958,7 @@ recognize types.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Faces, Doc Comments, Font Locking Preliminaries, Font Locking
-@comment node-name, next, previous, up
+@node    Faces
 @section Faces
 @cindex faces
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2071,8 +2056,7 @@ since those aren't syntactic errors in themselves.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Doc Comments, Wrong Comment Style, Faces, Font Locking
-@comment node-name, next, previous, up
+@node    Doc Comments
 @section Documentation Comments
 @cindex documentation comments
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2156,7 +2140,7 @@ If you add support for another doc comment style, please 
consider
 contributing it: send a note to @email{bug-cc-mode@@gnu.org}.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Wrong Comment Style, Misc Font Locking, Doc Comments, Font Locking
+@node    Wrong Comment Style
 @comment  node-name,  next,  previous,  up
 @section Marking ``Wrong'' style comments
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2178,7 +2162,7 @@ which aren't of the default style will be fontified with
 @end defvar
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Misc Font Locking, AWK Mode Font Locking, Wrong Comment Style, Font 
Locking
+@node    Misc Font Locking
 @comment  node-name,  next,  previous,  up
 @section Miscellaneous Font Locking
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2233,7 +2217,7 @@ section only applies when CC Mode cannot disambiguate a 
construct in
 any other way.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    AWK Mode Font Locking,  , Misc Font Locking, Font Locking
+@node    AWK Mode Font Locking
 @comment  node-name,  next,  previous,  up
 @section AWK Mode Font Locking
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2294,7 +2278,7 @@ escaped newline.  The @samp{\} is highlighted.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Config Basics, Custom Filling and Breaking, Font Locking, Top
+@node    Config Basics
 @comment  node-name,  next,  previous,  up
 @chapter Configuration Basics
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2486,8 +2470,7 @@ have it enabled by default by placing the following in 
your
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    CC Hooks, Style Variables, Config Basics, Config Basics
-@comment node-name, next, previous, up
+@node    CC Hooks
 @section Hooks
 @cindex mode hooks
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2560,8 +2543,7 @@ file.
 @end example
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Style Variables, Styles, CC Hooks, Config Basics
-@comment node-name, next, previous, up
+@node    Style Variables
 @section Style Variables
 @cindex styles
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2648,8 +2630,7 @@ Commas});@*
 (@pxref{Custom Macros}).
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Styles,  , Style Variables, Config Basics
-@comment node-name, next, previous, up
+@node    Styles
 @section Styles
 @cindex styles
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2683,8 +2664,7 @@ already formatted piece of your code, @ref{Guessing the 
Style}.
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Built-in Styles, Choosing a Style, Styles, Styles
-@comment node-name, next, previous, up
+@node    Built-in Styles
 @subsection Built-in Styles
 @cindex styles, built-in
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -2761,8 +2741,7 @@ afterwards.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Choosing a Style, Adding Styles, Built-in Styles, Styles
-@comment node-name, next, previous, up
+@node    Choosing a Style
 @subsection Choosing a Style
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -2819,8 +2798,7 @@ string.
 @end defvar
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Adding Styles, Guessing the Style, Choosing a Style, Styles
-@comment node-name, next, previous, up
+@node    Adding Styles
 @subsection Adding and Amending Styles
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -2907,8 +2885,7 @@ should not be changed directly; use @code{c-add-style} 
instead.
 @end defvar
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Guessing the Style, File Styles, Adding Styles, Styles
-@comment node-name, next, previous, up
+@node    Guessing the Style
 @subsection Guessing the Style
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -3030,8 +3007,7 @@ these offsets or the parent style name.
 @end table
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    File Styles,  , Guessing the Style, Styles
-@comment node-name, next, previous, up
+@node    File Styles
 @subsection File Styles
 @cindex styles, file local
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -3079,8 +3055,7 @@ mode hooks (@pxref{CC Hooks}).  Any individual setting of 
a variable
 will override one made through @code{c-file-style} or
 @code{c-file-offsets}.
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Custom Filling and Breaking, Custom Auto-newlines, Config Basics, Top
-@comment node-name, next, previous, up
+@node    Custom Filling and Breaking
 @chapter Customizing Filling and Line Breaking
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -3298,8 +3273,7 @@ as one comment, and the rest of the paragraph handling 
code
 inconsistent behavior.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Custom Auto-newlines, Clean-ups, Custom Filling and Breaking, Top
-@comment node-name, next, previous, up
+@node    Custom Auto-newlines
 @chapter Customizing Auto-newlines
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -3354,8 +3328,7 @@ circumstances.  @xref{Clean-ups}.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Hanging Braces, Hanging Colons, Custom Auto-newlines, Custom 
Auto-newlines
-@comment node-name, next, previous, up
+@node    Hanging Braces
 @section Hanging Braces
 @cindex hanging braces
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -3504,8 +3477,7 @@ themselves.
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Custom Braces,  , Hanging Braces, Hanging Braces
-@comment node-name, next, previous, up
+@node    Custom Braces
 @subsection Custom Brace Hanging
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -3592,8 +3564,7 @@ In all other cases, it returns the list @samp{(before 
after)} so
 that the brace appears on a line by itself.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Hanging Colons, Hanging Semicolons and Commas, Hanging Braces, Custom 
Auto-newlines
-@comment node-name, next, previous, up
+@node    Hanging Colons
 @section Hanging Colons
 @cindex hanging colons
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -3635,8 +3606,7 @@ them are controlled by a different mechanism, called 
@dfn{clean-ups} in
 @ccmode{}.  @xref{Clean-ups}, for details.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Hanging Semicolons and Commas,  , Hanging Colons, Custom Auto-newlines
-@comment node-name, next, previous, up
+@node    Hanging Semicolons and Commas
 @section Hanging Semicolons and Commas
 @cindex hanging semicolons
 @cindex hanging commas
@@ -3715,8 +3685,7 @@ newlines after semicolons inside one-line inline method 
definitions
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Clean-ups, Indentation Engine Basics, Custom Auto-newlines, Top
-@comment node-name, next, previous, up
+@node    Clean-ups
 @chapter Clean-ups
 @cindex clean-ups
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -3968,8 +3937,7 @@ situation if you just want a literal @samp{/} inserted.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Indentation Engine Basics, Customizing Indentation, Clean-ups, Top
-@comment node-name, next, previous, up
+@node    Indentation Engine Basics
 @chapter Indentation Engine Basics
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4028,8 +3996,7 @@ of the variables associated with indentation, not even
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Syntactic Analysis, Syntactic Symbols, Indentation Engine Basics, 
Indentation Engine Basics
-@comment node-name, next, previous, up
+@node    Syntactic Analysis
 @section Syntactic Analysis
 @cindex syntactic analysis
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -4187,8 +4154,7 @@ anchor position.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Syntactic Symbols, Indentation Calculation, Syntactic Analysis, 
Indentation Engine Basics
-@comment node-name, next, previous, up
+@node    Syntactic Symbols
 @section Syntactic Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4435,8 +4401,7 @@ Java.  @ref{Java Symbols}.
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Function Symbols, Class Symbols, Syntactic Symbols, Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Function Symbols
 @subsection Function Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4478,8 +4443,7 @@ isn't much special about them.  Note however that line 8 
is given
 on the previous line.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Class Symbols, Conditional Construct Symbols, Function Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Class Symbols
 @subsection Class related Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4625,8 +4589,7 @@ Here, line 1 is analyzed as a @code{topmost-intro}, but 
lines 2 and 3
 are both analyzed as @code{template-args-cont} lines.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Conditional Construct Symbols, Switch Statement Symbols, Class 
Symbols, Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Conditional Construct Symbols
 @subsection Conditional Construct Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4693,8 +4656,7 @@ the same line as the preceding close brace, that line 
would still have
 @code{block-close} syntax.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Switch Statement Symbols, Brace List Symbols, Conditional Construct 
Symbols, Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Switch Statement Symbols
 @subsection Switch Statement Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4729,8 +4691,7 @@ is treated slightly differently since it contains a brace 
that opens a
 block; it is given @code{statement-case-open} syntax.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Brace List Symbols, External Scope Symbols, Switch Statement Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Brace List Symbols
 @subsection Brace List Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4796,8 +4757,7 @@ giving @code{brace-list-entry} an offset of
 @code{brace-list-entry} anchored on the @samp{1} of line 8.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    External Scope Symbols, Paren List Symbols, Brace List Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    External Scope Symbols
 @subsection External Scope Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4860,8 +4820,7 @@ that isn't the case for historical reasons.}
 @end table
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Paren List Symbols, Literal Symbols, External Scope Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Paren List Symbols
 @subsection Parenthesis (Argument) List Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -4920,8 +4879,7 @@ parenthesis that opens an argument list, appearing on a 
separate line,
 is assigned the @code{statement-cont} syntax instead.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Literal Symbols, Multiline Macro Symbols, Paren List Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Literal Symbols
 @subsection Comment String Label and Macro Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5009,8 +4967,7 @@ Line 17 is assigned @code{stream-op} syntax.
 @end itemize
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Multiline Macro Symbols, Objective-C Method Symbols, Literal Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Multiline Macro Symbols
 @subsection Multiline Macro Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5050,8 +5007,7 @@ macros.}.
 @xref{Custom Macros}, for more info about the treatment of macros.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Objective-C Method Symbols, Java Symbols, Multiline Macro Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Objective-C Method Symbols
 @subsection Objective-C Method Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5077,8 +5033,7 @@ assigned @code{objc-method-args-cont} syntax.  Lines 5 
and 6 are both
 assigned @code{objc-method-call-cont} syntax.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Java Symbols, Statement Block Symbols, Objective-C Method Symbols, 
Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Java Symbols
 @subsection Java Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5115,8 +5070,7 @@ syntax due to it being a continuation of a variable 
declaration where preceding
 the declaration is an annotation.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Statement Block Symbols, K&R Symbols, Java Symbols, Syntactic Symbols
-@comment node-name, next, previous, up
+@node    Statement Block Symbols
 @subsection Statement Block Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5194,8 +5148,7 @@ example above.  The other similar special function, 
@code{gauge}, is
 handled like this too.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    K&R Symbols,  , Statement Block Symbols, Syntactic Symbols
-@comment node-name, next, previous, up
+@node    K&R Symbols
 @subsection K&R Symbols
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5221,8 +5174,7 @@ syntax.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Indentation Calculation,  , Syntactic Symbols, Indentation Engine 
Basics
-@comment node-name, next, previous, up
+@node    Indentation Calculation
 @section Indentation Calculation
 @cindex indentation
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -5320,8 +5272,7 @@ minibuffer when you hit @kbd{TAB}.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Customizing Indentation, Custom Macros, Indentation Engine Basics, Top
-@comment node-name, next, previous, up
+@node    Customizing Indentation
 @chapter Customizing Indentation
 @cindex customization, indentation
 @cindex indentation
@@ -5367,8 +5318,7 @@ indentation.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    c-offsets-alist, Interactive Customization, Customizing Indentation, 
Customizing Indentation
-@comment node-name, next, previous, up
+@node    c-offsets-alist
 @section c-offsets-alist
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5536,8 +5486,7 @@ it doesn't work well with some of the alignment functions 
that return
 @code{c-strict-syntax-p} set to @code{nil}.}.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Interactive Customization, Line-Up Functions, c-offsets-alist, 
Customizing Indentation
-@comment node-name, next, previous, up
+@node    Interactive Customization
 @section Interactive Customization
 @cindex customization, interactive
 @cindex interactive customization
@@ -5644,8 +5593,7 @@ for that syntactic element.
 @c End of MOVE THIS BIT.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Line-Up Functions, Custom Line-Up, Interactive Customization, 
Customizing Indentation
-@comment node-name, next, previous, up
+@node    Line-Up Functions
 @section Line-Up Functions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5718,8 +5666,7 @@ Works with:
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Brace/Paren Line-Up, List Line-Up, Line-Up Functions, Line-Up 
Functions
-@comment node-name, next, previous, up
+@node    Brace/Paren Line-Up
 @subsection Brace and Parenthesis Line-Up Functions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -5975,8 +5922,7 @@ and @code{inextern-lang}.
 @end defun
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    List Line-Up, Operator Line-Up, Brace/Paren Line-Up, Line-Up Functions
-@comment node-name, next, previous, up
+@node    List Line-Up
 @subsection List Line-Up Functions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -6300,8 +6246,7 @@ the current line with the colon on the previous line.
 @end defun
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Operator Line-Up, Comment Line-Up, List Line-Up, Line-Up Functions
-@comment node-name, next, previous, up
+@node    Operator Line-Up
 @subsection Operator Line-Up Functions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -6468,8 +6413,7 @@ lineup functions.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Comment Line-Up, Misc Line-Up, Operator Line-Up, Line-Up Functions
-@comment node-name, next, previous, up
+@node    Comment Line-Up
 @subsection Comment Line-Up Functions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -6578,8 +6522,7 @@ expressions.
 @end defun
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Misc Line-Up,  , Comment Line-Up, Line-Up Functions
-@comment node-name, next, previous, up
+@node    Misc Line-Up
 @subsection Miscellaneous Line-Up Functions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -6780,8 +6723,7 @@ the_larch,            @hereFn{c-lineup-topmost-intro-cont}
 @end defun
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Custom Line-Up, Other Indentation, Line-Up Functions, Customizing 
Indentation
-@comment node-name, next, previous, up
+@node    Custom Line-Up
 @section Custom Line-Up Functions
 @cindex customization, indentation functions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -6896,8 +6838,7 @@ any syntactic symbol that appears in 
@code{c-offsets-alist} can have a
 custom line-up function associated with it.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Other Indentation,  , Custom Line-Up, Customizing Indentation
-@comment node-name, next, previous, up
+@node    Other Indentation
 @section Other Special Indentations
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -6948,8 +6889,7 @@ functions to this hook, not remove them.  @xref{Style 
Variables}.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Custom Macros, Odds and Ends, Customizing Indentation, Top
-@comment node-name, next, previous, up
+@node    Custom Macros
 @chapter Customizing Macros
 @cindex macros
 @cindex preprocessor directives
@@ -6997,7 +6937,7 @@ Macros}.
 @end menu
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node     Macro Backslashes, Macros with ;, Custom Macros, Custom Macros
+@node     Macro Backslashes
 @comment  node-name,  next,  previous,  up
 @section Customizing Macro Backslashes
 @cindex @code{#define}
@@ -7045,7 +6985,7 @@ get aligned only when you explicitly invoke the command
 @end defopt
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node Macros with ;, Noise Macros, Macro Backslashes, Custom Macros
+@node Macros with ;
 @comment  node-name,  next,  previous,  up
 @section Macros with semicolons
 @cindex macros with semicolons
@@ -7103,8 +7043,7 @@ initialization code, after the mode hooks have run.
 @end defun
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Noise Macros, Indenting Directives, Macros with ;, Custom Macros
-@comment node-name, next, previous, up
+@node    Noise Macros
 @section Noise Macros
 @cindex noise macros
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -7160,8 +7099,7 @@ after the mode hooks have run.
 @end defun
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Indenting Directives, , Noise Macros, Custom Macros
-@comment node-name, next, previous, up
+@node    Indenting Directives
 @section Indenting Directives
 @cindex Indenting Directives
 @cindex Indenting #pragma
@@ -7202,8 +7140,7 @@ depends on that variable.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Odds and Ends, Sample Init File, Custom Macros, Top
-@comment node-name, next, previous, up
+@node    Odds and Ends
 @chapter Odds and Ends
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -7246,8 +7183,7 @@ anchoring position to indent the line in that case.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Sample Init File, Performance Issues, Odds and Ends, Top
-@comment node-name, next, previous, up
+@node    Sample Init File
 @appendix Sample Init File
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -7305,8 +7241,7 @@ to change some of the actual values.
 @end verbatim
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Performance Issues, Limitations and Known Bugs, Sample Init File, Top
-@comment node-name, next, previous, up
+@node    Performance Issues
 @appendix Performance Issues
 @cindex performance
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -7414,8 +7349,7 @@ more info.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Limitations and Known Bugs, FAQ, Performance Issues, Top
-@comment node-name, next, previous, up
+@node    Limitations and Known Bugs
 @appendix Limitations and Known Bugs
 @cindex limitations
 @cindex bugs
@@ -7480,8 +7414,7 @@ early on:
 @end itemize
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    FAQ, Updating CC Mode, Limitations and Known Bugs, Top
-@comment node-name, next, previous, up
+@node    FAQ
 @appendix Frequently Asked Questions
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -7609,8 +7542,7 @@ there since it's got its own system to keep track of 
blocks.
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Updating CC Mode, Mailing Lists and Bug Reports, FAQ, Top
-@comment node-name, next, previous, up
+@node    Updating CC Mode
 @appendix Getting the Latest CC Mode Release
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -7629,8 +7561,7 @@ compatibility, etc.@: are all available on the web site:
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Mailing Lists and Bug Reports, GNU Free Documentation License, 
Updating CC Mode, Top
-@comment node-name, next, previous, up
+@node    Mailing Lists and Bug Reports
 @appendix Mailing Lists and Submitting Bug Reports
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -7673,15 +7604,14 @@ to the Usenet newsgroups @code{gnu.emacs.sources}, 
@code{comp.emacs},
 @c There is no newsgroup for Pike.  :-(
 
 
-@node GNU Free Documentation License, Command and Function Index, Mailing 
Lists and Bug Reports, Top
+@node GNU Free Documentation License
 @appendix GNU Free Documentation License
 @include doclicense.texi
 
 
 @c Removed the tentative node "Mode Initialization" from here, 2005/8/27.
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Command and Function Index, Variable Index, GNU Free Documentation 
License, Top
-@comment node-name, next, previous, up
+@node    Command and Function Index
 @unnumbered Command and Function Index
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -7695,8 +7625,7 @@ Since most @ccmode{} commands are prepended with the 
string
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Variable Index, Concept and Key Index, Command and Function Index, Top
-@comment node-name, next, previous, up
+@node    Variable Index
 @unnumbered Variable Index
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
@@ -7710,8 +7639,7 @@ Since most @ccmode{} variables are prepended with the 
string
 
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-@node    Concept and Key Index,  , Variable Index, Top
-@comment node-name, next, previous, up
+@node    Concept and Key Index
 @unnumbered Concept and Key Index
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
diff --git a/doc/misc/modus-themes.org b/doc/misc/modus-themes.org
index 001ed57..9b1a001 100644
--- a/doc/misc/modus-themes.org
+++ b/doc/misc/modus-themes.org
@@ -3,11 +3,11 @@
 #+email: info@protesilaos.com
 #+language: en
 #+options: ':t toc:nil author:t email:t
+#+startup: content
 
-#+macro: stable-version 1.3.2
-#+macro: release-date 2021-04-18
-#+macro: development-version 1.4.0-dev
-#+macro: export-date (eval (format-time-string "%F %R %z" (current-time)))
+#+macro: stable-version 1.4.0
+#+macro: release-date 2021-05-25
+#+macro: development-version 1.5.0-dev
 #+macro: file @@texinfo:@file{@@$1@@texinfo:}@@
 #+macro: space @@texinfo:@: @@
 #+macro: kbd @@texinfo:@kbd{@@$1@@texinfo:}@@
@@ -32,8 +32,7 @@ The documentation furnished herein corresponds to stable 
version
 feature which does not yet form part of the latest tagged commit, is
 explicitly marked as such.
 
-Current development target is {{{development-version}}}.  This manual was
-built on {{{export-date}}}.
+Current development target is {{{development-version}}}.
 
 #+toc: headlines 8 insert TOC here, with eight headline levels
 
@@ -82,6 +81,11 @@ To ensure that users have a consistently accessible 
experience, the
 themes strive to achieve as close to full face coverage as possible
 ([[#h:a9c8f29d-7f72-4b54-b74b-ddefe15d6a19][Face coverage]]).
 
+Furthermore, the themes are designed to empower users with red-green
+color deficiency (deuteranopia).  This is achieved through customization
+options which have the effect of replacing all relevant instances of
+green with a variant of blue 
([[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]]).
+
 Starting with version 0.12.0 and onwards, the themes are built into GNU
 Emacs.
 
@@ -367,6 +371,113 @@ set to nil.
 Remember that all customization options must be evaluated before loading
 a theme ([[#h:3f3c3728-1b34-437d-9d0c-b110f5b161a9][Enable and load]]).
 
+Below is a summary of what you will learn in the subsequent sections of
+this manual.
+
+#+begin_src emacs-lisp
+(setq modus-themes-slanted-constructs t
+      modus-themes-bold-constructs nil
+      modus-themes-no-mixed-fonts nil
+      modus-themes-subtle-line-numbers nil
+      modus-themes-success-deuteranopia t
+
+      modus-themes-fringes nil ; {nil,'subtle,'intense}
+
+      ;; Options for `modus-themes-lang-checkers': nil,
+      ;; 'straight-underline, 'subtle-foreground,
+      ;; 'subtle-foreground-straight-underline, 'intense-foreground,
+      ;; 'intense-foreground-straight-underline, 'colored-background
+      modus-themes-lang-checkers nil
+
+      ;; Options for `modus-themes-mode-line': nil, '3d, 'moody,
+      ;; 'borderless, 'borderless-3d, 'borderless-moody, 'accented,
+      ;; 'accented-3d, 'accented-moody, 'borderless-accented,
+      ;; 'borderless-accented-3d, 'borderless-accented-moody
+      modus-themes-mode-line '3d
+
+      ;; Options for `modus-themes-syntax': nil, 'faint,
+      ;; 'yellow-comments, 'green-strings,
+      ;; 'yellow-comments-green-strings, 'alt-syntax,
+      ;; 'alt-syntax-yellow-comments, 'faint-yellow-comments
+      modus-themes-syntax nil
+
+      ;; Options for `modus-themes-hl-line': nil, 'intense-background,
+      ;; 'accented-background, 'underline-neutral,
+      ;; 'underline-accented, 'underline-only-neutral,
+      ;; 'underline-only-accented
+      modus-themes-hl-line 'underline-neutral
+
+      modus-themes-paren-match 'subtle-bold ; 
{nil,'subtle-bold,'intense,'intense-bold}
+
+      ;; Options for `modus-themes-links': nil, 'faint,
+      ;; 'neutral-underline, 'faint-neutral-underline, 'no-underline,
+      ;; 'underline-only, 'neutral-underline-only
+      modus-themes-links 'neutral-underline
+
+      ;; Options for `modus-themes-prompts': nil, 'subtle-accented,
+      ;; 'intense-accented, 'subtle-gray, 'intense-gray
+      modus-themes-prompts 'subtle-gray
+
+      modus-themes-completions 'moderate ; {nil,'moderate,'opinionated}
+
+      modus-themes-mail-citations nil ; {nil,'faint,'monochrome}
+
+      ;; Options for `modus-themes-region': nil, 'no-extend, 'bg-only,
+      ;; 'bg-only-no-extend, 'accent, 'accent-no-extend
+      modus-themes-region 'bg-only-no-extend
+
+      ;; Options for `modus-themes-diffs': nil, 'desaturated,
+      ;; 'bg-only, 'deuteranopia, 'fg-only-deuteranopia
+      modus-themes-diffs 'fg-only-deuteranopia
+
+      modus-themes-org-blocks 'gray-background ; 
{nil,'gray-background,'tinted-background}
+      modus-themes-org-habit nil ; {nil,'simplified,'traffic-light}
+
+      modus-themes-headings ; this is an alist: read the manual or its doc 
string
+      '((1 . line)
+        (2 . rainbow-line-no-bold)
+        (t . no-bold))
+
+      modus-themes-variable-pitch-ui nil
+      modus-themes-variable-pitch-headings t
+      modus-themes-scale-headings t
+      modus-themes-scale-1 1.1
+      modus-themes-scale-2 1.15
+      modus-themes-scale-3 1.21
+      modus-themes-scale-4 1.27
+      modus-themes-scale-5 1.33)
+#+end_src
+
+** Option for color-coding success state (deuteranopia)
+:properties:
+:alt_title: Success' color-code
+:description: Toggle blue color for success or done states
+:custom_id: h:3ed03a48-20d8-4ce7-b214-0eb7e4c79abe
+:end:
+#+vindex: modus-themes-success-deuteranopia
+
+Symbol: ~modus-themes-success-deuteranopia~
+
+Possible values:
+
+1. ~nil~ (default)
+2. ~t~
+
+The default is to colorise all faces that denote "success", "done", or
+similar with a variant of green.
+
+With a non-nil value (~t~), use variants of blue instead of green.  This
+is meant to empower users with red-green color deficiency.
+
+The present customization option should apply to all contexts where
+there can be a color-coded distinction between success and failure,
+to-do and done, and so on.
+
+Diffs, which have a red/green dichotomy by default, can also be
+configured to conform with deuteranopia.
+
+[[#h:ea7ac54f-5827-49bd-b09f-62424b3b6427][Option for diff buffer looks]].
+
 ** Option for more bold constructs
 :properties:
 :alt_title: Bold constructs
@@ -591,21 +702,24 @@ Possible values:
 7. ~accented~
 8. ~accented-3d~
 9. ~accented-moody~
+10. ~borderless-accented~
+11. ~borderless-accented-3d~
+12. ~borderless-accented-moody~
 
 The default produces a two-dimensional effect both for the active and
-inactive modelines.  The differences between the two are limited to
+inactive mode lines.  The differences between the two are limited to
 distinct shades of grayscale values, with the active being more intense
 than the inactive.
 
-Option ~3d~ will make the active modeline look like a three-dimensional
-rectangle.  Inactive modelines remain 2D, though they are slightly toned
-down relative to the default.  This aesthetic is virtually the same as
-what you get when you run Emacs without any customizations (=emacs -Q= on
-the command line).
+Option ~3d~ will make the active mode line look like a three-dimensional
+rectangle.  Inactive mode lines remain 2D, though they are slightly
+toned down relative to the default.  This aesthetic is virtually the
+same as what you get when you run Emacs without any customizations
+(=emacs -Q= on the command line).
 
-While ~moody~ removes all box effects from the modelines and applies
+While ~moody~ removes all box effects from the mode lines and applies
 underline and overline properties instead.  It also tones down a bit the
-inactive modelines.  This is meant to optimize things for use with the
+inactive mode lines.  This is meant to optimize things for use with the
 [[https://github.com/tarsius/moody][moody package]] (hereinafter referred to 
as "Moody"), though it can work
 fine even without it.
 
@@ -616,7 +730,7 @@ creating some padding.
 
 The ~borderless-3d~ and ~borderless-moody~ approximate the ~3d~ and ~moody~
 options respectively, while removing the borders.  However, to ensure
-that the inactive modelines remain visible, they apply a slightly more
+that the inactive mode lines remain visible, they apply a slightly more
 prominent background to them than what their counterparts do (same
 inactive background as with the default).
 
@@ -625,12 +739,17 @@ default (~nil~), ~3d~, and ~moody~ styles respectively, 
except that the active
 mode line uses a colored background instead of the standard shade of
 gray.
 
+Same principle for ~borderless-accented~, ~borderless-accented-3d~, and
+~borderless-accented-moody~ which use a colored background for the active
+mode line and have no discernible borders around both the active and
+inactive the mode lines.
+
 Note that Moody does not expose any faces that the themes could style
 directly.  Instead it re-purposes existing ones to render its tabs and
 ribbons.  As such, there may be cases where the contrast ratio falls
 below the 7:1 target that the themes conform with (WCAG AAA).  To hedge
 against this, we configure a fallback foreground for the ~moody~ option,
-which will come into effect when the background of the modeline changes
+which will come into effect when the background of the mode line changes
 to something less accessible, such as Moody ribbons (read the doc string
 of ~set-face-attribute~, specifically ~:distant-foreground~).  This fallback
 is activated when Emacs determines that the background and foreground of
@@ -671,11 +790,12 @@ completion UI.  The interfaces can be grouped in two 
categories, based
 on their default aesthetics: (i) those that only or mostly use
 foreground colors for their interaction model, and (ii) those that
 combine background and foreground values for some of their metaphors.
-The former category encompasses Icomplete, Ido, Selectrum as well as
-pattern matching styles like Orderless and Flx.  The latter covers Helm,
-Ivy, and similar.
+The former category encompasses Icomplete, Ido, Selectrum, Vertico, as
+well as pattern matching styles like Orderless and Flx.  The latter
+covers Helm, Ivy, and Sallet.
 
-A value of ~nil~ will respect the metaphors of each completion framework.
+A value of ~nil~ (the default) will simply respect the metaphors of each
+completion framework.
 
 Option ~moderate~ applies a combination of background and foreground that
 is fairly subtle.  For Icomplete and friends this constitutes a
@@ -694,6 +814,35 @@ To appreciate the scope of this customization option, you 
should spend
 some time with every one of the ~nil~ (default), ~moderate~, and ~opinionated~
 possibilities.
 
+** Option for mail citations
+:properties:
+:alt_title: Mail citations
+:description: Choose among colorful, desaturated, monochrome citations
+:custom_id: h:5a12765d-0ba0-4a75-ab11-e35d3bbb317d
+:end:
+#+vindex: modus-themes-mail-citations
+
+Symbol: ~modus-themes-mail-citations~
+
+Possible values:
+
+1. ~nil~ (default)
+2. ~faint~
+3. ~monochrome~
+
+By default, citations in email-related buffers apply contrasting hues to
+different levels of depth in cited text.  The colors are fairly easy to
+tell apart.
+
+A value of ~faint~ makes all citation levels less intense, while retaining
+the default style of contrasting hues (albeit very subtle ones).
+
+Option ~monochrome~ turns all citations in to a uniform shade of gray.
+
+Whatever the value assigned to this variable, citations in emails are
+controlled by typographic elements or indentation, which the themes do
+not touch.
+
 ** Option for fringe visibility
 :properties:
 :alt_title: Fringes
@@ -792,8 +941,8 @@ The default is to use a subtle gray background for the 
current line when
 The ~intense-background~ applies a more prominent gray to the background
 of the current line.
 
-With ~accented-background~ the default's subtle aesthetic is retained, but
-the background has a more colored hint.
+With ~accented-background~ the background gets a colored hint and is more
+prominent than the default.
 
 The ~underline-neutral~ combines the default subtle neutral background
 with a gray underline.
@@ -926,53 +1075,42 @@ Possible values:
 
 1. ~nil~ (default)
 2. ~desaturated~
-3. ~fg-only~
-4. ~bg-only~
-5. ~deuteranopia~
-
-By default the themes apply rich coloration to the output of diffs, such
-as those of ~diff-mode~, ~ediff~, ~smerge-mode~, and Magit.  These are
-color combinations of an accented background and foreground so that, for
-example, added lines have a pronounced green background with an
-appropriate shade of green for the affected text.  Word-wise or
-"refined" changes follow this pattern but use different shades of those
-colors to remain distinct.
-
-Option ~desaturated~ tones down all relevant color values.  It still
-combines an accented background with an appropriate foreground, yet its
-overall impression is fairly subtle.  Refined changes are a bit more
-intense to fulfil their intended function, though still less saturated
-than default.
-
-Option ~fg-only~ will remove most accented backgrounds and instead rely
-on color-coded text to denote changes.  For instance, added lines use a
-green foreground, while their background is the same as the rest of the
-buffer.  Word-wise highlights still use a background value which is,
-nonetheless, more subtle than its default equivalent.
-
-Option ~bg-only~ applies color-coded backgrounds but does not override
-any syntax highlighting that may be present.  This makes it suitable for
-use with a non-nil value for ~diff-font-lock-syntax~ (which is the
-default for ~diff-mode~ buffers in Emacs 27 or higher).
-
-Option ~deuteranopia~ optimizes for red-green color deficiency.  It
-replaces all instances of green with blue variants.  This is to ensure
-that indicators for "removed" and "added" states are not mistaken for
-each other.
-
-Concerning Magit, an extra set of tweaks are introduced for the effect
-of highlighting the current diff hunk, so as to remain aligned with the
-overall experience of that mode.  Expect changes that are consistent
-with the overall intent of the aforementioned.  Note, however, that the
-~bg-only~ option will not deliver the intended results in Magit diffs
-because no syntax highlighting is used there (last checked with Magit
-version 20201116.1057, though upstream has a plan to eventually support
-such a feature---this entry shall be updated accordingly).
+3. ~bg-only~
+4. ~deuteranopia~
+5. ~fg-only-deuteranopia~
+
+The default (~nil~) uses fairly intense color combinations for diffs, by
+applying prominently colored backgrounds, with appropriate foregrounds.
+
+Option ~desaturated~ follows the same principles as with the default
+(~nil~), though it tones down all relevant colors.
+
+Option ~bg-only~ applies a background but does not override the text's
+foreground.  This makes it suitable for a non-nil value passed to
+~diff-font-lock-syntax~ (note: Magit does not support syntax highlighting
+in diffs---last checked on 2021-04-21).
+
+Option ~deuteranopia~ is like the default (~nil~) in terms of using
+prominently colored backgrounds, except that it also accounts for
+red-green color defficiency by replacing all instances of green with
+colors on the blue side of the spectrum.  Other stylistic changes are
+made in the interest of optimizing for such a use-case.
+
+Option ~fg-only-deuteranopia~ removes all colored backgrounds, except from
+word-wise or refined changes.  Instead, it only uses color-coded
+foreground values to differentiate between added, removed, and changed
+lines.  If a background is necessary to denote context, a subtle
+grayscale value is applied.  The color used for added lines is a variant
+of blue to account for red-green color defficiency but also because
+green text alone is hard to discern in the diff's context (hard for our
+accessibility purposes).  The ~fg-only~ option that existed in older
+versions of the themes is now an alias of ~fg-only-deuteranopia~, in the
+interest of backward compatibility.
 
 ** Option for org-mode block styles
 :properties:
 :alt_title: Org mode blocks
-:description: Choose among plain, grayscale, or rainbow styles
+:description: Choose among plain, gray, or tinted backgrounds
 :custom_id: h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2
 :end:
 #+vindex: modus-themes-org-blocks
@@ -982,32 +1120,33 @@ Symbol: ~modus-themes-org-blocks~
 Possible values:
 
 1. ~nil~ (default)
-2. ~grayscale~
-3. ~rainbow~
+2. ~gray-background~ (value ~grayscale~ exists for backward compatibility)
+3. ~tinted-background~ (value ~rainbow~ exists for backward compatibility)
 
-The default is to use the same background as the rest of the buffer for
-the contents of the block.
+The default means that the block has no distinct background of its own
+and uses the one that applies to the rest of the buffer.
 
-Option ~grayscale~ applies a subtle neutral gray background to the block's
-contents.  It will also extend to the edge of the window the background
-of the "begin" and "end" block delimiter lines (only relevant for Emacs
-versions >= 27 where the 'extend' keyword is part of the face
-specifications).
+Option ~gray-background~ applies a subtle gray background to the block's
+contents.  It also affects the begin and end lines of the block: their
+background extends to the edge of the window for Emacs version >= 27
+where the ~:extend~ keyword is recognized by ~set-face-attribute~ (this is
+contingent on the variable ~org-fontify-whole-block-delimiter-line~).
 
-Option ~rainbow~ uses an accented background for the contents of the
-block.  The exact color will depend on the programming language and is
-controlled by the ~org-src-block-faces~ variable.  This is most suitable
-for users who work on literate programming documents that mix and match
-several languages.
+Option ~tinted-background~ uses a slightly colored background for the
+contents of the block.  The exact color will depend on the programming
+language and is controlled by the variable ~org-src-block-faces~ (refer to
+the theme's source code for the current association list).  For this to
+take effect, Org must be restarted with {{{kbd(M-x org-mode-restart)}}}.
 
-Note that the "rainbow" blocks may require you to also reload the
-major-mode so that the colors are applied consistently throughout: use
-{{{kbd(M-x org-mode)}}} or {{{kbd(M-x org-mode-restart)}}} to refresh the 
buffer.
-Or start typing in each code block (inefficient at scale, but it still
-works).
+Code blocks use their major mode's colors only when the variable
+~org-src-fontify-natively~ is non-nil.  While quote/verse blocks require
+setting ~org-fontify-quote-and-verse-blocks~ to a non-nil value.
 
-The extent of Org block delimiter lines is controlled by the variable
-~org-fontify-whole-block-delimiter-line~.
+[[#h:f44cc6e3-b0f1-4a5e-8a90-9e48fa557b50][Update Org block delimiter 
fontification]].
+
+Older versions of the themes provided options ~grayscale~ (or ~greyscale~)
+and ~rainbow~.  Those will continue to work as they are aliases for
+~gray-background~ and ~tinted-background~, respectively.
 
 ** Option for org-habit graph styles
 :properties:
@@ -1637,6 +1776,170 @@ Perhaps you may wish to generalise those findings in to 
a set of
 functions that also accept an arbitrary face.  We shall leave the
 experimentation up to you.
 
+** Cycle through arbitrary colors (DIY)
+:properties:
+:custom_id: h:77dc4a30-b96a-4849-85a8-fee3c2995305
+:end:
+#+cindex: Cycle colors
+
+Users may opt to customize individual faces of the themes to accommodate
+their particular needs.  One such case is with the color intensity of
+comments, specifically the foreground of ~font-lock-comment-face~.  The
+Modus themes set that to a readable value, in accordance with their
+accessibility objective, though users may prefer to lower the overall
+contrast on an on-demand basis.
+
+One way to achieve this is to design a command that cycles through three
+distinct levels of intensity, though the following can be adapted to any
+kind of cyclic behaviour, such as to switch between red, green, and
+blue.
+
+In the following example, we employ the ~modus-themes-color~ function
+which reads a symbol that represents an entry in the active theme's
+color palette ([[#h:1487c631-f4fe-490d-8d58-d72ffa3bd474][Case-by-case face 
specs using the themes' palette]]).
+Those are stored in ~my-modus-themes-comment-colors~.
+
+#+begin_src emacs-lisp
+(defvar my-modus-themes-comment-colors
+  ;; We are abusing the palette here, as those colors have their own
+  ;; purpose in the palette, so please ignore the semantics of their
+  ;; names.
+  '((low . bg-region)
+    (medium . bg-tab-inactive-alt)
+    (high . fg-alt))
+  "Alist of levels of intensity mapped to color palette entries.
+The entries are found in `modus-themes-operandi-colors' or
+`modus-themes-vivendi-colors'.")
+
+(defvar my-modus-themes--adjust-comment-color-state nil
+  "The cyclic state of `my-modus-themes-adjust-comment-color'.
+For internal use.")
+
+(defun my-modus-themes--comment-foreground (degree state)
+  "Set `font-lock-comment-face' foreground.
+Use `my-modus-themes-comment-colors' to extract the color value
+for each level of intensity.
+
+This is complementary to `my-modus-themes-adjust-comment-color'."
+  (let ((palette-colors my-modus-themes-comment-colors))
+    (set-face-foreground
+     'font-lock-comment-face
+     (modus-themes-color (alist-get degree palette-colors)))
+    (setq my-modus-themes--adjust-comment-color-state state)
+    (message "Comments are set to %s contrast" degree)))
+
+(defun my-modus-themes-adjust-comment-color ()
+  "Cycle through levels of intensity for comments.
+The levels are determined by `my-modus-themes-comment-colors'."
+  (interactive)
+  (pcase my-modus-themes--adjust-comment-color-state
+    ('nil
+     (my-modus-themes--comment-foreground 'low 1))
+    (1
+     (my-modus-themes--comment-foreground 'medium 2))
+    (_
+     (my-modus-themes--comment-foreground 'high nil))))
+#+end_src
+
+With the above, {{{kbd(M-x my-modus-themes-adjust-comment-color)}}} will cycle
+through the three levels of intensity that have been specified.
+
+Another approach is to not read from the active theme's color palette
+and instead provide explicit color values, either in hexadecimal RGB
+notation (like =#123456=) or as the names that are displayed in the output
+of {{{kbd(M-x list-colors-display)}}}.  In this case, the alist with the
+colors will have to account for the active theme, so as to set the
+appropriate colors.  While this introduces a bit more complexity, it
+ultimately offers greater flexibility on the choice of colors for such a
+niche functionality (so there is no need to abuse the palette of the
+active Modus theme):
+
+#+begin_src emacs-lisp
+(defvar my-modus-themes-comment-colors
+  '((light . ((low . "gray75")
+              (medium . "gray50")
+              (high . "#505050")))      ; the default for `modus-operandi'
+
+    (dark . ((low . "gray25")
+             (medium . "gray50")
+             (high . "#a8a8a8"))))      ; the default for `modus-vivendi'
+  "Alist of levels of intensity mapped to color values.
+For such colors, consult the command `list-colors-display'.  Pass
+the name of a color or its hex value.")
+
+(defvar my-modus-themes--adjust-comment-color-state nil
+  "The cyclic state of `my-modus-themes-adjust-comment-color'.
+For internal use.")
+
+(defun my-modus-themes--comment-foreground (degree state)
+    "Set `font-lock-comment-face' foreground.
+Use `my-modus-themes-comment-colors' to extract the color value
+for each level of intensity.
+
+This is complementary to `my-modus-themes-adjust-comment-color'."
+  (let* ((colors my-modus-themes-comment-colors)
+         (levels (pcase (car custom-enabled-themes)
+                   ('modus-operandi (alist-get 'light colors))
+                   ('modus-vivendi (alist-get 'dark colors)))))
+    (set-face-foreground
+     'font-lock-comment-face
+     (alist-get degree levels))
+    (setq my-modus-themes--adjust-comment-color-state state)
+    (message "Comments are set to %s contrast" degree)))
+
+(defun my-modus-themes-adjust-comment-color ()
+  "Cycle through levels of intensity for comments.
+The levels are determined by `my-modus-themes-comment-colors'."
+  (interactive)
+  (pcase my-modus-themes--adjust-comment-color-state
+    ('nil
+     (my-modus-themes--comment-foreground 'low 1))
+    (1
+     (my-modus-themes--comment-foreground 'medium 2))
+    (_
+     (my-modus-themes--comment-foreground 'high nil))))
+#+end_src
+
+The effect of the above configurations on ~font-lock-comment-face~ is
+global.  To make it buffer-local, one must tweak the code to employ the
+function ~face-remap-add-relative~ 
([[#h:7a93cb6f-4eca-4d56-a85c-9dcd813d6b0f][Remap face with local value]]).
+
+So this form in ~my-modus-themes--comment-foreground~:
+
+#+begin_src emacs-lisp
+;; example 1
+(...
+ (set-face-foreground
+  'font-lock-comment-face
+  (modus-themes-color (alist-get degree palette-colors)))
+ ...)
+
+;; example 2
+(...
+ (set-face-foreground
+  'font-lock-comment-face
+  (alist-get degree levels))
+ ...)
+#+end_src
+
+Must become this:
+
+#+begin_src emacs-lisp
+;; example 1
+(...
+ (face-remap-add-relative
+  'font-lock-comment-face
+  `(:foreground ,(modus-themes-color (alist-get degree palette-colors))))
+ ...)
+
+;; example 2
+(...
+ (face-remap-add-relative
+  'font-lock-comment-face
+  `(:foreground ,(alist-get degree levels)))
+ ...)
+#+end_src
+
 ** Override colors (DIY)
 :properties:
 :custom_id: h:307d95dd-8dbd-4ece-a543-10ae86f155a6
@@ -1659,7 +1962,7 @@ basic background values that apply to buffers and the 
mode line
 that can be overridden):
 
 #+begin_src emacs-lisp
-(defconst modus-themes-colors-operandi
+(defconst modus-themes-operandi-colors
   '((bg-main . "#ffffff")
     (bg-dim . "#f8f8f8")
     (bg-alt . "#f0f0f0")
@@ -1808,9 +2111,59 @@ same for ~modus-themes-vivendi-color-overrides~ (dark 
theme).
 Using the above has an immediate effect, as it reloads the active Modus
 theme.
 
-To disable the effect, one must reset the aforementioned variables to
-~nil~.  Or specify a command for it, such as by taking inspiration from
-the ~modus-themes-toggle~ we already provide:
+The =my-modus-themes-saturate= function stores new color values in the
+variables =modus-themes-operandi-color-overrides= and
+=modus-themes-vivendi-color-overrides=, meaning that it undoes changes
+implemented by the user on individual colors.  To have both automatic
+saturation adjustment across the board and retain per-case edits to the
+palette, some tweaks to the above function are required.  For example:
+
+#+begin_src emacs-lisp
+(defvar my-modus-themes-vivendi-extra-color-overrides
+  '((fg-main . "#ead0c0")
+    (bg-main . "#050515"))
+  "My bespoke colors for `modus-vivendi'.")
+
+(defvar my-modus-themes-operandi-extra-color-overrides
+  '((fg-main . "#1a1a1a")
+    (bg-main . "#fefcf4"))
+  "My bespoke colors for `modus-operandi'.")
+
+(defun my-modus-themes-saturate (percent)
+  "Saturate current Modus theme palette overrides by PERCENT.
+Preserve the color values stored in
+`my-modus-themes-operandi-extra-color-overrides',
+`my-modus-themes-vivendi-extra-color-overrides'."
+  (interactive
+   (list (read-number "Saturation by percent: ")))
+  (let* ((theme (modus-themes--current-theme))
+         (palette (pcase theme
+                    ('modus-operandi modus-themes-operandi-colors)
+                    ('modus-vivendi modus-themes-vivendi-colors)
+                    (_ (error "No Modus theme is active"))))
+         (overrides (pcase theme
+                      ('modus-operandi 'modus-themes-operandi-color-overrides)
+                      ('modus-vivendi 'modus-themes-vivendi-color-overrides)
+                      (_ (error "No Modus theme is active"))))
+         (extra-overrides (pcase theme
+                            ('modus-operandi 
my-modus-themes-operandi-extra-color-overrides)
+                            ('modus-vivendi 
my-modus-themes-vivendi-extra-color-overrides)
+                            (_ (error "No Modus theme is active")))))
+    (let (name cons colors)
+      (dolist (cons palette)
+        (setq name (color-saturate-name (cdr cons) percent))
+        (setq name (format "%s" name))
+        (setq cons `(,(car cons) . ,name))
+        (push cons colors))
+      (set overrides (append extra-overrides colors)))
+    (pcase theme
+      ('modus-operandi (modus-themes-load-operandi))
+      ('modus-vivendi (modus-themes-load-vivendi)))))
+#+end_src
+
+To disable the effect, one must reset the aforementioned variables of
+the themes to ~nil~.  Or specify a command for it, such as by taking
+inspiration from the ~modus-themes-toggle~ we already provide:
 
 #+begin_src emacs-lisp
 (defun my-modus-themes-revert-overrides ()
@@ -1959,6 +2312,48 @@ it if you plan to control face attributes.
 
 [[#h:02e25930-e71a-493d-828a-8907fc80f874][Check color combinations]].
 
+** Update Org block delimiter fontification (DIY)
+:properties:
+:custom_id: h:f44cc6e3-b0f1-4a5e-8a90-9e48fa557b50
+:end:
+
+As noted in the section about ~modus-themes-org-blocks~, Org contains a
+variable that determines whether the block's begin and end lines are
+extended to the edge of the window 
([[#h:b7e328c0-3034-4db7-9cdf-d5ba12081ca2][Option for org-mode block styles]]).
+The variable is ~org-fontify-whole-block-delimiter-line~.
+
+Users who change the style of Org blocks from time to time may prefer to
+automatically update delimiter line fontification, such as with the
+following setup:
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-org-fontify-block-delimiter-lines ()
+  "Match `org-fontify-whole-block-delimiter-line' to theme style.
+Run this function at the post theme load phase, such as with the
+`modus-themes-after-load-theme-hook'."
+  (if (eq modus-themes-org-blocks 'gray-background)
+      (setq org-fontify-whole-block-delimiter-line t)
+    (setq org-fontify-whole-block-delimiter-line nil)))
+
+(add-hook 'modus-themes-after-load-theme-hook
+          #'my-modus-themes-org-fontify-block-delimiter-lines)
+#+end_src
+
+Then {{{kbd(M-x org-mode-restart)}}} for changes to take effect, though manual
+intervention can be circumvented by tweaking the function thus:
+
+#+begin_src emacs-lisp
+(defun my-modus-themes-org-fontify-block-delimiter-lines ()
+  "Match `org-fontify-whole-block-delimiter-line' to theme style.
+Run this function at the post theme load phase, such as with the
+`modus-themes-after-load-theme-hook'."
+  (if (eq modus-themes-org-blocks 'gray-background)
+      (setq org-fontify-whole-block-delimiter-line t)
+    (setq org-fontify-whole-block-delimiter-line nil))
+  (when (derived-mode-p 'org-mode)
+    (font-lock-flush)))
+#+end_src
+
 ** Measure color contrast (DIY)
 :properties:
 :custom_id: h:02e25930-e71a-493d-828a-8907fc80f874
@@ -2032,7 +2427,7 @@ minutia and relevant commentary.
 Such knowledge may prove valuable while attempting to override some of
 the themes' colors: [[#h:307d95dd-8dbd-4ece-a543-10ae86f155a6][Override 
colors]].
 
-** Load theme depending on time of day
+** Load theme depending on time of day (DIY)
 :properties:
 :custom_id: h:1d1ef4b4-8600-4a09-993c-6de3af0ddd26
 :end:
@@ -2210,6 +2605,7 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + bm
 + bongo
 + boon
++ bookmark
 + breakpoint (provided by the built-in {{{file(gdb-mi.el)}}} library)
 + buffer-expose
 + calendar and diary
@@ -2229,7 +2625,6 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + corfu
 + counsel*
 + counsel-css
-+ counsel-notmuch
 + counsel-org-capture-string
 + cov
 + cperl-mode
@@ -2372,7 +2767,7 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + minibuffer-line
 + minimap
 + mmm-mode
-+ modeline
++ mode-line
 + mood-line
 + moody
 + mpdel
@@ -2475,8 +2870,8 @@ have lots of extensions, so the "full support" may not be 
100% true…
 + tuareg
 + typescript
 + undo-tree
-+ vc (built-in mode line status for version control)
-+ vc-annotate (the out put of {{{kbd(C-x v g)}}})
++ vc (vc-dir.el, vc-hooks.el)
++ vc-annotate (the output of {{{kbd(C-x v g)}}})
 + vdiff
 + vertico
 + vimish-fold
@@ -2511,8 +2906,10 @@ GNU Emacs distribution.
 #+cindex: Implicitly supported packages
 
 These do not require any extra styles because they are configured to
-inherit from some basic faces.  Please confirm.
+inherit from some basic faces or their dependencies which are directly
+supported by the themes.
 
++ counsel-notmuch
 + edit-indirect
 + evil-owl
 + fortran-mode
@@ -2524,7 +2921,7 @@ inherit from some basic faces.  Please confirm.
 + swift-mode
 + tab-bar-echo-area
 
-* Notes for individual packages
+* Notes on individual packages
 :properties:
 :custom_id: h:4c4d901a-84d7-4f20-bd99-0808c2b06eba
 :end:
@@ -2532,7 +2929,22 @@ inherit from some basic faces.  Please confirm.
 This section covers information that may be of interest to users of
 individual packages.
 
-** Note for dimmer.el
+** Note on inline Latex in Org buffers
+:properties:
+:custom_id: h:dd8478da-f56a-45cd-b199-b836c85c3c5a
+:end:
+
+Org can work with inline latex and related syntax.  To actually fontify
+those constructs, set the variable ~org-highlight-latex-and-related~ to
+the desired list of values (per its doc string).  For example:
+
+#+begin_src emacs-lisp
+(setq org-highlight-latex-and-related '(latex script))
+#+end_src
+
+Remember to use {{{kbd(M-x org-mode-restart)}}} for changes to take effect.
+
+** Note on dimmer.el
 :properties:
 :custom_id: h:8eb4b758-d318-4480-9ead-357a571beb93
 :end:
@@ -2568,7 +2980,7 @@ other value for that variable will turn the main 
background gray.  This
 inadvertently leads to the opposite of the intended utility of this
 package: it draws too much attention to unfocused windows.
 
-** Note for display-fill-column-indicator-mode
+** Note on display-fill-column-indicator-mode
 :properties:
 :custom_id: h:2a602816-bc1b-45bf-9675-4cbbd7bf6cab
 :end:
@@ -2600,7 +3012,7 @@ and have the foreground be indistinguishable from it.  
For example:
 
 [[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale using the 
themes' palette]].
 
-** Note for mmm-mode.el background colors
+** Note on mmm-mode.el background colors
 :properties:
 :custom_id: h:99cf0d6c-e478-4e26-9932-3bf3427d13f6
 :end:
@@ -2650,7 +3062,7 @@ very high cost of degraded legibility.
    `(mmm-special-submode-face ((,class :background ,green-refine-bg)))))
 #+end_src
 
-** Note for prism.el
+** Note on prism.el
 :properties:
 :alt_title: Note for prism
 :custom_id: h:a94272e0-99da-4149-9e80-11a7e67a2cf2
@@ -2746,6 +3158,42 @@ examples with the 4, 8, 16 colors):
                   magenta)))
 #+end_src
 
+** Note on god-mode.el
+:properties:
+:alt_title: Note for god-mode
+:custom_id: h:4da1d515-3e05-47ef-9e45-8251fc7e986a
+:end:
+
+The ~god-mode~ library does not provide faces that could be configured by
+the Modus themes.  Users who would like to get some visual feedback on
+the status of {{{kbd(M-x god-mode)}}} are instead encouraged by upstream to
+set up their own configurations, such as by changing the ~mode-line~ face
+([[#h:f4651d55-8c07-46aa-b52b-bed1e53463bb][Advanced customization 
(do-it-yourself)]]).  This is an adaptation of the
+approach followed in the upstream README:
+
+#+begin_src emacs-lisp
+(defun my-god-mode-update-mode-line ()
+  "Make `mode-line' blue if God local mode is active."
+  (modus-themes-with-colors
+    (if god-local-mode
+        (set-face-attribute 'mode-line nil
+                            :foreground blue-active
+                            :background bg-active-accent
+                            :box blue)
+      (set-face-attribute 'mode-line nil
+                          :foreground fg-active
+                          :background bg-active
+                          :box fg-alt))))
+
+(add-hook 'post-command-hook 'my-god-mode-update-mode-line)
+#+end_src
+
+We employ the ~modus-themes-with-colors~ which provides access to color
+variables defined by the active theme.  Its use is covered elsewhere in
+this manual ([[#h:51ba3547-b8c8-40d6-ba5a-4586477fd4ae][Face specs at scale 
using the themes' palette]]).  As for the
+attributes that can be passed to each face, start by consulting the
+documentation string of ~set-face-attribute~.
+
 ** Note on company-mode overlay pop-up
 :properties:
 :custom_id: h:20cef8c4-d11f-4053-8b2c-2872925780b1
@@ -2762,7 +3210,7 @@ instead of overlays.[fn::
 https://github.com/company-mode/company-mode/issues/1010][fn::
 https://github.com/tumashu/company-posframe/]
 
-** Note for ERC escaped color sequences
+** Note on ERC escaped color sequences
 :properties:
 :custom_id: h:98bdf319-1e32-4469-8a01-771200fba65c
 :end:
@@ -2795,14 +3243,14 @@ accessibility standard of the themes:
 Colors 0 and 1 are white and black respectively.  So combine them
 together, if you must.
 
-** Note for powerline or spaceline
+** Note on powerline or spaceline
 :properties:
 :custom_id: h:9130a8ba-d8e3-41be-a58b-3cb1eb7b6d17
 :end:
 
 Both Powerline and Spaceline package users will likely need to use the
 command ~powerline-reset~ whenever they make changes to their themes
-and/or modeline setup.
+and/or mode line setup.
 
 ** Note on SHR colors
 :properties:
@@ -2815,8 +3263,7 @@ specifications the webpage provides.
 
 Consult {{{kbd(C-h v shr-use-colors)}}}.
 
-
-** Note for EWW and Elfeed fonts (SHR fonts)
+** Note on EWW and Elfeed fonts (SHR fonts)
 :properties:
 :custom_id: h:e6c5451f-6763-4be7-8fdb-b4706a422a4c
 :end:
@@ -2830,7 +3277,7 @@ default font family is.  Its default value is non-nil, 
which means that
 
 [[#h:defcf4fc-8fa8-4c29-b12e-7119582cc929][Font configurations for Org and 
others]].
 
-** Note for Helm grep
+** Note on Helm grep
 :properties:
 :custom_id: h:d28879a2-8e4b-4525-986e-14c0f873d229
 :end:
@@ -2930,6 +3377,217 @@ you've customized any faces.
             "-draw"       "text %X,%Y '%c'"))))
 #+end_src
 
+* Frequently Asked Questions (FAQ)
+:properties:
+:custom_id: h:b3384767-30d3-4484-ba7f-081729f03a47
+:end:
+#+cindex: Frequently Asked Questions (FAQ)
+
+In this section we provide answers related to some aspects of the Modus
+themes' design and application.
+
+** Is the contrast ratio about adjacent colors?
+:properties:
+:custom_id: h:5ce7ae2e-9348-4e55-b4cf-9302345b1826
+:end:
+#+cindex: Contrast between adjacent colors
+
+The minimum contrast ratio in relative luminance that the themes conform
+with always refers to any given combination of background and foreground
+colors.  If we have some blue colored text next to a magenta one, both
+against a white background, we do not mean to imply that blue:magenta is
+7:1 in terms of relative luminance.  Rather, we state that blue:white
+and magenta:white each are 7:1 or higher.
+
+The point of reference is always the background.  Because colors have
+about the same minimum distance in luminance from their backdrop, they
+necessarily are fairly close to each other in this measure.  A possible
+blue:magenta combination would naturally be around 1:1 in contrast of
+the sort here considered.
+
+To differentiate between sequential colors, we rely on hueness by
+mapping contrasting hues to adjacent constructs, while avoiding
+exaggerations.  A blue next to a magenta can be told apart regardless of
+their respective contrast ratio against their common background.
+Exceptions would be tiny characters in arguably not so realistic cases,
+such as two dots drawn side-by-side which for some reason would need to
+be colored differently.  They would still be legible though, which is
+the primary objective of the Modus themes.
+
+** What does it mean to avoid exaggerations?
+:properties:
+:custom_id: h:44284e1f-fab8-4c4f-92f0-544728a7c91e
+:end:
+#+cindex: Avoiding exaggerations in design
+
+The Modus themes are designed with restraint, so that their default
+looks do not overdo it with the application of color.
+
+[[#h:bf1c82f2-46c7-4eb2-ad00-dd11fdd8b53f][Customization Options]].
+
+This is the non-quantifiable aspect of the themes' design: the artistic
+part, if you will.  There are a lot of cases where color can be used
+inconsiderately, without accounting for layout, typographic, or other
+properties of the presentation.  For example, two headings with distinct
+markers, such as leading asterisks in Org buffers, do not have to have
+highly contrasting hues between them in order to be told apart: the
+added element of contrast in hueness does not contribute significantly
+more to the distinction between the headings than colors whose hues are
+relatively closer to each other in the color space.
+
+Exaggerations can be hard to anticipate or identify.  Multiple shades of
+blue and magenta in the same context may not seem optimal: one might
+think that it would be better to use highly contrasting hues to ensure
+that all colors stand out, such as by placing blue next to yellow, next
+to magenta, and green.  That would, however, be a case of design for its
+own sake; a case where color is being applied without consideration of
+its end results in the given context.  Too many contrasting hues in
+close proximity force an erratic rate to how the eye jumps from one
+piece of text to the next.  Whereas multiple shades of, say, blue and
+magenta can suffice to tell things apart and avoid excess coloration: a
+harmonious rhythm.
+
+** Why are colors mostly variants of blue, magenta, cyan?
+:properties:
+:custom_id: h:0b26cb47-9733-4cb1-87d9-50850cb0386e
+:end:
+#+cindex: Innate color qualities of the palette
+
+Due to the innate properties of color, some options are better than
+others for the accessibility purposes of the themes, the stylistic
+consistency between ~modus-operandi~ and ~modus-vivendi~, and the avoidance
+of exaggerations in design.
+
+[[#h:44284e1f-fab8-4c4f-92f0-544728a7c91e][What does it mean to avoid 
exaggerations?]]
+
+What we describe as color is a function of three distinct channels of
+light: red, green, blue.  In hexadecimal RGB notation, a color value is
+read as three pairs of red, green, and blue light: =#RRGGBB=.  Of those
+three, the most luminant is green, while the least luminant is blue.
+
+The three basic colors represent each of the channels of light.  They
+can be intermixed to give us six colors: red and green derive yellow,
+green and blue make cyan, red and blue turn into magenta.
+
+We can test the luminance of each of those against white and black to
+get a sense of how not all colors are equally good for accessibility
+(white is =#ffffff=, which means that all three light channels are fully
+luminated, while black is =#000000= meaning that no light is present
+(notwithstanding display technology)).
+
+#+begin_example
+| Name    |         | #ffffff | #000000 |
+|---------+---------+---------+---------|
+| red     | #ff0000 |    4.00 |    5.25 |
+| yellow  | #ffff00 |    1.07 |   19.56 |
+| green   | #00ff00 |    1.37 |   15.30 |
+| cyan    | #00ffff |    1.25 |   16.75 |
+| blue    | #0000ff |    8.59 |    2.44 |
+| magenta | #ff00ff |    3.14 |    6.70 |
+#+end_example
+
+[[#h:02e25930-e71a-493d-828a-8907fc80f874][Measure color contrast]].
+
+By reading this table we learn that every color that has a high level of
+green light (green, yellow, cyan) is virtually unreadable against a
+white background and, conversely, can be easily read against black.
+
+We can then infer that red and blue, in different combinations, with
+green acting as calibrator for luminance, will give us fairly moderate
+colors that pass the 7:1 target.  Blue with a bit of green produce
+appropriate variants of cyan.  Similarly, blue combined with some red
+and hints of green give us suitable shades of purple.
+
+Due to the need of maintaining some difference in hueness between
+adjacent colors, it is not possible to make red, green, and yellow the
+primary colors, because blue could not be used to control their
+luminance and, thus the relevant space would shrink considerably.
+
+[[#h:5ce7ae2e-9348-4e55-b4cf-9302345b1826][Is the contrast ratio about 
adjacent colors?]]
+
+This phenomenon is best illustrated by the following table that measures
+the relative luminance of shades of red, yellow, magenta against white:
+
+#+begin_example
+|         | #ffffff |
+|---------+---------|
+| #990000 |    8.92 |
+| #995500 |    5.75 |
+| #990099 |    7.46 |
+#+end_example
+
+We notice that equal values of red and blue light in =#990099= (magenta
+shade) do not lead to a considerable change in luminance compared with
+=#990000= (red variant).  Whereas less amount of green light in =#995500=
+leads to a major drop in luminance relative to white.  It follows that
+using the green channel of light to calibrate the luminance of colors is
+more effective than trying to do the same with either red or blue (the
+latter is the least effective in that regard).
+
+When we need to work with several colors, it is always better to have
+sufficient manoeuvring space, especially since we cannot pick arbitrary
+colors but only those that satisfy the accessibility objectives of the
+themes.
+
+As for why we do not mostly use green, yellow, cyan for the dark theme,
+it is because those colors are far more luminant than their counterparts
+on the other side of the spectrum, so to ensure that they all have about
+the same contrast ratios we would have to alter their hueness
+considerably.  In short, the effect would not be optimal as it would
+lead to exaggerations.  Plus, it would make ~modus-vivendi~ look
+completely different than ~modus-operandi~, to the effect that the two
+could not be properly considered part of the same project.
+
+** What is the best setup for legibility?
+:properties:
+:custom_id: h:f60cc2ae-129d-47c0-9849-4f6bbd87d8be
+:end:
+#+cindex: General setup for readability
+
+The Modus themes can be conceptually simplified as combinations of color
+values that account for relative luminance and inner harmony.  Those
+qualities do not guarantee that every end-user will have the same
+experience, due to differences between people, but also because of
+variances in hardware capabilities and configurations.  For the purposes
+of this document, we may only provide suggestions pertaining to the
+latter case.
+
+~modus-operandi~ is best used outdoors or in a room that either gets
+direct sunlight or has plenty of light.  Whereas ~modus-vivendi~ works
+better when there is not a lot of sunshine or the room has a source of
+light, preferably a faint or warm one.  It is possible to use
+~modus-operandi~ at night and ~modus-vivendi~ during the day, though that
+will depend on several variables, such as one's overall perception of
+color, the paint on the walls and how that contributes to the impression
+of lightness in the room, the sense of space within the eye's peripheral
+vision, hardware specifications, and environmental factors.
+
+In general, an additional source of light other than that of the monitor
+can help reduce eye strain: the eyes are more relaxed when they do not
+have to focus on one point to gather light.
+
+The monitor's display settings must be accounted for.  Gamma ray values,
+in particular, need to be calibrated to neither amplify nor distort the
+perception of black.  Same principle for sharpness, brightness, and
+contrast as determined by the hardware, which all have an effect on how
+text is read on the screen.
+
+There are software level methods on offer, such as the XrandR utility
+for the X Window System (X.org), which can make gamma corrections for
+each of the three channels of light (red, green, blue).  For example:
+
+: xrandr --output LVDS1 --brightness 1.0 --gamma 0.76:0.75:0.68
+
+Typography is another variable.  Some font families are blurry at small
+point sizes.  Others may have a regular weight that is lighter (thiner)
+than that of their peers which may, under certain circumstances, cause a
+halo effect around each glyph.
+
+The gist is that legibility cannot be fully solved at the theme level.
+The color combinations may have been optimized for accessibility, though
+the remaining contributing factors in each case need to be considered in
+full.
+
 * Contributing
 :properties:
 :custom_id: h:9c3cd842-14b7-44d7-84b2-a5c8bc3fc3b1
@@ -3056,10 +3714,10 @@ The Modus themes are a collective effort.  Every bit of 
work matters.
 + Author/maintainer :: Protesilaos Stavrou.
 
 + Contributions to code or documentation :: Anders Johansson, Basil
-  L.{{{space()}}} Contovounesios, Carlo Zancanaro, Eli Zaretskii, Kostadin
-  Ninev, Madhavan Krishnan, Markus Beppler, Matthew Stevenson, Mauro
-  Aranda, Nicolas De Jaeghere, Shreyas Ragavan, Stefan Kangas, Vincent
-  Murphy, Xinglu Chen.
+  L.{{{space()}}} Contovounesios, Carlo Zancanaro, Eli Zaretskii, Fritz Grabo,
+  Kostadin Ninev, Madhavan Krishnan, Markus Beppler, Matthew Stevenson,
+  Mauro Aranda, Nicolas De Jaeghere, Rudolf Adamkovič, Shreyas Ragavan,
+  Stefan Kangas, Vincent Murphy, Xinglu Chen.
 
 + Ideas and user feedback :: Aaron Jensen, Adam Spiers, Adrian Manea,
   Alex Griffin, Alex Peitsinis, Alexey Shmalko, Alok Singh, Anders
@@ -3073,12 +3731,13 @@ The Modus themes are a collective effort.  Every bit of 
work matters.
   Ninev, Len Trigg, Manuel Uberti, Mark Burton, Markus Beppler, Mauro
   Aranda, Michael Goldenberg, Morgan Smith, Murilo Pereira, Nicky van
   Foreest, Nicolas De Jaeghere, Paul Poloskov, Pete Kazmier, Peter Wu,
-  Philip K., Pierre Téchoueyres, Roman Rudakov, Ryan Phillips, Sam
-  Kleinman, Shreyas Ragavan, Simon Pugnet, Tassilo Horn, Thibaut Verron,
-  Trey Merkley, Togan Muftuoglu, Toon Claes, Uri Sharf, Utkarsh Singh,
-  Vincent Foley.  As well as users: Ben, CsBigDataHub1, Emacs Contrib,
-  Eugene, Fourchaux, Fredrik, Moesasji, Nick, TheBlob42, Trey,
-  bepolymathe, doolio, fleimgruber, iSeeU, jixiuf, okamsn, pRot0ta1p.
+  Philip K., Pierre Téchoueyres, Roman Rudakov, Ryan Phillips, Rudolf
+  Adamkovič, Sam Kleinman, Shreyas Ragavan, Simon Pugnet, Tassilo Horn,
+  Thibaut Verron, Trey Merkley, Togan Muftuoglu, Toon Claes, Uri Sharf,
+  Utkarsh Singh, Vincent Foley.  As well as users: Ben, CsBigDataHub1,
+  Emacs Contrib, Eugene, Fourchaux, Fredrik, Moesasji, Nick, TheBlob42,
+  Trey, bepolymathe, doolio, fleimgruber, iSeeU, jixiuf, okamsn,
+  pRot0ta1p.
 
 + Packaging :: Basil L.{{{space()}}} Contovounesios, Eli Zaretskii, Glenn
   Morris, Mauro Aranda, Richard Stallman, Stefan Kangas (core Emacs),
diff --git a/etc/NEWS b/etc/NEWS
index 8bbb972..49bde94 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,7 +340,8 @@ When invoked like that, it prompts in the minibuffer for 
one of the
 previous kills, offering completion and minibuffer-history navigation
 through previous kills recorded in the kill ring.  A similar feature
 in Isearch can be invoked if you bind 'C-s M-y' to the command
-'isearch-yank-pop'.
+'isearch-yank-pop'.  When the user option 'yank-from-kill-ring-rotate'
+is nil the kill ring is not rotated after 'yank-from-kill-ring'.
 
 ---
 ** New user options 'copy-region-blink-delay' and 'delete-pair-blink-delay'.
@@ -441,6 +442,11 @@ major mode.
 
 * Changes in Specialized Modes and Packages in Emacs 28.1
 
+** Completion List Mode
+New key bindings have been added: 'n' and 'p' to navigate completions,
+and 'M-g M-c' to switch to the minibuffer, and you can also switch back
+to the completion list buffer with 'M-g M-c'.
+
 ** Benchmark
 *** New function 'benchmark-call' to measure the execution time of a function.
 Additionally, the number of repetitions can be expressed as a minimal duration
@@ -747,6 +753,11 @@ If set to non-nil, Dired will dereference symbolic links 
when copying.
 This can be switched off on a per-usage basis by providing
 'dired-do-copy' with a 'C-u' prefix.
 
+*** New user option 'dired-do-revert-buffer'.
+Non-nil reverts the destination Dired buffer after performing one
+of these operations: 'dired-do-copy', 'dired-do-rename',
+'dired-do-symlink', 'dired-do-hardlink'.
+
 *** New user option 'dired-mark-region' affects all Dired commands
 that mark files.  When non-nil and the region is active in Transient
 Mark mode, then Dired commands operate only on files in the active
@@ -1052,6 +1063,11 @@ commands and is globally bound to `C-h x'.
 *** New command 'describe-keymap' describes keybindings in a keymap.
 
 ---
+*** New user option 'describe-bindings-outline'.
+It enables outlines in the output buffer of `describe-bindings' that
+can provide a better overview in a long list of available bindings.
+
+---
 *** New keybinding 'C-h R' prompts for a manual to display and displays it.
 
 +++
@@ -1089,12 +1105,11 @@ so e.g. like 'C-x 8 [' inserts a left single quotation 
mark,
 'C-x \ [' does the same.
 
 ---
-*** New user options 'read-char-by-name-sort' and 'read-char-by-name-group'.
-'read-char-by-name-sort' defines the sorting order of characters for
-completion of 'C-x 8 RET TAB' and can be customized to sort them
-by codepoints instead of character names by default.  The 't' value of
-'read-char-by-name-group' groups the characters for completion of
-'C-x 8 RET TAB' by Unicode blocks.
+*** New user option 'read-char-by-name-sort'.
+It defines the sorting order of characters for completion of 'C-x 8 RET TAB'
+and can be customized to sort them by codepoints instead of character names.
+Additionally, you can group characters by Unicode blocks after customizing
+'completions-group' and 'completions-group-sort'.
 
 ---
 *** Improved language transliteration in Malayalam input methods.
@@ -2481,6 +2496,14 @@ This is to keep the same behavior as Eshell.
 
 * Incompatible Lisp Changes in Emacs 28.1
 
+---
+** Some floating-point numbers are now handled differently by the Lisp reader.
+In previous versions of Emacs, numbers with a trailing dot and an exponent
+were read as integers and the exponent ignored: 2.e6 was interpreted as the
+integer 2.  Such numerals are now read as floats with the exponent included:
+2.e6 is now read as the floating-point value 2000000.0.
+That is, (read-from-string "1.e3") => (1000.0 . 4) now.
+
 +++
 ** The 'lexical-binding' local variable is always enabled.
 Previously, if 'enable-local-variables' was nil, a 'lexical-binding'
@@ -2687,9 +2710,24 @@ The implementation was buggy, and multiple '&define' 
forms in an '&or'
 form should be exceedingly rare.  See the Info node "(elisp) Backtracking" in
 the Emacs Lisp reference manual for background.
 
+---
+** 'sql-*-statement-starters' are no longer defcustoms.
+These variables describe facts about the SQL standard and
+product-specific additions.  There should be no need for users to
+customize them.
+
 
 * Lisp Changes in Emacs 28.1
 
+---
+** Emacs now attempts to test for high-rate subprocess output more fairly.
+When several subprocesses produce output simultaneously at high rate,
+Emacs will now by default attempt to service them all in a round-robin
+fashion.  Set the new variable 'process-prioritize-lower-fds' to a
+non-nil value to get back the old behavior, whereby after reading
+from a subprocess, Emacs would check for output of other subprocesses
+in a way that is likely to read from the same process again.
+
 +++
 ** New function 'sxhash-equal-including-properties'.
 This is identical to 'sxhash-equal' but accounting also for string
@@ -2767,6 +2805,10 @@ each element is a list with three elements: a completion,
 a prefix string, and a suffix string.
 
 +++
+** New completion function 'group-function' for grouping candidates.
+It takes two arguments: a completion candidate and a 'transform' flag.
+
++++
 ** 'read-char-from-minibuffer' and 'y-or-n-p' support 'help-form'.
 If you bind 'help-form' to a non-nil value while calling these functions,
 then pressing 'C-h' ('help-char') causes the function to evaluate 'help-form'
diff --git a/etc/emacs.appdata.xml b/etc/emacs.metainfo.xml
similarity index 58%
rename from etc/emacs.appdata.xml
rename to etc/emacs.metainfo.xml
index ca6233a..7467b88 100644
--- a/etc/emacs.appdata.xml
+++ b/etc/emacs.metainfo.xml
@@ -3,9 +3,9 @@
 <component type="desktop-application">
  <id>org.gnu.emacs</id>
  <metadata_license>GFDL-1.3+</metadata_license>
- <project_license>GPL-3.0+ and GFDL-1.3+</project_license>
  <name>GNU Emacs</name>
  <summary>An extensible text editor</summary>
+ <icon type="remote" width="128" 
height="128">https://www.gnu.org/software/emacs/images/emacs.png</icon>
  <description>
   <p>
    GNU Emacs is an extensible, customizable text editor - and more.
@@ -23,13 +23,26 @@
    interface, calendar, and more</li>
   </ul>
  </description>
+ <categories>
+   <category>Development</category>
+   <category>TextEditor</category>
+ </categories>
+ <url type="homepage">https://www.gnu.org/software/emacs</url>
+ <url type="bugtracker">https://debbugs.gnu.org/</url>
+ <url 
type="faq">https://www.gnu.org/software/emacs/manual/html_mono/efaq.html</url>
+ <url type="help">https://www.gnu.org/software/emacs/documentation.html</url>
+ <url type="donation">https://my.fsf.org/donate/</url>
+ <url type="contact">https://lists.gnu.org/mailman/listinfo/emacs-devel/</url>
+ <launchable type="desktop-id">emacs.desktop</launchable>
+ <launchable type="service">emacs.service</launchable>
+ <project_group>GNU</project_group>
+ <project_license>GPL-3.0+ and GFDL-1.3+</project_license>
+ <developer_name>Free Software Foundation</developer_name>
  <screenshots>
   <screenshot type="default">
-  <image type="source" width="632" 
height="354">https://www.gnu.org/software/emacs/images/appdata-26.png</image>
- </screenshot>
+    <image type="source" width="632" 
height="354">https://www.gnu.org/software/emacs/images/appdata-26.png</image>
+    <caption>Editing a Lisp program whilst viewing the Emacs manual.</caption>
+  </screenshot>
  </screenshots>
- <launchable type="desktop-id">emacs</launchable>
- <url type="homepage">https://www.gnu.org/software/emacs</url>
  <update_contact>emacs-devel_AT_gnu.org</update_contact>
- <project_group>GNU</project_group>
 </component>
diff --git a/etc/themes/modus-operandi-theme.el 
b/etc/themes/modus-operandi-theme.el
index 77c2e11..cd73681 100644
--- a/etc/themes/modus-operandi-theme.el
+++ b/etc/themes/modus-operandi-theme.el
@@ -4,7 +4,7 @@
 
 ;; Author: Protesilaos Stavrou <info@protesilaos.com>
 ;; URL: https://gitlab.com/protesilaos/modus-themes
-;; Version: 1.3.2
+;; Version: 1.4.0
 ;; Package-Requires: ((emacs "26.1"))
 ;; Keywords: faces, theme, accessibility
 
diff --git a/etc/themes/modus-themes.el b/etc/themes/modus-themes.el
index 08e634e..c70c560 100644
--- a/etc/themes/modus-themes.el
+++ b/etc/themes/modus-themes.el
@@ -4,8 +4,8 @@
 
 ;; Author: Protesilaos Stavrou <info@protesilaos.com>
 ;; URL: https://gitlab.com/protesilaos/modus-themes
-;; Version: 1.3.2
-;; Last-Modified: <2021-04-18 06:25:05 +0300>
+;; Version: 1.4.0
+;; Last-Modified: <2021-05-25 12:25:39 +0300>
 ;; Package-Requires: ((emacs "26.1"))
 ;; Keywords: faces, theme, accessibility
 
@@ -28,21 +28,23 @@
 ;;
 ;; The Modus themes conform with the highest standard for color-contrast
 ;; accessibility between background and foreground values (WCAG AAA).
-;; This file contains all customization options, helper functions,
+;; This file contains all customization variables, helper functions,
 ;; interactive commands, and face specifications.  Please refer to the
 ;; official Info manual for further documentation (distributed with the
 ;; themes, or available at: <https://protesilaos.com/modus-themes>).
 ;;
-;; The themes share the following customization options, all of which
+;; The themes share the following customization variables, all of which
 ;; are disabled by default (nil):
 ;;
 ;;     modus-themes-slanted-constructs             (boolean)
 ;;     modus-themes-bold-constructs                (boolean)
 ;;     modus-themes-variable-pitch-headings        (boolean)
 ;;     modus-themes-variable-pitch-ui              (boolean)
+;;     modus-themes-scale-headings                 (boolean)
+;;     modus-themes-subtle-line-numbers            (boolean)
+;;     modus-themes-success-deuteranopia           (boolean)
 ;;     modus-themes-no-mixed-fonts                 (boolean)
 ;;     modus-themes-headings                       (alist)
-;;     modus-themes-scale-headings                 (boolean)
 ;;     modus-themes-fringes                        (choice)
 ;;     modus-themes-lang-checkers                  (choice)
 ;;     modus-themes-org-blocks                     (choice)
@@ -52,11 +54,11 @@
 ;;     modus-themes-diffs                          (choice)
 ;;     modus-themes-syntax                         (choice)
 ;;     modus-themes-hl-line                        (choice)
-;;     modus-themes-subtle-line-numbers            (boolean)
 ;;     modus-themes-paren-match                    (choice)
 ;;     modus-themes-region                         (choice)
 ;;     modus-themes-links                          (choice)
 ;;     modus-themes-completions                    (choice)
+;;     modus-themes-mail-citations                 (choice)
 ;;
 ;; The default scale for headings is as follows (it can be customized as
 ;; well---remember, no scaling takes place by default):
@@ -67,7 +69,7 @@
 ;;     modus-themes-scale-4 1.2
 ;;     modus-themes-scale-5 1.3
 ;;
-;; There also exist two unique customization options for overriding
+;; There also exist two unique customization variables for overriding
 ;; color palette values.  The specifics are documented in the manual.
 ;; The symbols are:
 ;;
@@ -97,6 +99,7 @@
 ;;     bm
 ;;     bongo
 ;;     boon
+;;     bookmark
 ;;     breakpoint (provided by built-in gdb-mi.el)
 ;;     buffer-expose
 ;;     calendar and diary
@@ -116,7 +119,6 @@
 ;;     corfu
 ;;     counsel
 ;;     counsel-css
-;;     counsel-notmuch
 ;;     counsel-org-capture-string
 ;;     cov
 ;;     cperl-mode
@@ -259,7 +261,7 @@
 ;;     minibuffer-line
 ;;     minimap
 ;;     mmm-mode
-;;     modeline
+;;     mode-line
 ;;     mood-line
 ;;     mpdel
 ;;     mu4e
@@ -360,7 +362,7 @@
 ;;     tuareg
 ;;     typescript
 ;;     undo-tree
-;;     vc (built-in mode line status for version control)
+;;     vc (vc-dir.el, vc-hooks.el)
 ;;     vc-annotate (C-x v g)
 ;;     vdiff
 ;;     vertico
@@ -414,7 +416,15 @@
 (eval-when-compile (require 'cl-lib))
 
 (defgroup modus-themes ()
-  "Options for `modus-operandi', `modus-vivendi'."
+  "Options for `modus-operandi', `modus-vivendi'.
+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."
   :group 'faces
   :link '(info-link "(modus-themes) Top")
   :prefix "modus-themes-"
@@ -424,16 +434,6 @@
 
 ;;;; Modus Operandi
 
-(define-obsolete-variable-alias
-  'modus-operandi-theme-default-colors-alist
-  'modus-themes-colors-operandi
-  "1.0.0")
-
-(define-obsolete-variable-alias
-  'modus-themes-colors-operandi
-  'modus-themes-operandi-colors
-  "1.1.0")
-
 (defconst modus-themes-operandi-colors
   '(;; base values
     (bg-main . "#ffffff") (fg-main . "#000000")
@@ -587,10 +587,6 @@
     ;; bg-tab-bar is only intended for the bar that holds the tabs and
     ;; can only be combined with fg-main
     ;;
-    ;; fg-tab-accent is meant to be combined with bg-tab-active,
-    ;; though only for styling special elements, such as underlining
-    ;; the current tab
-    ;;
     ;; fg-escape-char-construct and fg-escape-char-backslash can
     ;; be combined bg-main, bg-dim, bg-alt
     ;;
@@ -610,10 +606,12 @@
     ;; all pairs are combinable with themselves
     (bg-hl-line . "#f2eff3")
     (bg-hl-line-intense . "#e0e0e0")
+    (bg-hl-line-intense-accent . "#b9e1ef")
     (bg-hl-alt . "#fbeee0")
     (bg-hl-alt-intense . "#e8dfd1")
     (bg-paren-match . "#e0af82")
     (bg-paren-match-intense . "#c488ff")
+    (bg-paren-expression . "#dff0ff")
     (bg-region . "#bcbcbc")
     (bg-region-accent . "#afafef")
 
@@ -621,7 +619,6 @@
     (bg-tab-active . "#f6f6f6")
     (bg-tab-inactive . "#bdbdbd")
     (bg-tab-inactive-alt . "#999999")
-    (fg-tab-accent . "#30169e")
 
     (red-tab . "#680000")
     (green-tab . "#003900")
@@ -648,7 +645,7 @@
     (fg-unfocused . "#56576d")
 
     (fg-docstring . "#2a486a")
-    (fg-comment-yellow . "#5f4400")
+    (fg-comment-yellow . "#794319")
 
     (bg-header . "#e5e5e5") (fg-header . "#2a2a2a")
 
@@ -673,22 +670,12 @@
     (bg-mark-sel . "#a0f0cf") (fg-mark-sel . "#005040")
     (bg-mark-del . "#ffccbb") (fg-mark-del . "#840040")
     (bg-mark-alt . "#f5d88f") (fg-mark-alt . "#782900"))
-  "The entire palette of `modus-operandi' theme.
+  "The entire palette of the `modus-operandi' theme.
 Each element has the form (NAME . HEX) with the former as a
 symbol and the latter as a string.")
 
 ;;;; Modus Vivendi
 
-(define-obsolete-variable-alias
-  'modus-vivendi-theme-default-colors-alist
-  'modus-themes-colors-vivendi
-  "1.0.0")
-
-(define-obsolete-variable-alias
-  'modus-themes-colors-vivendi
-  'modus-themes-vivendi-colors
-  "1.1.0")
-
 (defconst modus-themes-vivendi-colors
   '(;; base values
     (bg-main . "#000000") (fg-main . "#ffffff")
@@ -712,29 +699,29 @@ symbol and the latter as a string.")
     (bg-special-calm . "#392a48") (fg-special-calm . "#fbd6f4")
     ;; foregrounds that can be combined with bg-main, bg-dim, bg-alt
     (red . "#ff8059")
-    (red-alt . "#f4923b")
-    (red-alt-other . "#ff9977")
+    (red-alt . "#ef8b50")
+    (red-alt-other . "#ff9077")
     (red-faint . "#ffa0a0")
     (red-alt-faint . "#f5aa80")
     (red-alt-other-faint . "#ff9fbf")
     (green . "#44bc44")
-    (green-alt . "#70c900")
-    (green-alt-other . "#00cd68")
-    (green-faint . "#88cf88")
-    (green-alt-faint . "#a8cf88")
-    (green-alt-other-faint . "#88cfaf")
-    (yellow . "#eecc00")
-    (yellow-alt . "#cfdf30")
-    (yellow-alt-other . "#f0ce43")
+    (green-alt . "#70b900")
+    (green-alt-other . "#00c06f")
+    (green-faint . "#78bf78")
+    (green-alt-faint . "#99b56f")
+    (green-alt-other-faint . "#88bf99")
+    (yellow . "#e0cc00")
+    (yellow-alt . "#c4d030")
+    (yellow-alt-other . "#e3c55f")
     (yellow-faint . "#d2b580")
     (yellow-alt-faint . "#cabf77")
     (yellow-alt-other-faint . "#d0ba95")
     (blue . "#2fafff")
     (blue-alt . "#79a8ff" )
     (blue-alt-other . "#00bcff")
-    (blue-faint . "#92baff")
-    (blue-alt-faint . "#a0acf5")
-    (blue-alt-other-faint . "#87c8ff")
+    (blue-faint . "#82b0ec")
+    (blue-alt-faint . "#a0acef")
+    (blue-alt-other-faint . "#80b2f0")
     (magenta . "#feacd0")
     (magenta-alt . "#f78fe7")
     (magenta-alt-other . "#b6a0ff")
@@ -742,7 +729,7 @@ symbol and the latter as a string.")
     (magenta-alt-faint . "#ef9fe4")
     (magenta-alt-other-faint . "#cfa6ff")
     (cyan . "#00d3d0")
-    (cyan-alt . "#4ae8fc")
+    (cyan-alt . "#4ae2f0")
     (cyan-alt-other . "#6ae4b9")
     (cyan-faint . "#90c4ed")
     (cyan-alt-faint . "#a0bfdf")
@@ -842,10 +829,6 @@ symbol and the latter as a string.")
     ;; bg-tab-bar is only intended for the bar that holds the tabs and
     ;; can only be combined with fg-main
     ;;
-    ;; fg-tab-accent is meant to be combined with bg-tab-active,
-    ;; though only for styling special elements, such as underlining
-    ;; the current tab
-    ;;
     ;; fg-escape-char-construct and fg-escape-char-backslash can
     ;; be combined bg-main, bg-dim, bg-alt
     ;;
@@ -865,10 +848,12 @@ symbol and the latter as a string.")
     ;; all pairs are combinable with themselves
     (bg-hl-line . "#151823")
     (bg-hl-line-intense . "#2f2f2f")
+    (bg-hl-line-intense-accent . "#00353f")
     (bg-hl-alt . "#181732")
     (bg-hl-alt-intense . "#282e46")
     (bg-paren-match . "#5f362f")
     (bg-paren-match-intense . "#7416b5")
+    (bg-paren-expression . "#221044")
     (bg-region . "#3c3c3c")
     (bg-region-accent . "#4f3d88")
 
@@ -876,7 +861,6 @@ symbol and the latter as a string.")
     (bg-tab-active . "#0e0e0e")
     (bg-tab-inactive . "#3d3d3d")
     (bg-tab-inactive-alt . "#595959")
-    (fg-tab-accent . "#5ac3cf")
 
     (red-tab . "#ffc0bf")
     (green-tab . "#88ef88")
@@ -903,7 +887,7 @@ symbol and the latter as a string.")
     (fg-unfocused . "#93959b")
 
     (fg-docstring . "#b0d6f5")
-    (fg-comment-yellow . "#cab98f")
+    (fg-comment-yellow . "#d0a070")
 
     (bg-header . "#212121") (fg-header . "#dddddd")
 
@@ -928,7 +912,7 @@ symbol and the latter as a string.")
     (bg-mark-sel . "#002f2f") (fg-mark-sel . "#60cfa2")
     (bg-mark-del . "#5a0000") (fg-mark-del . "#ff99aa")
     (bg-mark-alt . "#3f2210") (fg-mark-alt . "#f0aa20"))
-  "The entire palette of `modus-vivendi' theme.
+  "The entire palette of the `modus-vivendi' theme.
 Each element has the form (NAME . HEX) with the former as a
 symbol and the latter as a string.")
 
@@ -1080,38 +1064,38 @@ or for completion interfaces.
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-active-red nil
-  "A red background meant for use on the modeline or similar.
-This is combined with the modelines primary foreground value.
+  "A red background meant for use on the mode line or similar.
+This is combined with the mode lines primary foreground value.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-active-green nil
-  "A green background meant for use on the modeline or similar.
-This is combined with the modelines primary foreground value.
+  "A green background meant for use on the mode line or similar.
+This is combined with the mode lines primary foreground value.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-active-yellow nil
-  "A yellow background meant for use on the modeline or similar.
-This is combined with the modelines primary foreground value.
+  "A yellow background meant for use on the mode line or similar.
+This is combined with the mode lines primary foreground value.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-active-blue nil
-  "A blue background meant for use on the modeline or similar.
-This is combined with the modelines primary foreground value.
+  "A blue background meant for use on the mode line or similar.
+This is combined with the mode lines primary foreground value.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-active-magenta nil
-  "A magenta background meant for use on the modeline or similar.
-This is combined with the modelines primary foreground value.
+  "A magenta background meant for use on the mode line or similar.
+This is combined with the mode lines primary foreground value.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-active-cyan nil
-  "A cyan background meant for use on the modeline or similar.
-This is combined with the modelines primary foreground value.
+  "A cyan background meant for use on the mode line or similar.
+This is combined with the mode lines primary foreground value.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
@@ -1153,81 +1137,87 @@ The actual styling of the face is done by 
`modus-themes-faces'.")
 
 (defface modus-themes-nuanced-red nil
   "A nuanced red background.
-This does not specify a foreground of its own.  Instead it is meant to
-serve as the backdrop for elements such as Org blocks, headings, and any
-other surface that needs to retain the colors on display.
+This does not specify a foreground of its own.  Instead it is
+meant to serve as the backdrop for elements such as Org blocks,
+headings, and any other surface that needs to retain the colors
+on display.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-nuanced-green nil
   "A nuanced green background.
-This does not specify a foreground of its own.  Instead it is meant to
-serve as the backdrop for elements such as Org blocks, headings, and any
-other surface that needs to retain the colors on display.
+This does not specify a foreground of its own.  Instead it is
+meant to serve as the backdrop for elements such as Org blocks,
+headings, and any other surface that needs to retain the colors
+on display.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-nuanced-yellow nil
   "A nuanced yellow background.
-This does not specify a foreground of its own.  Instead it is meant to
-serve as the backdrop for elements such as Org blocks, headings, and any
-other surface that needs to retain the colors on display.
+This does not specify a foreground of its own.  Instead it is
+meant to serve as the backdrop for elements such as Org blocks,
+headings, and any other surface that needs to retain the colors
+on display.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-nuanced-blue nil
   "A nuanced blue background.
-This does not specify a foreground of its own.  Instead it is meant to
-serve as the backdrop for elements such as Org blocks, headings, and any
-other surface that needs to retain the colors on display.
+This does not specify a foreground of its own.  Instead it is
+meant to serve as the backdrop for elements such as Org blocks,
+headings, and any other surface that needs to retain the colors
+on display.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-nuanced-magenta nil
   "A nuanced magenta background.
-This does not specify a foreground of its own.  Instead it is meant to
-serve as the backdrop for elements such as Org blocks, headings, and any
-other surface that needs to retain the colors on display.
+This does not specify a foreground of its own.  Instead it is
+meant to serve as the backdrop for elements such as Org blocks,
+headings, and any other surface that needs to retain the colors
+on display.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-nuanced-cyan nil
   "A nuanced cyan background.
-This does not specify a foreground of its own.  Instead it is meant to
-serve as the backdrop for elements such as Org blocks, headings, and any
-other surface that needs to retain the colors on display.
+This does not specify a foreground of its own.  Instead it is
+meant to serve as the backdrop for elements such as Org blocks,
+headings, and any other surface that needs to retain the colors
+on display.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-special-cold nil
   "Combines the 'special cold' background and foreground values.
 This is intended for cases when a neutral gray background is not
-suitable and where a combination of more saturated colors would not be
-appropriate.
+suitable and where a combination of more saturated colors would
+not be appropriate.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-special-mild nil
   "Combines the 'special mild' background and foreground values.
 This is intended for cases when a neutral gray background is not
-suitable and where a combination of more saturated colors would not be
-appropriate.
+suitable and where a combination of more saturated colors would
+not be appropriate.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-special-warm nil
   "Combines the 'special warm' background and foreground values.
 This is intended for cases when a neutral gray background is not
-suitable and where a combination of more saturated colors would not be
-appropriate.
+suitable and where a combination of more saturated colors would
+not be appropriate.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-special-calm nil
   "Combines the 'special calm' background and foreground values.
 This is intended for cases when a neutral gray background is not
-suitable and where a combination of more saturated colors would not be
-appropriate.
+suitable and where a combination of more saturated colors would
+not be appropriate.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
@@ -1331,64 +1321,64 @@ The actual styling of the face is done by 
`modus-themes-faces'.")
 
 (defface modus-themes-heading-1 nil
   "General purpose face for use in headings level 1.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-heading-2 nil
   "General purpose face for use in headings level 2.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-heading-3 nil
   "General purpose face for use in headings level 3.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-heading-4 nil
   "General purpose face for use in headings level 4.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-heading-5 nil
   "General purpose face for use in headings level 5.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-heading-6 nil
   "General purpose face for use in headings level 6.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-heading-7 nil
   "General purpose face for use in headings level 7.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-heading-8 nil
   "General purpose face for use in headings level 8.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-headings' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-headings' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-hl-line nil
   "General purpose face for the current line.
-The exact attributes assigned to this face are contingent on the values
-assigned to the `modus-themes-hl-line' variable.
+The exact attributes assigned to this face are contingent on the
+values assigned to the `modus-themes-hl-line' variable.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
@@ -1414,97 +1404,97 @@ The actual styling of the face is done by 
`modus-themes-faces'.")
 
 (defface modus-themes-graph-red-0 nil
   "Special subdued red face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-red-1 nil
   "Special prominent red face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-green-0 nil
   "Special subdued green face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-green-1 nil
   "Special prominent green face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-yellow-0 nil
   "Special subdued yellow face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-yellow-1 nil
   "Special prominent yellow face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-blue-0 nil
   "Special subdued blue face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-blue-1 nil
   "Special prominent blue face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-magenta-0 nil
   "Special subdued magenta face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-magenta-1 nil
   "Special prominent magenta face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-cyan-0 nil
   "Special subdued cyan face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
 (defface modus-themes-graph-cyan-1 nil
   "Special prominent cyan face for use in graphs.
-This is intended to be applied in contexts such as the Org agenda habit
-graph where faithfulness to the semantics of a color value is of
-paramount importance.
+This is intended to be applied in contexts such as the Org agenda
+habit graph where faithfulness to the semantics of a color value
+is of paramount importance.
 
 The actual styling of the face is done by `modus-themes-faces'.")
 
@@ -1553,11 +1543,21 @@ The actual styling of the face is done by 
`modus-themes-faces'.")
   "Generic face for key bindings.
 The actual styling of the face is done by `modus-themes-faces'.")
 
-
+(defface modus-themes-search-success nil
+  "Generic face for successful search.
+The actual styling of the face is done by `modus-themes-faces'.")
 
-;;; Customization options
+(defface modus-themes-search-success-modeline nil
+  "Generic mode line indicator for successful search.
+The actual styling of the face is done by `modus-themes-faces'.")
 
-;;;; Current customization options (>= 1.0.0)
+(defface modus-themes-search-success-lazy nil
+  "Generic face for successful, lazily highlighted search.
+The actual styling of the face is done by `modus-themes-faces'.")
+
+
+
+;;; Customization variables
 
 (defcustom modus-themes-operandi-color-overrides nil
   "Override colors in the Modus Operandi palette.
@@ -1934,28 +1934,43 @@ most intense combination of face properties."
 (defcustom modus-themes-org-blocks nil
   "Use a subtle gray or color-coded background for Org blocks.
 
-Nil means that the block will have no background of its own and
-will use the default that applies to the rest of the buffer.
-
-Option `grayscale' (or `greyscale') will apply a subtle neutral
-gray background to the block's contents.  It also affects the
-begin and end lines of the block: their background will be
-extended to the edge of the window for Emacs version >= 27 where
-the ':extend' keyword is recognized by `set-face-attribute'.
+Nil (the default) means that the block has no distinct background
+of its own and uses the one that applies to the rest of the
+buffer.
+
+Option `gray-background' applies a subtle gray background to the
+block's contents.  It also affects the begin and end lines of the
+block: their background extends to the edge of the window for
+Emacs version >= 27 where the ':extend' keyword is recognized by
+`set-face-attribute' (this is contingent on the variable
+`org-fontify-whole-block-delimiter-line').
+
+Option `tinted-background' uses a slightly colored background for
+the contents of the block.  The exact color will depend on the
+programming language and is controlled by the variable
+`org-src-block-faces' (refer to the theme's source code for the
+current association list).  For this to take effect, the Org
+buffer needs to be restarted with `org-mode-restart'.
+
+Code blocks use their major mode's colors only when the variable
+`org-src-fontify-natively' is non-nil.  While quote/verse blocks
+require setting `org-fontify-quote-and-verse-blocks' to a non-nil
+value.
 
-Option `rainbow' will use an accented background for the contents
-of the block.  The exact color will depend on the programming
-language and is controlled by the `org-src-block-faces'
-variable (refer to the theme's source code for the current
-association list)."
+Older versions of the themes provided options `grayscale' (or
+`greyscale') and `rainbow'.  Those will continue to work as they
+are aliases for `gray-background' and `tinted-background',
+respectively."
   :group 'modus-themes
-  :package-version '(modus-themes . "1.0.0")
+  :package-version '(modus-themes . "1.4.0")
   :version "28.1"
   :type '(choice
           (const :format "[%v] %t\n" :tag "No Org block background (default)" 
nil)
-          (const :format "[%v] %t\n" :tag "Subtle gray block background" 
grayscale)
-          (const :format "[%v] %t\n" :tag "Subtle gray block background (alt 
spelling)" greyscale)
-          (const :format "[%v] %t\n" :tag "Color-coded background per 
programming language" rainbow))
+          (const :format "[%v] %t\n" :tag "Subtle gray block background" 
gray-background)
+          (const :format "[%v] %t\n" :tag "Alias for `gray-background'" 
grayscale) ; for backward compatibility
+          (const :format "[%v] %t\n" :tag "Alias for `gray-background'" 
greyscale)
+          (const :format "[%v] %t\n" :tag "Color-coded background per 
programming language" tinted-background)
+          (const :format "[%v] %t\n" :tag "Alias for `tinted-background'" 
rainbow)) ; back compat
   :link '(info-link "(modus-themes) Org mode blocks"))
 
 (defcustom modus-themes-org-habit nil
@@ -2000,19 +2015,19 @@ highlights the alert and overdue states."
   "Adjust the overall style of the mode line.
 
 The default (nil) is a two-dimensional rectangle with a border
-around it.  The active and the inactive modelines use different
+around it.  The active and the inactive mode lines use different
 shades of grayscale values for the background and foreground.
 
 A `3d' value will apply a three-dimensional effect to the active
-modeline.  The inactive modelines remain two-dimensional and are
-toned down a bit, relative to the nil value.
+mode line.  The inactive mode lines remain two-dimensional and
+are toned down a bit, relative to the nil value.
 
-The `moody' option is meant to optimize the modeline for use with
-the library of the same name.  This practically means to remove
-the box effect and rely on underline and overline properties
-instead.  It also tones down the inactive modelines.  Despite its
-intended purpose, this option can also be used without the
-`moody' library.
+The `moody' option is meant to optimize the mode line for use
+with the library of the same name.  This practically means to
+remove the box effect and rely on underline and overline
+properties instead.  It also tones down the inactive mode lines.
+Despite its intended purpose, this option can also be used
+without the `moody' library.
 
 The `borderless' option uses the same colors as the default (nil
 value), but removes the border effect.  This is done by making
@@ -2021,7 +2036,7 @@ effectively blending the two and creating some padding.
 
 The `borderless-3d' and `borderless-moody' approximate the `3d'
 and `moody' options respectively, while removing the borders.
-However, to ensure that the inactive modelines remain visible,
+However, to ensure that the inactive mode lines remain visible,
 they apply a slightly more prominent background to them than what
 their counterparts do (same inactive background as with the
 default).
@@ -2029,84 +2044,110 @@ default).
 Similarly, `accented', `accented-3d', and `accented-moody'
 correspond to the default (nil), `3d', and `moody' styles
 respectively, except that the active mode line uses a colored
-background instead of the standard shade of gray."
+background instead of the standard shade of gray.
+
+Same principle for styles `borderless-accented',
+`borderless-accented-3d', `borderless-accented-moody', which
+apply a colored background to the active mode line, while they
+remove any noticeable border around both the active and inactive
+the mode lines."
   :group 'modus-themes
-  :package-version '(modus-themes . "1.3.0")
+  :package-version '(modus-themes . "1.4.0")
   :version "28.1"
   :type '(choice
           (const :format "[%v] %t\n" :tag "Two-dimensional box (default)" nil)
           (const :format "[%v] %t\n" :tag "Three-dimensional style for the 
active mode line" 3d)
           (const :format "[%v] %t\n" :tag "No box effects, which are optimal 
for use with the `moody' library" moody)
-          (const :format "[%v] %t\n" :tag "Like the default, but without 
border effects" borderless)
+          (const :format "[%v] %t\n" :tag "Like the default, but without 
discernible border effects" borderless)
           (const :format "[%v] %t\n" :tag "Like `3d', but without noticeable 
border" borderless-3d)
           (const :format "[%v] %t\n" :tag "Like `moody', but without 
noticeable border" borderless-moody)
           (const :format "[%v] %t\n" :tag "Two-dimensional box with a colored 
background" accented)
           (const :format "[%v] %t\n" :tag "Like `3d', but with a colored 
background" accented-3d)
-          (const :format "[%v] %t\n" :tag "Like `moody', but with a colored 
background" accented-moody))
+          (const :format "[%v] %t\n" :tag "Like `moody', but with a colored 
background" accented-moody)
+          (const :format "[%v] %t\n" :tag "Like `accented', but without a 
noticeable border" borderless-accented)
+          (const :format "[%v] %t\n" :tag "Like `accented-3d', but with a 
noticeable border" borderless-accented-3d)
+          (const :format "[%v] %t\n" :tag "Like `accented-moody', but with a 
noticeable border" borderless-accented-moody))
   :link '(info-link "(modus-themes) Mode line"))
 
 (defcustom modus-themes-diffs nil
-  "Adjust the overall styles of diffs.
-
-Nil means to use fairly intense color combinations for diffs.
-For example, you get a rich green background with a green
-foreground for added lines.  Word-wise or 'refined' diffs follow
-the same pattern but use different shades of those colors to
-remain distinct.
+  "Adjust the overall style of diffs.
 
-A `desaturated' value follows the same principles as with the nil
-option, while it tones down all relevant colors.
+The default (nil) uses fairly intense color combinations for
+diffs, by applying prominently colored backgrounds, with
+appropriate foregrounds.
 
-Option `fg-only' will remove all accented backgrounds, except
-from word-wise changes.  It instead uses color-coded foreground
-values to differentiate between added/removed/changed lines.  If
-a background is necessary, such as with `ediff', then a subtle
-grayscale value is used.
+Option `desaturated' follows the same principles as with the
+default (nil), though it tones down all relevant colors.
 
 Option `bg-only' applies a background but does not override the
 text's foreground.  This makes it suitable for a non-nil value
 passed to `diff-font-lock-syntax' (note: Magit does not support
-syntax highlighting in diffs as of 2020-11-25, version
-20201116.1057).
-
-Option `deuteranopia' accounts for red-green color defficiency by
-replacing all instances of green with colors on the blue side of
-the spectrum.  Other stylistic changes are made in the interest
-of optimizing for such a use-case."
+syntax highlighting in diffs---last checked on 2021-04-21).
+
+Option `deuteranopia' is like the default (nil) in terms of using
+prominently colored backgrounds, except that it also accounts for
+red-green color defficiency by replacing all instances of green
+with colors on the blue side of the spectrum.  Other stylistic
+changes are made in the interest of optimizing for such a
+use-case.
+
+Option `fg-only-deuteranopia' removes all colored backgrounds,
+except from word-wise or refined changes.  Instead, it only uses
+color-coded foreground values to differentiate between added,
+removed, and changed lines.  If a background is necessary to
+denote context, a subtle grayscale value is applied.  The color
+used for added lines is a variant of blue to account for
+red-green color defficiency but also because green text alone is
+hard to discern in the diff's context (hard for our accessibility
+purposes).  The `fg-only' option that existed in older versions
+of the themes is now an alias of `fg-only-deuteranopia', in the
+interest of backward compatibility."
   :group 'modus-themes
-  :package-version '(modus-themes . "1.2.0")
+  :package-version '(modus-themes . "1.4.0")
   :version "28.1"
   :type '(choice
           (const :format "[%v] %t\n" :tag "Intensely colored backgrounds 
(default)" nil)
           (const :format "[%v] %t\n" :tag "Slightly accented backgrounds with 
tinted text" desaturated)
-          (const :format "[%v] %t\n" :tag "No backgrounds, except for refined 
diffs" fg-only)
           (const :format "[%v] %t\n" :tag "Apply color-coded backgrounds; keep 
syntax colors in tact" bg-only)
-          (const :format "[%v] %t\n" :tag "Optimized for red-green color 
defficiency" deuteranopia))
+          (const :format "[%v] %t\n" :tag "Like the default (nil), though 
optimized for red-green color defficiency" deuteranopia)
+          (const :format "[%v] %t\n" :tag "No backgrounds, except for refined 
diffs" fg-only-deuteranopia)
+          (const :format "[%v] %t\n" :tag "Alias of `fg-only-deuteranopia' for 
backward compatibility" fg-only))
   :link '(info-link "(modus-themes) Diffs"))
 
 (defcustom modus-themes-completions nil
-  "Apply special styles to the UI of completion frameworks.
-
-This concerns Icomplete, Ivy, Helm, Selectrum, Ido, as well as
-any other tool meant to enhance their experience.  The effect
-will vary depending on the completion framework.
-
-Nil means to remain faithful to the metaphors that each UI
-establishes.  For example, Icomplete and Ido only use foreground
-colors to style their matches, whereas Ivy or Helm rely on an
-aesthetic that combines colored backgrounds with appropriate text
-color.
-
-Option `moderate' will apply a combination of background and
-foreground that is fairly subtle.  For Icomplete and the like,
-this constitutes a departure from their standard style.  While
-Ivy, Helm, and the others, will use less pronounced colors for
-applicable contexts.
-
-Option `opinionated' will apply color combinations that refashion
-the completion UI.  So Icomplete et al will now use styles that
-resemble the defaults of Ivy and co., while the latter group will
-revert to an even more nuanced aesthetic."
+  "Control the style of the completion framework's interface.
+
+This is a special option that has different effects depending on
+the completion UI.  The interfaces can be grouped in two
+categories, based on their default aesthetics: (i) those that
+only or mostly use foreground colors for their interaction model,
+and (ii) those that combine background and foreground values for
+some of their metaphors.  The former category encompasses
+Icomplete, Ido, Selectrum, Vertico, as well as pattern matching
+styles like Orderless and Flx.  The latter covers Helm, Ivy, and
+Sallet.
+
+A value of nil (the default) will simply respect the metaphors of
+each completion framework.
+
+Option `moderate' applies a combination of background and
+foreground that is fairly subtle.  For Icomplete and friends this
+constitutes a departure from their default aesthetics, however
+the difference is small.  While Helm, Ivy et al appear slightly
+different than their original looks, as they are toned down a
+bit.
+
+Option `opinionated' uses color combinations that refashion the
+completion UI.  For the Icomplete camp this means that intense
+background and foreground combinations are used: in effect their
+looks emulate those of Helm, Ivy and company in their original
+style.  Whereas the other group of packages will revert to an
+even more nuanced aesthetic with some additional changes to the
+choice of hues.
+
+To appreciate the scope of this customization option, you should
+spend some time with every one of the nil (default), `moderate',
+and `opinionated' possibilities."
   :group 'modus-themes
   :package-version '(modus-themes . "1.0.0")
   :version "28.1"
@@ -2164,7 +2205,8 @@ current line.
 
 Option `intense-background' uses a prominent neutral background.
 
-Option `accented-background' uses a subtle colored background.
+Option `accented-background' is like the `intense-background' but
+with a more colorful background.
 
 Option `underline-neutral' combines a subtle neutral background
 with a gray underline.
@@ -2181,7 +2223,7 @@ without any added change to the background.
 Set `x-underline-at-descent-line' to a non-nil value for better
 results with underlines."
   :group 'modus-themes
-  :package-version '(modus-themes . "1.3.0")
+  :package-version '(modus-themes . "1.4.0")
   :version "28.1"
   :type '(choice
           (const :format "[%v] %t\n" :tag "Subtle neutral background 
(default)" nil)
@@ -2340,83 +2382,45 @@ to the end of each line within the region."
           (const :format "[%v] %t\n" :tag "As with the `accent' option, but 
does not extend" accent-no-extend))
   :link '(info-link "(modus-themes) Active region"))
 
-
+(defcustom modus-themes-success-deuteranopia nil
+  "Color-code 'success' or 'done' as blue instead of green.
 
-;;;; Deprecated customization options (prior to 1.0.0)
-
-;;;;; Modus Operandi obsolete options
-
-(make-obsolete 'modus-operandi-theme-override-colors-alist nil "1.0.0")
-(make-obsolete 'modus-operandi-theme-slanted-constructs 
'modus-themes-slanted-constructs "1.0.0")
-(make-obsolete 'modus-operandi-theme-bold-constructs 
'modus-themes-bold-constructs "1.0.0")
-(make-obsolete 'modus-operandi-theme-proportional-fonts 
'modus-themes-variable-pitch-headings "1.0.0")
-(make-obsolete 'modus-operandi-theme-variable-pitch-headings 
'modus-themes-variable-pitch-headings "1.0.0")
-(make-obsolete 'modus-operandi-theme-no-mixed-fonts 
'modus-themes-no-mixed-fonts "1.0.0")
-(make-obsolete 'modus-operandi-theme-rainbow-headings 'modus-themes-headings 
"1.0.0")
-(make-obsolete 'modus-operandi-theme-section-headings 'modus-themes-headings 
"1.0.0")
-(make-obsolete 'modus-operandi-theme-headings 'modus-themes-headings "1.0.0")
-(make-obsolete 'modus-operandi-theme-scale-headings 
'modus-themes-scale-headings "1.0.0")
-(make-obsolete 'modus-operandi-theme-scale-1 'modus-themes-scale-1 "1.0.0")
-(make-obsolete 'modus-operandi-theme-scale-2 'modus-themes-scale-2 "1.0.0")
-(make-obsolete 'modus-operandi-theme-scale-3 'modus-themes-scale-3 "1.0.0")
-(make-obsolete 'modus-operandi-theme-scale-4 'modus-themes-scale-4 "1.0.0")
-(make-obsolete 'modus-operandi-theme-scale-5 'modus-themes-scale-5 "1.0.0")
-(make-obsolete 'modus-operandi-theme-visible-fringes 'modus-themes-fringes 
"1.0.0")
-(make-obsolete 'modus-operandi-theme-fringes 'modus-themes-fringes "1.0.0")
-(make-obsolete 'modus-operandi-theme-distinct-org-blocks 
'modus-themes-org-blocks "1.0.0")
-(make-obsolete 'modus-operandi-theme-rainbow-org-src-blocks 
'modus-themes-org-blocks "1.0.0")
-(make-obsolete 'modus-operandi-theme-org-blocks 'modus-themes-org-blocks 
"1.0.0")
-(make-obsolete 'modus-operandi-theme-3d-modeline 'modus-themes-mode-line 
"1.0.0")
-(make-obsolete 'modus-operandi-theme-mode-line 'modus-themes-mode-line "1.0.0")
-(make-obsolete 'modus-operandi-theme-subtle-diffs 'modus-themes-diffs "1.0.0")
-(make-obsolete 'modus-operandi-theme-diffs 'modus-themes-diffs "1.0.0")
-(make-obsolete 'modus-operandi-theme-intense-standard-completions 
'modus-themes-completions "1.0.0")
-(make-obsolete 'modus-operandi-theme-completions 'modus-themes-completions 
"1.0.0")
-(make-obsolete 'modus-operandi-theme-prompts 'modus-themes-prompts "1.0.0")
-(make-obsolete 'modus-operandi-theme-intense-hl-line 
'modus-themes-intense-hl-line "1.0.0")
-(make-obsolete 'modus-operandi-theme-intense-paren-match 
'modus-themes-paren-match "1.0.0")
-(make-obsolete 'modus-operandi-theme-faint-syntax 'modus-themes-syntax "1.0.0")
-(make-obsolete 'modus-operandi-theme-comments 'modus-themes-syntax "1.0.0")
-(make-obsolete 'modus-operandi-theme-syntax 'modus-themes-syntax "1.0.0")
-(make-obsolete 'modus-operandi-theme-no-link-underline 'modus-themes-links 
"1.0.0")
-(make-obsolete 'modus-operandi-theme-links 'modus-themes-links "1.0.0")
-
-;;;;; Modus Vivendi obsolete options
-
-(make-obsolete 'modus-vivendi-theme-override-colors-alist nil "1.0.0")
-(make-obsolete 'modus-vivendi-theme-slanted-constructs 
'modus-themes-slanted-constructs "1.0.0")
-(make-obsolete 'modus-vivendi-theme-bold-constructs 
'modus-themes-bold-constructs "1.0.0")
-(make-obsolete 'modus-vivendi-theme-proportional-fonts 
'modus-themes-variable-pitch-headings "1.0.0")
-(make-obsolete 'modus-vivendi-theme-variable-pitch-headings 
'modus-themes-variable-pitch-headings "1.0.0")
-(make-obsolete 'modus-vivendi-theme-no-mixed-fonts 
'modus-themes-no-mixed-fonts "1.0.0")
-(make-obsolete 'modus-vivendi-theme-rainbow-headings 'modus-themes-headings 
"1.0.0")
-(make-obsolete 'modus-vivendi-theme-section-headings 'modus-themes-headings 
"1.0.0")
-(make-obsolete 'modus-vivendi-theme-headings 'modus-themes-headings "1.0.0")
-(make-obsolete 'modus-vivendi-theme-scale-headings 
'modus-themes-scale-headings "1.0.0")
-(make-obsolete 'modus-vivendi-theme-scale-1 'modus-themes-scale-1 "1.0.0")
-(make-obsolete 'modus-vivendi-theme-scale-2 'modus-themes-scale-2 "1.0.0")
-(make-obsolete 'modus-vivendi-theme-scale-3 'modus-themes-scale-3 "1.0.0")
-(make-obsolete 'modus-vivendi-theme-scale-4 'modus-themes-scale-4 "1.0.0")
-(make-obsolete 'modus-vivendi-theme-scale-5 'modus-themes-scale-5 "1.0.0")
-(make-obsolete 'modus-vivendi-theme-visible-fringes 'modus-themes-fringes 
"1.0.0")
-(make-obsolete 'modus-vivendi-theme-fringes 'modus-themes-fringes "1.0.0")
-(make-obsolete 'modus-vivendi-theme-distinct-org-blocks 
'modus-themes-org-blocks "1.0.0")
-(make-obsolete 'modus-vivendi-theme-rainbow-org-src-blocks 
'modus-themes-org-blocks "1.0.0")
-(make-obsolete 'modus-vivendi-theme-org-blocks 'modus-themes-org-blocks 
"1.0.0")
-(make-obsolete 'modus-vivendi-theme-3d-modeline 'modus-themes-mode-line 
"1.0.0")
-(make-obsolete 'modus-vivendi-theme-mode-line 'modus-themes-mode-line "1.0.0")
-(make-obsolete 'modus-vivendi-theme-subtle-diffs 'modus-themes-diffs "1.0.0")
-(make-obsolete 'modus-vivendi-theme-diffs 'modus-themes-diffs "1.0.0")
-(make-obsolete 'modus-vivendi-theme-intense-standard-completions 
'modus-themes-completions "1.0.0")
-(make-obsolete 'modus-vivendi-theme-completions 'modus-themes-completions 
"1.0.0")
-(make-obsolete 'modus-vivendi-theme-prompts 'modus-themes-prompts "1.0.0")
-(make-obsolete 'modus-vivendi-theme-intense-hl-line 
'modus-themes-intense-hl-line "1.0.0")
-(make-obsolete 'modus-vivendi-theme-intense-paren-match 
'modus-themes-paren-match "1.0.0")
-(make-obsolete 'modus-vivendi-theme-faint-syntax 'modus-themes-syntax "1.0.0")
-(make-obsolete 'modus-vivendi-theme-comments 'modus-themes-syntax "1.0.0")
-(make-obsolete 'modus-vivendi-theme-syntax 'modus-themes-syntax "1.0.0")
-(make-obsolete 'modus-vivendi-theme-no-link-underline 'modus-themes-links 
"1.0.0")
-(make-obsolete 'modus-vivendi-theme-links 'modus-themes-links "1.0.0")
+This is to account for red-green color deficiency.
+
+The present customization option should apply to all contexts where
+there can be a color-coded distinction between success and failure,
+to-do and done, and so on.
+
+Diffs, which have a red/green dichotomy by default, can also be
+configured to conform with deuteranopia: `modus-themes-diffs'."
+  :group 'modus-themes
+  :package-version '(modus-themes . "1.4.0")
+  :version "28.1"
+  :type 'boolean
+  :link '(info-link "(modus-themes) Success' color-code"))
+
+(defcustom modus-themes-mail-citations nil
+  "Control the color of citations in messages or email clients.
+
+Nil (the default) means to use a variety of contrasting hues to
+denote depth in nested citations.  Colors are fairly easy to tell
+apart.
+
+Option `faint' maintains a color-based distinction between
+citation levels but the colors it applies have very subtle
+differences between them.
+
+Option `monochrome' turns all citations that would otherwise be
+colored into a uniform shade of shade of gray."
+  :group 'modus-themes
+  :package-version '(modus-themes . "1.4.0")
+  :version "28.1"
+  :type '(choice
+          (const :format "[%v] %t\n" :tag "Colorful mail citations with 
contrasting hues (default)" nil)
+          (const :format "[%v] %t\n" :tag "Like the default, but with less 
saturated colors" faint)
+          (const :format "[%v] %t\n" :tag "Deprecated alias of `faint'" 
desaturated)
+          (const :format "[%v] %t\n" :tag "Uniformly gray mail citations" 
monochrome))
+  :link '(info-link "(modus-themes) Mail citations"))
 
 
 
@@ -2464,7 +2468,7 @@ Those are stored in `modus-themes-faces' and
   (car custom-enabled-themes))
 
 ;; Helper functions that are meant to ease the implementation of the
-;; above customization options.
+;; above customization variables.
 (defun modus-themes--bold-weight ()
   "Conditional use of a heavier text weight."
   (when modus-themes-bold-constructs
@@ -2629,7 +2633,7 @@ than the default.  BG is a nuanced, typically accented,
 background that can work well with either of the foreground
 values.  BORDER is a color value that combines well with the
 background and alternative foreground."
-  (let* ((key (modus-themes--heading-p `,level))
+  (let* ((key (modus-themes--heading-p level))
          (style (or key (modus-themes--heading-p t)))
          (var (when modus-themes-variable-pitch-headings
                 'variable-pitch))
@@ -2638,55 +2642,58 @@ background and alternative foreground."
                     'bold)))
     (pcase style
       ('no-bold
-       (list :inherit `,var :foreground fg))
+       (list :inherit var :foreground fg))
       ('no-color
-       (list :inherit `,varbold))
+       (list :inherit varbold))
       ('no-color-no-bold
-       (list :inherit `,var))
+       (list :inherit var))
       ('line
-       (list :inherit `,varbold :foreground fg :overline border))
+       (list :inherit varbold :foreground fg :overline border))
       ('line-no-bold
-       (list :inherit `,var :foreground fg :overline border))
+       (list :inherit var :foreground fg :overline border))
       ('rainbow
-       (list :inherit `,varbold :foreground fg-alt))
+       (list :inherit varbold :foreground fg-alt))
       ('rainbow-no-bold
-       (list :inherit `,var :foreground fg-alt))
+       (list :inherit var :foreground fg-alt))
       ('rainbow-line
-       (list :inherit `,varbold :foreground fg-alt :overline border))
+       (list :inherit varbold :foreground fg-alt :overline border))
       ('rainbow-line-no-bold
-       (list :inherit `,var :foreground fg-alt :overline border))
+       (list :inherit var :foreground fg-alt :overline border))
       ('highlight
-       (list :inherit `,varbold :background bg :foreground fg))
+       (list :inherit varbold :background bg :foreground fg))
       ('highlight-no-bold
-       (list :inherit `,var :background bg :foreground fg))
+       (list :inherit var :background bg :foreground fg))
       ('rainbow-highlight
-       (list :inherit `,varbold :background bg :foreground fg-alt))
+       (list :inherit varbold :background bg :foreground fg-alt))
       ('rainbow-highlight-no-bold
-       (list :inherit `,var :background bg :foreground fg-alt))
+       (list :inherit var :background bg :foreground fg-alt))
       ('section
-       (list :inherit `,varbold :background bg :foreground fg :overline border 
:extend t))
+       (list :inherit varbold :background bg :foreground fg :overline border 
:extend t))
       ('section-no-bold
-       (list :inherit `,var :background bg :foreground fg :overline border 
:extend t))
+       (list :inherit var :background bg :foreground fg :overline border 
:extend t))
       ('rainbow-section
-       (list :inherit `,varbold :background bg :foreground fg-alt :overline 
border :extend t))
+       (list :inherit varbold :background bg :foreground fg-alt :overline 
border :extend t))
       ('rainbow-section-no-bold
-       (list :inherit `,var :background bg :foreground fg-alt :overline border 
:extend t))
+       (list :inherit var :background bg :foreground fg-alt :overline border 
:extend t))
       (_
-       (list :inherit `,varbold :foreground fg)))))
+       (list :inherit varbold :foreground fg)))))
 
-(defun modus-themes--org-block (bgblk)
+(defun modus-themes--org-block (bgblk fgdefault &optional fgblk)
   "Conditionally set the background of Org blocks.
 BGBLK applies to a distinct neutral background.  Else blocks have
 no background of their own (the default), so they look the same
-as the rest of the buffer.
-
-`modus-themes-org-blocks' also accepts a `rainbow' option
-which is applied conditionally to `org-src-block-faces' (see the
-theme's source code)."
-  (if (or (eq modus-themes-org-blocks 'grayscale)
+as the rest of the buffer.  FGDEFAULT is used when no distinct
+background is present.  While optional FGBLK specifies a
+foreground value that can be combined with BGBLK.
+
+`modus-themes-org-blocks' also accepts `tinted-background' (alias
+`rainbow') as a value which applies to `org-src-block-faces' (see
+the theme's source code)."
+  (if (or (eq modus-themes-org-blocks 'gray-background)
+          (eq modus-themes-org-blocks 'grayscale)
           (eq modus-themes-org-blocks 'greyscale))
-      (list :background bgblk :extend t)
-    (list :background 'unspecified)))
+      (list :background bgblk :foreground (or fgblk fgdefault) :extend t)
+    (list :background 'unspecified :foreground fgdefault)))
 
 (defun modus-themes--org-block-delim (bgaccent fgaccent bg fg)
   "Conditionally set the styles of Org block delimiters.
@@ -2702,6 +2709,7 @@ The latter pair should be more subtle than the background 
of the
 block, as it is used when `modus-themes-org-blocks' is
 set to `rainbow'."
   (pcase modus-themes-org-blocks
+    ('gray-background (list :background bg :foreground fg :extend t))
     ('grayscale (list :background bg :foreground fg :extend t))
     ('greyscale (list :background bg :foreground fg :extend t))
     ('rainbow (list :background bgaccent :foreground fgaccent))
@@ -2721,9 +2729,9 @@ instead.  Same for SIMPLE."
   "Color combinations for `modus-themes-mode-line'.
 
 FG and BG are the default colors.  FG-ALT and BG-ALT are meant to
-accommodate the options for a 3D modeline or a `moody' compliant
+accommodate the options for a 3D mode line or a `moody' compliant
 one.  FG-ACCENT and BG-ACCENT are used for all variants.  BORDER
-applies to all permutations of the modeline, except the
+applies to all permutations of the mode line, except the
 three-dimensional effect, where BORDER-3D is used instead.
 
 Optional ALT-STYLE applies an appropriate style to the mode
@@ -2737,38 +2745,49 @@ values.  It is intended to be used as a 
distant-foreground
 property."
   (pcase modus-themes-mode-line
     ('3d
-     `(:background ,bg-alt :foreground ,fg-alt
-       :box (:line-width ,(or border-width 1)
-             :color ,border-3d
-             :style ,(and alt-style 'released-button))))
+     `( :background ,bg-alt :foreground ,fg-alt
+        :box ( :line-width ,(or border-width 1)
+               :color ,border-3d
+               :style ,(and alt-style 'released-button))))
     ('moody
-     `(:background ,bg-alt :foreground ,fg-alt
-       :underline ,border :overline ,border
-       :distant-foreground ,fg-distant))
+     `( :background ,bg-alt :foreground ,fg-alt
+        :underline ,border :overline ,border
+        :distant-foreground ,fg-distant))
     ('borderless
-     `(:foreground ,fg :background ,bg :box ,bg))
+     `(:background ,bg :foreground ,fg :box ,bg))
     ('borderless-3d
-     `(:foreground ,fg :background ,bg
-       :box (:line-width ,(or border-width 1)
-             :color ,bg
-             :style ,(and alt-style 'released-button))))
+     `( :background ,bg :foreground ,fg
+        :box ( :line-width ,(or border-width 1)
+               :color ,bg
+               :style ,(and alt-style 'released-button))))
     ('borderless-moody
-     `(:background ,bg :foreground ,fg
-       :underline ,bg :overline ,bg
-       :distant-foreground ,fg-distant))
+     `( :background ,bg :foreground ,fg
+        :underline ,bg :overline ,bg
+        :distant-foreground ,fg-distant))
     ('accented
-     `(:foreground ,fg-accent :background ,bg-accent :box ,border))
+     `(:background ,bg-accent :foreground ,fg-accent :box ,border))
     ('accented-3d
-     `(:background ,bg-accent :foreground ,fg-accent
-       :box (:line-width ,(or border-width 1)
-             :color ,border-3d
-             :style ,(and alt-style 'released-button))))
+     `( :background ,bg-accent :foreground ,fg-accent
+        :box ( :line-width ,(or border-width 1)
+               :color ,border-3d
+               :style ,(and alt-style 'released-button))))
     ('accented-moody
-     `(:background ,bg-accent :foreground ,fg-accent
-       :underline ,border :overline ,border
-       :distant-foreground ,fg-distant))
+     `( :background ,bg-accent :foreground ,fg-accent
+        :underline ,border :overline ,border
+        :distant-foreground ,fg-distant))
+    ('borderless-accented
+     `(:background ,bg-accent :foreground ,fg-accent :box ,bg-accent))
+    ('borderless-accented-3d
+     `( :background ,bg-accent :foreground ,fg-accent
+        :box ( :line-width ,(or border-width 1)
+               :color ,bg-accent
+               :style ,(and alt-style 'released-button))))
+    ('borderless-accented-moody
+     `( :background ,bg-accent :foreground ,fg-accent
+        :underline ,bg-accent :overline ,bg-accent
+        :distant-foreground ,fg-distant))
     (_
-     `(:foreground ,fg :background ,bg :box ,border))))
+     `(:background ,bg :foreground ,fg :box ,border))))
 
 (defun modus-themes--diff
     (fg-only-bg fg-only-fg mainbg mainfg altbg altfg &optional deuteranbg 
deuteranfg  bg-only-fg)
@@ -2792,6 +2811,7 @@ Optional BG-ONLY-FG applies ALTFG else leaves the 
foreground
 unspecified."
   (pcase modus-themes-diffs
     ('fg-only (list :background fg-only-bg :foreground fg-only-fg))
+    ('fg-only-deuteranopia (list :background fg-only-bg :foreground 
fg-only-fg))
     ('desaturated (list :background altbg :foreground altfg))
     ('deuteranopia (list :background (or deuteranbg mainbg) :foreground (or 
deuteranfg mainfg)))
     ('bg-only (list :background altbg :foreground (if bg-only-fg altfg 
'unspecified)))
@@ -2801,19 +2821,17 @@ unspecified."
   "Determine whether the DEUTERAN or MAIN color should be used.
 This is based on whether `modus-themes-diffs' has the value
 `deuteranopia'."
-  (if (eq modus-themes-diffs 'deuteranopia)
+  (if (or (eq modus-themes-diffs 'deuteranopia)
+          (eq modus-themes-diffs 'fg-only-deuteranopia)
+          (eq modus-themes-diffs 'fg-only))
       (list deuteran)
     (list main)))
 
-(defun modus-themes--diff-text (fg-only-fg default-fg)
-  "Like `modus-themes--diff', but only for foregrounds.
-FG-ONLY-FG is the foreground that is used when diffs are styled
-using only foreground colors.  DEFAULT-FG covers all other
-cases."
-  (pcase modus-themes-diffs
-    ('fg-only (list :foreground fg-only-fg))
-    ('bg-only (list :foreground 'unspecified))
-    (_ (list :foreground default-fg))))
+(defun modus-themes--success-deuteran (deuteran main)
+  "Determine whether to color-code success as DEUTERAN or MAIN."
+  (if modus-themes-success-deuteranopia
+      (list deuteran)
+    (list main)))
 
 (defun modus-themes--standard-completions (mainfg subtlebg intensebg intensefg)
   "Combinations for `modus-themes-completions'.
@@ -2895,24 +2913,36 @@ background that combines well with FG."
     ('accent-no-extend (list :background bgaccent :foreground fg :extend nil))
     (_ (list :background bg :foreground fg))))
 
-(defun modus-themes--hl-line (bgdefault bgintense bgaccent lineneutral 
lineaccent)
+(defun modus-themes--hl-line (bgdefault bgintense bgaccent bgaccentul 
lineneutral lineaccent)
   "Apply `modus-themes-hl-line' styles.
 
 BGDEFAULT is a subtle neutral background.  BGINTENSE is like the
-default, but more prominent.  BGACCENT is a subtle accented
-background.  LINENEUTRAL and LINEACCENT are a color values that
-can remain distinct against the buffer's possible backgrounds:
-the former is neutral, the latter is accented.  LINEONLY must be
-a prominent neutral color."
+default, but more prominent.  BGACCENT is a prominent accented
+background, while BGACCENTUL is more subtle and is meant to be
+used in tandem with an underline.  LINENEUTRAL and LINEACCENT are
+a color values that can remain distinct against the buffer's
+possible backgrounds: the former is neutral, the latter is
+accented."
   (pcase modus-themes-hl-line
     ('intense-background (list :background bgintense))
     ('accented-background (list :background bgaccent))
     ('underline-neutral (list :background bgdefault :underline lineneutral))
-    ('underline-accented (list :background bgaccent :underline lineaccent))
+    ('underline-accented (list :background bgaccentul :underline lineaccent))
     ('underline-only-neutral (list :background 'unspecified :underline 
lineneutral))
     ('underline-only-accented (list :background 'unspecified :underline 
lineaccent))
     (_ (list :background bgdefault))))
 
+(defun modus-themes--mail-cite (mainfg subtlefg)
+  "Combinations for `modus-themes-mail-citations'.
+
+MAINFG is an accented foreground value.  SUBTLEFG is its
+desaturated counterpart."
+  (pcase modus-themes-mail-citations
+    ('monochrome (list :inherit 'shadow))
+    ('faint (list :foreground subtlefg))
+    ('desaturated (list :foreground subtlefg))
+    (_ (list :foreground mainfg))))
+
 
 
 ;;;; Utilities for DIY users
@@ -3132,7 +3162,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     ;; intended for `diff-mode' or equivalent
     `(modus-themes-diff-added
       ((,class ,@(modus-themes--diff
-                  bg-main green
+                  bg-main blue-alt-other
                   bg-diff-focus-added fg-diff-focus-added
                   green-nuanced-bg fg-diff-added
                   bg-diff-focus-added-deuteran fg-diff-focus-added-deuteran))))
@@ -3148,7 +3178,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                   red-nuanced-bg fg-diff-removed))))
     `(modus-themes-diff-refine-added
       ((,class ,@(modus-themes--diff
-                  bg-diff-added fg-diff-added
+                  bg-diff-added-deuteran fg-diff-added-deuteran
                   bg-diff-refine-added fg-diff-refine-added
                   bg-diff-focus-added fg-diff-focus-added
                   bg-diff-refine-added-deuteran 
fg-diff-refine-added-deuteran))))
@@ -3164,7 +3194,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                   bg-diff-focus-removed fg-diff-focus-removed))))
     `(modus-themes-diff-focus-added
       ((,class ,@(modus-themes--diff
-                  bg-dim green
+                  bg-dim blue-alt-other
                   bg-diff-focus-added fg-diff-focus-added
                   bg-diff-added fg-diff-added
                   bg-diff-focus-added-deuteran fg-diff-focus-added-deuteran))))
@@ -3180,7 +3210,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                   bg-diff-removed fg-diff-removed))))
     `(modus-themes-diff-heading
       ((,class ,@(modus-themes--diff
-                  bg-main blue
+                  bg-alt fg-main
                   bg-diff-heading fg-diff-heading
                   cyan-nuanced-bg cyan-nuanced-fg
                   bg-header fg-main
@@ -3221,7 +3251,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                   7 red-nuanced-fg red-alt red-nuanced-bg bg-region))))
     `(modus-themes-heading-8
       ((,class ,@(modus-themes--heading
-                  8 fg-dim magenta bg-alt bg-region))))
+                  8 magenta-nuanced-fg magenta bg-alt bg-region))))
 ;;;;; graph-specific faces
     `(modus-themes-graph-red-0 ((,class :background ,red-graph-0-bg)))
     `(modus-themes-graph-red-1 ((,class :background ,red-graph-1-bg)))
@@ -3236,21 +3266,41 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(modus-themes-graph-cyan-0 ((,class :background ,cyan-graph-0-bg)))
     `(modus-themes-graph-cyan-1 ((,class :background ,cyan-graph-1-bg)))
 ;;;;; language checkers
-    `(modus-themes-lang-error ((,class ,@(modus-themes--lang-check 
fg-lang-underline-error fg-lang-error red red-nuanced-bg))))
-    `(modus-themes-lang-note ((,class ,@(modus-themes--lang-check 
fg-lang-underline-note fg-lang-note blue-alt blue-nuanced-bg))))
-    `(modus-themes-lang-warning ((,class ,@(modus-themes--lang-check 
fg-lang-underline-warning fg-lang-warning yellow yellow-nuanced-bg))))
+    `(modus-themes-lang-error ((,class ,@(modus-themes--lang-check
+                                          fg-lang-underline-error
+                                          fg-lang-error
+                                          red red-nuanced-bg))))
+    `(modus-themes-lang-note ((,class ,@(modus-themes--lang-check
+                                         fg-lang-underline-note
+                                         fg-lang-note
+                                         blue-alt blue-nuanced-bg))))
+    `(modus-themes-lang-warning ((,class ,@(modus-themes--lang-check
+                                            fg-lang-underline-warning
+                                            fg-lang-warning
+                                            yellow yellow-nuanced-bg))))
 ;;;;; other custom faces
     `(modus-themes-bold ((,class ,@(modus-themes--bold-weight))))
-    `(modus-themes-hl-line ((,class ,@(modus-themes--hl-line bg-hl-line 
bg-hl-line-intense blue-nuanced-bg
-                                                             bg-region 
blue-intense-bg)
+    `(modus-themes-hl-line ((,class ,@(modus-themes--hl-line
+                                       bg-hl-line bg-hl-line-intense
+                                       bg-hl-line-intense-accent 
blue-nuanced-bg
+                                       bg-region blue-intense-bg)
                                     :extend t)))
     `(modus-themes-key-binding ((,class :inherit bold :foreground 
,blue-alt-other)))
-    `(modus-themes-slant ((,class :inherit italic :slant 
,@(modus-themes--slant))))
-    `(modus-themes-variable-pitch ((,class ,@(modus-themes--variable-pitch))))
+    `(modus-themes-reset-hard ((,class :inherit (fixed-pitch 
modus-themes-reset-soft))))
     `(modus-themes-reset-soft ((,class :background ,bg-main :foreground 
,fg-main
                                        :weight normal :slant normal 
:strike-through nil
                                        :box nil :underline nil :overline nil 
:extend nil)))
-    `(modus-themes-reset-hard ((,class :inherit (fixed-pitch 
modus-themes-reset-soft))))
+    `(modus-themes-search-success ((,class :inherit 
,@(modus-themes--success-deuteran
+                                                       
'modus-themes-intense-blue
+                                                       
'modus-themes-intense-green))))
+    `(modus-themes-search-success-lazy ((,class :inherit 
,@(modus-themes--success-deuteran
+                                                            
'modus-themes-special-mild
+                                                            
'modus-themes-refine-cyan))))
+    `(modus-themes-search-success-modeline ((,class :foreground 
,@(modus-themes--success-deuteran
+                                                                   blue-active
+                                                                   
green-active))))
+    `(modus-themes-slant ((,class :inherit italic :slant 
,@(modus-themes--slant))))
+    `(modus-themes-variable-pitch ((,class ,@(modus-themes--variable-pitch))))
 ;;;; standard faces
 ;;;;; absolute essentials
     `(default ((,class :background ,bg-main :foreground ,fg-main)))
@@ -3293,7 +3343,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(region ((,class ,@(modus-themes--region bg-region fg-main 
bg-hl-alt-intense bg-region-accent))))
     `(secondary-selection ((,class :inherit modus-themes-special-cold)))
     `(shadow ((,class :foreground ,fg-alt)))
-    `(success ((,class :inherit bold :foreground ,green)))
+    `(success ((,class :inherit bold :foreground 
,@(modus-themes--success-deuteran blue green))))
     `(trailing-whitespace ((,class :background ,red-intense-bg)))
     `(warning ((,class :inherit bold :foreground ,yellow)))
 ;;;;; buttons, links, widgets
@@ -3304,10 +3354,8 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                             ,@(modus-themes--link-color
                                magenta-alt-other magenta-alt-other-faint 
fg-alt))))
     `(tooltip ((,class :background ,bg-special-cold :foreground ,fg-main)))
-    `(widget-button ((,class :inherit button)))
-    `(widget-button-pressed ((,class :inherit button
-                                     ,@(modus-themes--link-color
-                                        magenta magenta-faint))))
+    `(widget-button ((,class :inherit bold :foreground ,blue-alt)))
+    `(widget-button-pressed ((,class :inherit widget-button :foreground 
,magenta)))
     `(widget-documentation ((,class :foreground ,green)))
     `(widget-field ((,class :background ,bg-alt :foreground ,fg-dim)))
     `(widget-inactive ((,class :background ,bg-inactive :foreground 
,fg-inactive)))
@@ -3364,12 +3412,12 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(annotate-highlight-secondary ((,class :background ,green-nuanced-bg 
:underline ,green-intense)))
 ;;;;; anzu
     `(anzu-match-1 ((,class :inherit modus-themes-subtle-cyan)))
-    `(anzu-match-2 ((,class :inherit modus-themes-subtle-green)))
+    `(anzu-match-2 ((,class :inherit modus-themes-search-success)))
     `(anzu-match-3 ((,class :inherit modus-themes-subtle-yellow)))
-    `(anzu-mode-line ((,class :inherit bold :foreground ,green-active)))
+    `(anzu-mode-line ((,class :inherit (bold 
modus-themes-search-success-modeline))))
     `(anzu-mode-line-no-match ((,class :inherit bold :foreground ,red-active)))
     `(anzu-replace-highlight ((,class :inherit modus-themes-refine-yellow 
:underline t)))
-    `(anzu-replace-to ((,class :inherit (modus-themes-intense-green bold))))
+    `(anzu-replace-to ((,class :inherit (modus-themes-search-success bold))))
 ;;;;; apropos
     `(apropos-function-button ((,class :inherit button
                                        ,@(modus-themes--link-color
@@ -3485,6 +3533,8 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(boon-modeline-ins ((,class :inherit modus-themes-active-red)))
     `(boon-modeline-off ((,class :inherit modus-themes-active-yellow)))
     `(boon-modeline-spc ((,class :inherit modus-themes-active-green)))
+;;;;; bookmark
+    `(bookmark-face ((,class :inherit modus-themes-special-warm :extend t)))
 ;;;;; breakpoint (built-in gdb-mi.el)
     `(breakpoint-disabled ((,class :inherit shadow)))
     `(breakpoint-enabled ((,class :inherit bold :foreground ,red)))
@@ -3524,7 +3574,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(cfw:face-toolbar-button-on ((,class :inherit bold :background 
,blue-nuanced-bg
                                           :foreground ,blue-alt)))
 ;;;;; centaur-tabs
-    `(centaur-tabs-active-bar-face ((,class :background ,fg-tab-accent)))
+    `(centaur-tabs-active-bar-face ((,class :background ,blue-active)))
     `(centaur-tabs-close-mouse-face ((,class :inherit bold :foreground 
,red-active :underline t)))
     `(centaur-tabs-close-selected ((,class :inherit centaur-tabs-selected)))
     `(centaur-tabs-close-unselected ((,class :inherit 
centaur-tabs-unselected)))
@@ -3584,7 +3634,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                                                        :background ,bg-alt 
:foreground ,fg-alt)))
     `(cider-test-error-face ((,class :inherit modus-themes-subtle-red)))
     `(cider-test-failure-face ((,class :inherit (modus-themes-intense-red 
bold))))
-    `(cider-test-success-face ((,class :inherit modus-themes-intense-green)))
+    `(cider-test-success-face ((,class :inherit 
,@(modus-themes--success-deuteran
+                                                   'modus-themes-intense-blue
+                                                   
'modus-themes-intense-green))))
     `(cider-traced-face ((,class :box (:line-width -1 :color ,cyan :style nil) 
:background ,bg-dim)))
     `(cider-warning-highlight-face ((,class :foreground ,yellow :underline t)))
 ;;;;; circe (and lui)
@@ -3626,8 +3678,8 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(company-tooltip-common ((,class :inherit bold :foreground ,blue-alt)))
     `(company-tooltip-common-selection ((,class :foreground ,fg-main)))
     `(company-tooltip-mouse ((,class :inherit modus-themes-intense-blue)))
-    `(company-tooltip-search ((,class :inherit (modus-themes-refine-cyan 
bold))))
-    `(company-tooltip-search-selection ((,class :inherit 
(modus-themes-intense-green bold) :underline t)))
+    `(company-tooltip-search ((,class :inherit 
(modus-themes-search-success-lazy bold))))
+    `(company-tooltip-search-selection ((,class :inherit 
(modus-themes-search-success bold) :underline t)))
     `(company-tooltip-selection ((,class :inherit (modus-themes-subtle-cyan 
bold))))
 ;;;;; company-posframe
     `(company-posframe-active-backend-name ((,class :inherit bold :background 
,bg-active :foreground ,blue-active)))
@@ -3665,10 +3717,10 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(consult-preview-error ((,class :inherit modus-themes-intense-red)))
     `(consult-preview-line ((,class :background ,bg-hl-alt-intense)))
 ;;;;; corfu
-    `(corfu-background ((,class :background ,bg-alt :foreground ,fg-alt)))
+    `(corfu-background ((,class :background ,bg-alt)))
     `(corfu-current ((,class :inherit bold :background ,cyan-subtle-bg)))
-    `(corfu-bar ((,class :background ,fg-alt :foreground ,fg-alt)))
-    `(corfu-border ((,class :background ,bg-active :foreground ,bg-region)))
+    `(corfu-bar ((,class :background ,fg-alt)))
+    `(corfu-border ((,class :background ,bg-active)))
 ;;;;; counsel
     `(counsel-active-mode ((,class :foreground ,magenta-alt-other)))
     `(counsel-application-name ((,class :foreground ,red-alt-other)))
@@ -3690,11 +3742,6 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(counsel-css-selector-depth-face-4 ((,class :foreground ,yellow)))
     `(counsel-css-selector-depth-face-5 ((,class :foreground ,magenta)))
     `(counsel-css-selector-depth-face-6 ((,class :foreground ,red)))
-;;;;; counsel-notmuch
-    `(counsel-notmuch-count-face ((,class :foreground ,cyan)))
-    `(counsel-notmuch-date-face ((,class :foreground ,blue)))
-    `(counsel-notmuch-people-face ((,class :foreground ,magenta)))
-    `(counsel-notmuch-subject-face ((,class :foreground ,magenta-alt-other)))
 ;;;;; counsel-org-capture-string
     `(counsel-org-capture-string-template-body-face ((,class :foreground 
,fg-special-cold)))
 ;;;;; cov
@@ -3709,11 +3756,11 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(cperl-array-face ((,class :inherit font-lock-keyword-face)))
     `(cperl-hash-face ((,class :inherit font-lock-variable-name-face)))
 ;;;;; csv-mode
-    `(csv-separator-face ((,class :background ,bg-special-cold :foreground 
,fg-main)))
+    `(csv-separator-face ((,class :foreground ,red-intense)))
 ;;;;; ctrlf
-    `(ctrlf-highlight-active ((,class :inherit (modus-themes-intense-green 
bold))))
+    `(ctrlf-highlight-active ((,class :inherit (modus-themes-search-success 
bold))))
     `(ctrlf-highlight-line ((,class :inherit modus-themes-hl-line)))
-    `(ctrlf-highlight-passive ((,class :inherit modus-themes-refine-cyan)))
+    `(ctrlf-highlight-passive ((,class :inherit 
modus-themes-search-success-lazy)))
 ;;;;; custom (M-x customize)
     `(custom-button ((,class :box (:line-width 2 :color nil :style 
released-button)
                              :background ,bg-active :foreground ,fg-main)))
@@ -3764,7 +3811,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(debbugs-gnu-archived ((,class :inverse-video t)))
     `(debbugs-gnu-done ((,class :inherit shadow)))
     `(debbugs-gnu-forwarded ((,class :foreground ,fg-special-warm)))
-    `(debbugs-gnu-handled ((,class :foreground ,green)))
+    `(debbugs-gnu-handled ((,class :foreground ,blue)))
     `(debbugs-gnu-new ((,class :foreground ,red)))
     `(debbugs-gnu-pending ((,class :foreground ,cyan)))
     `(debbugs-gnu-stale-1 ((,class :foreground ,yellow-nuanced-fg)))
@@ -3797,16 +3844,18 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(diff-hl-dired-ignored ((,class :inherit dired-ignored)))
     `(diff-hl-dired-insert ((,class :inherit diff-hl-insert)))
     `(diff-hl-dired-unknown ((,class :inherit dired-ignored)))
-    `(diff-hl-insert ((,class :inherit modus-themes-fringe-green)))
-    `(diff-hl-reverted-hunk-highlight ((,class :inherit 
(modus-themes-active-magenta bold))))
+    `(diff-hl-insert ((,class :inherit ,@(modus-themes--diff-deuteran
+                                          'modus-themes-fringe-blue
+                                          'modus-themes-fringe-green))))
+    `(diff-hl-reverted-hunk-highlight ((,class :background ,fg-main 
:foreground ,bg-main)))
 ;;;;; diff-mode
     `(diff-added ((,class :inherit modus-themes-diff-added)))
     `(diff-changed ((,class :inherit modus-themes-diff-changed :extend t)))
-    `(diff-context ((,class ,@(modus-themes--diff-text fg-main fg-unfocused))))
+    `(diff-context ((,class :foreground ,fg-alt)))
     `(diff-error ((,class :inherit modus-themes-intense-red)))
     `(diff-file-header ((,class :inherit (bold diff-header))))
     `(diff-function ((,class :inherit modus-themes-diff-heading)))
-    `(diff-header ((,class ,@(modus-themes--diff-text cyan-faint fg-main))))
+    `(diff-header ((,class :foreground ,fg-main)))
     `(diff-hunk-header ((,class :inherit (bold modus-themes-diff-heading))))
     `(diff-index ((,class :inherit bold :foreground ,blue-alt)))
     `(diff-indicator-added ((,class :inherit (diff-added bold)
@@ -3975,7 +4024,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(doom-modeline-host ((,class :inherit italic)))
     `(doom-modeline-info ((,class :foreground ,green-active)))
     `(doom-modeline-lsp-error ((,class :inherit bold :foreground ,red-active)))
-    `(doom-modeline-lsp-success ((,class :inherit bold :foreground 
,green-active)))
+    `(doom-modeline-lsp-success ((,class :inherit bold :foreground 
,@(modus-themes--success-deuteran
+                                                                      
blue-active
+                                                                      
green-active))))
     `(doom-modeline-lsp-warning ((,class :inherit bold :foreground 
,yellow-active)))
     `(doom-modeline-panel ((,class :inherit modus-themes-active-blue)))
     `(doom-modeline-persp-buffer-not-in-persp ((,class :inherit italic 
:foreground ,yellow-active)))
@@ -4007,13 +4058,13 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(ebdb-phone-default ((,class :foreground ,cyan)))
     `(eieio-custom-slot-tag-face ((,class :foreground ,red-alt)))
 ;;;;; ediff
-    `(ediff-current-diff-A ((,class :inherit modus-themes-diff-removed)))
+    `(ediff-current-diff-A ((,class :inherit modus-themes-diff-focus-removed)))
     `(ediff-current-diff-Ancestor ((,class ,@(modus-themes--diff
                                               bg-alt fg-special-cold
                                               bg-special-cold fg-special-cold
                                               blue-nuanced-bg blue))))
-    `(ediff-current-diff-B ((,class :inherit modus-themes-diff-added)))
-    `(ediff-current-diff-C ((,class :inherit modus-themes-diff-changed)))
+    `(ediff-current-diff-B ((,class :inherit modus-themes-diff-focus-added)))
+    `(ediff-current-diff-C ((,class :inherit modus-themes-diff-focus-changed)))
     `(ediff-even-diff-A ((,class :background ,bg-alt)))
     `(ediff-even-diff-Ancestor ((,class :background ,bg-alt)))
     `(ediff-even-diff-B ((,class :background ,bg-alt)))
@@ -4030,7 +4081,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(eglot-mode-line ((,class :inherit modus-themes-bold :foreground 
,magenta-active)))
 ;;;;; el-search
     `(el-search-highlight-in-prompt-face ((,class :inherit bold :foreground 
,magenta-alt)))
-    `(el-search-match ((,class :inherit modus-themes-intense-green)))
+    `(el-search-match ((,class :inherit modus-themes-search-success)))
     `(el-search-other-match ((,class :inherit modus-themes-special-mild)))
     `(el-search-occur-match ((,class :inherit modus-themes-special-calm)))
 ;;;;; eldoc
@@ -4083,7 +4134,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(epa-validity-medium ((,class :foreground ,green-alt)))
 ;;;;; equake
     `(equake-buffer-face ((,class :background ,bg-main :foreground ,fg-main)))
-    `(equake-shell-type-eshell ((,class :background ,bg-inactive :foreground 
,green-active)))
+    `(equake-shell-type-eshell ((,class :background ,bg-inactive :foreground 
,blue-active)))
     `(equake-shell-type-rash ((,class :background ,bg-inactive :foreground 
,red-active)))
     `(equake-shell-type-shell ((,class :background ,bg-inactive :foreground 
,cyan-active)))
     `(equake-shell-type-term ((,class :background ,bg-inactive :foreground 
,yellow-active)))
@@ -4153,67 +4204,56 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(ert-test-result-expected ((,class :inherit modus-themes-intense-green)))
     `(ert-test-result-unexpected ((,class :inherit modus-themes-intense-red)))
 ;;;;; eshell
-    `(eshell-ls-archive ((,class :inherit bold :foreground ,cyan-alt)))
-    `(eshell-ls-backup ((,class :foreground ,yellow-alt)))
+    `(eshell-ls-archive ((,class :foreground ,cyan-alt)))
+    `(eshell-ls-backup ((,class :inherit shadow)))
     `(eshell-ls-clutter ((,class :foreground ,red-alt)))
-    `(eshell-ls-directory ((,class :inherit bold :foreground ,blue-alt)))
+    `(eshell-ls-directory ((,class :foreground ,blue-alt)))
     `(eshell-ls-executable ((,class :foreground ,magenta-alt)))
     `(eshell-ls-missing ((,class :inherit modus-themes-intense-red)))
-    `(eshell-ls-product ((,class :foreground ,fg-special-warm)))
-    `(eshell-ls-readonly ((,class :foreground ,fg-special-cold)))
-    `(eshell-ls-special ((,class :inherit bold :foreground ,magenta)))
-    `(eshell-ls-symlink ((,class :inherit button
-                                 ,@(modus-themes--link-color
-                                    cyan cyan-faint))))
+    `(eshell-ls-product ((,class :inherit shadow)))
+    `(eshell-ls-readonly ((,class :foreground ,yellow-faint)))
+    `(eshell-ls-special ((,class :foreground ,magenta)))
+    `(eshell-ls-symlink ((,class :foreground ,cyan)))
     `(eshell-ls-unreadable ((,class :background ,bg-inactive :foreground 
,fg-inactive)))
-    `(eshell-prompt ((,class :inherit modus-themes-bold
-                             ,@(modus-themes--prompt
-                                green-alt-other
-                                green-nuanced-bg green-alt
-                                green-refine-bg fg-main))))
+    `(eshell-prompt ((,class :inherit comint-highlight-prompt)))
 ;;;;; eshell-fringe-status
-    `(eshell-fringe-status-failure ((,class :foreground ,red)))
-    `(eshell-fringe-status-success ((,class :foreground ,green)))
+    `(eshell-fringe-status-failure ((,class :inherit error)))
+    `(eshell-fringe-status-success ((,class :inherit success)))
 ;;;;; eshell-git-prompt
-    `(eshell-git-prompt-add-face ((,class :inherit shadow)))
-    `(eshell-git-prompt-branch-face ((,class :inherit shadow)))
-    `(eshell-git-prompt-directory-face ((,class :foreground ,cyan)))
-    `(eshell-git-prompt-exit-fail-face ((,class :foreground ,red)))
-    `(eshell-git-prompt-exit-success-face ((,class :foreground ,green)))
+    `(eshell-git-prompt-add-face ((,class :foreground ,magenta-alt-other)))
+    `(eshell-git-prompt-branch-face ((,class :foreground ,magenta-alt)))
+    `(eshell-git-prompt-directory-face ((,class :inherit bold :foreground 
,blue)))
+    `(eshell-git-prompt-exit-fail-face ((,class :inherit error)))
+    `(eshell-git-prompt-exit-success-face ((,class :inherit success)))
     `(eshell-git-prompt-modified-face ((,class :foreground ,yellow)))
     `(eshell-git-prompt-powerline-clean-face ((,class :background 
,green-refine-bg)))
     `(eshell-git-prompt-powerline-dir-face ((,class :background 
,blue-refine-bg)))
-    `(eshell-git-prompt-powerline-not-clean-face ((,class :background 
,magenta-refine-bg)))
-    `(eshell-git-prompt-robyrussell-branch-face ((,class :foreground ,red)))
+    `(eshell-git-prompt-powerline-not-clean-face ((,class :background 
,yellow-fringe-bg)))
+    `(eshell-git-prompt-robyrussell-branch-face ((,class :foreground 
,magenta-alt)))
     `(eshell-git-prompt-robyrussell-git-dirty-face ((,class :foreground 
,yellow)))
-    `(eshell-git-prompt-robyrussell-git-face ((,class :foreground ,blue)))
+    `(eshell-git-prompt-robyrussell-git-face ((,class :foreground 
,magenta-alt-other)))
 ;;;;; eshell-prompt-extras (epe)
-    `(epe-dir-face ((,class :inherit modus-themes-bold :foreground ,blue)))
+    `(epe-dir-face ((,class :inherit bold :foreground ,blue)))
     `(epe-git-dir-face ((,class :foreground ,red-alt-other)))
-    `(epe-git-face ((,class :foreground ,cyan-alt)))
-    `(epe-pipeline-delimiter-face ((,class :foreground ,green-alt)))
-    `(epe-pipeline-host-face ((,class :foreground ,blue)))
-    `(epe-pipeline-time-face ((,class :foreground ,fg-special-warm)))
-    `(epe-pipeline-user-face ((,class :foreground ,magenta)))
-    `(epe-remote-face ((,class :inherit modus-themes-slant :foreground 
,fg-alt)))
+    `(epe-git-face ((,class :foreground ,magenta-alt)))
+    `(epe-pipeline-delimiter-face ((,class :inherit shadow)))
+    `(epe-pipeline-host-face ((,class :foreground ,fg-main)))
+    `(epe-pipeline-time-face ((,class :foreground ,fg-main)))
+    `(epe-pipeline-user-face ((,class :foreground ,magenta-alt-other)))
+    `(epe-remote-face ((,class :inherit (shadow modus-themes-slant))))
     `(epe-status-face ((,class :foreground ,magenta-alt-other)))
-    `(epe-venv-face ((,class :inherit modus-themes-slant :foreground ,fg-alt)))
+    `(epe-venv-face ((,class :inherit (shadow modus-themes-slant))))
 ;;;;; eshell-syntax-highlighting
-    `(eshell-syntax-highlighting-alias-face ((,class :foreground ,cyan)))
-    `(eshell-syntax-highlighting-comment-face ((,class :inherit shadow)))
-    `(eshell-syntax-highlighting-directory-face ((,class :foreground ,blue)))
-    `(eshell-syntax-highlighting-envvar-face ((,class :foreground 
,magenta-alt)))
+    `(eshell-syntax-highlighting-directory-face ((,class :inherit 
eshell-ls-directory)))
     `(eshell-syntax-highlighting-invalid-face ((,class :foreground ,red)))
-    `(eshell-syntax-highlighting-lisp-function-face ((,class :foreground 
,magenta)))
-    `(eshell-syntax-highlighting-shell-command-face ((,class :foreground 
,cyan-alt-other)))
-    `(eshell-syntax-highlighting-string-face ((,class :foreground ,blue-alt)))
+    `(eshell-syntax-highlighting-shell-command-face ((,class :foreground 
,fg-main)))
 ;;;;; evil-mode
     `(evil-ex-commands ((,class :foreground ,magenta-alt-other)))
     `(evil-ex-info ((,class :foreground ,cyan-alt-other)))
-    `(evil-ex-lazy-highlight ((,class :inherit modus-themes-refine-cyan)))
-    `(evil-ex-search ((,class :inherit modus-themes-intense-green)))
+    `(evil-ex-lazy-highlight ((,class :inherit 
modus-themes-search-success-lazy)))
+    `(evil-ex-search ((,class :inherit modus-themes-search-success)))
     `(evil-ex-substitute-matches ((,class :inherit modus-themes-refine-yellow 
:underline t)))
-    `(evil-ex-substitute-replacement ((,class :inherit 
(modus-themes-intense-green bold))))
+    `(evil-ex-substitute-replacement ((,class :inherit 
(modus-themes-search-success bold))))
 ;;;;; evil-goggles
     `(evil-goggles-change-face ((,class :inherit modus-themes-refine-yellow)))
     `(evil-goggles-commentary-face ((,class :inherit 
(modus-themes-subtle-neutral modus-themes-slant))))
@@ -4279,7 +4319,10 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(flycheck-indicator-error ((,class :inherit modus-themes-bold :foreground 
,red-active)))
     `(flycheck-indicator-info ((,class :inherit modus-themes-bold :foreground 
,blue-active)))
     `(flycheck-indicator-running ((,class :inherit modus-themes-bold 
:foreground ,magenta-active)))
-    `(flycheck-indicator-success ((,class :inherit modus-themes-bold 
:foreground ,green-active)))
+    `(flycheck-indicator-success ((,class :inherit modus-themes-bold
+                                          :foreground 
,@(modus-themes--success-deuteran
+                                                         blue-active
+                                                         green-active))))
     `(flycheck-indicator-warning ((,class :inherit modus-themes-bold 
:foreground ,yellow-active)))
 ;;;;; flycheck-posframe
     `(flycheck-posframe-background-face ((,class :background ,bg-alt)))
@@ -4417,17 +4460,23 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(git-commit-pseudo-header ((,class :foreground ,blue)))
     `(git-commit-summary ((,class :inherit bold :foreground ,cyan)))
 ;;;;; git-gutter
-    `(git-gutter:added ((,class :inherit modus-themes-fringe-green)))
+    `(git-gutter:added ((,class :inherit ,@(modus-themes--diff-deuteran
+                                            'modus-themes-fringe-blue
+                                            'modus-themes-fringe-green))))
     `(git-gutter:deleted ((,class :inherit modus-themes-fringe-red)))
     `(git-gutter:modified ((,class :inherit modus-themes-fringe-yellow)))
     `(git-gutter:separator ((,class :inherit modus-themes-fringe-cyan)))
     `(git-gutter:unchanged ((,class :inherit modus-themes-fringe-magenta)))
 ;;;;; git-gutter-fr
-    `(git-gutter-fr:added ((,class :inherit modus-themes-fringe-green)))
+    `(git-gutter-fr:added ((,class :inherit ,@(modus-themes--diff-deuteran
+                                               'modus-themes-fringe-blue
+                                               'modus-themes-fringe-green))))
     `(git-gutter-fr:deleted ((,class :inherit modus-themes-fringe-red)))
     `(git-gutter-fr:modified ((,class :inherit modus-themes-fringe-yellow)))
 ;;;;; git-{gutter,fringe}+
-    `(git-gutter+-added ((,class :inherit modus-themes-fringe-green)))
+    `(git-gutter+-added ((,class :inherit ,@(modus-themes--diff-deuteran
+                                          'modus-themes-fringe-blue
+                                          'modus-themes-fringe-green))))
     `(git-gutter+-deleted ((,class :inherit modus-themes-fringe-red)))
     `(git-gutter+-modified ((,class :inherit modus-themes-fringe-yellow)))
     `(git-gutter+-separator ((,class :inherit modus-themes-fringe-cyan)))
@@ -4436,7 +4485,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(git-gutter-fr+-deleted ((,class :inherit modus-themes-fringe-red)))
     `(git-gutter-fr+-modified ((,class :inherit modus-themes-fringe-yellow)))
 ;;;;; git-lens
-    `(git-lens-added ((,class :inherit bold :foreground ,green)))
+    `(git-lens-added ((,class :inherit bold :foreground 
,@(modus-themes--diff-deuteran blue green))))
     `(git-lens-deleted ((,class :inherit bold :foreground ,red)))
     `(git-lens-header ((,class :inherit bold :height 1.1 :foreground ,cyan)))
     `(git-lens-modified ((,class :inherit bold :foreground ,yellow)))
@@ -4460,17 +4509,17 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(git-walktree-tree-face ((,class :foreground ,magenta)))
 ;;;;; gnus
     `(gnus-button ((,class :inherit button)))
-    `(gnus-cite-1 ((,class :foreground ,blue-faint)))
-    `(gnus-cite-10 ((,class :foreground ,yellow-alt-other)))
-    `(gnus-cite-11 ((,class :foreground ,magenta-alt)))
-    `(gnus-cite-2 ((,class :foreground ,green-alt-other)))
-    `(gnus-cite-3 ((,class :foreground ,red-alt-other)))
-    `(gnus-cite-4 ((,class :foreground ,cyan)))
-    `(gnus-cite-5 ((,class :foreground ,yellow-alt)))
-    `(gnus-cite-6 ((,class :foreground ,magenta)))
-    `(gnus-cite-7 ((,class :foreground ,green-alt)))
-    `(gnus-cite-8 ((,class :foreground ,magenta-alt-other)))
-    `(gnus-cite-9 ((,class :foreground ,cyan-alt)))
+    `(gnus-cite-1 ((,class :inherit message-cited-text-1)))
+    `(gnus-cite-2 ((,class :inherit message-cited-text-2)))
+    `(gnus-cite-3 ((,class :inherit message-cited-text-3)))
+    `(gnus-cite-4 ((,class :inherit message-cited-text-4)))
+    `(gnus-cite-5 ((,class :inherit gnus-cite-1)))
+    `(gnus-cite-6 ((,class :inherit gnus-cite-2)))
+    `(gnus-cite-7 ((,class :inherit gnus-cite-3)))
+    `(gnus-cite-8 ((,class :inherit gnus-cite-4)))
+    `(gnus-cite-9 ((,class :inherit gnus-cite-1)))
+    `(gnus-cite-10 ((,class :inherit gnus-cite-2)))
+    `(gnus-cite-11 ((,class :inherit gnus-cite-3)))
     `(gnus-cite-attribution ((,class :inherit italic :foreground ,fg-main)))
     `(gnus-emphasis-bold ((,class :inherit bold)))
     `(gnus-emphasis-bold-italic ((,class :inherit bold-italic)))
@@ -4497,8 +4546,8 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(gnus-group-news-4-empty ((,class :foreground ,cyan-nuanced-fg)))
     `(gnus-group-news-5 ((,class :inherit bold :foreground ,red-nuanced-fg)))
     `(gnus-group-news-5-empty ((,class :foreground ,red-nuanced-fg)))
-    `(gnus-group-news-6 ((,class :inherit bold :foreground ,fg-alt)))
-    `(gnus-group-news-6-empty ((,class :inherit shadow)))
+    `(gnus-group-news-6 ((,class :inherit bold :foreground ,fg-unfocused)))
+    `(gnus-group-news-6-empty ((,class :foreground ,fg-unfocused)))
     `(gnus-group-news-low ((,class :inherit bold :foreground 
,green-nuanced-fg)))
     `(gnus-group-news-low-empty ((,class :foreground ,green-nuanced-fg)))
     `(gnus-header-content ((,class :inherit message-header-other)))
@@ -4722,8 +4771,8 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(highlight-defined-special-form-name-face ((,class :foreground 
,magenta-alt-other)))
     `(highlight-defined-variable-name-face ((,class :foreground ,cyan)))
 ;;;;; highlight-escape-sequences (`hes-mode')
-    `(hes-escape-backslash-face ((,class :inherit bold :foreground 
,fg-escape-char-construct)))
-    `(hes-escape-sequence-face ((,class :inherit bold :foreground 
,fg-escape-char-backslash)))
+    `(hes-escape-backslash-face ((,class :inherit 
font-lock-regexp-grouping-construct)))
+    `(hes-escape-sequence-face ((,class :inherit 
font-lock-regexp-grouping-backslash)))
 ;;;;; highlight-indentation
     `(highlight-indentation-face ((,class :inherit modus-themes-hl-line)))
     `(highlight-indentation-current-column-face ((,class :background 
,bg-active)))
@@ -4843,18 +4892,20 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(ioccur-title-face ((,class :inherit bold :foreground ,red-alt
                                  ,@(modus-themes--scale 
modus-themes-scale-4))))
 ;;;;; isearch, occur, and the like
-    `(isearch ((,class :inherit (modus-themes-intense-green bold))))
+    `(isearch ((,class :inherit (modus-themes-search-success bold))))
     `(isearch-fail ((,class :inherit modus-themes-refine-red)))
-    `(isearch-group-1 ((,class :inherit modus-themes-intense-blue)))
-    `(isearch-group-2 ((,class :inherit modus-themes-intense-magenta)))
-    `(lazy-highlight ((,class :inherit modus-themes-refine-cyan)))
+    `(isearch-group-1 ((,class :inherit modus-themes-refine-blue)))
+    `(isearch-group-2 ((,class :inherit modus-themes-refine-magenta)))
+    `(lazy-highlight ((,class :inherit modus-themes-search-success-lazy)))
     `(match ((,class :inherit modus-themes-special-calm)))
     `(query-replace ((,class :inherit (modus-themes-intense-yellow bold))))
 ;;;;; isl (isearch-light)
-    `(isl-line ((,class :inherit modus-themes-subtle-green)))
-    `(isl-match ((,class :inherit modus-themes-refine-cyan)))
-    `(isl-number ((,class :inherit modus-themes-bold :foreground 
,green-active)))
-    `(isl-on ((,class :inherit (bold modus-themes-intense-green))))
+    `(isl-line ((,class :inherit ,@(modus-themes--success-deuteran
+                                    'modus-themes-subtle-blue
+                                    'modus-themes-subtle-green))))
+    `(isl-match ((,class :inherit modus-themes-search-success-lazy)))
+    `(isl-number ((,class :inherit (modus-themes-bold 
modus-themes-search-success-modeline))))
+    `(isl-on ((,class :inherit (bold modus-themes-search-success))))
     `(isl-string ((,class :inherit modus-themes-bold :foreground 
,cyan-active)))
 ;;;;; ivy
     `(ivy-action ((,class :inherit bold :foreground ,red-alt)))
@@ -4959,9 +5010,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(jupyter-repl-output-prompt ((,class :foreground ,magenta-alt-other)))
     `(jupyter-repl-traceback ((,class :inherit modus-themes-intense-red)))
 ;;;;; kaocha-runner
-    `(kaocha-runner-error-face ((,class :foreground ,red)))
-    `(kaocha-runner-success-face ((,class :foreground ,green)))
-    `(kaocha-runner-warning-face ((,class :foreground ,yellow)))
+    `(kaocha-runner-error-face ((,class :inherit error)))
+    `(kaocha-runner-success-face ((,class :inherit success)))
+    `(kaocha-runner-warning-face ((,class :inherit warning)))
 ;;;;; keycast
     `(keycast-command ((,class :inherit bold :foreground ,blue-active)))
     `(keycast-key ((,class :background ,blue-active :foreground ,bg-main)))
@@ -5058,7 +5109,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     ;; not the highlighted ones.  This is because Magit's interaction
     ;; model relies on highlighting the current diff hunk.
     `(magit-diff-added ((,class ,@(modus-themes--diff
-                                   bg-main green
+                                   bg-main blue-alt-other
                                    bg-diff-added fg-diff-added
                                    green-nuanced-bg fg-diff-added
                                    bg-diff-added-deuteran 
fg-diff-added-deuteran))))
@@ -5072,17 +5123,23 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(magit-diff-context-highlight ((,class ,@(modus-themes--diff
                                                bg-dim fg-dim
                                                bg-inactive fg-inactive
+                                               bg-dim fg-alt
                                                bg-dim fg-alt))))
     `(magit-diff-file-heading ((,class :inherit bold :foreground 
,fg-special-cold)))
     `(magit-diff-file-heading-highlight ((,class :inherit 
(modus-themes-special-cold bold))))
     `(magit-diff-file-heading-selection ((,class :inherit 
modus-themes-refine-cyan)))
     ;; NOTE: here we break from the pattern of inheriting from the
     ;; modus-themes-diff-* faces.
-    `(magit-diff-hunk-heading ((,class :inherit bold :background ,bg-active
-                                       :foreground ,fg-inactive)))
+    `(magit-diff-hunk-heading ((,class :inherit bold
+                                       ,@(modus-themes--diff
+                                          bg-alt fg-alt
+                                          bg-active fg-inactive
+                                          bg-inactive fg-inactive
+                                          bg-inactive fg-inactive
+                                          t))))
     `(magit-diff-hunk-heading-highlight
       ((,class :inherit bold
-               :background ,@(modus-themes--diff-deuteran bg-region 
bg-diff-heading)
+               :background ,@(modus-themes--diff-deuteran bg-active 
bg-diff-heading)
                :foreground ,@(modus-themes--diff-deuteran fg-main 
fg-diff-heading))))
     `(magit-diff-hunk-heading-selection ((,class :inherit 
modus-themes-refine-blue)))
     `(magit-diff-hunk-region ((,class :inherit bold)))
@@ -5128,7 +5185,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(magit-section-heading ((,class :inherit bold :foreground ,cyan)))
     `(magit-section-heading-selection ((,class :inherit 
(modus-themes-refine-cyan bold))))
     `(magit-section-highlight ((,class :background ,bg-alt)))
-    `(magit-sequence-done ((,class :foreground ,green-alt)))
+    `(magit-sequence-done ((,class :foreground 
,@(modus-themes--success-deuteran
+                                                  blue
+                                                  green))))
     `(magit-sequence-drop ((,class :foreground ,red-alt)))
     `(magit-sequence-exec ((,class :foreground ,magenta-alt)))
     `(magit-sequence-head ((,class :foreground ,cyan-alt)))
@@ -5140,7 +5199,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(magit-signature-error ((,class :foreground ,red-alt)))
     `(magit-signature-expired ((,class :foreground ,yellow)))
     `(magit-signature-expired-key ((,class :foreground ,yellow)))
-    `(magit-signature-good ((,class :foreground ,green)))
+    `(magit-signature-good ((,class :foreground 
,@(modus-themes--success-deuteran
+                                                   blue
+                                                   green))))
     `(magit-signature-revoked ((,class :foreground ,magenta)))
     `(magit-signature-untrusted ((,class :foreground ,cyan)))
     `(magit-tag ((,class :foreground ,yellow-alt-other)))
@@ -5275,10 +5336,10 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(mentor-highlight-face ((,class :inherit modus-themes-subtle-blue)))
     `(mentor-tracker-name ((,class :foreground ,magenta-alt)))
 ;;;;; messages
-    `(message-cited-text-1 ((,class :foreground ,blue-faint)))
-    `(message-cited-text-2 ((,class :foreground ,green-alt-other)))
-    `(message-cited-text-3 ((,class :foreground ,red-alt-other)))
-    `(message-cited-text-4 ((,class :foreground ,cyan)))
+    `(message-cited-text-1 ((,class ,@(modus-themes--mail-cite blue-faint 
fg-alt))))
+    `(message-cited-text-2 ((,class ,@(modus-themes--mail-cite green-faint 
fg-comment-yellow))))
+    `(message-cited-text-3 ((,class ,@(modus-themes--mail-cite red-faint 
fg-special-cold))))
+    `(message-cited-text-4 ((,class ,@(modus-themes--mail-cite yellow-faint 
fg-special-calm))))
     `(message-header-cc ((,class :foreground ,blue-alt-other)))
     `(message-header-name ((,class :inherit bold :foreground ,cyan)))
     `(message-header-newsgroups ((,class :inherit message-header-other)))
@@ -5286,7 +5347,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(message-header-subject ((,class :inherit bold :foreground ,magenta-alt)))
     `(message-header-to ((,class :inherit bold :foreground 
,magenta-alt-other)))
     `(message-header-xheader ((,class :foreground ,blue-alt)))
-    `(message-mml ((,class :foreground ,yellow)))
+    `(message-mml ((,class :foreground ,cyan-alt-other)))
     `(message-separator ((,class :inherit modus-themes-intense-neutral)))
 ;;;;; minibuffer-line
     `(minibuffer-line ((,class :foreground ,fg-main)))
@@ -5302,7 +5363,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(mmm-init-submode-face ((,class :background ,magenta-nuanced-bg)))
     `(mmm-output-submode-face ((,class :background ,red-nuanced-bg)))
     `(mmm-special-submode-face ((,class :background ,green-nuanced-bg)))
-;;;;; modeline
+;;;;; mode-line
     `(mode-line ((,class ,@(modus-themes--variable-pitch-ui)
                          ,@(modus-themes--mode-line-attrs
                             fg-active bg-active
@@ -5324,7 +5385,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(mood-line-status-error ((,class :inherit bold :foreground ,red-active)))
     `(mood-line-status-info ((,class :foreground ,cyan-active)))
     `(mood-line-status-neutral ((,class :foreground ,blue-active)))
-    `(mood-line-status-success ((,class :foreground ,green-active)))
+    `(mood-line-status-success ((,class :foreground 
,@(modus-themes--success-deuteran
+                                                       blue-active
+                                                       green-active))))
     `(mood-line-status-warning ((,class :inherit bold :foreground 
,yellow-active)))
     `(mood-line-unimportant ((,class :foreground ,fg-inactive)))
 ;;;;; mpdel
@@ -5332,13 +5395,13 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(mpdel-playlist-current-song-face ((,class :inherit bold :foreground 
,blue-alt-other)))
 ;;;;; mu4e
     `(mu4e-attach-number-face ((,class :inherit bold :foreground ,fg-dim)))
-    `(mu4e-cited-1-face ((,class :foreground ,blue-faint)))
-    `(mu4e-cited-2-face ((,class :foreground ,green-alt-other)))
-    `(mu4e-cited-3-face ((,class :foreground ,red-alt-other)))
-    `(mu4e-cited-4-face ((,class :foreground ,cyan)))
-    `(mu4e-cited-5-face ((,class :foreground ,yellow-alt)))
-    `(mu4e-cited-6-face ((,class :foreground ,magenta)))
-    `(mu4e-cited-7-face ((,class :foreground ,green-alt)))
+    `(mu4e-cited-1-face ((,class :inherit message-cited-text-1)))
+    `(mu4e-cited-2-face ((,class :inherit message-cited-text-2)))
+    `(mu4e-cited-3-face ((,class :inherit message-cited-text-3)))
+    `(mu4e-cited-4-face ((,class :inherit message-cited-text-4)))
+    `(mu4e-cited-5-face ((,class :inherit message-cited-text-1)))
+    `(mu4e-cited-6-face ((,class :inherit message-cited-text-2)))
+    `(mu4e-cited-7-face ((,class :inherit message-cited-text-3)))
     `(mu4e-compose-header-face ((,class :inherit mu4e-compose-separator-face)))
     `(mu4e-compose-separator-face ((,class :inherit 
modus-themes-intense-neutral)))
     `(mu4e-contact-face ((,class :inherit message-header-to)))
@@ -5392,7 +5455,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(neo-file-link-face ((,class :foreground ,fg-main)))
     `(neo-header-face ((,class :inherit bold :foreground ,fg-main)))
     `(neo-root-dir-face ((,class :inherit bold :foreground ,cyan-alt)))
-    `(neo-vc-added-face ((,class :foreground ,green)))
+    `(neo-vc-added-face ((,class :foreground ,@(modus-themes--diff-deuteran 
blue green))))
     `(neo-vc-conflict-face ((,class :inherit bold :foreground ,red)))
     `(neo-vc-default-face ((,class :foreground ,fg-main)))
     `(neo-vc-edited-face ((,class :foreground ,yellow)))
@@ -5407,33 +5470,33 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
 ;;;;; no-emoji
     `(no-emoji ((,class :foreground ,cyan)))
 ;;;;; notmuch
-    `(notmuch-crypto-decryption ((,class :inherit modus-themes-special-mild)))
+    `(notmuch-crypto-decryption ((,class :inherit (shadow bold))))
     `(notmuch-crypto-part-header ((,class :foreground ,magenta-alt-other)))
-    `(notmuch-crypto-signature-bad ((,class :inherit 
modus-themes-intense-red)))
-    `(notmuch-crypto-signature-good ((,class :inherit 
modus-themes-refine-blue)))
-    `(notmuch-crypto-signature-good-key ((,class :inherit 
modus-themes-refine-cyan)))
-    `(notmuch-crypto-signature-unknown ((,class :inherit 
modus-themes-refine-red)))
+    `(notmuch-crypto-signature-bad ((,class :inherit error)))
+    `(notmuch-crypto-signature-good ((,class :inherit success)))
+    `(notmuch-crypto-signature-good-key ((,class :inherit bold :foreground 
,cyan)))
+    `(notmuch-crypto-signature-unknown ((,class :inherit warning)))
     `(notmuch-hello-logo-background ((,class :background "gray50")))
-    `(notmuch-message-summary-face ((,class :inherit 
modus-themes-nuanced-cyan)))
+    `(notmuch-message-summary-face ((,class :inherit (bold 
modus-themes-nuanced-cyan))))
     `(notmuch-search-count ((,class :inherit shadow)))
     `(notmuch-search-date ((,class :foreground ,cyan)))
     `(notmuch-search-flagged-face ((,class :foreground ,red-alt)))
-    `(notmuch-search-matching-authors ((,class :foreground ,fg-main)))
+    `(notmuch-search-matching-authors ((,class :foreground ,fg-special-cold)))
     `(notmuch-search-non-matching-authors ((,class :inherit shadow)))
-    `(notmuch-search-subject ((,class :foreground ,fg-dim)))
+    `(notmuch-search-subject ((,class :foreground ,fg-main)))
     `(notmuch-search-unread-face ((,class :inherit bold)))
-    `(notmuch-tag-added ((,class :inherit modus-themes-lang-note)))
-    `(notmuch-tag-deleted ((,class :inherit modus-themes-lang-error)))
-    `(notmuch-tag-face ((,class :inherit bold :foreground ,blue-alt)))
+    `(notmuch-tag-added ((,class :underline ,blue)))
+    `(notmuch-tag-deleted ((,class :strike-through ,red)))
+    `(notmuch-tag-face ((,class :foreground ,blue)))
     `(notmuch-tag-flagged ((,class :foreground ,red-alt)))
     `(notmuch-tag-unread ((,class :foreground ,magenta-alt)))
-    `(notmuch-tree-match-author-face ((,class :foreground ,fg-special-cold)))
+    `(notmuch-tree-match-author-face ((,class :inherit 
notmuch-search-matching-authors)))
     `(notmuch-tree-match-date-face ((,class :inherit notmuch-search-date)))
     `(notmuch-tree-match-face ((,class :foreground ,fg-main)))
-    `(notmuch-tree-match-tag-face ((,class :inherit bold :foreground 
,blue-alt)))
+    `(notmuch-tree-match-tag-face ((,class :inherit notmuch-tag-face)))
     `(notmuch-tree-no-match-face ((,class :inherit shadow)))
     `(notmuch-tree-no-match-date-face ((,class :inherit shadow)))
-    `(notmuch-wash-cited-text ((,class :foreground ,cyan)))
+    `(notmuch-wash-cited-text ((,class :inherit message-cited-text-1)))
     `(notmuch-wash-toggle-button ((,class :background ,bg-alt :foreground 
,fg-alt)))
 ;;;;; num3-mode
     `(num3-face-even ((,class :inherit bold :background ,bg-alt)))
@@ -5505,8 +5568,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                                     :foreground ,blue-alt)))
     `(org-archived ((,class :background ,bg-alt :foreground ,fg-alt)))
     `(org-block ((,class ,@(modus-themes--mixed-fonts)
-                         ,@(modus-themes--org-block bg-dim)
-                         :foreground ,fg-main)))
+                         ,@(modus-themes--org-block bg-dim fg-main))))
     `(org-block-begin-line ((,class ,@(modus-themes--mixed-fonts)
                                     ,@(modus-themes--org-block-delim
                                        bg-dim fg-special-cold
@@ -5533,7 +5595,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                                          :foreground ,fg-alt)))
     `(org-document-title ((,class :inherit (bold modus-themes-variable-pitch) 
:foreground ,fg-special-cold
                                   ,@(modus-themes--scale 
modus-themes-scale-5))))
-    `(org-done ((,class :foreground ,green)))
+    `(org-done ((,class :foreground ,@(modus-themes--success-deuteran blue 
green))))
     `(org-drawer ((,class ,@(modus-themes--mixed-fonts)
                           :foreground ,fg-alt)))
     `(org-ellipsis (())) ; inherits from the heading's color
@@ -5574,7 +5636,10 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
                                               green-graph-1-bg
                                               green-graph-0-bg
                                               green-graph-1-bg))))
-    `(org-headline-done ((,class :inherit modus-themes-variable-pitch 
:foreground ,green-nuanced-fg)))
+    `(org-headline-done ((,class :inherit modus-themes-variable-pitch
+                                 :foreground ,@(modus-themes--success-deuteran
+                                                blue-nuanced-fg
+                                                green-nuanced-fg))))
     `(org-headline-todo ((,class :inherit modus-themes-variable-pitch 
:foreground ,red-nuanced-fg)))
     `(org-hide ((,class :foreground ,bg-main)))
     `(org-indent ((,class :inherit (fixed-pitch org-hide))))
@@ -5597,7 +5662,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(org-priority ((,class :foreground ,magenta)))
     `(org-property-value ((,class ,@(modus-themes--mixed-fonts)
                                   :foreground ,fg-special-cold)))
-    `(org-quote ((,class ,@(modus-themes--org-block bg-dim))))
+    `(org-quote ((,class ,@(modus-themes--org-block bg-dim fg-special-cold 
fg-main))))
     `(org-scheduled ((,class :foreground ,magenta-alt)))
     `(org-scheduled-previously ((,class :foreground ,yellow-alt-other)))
     `(org-scheduled-today ((,class :foreground ,magenta-alt-other)))
@@ -5736,15 +5801,17 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
 ;;;;; phi-search
     `(phi-replace-preview-face ((,class :inherit 
modus-themes-intense-magenta)))
     `(phi-search-failpart-face ((,class :inherit modus-themes-refine-red)))
-    `(phi-search-match-face ((,class :inherit modus-themes-refine-cyan)))
-    `(phi-search-selection-face ((,class :inherit (modus-themes-intense-green 
bold))))
+    `(phi-search-match-face ((,class :inherit 
modus-themes-search-success-lazy)))
+    `(phi-search-selection-face ((,class :inherit (modus-themes-search-success 
bold))))
 ;;;;; pkgbuild-mode
     `(pkgbuild-error-face ((,class :inherit modus-themes-lang-error)))
 ;;;;; pomidor
     `(pomidor-break-face ((,class :foreground ,blue-alt-other)))
     `(pomidor-overwork-face ((,class :foreground ,red-alt-other)))
     `(pomidor-skip-face ((,class :inherit modus-themes-slant :foreground 
,fg-alt)))
-    `(pomidor-work-face ((,class :foreground ,green-alt-other)))
+    `(pomidor-work-face ((,class :foreground ,@(modus-themes--success-deuteran
+                                                blue-alt
+                                                green-alt-other))))
 ;;;;; popup
     `(popup-face ((,class :background ,bg-alt :foreground ,fg-main)))
     `(popup-isearch-match ((,class :inherit (modus-themes-refine-cyan bold))))
@@ -5943,7 +6010,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(selectrum-quick-keys-highlight
       ((,class :inherit modus-themes-refine-red)))
     `(selectrum-quick-keys-match
-      ((,class :inherit (bold modus-themes-intense-green))))
+      ((,class :inherit (bold modus-themes-search-success))))
 ;;;;; selectrum-prescient
     `(selectrum-prescient-primary-highlight
       ((,class :inherit bold
@@ -5983,7 +6050,7 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(show-paren-match ((,class ,@(modus-themes--paren bg-paren-match
                                                        bg-paren-match-intense)
                                 :foreground ,fg-main)))
-    `(show-paren-match-expression ((,class :inherit 
modus-themes-special-calm)))
+    `(show-paren-match-expression ((,class :background ,bg-paren-expression)))
     `(show-paren-mismatch ((,class :inherit modus-themes-intense-red)))
 ;;;;; shr
     `(shr-abbreviation ((,class :inherit modus-themes-lang-note)))
@@ -6149,22 +6216,14 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(syslog-su ((,class :inherit bold :foreground ,red-alt)))
     `(syslog-warn ((,class :inherit bold :foreground ,yellow)))
 ;;;;; tab-bar-groups
-    `(tab-bar-groups-1 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,blue-tab)))
-    `(tab-bar-groups-1-group-name ((,class :inherit tab-bar-groups-1 
:inverse-video t)))
-    `(tab-bar-groups-2 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,red-tab)))
-    `(tab-bar-groups-2-group-name ((,class :inherit tab-bar-groups-2 
:inverse-video t)))
-    `(tab-bar-groups-3 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,green-tab)))
-    `(tab-bar-groups-3-group-name ((,class :inherit tab-bar-groups-3 
:inverse-video t)))
-    `(tab-bar-groups-4 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,orange-tab)))
-    `(tab-bar-groups-4-group-name ((,class :inherit tab-bar-groups-4 
:inverse-video t)))
-    `(tab-bar-groups-5 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,purple-tab)))
-    `(tab-bar-groups-5-group-name ((,class :inherit tab-bar-groups-5 
:inverse-video t)))
-    `(tab-bar-groups-6 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,cyan-tab)))
-    `(tab-bar-groups-6-group-name ((,class :inherit tab-bar-groups-6 
:inverse-video t)))
-    `(tab-bar-groups-7 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,yellow-tab)))
-    `(tab-bar-groups-7-group-name ((,class :inherit tab-bar-groups-7 
:inverse-video t)))
-    `(tab-bar-groups-8 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,magenta-tab)))
-    `(tab-bar-groups-8-group-name ((,class :inherit tab-bar-groups-8 
:inverse-video t)))
+    `(tab-bar-groups-tab-1 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,blue-tab)))
+    `(tab-bar-groups-tab-2 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,red-tab)))
+    `(tab-bar-groups-tab-3 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,green-tab)))
+    `(tab-bar-groups-tab-4 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,orange-tab)))
+    `(tab-bar-groups-tab-5 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,purple-tab)))
+    `(tab-bar-groups-tab-6 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,cyan-tab)))
+    `(tab-bar-groups-tab-7 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,yellow-tab)))
+    `(tab-bar-groups-tab-8 ((,class ,@(modus-themes--variable-pitch-ui) 
:foreground ,magenta-tab)))
 ;;;;; tab-bar-mode
     `(tab-bar ((,class ,@(modus-themes--variable-pitch-ui)
                        :background ,bg-tab-bar :foreground ,fg-main)))
@@ -6254,7 +6313,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(transient-argument ((,class :inherit bold :foreground ,red-alt)))
     `(transient-blue ((,class :inherit bold :foreground ,blue)))
     `(transient-disabled-suffix ((,class :inherit modus-themes-intense-red)))
-    `(transient-enabled-suffix ((,class :inherit modus-themes-intense-green)))
+    `(transient-enabled-suffix ((,class :inherit 
,@(modus-themes--success-deuteran
+                                                    'modus-themes-subtle-blue
+                                                    
'modus-themes-subtle-green))))
     `(transient-heading ((,class :inherit bold :foreground ,fg-main)))
     `(transient-inactive-argument ((,class :inherit shadow)))
     `(transient-inactive-value ((,class :inherit shadow)))
@@ -6291,7 +6352,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(treemacs-help-column-face ((,class :inherit modus-themes-bold 
:foreground ,magenta-alt-other :underline t)))
     `(treemacs-help-title-face ((,class :foreground ,blue-alt-other)))
     `(treemacs-on-failure-pulse-face ((,class :inherit 
modus-themes-intense-red)))
-    `(treemacs-on-success-pulse-face ((,class :inherit 
modus-themes-intense-green)))
+    `(treemacs-on-success-pulse-face ((,class :inherit 
,@(modus-themes--success-deuteran
+                                                          
'modus-themes-intense-blue
+                                                          
'modus-themes-intense-green))))
     `(treemacs-root-face ((,class :inherit bold :foreground ,blue-alt-other 
:height 1.2 :underline t)))
     `(treemacs-root-remote-disconnected-face ((,class :inherit 
treemacs-root-remote-face :foreground ,yellow)))
     `(treemacs-root-remote-face ((,class :inherit treemacs-root-face 
:foreground ,magenta)))
@@ -6563,9 +6626,9 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
     `(flymake-note-bitmap '(exclamation-mark modus-themes-fringe-cyan))
 ;;;; ibuffer
     `(ibuffer-deletion-face 'modus-themes-mark-del)
-    `(ibuffer-filter-group-name-face 'modus-themes-mark-symbol)
+    `(ibuffer-filter-group-name-face 'modus-themes-pseudo-header)
     `(ibuffer-marked-face 'modus-themes-mark-sel)
-    `(ibuffer-title-face 'modus-themes-pseudo-header)
+    `(ibuffer-title-face 'default)
 ;;;; highlight-tail
     `(highlight-tail-colors
       '((,green-subtle-bg . 0)
@@ -6619,7 +6682,8 @@ by virtue of calling either of 
`modus-themes-load-operandi' and
 ;;;; xterm-color
     `(xterm-color-names ["black" ,red ,green ,yellow ,blue ,magenta ,cyan 
"gray65"])
     `(xterm-color-names-bright ["gray35" ,red-alt ,green-alt ,yellow-alt 
,blue-alt ,magenta-alt ,cyan-alt "white"])
-    (if (eq modus-themes-org-blocks 'rainbow)
+    (if (or (eq modus-themes-org-blocks 'tinted-background)
+            (eq modus-themes-org-blocks 'rainbow))
         `(org-src-block-faces              ; TODO this list should be expanded
           `(("emacs-lisp" modus-themes-nuanced-magenta)
             ("elisp" modus-themes-nuanced-magenta)
diff --git a/etc/themes/modus-vivendi-theme.el 
b/etc/themes/modus-vivendi-theme.el
index ff59d30..fa8ba21 100644
--- a/etc/themes/modus-vivendi-theme.el
+++ b/etc/themes/modus-vivendi-theme.el
@@ -4,7 +4,7 @@
 
 ;; Author: Protesilaos Stavrou <info@protesilaos.com>
 ;; URL: https://gitlab.com/protesilaos/modus-themes
-;; Version: 1.3.2
+;; Version: 1.4.0
 ;; Package-Requires: ((emacs "26.1"))
 ;; Keywords: faces, theme, accessibility
 
diff --git a/etc/tutorials/TUTORIAL.sv b/etc/tutorials/TUTORIAL.sv
index cbe9cfc..dacc66d 100644
--- a/etc/tutorials/TUTORIAL.sv
+++ b/etc/tutorials/TUTORIAL.sv
@@ -1056,7 +1056,7 @@ att först senare ta bort fönstret med C-x 1.
 
 Här är fler varianter på C-h:
 
-   C-h f        Beskriv ett kommando. Du skriver in kommandots namn.
+   C-h x        Beskriv ett kommando. Du skriver in kommandots namn.
 
 >> Prova att skriva C-h x previous-line <Return>.
    Detta visar den information Emacs har om den funktion
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 6c7a443..ec92f92 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -69,7 +69,9 @@ Makefile: ../config.status $(srcdir)/Makefile.in
 # Object modules that need not be built for Emacs.
 # Emacs does not need e-regex.o (it has its own regex-emacs.c),
 # and building it would just waste time.
-not_emacs_OBJECTS = regex.o
+# Emacs also doesn't need the dynarray-related files in malloc/ and
+# the replacement 'free'.
+not_emacs_OBJECTS = regex.o malloc/%.o free.o
 
 libgnu_a_OBJECTS = fingerprint.o $(gl_LIBOBJS) \
   $(patsubst %.c,%.o,$(filter %.c,$(libgnu_a_SOURCES)))
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index 64b467a..31e41a9 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -2054,7 +2054,10 @@ You can mark bookmarks with the 
\\<bookmark-bmenu-mode-map>\\[bookmark-bmenu-mar
 
 (defun bookmark-bmenu-save ()
   "Save the current list into a bookmark file.
-With a prefix arg, prompts for a file to save them in."
+With a prefix arg, prompts for a file to save them in.
+
+See also the related behaviors of `bookmark-load' and
+`bookmark-bmenu-load'."
   (interactive nil bookmark-bmenu-mode)
   (save-excursion
     (save-window-excursion
@@ -2063,7 +2066,19 @@ With a prefix arg, prompts for a file to save them in."
 
 
 (defun bookmark-bmenu-load ()
-  "Load the bookmark file and rebuild the bookmark menu-buffer."
+  "Load bookmarks from a file and rebuild the bookmark menu-buffer.
+Prompt for a file, with the default choice being the value of
+`bookmark-default-file'.
+
+With a prefix argument, replace the current ambient bookmarks
+(i.e., the ones in `bookmark-alist') with the ones from the selected
+file and make that file be the new value of `bookmark-default-file'.
+In other words, a prefix argument means \"switch over to the bookmark
+universe defined in the loaded file\".  Without a prefix argument,
+just add the loaded bookmarks into the current ambient set.
+
+See the documentation for `bookmark-load' for more details; see also
+the related behaviors of `bookmark-save' and `bookmark-bmenu-save'."
   (interactive nil bookmark-bmenu-mode)
   (bookmark-bmenu-ensure-position)
   (save-excursion
diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el
index 1e45067..62b2072 100644
--- a/lisp/cedet/pulse.el
+++ b/lisp/cedet/pulse.el
@@ -153,8 +153,7 @@ Optional argument FACE specifies the face to do the 
highlighting."
       ;; with a reference face needed for the color.
       (pulse-reset-face face)
       (let* ((start (color-name-to-rgb
-                     (face-background 'pulse-highlight-start-face
-                                      nil 'default)))
+                     (face-background 'pulse-highlight-face nil 'default)))
              (stop (color-name-to-rgb (face-background 'default)))
              (colors (mapcar (apply-partially 'apply 'color-rgb-to-hex)
                              (color-gradient start stop pulse-iterations))))
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index eb43ab1..a1dda3f 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1169,7 +1169,7 @@ ARGS are command switches passed to PROGRAM.")
 (defcustom dired-compress-file-default-suffix nil
   "Default suffix for compressing a single file.
 If nil, \".gz\" will be used."
-  :type 'string
+  :type '(choice (const :tag ".gz" nil) string)
   :group 'dired
   :version "28.1")
 
@@ -1190,7 +1190,7 @@ output file.  %i path(s) are relative, while %o is 
absolute.")
 (defcustom dired-compress-directory-default-suffix nil
   "Default suffix for compressing a directory.
 If nil, \".tar.gz\" will be used."
-  :type 'string
+  :type '(choice (const :tag ".tar.gz" nil) string)
   :group 'dired
   :version "28.1")
 
@@ -2065,6 +2065,25 @@ ESC or `q' to not overwrite any of the remaining files,
               operation success-count))))
   (dired-move-to-filename))
 
+(defcustom dired-do-revert-buffer nil
+  "Automatically revert Dired buffers after `dired-do' operations.
+This option controls whether to refresh the directory listing in a
+Dired buffer that is the destination of one of these operations:
+`dired-do-copy', `dired-do-rename', `dired-do-symlink', `dired-do-hardlink'.
+If the value is t, always revert the Dired buffer updated in the result
+of these operations.
+If the value is a function, it is called with the destination directory name
+as a single argument, and the buffer is reverted after Dired operations
+if the function returns non-nil."
+  :type '(choice
+          (const :tag "Don't revert" nil)
+          (const :tag "Always revert destination directory" t)
+          (const :tag "Revert only local Dired buffers"
+                 (lambda (dir) (not (file-remote-p dir))))
+          (function :tag "Predicate function"))
+  :group 'dired
+  :version "28.1")
+
 (defun dired-do-create-files (op-symbol file-creator operation arg
                                        &optional marker-char op1
                                        how-to)
@@ -2160,15 +2179,21 @@ Optional arg HOW-TO determines how to treat the target.
           (error "%s: Target directory does not exist: %s" operation target))
       ;; rename-file bombs when moving directories unless we do this:
       (or into-dir (setq target (directory-file-name target)))
-      (dired-create-files
-       file-creator operation fn-list
-       (if into-dir                    ; target is a directory
-          ;; This function uses fluid variable target when called
-          ;; inside dired-create-files:
-          (lambda (from)
-            (expand-file-name (file-name-nondirectory from) target))
-        (lambda (_from) target))
-       marker-char))))
+      (prog1
+          (dired-create-files
+           file-creator operation fn-list
+           (if into-dir                        ; target is a directory
+              ;; This function uses fluid variable target when called
+              ;; inside dired-create-files:
+              (lambda (from)
+                (expand-file-name (file-name-nondirectory from) target))
+            (lambda (_from) target))
+           marker-char)
+        (when (or (eq dired-do-revert-buffer t)
+                  (and (functionp dired-do-revert-buffer)
+                       (funcall dired-do-revert-buffer target)))
+          (dired-fun-in-all-buffers (file-name-directory target) nil
+                                    #'revert-buffer))))))
 
 ;; Read arguments for a marked-files command that wants a file name,
 ;; perhaps popping up the list of marked files.
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 5f31bc4..6619a39 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -576,7 +576,7 @@ files in the active region if `dired-mark-region' is 
non-nil."
 
 (defalias 'virtual-dired 'dired-virtual)
 (defun dired-virtual (dirname &optional switches)
-  "Put this buffer into Virtual Dired mode.
+  "Put this Dired buffer into Virtual Dired mode.
 
 In Virtual Dired mode, all commands that do not actually consult the
 filesystem will work.
@@ -608,7 +608,8 @@ you can relist single subdirs using \\[dired-do-redisplay]."
   ;; hand if you want them.
 
   (interactive
-   (list (read-string "Virtual Dired directory: " (dired-virtual-guess-dir))))
+   (list (read-directory-name "Virtual Dired directory: "
+                              nil (dired-virtual-guess-dir))))
   (goto-char (point-min))
   (or (looking-at-p "  ")
       ;; if not already indented, do it now:
@@ -940,10 +941,15 @@ Each element of this list looks like
 
     (REGEXP COMMAND...)
 
-where each COMMAND can either be a string or a Lisp expression that evaluates
+COMMAND will be used if REGEXP matches the file to be processed.
+If several files are to be processed, REGEXP has to match all the
+files.
+
+Each COMMAND can either be a string or a Lisp expression that evaluates
 to a string.  If this expression needs to consult the name of the file for
 which the shell commands are being requested, it can access that file name
 as the variable `file'.
+
 If several COMMANDs are given, the first one will be the default
 and the rest will be added temporarily to the history and can be retrieved
 with \\[previous-history-element] (M-p) .
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 28b53d0..10a50da 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -225,6 +225,14 @@
        (byte-compile-log-lap-1 ,format-string ,@args)))
 
 
+(defvar byte-optimize--lexvars nil
+  "Lexical variables in scope, in reverse order of declaration.
+Each element is on the form (NAME KEEP [VALUE]), where:
+  NAME is the variable name,
+  KEEP is a boolean indicating whether the binding must be retained,
+  VALUE, if present, is a substitutable expression.
+Earlier variables shadow later ones with the same name.")
+
 ;;; byte-compile optimizers to support inlining
 
 (put 'inline 'byte-optimizer #'byte-optimize-inline-handler)
@@ -268,32 +276,31 @@
        ;; The byte-code will be really inlined in byte-compile-unfold-bcf.
        `(,fn ,@(cdr form)))
       ((or `(lambda . ,_) `(closure . ,_))
-       (if (not (or (eq fn localfn)     ;From the same file => same mode.
-                    (eq (car fn)        ;Same mode.
-                        (if lexical-binding 'closure 'lambda))))
-           ;; While byte-compile-unfold-bcf can inline dynbind byte-code into
-           ;; letbind byte-code (or any other combination for that matter), we
-           ;; can only inline dynbind source into dynbind source or letbind
-           ;; source into letbind source.
-           (progn
-             ;; We can of course byte-compile the inlined function
-             ;; first, and then inline its byte-code.
-             (byte-compile name)
-             `(,(symbol-function name) ,@(cdr form)))
-         (let ((newfn (if (eq fn localfn)
-                          ;; If `fn' is from the same file, it has already
-                          ;; been preprocessed!
-                          `(function ,fn)
-                        ;; Try and process it "in its original environment".
-                        (let ((byte-compile-bound-variables nil))
-                          (byte-compile-preprocess
-                           (byte-compile--reify-function fn))))))
-           (if (eq (car-safe newfn) 'function)
-               (macroexp--unfold-lambda `(,(cadr newfn) ,@(cdr form)))
-             ;; This can happen because of macroexp-warn-and-return &co.
-             (byte-compile-warn
-              "Inlining closure %S failed" name)
-             form))))
+       ;; While byte-compile-unfold-bcf can inline dynbind byte-code into
+       ;; letbind byte-code (or any other combination for that matter), we
+       ;; can only inline dynbind source into dynbind source or letbind
+       ;; source into letbind source.
+       ;; When the function comes from another file, we byte-compile
+       ;; the inlined function first, and then inline its byte-code.
+       ;; This also has the advantage that the final code does not
+       ;; depend on the order of compilation of ELisp files, making
+       ;; the build more reproducible.
+       (if (eq fn localfn)
+           ;; From the same file => same mode.
+           (macroexp--unfold-lambda `(,fn ,@(cdr form)))
+         ;; Since we are called from inside the optimiser, we need to make
+         ;; sure not to propagate lexvar values.
+         (let ((byte-optimize--lexvars nil)
+               ;; Silence all compilation warnings: the useful ones should
+               ;; be displayed when the function's source file will be
+               ;; compiled anyway, but more importantly we would otherwise
+               ;; emit spurious warnings here because we don't have the full
+               ;; context, such as `declare-functions' placed earlier in the
+               ;; source file's code or `with-suppressed-warnings' that
+               ;; surrounded the `defsubst'.
+               (byte-compile-warnings nil))
+           (byte-compile name))
+         `(,(symbol-function name) ,@(cdr form))))
 
       (_ ;; Give up on inlining.
        form))))
@@ -308,14 +315,6 @@
 This does usually not indicate a problem and makes the compiler
 very chatty, but can be useful for debugging.")
 
-(defvar byte-optimize--lexvars nil
-  "Lexical variables in scope, in reverse order of declaration.
-Each element is on the form (NAME KEEP [VALUE]), where:
-  NAME is the variable name,
-  KEEP is a boolean indicating whether the binding must be retained,
-  VALUE, if present, is a substitutable expression.
-Earlier variables shadow later ones with the same name.")
-
 (defvar byte-optimize--vars-outside-condition nil
   "Alist of variables lexically bound outside conditionally executed code.
 Variables here are sensitive to mutation inside the conditional code,
@@ -369,7 +368,7 @@ Same format as `byte-optimize--lexvars', with shared 
structure and contents.")
   ;; to   `(if . (or `(,exp ,then ,else) pcase--dontcare))'.
   ;;
   ;; The resulting macroexpansion is also significantly cleaner/smaller/faster.
-  (declare (indent 1) (debug (form &rest (pcase-PAT body))))
+  (declare (indent 1) (debug pcase))
   `(pcase ,exp
      . ,(mapcar (lambda (case)
                   `(,(pcase (car case)
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 283c5e4..a59d42e 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -941,7 +941,8 @@ For more details, see Info node `(cl)Loop Facility'.
                                "above" "below" "by" "in" "on" "=" "across"
                                "repeat" "while" "until" "always" "never"
                                "thereis" "collect" "append" "nconc" "sum"
-                               "count" "maximize" "minimize" "if" "unless"
+                               "count" "maximize" "minimize"
+                               "if" "when" "unless"
                                "return"]
                           form]
                          ["using" (symbolp symbolp)]
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 8c63831..b09739c 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -154,7 +154,7 @@ buffer."
   :type '(choice
           (const :tag "Do not report warnings" nil)
           (const :tag "Report and display warnings" t)
-          (const :tag "Report but do not display warnings" 'silent))
+          (const :tag "Report but do not display warnings" silent))
   :version "28.1")
 
 (defcustom native-comp-async-query-on-exit nil
diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el
index a9baef3..6ba2e78 100644
--- a/lisp/emacs-lisp/copyright.el
+++ b/lisp/emacs-lisp/copyright.el
@@ -51,7 +51,7 @@ This is useful for ChangeLogs."
  "\\(©\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\
 \\|[Cc]opyright\\s *:?\\s *©\\)\
 \\s *[^0-9\n]*\\s *\
-\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
+\\([1-9]\\([-0-9, ';/*%#\n\t–]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
   "What your copyright notice looks like.
 The second \\( \\) construct must match the years."
   :type 'regexp)
@@ -69,7 +69,7 @@ someone else or to a group for which you do not work."
 ;;;###autoload(put 'copyright-names-regexp 'safe-local-variable 'stringp)
 
 (defcustom copyright-years-regexp
- "\\(\\s *\\)\\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
+  "\\(\\s *\\)\\([1-9]\\([-0-9, ';/*%#\n\t–]\\|\\s<\\|\\s>\\)*[0-9]+\\)"
   "Match additional copyright notice years.
 The second \\( \\) construct must match the years."
   :type 'regexp)
@@ -197,8 +197,8 @@ skips to the end of all the years."
                                                  (point))))
                            100)
                         1)
-                    (or (eq (char-after (+ (point) size -1)) ?-)
-                        (eq (char-after (+ (point) size -2)) ?-)))
+                    (or (memq (char-after (+ (point) size -1)) '(?- ?–))
+                        (memq (char-after (+ (point) size -2)) '(?- ?–))))
                ;; This is a range so just replace the end part.
                (delete-char size)
              ;; Insert a comma with the preferred number of spaces.
@@ -287,7 +287,7 @@ independently replaces consecutive years with a range."
          (setq year (string-to-number (match-string 0)))
          (and (setq sep (char-before))
               (/= (char-syntax sep) ?\s)
-              (/= sep ?-)
+              (not (memq sep '(?- ?–)))
               (insert " "))
          (when (< year 100)
            (insert (if (>= year 50) "19" "20"))
@@ -297,7 +297,7 @@ independently replaces consecutive years with a range."
            ;; If the previous thing was a range, don't try to tack more on.
            ;; Ie not 2000-2005 -> 2000-2005-2007
            ;; TODO should merge into existing range if possible.
-           (if (eq sep ?-)
+           (if (memq sep '(?- ?–))
                (setq prev-year nil
                      year nil)
              (if (and prev-year (= year (1+ prev-year)))
@@ -306,7 +306,7 @@ independently replaces consecutive years with a range."
                           (> prev-year first-year))
                  (goto-char range-end)
                  (delete-region range-start range-end)
-                 (insert (format "-%d" prev-year))
+                 (insert (format "%c%d" sep prev-year))
                  (goto-char p))
                (setq first-year year
                      range-start (point)))))
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 43bd84d..071d390 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -1442,10 +1442,9 @@ following constructs:
                    introduced by a previous (let REF ...)
                    construct."
   (let* ((rx--pcase-vars nil)
-         (regexp (rx--to-expr (rx--pcase-transform (cons 'seq regexps))))
-         (nvars (length rx--pcase-vars)))
+         (regexp (rx--to-expr (rx--pcase-transform (cons 'seq regexps)))))
     `(and (pred stringp)
-          ,(pcase nvars
+          ,(pcase (length rx--pcase-vars)
             (0
              ;; No variables bound: a single predicate suffices.
              `(pred (string-match ,regexp)))
@@ -1458,7 +1457,7 @@ following constructs:
                          (match-string 1 s)
                        0))
                    (and ,(car rx--pcase-vars) (pred (not numberp)))))
-            (_
+            (nvars
              ;; Pack the submatches into a dotted list which is then
              ;; immediately destructured into individual variables again.
              ;; This is of course slightly inefficient.
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index 0320e17..38d8ad6 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -221,7 +221,7 @@ There can be any number of :example/:result elements."
   (string-greaterp
    :eval (string-greaterp "foo" "bar"))
   (string-version-lessp
-   :eval (string-lessp "foo32.png" "bar4.png"))
+   :eval (string-version-lessp "pic4.png" "pic32.png"))
   (string-prefix-p
    :eval (string-prefix-p "foo" "foobar"))
   (string-suffix-p
@@ -613,7 +613,7 @@ There can be any number of :example/:result elements."
   (lax-plist-get
    :eval (lax-plist-get '("a" 1 "b" 2 "c" 3) "b"))
   (lax-plist-put
-   :no-eval (setq plist (plist-put plist "d" 4))
+   :no-eval (setq plist (lax-plist-put plist "d" 4))
    :eq-result '("a" 1 "b" 2 "c" 3 "d" 4))
   (plist-member
    :eval (plist-member '(a 1 b 2 c 3) 'b))
@@ -666,7 +666,7 @@ There can be any number of :example/:result elements."
    :no-eval (re-search-backward "^foo$" nil t)
    :eg-result 43)
   (looking-at-p
-   :no-eval (looking-at "f[0-9]")
+   :no-eval (looking-at-p "f[0-9]")
    :eg-result t)
   "Match Data"
   (match-string
@@ -838,7 +838,7 @@ There can be any number of :example/:result elements."
   (point
    :eval (point))
   (point-min
-   :eval (point-max))
+   :eval (point-min))
   (point-max
    :eval (point-max))
   (line-beginning-position
@@ -1056,7 +1056,7 @@ There can be any number of :example/:result elements."
   (logb
    :eval (logb 10.5))
   (ffloor
-   :eval (floor 1.2))
+   :eval (ffloor 1.2))
   (fceiling
    :eval (fceiling 1.2))
   (ftruncate
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index fb89050..1c13c39 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -127,7 +127,7 @@ This is like `if-let' but doesn't handle a VARLIST of the 
form
 \(SYMBOL SOMETHING) specially."
   (declare (indent 2)
            (debug ((&rest [&or symbolp (symbolp form) (form)])
-                   form body)))
+                   body)))
   (if varlist
       `(let* ,(setq varlist (internal--build-bindings varlist))
          (if ,(caar (last varlist))
@@ -146,9 +146,7 @@ This is like `when-let' but doesn't handle a VARLIST of the 
form
   "Bind variables according to VARLIST and conditionally evaluate BODY.
 Like `when-let*', except if BODY is empty and all the bindings
 are non-nil, then the result is non-nil."
-  (declare (indent 1)
-           (debug ((&rest [&or symbolp (symbolp form) (form)])
-                   body)))
+  (declare (indent 1) (debug if-let*))
   (let (res)
     (if varlist
         `(let* ,(setq varlist (internal--build-bindings varlist))
@@ -176,7 +174,7 @@ with an old syntax that accepted only one binding."
   (declare (indent 2)
            (debug ([&or (symbolp form)  ; must be first, Bug#48489
                         (&rest [&or symbolp (symbolp form) (form)])]
-                   form body)))
+                   body)))
   (when (and (<= (length spec) 2)
              (not (listp (car spec))))
     ;; Adjust the single binding case
diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el
index 09d1f7a..073d164 100644
--- a/lisp/erc/erc-services.el
+++ b/lisp/erc/erc-services.el
@@ -32,8 +32,8 @@
 
 ;; As a default, ERC has the data for the official nickname services on
 ;; the networks Austnet, BrasNET, Dalnet, freenode, GalaxyNet, GRnet,
-;; and Slashnet.  You can add more by using M-x customize-variable RET
-;; erc-nickserv-alist.
+;; Libera.Chat and Slashnet.  You can add more by using
+;;   M-x customize-variable RET erc-nickserv-alist.
 
 ;; Usage:
 ;;
@@ -197,6 +197,7 @@ Example of use:
                        (const GalaxyNet)
                        (const GRnet)
                        (const iip)
+                        (const Libera.Chat)
                        (const OFTC)
                        (const QuakeNet)
                        (const Rizon)
@@ -264,6 +265,15 @@ Example of use:
      "type\\s-/squery\\s-Trent\\s-identify\\s-<password>"
      "Trent@anon.iip"
      "IDENTIFY" nil "SQUERY" nil)
+    (Libera.Chat
+     "NickServ!NickServ@services.libera.chat"
+     ;; Libera.Chat also accepts a password at login, see the `erc'
+     ;; :password argument.
+     "This\\s-nickname\\s-is\\s-registered.\\s-Please\\s-choose"
+     "NickServ"
+     "IDENTIFY" nil nil
+     ;; See also the 901 response code message.
+     "You\\s-are\\s-now\\s-identified\\s-for\\s-")
     (OFTC
      "NickServ!services@services.oftc.net"
      ;; OFTC's NickServ doesn't ask you to identify anymore.
diff --git a/lisp/faces.el b/lisp/faces.el
index 138abc1..bc0c3f9 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -46,7 +46,7 @@ the terminal-initialization file to be loaded."
     ("vt320" . "vt200")
     ("vt400" . "vt200")
     ("vt420" . "vt200")
-    )
+    ("alacritty" . "xterm"))
   "Alist of terminal type aliases.
 Entries are of the form (TYPE . ALIAS), where both elements are strings.
 This means to treat a terminal of type TYPE as if it were of type ALIAS."
diff --git a/lisp/files.el b/lisp/files.el
index 4fdafe1..c694507 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -4359,6 +4359,9 @@ Return the new class name, which is a symbol named DIR."
                      (let ((read-circle nil))
                        (read (current-buffer)))
                    (end-of-file nil))))
+            (unless (listp newvars)
+              (message "Invalid data in %s: %s" file newvars)
+              (setq newvars nil))
             (setq variables
                   ;; Try and avoid loading `map' since that also loads cl-lib
                   ;; which then might hamper bytecomp warnings (bug#30635).
@@ -7945,6 +7948,7 @@ Otherwise, trash FILENAME using the freedesktop.org 
conventions,
 
               ;; Make a .trashinfo file.  Use O_EXCL, as per trash-spec 1.0.
               (let* ((files-base (file-name-nondirectory fn))
+                      (is-directory (file-directory-p fn))
                       (overwrite nil)
                       info-fn)
                  ;; We're checking further down whether the info file
@@ -7956,7 +7960,8 @@ Otherwise, trash FILENAME using the freedesktop.org 
conventions,
                          files-base (file-name-nondirectory
                                      (make-temp-file
                                       (expand-file-name
-                                       files-base trash-files-dir)))))
+                                       files-base trash-files-dir)
+                                      is-directory))))
                 (setq info-fn (expand-file-name
                                (concat files-base ".trashinfo")
                                trash-info-dir))
diff --git a/lisp/find-file.el b/lisp/find-file.el
index 6c3c0f1..4fd4f4e 100644
--- a/lisp/find-file.el
+++ b/lisp/find-file.el
@@ -305,6 +305,10 @@ Being on a `#include' line pulls in that file.
 If optional IN-OTHER-WINDOW is non-nil, find the file in the other window.
 If optional IGNORE-INCLUDE is non-nil, ignore being on `#include' lines.
 
+If optional EVENT is non-nil (default `last-nonmenu-event', move
+point to the end position of that event before calling the
+various ff-* hooks.
+
 Variables of interest include:
 
  - `ff-case-fold-search'
@@ -351,10 +355,16 @@ Variables of interest include:
  - `ff-file-created-hook'
    List of functions to be called if the other file has been created."
   (interactive (list current-prefix-arg nil last-nonmenu-event))
-  (save-excursion
+  ;; We want to preserve point in the current buffer. But the point of
+  ;; ff-find-the-other-file is to make the the other file buffer
+  ;; current, so we can't use save-excursion here (see bug 48535).
+  (let ((start-buffer (current-buffer))
+        (start-point (point)))
     (posn-set-point (event-end event))
     (let ((ff-ignore-include ignore-include))
-      (ff-find-the-other-file in-other-window))))
+      (ff-find-the-other-file in-other-window))
+    (with-current-buffer start-buffer
+      (goto-char start-point))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Support functions
diff --git a/lisp/gnus/gnus-fun.el b/lisp/gnus/gnus-fun.el
index c2e72ab..8bca4ff 100644
--- a/lisp/gnus/gnus-fun.el
+++ b/lisp/gnus/gnus-fun.el
@@ -206,12 +206,11 @@ different input formats."
 (defun gnus-convert-face-to-png (face)
   "Convert FACE (which is base64-encoded) to a PNG.
 The PNG is returned as a string."
-  (let ((face (gnus-base64-repad face nil nil t)))
-    (mm-with-unibyte-buffer
-      (insert face)
-      (ignore-errors
-       (base64-decode-region (point-min) (point-max)))
-      (buffer-string))))
+  (mm-with-unibyte-buffer
+    (insert face)
+    (ignore-errors
+      (base64-decode-region (point-min) (point-max)))
+    (buffer-string)))
 
 ;;;###autoload
 (defun gnus-convert-png-to-face (file)
diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el
index a59d0e5..fc9f868 100644
--- a/lisp/gnus/gnus-search.el
+++ b/lisp/gnus/gnus-search.el
@@ -1358,9 +1358,12 @@ Returns a list of [group article score] vectors."
                         "\\|")))
        artlist vectors article group)
     (goto-char (point-min))
-    (while (not (eobp))
+    (while (not (or (eobp)
+                    (looking-at-p
+                     "\\(?:[[:space:]\n]+\\)?Process .+ finished")))
       (pcase-let ((`(,f-name ,score) (gnus-search-indexed-extract engine)))
-       (when (and (file-readable-p f-name)
+       (when (and f-name
+                   (file-readable-p f-name)
                   (null (file-directory-p f-name))
                   (or (null groups)
                       (and (gnus-search-single-p query)
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index e558f63..be02845 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -1291,61 +1291,6 @@ forbidden in URL encoding."
     (setq tmp (concat tmp str))
     tmp))
 
-(defun gnus-base64-repad (str &optional reject-newlines line-length no-check)
-  "Take a base 64-encoded string and return it padded correctly.
-Existing padding is ignored.
-
-If any combination of CR and LF characters are present and
-REJECT-NEWLINES is nil, remove them; otherwise raise an error.
-If LINE-LENGTH is set and the string (or any line in the string
-if REJECT-NEWLINES is nil) is longer than that number, raise an
-error.  Common line length for input characters are 76 plus CRLF
-\(RFC 2045 MIME), 64 plus CRLF (RFC 1421 PEM), and 1000 including
-CRLF (RFC 5321 SMTP).
-
-If NOCHECK, don't check anything, but just repad."
-  ;; RFC 4648 specifies that:
-  ;; - three 8-bit inputs make up a 24-bit group
-  ;; - the 24-bit group is broken up into four 6-bit values
-  ;; - each 6-bit value is mapped to one character of the base 64 alphabet
-  ;; - if the final 24-bit quantum is filled with only 8 bits the output
-  ;;   will be two base 64 characters followed by two "=" padding characters
-  ;; - if the final 24-bit quantum is filled with only 16 bits the output
-  ;;   will be three base 64 character followed by one "=" padding character
-  ;;
-  ;; RFC 4648 section 3 considerations:
-  ;; - if reject-newlines is nil (default), concatenate multi-line
-  ;;   input (3.1, 3.3)
-  ;; - if line-length is set, error on input exceeding the limit (3.1)
-  ;; - reject characters outside base encoding (3.3, also section 12)
-  ;;
-  ;; RFC 5322 section 2.2.3 consideration:
-  ;; Because base 64-encoded strings can appear in long header fields, remove
-  ;; folding whitespace while still observing the RFC 4648 decisions above.
-  (when no-check
-    (setq str (replace-regexp-in-string "[\n\r \t]+" "" str)));
-  (let ((splitstr (split-string str "[ \t]*[\r\n]+[ \t]?" t)))
-    (when (and reject-newlines (> (length splitstr) 1))
-      (error "Invalid Base64 string"))
-    (dolist (substr splitstr)
-      (when (and line-length (> (length substr) line-length))
-       (error "Base64 string exceeds line-length"))
-      (when (string-match "[^A-Za-z0-9+/=]" substr)
-       (error "Invalid Base64 string")))
-    (let* ((str (string-join splitstr))
-          (len (length str)))
-      (when (string-match "=" str)
-       (setq len (match-beginning 0)))
-      (concat
-       (substring str 0 len)
-       (make-string (/
-                    (- 24
-                       (pcase (mod (* len 6) 24)
-                         (`0 24)
-                         (n n)))
-                    6)
-                   ?=)))))
-
 (defun gnus-make-predicate (spec)
   "Transform SPEC into a function that can be called.
 SPEC is a predicate specifier that contains stuff like `or', `and',
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 570be49..f869f58 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -1076,7 +1076,9 @@ during splitting, which may be slow."
                   "UID COPY %s %S")
                 (nnimap-article-ranges (gnus-compress-sequence articles))
                 (nnimap-group-to-imap (gnus-group-real-name 
nnmail-expiry-target)))
-               (set (if can-move 'deleted-articles 'articles-to-delete) 
articles))))
+               (if can-move
+                   (setq deleted-articles articles)
+                 (setq articles-to-delete articles)))))
       t)
      (t
       (dolist (article articles)
diff --git a/lisp/help.el b/lisp/help.el
index babaf4a..1bb1b30 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -561,6 +561,12 @@ To record all your input, use `open-dribble-file'."
               'font-lock-face 'help-key-binding
               'face 'help-key-binding))
 
+(defcustom describe-bindings-outline nil
+  "Non-nil enables outlines in the output buffer of `describe-bindings'."
+  :type 'boolean
+  :group 'help
+  :version "28.1")
+
 (defun describe-bindings (&optional prefix buffer)
   "Display a buffer showing a list of all defined keys, and their definitions.
 The keys are displayed in order of precedence.
@@ -578,23 +584,26 @@ or a buffer name."
     ;; Be aware that `describe-buffer-bindings' puts its output into
     ;; the current buffer.
     (with-current-buffer (help-buffer)
-      (describe-buffer-bindings buffer prefix))))
-
-(defun describe-bindings-internal (&optional menus prefix)
-  "Show a list of all defined keys, and their definitions.
-We put that list in a buffer, and display the buffer.
-
-The optional argument MENUS, if non-nil, says to mention menu bindings.
-\(Ordinarily these are omitted from the output.)
-The optional argument PREFIX, if non-nil, should be a key sequence;
-then we display only bindings that start with that prefix."
-  (declare (obsolete describe-buffer-bindings "24.4"))
-  (let ((buf (current-buffer)))
-    (with-help-window (help-buffer)
-      ;; Be aware that `describe-buffer-bindings' puts its output into
-      ;; the current buffer.
-      (with-current-buffer (help-buffer)
-       (describe-buffer-bindings buf prefix menus)))))
+      (describe-buffer-bindings buffer prefix)
+
+      (when describe-bindings-outline
+        (setq-local outline-regexp ".*:$")
+        (setq-local outline-heading-end-regexp ":\n")
+        (setq-local outline-level (lambda () 1))
+        (setq-local outline-minor-mode-cycle t
+                    outline-minor-mode-highlight t)
+        (outline-minor-mode 1)
+        (save-excursion
+          (let ((inhibit-read-only t))
+            (goto-char (point-min))
+            (insert (substitute-command-keys
+                     (concat "\\<outline-mode-cycle-map>Type "
+                             "\\[outline-cycle] or \\[outline-cycle-buffer] "
+                             "on headings to cycle their visibility.\n\n")))
+            ;; Hide the longest body
+            (when (and (re-search-forward "Key translations" nil t)
+                       (fboundp 'outline-cycle))
+              (outline-cycle))))))))
 
 (defun where-is (definition &optional insert)
   "Print message listing key sequences that invoke the command DEFINITION.
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index 2ffc2f2..05dafe3 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -3104,35 +3104,12 @@ on encoding."
               (list name (concat (if char (list char) " ") "\t") "")))
           names))
 
-(defun mule--ucs-names-group (names)
-  (let* ((codes-and-names
-          (mapcar (lambda (name) (cons (gethash name ucs-names) name)) names))
-         (grouped
-          (seq-group-by
-           (lambda (code-name)
-             (let ((script (aref char-script-table (car code-name))))
-               (if script (symbol-name script) "ungrouped")))
-           codes-and-names))
-         names-with-header header)
-    (dolist (group (sort grouped (lambda (a b) (string< (car a) (car b)))))
-      (setq header t)
-      (dolist (code-name (cdr group))
-        (push (list
-               (cdr code-name)
-               (concat
-                (if header
-                    (progn
-                      (setq header nil)
-                      (concat "\n" (propertize
-                                    (format "* %s\n" (car group))
-                                    'face 'header-line)))
-                  "")
-                ;; prefix
-                (if (car code-name) (format "%c" (car code-name)) " ") "\t")
-               ;; suffix
-               "")
-              names-with-header)))
-    (nreverse names-with-header)))
+(defun mule--ucs-names-group (name transform)
+  (if transform
+      name
+    (let* ((char (gethash name ucs-names))
+           (script (and char (aref char-script-table char))))
+      (if script (symbol-name script) "ungrouped"))))
 
 (defun char-from-name (string &optional ignore-case)
   "Return a character as a number from its Unicode name STRING.
@@ -3164,14 +3141,6 @@ Defines the sorting order either by character names or 
their codepoints."
   :group 'mule
   :version "28.1")
 
-(defcustom read-char-by-name-group nil
-  "How to group characters for `read-char-by-name' completion.
-When t, split characters to sections of Unicode blocks
-sorted alphabetically."
-  :type 'boolean
-  :group 'mule
-  :version "28.1")
-
 (defun read-char-by-name (prompt)
   "Read a character by its Unicode name or hex number string.
 Display PROMPT and read a string that represents a character by its
@@ -3185,8 +3154,9 @@ preceded by an asterisk `*' and use completion, it will 
show all
 the characters whose names include that substring, not necessarily
 at the beginning of the name.
 
-The options `read-char-by-name-sort' and `read-char-by-name-group'
-define the sorting order of completion characters and how to group them.
+The options `read-char-by-name-sort', `completions-group', and
+`completions-group-sort' define the sorting order of completion characters,
+whether to group them, and how to sort groups.
 
 Accept a name like \"CIRCULATION FUNCTION\", a hexadecimal
 number like \"2A10\", or a number in hash notation (e.g.,
@@ -3204,11 +3174,12 @@ as names, not numbers."
                 `(metadata
                   (display-sort-function
                    . ,(when (eq read-char-by-name-sort 'code)
-                         #'mule--ucs-names-sort-by-code))
+                        #'mule--ucs-names-sort-by-code))
                   (affixation-function
-                   . ,(if read-char-by-name-group
-                           #'mule--ucs-names-group
-                         #'mule--ucs-names-affixation))
+                   . ,#'mule--ucs-names-affixation)
+                  (group-function
+                   . ,(when completions-group
+                        #'mule--ucs-names-group))
                   (category . unicode-name))
               (complete-with-action action (ucs-names) string pred)))))
         (char
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index fff06de..5d13115 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -1368,6 +1368,30 @@ If STR has `advice' text property, append the following 
special event:
       (delete-region (overlay-start quail-overlay)
                     (overlay-end quail-overlay))))
 
+;; Quail puts keys back in `unread-command-events' to be re-read
+;; again, but these keys have already been recorded in recent-keys and
+;; in the keyboard macro, if one is being defined, which means that
+;; recording them again creates duplicates.  This function is a
+;; wrapper around adding input events to `unread-command-events', but
+;; it makes sure these events will not be recorded a second time.
+(defun quail-add-unread-command-events (key &optional reset)
+  "Add KEY to `unread-command-events', but avoid recording it a second time.
+If KEY is a character, it is prepended to `unread-command-events' as
+a cons cell of the form (no-record . KEY).
+If KEY is a vector of events, the events in the vector are prepended
+to `unread-command-events', after converting each event to a cons cell
+of the form (no-record . EVENT).
+If RESET is non-nil, the events in `unread-command-events' are first
+discarded, i.e. in this case KEY will end up being the only key
+in `unread-command-events'."
+  (if reset (setq unread-command-events nil))
+  (setq unread-command-events
+        (if (characterp key)
+            (cons (cons 'no-record key) unread-command-events)
+          (append (mapcan (lambda (e) (list (cons 'no-record e)))
+                          (append key nil))
+                  unread-command-events))))
+
 (defun quail-start-translation (key)
   "Start translation of the typed character KEY by the current Quail package.
 Return the input string."
@@ -1385,13 +1409,11 @@ Return the input string."
             ;; (generated-events nil)     ;FIXME: What is this?
             (input-method-function nil)
             (modified-p (buffer-modified-p))
-            last-command-event last-command this-command inhibit-record)
+            last-command-event last-command this-command)
        (setq quail-current-key ""
              quail-current-str ""
              quail-translating t)
-       (if key
-           (setq unread-command-events (cons key unread-command-events)
-                  inhibit-record t))
+       (if key (quail-add-unread-command-events key))
        (while quail-translating
          (set-buffer-modified-p modified-p)
          (quail-show-guidance)
@@ -1400,13 +1422,8 @@ Return the input string."
                                     (or input-method-previous-message "")
                                     quail-current-str
                                     quail-guidance-str)))
-                 ;; We inhibit record_char only for the first key,
-                 ;; because it was already recorded before read_char
-                 ;; called quail-input-method.
-                 (inhibit--record-char inhibit-record)
                 (keyseq (read-key-sequence prompt nil nil t))
                 (cmd (lookup-key (quail-translation-keymap) keyseq)))
-            (setq inhibit-record nil)
            (if (if key
                    (and (commandp cmd) (not (eq cmd 'quail-other-command)))
                  (eq cmd 'quail-self-insert-command))
@@ -1420,9 +1437,7 @@ Return the input string."
                    (quail-error (message "%s" (cdr err)) (beep))))
              ;; KEYSEQ is not defined in the translation keymap.
              ;; Let's return the event(s) to the caller.
-             (setq unread-command-events
-                   (append (this-single-command-raw-keys)
-                            unread-command-events))
+             (quail-add-unread-command-events (this-single-command-raw-keys))
              (setq quail-translating nil))))
        (quail-delete-region)
        quail-current-str)
@@ -1450,15 +1465,13 @@ Return the input string."
             ;; (generated-events nil)     ;FIXME: What is this?
             (input-method-function nil)
             (modified-p (buffer-modified-p))
-            last-command-event last-command this-command inhibit-record)
+            last-command-event last-command this-command)
        (setq quail-current-key ""
              quail-current-str ""
              quail-translating t
              quail-converting t
              quail-conversion-str "")
-       (if key
-           (setq unread-command-events (cons key unread-command-events)
-                  inhibit-record t))
+       (if key (quail-add-unread-command-events key))
        (while quail-converting
          (set-buffer-modified-p modified-p)
          (or quail-translating
@@ -1474,13 +1487,8 @@ Return the input string."
                                     quail-conversion-str
                                     quail-current-str
                                     quail-guidance-str)))
-                 ;; We inhibit record_char only for the first key,
-                 ;; because it was already recorded before read_char
-                 ;; called quail-input-method.
-                 (inhibit--record-char inhibit-record)
                 (keyseq (read-key-sequence prompt nil nil t))
                 (cmd (lookup-key (quail-conversion-keymap) keyseq)))
-            (setq inhibit-record nil)
            (if (if key (commandp cmd) (eq cmd 'quail-self-insert-command))
                (progn
                  (setq last-command-event (aref keyseq (1- (length keyseq)))
@@ -1503,9 +1511,7 @@ Return the input string."
                            (setq quail-converting nil)))))
              ;; KEYSEQ is not defined in the conversion keymap.
              ;; Let's return the event(s) to the caller.
-             (setq unread-command-events
-                   (append (this-single-command-raw-keys)
-                            unread-command-events))
+             (quail-add-unread-command-events (this-single-command-raw-keys))
              (setq quail-converting nil))))
        (setq quail-translating nil)
        (if (overlay-start quail-conv-overlay)
@@ -1551,9 +1557,8 @@ with more keys."
               (or input-method-exit-on-first-char
                   (while (> len control-flag)
                     (setq len (1- len))
-                    (setq unread-command-events
-                          (cons (aref quail-current-key len)
-                                unread-command-events))))))
+                    (quail-add-unread-command-events
+                     (aref quail-current-key len))))))
            ((null control-flag)
             (unless quail-current-str
               (setq quail-current-str
@@ -1799,8 +1804,7 @@ sequence counting from the head."
          (setcar indices (1+ (car indices)))
          (quail-update-current-translations)
          (quail-update-translation nil)))
-    (setq unread-command-events
-         (cons last-command-event unread-command-events))
+    (quail-add-unread-command-events last-command-event)
     (quail-terminate-translation)))
 
 (defun quail-prev-translation ()
@@ -1814,8 +1818,7 @@ sequence counting from the head."
          (setcar indices (1- (car indices)))
          (quail-update-current-translations)
          (quail-update-translation nil)))
-    (setq unread-command-events
-         (cons last-command-event unread-command-events))
+    (quail-add-unread-command-events last-command-event)
     (quail-terminate-translation)))
 
 (defun quail-next-translation-block ()
@@ -1830,8 +1833,7 @@ sequence counting from the head."
          (setcar indices (+ (nth 2 indices) offset))
          (quail-update-current-translations)
          (quail-update-translation nil)))
-    (setq unread-command-events
-         (cons last-command-event unread-command-events))
+    (quail-add-unread-command-events last-command-event)
     (quail-terminate-translation)))
 
 (defun quail-prev-translation-block ()
@@ -1850,8 +1852,7 @@ sequence counting from the head."
                (setcar indices (+ (nth 1 indices) offset))
                (quail-update-current-translations)))
          (quail-update-translation nil)))
-    (setq unread-command-events
-         (cons last-command-event unread-command-events))
+    (quail-add-unread-command-events last-command-event)
     (quail-terminate-translation)))
 
 (defun quail-abort-translation ()
@@ -2006,8 +2007,8 @@ Remaining args are for FUNC."
     (sit-for 1000000)
     (delete-region point-max (point-max))
     (when quit-flag
-      (setq quit-flag nil
-           unread-command-events '(7)))))
+      (setq quit-flag nil)
+      (quail-add-unread-command-events 7 t))))
 
 (defun quail-show-guidance ()
   "Display a guidance for Quail input method in some window.
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 00969e5..232a994 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -3462,6 +3462,10 @@ Can be changed via `isearch-search-fun-function' for 
special needs."
        (if isearch-forward #'re-search-forward #'re-search-backward)
        regexp bound noerror count))))
 
+;; This is for when we compile this file during bootstrap, with
+;; loaddefs.el still not loaded.
+(declare-function multi-isearch-switch-buffer "misearch" ())
+
 (defun isearch-search-string (string bound noerror)
   "Search for the first occurrence of STRING or its translation.
 STRING's characters are translated using `translation-table-for-input'
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 3700a19..afc486f 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -782,17 +782,23 @@ If kbd macro currently being defined end it before 
activating it."
 ;; executing the macro later on (but that's controversial...)
 
 ;;;###autoload
-(defun kmacro-lambda-form (mac)
+(defun kmacro-lambda-form (mac &optional counter format)
   "Create lambda form for macro bound to symbol or key."
-  ;; FIXME: This should be a "funcallable struct"!
-  (lambda (&optional arg)
-    "Keyboard macro."
-    ;; We put an "unused prompt" as a special marker so
-    ;; `kmacro-extract-lambda' can see it's "one of us".
-    (interactive "pkmacro")
-    (if (eq arg 'kmacro--extract-lambda)
-        (cons 'kmacro--extract-lambda mac)
-      (kmacro-exec-ring-item mac arg))))
+  ;; Apparently, there are two different ways this is called:
+  ;; either `counter' and `format' are both provided and `mac' is a vector,
+  ;; or only `mac' is provided, as a list (MAC COUNTER FORMAT).
+  ;; The first is used from `insert-kbd-macro' and `edmacro-finish-edit',
+  ;; while the second is used from within this file.
+  (let ((mac (if counter (list mac counter format) mac)))
+    ;; FIXME: This should be a "funcallable struct"!
+    (lambda (&optional arg)
+      "Keyboard macro."
+      ;; We put an "unused prompt" as a special marker so
+      ;; `kmacro-extract-lambda' can see it's "one of us".
+      (interactive "pkmacro")
+      (if (eq arg 'kmacro--extract-lambda)
+          (cons 'kmacro--extract-lambda mac)
+        (kmacro-exec-ring-item mac arg)))))
 
 (defun kmacro-extract-lambda (mac)
   "Extract kmacro from a kmacro lambda form."
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index 7ef3754..e479a8e 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -3360,7 +3360,7 @@ tags such as [tag]."
     ;; Corporate mailing systems sometimes add `[External] :'; if that 
happened,
     ;; delete everything up thru there.  Empirically, that deletion makes
     ;; the Subject match the other messages in the thread.
-    (if (string-match "[[]external][ \t\n]*:" subject)
+    (if (string-match "\\[external][ \t\n]*:" subject)
         (setq subject (substring subject (match-end 0))))
     (setq subject (rfc2047-decode-string subject))
     (setq subject (replace-regexp-in-string regexp "" subject))
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index d6a6f9a..ec21b7b 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -126,6 +126,13 @@ This metadata is an alist.  Currently understood keys are:
    three-element lists: completion, its prefix and suffix.  This
    function takes priority over `annotation-function' when both are
    provided, so only this function is used.
+- `group-function': function for grouping the completion candidates.
+   Takes two arguments: a completion candidate (COMPLETION) and a
+   boolean flag (TRANSFORM).  If TRANSFORM is nil, the function
+   returns the group title of the group to which the candidate
+   belongs.  The returned title may be nil.  Otherwise the function
+   returns the transformed candidate.  The transformation can remove a
+   redundant prefix, which is displayed in the group title.
 - `display-sort-function': function to sort entries in *Completions*.
    Takes one argument (COMPLETIONS) and should return a new list
    of completions.  Can operate destructively.
@@ -1138,6 +1145,44 @@ completion candidates than this number."
   :version "24.1"
   :type completion--cycling-threshold-type)
 
+(defcustom completions-group nil
+  "Enable grouping of completion candidates in the *Completions* buffer.
+See also `completions-group-format' and `completions-group-sort'."
+  :type 'boolean
+  :version "28.1")
+
+(defcustom completions-group-sort nil
+  "Sort groups in the *Completions* buffer.
+
+The value can either be nil to disable sorting, `alphabetical' for
+alphabetical sorting or a custom sorting function.  The sorting
+function takes and returns an alist of groups, where each element is a
+pair of a group title string and a list of group candidate strings."
+  :type '(choice (const :tag "No sorting" nil)
+                 (const :tag "Alphabetical sorting" alphabetical)
+                 function)
+  :version "28.1")
+
+(defcustom completions-group-format
+  (concat
+   (propertize "    " 'face 'completions-group-separator)
+   (propertize " %s " 'face 'completions-group-title)
+   (propertize " " 'face 'completions-group-separator
+               'display '(space :align-to right)))
+  "Format string used for the group title."
+  :type 'string
+  :version "28.1")
+
+(defface completions-group-title
+  '((t :inherit shadow :slant italic))
+  "Face used for the title text of the candidate group headlines."
+  :version "28.1")
+
+(defface completions-group-separator
+  '((t :inherit shadow :strike-through t))
+  "Face used for the separator lines between the candidate groups."
+  :version "28.1")
+
 (defun completion--cycle-threshold (metadata)
   (let* ((cat (completion-metadata-get metadata 'category))
          (over (completion--category-override cat 'cycle)))
@@ -1401,6 +1446,22 @@ Remove completion BASE prefix string from history 
elements."
                      (substring c base-size)))
                  hist)))))
 
+(defun minibuffer--group-by (group-fun sort-fun elems)
+  "Group ELEMS by GROUP-FUN and sort groups by SORT-FUN."
+  (let ((groups))
+    (dolist (cand elems)
+      (let* ((key (funcall group-fun cand nil))
+             (group (assoc key groups)))
+        (if group
+            (setcdr group (cons cand (cdr group)))
+          (push (list key cand) groups))))
+    (setq groups (nreverse groups)
+          groups (mapc (lambda (x)
+                         (setcdr x (nreverse (cdr x))))
+                       groups)
+          groups (funcall sort-fun groups))
+    (mapcan #'cdr groups)))
+
 (defun completion-all-sorted-completions (&optional start end)
   (or completion-all-sorted-completions
       (let* ((start (or start (minibuffer-prompt-end)))
@@ -1747,15 +1808,17 @@ or appended to completions."
   :type 'boolean
   :version "28.1")
 
-(defun completion--insert-strings (strings)
+(defun completion--insert-strings (strings &optional group-fun)
   "Insert a list of STRINGS into the current buffer.
-Uses columns to keep the listing readable but compact.
-It also eliminates runs of equal strings."
+The candidate strings are inserted into the buffer depending on the
+completions format as specified by the variable `completions-format'.
+Runs of equal candidate strings are eliminated.  GROUP-FUN is a
+`group-function' used for grouping the completion candidates."
   (when (consp strings)
     (let* ((length (apply #'max
                          (mapcar (lambda (s)
                                    (if (consp s)
-                                       (apply #'+ (mapcar #'string-width s))
+                                       (apply #'+ (mapcar #'string-width s))
                                      (string-width s)))
                                  strings)))
           (window (get-buffer-window (current-buffer) 0))
@@ -1766,104 +1829,158 @@ It also eliminates runs of equal strings."
                     ;; Don't allocate more columns than we can fill.
                     ;; Windows can't show less than 3 lines anyway.
                     (max 1 (/ (length strings) 2))))
-          (colwidth (/ wwidth columns))
-           (column 0)
-          (rows (/ (length strings) columns))
-          (row 0)
-           (first t)
-          (laststring nil))
+          (colwidth (/ wwidth columns)))
       (unless (or tab-stop-list (null completion-tab-width)
                   (zerop (mod colwidth completion-tab-width)))
         ;; Align to tab positions for the case
         ;; when the caller uses tabs inside prefix.
         (setq colwidth (- colwidth (mod colwidth completion-tab-width))))
-      ;; The insertion should be "sensible" no matter what choices were made
-      ;; for the parameters above.
-      (dolist (str strings)
-       (unless (equal laststring str) ; Remove (consecutive) duplicates.
-         (setq laststring str)
+      (funcall (intern (format "completion--insert-%s" completions-format))
+               strings group-fun length wwidth colwidth columns))))
+
+(defun completion--insert-horizontal (strings group-fun
+                                              length wwidth
+                                              colwidth _columns)
+  (let ((column 0)
+        (first t)
+       (last-title nil)
+        (last-string nil))
+    (dolist (str strings)
+      (unless (equal last-string str) ; Remove (consecutive) duplicates.
+       (setq last-string str)
+        (when group-fun
+          (let ((title (funcall group-fun (if (consp str) (car str) str) nil)))
+            (unless (equal title last-title)
+              (setq last-title title)
+              (when title
+                (insert (if first "" "\n") (format completions-group-format 
title) "\n")
+                (setq column 0
+                      first t)))))
+       (unless first
           ;; FIXME: `string-width' doesn't pay attention to
           ;; `display' properties.
-          (let ((length (if (consp str)
-                            (apply #'+ (mapcar #'string-width str))
-                          (string-width str))))
-            (cond
-             ((eq completions-format 'one-column)
-              ;; Nothing special
-              )
-            ((eq completions-format 'vertical)
-             ;; Vertical format
-             (when (> row rows)
-               (forward-line (- -1 rows))
-               (setq row 0 column (+ column colwidth)))
-             (when (> column 0)
-               (end-of-line)
-               (while (> (current-column) column)
-                 (if (eobp)
-                     (insert "\n")
-                   (forward-line 1)
-                   (end-of-line)))
-               (insert " \t")
-               (set-text-properties (1- (point)) (point)
-                                    `(display (space :align-to ,column)))))
-            (t
-             ;; Horizontal format
-             (unless first
-               (if (< wwidth (+ (max colwidth length) column))
-                   ;; No space for `str' at point, move to next line.
-                   (progn (insert "\n") (setq column 0))
-                 (insert " \t")
-                 ;; Leave the space unpropertized so that in the case we're
-                 ;; already past the goal column, there is still
-                 ;; a space displayed.
-                 (set-text-properties (1- (point)) (point)
-                                      ;; We can set tab-width using
-                                      ;; completion-tab-width, but
-                                      ;; the caller can prefer using
-                                      ;; \t to align prefixes.
-                                      `(display (space :align-to ,column)))
-                 nil))))
-            (setq first nil)
-            (if (not (consp str))
-                (put-text-property (point) (progn (insert str) (point))
-                                   'mouse-face 'highlight)
-              ;; If `str' is a list that has 2 elements,
-              ;; then the second element is a suffix annotation.
-              ;; If `str' has 3 elements, then the second element
-              ;; is a prefix, and the third element is a suffix.
-              (let* ((prefix (when (nth 2 str) (nth 1 str)))
-                     (suffix (or (nth 2 str) (nth 1 str))))
-                (when prefix
-                  (let ((beg (point))
-                        (end (progn (insert prefix) (point))))
-                    (put-text-property beg end 'mouse-face nil)))
-                (put-text-property (point) (progn (insert (car str)) (point))
-                                   'mouse-face 'highlight)
-                (let ((beg (point))
-                      (end (progn (insert suffix) (point))))
-                  (put-text-property beg end 'mouse-face nil)
-                  ;; Put the predefined face only when suffix
-                  ;; is added via annotation-function without prefix,
-                  ;; and when the caller doesn't use own face.
-                  (unless (or prefix (text-property-not-all
-                                      0 (length suffix) 'face nil suffix))
-                    (font-lock-prepend-text-property
-                     beg end 'face 'completions-annotations)))))
-           (cond
-             ((eq completions-format 'one-column)
-              (insert "\n"))
-            ((eq completions-format 'vertical)
-             ;; Vertical format
-             (if (> column 0)
-                 (forward-line)
-               (insert "\n"))
-             (setq row (1+ row)))
-            (t
-             ;; Horizontal format
-             ;; Next column to align to.
-             (setq column (+ column
-                             ;; Round up to a whole number of columns.
-                             (* colwidth (ceiling length colwidth))))))))))))
+         (if (< wwidth (+ column (max colwidth
+                                       (if (consp str)
+                                           (apply #'+ (mapcar #'string-width 
str))
+                                         (string-width str)))))
+             ;; No space for `str' at point, move to next line.
+             (progn (insert "\n") (setq column 0))
+           (insert " \t")
+           ;; Leave the space unpropertized so that in the case we're
+           ;; already past the goal column, there is still
+           ;; a space displayed.
+           (set-text-properties (1- (point)) (point)
+                                ;; We can set tab-width using
+                                ;; completion-tab-width, but
+                                ;; the caller can prefer using
+                                ;; \t to align prefixes.
+                                `(display (space :align-to ,column)))
+           nil))
+        (setq first nil)
+        (completion--insert str group-fun)
+       ;; Next column to align to.
+       (setq column (+ column
+                       ;; Round up to a whole number of columns.
+                       (* colwidth (ceiling length colwidth))))))))
+
+(defun completion--insert-vertical (strings group-fun
+                                            _length _wwidth
+                                            colwidth columns)
+  (while strings
+    (let ((group nil)
+          (column 0)
+         (row 0)
+          (rows)
+          (last-string nil))
+      (if group-fun
+          (let* ((str (car strings))
+                 (title (funcall group-fun (if (consp str) (car str) str) 
nil)))
+            (while (and strings
+                        (equal title (funcall group-fun
+                                              (if (consp (car strings))
+                                                  (car (car strings))
+                                                (car strings))
+                                              nil)))
+              (push (car strings) group)
+              (pop strings))
+            (setq group (nreverse group)))
+        (setq group strings
+              strings nil))
+      (setq rows (/ (length group) columns))
+      (when group-fun
+        (let* ((str (car group))
+               (title (funcall group-fun (if (consp str) (car str) str) nil)))
+          (when title
+            (goto-char (point-max))
+            (insert (format completions-group-format title) "\n"))))
+      (dolist (str group)
+        (unless (equal last-string str) ; Remove (consecutive) duplicates.
+         (setq last-string str)
+         (when (> row rows)
+            (forward-line (- -1 rows))
+           (setq row 0 column (+ column colwidth)))
+         (when (> column 0)
+           (end-of-line)
+           (while (> (current-column) column)
+             (if (eobp)
+                 (insert "\n")
+               (forward-line 1)
+               (end-of-line)))
+           (insert " \t")
+           (set-text-properties (1- (point)) (point)
+                                `(display (space :align-to ,column))))
+          (completion--insert str group-fun)
+         (if (> column 0)
+             (forward-line)
+           (insert "\n"))
+         (setq row (1+ row)))))))
+
+(defun completion--insert-one-column (strings group-fun &rest _)
+  (let ((last-title nil) (last-string nil))
+    (dolist (str strings)
+      (unless (equal last-string str) ; Remove (consecutive) duplicates.
+       (setq last-string str)
+        (when group-fun
+          (let ((title (funcall group-fun (if (consp str) (car str) str) nil)))
+            (unless (equal title last-title)
+              (setq last-title title)
+              (when title
+                (insert (format completions-group-format title) "\n")))))
+        (completion--insert str group-fun)
+        (insert "\n")))))
+
+(defun completion--insert (str group-fun)
+  (if (not (consp str))
+      (add-text-properties
+       (point)
+       (progn
+         (insert
+          (if group-fun
+              (funcall group-fun str 'transform)
+            str))
+         (point))
+       `(mouse-face highlight completion--string ,str))
+    ;; If `str' is a list that has 2 elements,
+    ;; then the second element is a suffix annotation.
+    ;; If `str' has 3 elements, then the second element
+    ;; is a prefix, and the third element is a suffix.
+    (let* ((prefix (when (nth 2 str) (nth 1 str)))
+           (suffix (or (nth 2 str) (nth 1 str))))
+      (when prefix
+        (let ((beg (point))
+              (end (progn (insert prefix) (point))))
+          (put-text-property beg end 'mouse-face nil)))
+      (completion--insert (car str) group-fun)
+      (let ((beg (point))
+            (end (progn (insert suffix) (point))))
+        (put-text-property beg end 'mouse-face nil)
+        ;; Put the predefined face only when suffix
+        ;; is added via annotation-function without prefix,
+        ;; and when the caller doesn't use own face.
+        (unless (or prefix (text-property-not-all
+                            0 (length suffix) 'face nil suffix))
+          (font-lock-prepend-text-property
+           beg end 'face 'completions-annotations))))))
 
 (defvar completion-setup-hook nil
   "Normal hook run at the end of setting up a completion list buffer.
@@ -1923,7 +2040,7 @@ and with BASE-SIZE appended as the last element."
         completions)
        base-size))))
 
-(defun display-completion-list (completions &optional common-substring)
+(defun display-completion-list (completions &optional common-substring 
group-fun)
   "Display the list of completions, COMPLETIONS, using `standard-output'.
 Each element may be just a symbol or string
 or may be a list of two strings to be printed as if concatenated.
@@ -1933,7 +2050,9 @@ alternative, the second serves as annotation.
 The actual completion alternatives, as inserted, are given `mouse-face'
 properties of `highlight'.
 At the end, this runs the normal hook `completion-setup-hook'.
-It can find the completion buffer in `standard-output'."
+It can find the completion buffer in `standard-output'.
+GROUP-FUN is a `group-function' used for grouping the completion
+candidates."
   (declare (advertised-calling-convention (completions) "24.4"))
   (if common-substring
       (setq completions (completion-hilit-commonality
@@ -1946,7 +2065,7 @@ It can find the completion buffer in `standard-output'."
        (let ((standard-output (current-buffer))
              (completion-setup-hook nil))
           (with-suppressed-warnings ((callargs display-completion-list))
-           (display-completion-list completions common-substring)))
+           (display-completion-list completions common-substring group-fun)))
        (princ (buffer-string)))
 
     (with-current-buffer standard-output
@@ -1954,7 +2073,7 @@ It can find the completion buffer in `standard-output'."
       (if (null completions)
           (insert "There are no possible completions of what you have typed.")
         (insert "Possible completions are:\n")
-        (completion--insert-strings completions))))
+        (completion--insert-strings completions group-fun))))
 
   (run-hooks 'completion-setup-hook)
   nil)
@@ -2067,6 +2186,8 @@ variables.")
              (aff-fun (or (completion-metadata-get all-md 'affixation-function)
                           (plist-get completion-extra-properties
                                      :affixation-function)))
+             (sort-fun (completion-metadata-get all-md 'display-sort-function))
+             (group-fun (completion-metadata-get all-md 'group-function))
              (mainbuf (current-buffer))
              ;; If the *Completions* buffer is shown in a new
              ;; window, mark it as softly-dedicated, so bury-buffer in
@@ -2098,15 +2219,32 @@ variables.")
                       ;; Remove the base-size tail because `sort' requires a 
properly
                       ;; nil-terminated list.
                       (when last (setcdr last nil))
-                      (setq completions
-                            ;; FIXME: This function is for the output of 
all-completions,
-                            ;; not completion-all-completions.  Often it's the 
same, but
-                            ;; not always.
-                            (let ((sort-fun (completion-metadata-get
-                                             all-md 'display-sort-function)))
-                              (if sort-fun
-                                  (funcall sort-fun completions)
-                                (sort completions 'string-lessp))))
+
+                      ;; Sort first using the `display-sort-function'.
+                      ;; FIXME: This function is for the output of
+                      ;; all-completions, not
+                      ;; completion-all-completions.  Often it's the
+                      ;; same, but not always.
+                      (setq completions (if sort-fun
+                                            (funcall sort-fun completions)
+                                          (sort completions 'string-lessp)))
+
+                      ;; After sorting, group the candidates using the
+                      ;; `group-function'.
+                      (when group-fun
+                        (setq completions
+                              (minibuffer--group-by
+                               group-fun
+                               (pcase completions-group-sort
+                                 ('nil #'identity)
+                                 ('alphabetical
+                                  (lambda (groups)
+                                    (sort groups
+                                          (lambda (x y)
+                                            (string< (car x) (car y))))))
+                                 (_ completions-group-sort))
+                               completions)))
+
                       (cond
                        (aff-fun
                         (setq completions
@@ -2152,7 +2290,7 @@ variables.")
                                                      (if (eq (car bounds) 
(length result))
                                                          'exact 
'finished)))))))
 
-                      (display-completion-list completions)))))
+                      (display-completion-list completions nil group-fun)))))
           nil)))
     nil))
 
@@ -2465,6 +2603,7 @@ The completion method is determined by 
`completion-at-point-functions'."
     (define-key map "?" 'minibuffer-completion-help)
     (define-key map [prior] 'switch-to-completions)
     (define-key map "\M-v"  'switch-to-completions)
+    (define-key map "\M-g\M-c"  'switch-to-completions)
     map)
   "Local keymap for minibuffer input with completion.")
 
diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el
index 04ea809..3f3a3df 100644
--- a/lisp/net/ange-ftp.el
+++ b/lisp/net/ange-ftp.el
@@ -949,7 +949,11 @@ Some AT&T folks claim to use something called `pftp' here."
   :type 'string)
 
 (defcustom ange-ftp-ftp-program-args '("-i" "-n" "-g" "-v")
-  "A list of arguments passed to the FTP program when started."
+  ;; Clients that use the BSD editline instead of the GNU readline
+  ;; library may need to disable command line editing. (Bug#48494)
+  "A list of arguments passed to the FTP program when started.
+Some FTP clients may also require the \"-e\" argument, which disables
+command line editing."
   :group 'ange-ftp
   :type '(repeat string))
 
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 61c40ff..d2ee729 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -345,8 +345,17 @@ arguments to pass to the OPERATION."
              (tramp-archive-run-real-handler operation args)))))))
 
 ;;;###autoload
-(defalias
-  'tramp-archive-autoload-file-name-handler #'tramp-autoload-file-name-handler)
+(progn (defun tramp-archive-autoload-file-name-handler (operation &rest args)
+  "Load Tramp archive file name handler, and perform OPERATION."
+  (when tramp-archive-enabled
+    ;; We cannot use `tramp-compat-temporary-file-directory' here due
+    ;; to autoload.  When installing Tramp's GNU ELPA package, there
+    ;; might be an older, incompatible version active.  We try to
+    ;; overload this.
+    (let ((default-directory temporary-file-directory)
+          (tramp-archive-autoload t))
+      tramp-archive-autoload ; Silence byte compiler.
+      (apply #'tramp-autoload-file-name-handler operation args)))))
 
 ;;;###autoload
 (progn (defun tramp-register-archive-file-name-handler ()
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index 2fcb7b1..fdde7fb 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -237,8 +237,7 @@ Return VALUE."
 ;;;###tramp-autoload
 (defun tramp-flush-file-properties (key file)
   "Remove all properties of FILE in the cache context of KEY."
-  (let* ((file (tramp-run-real-handler
-               #'directory-file-name (list file)))
+  (let* ((file (tramp-run-real-handler #'directory-file-name (list file)))
         (truename (tramp-get-file-property key file "file-truename" nil)))
     ;; Unify localname.  Remove hop from `tramp-file-name' structure.
     (setq file (tramp-compat-file-name-unquote file)
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index c4ec112..f1d24dc 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -1089,7 +1089,7 @@ file names."
        'copy filename newname ok-if-already-exists keep-date
        preserve-uid-gid preserve-extended-attributes)
     (tramp-run-real-handler
-     'copy-file
+     #'copy-file
      (list filename newname ok-if-already-exists keep-date
           preserve-uid-gid preserve-extended-attributes))))
 
diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el
index 2931b4f..17264193 100644
--- a/lisp/net/tramp-integration.el
+++ b/lisp/net/tramp-integration.el
@@ -42,6 +42,8 @@
 (declare-function tramp-dissect-file-name "tramp")
 (declare-function tramp-file-name-equal-p "tramp")
 (declare-function tramp-tramp-file-p "tramp")
+(declare-function tramp-rename-files "tramp-cmds")
+(declare-function tramp-rename-these-files "tramp-cmds")
 (defvar eshell-path-env)
 (defvar ido-read-file-name-non-ido)
 (defvar info-lookup-alist)
@@ -184,14 +186,14 @@ NAME must be equal to `tramp-current-connection'."
 ;;; Integration of ido.el:
 
 (with-eval-after-load 'ido
-  (add-to-list 'ido-read-file-name-non-ido 'tramp-rename-files)
-  (add-to-list 'ido-read-file-name-non-ido 'tramp-these-rename-files)
+  (add-to-list 'ido-read-file-name-non-ido #'tramp-rename-files)
+  (add-to-list 'ido-read-file-name-non-ido #'tramp-rename-these-files)
   (add-hook 'tramp-integration-unload-hook
            (lambda ()
              (setq ido-read-file-name-non-ido
-                   (delq 'tramp-these-rename-files ido-read-file-name-non-ido)
+                   (delq #'tramp-rename-these-files ido-read-file-name-non-ido)
                    ido-read-file-name-non-ido
-                   (delq 'tramp-rename-files ido-read-file-name-non-ido)))))
+                   (delq #'tramp-rename-files ido-read-file-name-non-ido)))))
 
 ;;; Integration of ivy.el:
 
@@ -199,17 +201,17 @@ NAME must be equal to `tramp-current-connection'."
   (add-to-list 'ivy-completing-read-handlers-alist
               '(tramp-rename-files . completing-read-default))
   (add-to-list 'ivy-completing-read-handlers-alist
-              '(tramp-these-rename-files . completing-read-default))
+              '(tramp-rename-these-files . completing-read-default))
   (add-hook
    'tramp-integration-unload-hook
    (lambda ()
      (setq ivy-completing-read-handlers-alist
           (delete
-           (assq 'tramp-these-rename-files ivy-completing-read-handlers-alist)
+           (assq #'tramp-rename-these-files ivy-completing-read-handlers-alist)
            ivy-completing-read-handlers-alist)
           ivy-completing-read-handlers-alist
           (delete
-           (assq 'tramp-rename-files ivy-completing-read-handlers-alist)
+           (assq #'tramp-rename-files ivy-completing-read-handlers-alist)
            ivy-completing-read-handlers-alist)))))
 
 ;;; Integration of info-look.el:
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index f24d0ef..29ed944 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1843,7 +1843,7 @@ ID-FORMAT valid values are `string' and `integer'."
        'copy filename newname ok-if-already-exists keep-date
        preserve-uid-gid preserve-extended-attributes)
     (tramp-run-real-handler
-     'copy-file
+     #'copy-file
      (list filename newname ok-if-already-exists keep-date
           preserve-uid-gid preserve-extended-attributes))))
 
@@ -1884,7 +1884,7 @@ ID-FORMAT valid values are `string' and `integer'."
 
        ;; We must do it file-wise.
        (tramp-run-real-handler
-        'copy-directory
+        #'copy-directory
         (list dirname newname keep-date parents copy-contents)))
 
       ;; When newname did exist, we have wrong cached values.
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index 66737e6..d641709 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -650,7 +650,7 @@ component is used as the target of the symlink."
        'rename filename newname ok-if-already-exists
        'keep-date 'preserve-uid-gid)
     (tramp-run-real-handler
-     'rename-file (list filename newname ok-if-already-exists))))
+     #'rename-file (list filename newname ok-if-already-exists))))
 
 (defun tramp-sudoedit-handle-set-file-acl (filename acl-string)
   "Like `set-file-acl' for Tramp files."
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 62df289..4fd7a322 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -2631,6 +2631,8 @@ Falls back to normal file name handler if no Tramp file 
name handler exists."
     ;; might be an older, incompatible version active.  We try to
     ;; overload this.
     (let ((default-directory temporary-file-directory))
+      (when (bound-and-true-p tramp-archive-autoload)
+       (load "tramp-archive" 'noerror 'nomessage))
       (load "tramp" 'noerror 'nomessage)))
   (apply operation args)))
 
@@ -2642,7 +2644,7 @@ Falls back to normal file name handler if no Tramp file 
name handler exists."
   "Add Tramp file name handlers to `file-name-handler-alist' during autoload."
   (add-to-list 'file-name-handler-alist
               (cons tramp-autoload-file-name-regexp
-                    'tramp-autoload-file-name-handler))
+                    #'tramp-autoload-file-name-handler))
   (put #'tramp-autoload-file-name-handler 'safe-magic t)))
 
 ;;;###autoload (tramp-register-autoload-file-name-handlers)
@@ -2854,7 +2856,7 @@ not in completion mode."
      result1
      (ignore-errors
        (tramp-run-real-handler
-       'file-name-all-completions (list filename directory))))))
+       #'file-name-all-completions (list filename directory))))))
 
 ;; Method, host name and user name completion for a file.
 (defun tramp-completion-handle-file-name-completion
@@ -3275,7 +3277,7 @@ User is always nil."
     (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
   ;; We must do it file-wise.
   (tramp-run-real-handler
-   'copy-directory
+   #'copy-directory
    (list directory newname keep-date parents copy-contents)))
 
 (defun tramp-handle-directory-file-name (directory)
diff --git a/lisp/outline.el b/lisp/outline.el
index fa7c1a2..68b8f4b 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -205,7 +205,9 @@ in the file it applies to.")
                                  (list 'face (outline-font-lock-face)
                                        'keymap outline-mode-cycle-map)
                                (list 'face nil
-                                     'keymap outline-mode-cycle-map)))
+                                     'keymap outline-mode-cycle-map))
+                           (if outline-minor-mode-highlight
+                               (list 'face (outline-font-lock-face))))
                        (outline-font-lock-face))
                   (when outline-minor-mode
                     (pcase outline-minor-mode-highlight
@@ -349,7 +351,7 @@ faces to major mode's faces."
                  (const :tag "Append outline faces to major mode faces" append)
                  (const :tag "Highlight separately from major mode faces" t))
   :version "28.1")
-;;;###autoload(put 'outline-minor-mode-highlight 'safe-local-variable 
'booleanp)
+;;;###autoload(put 'outline-minor-mode-highlight 'safe-local-variable 'symbolp)
 
 (defun outline-minor-mode-highlight-buffer ()
   ;; Fallback to overlays when font-lock is unsupported.
diff --git a/lisp/play/morse.el b/lisp/play/morse.el
index 91dc687..66a826f 100644
--- a/lisp/play/morse.el
+++ b/lisp/play/morse.el
@@ -165,7 +165,7 @@ Geospatial-Intelligence Agency at URL 
`https://www.nga.mil/'")
               (setq sep ""))
              ((setq morse (assoc str morse-code))
               (delete-char 1)
-              (insert sep (cdr morse))
+              (insert-before-markers sep (cdr morse))
               (setq sep "/"))
              (t
               (forward-char 1)
@@ -211,7 +211,7 @@ Geospatial-Intelligence Agency at URL 
`https://www.nga.mil/'")
               (setq sep ""))
              ((setq nato (assoc str nato-alphabet))
               (delete-char 1)
-              (insert sep (cdr nato))
+              (insert-before-markers sep (cdr nato))
               (setq sep "-"))
              (t
               (forward-char 1)
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index fc9627c..f1ec522 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -138,7 +138,7 @@ The second subexpression should match the bug reference 
(usually a number)."
        (when url
          (browse-url url))))))
 
-(defun bug-reference--maybe-setup-from-vc (url url-rx bug-rx bug-url-fmt)
+(defun bug-reference-maybe-setup-from-vc (url url-rx bug-rx bug-url-fmt)
   (when (string-match url-rx url)
     (setq-local bug-reference-bug-regexp bug-rx)
     (setq-local bug-reference-url-format
@@ -224,7 +224,7 @@ and apply it if applicable."
         (when url
           (catch 'found
             (dolist (config bug-reference-setup-from-vc-alist)
-              (when (apply #'bug-reference--maybe-setup-from-vc
+              (when (apply #'bug-reference-maybe-setup-from-vc
                            url config)
                 (throw 'found t)))))))))
 
@@ -258,7 +258,7 @@ same `bug-reference-url-format' and 
`bug-reference-url-format'.")
 
 (defvar gnus-newsgroup-name)
 
-(defun bug-reference--maybe-setup-from-mail (group header-values)
+(defun bug-reference-maybe-setup-from-mail (group header-values)
   "Set up according to mail GROUP or HEADER-VALUES.
 Group is a mail group/folder name and HEADER-VALUES is a list of
 mail header values, e.g., the values of From, To, Cc, List-ID,
@@ -294,53 +294,51 @@ and set it if applicable."
     ;; article changes.
     (add-hook 'gnus-article-prepare-hook
               #'bug-reference--try-setup-gnus-article)
-    (bug-reference--maybe-setup-from-mail gnus-newsgroup-name nil)))
+    (bug-reference-maybe-setup-from-mail gnus-newsgroup-name nil)))
 
 (defvar gnus-article-buffer)
 (defvar gnus-original-article-buffer)
 (defvar gnus-summary-buffer)
 
 (defun bug-reference--try-setup-gnus-article ()
-  (with-demoted-errors
-      "Error in bug-reference--try-setup-gnus-article: %S"
-    (when (and bug-reference-mode ;; Only if enabled in article buffers.
-               (derived-mode-p
-                'gnus-article-mode
-                ;; Apparently, gnus-article-prepare-hook is run in the
-                ;; summary buffer...
-                'gnus-summary-mode)
-               gnus-article-buffer
-               gnus-original-article-buffer
-               (buffer-live-p (get-buffer gnus-article-buffer))
-               (buffer-live-p (get-buffer gnus-original-article-buffer)))
-      (with-current-buffer gnus-article-buffer
-        (catch 'setup-done
-          ;; Copy over the values from the summary buffer.
-          (when (and gnus-summary-buffer
-                     (buffer-live-p gnus-summary-buffer))
-            (setq-local bug-reference-bug-regexp
-                        (with-current-buffer gnus-summary-buffer
-                          bug-reference-bug-regexp))
-            (setq-local bug-reference-url-format
-                        (with-current-buffer gnus-summary-buffer
-                          bug-reference-url-format))
-            (when (and bug-reference-bug-regexp
-                       bug-reference-url-format)
-              (throw 'setup-done t)))
-          ;; If the summary had no values, try setting according to
-          ;; the values of the From, To, and Cc headers.
-          (let (header-values)
-            (with-current-buffer
-                (get-buffer gnus-original-article-buffer)
-              (save-excursion
-                (goto-char (point-min))
-                ;; The Newsgroup is omitted because we already matched
-                ;; based on group name in the summary buffer.
-                (dolist (field '("list-id" "to" "from" "cc"))
-                  (let ((val (mail-fetch-field field)))
-                    (when val
-                      (push val header-values))))))
-            (bug-reference--maybe-setup-from-mail nil header-values)))))))
+  (when (and bug-reference-mode ;; Only if enabled in article buffers.
+             (derived-mode-p
+              'gnus-article-mode
+              ;; Apparently, gnus-article-prepare-hook is run in the
+              ;; summary buffer...
+              'gnus-summary-mode)
+             gnus-article-buffer
+             gnus-original-article-buffer
+             (buffer-live-p (get-buffer gnus-article-buffer))
+             (buffer-live-p (get-buffer gnus-original-article-buffer)))
+    (with-current-buffer gnus-article-buffer
+      (catch 'setup-done
+        ;; Copy over the values from the summary buffer.
+        (when (and gnus-summary-buffer
+                   (buffer-live-p gnus-summary-buffer))
+          (setq-local bug-reference-bug-regexp
+                      (with-current-buffer gnus-summary-buffer
+                        bug-reference-bug-regexp))
+          (setq-local bug-reference-url-format
+                      (with-current-buffer gnus-summary-buffer
+                        bug-reference-url-format))
+          (when (and bug-reference-bug-regexp
+                     bug-reference-url-format)
+            (throw 'setup-done t)))
+        ;; If the summary had no values, try setting according to
+        ;; the values of the From, To, and Cc headers.
+        (let (header-values)
+          (with-current-buffer
+              (get-buffer gnus-original-article-buffer)
+            (save-excursion
+              (goto-char (point-min))
+              ;; The Newsgroup is omitted because we already matched
+              ;; based on group name in the summary buffer.
+              (dolist (field '("list-id" "to" "from" "cc"))
+                (let ((val (mail-fetch-field field)))
+                  (when val
+                    (push val header-values))))))
+          (bug-reference-maybe-setup-from-mail nil header-values))))))
 
 (defun bug-reference-try-setup-from-rmail ()
   "Try setting up `bug-reference-mode' from the current rmail mail.
@@ -349,19 +347,17 @@ Guesses suitable `bug-reference-bug-regexp' and
 file's name against GROUP-REGEXP and the values of List-Id, To,
 From, and Cc against HEADER-REGEXP in
 `bug-reference-setup-from-mail-alist'."
-  (with-demoted-errors
-      "Error in bug-reference-try-setup-from-rmail: %S"
-    (when (and bug-reference-mode
-               (derived-mode-p 'rmail-mode))
-      (let (header-values)
-        (save-excursion
-          (goto-char (point-min))
-          (dolist (field '("list-id" "to" "from" "cc"))
-            (let ((val (mail-fetch-field field)))
-              (when val
-                (push val header-values)))))
-        (bug-reference--maybe-setup-from-mail
-         (buffer-file-name) header-values)))))
+  (when (and bug-reference-mode
+             (derived-mode-p 'rmail-mode))
+    (let (header-values)
+      (save-excursion
+        (goto-char (point-min))
+        (dolist (field '("list-id" "to" "from" "cc"))
+          (let ((val (mail-fetch-field field)))
+            (when val
+              (push val header-values)))))
+      (bug-reference-maybe-setup-from-mail
+       (buffer-file-name) header-values))))
 
 (defvar bug-reference-setup-from-irc-alist
   `((,(concat "#" (regexp-opt '("emacs" "gnus" "org-mode" "rcirc"
@@ -372,8 +368,8 @@ From, and Cc against HEADER-REGEXP in
   "An alist for setting up `bug-reference-mode' in IRC modes.
 
 This takes action if `bug-reference-mode' is enabled in IRC
-channels using one of Emacs' IRC clients (rcirc and ERC).
-Currently, rcirc and ERC are supported.
+channels using one of Emacs' IRC clients.  Currently, rcirc and
+ERC are supported.
 
 Each element has the form
 
@@ -386,7 +382,7 @@ If all given entries match, BUG-REGEXP is set as
 `bug-reference-bug-regexp' and URL-FORMAT is set as
 `bug-reference-url-format'.")
 
-(defun bug-reference--maybe-setup-from-irc (channel network)
+(defun bug-reference-maybe-setup-from-irc (channel network)
   "Set up according to IRC CHANNEL or NETWORK.
 CHANNEL is an IRC channel name (or generally a target, i.e., it
 could also be a user name) and NETWORK is that channel's network
@@ -422,7 +418,7 @@ corresponding BUG-REGEXP and URL-FORMAT are set."
 Test each configuration in `bug-reference-setup-from-irc-alist'
 and set it if applicable."
   (when (derived-mode-p 'rcirc-mode)
-    (bug-reference--maybe-setup-from-irc
+    (bug-reference-maybe-setup-from-irc
      rcirc-target
      (and rcirc-server-buffer
           (buffer-live-p rcirc-server-buffer)
@@ -437,7 +433,7 @@ and set it if applicable."
 Test each configuration in `bug-reference-setup-from-irc-alist'
 and set it if applicable."
   (when (derived-mode-p 'erc-mode)
-    (bug-reference--maybe-setup-from-irc
+    (bug-reference-maybe-setup-from-irc
      (erc-format-target)
      (erc-network-name))))
 
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index a8f1662..5108549 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -2979,7 +2979,7 @@ Key bindings:
 ;; bug reporting
 
 (defconst c-mode-help-address
-  "submit@debbugs.gnu.org"
+  "bug-gnu-emacs@gnu.org"
   "Address(es) for CC Mode bug reports.")
 
 (defun c-version ()
diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el
index 81ba0d8..b255758 100644
--- a/lisp/progmodes/hideshow.el
+++ b/lisp/progmodes/hideshow.el
@@ -310,7 +310,7 @@ a block), `hs-hide-all', `hs-hide-block' and 
`hs-hide-level'.")
 These commands include the toggling commands (when the result is to show
 a block), `hs-show-all' and `hs-show-block'.")
 
-(defvar hs-set-up-overlay #'ignore
+(defcustom hs-set-up-overlay #'ignore
   "Function called with one arg, OV, a newly initialized overlay.
 Hideshow puts a unique overlay on each range of text to be hidden
 in the buffer.  Here is a simple example of how to use this variable:
@@ -326,7 +326,9 @@ in the buffer.  Here is a simple example of how to use this 
variable:
 
 This example shows how to get information from the overlay as well
 as how to set its `display' property.  See `hs-make-overlay' and
-info node `(elisp)Overlays'.")
+info node `(elisp)Overlays'."
+  :type 'function
+  :version "28.1")
 
 ;;---------------------------------------------------------------------------
 ;; internal variables
diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el
index 2a0374a..a8d644d 100644
--- a/lisp/progmodes/modula2.el
+++ b/lisp/progmodes/modula2.el
@@ -201,7 +201,10 @@
          ((zerop (length tok))
           (let ((forward-sexp-function nil))
             (condition-case nil
-                (forward-sexp -1)
+                (let ((p (point)))
+                  (forward-sexp -1)
+                  (when (= p (point))
+                    (setq res ":")))
               (scan-error (setq res ":")))))
          ((member tok '("|" "OF" "..")) (setq res ":-case"))
          ((member tok '(":" "END" ";" "BEGIN" "VAR" "RECORD" "PROCEDURE"))
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index a1a5192..5d877fc 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -460,7 +460,8 @@ Non-nil means always go to the next Octave code line after 
sending."
          (smie-rule-parent octave-block-offset)
        ;; For (invalid) code between switch and case.
        ;; (if (smie-rule-parent-p "switch") 4)
-       nil))))
+       nil))
+    ('(:after . "=") octave-block-offset)))
 
 (defun octave-indent-comment ()
   "A function for `smie-indent-functions' (which see)."
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 047f55e..eab6075 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -297,11 +297,10 @@ to find the list of ignores for each directory."
          ;; expanded and not left for the shell command
          ;; to interpret.
          (localdir (file-name-unquote (file-local-name (expand-file-name 
dir))))
-         (command (format "%s %s %s -type f %s -print0"
+         (command (format "%s -H %s %s -type f %s -print0"
                           find-program
                           (shell-quote-argument
-                           ;; In case DIR is a symlink.
-                           (file-name-as-directory localdir))
+                           (directory-file-name localdir)) ; Bug#48471
                           (xref--find-ignores-arguments ignores localdir)
                           (if files
                               (concat (shell-quote-argument "(")
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 20ec339..f7267bd 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -4239,6 +4239,11 @@ JUSTIFY should be used (if applicable) as in 
`fill-paragraph'."
                     (point)))))
          (num-quotes (python-syntax-count-quotes
                       (char-after str-start-pos) str-start-pos))
+         (str-line-start-pos
+          (save-excursion
+            (goto-char str-start-pos)
+            (beginning-of-line)
+            (point-marker)))
          (str-end-pos
           (save-excursion
             (goto-char (+ str-start-pos num-quotes))
@@ -4262,7 +4267,7 @@ JUSTIFY should be used (if applicable) as in 
`fill-paragraph'."
             ('symmetric (and multi-line-p (cons 1 1)))))
          (fill-paragraph-function))
     (save-restriction
-      (narrow-to-region str-start-pos str-end-pos)
+      (narrow-to-region str-line-start-pos str-end-pos)
       (fill-paragraph justify))
     (save-excursion
       (when (and (python-info-docstring-p) python-fill-docstring-style)
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 0c54a1d..01fb044 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -2421,6 +2421,15 @@ If there is no Rubocop config file, Rubocop will be 
passed a flag
    report-fn
    args))
 
+(defconst ruby--prettify-symbols-alist
+  '(("<=" . ?≤)
+    (">=" . ?≥)
+    ("->"  . ?→)
+    ("=>"  . ?⇒)
+    ("::" . ?∷)
+    ("lambda" . ?λ))
+  "Value for `prettify-symbols-alist' in `ruby-mode'.")
+
 ;;;###autoload
 (define-derived-mode ruby-mode prog-mode "Ruby"
   "Major mode for editing Ruby code."
@@ -2437,6 +2446,7 @@ If there is no Rubocop config file, Rubocop will be 
passed a flag
 
   (setq-local font-lock-defaults '((ruby-font-lock-keywords) nil nil
                                    ((?_ . "w"))))
+  (setq-local prettify-symbols-alist ruby--prettify-symbols-alist)
 
   (setq-local syntax-propertize-function #'ruby-syntax-propertize))
 
diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el
index b697284..57351a7 100644
--- a/lisp/progmodes/scheme.el
+++ b/lisp/progmodes/scheme.el
@@ -299,7 +299,9 @@ See `run-hooks'."
        (concat
         "(" (regexp-opt
              '("begin" "call-with-current-continuation" "call/cc"
-               "call-with-input-file" "call-with-output-file" "case" "cond"
+               "call-with-input-file" "call-with-output-file"
+               "call-with-port"
+               "case" "cond"
                "do" "else" "for-each" "if" "lambda" "λ"
                "let" "let*" "let-syntax" "letrec" "letrec-syntax"
                ;; R6RS library subforms.
@@ -542,6 +544,7 @@ indentation."
 (put 'library 'scheme-indent-function 1) ; R6RS
 
 (put 'call-with-input-file 'scheme-indent-function 1)
+(put 'call-with-port 'scheme-indent-function 1)
 (put 'with-input-from-file 'scheme-indent-function 1)
 (put 'with-input-from-port 'scheme-indent-function 1)
 (put 'call-with-output-file 'scheme-indent-function 1)
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 83cb77e..f144549 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -484,6 +484,7 @@ file.  Since that is a plaintext file, this could be 
dangerous."
      :prompt-regexp "^[[:alnum:]_]*=[#>] "
      :prompt-length 5
      :prompt-cont-regexp "^[[:alnum:]_]*[-(][#>] "
+     :statement sql-postgres-statement-starters
      :input-filter sql-remove-tabs-filter
      :terminator ("\\(^\\s-*\\\\g\\|;\\)" . "\\g"))
 
@@ -997,20 +998,6 @@ for the first time."
   :version "24.1"
   :type 'hook)
 
-;; Customization for ANSI
-
-(defcustom sql-ansi-statement-starters
-  (regexp-opt '("create" "alter" "drop"
-                "select" "insert" "update" "delete" "merge"
-                "grant" "revoke"))
-  "Regexp of keywords that start SQL commands.
-
-All products share this list; products should define a regexp to
-identify additional keywords in a variable defined by
-the :statement feature."
-  :version "24.1"
-  :type 'regexp)
-
 ;; Customization for Oracle
 
 (defcustom sql-oracle-program "sqlplus"
@@ -1033,12 +1020,6 @@ You will find the file in your Orant\\bin directory."
   :type 'sql-login-params
   :version "24.1")
 
-(defcustom sql-oracle-statement-starters
-  (regexp-opt '("declare" "begin" "with"))
-  "Additional statement starting keywords in Oracle."
-  :version "24.1"
-  :type 'string)
-
 (defcustom sql-oracle-scan-on t
   "Non-nil if placeholders should be replaced in Oracle SQLi.
 
@@ -1502,6 +1483,26 @@ Based on `comint-mode-map'.")
     table)
   "Syntax table used in `sql-mode' and `sql-interactive-mode'.")
 
+;; Motion Function Keywords
+
+(defvar sql-ansi-statement-starters
+  (regexp-opt '("create" "alter" "drop"
+                "select" "insert" "update" "delete" "merge"
+                "grant" "revoke"))
+  "Regexp of keywords that start SQL commands.
+
+All products share this list; products should define a regexp to
+identify additional keywords in a variable defined by
+the :statement feature.")
+
+(defvar sql-oracle-statement-starters
+  (regexp-opt '("declare" "begin" "with"))
+  "Additional statement-starting keywords in Oracle.")
+
+(defvar sql-postgres-statement-starters
+  (regexp-opt '("with"))
+  "Additional statement-starting keywords in Postgres.")
+
 ;; Font lock support
 
 (defvar sql-mode-font-lock-object-name
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 180c0e0..d307c31 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1088,6 +1088,12 @@ local keymap that binds `RET' to 
`xref-quit-and-goto-xref'."
 (define-obsolete-function-alias 'xref--show-defs-buffer-at-bottom
   #'xref-show-definitions-buffer-at-bottom "28.1")
 
+(defun xref--completing-read-group (cand transform)
+  "Return group title of candidate CAND or TRANSFORM the candidate."
+  (if transform
+      (substring cand (1+ (next-single-property-change 0 'xref--group cand)))
+    (get-text-property 0 'xref--group cand)))
+
 (defun xref-show-definitions-completing-read (fetcher alist)
   "Let the user choose the target definition with completion.
 
@@ -1116,10 +1122,12 @@ between them by typing in the minibuffer with 
completion."
                                     (format #("%d:" 0 2 (face 
xref-line-number))
                                             line)
                                   ""))
+                               (group-prefix
+                                (substring group group-prefix-length))
                                (group-fmt
-                                (propertize
-                                 (substring group group-prefix-length)
-                                 'face 'xref-file-header))
+                                (propertize group-prefix
+                                            'face 'xref-file-header
+                                            'xref--group group-prefix))
                                (candidate
                                 (format "%s:%s%s" group-fmt line-fmt summary)))
                           (push (cons candidate xref) 
xref-alist-with-line-info)))))
@@ -1131,7 +1139,9 @@ between them by typing in the minibuffer with completion."
                          (lambda (string pred action)
                            (cond
                             ((eq action 'metadata)
-                             '(metadata . ((category . xref-location))))
+                             `(metadata
+                               . ((category . xref-location)
+                                  (group-function . 
,#'xref--completing-read-group))))
                             (t
                              (complete-with-action action collection string 
pred)))))
                         (def (caar collection)))
diff --git a/lisp/ps-mule.el b/lisp/ps-mule.el
index a8b5210..ab8af40 100644
--- a/lisp/ps-mule.el
+++ b/lisp/ps-mule.el
@@ -673,7 +673,7 @@ the sequence."
                        (not (vectorp (aref (nth 2 composition) 0))))
                   (car composition)
                 to))
-        (ascii-or-latin-1 "[\000-\377]+")
+        (ascii-or-latin-1 "[\000-ÿ]+")
         (run-width 0)
         (endpos nil)
         (font-spec-table (aref ps-mule-font-spec-tables
@@ -699,6 +699,7 @@ the sequence."
                 (setq composition (find-composition (point) to nil t))
                 (setq stop (if composition (car composition) to)))))
 
+            ;; We fold lines that contain ASCII or Latin-1.
            ((looking-at ascii-or-latin-1)
             (let ((nchars (- (min (match-end 0) stop) (point))))
               (setq width (* average-width nchars))
@@ -710,6 +711,7 @@ the sequence."
                 (setq run-width (+ run-width width))
                 (forward-char nchars))))
 
+            ;; Don't fold other lines.  (But why?)
            (t
             (while (and (< (point) stop) (not endpos))
               (setq width (char-width (following-char)))
diff --git a/lisp/simple.el b/lisp/simple.el
index b742ccd..4695a6a 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1661,6 +1661,7 @@ in *Help* buffer.  See also the command `describe-char'."
     (define-key m "\t" 'completion-at-point)
     (define-key m "\r" 'read--expression-try-read)
     (define-key m "\n" 'read--expression-try-read)
+    (define-key m "\M-g\M-c" 'read-expression-switch-to-completions)
     (set-keymap-parent m minibuffer-local-map)
     m))
 
@@ -5683,6 +5684,9 @@ PROMPT is a string to prompt with."
   ;; `current-kill' updates `kill-ring' with a possible interprogram-paste
   (current-kill 0)
   (let* ((history-add-new-input nil)
+         (history-pos (when yank-from-kill-ring-rotate
+                        (- (length kill-ring)
+                           (length kill-ring-yank-pointer))))
          (ellipsis (if (char-displayable-p ?…) "…" "..."))
          ;; Remove keymaps from text properties of copied string,
          ;; because typing RET in the minibuffer might call
@@ -5730,7 +5734,16 @@ PROMPT is a string to prompt with."
              '(metadata (display-sort-function . identity))
            (complete-with-action action completions string pred)))
        nil nil nil
-       'read-from-kill-ring-history))))
+       (if history-pos
+           (cons 'read-from-kill-ring-history (1+ history-pos))
+         'read-from-kill-ring-history)))))
+
+(defcustom yank-from-kill-ring-rotate t
+  "Whether using `yank-from-kill-ring' should rotate `kill-ring-yank-pointer'.
+If non-nil, the kill ring is rotated after selecting previously killed text."
+  :type 'boolean
+  :group 'killing
+  :version "28.1")
 
 (defun yank-from-kill-ring (string &optional arg)
   "Select a stretch of previously killed text and insert (\"paste\") it.
@@ -5755,12 +5768,18 @@ beginning of the inserted text and mark at the end, 
like `yank' does.
 When called from Lisp, insert STRING like `insert-for-yank' does."
   (interactive (list (read-from-kill-ring "Yank from kill-ring: ")
                      current-prefix-arg))
+  (setq yank-window-start (window-start))
   (push-mark)
   (insert-for-yank string)
+  (when yank-from-kill-ring-rotate
+    (let ((pos (seq-position kill-ring string)))
+      (when pos
+        (setq kill-ring-yank-pointer (nthcdr pos kill-ring)))))
   (if (consp arg)
-      ;; Swap point and mark like in `yank'.
+      ;; Swap point and mark like in `yank' and `yank-pop'.
       (goto-char (prog1 (mark t)
                    (set-marker (mark-marker) (point) (current-buffer))))))
+
 
 ;; Some kill commands.
 
@@ -8816,6 +8835,8 @@ makes it easier to edit it."
 
 (defvar completion-list-mode-map
   (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map special-mode-map)
+    (define-key map "g" nil) ;; There's nothing to revert from.
     (define-key map [mouse-2] 'choose-completion)
     (define-key map [follow-link] 'mouse-face)
     (define-key map [down-mouse-2] nil)
@@ -8825,8 +8846,10 @@ makes it easier to edit it."
     (define-key map [right] 'next-completion)
     (define-key map [?\t] 'next-completion)
     (define-key map [backtab] 'previous-completion)
-    (define-key map "q" 'quit-window)
     (define-key map "z" 'kill-current-buffer)
+    (define-key map "n" 'next-completion)
+    (define-key map "p" 'previous-completion)
+    (define-key map "\M-g\M-c" 'switch-to-minibuffer)
     map)
   "Local map for completion list buffers.")
 
@@ -8913,18 +8936,17 @@ If EVENT, use EVENT's position to determine the 
starting position."
           (choice
            (save-excursion
              (goto-char (posn-point (event-start event)))
-             (let (beg end)
+             (let (beg)
                (cond
                 ((and (not (eobp)) (get-text-property (point) 'mouse-face))
-                 (setq end (point) beg (1+ (point))))
+                 (setq beg (1+ (point))))
                 ((and (not (bobp))
                       (get-text-property (1- (point)) 'mouse-face))
-                 (setq end (1- (point)) beg (point)))
+                 (setq beg (point)))
                 (t (error "No completion here")))
                (setq beg (previous-single-property-change beg 'mouse-face))
-               (setq end (or (next-single-property-change end 'mouse-face)
-                             (point-max)))
-               (buffer-substring-no-properties beg end)))))
+               (substring-no-properties
+                (get-text-property beg 'completion--string))))))
 
       (unless (buffer-live-p buffer)
         (error "Destination buffer is dead"))
@@ -9116,6 +9138,18 @@ select the completion near point.\n\n"))))))
       ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
       (when (bobp)
        (next-completion 1)))))
+
+(defun read-expression-switch-to-completions ()
+  "Select the completion list window while reading an expression."
+  (interactive)
+  (completion-help-at-point)
+  (switch-to-completions))
+
+(defun switch-to-minibuffer ()
+  "Select the minibuffer window."
+  (interactive)
+  (when (active-minibuffer-window)
+    (select-window (active-minibuffer-window))))
 
 ;;; Support keyboard commands to turn on various modifiers.
 
diff --git a/lisp/startup.el b/lisp/startup.el
index 61b49b2..9edbe02 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -2319,6 +2319,9 @@ A fancy display is used on graphic displays, normal 
otherwise."
         (set-buffer-major-mode (current-buffer))
         (current-buffer))))
 
+;; This avoids byte-compiler warning in the unexec build.
+(declare-function pdumper-stats "pdumper.c" ())
+
 (defun command-line-1 (args-left)
   "A subroutine of `command-line'."
   (display-startup-echo-area-message)
diff --git a/lisp/subr.el b/lisp/subr.el
index 82c2d22..78507a5 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1757,6 +1757,12 @@ be a list of the form returned by `event-start' and 
`event-end'."
 (make-obsolete-variable 'load-dangerous-libraries
                         "no longer used." "27.1")
 
+(defvar inhibit--record-char nil
+  "Obsolete variable.
+This was used internally by quail.el and keyboard.c in Emacs 27.
+It does nothing in Emacs 28.")
+(make-obsolete-variable 'inhibit--record-char nil "28.1")
+
 ;; We can't actually make `values' obsolete, because that will result
 ;; in warnings when using `values' in let-bindings.
 ;;(make-obsolete-variable 'values "no longer used" "28.1")
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index eeaf805..8bcae37 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -770,8 +770,7 @@ Can be nil to mean \"no timeout\".")
 By not redisplaying right away for xterm queries, we can avoid
 unsightly flashing during initialization. Give up and redisplay
 anyway if we've been waiting a little while."
-  (let ((start-time (current-time))
-        (inhibit--record-char t))
+  (let ((start-time (current-time)))
     (or (let ((inhibit-redisplay t))
           (read-event nil nil xterm-query-redisplay-timeout))
         (read-event nil nil
@@ -839,8 +838,8 @@ We run the first FUNCTION whose STRING matches the input 
events."
    basemap
    (make-composed-keymap map (keymap-parent basemap))))
 
-(defun terminal-init-xterm ()
-  "Terminal initialization function for xterm."
+(defun xterm--init ()
+  "Initialize the terminal for xterm."
   ;; rxvt terminals sometimes set the TERM variable to "xterm", but
   ;; rxvt's keybindings are incompatible with xterm's. It is
   ;; better in that case to use rxvt's initialization function.
@@ -882,9 +881,18 @@ We run the first FUNCTION whose STRING matches the input 
events."
   ;; support it just ignore the sequence.
   (xterm--init-bracketed-paste-mode)
   ;; We likewise unconditionally enable support for focus tracking.
-  (xterm--init-focus-tracking)
+  (xterm--init-focus-tracking))
 
-  (run-hooks 'terminal-init-xterm-hook))
+(defun terminal-init-xterm ()
+  "Terminal initialization function for xterm."
+  (unwind-protect
+      (progn
+        (xterm--init)
+        ;; If the terminal initialization completed without errors, clear
+        ;; the lossage to discard the responses of the terminal emulator
+        ;; during initialization; otherwise they appear in the recent keys.
+        (clear-this-command-keys))
+    (run-hooks 'terminal-init-xterm-hook)))
 
 (defun xterm--init-modify-other-keys ()
   "Terminal initialization for xterm's modifyOtherKeys support."
diff --git a/lisp/transient.el b/lisp/transient.el
index 2ce7b7c..93a643c 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -4,25 +4,28 @@
 
 ;; Author: Jonas Bernoulli <jonas@bernoul.li>
 ;; Homepage: https://github.com/magit/transient
-;; Package-Requires: ((emacs "25.1"))
-;; Package-Version: 0.3.2
 ;; Keywords: bindings
 
-;; This file is part of GNU Emacs.
+;; Package-Requires: ((emacs "25.1"))
+;; Package-Version: 0.3.4
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
 
 ;; 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 this program.  If not, see <https://www.gnu.org/licenses/>.
 
+;; This file is part of GNU Emacs.
+
 ;;; Commentary:
 
 ;; Taking inspiration from prefix keys and prefix arguments, Transient
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index 2c72c45..a009339 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -1767,13 +1767,26 @@ char-offset in TEXT."
            (delete-region (point-min) keep))
          ;; Remove line-prefix characters, and unneeded lines (unified diffs).
           ;; Also skip lines like "\ No newline at end of file"
-         (let ((kill-chars (list (if destp ?- ?+) ?\\)))
+         (let ((kill-chars (list (if destp ?- ?+) ?\\))
+                curr-char last-char)
            (goto-char (point-min))
            (while (not (eobp))
-             (if (memq (char-after) kill-chars)
-                 (delete-region (point) (progn (forward-line 1) (point)))
+             (setq curr-char (char-after))
+             (if (memq curr-char kill-chars)
+                 (delete-region
+                  ;; Check for "\ No newline at end of file"
+                  (if (and (eq curr-char ?\\)
+                           (not (eq last-char (if destp ?- ?+)))
+                           (save-excursion
+                             (forward-line 1)
+                             (or (eobp) (and (eq last-char ?-)
+                                             (eq (char-after) ?+)))))
+                      (max (1- (point)) (point-min))
+                    (point))
+                  (progn (forward-line 1) (point)))
                (delete-char num-pfx-chars)
-               (forward-line 1)))))
+               (forward-line 1))
+             (setq last-char curr-char))))
 
        (let ((text (buffer-substring-no-properties (point-min) (point-max))))
          (if char-offset (cons text (- (point) (point-min))) text))))))
diff --git a/lisp/vc/ediff-diff.el b/lisp/vc/ediff-diff.el
index b93dfc8..270c99e 100644
--- a/lisp/vc/ediff-diff.el
+++ b/lisp/vc/ediff-diff.el
@@ -1146,7 +1146,10 @@ are ignored."
         (if (string-match "buffer" (symbol-name ediff-job-name))
             ediff-coding-system-for-write
           ediff-coding-system-for-read))
-       args)
+        (process-environment
+         ;; Avoid localization of messages so we can parse the output.
+         (cons "LC_MESSAGES=C" process-environment))
+        args)
     (setq args (append (split-string options)
                        (mapcar (lambda (file)
                                  (when (stringp file)
diff --git a/lisp/window.el b/lisp/window.el
index 1c71948..fd1c617 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -8788,7 +8788,11 @@ font on WINDOW's frame."
   (let* ((window (window-normalize-window window t))
         (frame (window-frame window))
         (default-font (face-font 'default frame)))
-    (if (and (display-multi-font-p (frame-parameter frame 'display))
+    ;; Client frames can have the 'display' parameter set like for X
+    ;; frames, even though they are TTY frames, so make sure we won't
+    ;; be duped by that up front with 'framep'.
+    (if (and (not (eq (framep frame) t))
+             (display-multi-font-p (frame-parameter frame 'display))
             (not (string-equal (frame-parameter frame 'font) default-font)))
         (aref (font-info default-font frame) 3)
       (frame-char-height frame))))
@@ -10051,6 +10055,9 @@ is active.  This function is run by 
`mouse-autoselect-window-timer'."
                 ;; already selected.
                 (and (not (eq frame (selected-frame)))
                      (frame-parameter frame 'no-accept-focus))
+                ;; Don't switch if window autoselection with mouse is active
+                ;; and minibuffer window is selected.
+                (and mouse-autoselect-window (window-minibuffer-p))
                 ;; Don't switch to minibuffer window unless it's active.
                 (and (window-minibuffer-p window)
                      (not (minibuffer-window-active-p window))))
diff --git a/nt/mingw-cfg.site b/nt/mingw-cfg.site
index 431fdab..6ab81e9 100644
--- a/nt/mingw-cfg.site
+++ b/nt/mingw-cfg.site
@@ -90,8 +90,9 @@ ac_cv_func_readlinkat=yes
 ac_cv_func_faccessat=yes
 # Avoid compiling Gnulib's canonicalize-lgpl.c, which fails
 ac_cv_func_canonicalize_file_name=yes
-ac_cv_func_realpath="not-needed"
-gl_cv_func_realpath_works="no-but-not-needed-so-yes"
+# Implemented in w32.c
+ac_cv_func_realpath=yes
+gl_cv_func_realpath_works=yes
 # Implemented in w32.c
 ac_cv_func_fcntl=yes
 gl_cv_func_fcntl_f_dupfd_cloexec=yes
diff --git a/src/Makefile.in b/src/Makefile.in
index 5da2257..40a423d 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -345,7 +345,7 @@ DUMPING=@DUMPING@
 CHECK_STRUCTS = @CHECK_STRUCTS@
 HAVE_PDUMPER = @HAVE_PDUMPER@
 
-## ARM Macs require that all code have a valid signature.  Since pump
+## ARM Macs require that all code have a valid signature.  Since pdump
 ## invalidates the signature, we must re-sign to fix it.
 DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@)
 
diff --git a/src/buffer.c b/src/buffer.c
index df302db..565577e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5681,10 +5681,10 @@ inserts one or more TAB characters, this variable will 
affect the
 indentation step as well, even if `indent-tabs-mode' is non-nil.  */);
 
   DEFVAR_PER_BUFFER ("ctl-arrow", &BVAR (current_buffer, ctl_arrow), Qnil,
-                    doc: /* Non-nil means display control chars with uparrow.
-A value of nil means use backslash and octal digits.
-This variable does not apply to characters whose display is specified
-in the current display table (if there is one).  */);
+                    doc: /* Non-nil means display control chars with uparrow 
`^'.
+A value of nil means use backslash `\\' and octal digits.
+This variable does not apply to characters whose display is specified in
+the current display table (if there is one; see `standard-display-table').  
*/);
 
   DEFVAR_PER_BUFFER ("enable-multibyte-characters",
                     &BVAR (current_buffer, enable_multibyte_characters),
diff --git a/src/character.c b/src/character.c
index 41abb83..e874cf5 100644
--- a/src/character.c
+++ b/src/character.c
@@ -34,6 +34,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "lisp.h"
 #include "character.h"
 #include "buffer.h"
+#include "frame.h"
 #include "dispextern.h"
 #include "composite.h"
 #include "disptab.h"
@@ -338,11 +339,18 @@ lisp_string_width (Lisp_Object string, ptrdiff_t from, 
ptrdiff_t to,
      contains only ascii and eight-bit-graphic, but that's
      intentional.  */
   bool multibyte = SCHARS (string) < SBYTES (string);
-  unsigned char *str = SDATA (string);
   ptrdiff_t i = from, i_byte = from ? string_char_to_byte (string, from) : 0;
   ptrdiff_t from_byte = i_byte;
   ptrdiff_t width = 0;
   struct Lisp_Char_Table *dp = buffer_display_table ();
+#ifdef HAVE_WINDOW_SYSTEM
+  struct frame *f =
+    (FRAMEP (selected_frame) && FRAME_LIVE_P (XFRAME (selected_frame)))
+    ? XFRAME (selected_frame)
+    : NULL;
+  int font_width = -1;
+  Lisp_Object default_font, frame_font;
+#endif
 
   eassert (precision <= 0 || (nchars && nbytes));
 
@@ -361,9 +369,51 @@ lisp_string_width (Lisp_Object string, ptrdiff_t from, 
ptrdiff_t to,
          chars = end - i;
          bytes = string_char_to_byte (string, end) - i_byte;
        }
+#ifdef HAVE_WINDOW_SYSTEM
+      else if (f && FRAME_WINDOW_P (f)
+              && multibyte
+              && find_automatic_composition (i, -1, &ignore, &end, &val, 
string)
+              && end > i)
+       {
+         int j;
+         for (j = 0; j < LGSTRING_GLYPH_LEN (val); j++)
+           if (NILP (LGSTRING_GLYPH (val, j)))
+             break;
+
+         int pixelwidth = composition_gstring_width (val, 0, j, NULL);
+
+         /* The below is somewhat expensive, so compute it only once
+            for the entire loop, and only if needed.  */
+         if (font_width < 0)
+           {
+             font_width = FRAME_COLUMN_WIDTH (f);
+             default_font = Fface_font (Qdefault, Qnil, Qnil);
+             frame_font = Fframe_parameter (Qnil, Qfont);
+
+             if (STRINGP (default_font) && STRINGP (frame_font)
+                 && (SCHARS (default_font) != SCHARS (frame_font)
+                     || SBYTES (default_font) != SBYTES (frame_font)
+                     || memcmp (SDATA (default_font), SDATA (frame_font),
+                                SBYTES (default_font))))
+               {
+                 Lisp_Object font_info = Ffont_info (default_font, Qnil);
+                 if (VECTORP (font_info))
+                   {
+                     font_width = XFIXNUM (AREF (font_info, 11));
+                     if (font_width <= 0)
+                       font_width = XFIXNUM (AREF (font_info, 10));
+                   }
+               }
+           }
+         thiswidth = (double) pixelwidth / font_width + 0.5;
+         chars = end - i;
+         bytes = string_char_to_byte (string, end) - i_byte;
+       }
+#endif /* HAVE_WINDOW_SYSTEM */
       else
        {
          int c;
+         unsigned char *str = SDATA (string);
 
          if (multibyte)
            {
diff --git a/src/comp.c b/src/comp.c
index c044505..056d086 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -4008,15 +4008,16 @@ DEFUN ("comp-el-to-eln-rel-filename", 
Fcomp_el_to_eln_rel_filename,
 {
   CHECK_STRING (filename);
 
-  /* Use `file-truename' or fall back to `expand-file-name' when the
-     first is not available (bug#44701).
-
-     `file-truename' is not available only for a short phases of the
-     bootstrap before file.el is loaded, given we do not symlink
-     inside the build directory this should work.  */
-  filename = NILP (Ffboundp (intern_c_string ("file-truename")))
-    ? Fexpand_file_name (filename, Qnil)
-    : CALL1I (file-truename, filename);
+  /* Resolve possible symlinks in FILENAME, so that path_hash below
+     always compares equal. (Bug#44701).  */
+  filename = Fexpand_file_name (filename, Qnil);
+  char *file_normalized = realpath (SSDATA (ENCODE_FILE (filename)), NULL);
+  if (file_normalized)
+    {
+      filename = DECODE_FILE (make_unibyte_string (file_normalized,
+                                                  strlen (file_normalized)));
+      xfree (file_normalized);
+    }
 
   if (NILP (Ffile_exists_p (filename)))
     xsignal1 (Qfile_missing, filename);
@@ -4056,7 +4057,8 @@ DEFUN ("comp-el-to-eln-rel-filename", 
Fcomp_el_to_eln_rel_filename,
       Lisp_Object sys_re =
        concat2 (build_string ("\\`[[:ascii:]]+"),
                 Fregexp_quote (build_string ("/" PATH_REL_LOADSEARCH "/")));
-      Lisp_Object dump_load_search = build_string (PATH_DUMPLOADSEARCH "/");
+      Lisp_Object dump_load_search =
+       Fexpand_file_name (build_string (PATH_DUMPLOADSEARCH "/"), Qnil);
 #ifdef WINDOWSNT
       dump_load_search = Fw32_long_file_name (dump_load_search);
 #endif
diff --git a/src/composite.c b/src/composite.c
index f1c0112..17d5914 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -953,8 +953,12 @@ char_composable_p (int c)
   Lisp_Object val;
   return (c >= ' '
          && (c == ZERO_WIDTH_NON_JOINER || c == ZERO_WIDTH_JOINER
-             || (val = CHAR_TABLE_REF (Vunicode_category_table, c),
-                 (FIXNUMP (val) && (XFIXNUM (val) <= UNICODE_CATEGORY_Zs)))));
+             /* unicode-category-table may not be available during
+                dumping.  */
+             || (CHAR_TABLE_P (Vunicode_category_table)
+                 && (val = CHAR_TABLE_REF (Vunicode_category_table, c),
+                     (FIXNUMP (val)
+                      && (XFIXNUM (val) <= UNICODE_CATEGORY_Zs))))));
 }
 
 /* Update cmp_it->stop_pos to the next position after CHARPOS (and
@@ -1475,7 +1479,7 @@ struct position_record
    representing the composition, and return true.  Otherwise, *GSTRING to
    Qnil, and return false.  */
 
-static bool
+bool
 find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit,
                            ptrdiff_t *start, ptrdiff_t *end,
                            Lisp_Object *gstring, Lisp_Object string)
diff --git a/src/composite.h b/src/composite.h
index c5d3c0f..75e5f9b 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -320,6 +320,10 @@ extern bool composition_gstring_p (Lisp_Object);
 extern int composition_gstring_width (Lisp_Object, ptrdiff_t, ptrdiff_t,
                                       struct font_metrics *);
 
+extern bool find_automatic_composition (ptrdiff_t, ptrdiff_t, ptrdiff_t *,
+                                       ptrdiff_t *, Lisp_Object *,
+                                       Lisp_Object);
+
 extern void composition_compute_stop_pos (struct composition_it *,
                                           ptrdiff_t, ptrdiff_t, ptrdiff_t,
                                           Lisp_Object);
diff --git a/src/conf_post.h b/src/conf_post.h
index 176ab28..8558dc4 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -99,10 +99,28 @@ typedef bool bool_bf;
 # define ADDRESS_SANITIZER false
 #endif
 
+#ifdef emacs
+/* We include stdlib.h here, because Gnulib's stdlib.h might redirect
+   'free' to its replacement, and we want to avoid that in unexec
+   builds.  Inclduing it here will render its inclusion after config.h
+   a no-op.  */
+# if (defined DARWIN_OS && defined HAVE_UNEXEC) || defined HYBRID_MALLOC
+#  include <stdlib.h>
+# endif
+#endif
+
 #if defined DARWIN_OS && defined emacs && defined HAVE_UNEXEC
+# undef malloc
 # define malloc unexec_malloc
+# undef realloc
 # define realloc unexec_realloc
+# undef free
 # define free unexec_free
+
+extern void *unexec_malloc (size_t);
+extern void *unexec_realloc (void *, size_t);
+extern void unexec_free (void *);
+
 #endif
 
 /* If HYBRID_MALLOC is defined (e.g., on Cygwin), emacs will use
@@ -111,12 +129,23 @@ typedef bool bool_bf;
    accomplish this.  */
 #ifdef HYBRID_MALLOC
 #ifdef emacs
+#undef malloc
 #define malloc hybrid_malloc
+#undef realloc
 #define realloc hybrid_realloc
+#undef aligned_alloc
 #define aligned_alloc hybrid_aligned_alloc
+#undef calloc
 #define calloc hybrid_calloc
+#undef free
 #define free hybrid_free
-#endif
+
+extern void *hybrid_malloc (size_t);
+extern void *hybrid_calloc (size_t, size_t);
+extern void hybrid_free (void *);
+extern void *hybrid_aligned_alloc (size_t, size_t);
+extern void *hybrid_realloc (void *, size_t);
+#endif /* emacs */
 #endif /* HYBRID_MALLOC */
 
 /* We have to go this route, rather than the old hpux9 approach of
diff --git a/src/editfns.c b/src/editfns.c
index 04b8e85..182d3ba 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1452,8 +1452,8 @@ DEFUN ("insert-char", Finsert_char, Sinsert_char, 1, 3,
               (prefix-numeric-value current-prefix-arg)\
               t))",
        doc: /* Insert COUNT copies of CHARACTER.
-Interactively, prompt for CHARACTER.  You can specify CHARACTER in one
-of these ways:
+Interactively, prompt for CHARACTER using `read-char-by-name'.
+You can specify CHARACTER in one of these ways:
 
  - As its Unicode character name, e.g. \"LATIN SMALL LETTER A\".
    Completion is available; if you type a substring of the name
diff --git a/src/fileio.c b/src/fileio.c
index 741e297..caf077e 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2987,12 +2987,16 @@ file_directory_p (Lisp_Object file)
 DEFUN ("file-accessible-directory-p", Ffile_accessible_directory_p,
        Sfile_accessible_directory_p, 1, 1, 0,
        doc: /* Return t if FILENAME names a directory you can open.
-For the value to be t, FILENAME must specify the name of a directory
-as a file, and the directory must allow you to open files in it.  In
-order to use a directory as a buffer's current directory, this
-predicate must return true.  A directory name spec may be given
-instead; then the value is t if the directory so specified exists and
-really is a readable and searchable directory.  */)
+This means that FILENAME must specify the name of a directory, and the
+directory must allow you to open files in it.  If this isn't the case,
+return nil.
+
+FILENAME can either be a directory name (eg. \"/tmp/foo/\") or the
+file name of a file which is a directory (eg. \"/tmp/foo\", without
+the final slash).
+
+In order to use a directory as a buffer's current directory, this
+predicate must return true.  */)
   (Lisp_Object filename)
 {
   Lisp_Object absname;
diff --git a/src/fns.c b/src/fns.c
index 41429c8..40ade57 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5892,12 +5892,14 @@ in OBJECT.  */)
 
 DEFUN ("line-number-at-pos", Fline_number_at_pos,
        Sline_number_at_pos, 0, 2, 0,
-       doc: /* Return the line number at POSITION.
-If POSITION is nil, use the current buffer location.
-
-If the buffer is narrowed, the position returned is the position in the
-visible part of the buffer.  If ABSOLUTE is non-nil, count the lines
-from the absolute start of the buffer.  */)
+       doc: /* Return the line number at POSITION in the current buffer.
+If POSITION is nil or omitted, it defaults to point's position in the
+current buffer.
+
+If the buffer is narrowed, the return value by default counts the lines
+from the beginning of the accessible portion of the buffer.  But if the
+second optional argument ABSOLUTE is non-nil, the value counts the lines
+from the absolute start of the buffer, disregarding the narrowing.  */)
   (register Lisp_Object position, Lisp_Object absolute)
 {
   ptrdiff_t pos, start = BEGV_BYTE;
@@ -5915,9 +5917,9 @@ from the absolute start of the buffer.  */)
   if (!NILP (absolute))
     start = BEG_BYTE;
 
-  /* Check that POSITION is n the visible range of the buffer. */
+  /* Check that POSITION is in the accessible range of the buffer. */
   if (pos < BEGV || pos > ZV)
-    args_out_of_range (make_int (start), make_int (ZV));
+    args_out_of_range_3 (make_int (pos), make_int (BEGV), make_int (ZV));
 
   return make_int (count_lines (start, CHAR_TO_BYTE (pos)) + 1);
 }
diff --git a/src/fringe.c b/src/fringe.c
index 0224268..e67ea9d 100644
--- a/src/fringe.c
+++ b/src/fringe.c
@@ -1797,14 +1797,15 @@ gui_init_fringe (struct redisplay_interface *rif)
   for (bt = NO_FRINGE_BITMAP + 1; bt < MAX_STANDARD_FRINGE_BITMAPS; bt++)
     {
       struct fringe_bitmap *fb = &standard_bitmaps[bt];
-      rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
+      if (!fringe_bitmaps[bt])
+        rif->define_fringe_bitmap (bt, fb->bits, fb->height, fb->width);
     }
 
   /* Set up user-defined fringe bitmaps that might have been defined
      before the frame of this kind was initialized.  This can happen
      if Emacs is started as a daemon and the init files define fringe
      bitmaps.  */
-  for ( ; bt < max_used_fringe_bitmap; bt++)
+  for (bt = NO_FRINGE_BITMAP + 1; bt < max_used_fringe_bitmap; bt++)
     {
       struct fringe_bitmap *fb = fringe_bitmaps[bt];
       if (fb)
diff --git a/src/gmalloc.c b/src/gmalloc.c
index 66008ea..55ae736 100644
--- a/src/gmalloc.c
+++ b/src/gmalloc.c
@@ -1690,16 +1690,6 @@ valloc (size_t size)
 #undef free
 
 #ifdef HYBRID_MALLOC
-/* Declare system malloc and friends.  */
-extern void *malloc (size_t size);
-extern void *realloc (void *ptr, size_t size);
-extern void *calloc (size_t nmemb, size_t size);
-extern void free (void *ptr);
-#ifdef HAVE_ALIGNED_ALLOC
-extern void *aligned_alloc (size_t alignment, size_t size);
-#elif defined HAVE_POSIX_MEMALIGN
-extern int posix_memalign (void **memptr, size_t alignment, size_t size);
-#endif
 
 /* Assuming PTR was allocated via the hybrid malloc, return true if
    PTR was allocated via gmalloc, not the system malloc.  Also, return
@@ -1736,8 +1726,8 @@ hybrid_calloc (size_t nmemb, size_t size)
   return gcalloc (nmemb, size);
 }
 
-void
-hybrid_free (void *ptr)
+static void
+hybrid_free_1 (void *ptr)
 {
   if (allocated_via_gmalloc (ptr))
     gfree (ptr);
@@ -1745,6 +1735,24 @@ hybrid_free (void *ptr)
     free (ptr);
 }
 
+void
+hybrid_free (void *ptr)
+{
+  /* Stolen from Gnulib, to make sure we preserve errno.  */
+#if defined __GNUC__ && !defined __clang__
+  int err[2];
+  err[0] = errno;
+  err[1] = errno;
+  errno = 0;
+  hybrid_free_1 (ptr);
+  errno = err[errno == 0];
+#else
+  int err = errno;
+  hybrid_free_1 (ptr);
+  errno = err;
+#endif
+}
+
 #if defined HAVE_ALIGNED_ALLOC || defined HAVE_POSIX_MEMALIGN
 void *
 hybrid_aligned_alloc (size_t alignment, size_t size)
diff --git a/src/keyboard.c b/src/keyboard.c
index c3fce19..b2aabdd 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3233,10 +3233,6 @@ help_char_p (Lisp_Object c)
 static void
 record_char (Lisp_Object c)
 {
-  /* quail.el binds this to avoid recording keys twice.  */
-  if (inhibit_record_char)
-    return;
-
   int recorded = 0;
 
   if (CONSP (c) && (EQ (XCAR (c), Qhelp_echo) || EQ (XCAR (c), 
Qmouse_movement)))
@@ -12351,13 +12347,6 @@ If nil, Emacs crashes immediately in response to fatal 
signals.  */);
                Vwhile_no_input_ignore_events,
                doc: /* Ignored events from while-no-input.  */);
 
-  DEFVAR_BOOL ("inhibit--record-char",
-              inhibit_record_char,
-              doc: /* If non-nil, don't record input events.
-This inhibits recording input events for the purposes of keyboard
-macros, dribble file, and `recent-keys'.
-Internal use only.  */);
-
   pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
 }
 
@@ -12391,8 +12380,6 @@ syms_of_keyboard_for_pdumper (void)
   /* Create the initial keyboard.  Qt means 'unset'.  */
   eassert (initial_kboard == NULL);
   initial_kboard = allocate_kboard (Qt);
-
-  inhibit_record_char = false;
 }
 
 void
diff --git a/src/lread.c b/src/lread.c
index bca53a9..0b33fd0 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3938,8 +3938,7 @@ string_to_number (char const *string, int base, ptrdiff_t 
*plen)
   bool signedp = negative | positive;
   cp += signedp;
 
-  enum { INTOVERFLOW = 1, LEAD_INT = 2, DOT_CHAR = 4, TRAIL_INT = 8,
-        E_EXP = 16 };
+  enum { INTOVERFLOW = 1, LEAD_INT = 2, TRAIL_INT = 4, E_EXP = 16 };
   int state = 0;
   int leading_digit = digit_to_number (*cp, base);
   uintmax_t n = leading_digit;
@@ -3959,7 +3958,6 @@ string_to_number (char const *string, int base, ptrdiff_t 
*plen)
   char const *after_digits = cp;
   if (*cp == '.')
     {
-      state |= DOT_CHAR;
       cp++;
     }
 
@@ -4008,8 +4006,10 @@ string_to_number (char const *string, int base, 
ptrdiff_t *plen)
            cp = ecp;
        }
 
-      float_syntax = ((state & (DOT_CHAR|TRAIL_INT)) == (DOT_CHAR|TRAIL_INT)
-                     || (state & ~INTOVERFLOW) == (LEAD_INT|E_EXP));
+      /* A float has digits after the dot or an exponent.
+        This excludes numbers like "1." which are lexed as integers. */
+      float_syntax = ((state & TRAIL_INT)
+                     || ((state & LEAD_INT) && (state & E_EXP)));
     }
 
   if (plen)
diff --git a/src/process.c b/src/process.c
index f3f4f09..ce71545 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5134,6 +5134,7 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
                             Lisp_Object wait_for_cell,
                             struct Lisp_Process *wait_proc, int just_wait_proc)
 {
+  static int last_read_channel = -1;
   int channel, nfds;
   fd_set Available;
   fd_set Writeok;
@@ -5188,6 +5189,8 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
   while (1)
     {
       bool process_skipped = false;
+      bool wrapped;
+      int channel_start;
 
       /* If calling from keyboard input, do not quit
         since we want to return C-g as an input character.
@@ -5726,8 +5729,21 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
             d->func (channel, d->data);
        }
 
-      for (channel = 0; channel <= max_desc; channel++)
+      /* Do round robin if `process-pritoritize-lower-fds' is nil. */
+      channel_start
+       = process_prioritize_lower_fds ? 0 : last_read_channel + 1;
+
+      for (channel = channel_start, wrapped = false;
+          !wrapped || (channel < channel_start && channel <= max_desc);
+          channel++)
        {
+         if (channel > max_desc)
+           {
+             wrapped = true;
+             channel = -1;
+             continue;
+           }
+
          if (FD_ISSET (channel, &Available)
              && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD))
                  == PROCESS_FD))
@@ -5765,6 +5781,7 @@ wait_reading_process_output (intmax_t time_limit, int 
nsecs, int read_kbd,
                     don't try to read from any other processes
                     before doing the select again.  */
                  FD_ZERO (&Available);
+                 last_read_channel = channel;
 
                  if (do_display)
                    redisplay_preserve_echo_area (12);
@@ -8481,6 +8498,16 @@ non-nil value means that the delay is not reset on write.
 The variable takes effect when `start-process' is called.  */);
   Vprocess_adaptive_read_buffering = Qt;
 
+  DEFVAR_BOOL ("process-prioritize-lower-fds", process_prioritize_lower_fds,
+              doc: /* Whether to start checking for subprocess output from 
first file descriptor.
+Emacs loops through file descriptors to check for output from subprocesses.
+If this variable is nil, the default, then after accepting output from a
+subprocess, Emacs will continue checking the rest of descriptors, starting
+from the one following the descriptor it just read.  If this variable is
+non-nil, Emacs will always restart the loop from the first file descriptor,
+thus favoring processes with lower descriptors.  */);
+  process_prioritize_lower_fds = 0;
+
   DEFVAR_LISP ("interrupt-process-functions", Vinterrupt_process_functions,
               doc: /* List of functions to be called for `interrupt-process'.
 The arguments of the functions are the same as for `interrupt-process'.
diff --git a/src/sysdep.c b/src/sysdep.c
index d940acc..51d8b5e 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3626,7 +3626,7 @@ system_process_attributes (Lisp_Object pid)
   ttyname = proc.ki_tdev == NODEV ? NULL : devname (proc.ki_tdev, S_IFCHR);
   unblock_input ();
   if (ttyname)
-    attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs);
+    attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
 
   attrs = Fcons (Fcons (Qtpgid,   INT_TO_INTEGER (proc.ki_tpgid)), attrs);
   attrs = Fcons (Fcons (Qminflt,  INT_TO_INTEGER (proc.ki_rusage.ru_minflt)),
@@ -3898,20 +3898,19 @@ system_process_attributes (Lisp_Object pid)
 Lisp_Object
 system_process_attributes (Lisp_Object pid)
 {
-  int proc_id;
+  int proc_id, i;
   struct passwd *pw;
   struct group  *gr;
   char *ttyname;
   struct timeval starttime;
   struct timespec t, now;
-  struct rusage *rusage;
   dev_t tdev;
   uid_t uid;
   gid_t gid;
 
   int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID};
   struct kinfo_proc proc;
-  size_t proclen = sizeof proc;
+  size_t len = sizeof proc;
 
   Lisp_Object attrs = Qnil;
   Lisp_Object decoded_comm;
@@ -3920,7 +3919,7 @@ system_process_attributes (Lisp_Object pid)
   CONS_TO_INTEGER (pid, int, proc_id);
   mib[3] = proc_id;
 
-  if (sysctl (mib, 4, &proc, &proclen, NULL, 0) != 0 || proclen == 0)
+  if (sysctl (mib, 4, &proc, &len, NULL, 0) != 0 || len == 0)
     return attrs;
 
   uid = proc.kp_eproc.e_ucred.cr_uid;
@@ -3957,8 +3956,8 @@ system_process_attributes (Lisp_Object pid)
   decoded_comm = (code_convert_string_norecord
                  (build_unibyte_string (comm),
                   Vlocale_coding_system, 0));
-
   attrs = Fcons (Fcons (Qcomm, decoded_comm), attrs);
+
   {
     char state[2] = {'\0', '\0'};
     switch (proc.kp_proc.p_stat)
@@ -3994,27 +3993,24 @@ system_process_attributes (Lisp_Object pid)
   ttyname = tdev == NODEV ? NULL : devname (tdev, S_IFCHR);
   unblock_input ();
   if (ttyname)
-    attrs = Fcons (Fcons (Qtty, build_string (ttyname)), attrs);
+    attrs = Fcons (Fcons (Qttname, build_string (ttyname)), attrs);
 
   attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)),
                 attrs);
 
-  rusage = proc.kp_proc.p_ru;
-  if (rusage)
+  rusage_info_current ri;
+  if (proc_pid_rusage(proc_id, RUSAGE_INFO_CURRENT, (rusage_info_t *) &ri) == 
0)
     {
-      attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (rusage->ru_minflt)),
-                    attrs);
-      attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (rusage->ru_majflt)),
-                    attrs);
-
-      attrs = Fcons (Fcons (Qutime, make_lisp_timeval (rusage->ru_utime)),
-                    attrs);
-      attrs = Fcons (Fcons (Qstime, make_lisp_timeval (rusage->ru_stime)),
-                    attrs);
-      t = timespec_add (timeval_to_timespec (rusage->ru_utime),
-                       timeval_to_timespec (rusage->ru_stime));
-      attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs);
-    }
+      struct timespec utime = make_timespec (ri.ri_user_time / TIMESPEC_HZ,
+                                            ri.ri_user_time % TIMESPEC_HZ);
+      struct timespec stime = make_timespec (ri.ri_system_time / TIMESPEC_HZ,
+                                            ri.ri_system_time % TIMESPEC_HZ);
+      attrs = Fcons (Fcons (Qutime, make_lisp_time (utime)), attrs);
+      attrs = Fcons (Fcons (Qstime, make_lisp_time (stime)), attrs);
+      attrs = Fcons (Fcons (Qtime, make_lisp_time (timespec_add (utime, 
stime))), attrs);
+
+      attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (ri.ri_pageins)), attrs);
+  }
 
   starttime = proc.kp_proc.p_starttime;
   attrs = Fcons (Fcons (Qnice,  make_fixnum (proc.kp_proc.p_nice)), attrs);
@@ -4024,6 +4020,50 @@ system_process_attributes (Lisp_Object pid)
   t = timespec_sub (now, timeval_to_timespec (starttime));
   attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs);
 
+  struct proc_taskinfo taskinfo;
+  if (proc_pidinfo (proc_id, PROC_PIDTASKINFO, 0, &taskinfo, sizeof 
(taskinfo)) > 0)
+    {
+      attrs = Fcons (Fcons (Qvsize, make_fixnum (taskinfo.pti_virtual_size / 
1024)), attrs);
+      attrs = Fcons (Fcons (Qrss, make_fixnum (taskinfo.pti_resident_size / 
1024)), attrs);
+      attrs = Fcons (Fcons (Qthcount, make_fixnum (taskinfo.pti_threadnum)), 
attrs);
+    }
+
+#ifdef KERN_PROCARGS2
+  char args[ARG_MAX];
+  mib[1] = KERN_PROCARGS2;
+  mib[2] = proc_id;
+  len = sizeof args;
+
+  if (sysctl (mib, 3, &args, &len, NULL, 0) == 0 && len != 0)
+    {
+      char *start, *end;
+
+      int argc = *(int*)args; /* argc is the first int */
+      start = args + sizeof (int);
+
+      start += strlen (start) + 1; /* skip executable name and any '\0's */
+      while ((start - args < len) && ! *start) start++;
+
+      /* skip argv to find real end */
+      for (i = 0, end = start; i < argc && (end - args) < len; i++)
+       {
+         end += strlen (end) + 1;
+       }
+
+      len = end - start;
+      for (int i = 0; i < len; i++)
+       {
+         if (! start[i] && i < len - 1)
+           start[i] = ' ';
+       }
+
+      AUTO_STRING (comm, start);
+      decoded_comm = code_convert_string_norecord (comm,
+                                                  Vlocale_coding_system, 0);
+      attrs = Fcons (Fcons (Qargs, decoded_comm), attrs);
+    }
+#endif /* KERN_PROCARGS2 */
+
   return attrs;
 }
 
diff --git a/src/w32.c b/src/w32.c
index 26cc28f..968b4bb 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -10587,6 +10587,45 @@ w32_my_exename (void)
   return exename;
 }
 
+/* Emulate Posix 'realpath'.  This is needed in
+   comp-el-to-eln-rel-filename.  */
+char *
+realpath (const char *file_name, char *resolved_name)
+{
+  char *tgt = chase_symlinks (file_name);
+  char target[MAX_UTF8_PATH];
+
+  if (tgt == file_name)
+    {
+      /* If FILE_NAME is not a symlink, chase_symlinks returns its
+        argument, possibly not in canonical absolute form.  Make sure
+        we return a canonical file name.  */
+      if (w32_unicode_filenames)
+       {
+         wchar_t file_w[MAX_PATH], tgt_w[MAX_PATH];
+
+         filename_to_utf16 (file_name, file_w);
+         if (GetFullPathNameW (file_w, MAX_PATH, tgt_w, NULL) == 0)
+           return NULL;
+         filename_from_utf16 (tgt_w, target);
+       }
+      else
+       {
+         char file_a[MAX_PATH], tgt_a[MAX_PATH];
+
+         filename_to_ansi (file_name, file_a);
+         if (GetFullPathNameA (file_a, MAX_PATH, tgt_a, NULL) == 0)
+           return NULL;
+         filename_from_ansi (tgt_a, target);
+       }
+      tgt = target;
+    }
+
+  if (resolved_name)
+    return strcpy (resolved_name, tgt);
+  return xstrdup (tgt);
+}
+
 /*
        globals_of_w32 is used to initialize those global variables that
        must always be initialized on startup even when the global variable
diff --git a/src/w32.h b/src/w32.h
index a382dbe..ffa145b 100644
--- a/src/w32.h
+++ b/src/w32.h
@@ -187,6 +187,7 @@ extern DWORD multiByteToWideCharFlags;
 
 extern char *w32_my_exename (void);
 extern const char *w32_relocate (const char *);
+extern char *realpath (const char *, char *);
 
 extern void init_environment (char **);
 extern void check_windows_init_file (void);
diff --git a/test/README b/test/README
index a348074..0c8d5a4 100644
--- a/test/README
+++ b/test/README
@@ -7,6 +7,9 @@ Emacs's functionality.  Please help add tests!
 See the file file-organization.org for the details of the directory
 structure and file-naming conventions.
 
+For tests in the manual/ subdirectory, look there for separate README
+files, or look for instructions in the test files themselves.
+
 Emacs uses ERT, Emacs Lisp Regression Testing, for testing.  See (info
 "(ert)") or https://www.gnu.org/software/emacs/manual/html_node/ert/
 for more information on writing and running tests.
diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba
index 19c83a8..9f03482 100644
--- a/test/infra/Dockerfile.emba
+++ b/test/infra/Dockerfile.emba
@@ -70,3 +70,18 @@ RUN ./autogen.sh autoconf
 RUN ./configure --with-ns
 RUN make bootstrap
 RUN make -j4
+
+FROM emacs-base as emacs-native-comp-speed0
+
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 
libgccjit-6-dev \
+    && rm -rf /var/lib/apt/lists/*
+
+ARG make_bootstrap_params=""
+
+COPY . /checkout
+WORKDIR /checkout
+RUN ./autogen.sh autoconf
+RUN ./configure --with-nativecomp
+RUN make bootstrap -j2 NATIVE_FULL_AOT=1 BYTE_COMPILE_EXTRA_FLAGS='--eval 
"(setq comp-speed 0)"'
+RUN make -j4
diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml
index 4023437..fa10fa6 100644
--- a/test/infra/gitlab-ci.yml
+++ b/test/infra/gitlab-ci.yml
@@ -181,6 +181,21 @@ default:
         - test/lisp/autorevert-tests.el
         - test/lisp/filenotify-tests.el
 
+.native-comp-template:
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "web"'
+    - if: '$CI_PIPELINE_SOURCE == "schedule"'
+      changes:
+        - "**/Makefile.in"
+        - .gitlab-ci.yml
+        - lisp/emacs-lisp/comp.el
+        - lisp/emacs-lisp/comp-cstr.el
+        - src/comp.{h,m}
+        - test/infra/*
+        - test/src/comp-resources/*.el
+        - test/src/comp-tests.el
+  timeout: 8 hours
+
 stages:
   - prep-images
   - build-images
@@ -188,6 +203,8 @@ stages:
   - normal
   - platform-images
   - platforms
+  - native-comp-images
+  - native-comp
   - slow
 
 prep-image-base:
@@ -199,6 +216,7 @@ prep-image-base:
 build-image-inotify:
   stage: build-images
   extends: [.job-template, .build-template]
+  needs: [prep-image-base]
   variables:
     target: emacs-inotify
 
@@ -209,18 +227,6 @@ test-fast-inotify:
     target: emacs-inotify
     make_params: "-C test check"
 
-build-image-filenotify-gio:
-  stage: platform-images
-  extends: [.job-template, .build-template, .filenotify-gio-template]
-  variables:
-    target: emacs-filenotify-gio
-
-build-image-gnustep:
-  stage: platform-images
-  extends: [.job-template, .build-template, .gnustep-template]
-  variables:
-    target: emacs-gnustep
-
 test-lisp-inotify:
   stage: normal
   extends: [.job-template, .test-template]
@@ -235,6 +241,20 @@ test-lisp-net-inotify:
     target: emacs-inotify
     make_params: "-C test check-lisp-net"
 
+build-image-filenotify-gio:
+  stage: platform-images
+  extends: [.job-template, .build-template, .filenotify-gio-template]
+  needs: [prep-image-base]
+  variables:
+    target: emacs-filenotify-gio
+
+build-image-gnustep:
+  stage: platform-images
+  extends: [.job-template, .build-template, .gnustep-template]
+  needs: [prep-image-base]
+  variables:
+    target: emacs-gnustep
+
 test-filenotify-gio:
   # This tests file monitor libraries gfilemonitor and gio.
   stage: platforms
@@ -244,38 +264,6 @@ test-filenotify-gio:
     target: emacs-filenotify-gio
     make_params: "-k -C test autorevert-tests.log filenotify-tests.log"
 
-build-native-bootstrap-speed0:
-  # Test a full native bootstrap
-  # Run for now only speed 0 to limit memory usage and compilation time.
-  stage: slow
-  # Uncomment the following to run it only when scheduled.
-  # only:
-  #   - schedules
-  script:
-    - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y 
-qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
-    - ./autogen.sh autoconf
-    - ./configure --with-nativecomp
-    - make bootstrap NATIVE_FULL_AOT=1 BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq 
comp-speed 0)"' -j2
-  timeout: 8 hours
-
-build-native-bootstrap-speed1:
-  stage: slow
-  script:
-    - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y 
-qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
-    - ./autogen.sh autoconf
-    - ./configure --with-nativecomp
-    - make bootstrap BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 1)"'
-  timeout: 8 hours
-
-build-native-bootstrap-speed2:
-  stage: slow
-  script:
-    - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y 
-qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
-    - ./autogen.sh autoconf
-    - ./configure --with-nativecomp
-    - make bootstrap
-  timeout: 8 hours
-
 test-gnustep:
   # This tests the GNUstep build process
   stage: platforms
@@ -285,6 +273,45 @@ test-gnustep:
     target: emacs-gnustep
     make_params: install
 
+build-native-bootstrap-speed0:
+  stage: native-comp-images
+  extends: [.job-template, .build-template, .native-comp-template]
+  needs: [prep-image-base]
+  variables:
+    target: emacs-native-comp-speed0
+
+# build-native-bootstrap-speed0:
+#   # Test a full native bootstrap
+#   # Run for now only speed 0 to limit memory usage and compilation time.
+#   stage: native-comp-images
+#   # Uncomment the following to run it only when scheduled.
+#   # only:
+#   #   - schedules
+#   script:
+#     - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y 
-qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
+#     - ./autogen.sh autoconf
+#     - ./configure --with-nativecomp
+#     - make bootstrap NATIVE_FULL_AOT=1 BYTE_COMPILE_EXTRA_FLAGS='--eval 
"(setq comp-speed 0)"' -j2
+#   timeout: 8 hours
+
+# build-native-bootstrap-speed1:
+#   stage: native-comp-images
+#   script:
+#     - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y 
-qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
+#     - ./autogen.sh autoconf
+#     - ./configure --with-nativecomp
+#     - make bootstrap BYTE_COMPILE_EXTRA_FLAGS='--eval "(setq comp-speed 1)"'
+#   timeout: 8 hours
+
+# build-native-bootstrap-speed2:
+#   stage: native-comp-images
+#   script:
+#     - DEBIAN_FRONTEND=noninteractive apt install --no-install-recommends -y 
-qq -o=Dpkg::Use-Pty=0 libgccjit-6-dev
+#     - ./autogen.sh autoconf
+#     - ./configure --with-nativecomp
+#     - make bootstrap
+#   timeout: 8 hours
+
 test-all-inotify:
   # This tests also file monitor libraries inotify and inotifywatch.
   stage: slow
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el 
b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el
new file mode 100644
index 0000000..6997d91
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-alpha.el
@@ -0,0 +1,9 @@
+;;; -*- lexical-binding: t -*-
+
+(require 'bc-test-beta)
+
+(defun bc-test-alpha-f (x)
+  (let ((y nil))
+    (list y (bc-test-beta-f x))))
+
+(provide 'bc-test-alpha)
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el 
b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el
new file mode 100644
index 0000000..9205a13
--- /dev/null
+++ b/test/lisp/emacs-lisp/bytecomp-resources/bc-test-beta.el
@@ -0,0 +1,6 @@
+;;; -*- lexical-binding: t -*-
+
+(defsubst bc-test-beta-f (y)
+  y)
+
+(provide 'bc-test-beta)
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el 
b/test/lisp/emacs-lisp/bytecomp-tests.el
index c9ab3ec..33413f5 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -1312,6 +1312,24 @@ compiled correctly."
                    (funcall f 3))
                  4)))
 
+(declare-function bc-test-alpha-f (ert-resource-file "bc-test-alpha.el"))
+
+(ert-deftest bytecomp-defsubst ()
+  ;; Check that lexical variables don't leak into inlined code.  See
+  ;; https://lists.gnu.org/archive/html/emacs-devel/2021-05/msg01227.html
+
+  ;; First, remove any trace of the functions and package defined:
+  (fmakunbound 'bc-test-alpha-f)
+  (fmakunbound 'bc-test-beta-f)
+  (setq features (delq 'bc-test-beta features))
+  ;; Byte-compile one file that uses a function from another file that isn't
+  ;; compiled.
+  (let ((file (ert-resource-file "bc-test-alpha.el"))
+        (load-path (cons (ert-resource-directory) load-path)))
+    (byte-compile-file file)
+    (load-file (concat file "c"))
+    (should (equal (bc-test-alpha-f 'a) '(nil a)))))
+
 ;; Local Variables:
 ;; no-byte-compile: t
 ;; End:
diff --git a/test/lisp/emacs-lisp/copyright-tests.el 
b/test/lisp/emacs-lisp/copyright-tests.el
index 7deb8b5..6bb6e35 100644
--- a/test/lisp/emacs-lisp/copyright-tests.el
+++ b/test/lisp/emacs-lisp/copyright-tests.el
@@ -37,8 +37,12 @@
      . ";; Copyright (C) 2017, 2019 Free Software Foundation, Inc.")
     (";; Copyright (C) 2017-2018 Free Software Foundation, Inc."
      . ";; Copyright (C) 2017-2019 Free Software Foundation, Inc.")
+    (";; Copyright (C) 2017–2018 Free Software Foundation, Inc."
+     . ";; Copyright (C) 2017–2019 Free Software Foundation, Inc.")
     (";; Copyright (C) 2005-2006, 2015, 2017-2018 Free Software Foundation, 
Inc."
      . ";; Copyright (C) 2005-2006, 2015, 2017-2019 Free Software Foundation, 
Inc.")
+    (";; Copyright (C) 2005–2006, 2015, 2017–2018 Free Software Foundation, 
Inc."
+     . ";; Copyright (C) 2005–2006, 2015, 2017–2019 Free Software Foundation, 
Inc.")
     (";; copyright '18 FSF"
      . ";; copyright '18, '19 FSF")))
 
diff --git a/test/lisp/emacs-lisp/shortdoc-tests.el 
b/test/lisp/emacs-lisp/shortdoc-tests.el
new file mode 100644
index 0000000..050aac3
--- /dev/null
+++ b/test/lisp/emacs-lisp/shortdoc-tests.el
@@ -0,0 +1,45 @@
+;;; shortdoc-tests.el --- tests for shortdoc.el   -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 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/>.
+
+(require 'ert)
+(require 'shortdoc)
+
+(defun shortdoc-tests--tree-contains (tree fun)
+  "Whether TREE contains a call to FUN."
+  (and (proper-list-p tree)
+       (or (eq (car tree) fun)
+           (cl-some (lambda (x) (shortdoc-tests--tree-contains x fun)) tree))))
+
+(ert-deftest shortdoc-examples ()
+  "Check that each example actually contains the corresponding form."
+  (dolist (group shortdoc--groups)
+    (dolist (item group)
+      (when (consp item)
+        (let ((fun (car item))
+              (props (cdr item)))
+          (while props
+            (when (memq (car props) '(:eval :no-eval :no-eval*))
+              (let* ((example (cadr props))
+                     (expr (cond
+                            ((consp example) example)
+                            ((stringp example) (read example)))))
+                (should (shortdoc-tests--tree-contains expr fun))))
+            (setq props (cddr props))))))))
+
+(provide 'shortdoc-tests)
diff --git a/test/lisp/gnus/gnus-util-tests.el 
b/test/lisp/gnus/gnus-util-tests.el
index 959be79..f8d30f6 100644
--- a/test/lisp/gnus/gnus-util-tests.el
+++ b/test/lisp/gnus/gnus-util-tests.el
@@ -132,41 +132,4 @@
   (should (equal '("1") (gnus-setdiff '(2 "1" 2) '(2))))
   (should (equal '("1" "1") (gnus-setdiff '(2 "1" 2 "1") '(2)))))
 
-(ert-deftest gnus-base64-repad ()
-  (should-error (gnus-base64-repad 1)
-                :type 'wrong-type-argument)
-
-  ;; RFC4648 test vectors
-  (should (equal "" (gnus-base64-repad "")))
-  (should (equal "Zg==" (gnus-base64-repad "Zg==")))
-  (should (equal "Zm8=" (gnus-base64-repad "Zm8=")))
-  (should (equal "Zm9v" (gnus-base64-repad "Zm9v")))
-  (should (equal "Zm9vYg==" (gnus-base64-repad "Zm9vYg==")))
-  (should (equal "Zm9vYmE=" (gnus-base64-repad "Zm9vYmE=")))
-  (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9vYmFy")))
-
-  (should (equal "Zm8=" (gnus-base64-repad "Zm8")))
-  (should (equal "Zg==" (gnus-base64-repad "Zg")))
-  (should (equal "Zg==" (gnus-base64-repad "Zg====")))
-
-  (should-error (gnus-base64-repad " ")
-                :type 'error)
-  (should-error (gnus-base64-repad "Zg== ")
-                :type 'error)
-  (should-error (gnus-base64-repad "Z?\x00g==")
-                :type 'error)
-  ;; line-length
-  (should-error (gnus-base64-repad "Zg====" nil 4)
-                :type 'error)
-  ;; reject-newlines
-  (should-error (gnus-base64-repad "Zm9v\r\nYmFy" t)
-                :type 'error)
-  (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9vYmFy" t)))
-  (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9v\r\nYmFy")))
-  (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9v\r\nYmFy\n")))
-  (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9v\r\n YmFy\r\n")))
-  (should (equal "Zm9vYmFy" (gnus-base64-repad "Zm9v \r\n\tYmFy")))
-  (should-error (gnus-base64-repad "Zm9v\r\nYmFy" nil 3)
-                :type 'error))
-
 ;;; gnustest-gnus-util.el ends here
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
index b2fec5c..871417d 100644
--- a/test/lisp/help-tests.el
+++ b/test/lisp/help-tests.el
@@ -110,14 +110,19 @@ C-<tab>           file-cache-minibuffer-complete
 <prior>                switch-to-completions
 <up>           previous-line-or-history-element
 
+M-g            Prefix Command
 M-v            switch-to-completions
 
+M-g ESC                Prefix Command
+
 M-<            minibuffer-beginning-of-buffer
 M-n            next-history-element
 M-p            previous-history-element
 M-r            previous-matching-history-element
 M-s            next-matching-history-element
 
+M-g M-c                switch-to-completions
+
 ")))
 
 (ert-deftest help-tests-substitute-command-keys/keymap-change ()
diff --git a/test/lisp/net/tramp-archive-tests.el 
b/test/lisp/net/tramp-archive-tests.el
index 6a6b56f..773bc8f 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -887,27 +887,35 @@ This tests also `file-executable-p', `file-writable-p' 
and `set-file-modes'."
 
   ;; tramp-archive is neither loaded at Emacs startup, nor when
   ;; loading a file like "/mock::foo" (which loads Tramp).
-  (let ((default-directory (expand-file-name temporary-file-directory))
-       (code
+  (let ((code
         "(progn \
-           (message \"tramp-archive loaded: %%s %%s\" \
-              (featurep 'tramp) (featurep 'tramp-archive)) \
+           (message \"tramp-archive loaded: %%s\" \
+              (featurep 'tramp-archive)) \
            (file-attributes %S \"/\") \
-           (message \"tramp-archive loaded: %%s %%s\" \
-              (featurep 'tramp) (featurep 'tramp-archive)))"))
-    (dolist (file `("/mock::foo" ,(concat tramp-archive-test-archive "foo")))
-      (should
-       (string-match
-       (format
-        "tramp-archive loaded: nil nil[[:ascii:]]+tramp-archive loaded: t %s"
-        (tramp-archive-file-name-p file))
-       (shell-command-to-string
-        (format
-         "%s -batch -Q -L %s --eval %s"
-         (shell-quote-argument
-          (expand-file-name invocation-name invocation-directory))
-         (mapconcat #'shell-quote-argument load-path " -L ")
-         (shell-quote-argument (format code file)))))))))
+           (message \"tramp-archive loaded: %%s\" \
+              (featurep 'tramp-archive)))"))
+    (dolist (default-directory
+              `(,temporary-file-directory
+               ;;  Starting Emacs in a directory which has
+               ;; `tramp-archive-file-name-regexp' syntax is
+               ;; supported only with Emacs > 27.2 (sigh!).
+               ;; (Bug#48476)
+                ,(file-name-as-directory tramp-archive-test-directory)))
+      (dolist (file `("/mock::foo" ,(concat tramp-archive-test-archive "foo")))
+        (should
+         (string-match
+         (format
+          "tramp-archive loaded: %s[[:ascii:]]+tramp-archive loaded: %s"
+          (tramp-archive-file-name-p default-directory)
+          (or (tramp-archive-file-name-p default-directory)
+               (tramp-archive-file-name-p file)))
+         (shell-command-to-string
+          (format
+           "%s -batch -Q -L %s --eval %s"
+           (shell-quote-argument
+            (expand-file-name invocation-name invocation-directory))
+           (mapconcat #'shell-quote-argument load-path " -L ")
+           (shell-quote-argument (format code file))))))))))
 
 (ert-deftest tramp-archive-test45-delay-load ()
   "Check that `tramp-archive' is loaded lazily, only when needed."
diff --git a/test/lisp/progmodes/python-tests.el 
b/test/lisp/progmodes/python-tests.el
index 3e653cb..1af579b 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -5432,6 +5432,30 @@ buffer with overlapping strings."
     (run-python nil nil 'show)
     (should (eq buffer (current-buffer)))))
 
+(ert-deftest python-tests--fill-long-first-line ()
+  (should
+   (equal
+    (with-temp-buffer
+      (insert "def asdf():
+    \"\"\"123 123 123 123 123 123 123 123 123 123 123 123 123 SHOULDBEWRAPPED 
123 123 123 123
+
+    \"\"\"
+    a = 1
+")
+      (python-mode)
+      (goto-char (point-min))
+      (forward-line 1)
+      (end-of-line)
+      (fill-paragraph)
+      (buffer-substring-no-properties (point-min) (point-max)))
+    "def asdf():
+    \"\"\"123 123 123 123 123 123 123 123 123 123 123 123 123
+    SHOULDBEWRAPPED 123 123 123 123
+
+    \"\"\"
+    a = 1
+")))
+
 (provide 'python-tests)
 
 ;; Local Variables:
diff --git a/test/lisp/vc/diff-mode-tests.el b/test/lisp/vc/diff-mode-tests.el
index f4e5c89..5bc4ad6 100644
--- a/test/lisp/vc/diff-mode-tests.el
+++ b/test/lisp/vc/diff-mode-tests.el
@@ -203,6 +203,148 @@ youthfulness
           (kill-buffer buf2)
           (delete-directory temp-dir 'recursive))))))
 
+(ert-deftest diff-mode-test-hunk-text-no-newline ()
+  "Check output of `diff-hunk-text' with no newline at end of file."
+
+  ;; First check unified change/remove/add cases with newline
+  (let ((hunk "\
+@@ -1 +1 @@
+-foo
++bar
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo
+"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar
+")))
+
+  (let ((hunk "\
+@@ -1 +0,0 @@
+-foo
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo
+"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+")))
+
+  (let ((hunk "\
+@@ -0,0 +1 @@
++bar
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar
+")))
+
+  ;; Check unified change/remove cases with no newline in old file
+  (let ((hunk "\
+@@ -1 +1 @@
+-foo
+\\ No newline at end of file
++bar
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar
+")))
+
+  (let ((hunk "\
+@@ -1 +0,0 @@
+-foo
+\\ No newline at end of file
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+")))
+
+  ;; Check unified change/add cases with no newline in new file
+  (let ((hunk "\
+@@ -1 +1 @@
+-foo
++bar
+\\ No newline at end of file
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo
+"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar")))
+
+  (let ((hunk "\
+@@ -0,0 +1 @@
++bar
+\\ No newline at end of file
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar")))
+
+  ;; Check unified change case with no newline in both old/new file
+  (let ((hunk "\
+@@ -1 +1 @@
+-foo
+\\ No newline at end of file
++bar
+\\ No newline at end of file
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar")))
+
+  ;; Check context-after unified change case with no newline in both old/new 
file
+  (let ((hunk "\
+@@ -1,2 +1,2 @@
+-foo
++bar
+ baz
+\\ No newline at end of file
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo
+baz"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar
+baz")))
+
+  (let ((hunk "\
+@@ -1,2 +1,2 @@
+-foo
+-baz
+\\ No newline at end of file
++bar
++baz
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo
+baz"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar
+baz
+")))
+
+  (let ((hunk "\
+@@ -1,2 +1,2 @@
+-foo
+-baz
++bar
++baz
+\\ No newline at end of file
+"))
+    (should (equal (diff-hunk-text hunk nil nil) "\
+foo
+baz
+"))
+    (should (equal (diff-hunk-text hunk t nil) "\
+bar
+baz"))))
+
 (ert-deftest diff-mode-test-font-lock ()
   "Check font-locking of diff hunks."
   ;; See comments in diff-hunk-file-names about nonascii.
diff --git a/test/manual/etags/README b/test/manual/etags/README
new file mode 100644
index 0000000..7bce861
--- /dev/null
+++ b/test/manual/etags/README
@@ -0,0 +1,60 @@
+This directory contains the test suite for the 'etags' and 'ctags'
+programs.
+
+The input files, which include source files in various languages
+supported by the programs, are in the *-src/ directories (e.g., c-src
+for C sources, ada-src for Ada, tex-src for TeX, etc.).
+
+The expected results are slightly different for each of the 7 commands
+(see below) run by the test suite, and are on files ETAGS.good_N
+(where N is between 1 and 6) and CTAGS.good.
+
+To run the tests, say
+
+   make check
+
+in this directory.  This should run the programs 7 times with various
+command line switches, and should not show any differences between the
+produced file ETAGS/CTAGS and the corresponding expected results.  Any
+diffs shown by the 'diff' utility should be examined for potential
+regressions in 'etags' or 'ctags'.
+
+In some cases, diffs should be expected.  These include:
+
+  . adding new input files in the *-src/ directories
+  . routine changes in the existing input files, such as the yearly
+    update of copyright years, spelling changes, etc.
+  . adding new features to etags.c
+
+When the diffs are expected, they should be examined to make sure
+there are no regressions.  To do so, compare the line numbers and byte
+offsets shown in the new ETAGS/CTAGS files against the up-to-date
+input files, and make sure the new values match, whereas the old one
+don't.  Also make sure there no new or missing entries in the
+ETAGS/CTAGS files as compared with the expected results.  (When new
+input files are added, there obviously will be new entries -- these
+should be compared to the input files to verify correctness.)
+
+Once the differences are deemed to be justified, i.e. you decide that
+the new ETAGS/CTAGS file should become the new expected result, you
+should copy the ETAGS/CTAGS files produced by the test run to the
+corresponding "good" files, one by one.  Like this:
+
+  $ make check
+  $ cp ETAGS ETAGS.good_1
+  $ make check
+  $ cp ETAGS ETAGS.good_2
+  $ make check
+  $ cp ETAGS ETAGS.good_3
+  ...
+  $ make check
+  $ cp ETAGS ETAGS.good_6
+  $ make check
+  $ cp CTAGS CTAGS.good
+
+This uses the fact that "make check" will stop after the first
+failure, i.e. after the first time 'diff' reports any diffs, and then
+the ETAGS/CTAGS file from the last invocation is available for
+becoming the new expected-result file.  Alternatively, you can see the
+name of the expected-result file which needs to be updated in the
+output of the 'diff' utility.
diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el
index f2a60bc..dac8f95 100644
--- a/test/src/lread-tests.el
+++ b/test/src/lread-tests.el
@@ -196,4 +196,71 @@ literals (Bug#20852)."
     (should-error (read-event "foo: "))
     (should-error (read-char-exclusive "foo: "))))
 
+(ert-deftest lread-float ()
+  (should (equal (read "13") 13))
+  (should (equal (read "+13") 13))
+  (should (equal (read "-13") -13))
+  (should (equal (read "13.") 13))
+  (should (equal (read "+13.") 13))
+  (should (equal (read "-13.") -13))
+  (should (equal (read "13.25") 13.25))
+  (should (equal (read "+13.25") 13.25))
+  (should (equal (read "-13.25") -13.25))
+  (should (equal (read ".25") 0.25))
+  (should (equal (read "+.25") 0.25))
+  (should (equal (read "-.25") -0.25))
+  (should (equal (read "13e4") 130000.0))
+  (should (equal (read "+13e4") 130000.0))
+  (should (equal (read "-13e4") -130000.0))
+  (should (equal (read "13e+4") 130000.0))
+  (should (equal (read "+13e+4") 130000.0))
+  (should (equal (read "-13e+4") -130000.0))
+  (should (equal (read "625e-4") 0.0625))
+  (should (equal (read "+625e-4") 0.0625))
+  (should (equal (read "-625e-4") -0.0625))
+  (should (equal (read "1.25e2") 125.0))
+  (should (equal (read "+1.25e2") 125.0))
+  (should (equal (read "-1.25e2") -125.0))
+  (should (equal (read "1.25e+2") 125.0))
+  (should (equal (read "+1.25e+2") 125.0))
+  (should (equal (read "-1.25e+2") -125.0))
+  (should (equal (read "1.25e-1") 0.125))
+  (should (equal (read "+1.25e-1") 0.125))
+  (should (equal (read "-1.25e-1") -0.125))
+  (should (equal (read "4.e3") 4000.0))
+  (should (equal (read "+4.e3") 4000.0))
+  (should (equal (read "-4.e3") -4000.0))
+  (should (equal (read "4.e+3") 4000.0))
+  (should (equal (read "+4.e+3") 4000.0))
+  (should (equal (read "-4.e+3") -4000.0))
+  (should (equal (read "5.e-1") 0.5))
+  (should (equal (read "+5.e-1") 0.5))
+  (should (equal (read "-5.e-1") -0.5))
+  (should (equal (read "0") 0))
+  (should (equal (read "+0") 0))
+  (should (equal (read "-0") 0))
+  (should (equal (read "0.") 0))
+  (should (equal (read "+0.") 0))
+  (should (equal (read "-0.") 0))
+  (should (equal (read "0.0") 0.0))
+  (should (equal (read "+0.0") 0.0))
+  (should (equal (read "-0.0") -0.0))
+  (should (equal (read "0e5") 0.0))
+  (should (equal (read "+0e5") 0.0))
+  (should (equal (read "-0e5") -0.0))
+  (should (equal (read "0e-5") 0.0))
+  (should (equal (read "+0e-5") 0.0))
+  (should (equal (read "-0e-5") -0.0))
+  (should (equal (read ".0e-5") 0.0))
+  (should (equal (read "+.0e-5") 0.0))
+  (should (equal (read "-.0e-5") -0.0))
+  (should (equal (read "0.0e-5") 0.0))
+  (should (equal (read "+0.0e-5") 0.0))
+  (should (equal (read "-0.0e-5") -0.0))
+  (should (equal (read "0.e-5") 0.0))
+  (should (equal (read "+0.e-5") 0.0))
+  (should (equal (read "-0.e-5") -0.0))
+  )
+
+
 ;;; lread-tests.el ends here



reply via email to

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