emacs-diffs
[Top][All Lists]
Advanced

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

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


From: Yuuki Harano
Subject: feature/pgtk 492a0ae: Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Date: Sun, 4 Jul 2021 09:47:01 -0400 (EDT)

branch: feature/pgtk
commit 492a0ae5927eda83b65dd08d3e1655a62fc2c43d
Merge: 01b0a90 2f2afa0
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                            |   40 +-
 configure.ac                           |   25 +-
 doc/emacs/back.texi                    |   98 +++
 doc/emacs/book-spine.texi              |   20 +
 doc/emacs/buffers.texi                 |    3 -
 doc/emacs/emacs.texi                   |    2 +-
 doc/emacs/help.texi                    |    9 +-
 doc/emacs/killing.texi                 |   15 +
 doc/emacs/misc.texi                    |    7 +
 doc/emacs/msdos.texi                   |    9 -
 doc/emacs/text.texi                    |    2 +-
 doc/lispref/files.texi                 |   29 +-
 doc/lispref/frames.texi                |    9 +-
 doc/lispref/functions.texi             |   11 +-
 doc/lispref/help.texi                  |    4 +-
 doc/lispref/tips.texi                  |    6 +-
 doc/misc/bovine.texi                   |   25 +-
 doc/misc/erc.texi                      |   72 +-
 doc/misc/gnus-faq.texi                 |    2 +-
 doc/misc/pcl-cvs.texi                  |    2 +-
 doc/misc/rcirc.texi                    |   47 +-
 doc/misc/srecode.texi                  |    2 +-
 doc/misc/trampver.texi                 |    2 +-
 doc/misc/wisent.texi                   |    6 +-
 etc/HELLO                              |    1 +
 etc/NEWS                               |   85 ++-
 etc/NEWS.27                            |   23 +
 etc/emacs-mail.desktop                 |    4 +-
 etc/emacs.desktop                      |    1 +
 etc/emacsclient-mail.desktop           |   19 +
 etc/emacsclient.desktop                |   14 +-
 lisp/allout.el                         |    8 +-
 lisp/apropos.el                        |    7 +-
 lisp/auth-source-pass.el               |   61 +-
 lisp/auth-source.el                    |    3 +-
 lisp/bindings.el                       |   43 +-
 lisp/comint.el                         |   30 +-
 lisp/cus-start.el                      |    1 +
 lisp/cus-theme.el                      |  100 +--
 lisp/desktop.el                        |    5 +-
 lisp/dired-aux.el                      |  127 ++--
 lisp/dired-x.el                        |  107 +--
 lisp/dired.el                          |  148 +++--
 lisp/emacs-lisp/bytecomp.el            |  134 ++--
 lisp/emacs-lisp/cl-extra.el            |   15 +-
 lisp/emacs-lisp/cl-macs.el             |    9 +-
 lisp/emacs-lisp/cl-preloaded.el        |   21 +-
 lisp/emacs-lisp/crm.el                 |    3 +-
 lisp/emacs-lisp/easy-mmode.el          |   18 +-
 lisp/emacs-lisp/ert.el                 |   21 +-
 lisp/emacs-lisp/find-func.el           |   10 +-
 lisp/emacs-lisp/lisp-mnt.el            |   26 +-
 lisp/emacs-lisp/lisp-mode.el           |    2 +-
 lisp/emacs-lisp/package.el             |    3 +-
 lisp/emacs-lisp/shortdoc.el            |    9 +-
 lisp/emacs-lisp/subr-x.el              |    1 +
 lisp/erc/erc-backend.el                |    2 +-
 lisp/erc/erc-networks.el               |   14 +-
 lisp/erc/erc-services.el               |   17 +-
 lisp/erc/erc.el                        |   15 +-
 lisp/eshell/em-dirs.el                 |    5 +-
 lisp/eshell/em-hist.el                 |    5 +-
 lisp/files.el                          |   45 +-
 lisp/gnus/gnus-search.el               |   16 +-
 lisp/gnus/gnus-sum.el                  |   29 +-
 lisp/gnus/message.el                   |   10 +-
 lisp/icomplete.el                      |   23 +-
 lisp/language/ethio-util.el            |   58 +-
 lisp/ldefs-boot.el                     | 1139 +++++++++++++++++++++-----------
 lisp/leim/quail/latin-post.el          |   58 ++
 lisp/leim/quail/latin-pre.el           |   29 +
 lisp/minibuffer.el                     |   37 +-
 lisp/mouse.el                          |   15 +
 lisp/net/dig.el                        |   11 +-
 lisp/net/eudc.el                       |    4 +-
 lisp/net/rcirc.el                      |   52 +-
 lisp/net/tramp-adb.el                  |    3 +-
 lisp/net/tramp-sh.el                   |  119 ++--
 lisp/net/tramp.el                      |   20 +-
 lisp/net/trampver.el                   |    6 +-
 lisp/org/ol-irc.el                     |    6 +-
 lisp/org/org-compat.el                 |    4 +-
 lisp/printing.el                       |   27 +-
 lisp/progmodes/bug-reference.el        |    6 +-
 lisp/progmodes/cc-engine.el            |   33 +-
 lisp/progmodes/cc-langs.el             |    3 +-
 lisp/progmodes/cmacexp.el              |    2 +-
 lisp/progmodes/cperl-mode.el           |    2 +-
 lisp/ps-print.el                       |    5 +-
 lisp/repeat.el                         |   24 +-
 lisp/server.el                         |   12 +-
 lisp/shell.el                          |    3 +-
 lisp/simple.el                         |   77 ++-
 lisp/tab-bar.el                        |   15 +-
 lisp/textmodes/flyspell.el             |   23 +-
 lisp/textmodes/ispell.el               |   28 +-
 lisp/textmodes/tex-mode.el             |    1 +
 lisp/textmodes/text-mode.el            |   10 +-
 lisp/time-stamp.el                     |  241 ++++++-
 lisp/transient.el                      |  102 ++-
 lisp/url/url-util.el                   |    7 +-
 lisp/vc/diff-mode.el                   |   25 +-
 nextstep/Makefile.in                   |   12 +-
 src/Makefile.in                        |    2 +-
 src/callproc.c                         |   61 +-
 src/comp.c                             |   28 +-
 src/emacs.c                            |   16 +-
 src/lread.c                            |    8 +-
 src/minibuf.c                          |    2 +-
 src/nsfont.m                           |   46 +-
 src/nsmenu.m                           |   69 +-
 src/nsterm.h                           |    8 +-
 src/nsterm.m                           |  143 +---
 src/process.c                          |    2 +-
 src/process.h                          |    2 +-
 src/sysdep.c                           |    2 +-
 src/thread.c                           |   17 +
 src/xgselect.c                         |   16 +
 test/README                            |    5 +
 test/infra/gitlab-ci.yml               |    1 +
 test/lisp/auth-source-pass-tests.el    |   24 +-
 test/lisp/emacs-lisp/shortdoc-tests.el |    2 +-
 test/lisp/files-tests.el               |   18 +
 test/lisp/gnus/message-tests.el        |   29 +
 test/lisp/net/tramp-archive-tests.el   |   71 +-
 test/lisp/net/tramp-tests.el           |    5 +-
 test/lisp/time-stamp-tests.el          |  414 +++++++++++-
 127 files changed, 3394 insertions(+), 1503 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 2aba179..24684e5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -100,12 +100,17 @@ FIND_DELETE = @FIND_DELETE@
 
 HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
 
+USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@
+
 # ==================== Where To Install Things ====================
 
 # Location to install Emacs.app under GNUstep / macOS.
 # Later values may use these.
+ns_appdir=@ns_appdir@
 ns_appbindir=@ns_appbindir@
+ns_applibexecdir=@ns_applibexecdir@
 ns_appresdir=@ns_appresdir@
+ns_applibdir=@ns_applibdir@
 # Either yes or no depending on whether this is a relocatable Emacs.app.
 ns_self_contained=@ns_self_contained@
 
@@ -333,14 +338,14 @@ BIN_DESTDIR='$(DESTDIR)${bindir}/'
 ELN_DESTDIR = $(DESTDIR)${libdir}/emacs/${version}/
 else
 BIN_DESTDIR='${ns_appbindir}/'
-ELN_DESTDIR = ${ns_appresdir}/
+ELN_DESTDIR = ${ns_applibdir}/
 endif
 
 gsettings_SCHEMAS = etc/org.gnu.emacs.defaults.gschema.xml
 
 all: ${SUBDIR} info $(gsettings_SCHEMAS:.xml=.valid)
 
-.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 etc-emacsver
+.PHONY: all ${SUBDIR} blessmail epaths-force epaths-force-w32 
epaths-force-ns-self-contained etc-emacsver
 
 # If configure were to just generate emacsver.tex from emacsver.tex.in
 # in the normal way, the timestamp of emacsver.tex would always be
@@ -409,6 +414,17 @@ epaths-force-w32:
          -e "/^.*#/s|@SRC@|$${w32srcdir}|g") &&                \
        ${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h
 
+# A NextStep style app bundle is relocatable, so instead of
+# hard-coding paths try to generate them at run-time.
+#
+# The paths are mostly the same, and the bundle paths are different
+# between macOS and GNUstep, so just replace any references to the app
+# bundle root itself with the relative path.
+epaths-force-ns-self-contained: epaths-force
+       @(sed < src/epaths.h > epaths.h.$$$$            \
+         -e 's;${ns_appdir}/;;') &&                    \
+       ${srcdir}/build-aux/move-if-change epaths.h.$$$$ src/epaths.h
+
 lib-src src: $(NTDIR) lib
 
 src: lib-src
@@ -713,11 +729,15 @@ install-man:
 ## Note: emacs22 does not have all the resolutions.
 EMACS_ICON=emacs
 
+ifeq (${USE_STARTUP_NOTIFICATION},no)
+USE_STARTUP_NOTIFICATION_SED_CMD=-e "/^StartupNotify=true$$/d"
+endif
 install-etc:
        umask 022; ${MKDIR_P} "$(DESTDIR)${desktopdir}"
        tmp=etc/emacs.tmpdesktop; rm -f $${tmp}; \
        sed -e "/^Exec=emacs/ s/emacs/${EMACS_NAME}/" \
          -e "/^Icon=emacs/ s/emacs/${EMACS_NAME}/" \
+         $(USE_STARTUP_NOTIFICATION_SED_CMD) \
          ${srcdir}/etc/emacs.desktop > $${tmp}; \
        ${INSTALL_DATA} $${tmp} 
"$(DESTDIR)${desktopdir}/${EMACS_NAME}.desktop"; \
        rm -f $${tmp}
@@ -725,9 +745,23 @@ install-etc:
        client_name=`echo emacsclient | sed '$(TRANSFORM)'`${EXEEXT}; \
        sed -e "/^Exec=emacsclient/ s|emacsclient|${bindir}/$${client_name}|" \
          -e "/^Icon=emacs/ s/emacs/${EMACS_NAME}/" \
+         $(USE_STARTUP_NOTIFICATION_SED_CMD) \
          ${srcdir}/etc/emacsclient.desktop > $${tmp}; \
        ${INSTALL_DATA} $${tmp} 
"$(DESTDIR)${desktopdir}/$${client_name}.desktop"; \
        rm -f $${tmp}
+       tmp=etc/emacs-mail.tmpdesktop; rm -f $${tmp}; \
+       sed -e "/^Exec=emacs/ s/emacs/${EMACS_NAME}/" \
+         -e "/^Icon=emacs/ s/emacs/${EMACS_NAME}/" \
+         ${srcdir}/etc/emacs-mail.desktop > $${tmp}; \
+       ${INSTALL_DATA} $${tmp} 
"$(DESTDIR)${desktopdir}/${EMACS_NAME}-mail.desktop"; \
+       rm -f $${tmp}
+       tmp=etc/emacsclient-mail.tmpdesktop; rm -f $${tmp}; \
+       client_name=`echo emacsclient | sed '$(TRANSFORM)'`${EXEEXT}; \
+       sed -e "/^Exec=emacsclient/ s|emacsclient|${bindir}/$${client_name}|" \
+         -e "/^Icon=emacs/ s/emacs/${EMACS_NAME}/" \
+         ${srcdir}/etc/emacsclient-mail.desktop > $${tmp}; \
+       ${INSTALL_DATA} $${tmp} 
"$(DESTDIR)${desktopdir}/$${client_name}-mail.desktop"; \
+       rm -f $${tmp}
        umask 022; ${MKDIR_P} "$(DESTDIR)${metainfodir}"
        tmp=etc/emacs.tmpmetainfo; rm -f $${tmp}; \
        sed -e "s/emacs\.desktop/${EMACS_NAME}.desktop/" \
@@ -760,7 +794,7 @@ install-etc:
        done
 
 ### Install native compiled Lisp files.
-install-eln:
+install-eln: lisp
 ifeq ($(HAVE_NATIVE_COMP),yes)
        find native-lisp -type d -exec $(MKDIR_P) "$(ELN_DESTDIR){}" \; ; \
        find native-lisp -type f -exec ${INSTALL_DATA} "{}" "$(ELN_DESTDIR){}" 
\;
diff --git a/configure.ac b/configure.ac
index 88d5cc1..50bbf89 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1898,10 +1898,11 @@ if test "${with_ns}" != no; then
   # so avoid NS_IMPL_COCOA if macuvs.h is absent.
   # Even a headless Emacs can build macuvs.h, so this should let you bootstrap.
   if test "${opsys}" = darwin && test -f "$srcdir/src/macuvs.h"; then
-     lispdirrel=Contents/Resources/lisp
      NS_IMPL_COCOA=yes
      ns_appdir=`pwd`/nextstep/Emacs.app
      ns_appbindir=${ns_appdir}/Contents/MacOS
+     ns_applibexecdir=${ns_appdir}/Contents/MacOS/libexec
+     ns_applibdir=${ns_appdir}/Contents/Frameworks
      ns_appresdir=${ns_appdir}/Contents/Resources
      ns_appsrc=Cocoa/Emacs.base
      ns_fontfile=macfont.o
@@ -1959,6 +1960,8 @@ fail;
   if test $NS_IMPL_GNUSTEP = yes; then
      ns_appdir=`pwd`/nextstep/Emacs.app
      ns_appbindir=${ns_appdir}
+     ns_applibexecdir=${ns_appdir}/libexec
+     ns_applibdir=${ns_appdir}/Frameworks
      ns_appresdir=${ns_appdir}/Resources
      ns_appsrc=GNUstep/Emacs.base
      ns_fontfile=nsfont.o
@@ -2015,12 +2018,13 @@ if test "${HAVE_NS}" = yes; then
   window_system=nextstep
   # set up packaging dirs
   if test "${EN_NS_SELF_CONTAINED}" = yes; then
+     AC_DEFINE(NS_SELF_CONTAINED, 1, [Build an NS bundled app])
      ns_self_contained=yes
      prefix=${ns_appresdir}
      exec_prefix=${ns_appbindir}
      dnl This one isn't really used, only archlibdir is.
-     libexecdir="\${ns_appbindir}/libexec"
-     archlibdir="\${ns_appbindir}/libexec"
+     libexecdir="\${ns_applibexecdir}"
+     archlibdir="\${ns_applibexecdir}"
      etcdocdir="\${ns_appresdir}/etc"
      etcdir="\${ns_appresdir}/etc"
      dnl FIXME maybe set datarootdir instead.
@@ -2028,7 +2032,8 @@ if test "${HAVE_NS}" = yes; then
      infodir="\${ns_appresdir}/info"
      mandir="\${ns_appresdir}/man"
      lispdir="\${ns_appresdir}/lisp"
-     test "$locallisppathset" = no && locallisppath=""
+     lispdirrel="\${ns_appresdir}/lisp"
+     test "$locallisppathset" = no && 
locallisppath="\${ns_appresdir}/site-lisp"
      INSTALL_ARCH_INDEP_EXTRA=
   fi
 
@@ -2923,6 +2928,11 @@ fi
 AC_SUBST(SETTINGS_CFLAGS)
 AC_SUBST(SETTINGS_LIBS)
 
+USE_STARTUP_NOTIFICATION=no
+if test "${HAVE_GTK}" = "yes"; then
+    USE_STARTUP_NOTIFICATION=yes
+fi
+AC_SUBST(USE_STARTUP_NOTIFICATION)
 
 dnl SELinux is available for GNU/Linux only.
 HAVE_LIBSELINUX=no
@@ -5485,6 +5495,8 @@ AC_SUBST(CFLAGS)
 AC_SUBST(X_TOOLKIT_TYPE)
 AC_SUBST(ns_appdir)
 AC_SUBST(ns_appbindir)
+AC_SUBST(ns_applibexecdir)
+AC_SUBST(ns_applibdir)
 AC_SUBST(ns_appresdir)
 AC_SUBST(ns_appsrc)
 AC_SUBST(GNU_OBJC_CFLAGS)
@@ -6088,10 +6100,13 @@ dnl the use of force in the 'epaths-force' rule in 
Makefile.in.
 AC_CONFIG_COMMANDS([src/epaths.h], [
 if test "${opsys}" = "mingw32"; then
   ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force-w32
+elif test "$HAVE_NS" = "yes" && test "$EN_NS_SELF_CONTAINED" = "yes"; then
+  ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile 
epaths-force-ns-self-contained
 else
   ${MAKE-make} MAKEFILE_NAME=do-not-make-Makefile epaths-force
 fi || AC_MSG_ERROR(['src/epaths.h' could not be made.])
-], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys"])
+], [GCC="$GCC" CPPFLAGS="$CPPFLAGS" opsys="$opsys" HAVE_NS="$HAVE_NS"
+    EN_NS_SELF_CONTAINED="$EN_NS_SELF_CONTAINED"])
 
 dnl NB we have to cheat and use the ac_... version because abs_top_srcdir
 dnl is not yet set, sigh.  Or we could use ../$srcdir/src/.gdbinit,
diff --git a/doc/emacs/back.texi b/doc/emacs/back.texi
new file mode 100644
index 0000000..e1a2a04
--- /dev/null
+++ b/doc/emacs/back.texi
@@ -0,0 +1,98 @@
+\input texinfo  @c -*-texinfo-*-
+@c This is part of the Emacs manual.
+@c Copyright (C) 1985--1987, 1993--1995, 1997, 2001--2021 Free Software
+@c Foundation, Inc.
+@c See file emacs.texi for copying conditions.
+@c
+@c %**start of header
+@setfilename back-cover
+@settitle GNU Emacs Manual
+@include docstyle.texi
+@c %**end of header
+.
+@sp 7
+@center @titlefont {GNU Emacs Manual}
+@sp 1
+
+@quotation
+GNU Emacs is much more than a text editor; over the years, it has
+expanded to become an entire workflow environment, impressing
+programmers with its integrated debugging and project-management
+features.  It is also a multi-lingual word processor, can handle all
+your email and Usenet news needs, display web pages, and even has a
+diary and a calendar for your appointments!
+
+And when you tire of all the work you can accomplish with it, Emacs
+contains games to play.
+
+@strong{Features include:}
+
+@itemize @bullet
+@item
+Special editing modes for @strong{27 programing languages}, including C,
+C@t{++}, Fortran, Java, JavaScript, Lisp, Objective C, Pascal, Perl,
+and Scheme.
+
+@item
+Special @strong{scripting language modes} for Bash, other common shells,
+and creating Makefiles for GNU/Linux, UNIX, Windows/DOS, and VMS
+systems.
+
+@item
+Support for typing and displaying in @strong{60 non-English languages},
+including Arabic, Chinese, Czech, Hebrew, Hindi, Japanese, Korean,
+Russian, Vietnamese, and all Western European languages.
+
+@item
+The ability to:
+
+@itemize @minus
+@item
+Create @strong{PostScript output} from plain-text files (special editing
+modes for @LaTeX{} and @TeX{} are included).
+
+@item
+@strong{Compile} and @strong{debug} from inside Emacs.
+
+@item
+Maintain program @strong{ChangeLogs}.
+
+@item
+Flag, move, and delete files and sub-directories recursively
+(@strong{directory navigation}).
+
+@item
+Run @strong{shell commands} from inside Emacs, or even use Emacs itself
+as a shell (Eshell).
+
+@item
+Enjoy the use of extensive @strong{merge} and @strong{diff} functions.
+
+@item
+Take advantage of built-in support for many @strong{version control}
+systems, including Git, Mercurial, Bazaar, Subversion, and CVS.
+
+@item
+And much more!
+@end itemize
+@end itemize
+
+Emacs comes with an introductory online tutorial available in many
+languages.  This book picks up where that tutorial ends.  It explains
+the full range of Emacs's power and contains reference material useful
+to expert users.
+
+Appendices are included, with specific material about X and GTK
+resources, and with details for users of Macintosh and Microsoft OS.
+
+@strong{About the Author:}
+
+Richard M.@: Stallman developed the first Emacs in 1975 and wrote GNU
+Emacs in 1984/85.  He has received the ACM Grace Hopper Award, a
+MacArthur Foundation fellowship, the Electronic Frontier Foundation's
+Pioneer award, and the Takeda Award for Social/Economic Betterment, as
+well as several honorary doctorates.
+@end quotation
+
+@hfil
+@bye
diff --git a/doc/emacs/book-spine.texi b/doc/emacs/book-spine.texi
new file mode 100644
index 0000000..84a0168
--- /dev/null
+++ b/doc/emacs/book-spine.texi
@@ -0,0 +1,20 @@
+\input texinfo  @c -*-texinfo-*-
+@c %**start of header
+@setfilename book-spine
+@settitle book-spine
+@include docstyle.texi
+@c %**end of header
+
+@include emacsver.texi
+
+@c need dot in text so first space command works!
+.
+@sp 7
+
+@center @titlefont{GNU Emacs Manual}
+@sp 5
+@center @value{EDITION} Edition, for Emacs Version @value{EMACSVER}
+@sp 5
+
+@center by Richard M.@: Stallman
+@bye
diff --git a/doc/emacs/buffers.texi b/doc/emacs/buffers.texi
index bec7f37..c4e5bc3 100644
--- a/doc/emacs/buffers.texi
+++ b/doc/emacs/buffers.texi
@@ -586,9 +586,6 @@ every @code{auto-revert-interval} seconds if you enable 
Auto Revert
 mode in this buffer, as long as it is not marked modified.  Global
 Auto Revert mode applies to the @file{*Buffer List*} buffer only if
 @code{global-auto-revert-non-file-buffers} is non-@code{nil}.
-@iftex
-@inforef{Auto Reverting the Buffer Menu,, emacs-xtra}, for details.
-@end iftex
 @ifnottex
 @xref{Auto Reverting the Buffer Menu, global-auto-revert-non-file-buffers}, 
for details.
 @end ifnottex
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index 9f64456..c895b01 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -92,7 +92,7 @@ developing GNU and promoting software freedom.''
 Published by the Free Software Foundation @*
 51 Franklin Street, Fifth Floor @*
 Boston, MA 02110-1301 USA @*
-ISBN 978-0-9831592-5-4
+ISBN 978-0-9831592-8-5
 
 @sp 2
 Cover art by Etienne Suvasa; cover design by Matt Lee.
diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index f144fd2..0caab68 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -629,13 +629,14 @@ Emacs Lisp Reference Manual}).
 
 @findex describe-prefix-bindings
   You can get a list of subcommands for a particular prefix key by
-typing @kbd{C-h}, @kbd{?}, or @key{F1}
+typing @kbd{C-h}, @kbd{?}, or @key{f1}
 (@code{describe-prefix-bindings}) after the prefix key.  (There are a
 few prefix keys for which not all of these keys work---those that
 provide their own bindings for that key.  One of these prefix keys
-is @key{ESC}, because @kbd{@key{ESC} C-h} is actually @kbd{C-M-h},
-which marks a defun.  However, @w{@kbd{@key{ESC} @key{F1}}} and
-@w{@kbd{@key{ESC} ?}} work fine.)
+is @key{ESC}, because @kbd{@key{ESC} C-h} and @kbd{@key{ESC} ?} are
+actually @kbd{C-M-h} (@code{mark-defun}) and @kbd{M-?}
+(@code{xref-find-references}), respectively.  However,
+@w{@kbd{@key{ESC} @key{f1}}} works fine.)
 
 @findex describe-keymap
 Finally, @kbd{M-x describe-keymap} prompts for the name of a keymap,
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 4291afe..6e4fd77 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -269,6 +269,21 @@ happens.  But if you set the variable 
@code{kill-read-only-ok} to a
 non-@code{nil} value, they just print a message in the echo area to
 explain why the text has not been erased.
 
+@vindex kill-transform-function
+  Before saving the kill to the kill ring, you can transform the
+string using @code{kill-transform-function}.  It's called with the
+string to be killed, and it should return the string you want to be
+saved.  It can also return @code{nil}, in which case the string won't
+be saved to the kill ring.  For instance, if you never want to save
+a pure white space string to the kill ring, you can say:
+
+@lisp
+(setq kill-transform-function
+      (lambda (string)
+        (and (not (string-blank-p string))
+             string)))
+@end lisp
+
 @vindex kill-do-not-save-duplicates
   If you change the variable @code{kill-do-not-save-duplicates} to a
 non-@code{nil} value, identical subsequent kills yield a single
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 027133c..3c11a39 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -1757,6 +1757,13 @@ expression @code{(+ 1 2)} on the @samp{foo} server, and 
returns
 @code{3}.  (If there is no server with that name, an error is
 signaled.)  Currently, this feature is mainly useful for developers.
 
+  If your operating system’s desktop environment is
+@url{https://www.freedesktop.org/wiki/Specifications/,,freedesktop.org-compatible}
+(which is true of most GNU/Linux and other recent Unix-like GUIs), you
+may use the @samp{Emacs (Client)} menu entry to connect to an Emacs
+server with @command{emacsclient}.  The daemon starts if not
+already running.
+
 @menu
 * TCP Emacs server::     Listening to a TCP socket.
 * Invoking emacsclient:: Connecting to the Emacs server.
diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi
index 4b58f6a..33d389a 100644
--- a/doc/emacs/msdos.texi
+++ b/doc/emacs/msdos.texi
@@ -549,10 +549,6 @@ meanings by enabling CUA Mode (@pxref{CUA Bindings}).  
Another
 optional feature which will make Emacs behave like other Windows
 applications is Delete Selection mode (@pxref{Using Region}).
 
-@iftex
-@inforef{Windows Keyboard, , emacs}, for information about additional
-Windows-specific variables in this category.
-@end iftex
 @ifnottex
 @vindex w32-alt-is-meta
 @cindex @code{Alt} key (MS-Windows)
@@ -1176,11 +1172,6 @@ the default when such software is detected when running 
Emacs.
 When this variable is non-@code{nil}, other variables affecting the
 cursor display have no effect.
 
-@iftex
-@inforef{Windows Misc, , emacs}, for information about additional
-Windows-specific variables in this category.
-@end iftex
-
 @ifnottex
 @vindex w32-grab-focus-on-raise
 @cindex frame focus policy, MS-Windows
diff --git a/doc/emacs/text.texi b/doc/emacs/text.texi
index f2fe248..c9c4be3 100644
--- a/doc/emacs/text.texi
+++ b/doc/emacs/text.texi
@@ -61,7 +61,7 @@ use Picture mode, a special major mode for editing such 
pictures.
 @cindex autotyping
 @cindex automatic typing
   The automatic typing features may be useful when writing text.
-@inforef{Top,The Autotype Manual,autotype}.
+@xref{Top, Autotyping, The Autotype Manual, autotype}.
 @end ifinfo
 
 @menu
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index 2033177..5238597 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -718,7 +718,7 @@ Emacs can then detect the first attempt to modify a buffer 
visiting a
 file that is locked by another Emacs job, and ask the user what to do.
 The file lock is really a file, a symbolic link with a special name,
 stored in the same directory as the file you are editing.  The name is
-constructed by prepending @file{.#} to the filename of the buffer.
+constructed by prepending @file{.#} to the file name of the buffer.
 The target of the symbolic link will be of the form
 @code{@var{user}@@@var{host}.@var{pid}:@var{boot}}, where @var{user}
 is replaced with the current username (from @code{user-login-name}),
@@ -1932,7 +1932,7 @@ is a symbolic link and @var{flag} is @code{nofollow}.
 
 @defun set-file-extended-attributes filename attribute-alist
 This function sets the Emacs-recognized extended file attributes for
-@code{filename}.  The second argument @var{attribute-alist} should be
+@var{filename}.  The second argument @var{attribute-alist} should be
 an alist of the same form returned by @code{file-extended-attributes}.
 The return value is @code{t} if the attributes are successfully set,
 otherwise it is @code{nil}.
@@ -2129,6 +2129,25 @@ the period that delimits the extension, and if 
@var{filename} has no
 extension, the value is @code{""}.
 @end defun
 
+@defun file-name-with-extension filename extension
+This function returns @var{filename} with its extension set to
+@var{extension}.  A single leading dot in the @var{extension} will be
+stripped if there is one.  For example:
+
+@example
+(file-name-with-extension "file" "el")
+     @result{} "file.el"
+(file-name-with-extension "file" ".el")
+     @result{} "file.el"
+(file-name-with-extension "file.c" "el")
+     @result{} "file.el"
+@end example
+
+Note that this function will error if @var{filename} or
+@var{extension} are empty, or if the @var{filename} is shaped like a
+directory (i.e., if @code{directory-name-p} returns non-@code{nil}).
+@end defun
+
 @defun file-name-sans-extension filename
 This function returns @var{filename} minus its extension, if any.  The
 version/backup part, if present, is only removed if the file has an
@@ -2415,7 +2434,7 @@ might begin with a literal @samp{~}, you can use 
@code{(concat
 (file-name-as-directory directory) filename)} instead of
 @code{(expand-file-name filename directory)}.
 
-Filenames containing @samp{.} or @samp{..} are simplified to their
+File names containing @samp{.} or @samp{..} are simplified to their
 canonical form:
 
 @example
@@ -3457,11 +3476,11 @@ identifies the remote system.
 
 This identifier string can include a host name and a user name, as
 well as characters designating the method used to access the remote
-system.  For example, the remote identifier string for the filename
+system.  For example, the remote identifier string for the file name
 @code{/sudo::/some/file} is @code{/sudo:root@@localhost:}.
 
 If @code{file-remote-p} returns the same identifier for two different
-filenames, that means they are stored on the same file system and can
+file names, that means they are stored on the same file system and can
 be accessed locally with respect to each other.  This means, for
 example, that it is possible to start a remote process accessing both
 files at the same time.  Implementers of file name handlers need to
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index a9d20c5..25706be 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -2023,8 +2023,8 @@ the @sc{cdr} of the cell is either @code{t} or 
@code{top-only}.
 
 The parameters described below provide support for resizing a frame by
 dragging its internal borders with the mouse.  They also allow moving a
-frame with the mouse by dragging the header line of its topmost or the
-mode line of its bottommost window.
+frame with the mouse by dragging the header or tab line of its topmost
+or the mode line of its bottommost window.
 
 These parameters are mostly useful for child frames (@pxref{Child
 Frames}) that come without window manager decorations.  If necessary,
@@ -2041,6 +2041,11 @@ borders, if present, with the mouse.
 If non-@code{nil}, the frame can be moved with the mouse by dragging the
 header line of its topmost window.
 
+@vindex drag-with-tab-line@r{, a frame parameter}
+@item drag-with-tab-line
+If non-@code{nil}, the frame can be moved with the mouse by dragging the
+tab line of its topmost window.
+
 @vindex drag-with-mode-line@r{, a frame parameter}
 @item drag-with-mode-line
 If non-@code{nil}, the frame can be moved with the mouse by dragging the
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index 64883bf..77d1465 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -2421,11 +2421,12 @@ opposed to an unspecified one).
 @cindex safety of functions
 
 Some major modes, such as SES, call functions that are stored in user
-files.  (@inforef{Top, ,ses}, for more information on SES@.)  User
-files sometimes have poor pedigrees---you can get a spreadsheet from
-someone you've just met, or you can get one through email from someone
-you've never met.  So it is risky to call a function whose source code
-is stored in a user file until you have determined that it is safe.
+files.  (@xref{Top, Simple Emacs Spreadsheet,,ses}, for more
+information on SES@.)  User files sometimes have poor pedigrees---you
+can get a spreadsheet from someone you've just met, or you can get one
+through email from someone you've never met.  So it is risky to call a
+function whose source code is stored in a user file until you have
+determined that it is safe.
 
 @defun unsafep form &optional unsafep-vars
 Returns @code{nil} if @var{form} is a @dfn{safe} Lisp expression, or
diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi
index dbbc34f..a788852 100644
--- a/doc/lispref/help.texi
+++ b/doc/lispref/help.texi
@@ -818,7 +818,7 @@ summaries of using those functions.  The optional argument
 @var{functions} is a list whose elements are of the form:
 
 @lisp
-(@var{func} @var{keyword} @var{val} @dots{})
+(@var{func} [@var{keyword} @var{val}]@dots{})
 @end lisp
 
 The following keywords are recognized:
@@ -914,7 +914,7 @@ eg. @click{} t
 @itemx :eg-result-string
 These two are the same as @code{:result} and @code{:eg-result},
 respectively, but are inserted as is.  This is useful when the result
-is unreadable or should be on a particular form:
+is unreadable or should be of a particular form:
 
 @example
 :no-eval (find-file "/tmp/foo")
diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi
index 36c68ee..54cafff 100644
--- a/doc/lispref/tips.texi
+++ b/doc/lispref/tips.texi
@@ -1034,7 +1034,7 @@ the conventional possibilities for @var{header-name}:
 
 @table @samp
 @item Author
-This line states the name and email address of at least the principal
+This header states the name and email address of at least the principal
 author of the library.  If there are multiple authors, list them on
 continuation lines led by @code{;;} and a tab or at least two spaces.
 We recommend including a contact email address, of the form
@@ -1053,8 +1053,8 @@ This header has the same format as the Author header.  It 
lists the
 person(s) who currently maintain(s) the file (respond to bug reports,
 etc.).
 
-If there is no maintainer line, the person(s) in the Author field
-is/are presumed to be the maintainers.  Some files in Emacs use
+If there is no Maintainer header, the person(s) in the Author header
+is/are presumed to be the maintainer(s).  Some files in Emacs use
 @samp{emacs-devel@@gnu.org} for the maintainer, which means the author is
 no longer responsible for the file, and that it is maintained as part
 of Emacs.
diff --git a/doc/misc/bovine.texi b/doc/misc/bovine.texi
index 780f0ad..9bfb117 100644
--- a/doc/misc/bovine.texi
+++ b/doc/misc/bovine.texi
@@ -78,13 +78,13 @@ The @dfn{bovine} parser is the original @semantic{} parser, 
and is an
 implementation of an @acronym{LL} parser.  It is good for simple
 languages.  It has many conveniences making grammar writing easy.  The
 conveniences make it less powerful than a Bison-like @acronym{LALR}
-parser.  For more information, @inforef{Top, The Wisent Parser Manual,
+parser.  For more information, @pxref{Top,, Wisent Parser Development,
 wisent}.
 
 Bovine @acronym{LL} grammars are stored in files with a @file{.by}
 extension.  When compiled, the contents is converted into a file of
 the form @file{NAME-by.el}.  This, in turn is byte compiled.
-@inforef{top, Grammar Framework Manual, grammar-fw}.
+@xref{top,, Grammar Framework Manual, grammar-fw}.
 
 @ifnottex
 @insertcopying
@@ -105,7 +105,8 @@ the form @file{NAME-by.el}.  This, in turn is byte compiled.
 In Bison, one and only one nonterminal is designated as the ``start''
 symbol.  In @semantic{}, one or more nonterminals can be designated as
 the ``start'' symbol.  They are declared following the @code{%start}
-keyword separated by spaces.  @inforef{start Decl, ,grammar-fw}.
+keyword separated by spaces.  @xref{start Decl,, Grammar Framework
+Manual, grammar-fw}.
 
 If no @code{%start} keyword is used in a grammar, then the very first
 is used.  Internally the first start nonterminal is targeted by the
@@ -115,7 +116,8 @@ parser harness.
 To find locally defined variables, the local context handler needs to
 parse the body of functional code.  The @code{scopestart} declaration
 specifies the name of a nonterminal used as the goal to parse a local
-context, @inforef{scopestart Decl, ,grammar-fw}.  Internally the
+context, @pxref{scopestart Decl,, Grammar Framework Manual,
+grammar-fw}.  Internally the
 scopestart nonterminal is targeted by the reserved symbol
 @code{bovine-inner-scope}, so it can be found by the parser harness.
 
@@ -124,7 +126,7 @@ scopestart nonterminal is targeted by the reserved symbol
 
 The rules are what allow the compiler to create tags from a language
 file.  Once the setup is done in the prologue, you can start writing
-rules.  @inforef{Grammar Rules, ,grammar-fw}.
+rules.  @xref{Grammar Rules,, Grammar Framework Manual, grammar-fw}.
 
 @example
 @var{result} : @var{components1} @var{optional-semantic-action1})
@@ -146,8 +148,8 @@ A particular @var{result} written into your grammar becomes
 the parser's goal.  It is designated by a @code{%start} statement
 (@pxref{Starting Rules}).  The value returned by the associated
 @var{optional-semantic-action} is the parser's result.  It should be
-a tree of @semantic{} @dfn{tags}, @inforef{Semantic Tags, ,
-semantic-appdev}.
+a tree of @semantic{} @dfn{tags}, @pxref{Semantic Tags,, Semantic
+Application Development, semantic-appdev}.
 
 @var{components} is made up of symbols.  A symbol such as @code{FOO}
 means that a syntactic token of class @code{FOO} must be matched.
@@ -170,8 +172,9 @@ For instance:
 @end example
 
 Means that @code{FOO} is a reserved language keyword, matched as such
-by looking up into a keyword table, @inforef{keyword Decl,
-,grammar-fw}.  This is because @code{"foo"} will be converted to
+by looking up into a keyword table, @pxref{keyword Decl,, Grammar
+Framework Manual, grammar-fw}.  This is because @code{"foo"} will be
+converted to
 @code{FOO} in the lexical analysis stage.  Thus the symbol @code{FOO}
 won't be available any other way.
 
@@ -383,8 +386,8 @@ Is an optional set of labeled values such as 
@code{:constant-flag t :parent
 Create a tag with @var{name} of respectively the class
 @code{variable}, @code{function}, @code{type}, @code{include},
 @code{package}, and @code{code}.
-See @inforef{Creating Tags, , semantic-appdev} for the lisp
-functions these translate into.
+See @ref{Creating Tags,, Semantic Application Development,
+semantic-appdev}, for the lisp functions these translate into.
 @end table
 
 If the symbol @code{%quotemode backquote} is specified, then use
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index 77a19a4..10ced67 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -131,21 +131,30 @@ customize-variable @key{RET} erc-modules @key{RET}}.
 @node Sample Session
 @section Sample Session
 
-This is an example ERC session which shows how to connect to the #emacs
-channel on Freenode.  Another IRC channel on Freenode that may be of
-interest is #erc, which is a channel where ERC users and developers hang
-out.
+This is an example ERC session which shows how to connect to the
+#emacs channel on Libera.Chat.  Another IRC channel on Libera.Chat
+that may be of interest is #erc, which is a channel where ERC users
+and developers hang out.  These channels used to live on the Freenode
+IRC network until June 2021, when they---along with the official IRC
+channels of the GNU Project, the Free Software Foundation, and many
+other free software communities---relocated to the Libera.Chat network
+in the aftermath of changes in governance and policies of Freenode in
+May and June 2021.  GNU and FSF's announcements about this are at
+@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html},
+@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html},
+and
+@uref{https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html}.
 
 @itemize @bullet
 
-@item Connect to Freenode
+@item Connect to Libera.Chat
 
-Run @kbd{M-x erc}.  Use ``chat.freenode.net'' as the IRC server,
-``6667'' as the port, and choose a nickname.
+Run @kbd{M-x erc}.  Use ``irc.libera.chat as the IRC server, ``6667''
+as the port, and choose a nickname.
 
 @item Get used to the interface
 
-Switch to the ``chat.freenode.net:6667'' buffer, if you're not already
+Switch to the ``irc.libera.chat:6667'' buffer, if you're not already
 there.  You will see first some messages about checking for ident, and
 then a bunch of other messages that describe the current IRC server.
 
@@ -158,13 +167,13 @@ background.  If the latter, switch to the ``#emacs'' 
buffer.  You will
 see the channel topic and a list of the people who are currently on the
 channel.
 
-@item Register your nickname with Freenode
+@item Register your nickname with Libera.Chat
 
 If you would like to be able to talk with people privately on the
-Freenode network, you will have to ``register'' your nickname.  To do
-so, switch to the ``chat.freenode.net:6667'' buffer and type ``/msg
-NickServ register <password>'', replacing ``<password>'' with your
-desired password.  It should tell you that the operation was
+Libera.Chat network, you will have to ``register'' your nickname.
+To do so, switch to the ``irc.libera.chat:6667'' buffer and type
+``/msg NickServ register <password>'', replacing ``<password>'' with
+your desired password.  It should tell you that the operation was
 successful.
 
 @item Talk to people in the channel
@@ -518,7 +527,7 @@ That is, if called with the following arguments, 
@var{server} and
 for the values of the other parameters.
 
 @example
-(erc :server "chat.freenode.net" :full-name "J. Random Hacker")
+(erc :server "irc.libera.chat" :full-name "J. Random Hacker")
 @end example
 @end defun
 
@@ -545,7 +554,7 @@ for the values of the other parameters, and 
@code{client-certificate}
 will be @code{nil}.
 
 @example
-(erc-tls :server "chat.freenode.net" :full-name "J. Random Hacker")
+(erc-tls :server "irc.libera.chat" :full-name "J. Random Hacker")
 @end example
 
 To use a certificate with @code{erc-tls}, specify the optional
@@ -563,21 +572,21 @@ various IRC networks.
 Examples of use:
 
 @example
-(erc-tls :server "chat.freenode.net" :port 6697
+(erc-tls :server "irc.libera.chat" :port 6697
          :client-certificate
          '("/home/bandali/my-cert.key"
            "/home/bandali/my-cert.crt"))
 @end example
 
 @example
-(erc-tls :server "chat.freenode.net" :port 6697
+(erc-tls :server "irc.libera.chat" :port 6697
          :client-certificate
-         `(,(expand-file-name "~/cert-freenode.key")
-           ,(expand-file-name "~/cert-freenode.crt")))
+         `(,(expand-file-name "~/cert-libera.key")
+           ,(expand-file-name "~/cert-libera.crt")))
 @end example
 
 @example
-(erc-tls :server "chat.freenode.net" :port 6697
+(erc-tls :server "irc.libera.chat" :port 6697
          :client-certificate t)
 @end example
 
@@ -586,7 +595,7 @@ line like the following to your authinfo file
 (e.g. @file{~/.authinfo.gpg}):
 
 @example
-machine chat.freenode.net key /home/bandali/my-cert.key cert 
/home/bandali/my-cert.crt
+machine irc.libera.chat key /home/bandali/my-cert.key cert 
/home/bandali/my-cert.crt
 @end example
 
 @xref{Help for users,,,auth, Emacs auth-source Library}, for more on the
@@ -762,11 +771,10 @@ stuff, to the current ERC buffer."
     (erc-send-message
      (concat "@{Uptime@} [" uname-output "]"))))
 
-;; This causes ERC to connect to the Freenode network upon hitting
+;; This causes ERC to connect to the Libera.Chat network upon hitting
 ;; C-c e f.  Replace MYNICK with your IRC nick.
 (global-set-key "\C-cef" (lambda () (interactive)
-                           (erc :server "chat.freenode.net"
-                                :port "6667"
+                           (erc :server "irc.libera.chat" :port "6667"
                                 :nick "MYNICK")))
 
 ;; This causes ERC to connect to the IRC server on your own machine (if
@@ -786,13 +794,15 @@ stuff, to the current ERC buffer."
 
 ;;; Options
 
-;; Join the #emacs and #erc channels whenever connecting to Freenode.
-(setq erc-autojoin-channels-alist '(("freenode.net" "#emacs" "#erc")))
+;; Join the #emacs and #erc channels whenever connecting to
+;; Libera.Chat.
+(setq erc-autojoin-channels-alist
+      '(("Libera.Chat" "#emacs" "#erc")))
 
 ;; Rename server buffers to reflect the current network name instead
-;; of SERVER:PORT (e.g., "freenode" instead of "chat.freenode.net:6667").
-;; This is useful when using a bouncer like ZNC where you have multiple
-;; connections to the same server.
+;; of SERVER:PORT (e.g., "Libera.Chat" instead of
+;; "irc.libera.chat:6667").  This is useful when using a bouncer like
+;; ZNC where you have multiple connections to the same server.
 (setq erc-rename-buffers t)
 
 ;; Interpret mIRC-style color commands in IRC chats
@@ -832,7 +842,7 @@ If non, @code{nil}, this is a list of IRC networks and 
message types
 to hide, e.g.:
 
 @example
-(setq erc-network-hide-list (("freenode" "JOIN" "PART" "QUIT")
+(setq erc-network-hide-list (("Libera.Chat" "JOIN" "PART" "QUIT")
 ("OFTC" "JOIN" "PART""))
 @end example
 @end defopt
@@ -881,7 +891,7 @@ You can ask questions about using ERC on the Emacs mailing 
list,
 @uref{https://lists.gnu.org/mailman/listinfo/help-gnu-emacs}.
 
 @item
-You can visit the IRC Freenode channel @samp{#emacs}. Many of the
+You can visit the IRC Libera.Chat channel @samp{#emacs}.  Many of the
 contributors are frequently around and willing to answer your
 questions.
 
diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi
index d3db940..28bee11 100644
--- a/doc/misc/gnus-faq.texi
+++ b/doc/misc/gnus-faq.texi
@@ -2138,7 +2138,7 @@ I need real-time help, where to find it?
 
 @subsubheading Answer
 
-Point your IRC client to chat.freenode.net, channel #gnus.
+Point your IRC client to irc.libera.chat, channel #gnus.
 
 @node FAQ 9 - Tuning Gnus
 @subsection Tuning Gnus
diff --git a/doc/misc/pcl-cvs.texi b/doc/misc/pcl-cvs.texi
index 0d4f976..4ba067f 100644
--- a/doc/misc/pcl-cvs.texi
+++ b/doc/misc/pcl-cvs.texi
@@ -839,7 +839,7 @@ files.
 @item f
 Find the file that the cursor points to (@code{cvs-mode-find-file}).  If
 the cursor points to a directory, run @code{dired} on that directory;
-@inforef{Dired, , emacs}.
+@pxref{Dired, Emacs Manual, , emacs}.
 
 @item o
 Like @kbd{f}, but use another window
diff --git a/doc/misc/rcirc.texi b/doc/misc/rcirc.texi
index ff8133b..ae3a3b1 100644
--- a/doc/misc/rcirc.texi
+++ b/doc/misc/rcirc.texi
@@ -124,10 +124,11 @@ server in a network, and servers relay messages from one 
to the next.
 Here's a typical example:
 
 @cindex redirection to random servers
-When you connect to the Freenode network
-(@code{http://freenode.net/}), you point your IRC client at the
-server @code{chat.freenode.net}.  That server will redirect your client
-to a random server on the network, such as @code{zelazny.freenode.net}.
+When you connect to the Libera.Chat network
+(@code{https://libera.chat}), you point your IRC client at the
+server @code{irc.libera.chat}.  That server will redirect your client
+to a random server on the network, such as
+@code{zirconium.libera.chat}.
 
 @cindex channel name
 @cindex # starts a channel name
@@ -171,15 +172,23 @@ using a different nick.  This will prompt you for four 
things:
 
 @table @asis
 @cindex server, connecting
-@cindex Freenode network
+@cindex Libera.Chat network
 @item IRC Server
 What server do you want to connect to? All the servers in a particular
-network are equivalent.  Some networks use a round-robin system where a
-single server redirects new connections to a random server in the
-network.  @code{chat.freenode.net} is such a server for the Freenode
-network.  Freenode provides the network ``for the Free and Open Source
-Software communities, for not-for-profit organizations and for related
-communities and organizations.''
+network are equivalent.  Some networks use a round-robin system where
+a single server redirects new connections to a random server in the
+network.  @code{irc.libera.chat} is such a server for the Libera.Chat
+network.  Libera.Chat's purpose is ``to provide services such as a
+community platform for free open-source software and peer directed
+projects on a volunteer basis,'' and was chosen as the official home
+of the GNU Project and the Free Software Foundation's IRC channels in
+June 2021 in the aftermath of the changes in governance and policies
+of the Freenode IRC network.  GNU and FSF's announcements about this
+are at
+@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html},
+@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html},
+and
+@uref{https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html}.
 
 @cindex port, connecting
 @cindex 6667, default IRC port
@@ -205,13 +214,13 @@ in use, you might for example get assigned the nick 
@code{alex`}.
 A space separated list of channels you want to join when connecting.
 You don't need to join any channels, if you just want to have one-to-one
 conversations with friends on the same network.  If you're new to the
-Freenode network, join @code{#emacs}, the channel about all things
+Libera.Chat network, join @code{#emacs}, the channel about all things
 Emacs, or join @code{#rcirc}, the channel about @code{rcirc}.
 @end table
 
 @cindex server buffer
 When you have answered these questions, @code{rcirc} will create a server
-buffer, which will be named something like @file{*chat.freenode.net*},
+buffer, which will be named something like @file{*irc.libera.chat*},
 and a channel buffer for each of the channels you wanted to join.
 
 @kindex RET
@@ -482,7 +491,7 @@ Here's an example of how to set it:
 @end example
 
 By default you will be connected to the @code{rcirc} support channel:
-@code{#rcirc} on @code{chat.freenode.net}.
+@code{#rcirc} on @code{irc.libera.chat}.
 
 @table @code
 @item :nick
@@ -554,8 +563,8 @@ Here is an example to illustrate how you would set it:
 
 @example
 (setq rcirc-authinfo
-      '(("freenode" nickserv "bob" "p455w0rd")
-        ("freenode" chanserv "bob" "#bobland" "passwd99")
+      '(("Libera.Chat" nickserv "bob" "p455w0rd")
+        ("Libera.Chat" chanserv "bob" "#bobland" "passwd99")
         ("bitlbee" bitlbee "robert" "sekrit")))
 @end example
 
@@ -590,6 +599,12 @@ Use this symbol if you need to identify yourself in the 
Bitlbee channel
 as follows: @code{identify secret}.  The necessary arguments are the
 nickname you want to use this for, and the password to use.
 
+@item sasl
+@cindex sasl authentication
+Use this symbol if you want to use @acronym{SASL} authentication.  The
+necessary arguments are the nickname you want to use this for, and the
+password to use.
+
 @cindex gateway to other IM services
 @cindex instant messaging, other services
 @cindex Jabber
diff --git a/doc/misc/srecode.texi b/doc/misc/srecode.texi
index a0e999b..1f7473c 100644
--- a/doc/misc/srecode.texi
+++ b/doc/misc/srecode.texi
@@ -259,7 +259,7 @@ contexts to have the same name.  Some standard contexts are
 @code{file}, @code{declaration}, and @code{classdecl}.
 
 A context can be automatically derived as well based on the parsing
-state from @i{Semantic}.  @inforef{Top, Semantic Manual, semantic}.
+state from @i{Semantic}.  @xref{Top, Semantic Manual,, semantic}.
 
 @section Applications
 Commands that do a particular user task which involves also writing
diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi
index 827c477..10c951d 100644
--- a/doc/misc/trampver.texi
+++ b/doc/misc/trampver.texi
@@ -8,7 +8,7 @@
 @c In the Tramp GIT, the version numbers are auto-frobbed from
 @c tramp.el, and the bug report address is auto-frobbed from
 @c configure.ac.
-@set trampver 2.5.1-pre
+@set trampver 2.5.1
 @set trampurl https://www.gnu.org/software/tramp/
 @set tramp-bug-report-address tramp-devel@@gnu.org
 @set emacsver 25.1
diff --git a/doc/misc/wisent.texi b/doc/misc/wisent.texi
index dc5b8e4..c0bb7b1 100644
--- a/doc/misc/wisent.texi
+++ b/doc/misc/wisent.texi
@@ -1575,7 +1575,7 @@ To use the Wisent parser with @semantic{} you have to 
define
 your grammar in @dfn{WY} form, a grammar format very close
 to the one used by Bison.
 
-Please @inforef{top, Semantic Grammar Framework Manual, grammar-fw}
+Please see @ref{top, Semantic Grammar Framework Manual,, grammar-fw},
 for more information on @semantic{} grammars.
 
 @menu
@@ -1962,8 +1962,8 @@ See implementation of the function 
@code{wisent-skip-token} in
 
 @findex semantic-lex
 The lexical analysis step of @semantic{} is performed by the general
-function @code{semantic-lex}.  For more information, @inforef{Writing
-Lexers, ,semantic-langdev}.
+function @code{semantic-lex}.  For more information, see @ref{Writing
+Lexers, Semantic Language Development,,semantic-langdev}.
 
 @code{semantic-lex} produces lexical tokens of the form:
 
diff --git a/etc/HELLO b/etc/HELLO
index 0cebb2b..577c282 100644
--- a/etc/HELLO
+++ b/etc/HELLO
@@ -59,6 +59,7 @@ Italian (italiano)    Ciao / Buon giorno
 Javanese (ꦧꦱꦗꦮꦶ)       console.log("ꦲꦭꦺꦴ");
 Kannada (ಕನ್ನಡ)        ನಮಸ್ಕಾರ
 Khmer (ភាសាខ្មែរ)      ជំរាបសួរ
+Lakota (Lakȟotiyapi)   Taŋyáŋ yahí!
 Lao (ພາສາລາວ)  ສະບາຍດີ / ຂໍໃຫ້ໂຊກດີ
 Malayalam (മലയാളം)     നമസ്കാരം
 Maldivian (ދިވެހި)     އައްސަލާމު ޢަލައިކުމް / ކިހިނެހް؟
diff --git a/etc/NEWS b/etc/NEWS
index 889a0e6..1a31308 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -91,6 +91,12 @@ proper pty support that Emacs needs.
 
 * Startup Changes in Emacs 28.1
 
+---
+** In GTK builds, Emacs now supports startup notification.
+This means that Emacs won't steal keyboard focus upon startup
+(when started via the Desktop) if the user is typing into another
+application.
+
 ** Emacs can support 24-bit color TTY without terminfo database.
 If your text-mode terminal supports 24-bit true color, but your system
 lacks the terminfo database, you can instruct Emacs to support 24-bit
@@ -111,6 +117,10 @@ filters.
 
 * Changes in Emacs 28.1
 
+** 'blink-cursor-mode' is now enabled by default regardless of the UI.
+It used to be enabled when Emacs is started in GUI mode but not when started
+in text mode.  The cursor still only actually blinks in GUI frames.
+
 +++
 ** Etags now supports the Mercury programming language.
 See https://mercurylang.org.
@@ -163,7 +173,7 @@ looking at the doc string of a function that belongs to one 
of these
 groups.
 
 ---
-** Improved "find definition" feature of *Help* buffers.
+** Improved "find definition" feature of "*Help*" buffers.
 Now clicking on the link to find the definition of functions generated
 by 'cl-defstruct', or variables generated by 'define-derived-mode',
 for example, will go to the exact place where they are defined.
@@ -291,14 +301,6 @@ commands.  The new keystrokes are 'C-x x g' 
('revert-buffer'),
 input using the minibuffer.
 
 ---
-** New user option 'bookmark-menu-confirm-deletion'.
-In Bookmark Menu mode, Emacs by default does not prompt for
-confirmation when you type 'x' to execute the deletion of bookmarks
-that have been marked for deletion.  However, if this new option is
-non-nil then Emacs will require confirmation with 'yes-or-no-p' before
-deleting.
-
----
 ** New help window when Emacs prompts before opening a large file.
 Commands like 'find-file' or 'visit-tags-table' ask to visit a file
 normally or literally when the file is larger than a certain size (by
@@ -317,6 +319,10 @@ Meta characters to Emacs, e.g., send "ESC x" when the user 
types
 emulators by using the new input-meta-mode with the special value
 'encoded' with these terminal emulators.
 
++++
+** New frame parameter 'drag-with-tab-line'.
+This parameter, similar to 'drag-with-header-line', allows moving frames
+by dragging the tab lines of their topmost windows with the mouse.
 
 * Editing Changes in Emacs 28.1
 
@@ -484,10 +490,6 @@ in seconds.
 This used to be named 'macroexp--warn-and-return' and has proved useful
 and well-behaved enough to lose the "internal" marker.
 
-** 'blink-cursor-mode' is now enabled by default regardless of the UI.
-It used to be enabled when Emacs is started in GUI mode but not when started
-in text mode.  The cursor still only actually blinks in GUI frames.
-
 ** Bindat
 
 +++
@@ -539,6 +541,14 @@ an edit instead of marking it as "Done" (which the 'C-x #' 
command
 does).  The 'emacsclient' program exits with an abnormal status as
 result of this command.
 
++++
+*** New desktop integration for connecting to the server.
+If your operating system’s desktop environment is
+freedesktop.org-compatible (which is true of most GNU/Linux and other
+recent Unix-like GUIs), you may use the new "Emacs (Client)" desktop
+menu entry to open files in an existing Emacs instance rather than
+starting a new one.  The daemon starts if not already running.
+
 ** Perl mode
 
 ---
@@ -900,7 +910,7 @@ String or list of strings specifying switches for Git log 
under VC.
 +++
 *** New Summary buffer sort options for extra headers.
 The extra header sort option ('C-c C-s C-x') prompts for a header
-and fails if no sort function has been defined. Sorting by
+and fails if no sort function has been defined.  Sorting by
 Newsgroups ('C-c C-s C-u') has been pre-defined.
 
 +++
@@ -1067,6 +1077,7 @@ Clicking on a 'mailto:' link in other applications will 
then open
 Emacs with headers filled out according to the link, e.g.
 "mailto:larsi@gnus.org?subject=This+is+a+test";.  If you prefer
 emacsclient, use "emacsclient -e '(message-mailto "%u")'"
+or "emacsclient-mail.desktop".
 
 ---
 *** Change to default value of 'message-draft-headers' user option.
@@ -1169,6 +1180,11 @@ 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.
 
+---
+*** Closing the "*Help*" buffer from the toolbar now buries the buffer.
+In previous Emacs versions, the "*Help*" buffer was killed instead when
+clicking the "X" icon in the tool bar.
+
 +++
 ** New command 'lossage-size'.
 It allows users to set the maximum number of keystrokes and commands
@@ -1219,6 +1235,14 @@ deprecated.  Errors in the Inscript method were 
corrected.
 *** New input method 'cham'.
 There's also a Cham greeting in "etc/HELLO".
 
+---
+*** New input methods for Lakota language orthographies.
+Two orthographies are represented here, the Suggested Lakota
+Orthography and what is known as the White Hat Orthography.  Input
+methods 'lakota-slo-prefix', 'lakota-slo-postfix', and
+'lakota-white-hat-postfix' have been added.  There is also a Lakota
+greeting in "etc/HELLO".
+
 ** Ispell
 
 +++
@@ -1275,6 +1299,14 @@ the variables 'bookmark-bmenu-use-header-line' and
 If non-nil, setting a bookmark will colorize the current line with
 'bookmark-face'.
 
+---
+*** New user option 'bookmark-menu-confirm-deletion'.
+In Bookmark Menu mode, Emacs by default does not prompt for
+confirmation when you type 'x' to execute the deletion of bookmarks
+that have been marked for deletion.  However, if this new option is
+non-nil then Emacs will require confirmation with 'yes-or-no-p' before
+deleting.
+
 ** Edebug
 
 *** Obsoletions
@@ -1594,6 +1626,9 @@ These new navigation commands are bound to 'n' and 'p' in
 *** New command 'apropos-function'.
 This works like 'C-u M-x apropos-command' but is more discoverable.
 
+*** New face 'apropos-button'.
+Applies to buttons that indicate a face.
+
 ** CC Mode
 
 *** Added support for Doxygen documentation style.
@@ -2108,12 +2143,23 @@ Shift while typing 'C-a', i.e. 'C-S-a', will now 
highlight the text.
 
 +++
 *** ERT can now output more verbose test failure reports.
-If the EMACS_TEST_VERBOSE environment variable is set, failure
+If the 'EMACS_TEST_VERBOSE' environment variable is set, failure
 summaries will include the failing condition.
 
 ** Miscellaneous
 
 +++
+*** New user option 'kill-transform-function'.
+This can be used to transform (and suppress) strings from entering the
+kill ring.
+
+---
+*** 'C-u M-x dig' will now prompt for a query type to use.
+
++++
+*** rcirc now supports SASL authentication.
+
++++
 *** 'save-interprogram-paste-before-kill' can now be a number.
 In that case, it's interpreted as a limit on the size of the clipboard
 data that will be saved to the 'kill-ring' prior to killing text: if
@@ -2861,6 +2907,10 @@ These variables describe facts about the SQL standard and
 product-specific additions.  There should be no need for users to
 customize them.
 
+---
+** Function 'lm-maintainer' is replaced with 'lm-maintainers'.
+The former is now declared obsolete.
+
 
 * Lisp Changes in Emacs 28.1
 
@@ -3032,6 +3082,11 @@ been added, and takes a callback to handle the return 
status.
 ** 'ascii' is now a coding system alias for 'us-ascii'.
 
 +++
+** New function 'file-name-with-extension'.
+This function allows a canonical way to set/replace the extension of a
+file name.
+
++++
 ** New function 'file-backup-file-names'.
 This function returns the list of file names of all the backup files
 of its file argument.
diff --git a/etc/NEWS.27 b/etc/NEWS.27
index 4b4c1a3..e47f408 100644
--- a/etc/NEWS.27
+++ b/etc/NEWS.27
@@ -28,6 +28,29 @@ If set to a non-nil value which isn't a function, resize the 
mini
 frame using the new function 'fit-mini-frame-to-buffer' which won't
 skip leading or trailing empty lines of the buffer.
 
++++
+** Update IRC-related references to point to Libera.Chat.
+In June 2021, the Free Software Foundation and the GNU Project moved
+their official IRC channels from the Freenode network to Libera.Chat
+in the aftermath of the changes in Freenode's governance structure and
+policies in May and June 2021.  The decision-making process took into
+account the feedback received from the community against a set of
+criteria devised by a working group drawn from both GNU and the FSF
+to gauge a chat network's acceptability to software freedom activists.
+
+For the original announcement and the follow-up update, including more
+details, see:
+
+https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html
+https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html
+
+Given the relocation of GNU and FSF's official IRC channels, as well
+as #emacs and various other Emacs-themed channels (see the link below)
+to Libera.Chat, IRC-related references in the Emacs repository have
+now been updated to point to Libera.Chat.
+
+https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html
+
 
 * Changes in Specialized Modes and Packages in Emacs 27.2
 
diff --git a/etc/emacs-mail.desktop b/etc/emacs-mail.desktop
index 0c5fab1..3468033 100644
--- a/etc/emacs-mail.desktop
+++ b/etc/emacs-mail.desktop
@@ -2,11 +2,9 @@
 Categories=Network;Email;
 Comment=GNU Emacs is an extensible, customizable text editor - and more
 Exec=emacs -f message-mailto %u
-# If you prefer to use emacsclient, use this instead
-#Exec=emacsclient -e '(message-mailto "%u")'
 Icon=emacs
 Name=Emacs (Mail)
 MimeType=x-scheme-handler/mailto;
-NoDisplay=false
+NoDisplay=true
 Terminal=false
 Type=Application
diff --git a/etc/emacs.desktop b/etc/emacs.desktop
index 2e6496e..81c53c6 100644
--- a/etc/emacs.desktop
+++ b/etc/emacs.desktop
@@ -8,5 +8,6 @@ Icon=emacs
 Type=Application
 Terminal=false
 Categories=Development;TextEditor;
+StartupNotify=true
 StartupWMClass=Emacs
 Keywords=Text;Editor;
diff --git a/etc/emacsclient-mail.desktop b/etc/emacsclient-mail.desktop
new file mode 100644
index 0000000..8d51dcd
--- /dev/null
+++ b/etc/emacsclient-mail.desktop
@@ -0,0 +1,19 @@
+[Desktop Entry]
+Categories=Network;Email;
+Comment=GNU Emacs is an extensible, customizable text editor - and more
+Exec=sh -c 'exec emacsclient --alternate-editor= --display="$DISPLAY" --eval 
"(message-mailto \"%u\")"'
+Icon=emacs
+Name=Emacs (Mail, Client)
+MimeType=x-scheme-handler/mailto;
+NoDisplay=true
+Terminal=false
+Type=Application
+Actions=new-window;new-instance;
+
+[Desktop Action new-window]
+Name=New Window
+Exec=emacsclient --alternate-editor= --create-frame --eval '(message-mailto 
"%u")'
+
+[Desktop Action new-instance]
+Name=New Instance
+Exec=emacs -f message-mailto %u
diff --git a/etc/emacsclient.desktop b/etc/emacsclient.desktop
index 3feb83c..cd45463 100644
--- a/etc/emacsclient.desktop
+++ b/etc/emacsclient.desktop
@@ -3,10 +3,20 @@ Name=Emacs (Client)
 GenericName=Text Editor
 Comment=Edit text
 
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
-Exec=emacsclient -c %F
+Exec=sh -c 'if [ -n "$*" ]; then exec emacsclient --alternate-editor= 
--display="$DISPLAY" "$@"; else exec emacsclient --alternate-editor= 
--create-frame; fi' placeholder %F
 Icon=emacs
 Type=Application
 Terminal=false
 Categories=Development;TextEditor;
-StartupWMClass=Emacsd
+StartupNotify=true
+StartupWMClass=Emacs
 Keywords=Text;Editor;
+Actions=new-window;new-instance;
+
+[Desktop Action new-window]
+Name=New Window
+Exec=emacsclient --alternate-editor= --create-frame %F
+
+[Desktop Action new-instance]
+Name=New Instance
+Exec=emacs %F
diff --git a/lisp/allout.el b/lisp/allout.el
index 1605ce2..0625ea6 100644
--- a/lisp/allout.el
+++ b/lisp/allout.el
@@ -2490,10 +2490,10 @@ We skip anomalous low-level topics, a la 
`allout-aberrant-container-p'."
 
 ;;;_  - Subtree Charting
 ;;;_   " These routines either produce or assess charts, which are
-;;; nested lists of the locations of topics within a subtree.
-;;;
-;;; Charts enable efficient subtree navigation by providing a reusable basis
-;;; for elaborate, compound assessment and adjustment of a subtree.
+;; nested lists of the locations of topics within a subtree.
+;;
+;; Charts enable efficient subtree navigation by providing a reusable basis
+;; for elaborate, compound assessment and adjustment of a subtree.
 
 ;;;_   > allout-chart-subtree (&optional levels visible orig-depth prev-depth)
 (defun allout-chart-subtree (&optional levels visible orig-depth prev-depth)
diff --git a/lisp/apropos.el b/lisp/apropos.el
index 17665a7..f246064 100644
--- a/lisp/apropos.el
+++ b/lisp/apropos.el
@@ -96,6 +96,11 @@ include key-binding information in its output."
   "Face for property name in Apropos output, or nil for none."
   :version "24.3")
 
+(defface apropos-button
+  '((t (:inherit (font-lock-variable-name-face button))))
+  "Face for buttons that indicate a face in Apropos."
+  :version "28.1")
+
 (defface apropos-function-button
   '((t (:inherit (font-lock-function-name-face button))))
   "Button face indicating a function, macro, or command in Apropos."
@@ -276,7 +281,7 @@ before `apropos-mode' makes it buffer-local.")
 (define-button-type 'apropos-face
   'apropos-label "Face"
   'apropos-short-label "F"
-  'face '(font-lock-variable-name-face button)
+  'face 'apropos-button
   'help-echo "mouse-2, RET: Display more help on this face"
   'follow-link t
   'action (lambda (button)
diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el
index a7b959c..914f8d2 100644
--- a/lisp/auth-source-pass.el
+++ b/lisp/auth-source-pass.el
@@ -6,8 +6,6 @@
 ;;         Nicolas Petton <nicolas@petton.fr>
 ;;         Keith Amidon <camalot@picnicpark.org>
 ;; Version: 5.0.0
-;; Package-Requires: ((emacs "25"))
-;; Url: https://github.com/DamienCassou/auth-password-store
 ;; Created: 07 Jun 2015
 
 ;; This file is part of GNU Emacs.
@@ -60,14 +58,12 @@
 (cl-defun auth-source-pass-search (&rest spec
                                          &key backend type host user port
                                          &allow-other-keys)
-  "Given a property list SPEC, return search matches from the :backend.
-See `auth-source-search' for details on SPEC."
+  "Given some search query, return matching credentials.
+
+See `auth-source-search' for details on the parameters SPEC, BACKEND, TYPE,
+HOST, USER and PORT."
   (cl-assert (or (null type) (eq type (oref backend type)))
              t "Invalid password-store search: %s %s")
-  (when (consp host)
-    (warn "auth-source-pass ignores all but first host in spec.")
-    ;; Take the first non-nil item of the list of hosts
-    (setq host (seq-find #'identity host)))
   (cond ((eq host t)
          (warn "auth-source-pass does not handle host wildcards.")
          nil)
@@ -78,12 +74,14 @@ See `auth-source-search' for details on SPEC."
          (when-let ((result (auth-source-pass--build-result host port user)))
            (list result)))))
 
-(defun auth-source-pass--build-result (host port user)
-  "Build auth-source-pass entry matching HOST, PORT and USER."
-  (let ((entry-data (auth-source-pass--find-match host user port)))
+(defun auth-source-pass--build-result (hosts port user)
+  "Build auth-source-pass entry matching HOSTS, PORT and USER.
+
+HOSTS can be a string or a list of strings."
+  (let ((entry-data (auth-source-pass--find-match hosts user port)))
     (when entry-data
       (let ((retval (list
-                     :host host
+                     :host (auth-source-pass--get-attr "host" entry-data)
                      :port (or (auth-source-pass--get-attr "port" entry-data) 
port)
                      :user (or (auth-source-pass--get-attr "user" entry-data) 
user)
                      :secret (lambda () (auth-source-pass--get-attr 'secret 
entry-data)))))
@@ -125,7 +123,7 @@ ENTRY is the name of a password-store entry.
 The key used to retrieve the password is the symbol `secret'.
 
 The convention used as the format for a password-store file is
-the following (see https://www.passwordstore.org/#organization):
+the following (see URL `https://www.passwordstore.org/#organization'):
 
 secret
 key1: value1
@@ -169,15 +167,13 @@ The secret is the first line of CONTENTS."
 (defun auth-source-pass--parse-data (contents)
   "Parse the password-store data in the string CONTENTS and return an alist.
 CONTENTS is the contents of a password-store formatted file."
-  (let ((lines (split-string contents "\n" t "[ \t]+")))
+  (let ((lines (cdr (split-string contents "\n" t "[ \t]+"))))
     (seq-remove #'null
                 (mapcar (lambda (line)
-                          (let ((pair (mapcar (lambda (s) (string-trim s))
-                                              (split-string line ":"))))
-                            (when (> (length pair) 1)
-                              (cons (car pair)
-                                    (mapconcat #'identity (cdr pair) ":")))))
-                        (cdr lines)))))
+                          (when-let ((pos (seq-position line ?:)))
+                            (cons (string-trim (substring line 0 pos))
+                                  (string-trim (substring line (1+ pos))))))
+                        lines))))
 
 (defun auth-source-pass--do-debug (&rest msg)
   "Call `auth-source-do-debug` with MSG and a prefix."
@@ -194,12 +190,21 @@ CONTENTS is the contents of a password-store formatted 
file."
      (lambda (file) (file-name-sans-extension (file-relative-name file 
store-dir)))
      (directory-files-recursively store-dir "\\.gpg\\'"))))
 
-(defun auth-source-pass--find-match (host user port)
-  "Return password-store entry data matching HOST, USER and PORT.
-
-Disambiguate between user provided inside HOST (e.g., user@server.com) and
-inside USER by giving priority to USER.  Same for PORT."
-  (apply #'auth-source-pass--find-match-unambiguous 
(auth-source-pass--disambiguate host user port)))
+(defun auth-source-pass--find-match (hosts user port)
+  "Return password-store entry data matching HOSTS, USER and PORT.
+
+Disambiguate between user provided inside HOSTS (e.g., user@server.com) and
+inside USER by giving priority to USER.  Same for PORT.
+HOSTS can be a string or a list of strings."
+  (seq-some (lambda (host)
+              (let ((entry (apply #'auth-source-pass--find-match-unambiguous
+                                   (auth-source-pass--disambiguate host user 
port))))
+                (if (or (null entry) (assoc "host" entry))
+                    entry
+                  (cons (cons "host" host) entry))))
+            (if (listp hosts)
+                hosts
+              (list hosts))))
 
 (defun auth-source-pass--disambiguate (host &optional user port)
   "Return (HOST USER PORT) after disambiguation.
@@ -268,7 +273,7 @@ If ENTRIES is nil, use the result of calling 
`auth-source-pass-entries' instead.
 (defun auth-source-pass--generate-entry-suffixes (hostname user port)
   "Return a list of possible entry path suffixes in the password-store.
 
-Based on the supported pathname patterns for HOSTNAME, USER, &
+Based on the supported filename patterns for HOSTNAME, USER, &
 PORT, return a list of possible suffixes for matching entries in
 the password-store.
 
@@ -316,3 +321,5 @@ then NAME & USER, then NAME & PORT, then just NAME."
 
 (provide 'auth-source-pass)
 ;;; auth-source-pass.el ends here
+
+;; LocalWords:  backend hostname
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 9ca28eb..6919738 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -1270,7 +1270,7 @@ See `auth-source-search' for details on SPEC."
 ;; (auth-source-search :host "nonesuch" :type 'netrc :max 1 :create t 
:create-extra-keys '((A "default A") (B)))
 
 (cl-defun auth-source-netrc-create (&rest spec
-                                    &key backend host port create
+                                    &key backend host port create user
                                     &allow-other-keys)
   (let* ((base-required '(host user port secret))
          ;; we know (because of an assertion in auth-source-search) that the
@@ -1278,6 +1278,7 @@ See `auth-source-search' for details on SPEC."
          (create-extra (if (eq t create) nil create))
          (current-data (car (auth-source-search :max 1
                                                 :host host
+                                                :user user
                                                 :port port)))
          (required (append base-required create-extra))
          (file (oref backend source))
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 4e5497c..06ba5d0 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -330,22 +330,53 @@ of the menu's data."
 (defvar mode-line-mode-menu (make-sparse-keymap "Minor Modes") "\
 Menu of mode operations in the mode line.")
 
+(defun bindings--menu-item-string (item)
+  "Return the menu-item string for ITEM, or nil if not a menu-item."
+  (pcase item
+    (`(menu-item ,name . ,_) (eval name t))
+    (`(,(and (pred stringp) name) . ,_) name)))
+
+(defun bindings--sort-menu-keymap (map)
+  "Sort the bindings in MAP in alphabetical order by menu-item string.
+The order of bindings in a keymap matters only when it is used as
+a menu, so this function is not useful for non-menu keymaps."
+  (let ((bindings nil)
+        (prompt (keymap-prompt map)))
+    (while (keymapp map)
+      (setq map (map-keymap
+                 (lambda (key item)
+                   ;; FIXME: Handle char-ranges here?
+                   (push (cons key item) bindings))
+                 map)))
+    ;; Sort the bindings and make a new keymap from them.
+    (setq bindings
+          (sort bindings
+                (lambda (a b)
+                  (string< (bindings--menu-item-string (cdr-safe a))
+                           (bindings--menu-item-string (cdr-safe b))))))
+    (nconc (make-sparse-keymap prompt) bindings)))
+
 (defvar mode-line-major-mode-keymap
   (let ((map (make-sparse-keymap)))
     (bindings--define-key map [mode-line down-mouse-1]
       `(menu-item "Menu Bar" ignore
         :filter ,(lambda (_) (mouse-menu-major-mode-map))))
     (define-key map [mode-line mouse-2] 'describe-mode)
-    (define-key map [mode-line down-mouse-3] mode-line-mode-menu)
+    (bindings--define-key map [mode-line down-mouse-3]
+      `(menu-item "Minor Modes" ,mode-line-mode-menu
+        :filter bindings--sort-menu-keymap))
     map) "\
 Keymap to display on major mode.")
 
 (defvar mode-line-minor-mode-keymap
-  (let ((map (make-sparse-keymap)))
+  (let ((map (make-sparse-keymap))
+        (mode-menu-binding
+         `(menu-item "Menu Bar" ,mode-line-mode-menu
+           :filter bindings--sort-menu-keymap)))
     (define-key map [mode-line down-mouse-1] 'mouse-minor-mode-menu)
     (define-key map [mode-line mouse-2] 'mode-line-minor-mode-help)
-    (define-key map [mode-line down-mouse-3] mode-line-mode-menu)
-    (define-key map [header-line down-mouse-3] mode-line-mode-menu)
+    (define-key map [mode-line down-mouse-3] mode-menu-binding)
+    (define-key map [header-line down-mouse-3] mode-menu-binding)
     map) "\
 Keymap to display on minor modes.")
 
@@ -611,8 +642,8 @@ Switch to the most recently selected buffer other than the 
current one."
 
 (defmacro bound-and-true-p (var)
   "Return the value of symbol VAR if it is bound, else nil.
-Note that if `lexical-binding' is in effect, this refers to the
-global value outside of any lexical scope."
+Note that if `lexical-binding' is in effect, this function isn't
+meaningful if it refers to a lexically bound variable."
   `(and (boundp (quote ,var)) ,var))
 
 ;; Use mode-line-mode-menu for local minor-modes only.
diff --git a/lisp/comint.el b/lisp/comint.el
index ef34174..9e40661 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -54,7 +54,7 @@
 ;; instead of shell-mode, see the notes at the end of this file.
 
 
-;; Brief Command Documentation:
+;;; Brief Command Documentation:
 ;;============================================================================
 ;; Comint Mode Commands: (common to all derived modes, like shell & cmulisp
 ;; mode)
@@ -106,7 +106,7 @@
 (require 'regexp-opt)                   ;For regexp-opt-charset.
 (eval-when-compile (require 'subr-x))
 
-;; Buffer Local Variables:
+;;; Buffer Local Variables:
 ;;============================================================================
 ;; Comint mode buffer local variables:
 ;;  comint-prompt-regexp               string  comint-bol uses to match prompt
@@ -150,10 +150,10 @@
   :group 'comint)
 
 ;; Unused.
-;;; (defgroup comint-source nil
-;;;   "Source finding facilities in comint."
-;;;   :prefix "comint-"
-;;;   :group 'comint)
+;; (defgroup comint-source nil
+;;   "Source finding facilities in comint."
+;;   :prefix "comint-"
+;;   :group 'comint)
 
 (defvar comint-prompt-regexp "^"
   "Regexp to recognize prompts in the inferior process.
@@ -924,8 +924,8 @@ by the global keymap (usually `mouse-yank-at-click')."
         ;; Insert the input at point
         (insert input)))))
 
-;; Input history processing in a buffer
-;; ===========================================================================
+;;; Input history processing in a buffer
+;;============================================================================
 ;; Useful input history functions, courtesy of the Ergo group.
 
 ;; Eleven commands:
@@ -2847,7 +2847,7 @@ updated using `comint-update-fence', if necessary."
          (kill-region beg end)
          (comint-update-fence))))))
 
-;; Support for source-file processing commands.
+;;; Support for source-file processing commands.
 ;;============================================================================
 ;; Many command-interpreters (e.g., Lisp, Scheme, Soar) have
 ;; commands that process files of source text (e.g. loading or compiling
@@ -2981,8 +2981,8 @@ A typical use:
 ;;     -Olin
 
 
-;; Simple process query facility.
-;; ===========================================================================
+;;; Simple process query facility.
+;;============================================================================
 ;; This function is for commands that want to send a query to the process
 ;; and show the response to the user. For example, a command to get the
 ;; arglist for a Common Lisp function might send a "(arglist 'foo)" query
@@ -3018,8 +3018,8 @@ its response can be seen."
            (set-window-point proc-win opoint)))))))
 
 
-;; Filename/command/history completion in a buffer
-;; ===========================================================================
+;;; Filename/command/history completion in a buffer
+;;============================================================================
 ;; Useful completion functions, courtesy of the Ergo group.
 
 ;; Six commands:
@@ -3883,8 +3883,8 @@ REGEXP-GROUP is the regular expression group in REGEXP to 
use."
          (forward-line 1)))
       (nreverse results))))
 
-;; Converting process modes to use comint mode
-;; ===========================================================================
+;;; Converting process modes to use comint mode
+;;============================================================================
 ;; The code in the Emacs 19 distribution has all been modified to use comint
 ;; where needed.  However, there are `third-party' packages out there that
 ;; still use the old shell mode.  Here's a guide to conversion.
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index b7afef6..3c2625a 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -285,6 +285,7 @@ Leaving \"Default\" unchecked is equivalent with specifying 
a default of
                      (or (getenv "TMPDIR") (getenv "TMP") (getenv "TEMP")
                          ;; See bug#7135.
                          (let* (file-name-handler-alist
+                                 (default-directory "/")
                                 (tmp (ignore-errors
                                        (shell-command-to-string
                                         "getconf DARWIN_USER_TEMP_DIR"))))
diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el
index dfa2226..f4885d0 100644
--- a/lisp/cus-theme.el
+++ b/lisp/cus-theme.el
@@ -108,60 +108,16 @@ named *Custom Theme*."
     (unless (y-or-n-p "Include basic face customizations in this theme? ")
       (setq custom-theme--listed-faces nil)))
 
-  (if (eq theme 'user)
-      (widget-insert "This buffer contains all the Custom settings you have 
made.
-You can convert them into a new custom theme, and optionally
-remove them from your saved Custom file.\n\n"))
-
-  (widget-create 'push-button
-                :tag " Visit Theme "
-                :help-echo "Insert the settings of a pre-defined theme."
-                :action (lambda (_widget &optional _event)
-                           (call-interactively #'custom-theme-visit-theme)))
-  (widget-insert "  ")
-  (widget-create 'push-button
-                :tag " Merge Theme "
-                :help-echo "Merge in the settings of a pre-defined theme."
-                :action (lambda (_widget &optional _event)
-                           (call-interactively #'custom-theme-merge-theme)))
-  (widget-insert "  ")
-  (widget-create 'push-button
-                :tag " Revert "
-                :help-echo "Revert this buffer to its original state."
-                :action (lambda (&rest ignored) (revert-buffer)))
-
-  (widget-insert "\n\nTheme name : ")
-  (setq custom-theme-name
-       (widget-create 'editable-field
-                      :value (if (and theme (not (eq theme 'user)))
-                                 (symbol-name theme)
-                               "")))
-  (widget-insert "Description: ")
-  (setq custom-theme-description
-       (widget-create 'text
-                      :value (format-time-string "Created %Y-%m-%d.")))
-  (widget-create 'push-button
-                 :notify #'custom-theme-write
-                " Save Theme ")
-  (when (eq theme 'user)
-    (setq custom-theme--migrate-settings t)
-    (widget-insert "  ")
-    (widget-create 'checkbox
-                  :value custom-theme--migrate-settings
-                  :action (lambda (widget &optional event)
-                            (when (widget-value widget)
-                              (widget-toggle-action widget event)
-                              (setq custom-theme--migrate-settings
-                                    (widget-value widget)))))
-    (widget-insert (propertize " Remove saved theme settings from Custom save 
file."
-                              'face '(variable-pitch (:height 0.9)))))
-
   (let (vars values faces face-specs)
 
     ;; Load the theme settings.
     (when theme
-      (unless (eq theme 'user)
-       (load-theme theme nil t))
+      (if (eq theme 'user)
+          (widget-insert "This buffer contains all the Custom settings you 
have made.
+You can convert them into a new custom theme, and optionally
+remove them from your saved Custom file.\n\n")
+        (load-theme theme nil t))
+
       (dolist (setting (get theme 'theme-settings))
        (if (eq (car setting) 'theme-value)
            (progn (push (nth 1 setting) vars)
@@ -169,6 +125,50 @@ remove them from your saved Custom file.\n\n"))
          (push (nth 1 setting) faces)
          (push (nth 3 setting) face-specs))))
 
+    (widget-create 'push-button
+                  :tag " Visit Theme "
+                  :help-echo "Insert the settings of a pre-defined theme."
+                  :action (lambda (_widget &optional _event)
+                             (call-interactively #'custom-theme-visit-theme)))
+    (widget-insert "  ")
+    (widget-create 'push-button
+                  :tag " Merge Theme "
+                  :help-echo "Merge in the settings of a pre-defined theme."
+                  :action (lambda (_widget &optional _event)
+                             (call-interactively #'custom-theme-merge-theme)))
+    (widget-insert "  ")
+    (widget-create 'push-button
+                  :tag " Revert "
+                  :help-echo "Revert this buffer to its original state."
+                  :action (lambda (&rest ignored) (revert-buffer)))
+
+    (widget-insert "\n\nTheme name : ")
+    (setq custom-theme-name
+         (widget-create 'editable-field
+                        :value (if (and theme (not (eq theme 'user)))
+                                   (symbol-name theme)
+                                 "")))
+    (widget-insert "Description: ")
+    (setq custom-theme-description
+          (widget-create 'text :format "%v"
+                         :value (or (get theme 'theme-documentation)
+                                    (format-time-string "Created %Y-%m-%d."))))
+    (widget-create 'push-button
+                   :notify #'custom-theme-write
+                   " Save Theme ")
+    (when (eq theme 'user)
+      (setq custom-theme--migrate-settings t)
+      (widget-insert "  ")
+      (widget-create 'checkbox
+                    :value custom-theme--migrate-settings
+                    :action (lambda (widget &optional event)
+                              (when (widget-value widget)
+                                (widget-toggle-action widget event)
+                                (setq custom-theme--migrate-settings
+                                      (widget-value widget)))))
+      (widget-insert (propertize " Remove saved theme settings from Custom 
save file."
+                                'face '(variable-pitch (:height 0.9)))))
+
     ;; If THEME is non-nil, insert all of that theme's faces.
     ;; Otherwise, insert those in `custom-theme--listed-faces'.
     (widget-insert "\n\n  Theme faces:\n ")
diff --git a/lisp/desktop.el b/lisp/desktop.el
index fb7c6c7..ae8d026 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -731,7 +731,7 @@ if different)."
 
 ;; ----------------------------------------------------------------------------
 (unless noninteractive
-  (add-hook 'kill-emacs-hook #'desktop-kill))
+  (add-hook 'kill-emacs-query-functions #'desktop-kill))
 
 (defun desktop-kill ()
   "If `desktop-save-mode' is non-nil, do what `desktop-save' says to do.
@@ -759,7 +759,8 @@ is nil, ask the user where to save the desktop."
        (unless (yes-or-no-p "Error while saving the desktop.  Ignore? ")
         (signal (car err) (cdr err))))))
   ;; If we own it, we don't anymore.
-  (when (eq (emacs-pid) (desktop-owner)) (desktop-release-lock)))
+  (when (eq (emacs-pid) (desktop-owner)) (desktop-release-lock))
+  t)
 
 ;; ----------------------------------------------------------------------------
 (defun desktop-list* (&rest args)
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 54cfbba..060f3a8 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -33,6 +33,7 @@
 ;; sorting by Sebastian Kremer <sk@thp.uni-koeln.de>.
 ;; Finished up by rms in 1992.
 
+
 ;;; Code:
 
 (require 'cl-lib)
@@ -45,9 +46,8 @@
 Functions that operate recursively can store additional names
 into this list; they also should call `dired-log' to log the errors.")
 
-;;; 15K
-;;;###begin dired-cmd.el
-;; Diffing and compressing
+
+;;; Diffing and compressing
 
 (defconst dired-star-subst-regexp "\\(^\\|[ \t]\\)\\*\\([ \t]\\|$\\)")
 (defconst dired-quark-subst-regexp "\\(^\\|[ \t]\\)\\?\\([ \t]\\|$\\)")
@@ -135,7 +135,7 @@ substituted, and will be passed through normally to the 
shell.
 
 %s
 
-(Press ^ to %s markers below these occurrences.)
+\(Press ^ to %s markers below these occurrences.)
 "
    "`"
    (string (aref command (car char-positions)))
@@ -288,12 +288,12 @@ If this file is a backup, diff it with its original.
 The backup file is the first file given to `diff'.
 With prefix arg, prompt for argument SWITCHES which is options for `diff'."
   (interactive
-    (if current-prefix-arg
-       (list (read-string "Options for diff: "
-                          (if (stringp diff-switches)
-                              diff-switches
-                            (mapconcat #'identity diff-switches " "))))
-      nil))
+   (if current-prefix-arg
+       (list (read-string "Options for diff: "
+                         (if (stringp diff-switches)
+                             diff-switches
+                           (mapconcat #'identity diff-switches " "))))
+     nil))
   (diff-backup (dired-get-filename) switches))
 
 ;;;###autoload
@@ -418,6 +418,7 @@ List has a form of (file-name full-file-name 
(attribute-list))."
              full-file-name
              (file-attributes full-file-name))))
    (directory-files dir)))
+
 
 ;;; Change file attributes
 
@@ -636,7 +637,7 @@ Uses the shell command coming from variables `lpr-command' 
and
     (dired-run-shell-command (dired-shell-stuff-it command file-list nil))))
 
 (defun dired-mark-read-string (prompt initial op-symbol arg files
-                              &optional default-value collection)
+                                     &optional default-value collection)
   "Read args for a Dired marked-files command, prompting with PROMPT.
 Return the user input (a string).
 
@@ -655,8 +656,9 @@ passed as the second arg to `completing-read'."
                     'completing-read
                     (format prompt (dired-mark-prompt arg files))
                     collection nil nil initial nil default-value nil))
+
 
-;;; Cleaning a directory: flagging some backups for deletion.
+;;; Cleaning a directory: flagging some backups for deletion
 
 (defvar dired-file-version-alist)
 
@@ -699,7 +701,8 @@ with a prefix argument."
     (dired-map-dired-file-lines #'dired-trample-file-versions)
     (message "Cleaning numerical backups...done")))
 
-;;; Subroutines of dired-clean-directory.
+
+;;; Subroutines of dired-clean-directory
 
 (defun dired-map-dired-file-lines (fun)
   ;; Perform FUN with point at the end of each non-directory line.
@@ -750,6 +753,7 @@ with a prefix argument."
         (progn (beginning-of-line)
                (delete-char 1)
                (insert dired-del-marker)))))
+
 
 ;;; Shell commands
 
@@ -871,8 +875,8 @@ can be produced by `dired-get-marked-files', for example.
 `dired-guess-shell-alist-default' and
 `dired-guess-shell-alist-user' are consulted when the user is
 prompted for the shell command to use interactively."
-;;Functions dired-run-shell-command and dired-shell-stuff-it do the
-;;actual work and can be redefined for customization.
+  ;; Functions dired-run-shell-command and dired-shell-stuff-it do the
+  ;; actual work and can be redefined for customization.
   (interactive
    (let ((files (dired-get-marked-files t current-prefix-arg nil nil t)))
      (list
@@ -914,13 +918,13 @@ prompted for the shell command to use interactively."
   "Separates marked files in dired shell commands.")
 
 (defun dired-shell-stuff-it (command file-list on-each &optional _raw-arg)
-;; "Make up a shell command line from COMMAND and FILE-LIST.
-;; If ON-EACH is t, COMMAND should be applied to each file, else
-;; simply concat all files and apply COMMAND to this.
-;; FILE-LIST's elements will be quoted for the shell."
-;; Might be redefined for smarter things and could then use RAW-ARG
-;; (coming from interactive P and currently ignored) to decide what to do.
-;; Smart would be a way to access basename or extension of file names.
+  ;; "Make up a shell command line from COMMAND and FILE-LIST.
+  ;; If ON-EACH is t, COMMAND should be applied to each file, else
+  ;; simply concat all files and apply COMMAND to this.
+  ;; FILE-LIST's elements will be quoted for the shell."
+  ;; Might be redefined for smarter things and could then use RAW-ARG
+  ;; (coming from interactive P and currently ignored) to decide what to do.
+  ;; Smart would be a way to access basename or extension of file names.
   (let* ((in-background (string-match "[ \t]*&[ \t]*\\'" command))
         (command (if in-background
                      (substring command 0 (match-beginning 0))
@@ -986,8 +990,8 @@ prompted for the shell command to use interactively."
       (shell-command command)))
   ;; Return nil for sake of nconc in dired-bunch-files.
   nil)
-
 
+
 (defun dired-check-process (msg program &rest arguments)
   "Display MSG while running PROGRAM, and check for output.
 Remaining arguments are strings passed as command arguments to PROGRAM.
@@ -1032,8 +1036,9 @@ Return the result of `process-file' - zero for success."
         (unless (zerop res)
           (pop-to-buffer out-buffer))
         res))))
+
 
-;; Commands that delete or redisplay part of the dired buffer.
+;;; Commands that delete or redisplay part of the dired buffer
 
 (defun dired-kill-line (&optional arg)
   "Kill the current line (not the files).
@@ -1098,10 +1103,8 @@ present.  A FMT of \"\" will suppress the messaging."
            (message (or fmt "Killed %d line%s.") count (dired-plural-s count)))
        count))))
 
-;;;###end dired-cmd.el
 
-;;; 30K
-;;;###begin dired-cp.el
+;;; Compression
 
 (defun dired-compress ()
   ;; Compress or uncompress the current file.
@@ -1382,19 +1385,19 @@ see `dired-compress-file-alist' for the supported 
suffixes list."
                                   (dired-mark-prompt arg files) "? ")))))
 
 (defun dired-map-over-marks-check (fun arg op-symbol &optional show-progress)
-;  "Map FUN over marked files (with second ARG like in dired-map-over-marks)
-; and display failures.
+  ;;  "Map FUN over marked files (with second ARG like in dired-map-over-marks)
+  ;; and display failures.
 
-; FUN takes zero args.  It returns non-nil (the offending object, e.g.
-; the short form of the filename) for a failure and probably logs a
-; detailed error explanation using function `dired-log'.
+  ;; FUN takes zero args.  It returns non-nil (the offending object, e.g.
+  ;; the short form of the filename) for a failure and probably logs a
+  ;; detailed error explanation using function `dired-log'.
 
-; OP-SYMBOL is a symbol describing the operation performed (e.g.
-; `compress').  It is used with `dired-mark-pop-up' to prompt the user
-; (e.g. with `Compress * [2 files]? ') and to display errors (e.g.
-; `Failed to compress 1 of 2 files - type W to see why ("foo")')
+  ;; OP-SYMBOL is a symbol describing the operation performed (e.g.
+  ;; `compress').  It is used with `dired-mark-pop-up' to prompt the user
+  ;; (e.g. with `Compress * [2 files]? ') and to display errors (e.g.
+  ;; `Failed to compress 1 of 2 files - type W to see why ("foo")')
 
-; SHOW-PROGRESS if non-nil means redisplay dired after each file."
+  ;; SHOW-PROGRESS if non-nil means redisplay dired after each file."
   (if (dired-mark-confirm op-symbol arg)
       (let* ((total-list;; all of FUN's return values
              (dired-map-over-marks (funcall fun) arg show-progress))
@@ -1454,7 +1457,8 @@ uncompress and unpack all the files in the archive."
   (interactive "P")
   (dired-map-over-marks-check #'dired-compress arg 'compress t))
 
-;; Commands for Emacs Lisp files - load and byte compile
+
+;;; Commands for Emacs Lisp files - load and byte compile
 
 (defun dired-byte-compile ()
   ;; Return nil for success, offending file name else.
@@ -1486,7 +1490,7 @@ uncompress and unpack all the files in the archive."
   ;; Return nil for success, offending file name else.
   (let ((file (dired-get-filename)) failure)
     (condition-case err
-      (load file nil nil t)
+        (load file nil nil t)
       (error (setq failure err)))
     (if (not failure)
        nil
@@ -1546,6 +1550,7 @@ See Info node `(emacs)Subdir switches' for more details."
   (interactive)
   (setq dired-switches-alist nil)
   (revert-buffer))
+
 
 (defun dired-update-file-line (file)
   ;; Delete the current line, and insert an entry for FILE.
@@ -1700,7 +1705,7 @@ files matching `dired-omit-regexp'."
     (forward-line 1)
     (while (and (not (eolp))           ; don't cross subdir boundary
                (not (dired-move-to-filename)))
-       (forward-line 1))
+      (forward-line 1))
     (point)))
 
 ;;;###autoload
@@ -1734,6 +1739,7 @@ See `dired-delete-file' in case you wish that."
                          (line-beginning-position 2)))
       (setq file (directory-file-name file))
       (dired-add-entry file (if (eq ?\s marker) nil marker)))))
+
 
 ;;; Copy, move/rename, making hard and symbolic links
 
@@ -1933,7 +1939,9 @@ unless OK-IF-ALREADY-EXISTS is non-nil."
 (defvar overwrite-query)
 (defvar overwrite-backup-query)
 
-;; The basic function for half a dozen variations on cp/mv/ln/ln -s.
+
+;;; The basic function for half a dozen variations on cp/mv/ln/ln -s
+
 (defun dired-create-files (file-creator operation fn-list name-constructor
                                        &optional marker-char)
   "Create one or more new files from a list of existing files FN-LIST.
@@ -2067,6 +2075,7 @@ ESC or `q' to not overwrite any of the remaining files,
                         success-count)
               operation success-count))))
   (dired-move-to-filename))
+
 
 (defcustom dired-do-revert-buffer nil
   "Automatically revert Dired buffers after `dired-do' operations.
@@ -2299,7 +2308,6 @@ Optional arg HOW-TO determines how to treat the target.
       dired-dirs)))
 
 
-
 ;; We use this function in `dired-create-directory' and
 ;; `dired-create-empty-file'; the return value is the new entry
 ;; in the updated Dired buffer.
@@ -2415,7 +2423,7 @@ suggested for the target directory depends on the value of
 For relative symlinks, use \\[dired-do-relsymlink]."
   (interactive "P")
   (dired-do-create-files 'symlink #'make-symbolic-link
-                          "Symlink" arg dired-keep-marker-symlink))
+                         "Symlink" arg dired-keep-marker-symlink))
 
 ;;;###autoload
 (defun dired-do-hardlink (&optional arg)
@@ -2428,7 +2436,7 @@ suggested for the target directory depends on the value of
 `dired-dwim-target', which see."
   (interactive "P")
   (dired-do-create-files 'hardlink #'dired-hardlink
-                          "Hardlink" arg dired-keep-marker-hardlink))
+                         "Hardlink" arg dired-keep-marker-hardlink))
 
 (defun dired-hardlink (file newname &optional ok-if-already-exists)
   (dired-handle-overwrite newname)
@@ -2448,14 +2456,14 @@ of `dired-dwim-target', which see."
   (interactive "P")
   (dired-do-create-files 'move #'dired-rename-file
                         "Move" arg dired-keep-marker-rename "Rename"))
-;;;###end dired-cp.el
+
 
-;;; 5K
-;;;###begin dired-re.el
+;;; Operate on files matched by regexp
+
 (defvar rename-regexp-query)
 
 (defun dired-do-create-files-regexp
-  (file-creator operation arg regexp newname &optional whole-name marker-char)
+    (file-creator operation arg regexp newname &optional whole-name 
marker-char)
   ;; Create a new file for each marked file using regexps.
   ;; FILE-CREATOR and OPERATION as in dired-create-files.
   ;; ARG as in dired-get-marked-files.
@@ -2572,10 +2580,13 @@ See function `dired-do-rename-regexp' for more info."
    #'make-symbolic-link
    "SymLink" arg regexp newname whole-name dired-keep-marker-symlink))
 
+
+;;; Change case of file names
+
 (defvar rename-non-directory-query)
 
 (defun dired-create-files-non-directory
-  (file-creator basename-constructor operation arg)
+    (file-creator basename-constructor operation arg)
   ;; Perform FILE-CREATOR on the non-directory part of marked files
   ;; using function BASENAME-CONSTRUCTOR, with query for each file.
   ;; OPERATION like in dired-create-files, ARG as in dired-get-marked-files.
@@ -2617,10 +2628,8 @@ Type SPC or `y' to %s one file, DEL or `n' to skip to 
next,
   (interactive "P")
   (dired-rename-non-directory #'downcase "Rename downcase" arg))
 
-;;;###end dired-re.el
 
-;;; 13K
-;;;###begin dired-ins.el
+;;; Insert subdirectory
 
 ;;;###autoload
 (defun dired-maybe-insert-subdir (dirname &optional
@@ -2894,8 +2903,9 @@ is always equal to STRING."
        (setq result
              (cons (substring str end) result)))
     (nreverse result)))
+
 
-;;; moving by subdirectories
+;;; Moving by subdirectories
 
 ;;;###autoload
 (defun dired-prev-subdir (arg &optional no-error-if-not-found no-skip)
@@ -2998,8 +3008,9 @@ Lower levels are unaffected."
     (if pos
        (goto-char pos)
       (error "At the bottom"))))
+
 
-;;; hiding
+;;; Hiding
 
 ;;;###autoload
 (defun dired-hide-subdir (arg)
@@ -3043,10 +3054,8 @@ Use \\[dired-hide-subdir] to (un)hide a particular 
subdirectory."
             (dired--hide start end))
           (setq pos (cdr subdir))))))) ; prev dir gets current dir
 
-;;;###end dired-ins.el
-
 
-;; Search only in file names in the Dired buffer.
+;;; Search only in file names in the Dired buffer
 
 (defcustom dired-isearch-filenames nil
   "Non-nil to Isearch in file names only.
@@ -3116,7 +3125,7 @@ is part of a file name (i.e., has the text property 
`dired-filename')."
   (isearch-forward-regexp nil t))
 
 
-;; Functions for searching in tags style among marked files.
+;;; Functions for searching in tags style among marked files
 
 ;;;###autoload
 (defun dired-do-isearch ()
@@ -3208,10 +3217,12 @@ REGEXP should use constructs supported by your local 
`grep' command."
                                   files))
                    (push mark files)))
                (nreverse marks))
+              (message "Searching...")
               (setq xrefs
                     (xref-matches-in-files regexp files))
               (unless xrefs
                 (user-error "No matches for: %s" regexp))
+              (message "Searching...done")
               xrefs))))
     (xref--show-xrefs fetcher nil)))
 
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 6619a39..8d99d1a 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -44,7 +44,8 @@
 ;; but maybe not if a dired-x function is being autoloaded.
 (require 'dired)
 
-;;; User-defined variables.
+
+;;; User-defined variables
 
 (defgroup dired-x nil
   "Extended directory editing (dired-x)."
@@ -217,7 +218,9 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used."
   :type 'boolean
   :group 'dired-x)
 
-;;; KEY BINDINGS.
+
+;;; Key bindings
+
 (when (keymapp (lookup-key dired-mode-map "*"))
   (define-key dired-mode-map "*(" 'dired-mark-sexp)
   (define-key dired-mode-map "*O" 'dired-mark-omitted)
@@ -234,7 +237,8 @@ to nil: a pipe using `zcat' or `gunzip -c' will be used."
 (define-key dired-mode-map "Y"  'dired-do-relsymlink)
 (define-key dired-mode-map "V" 'dired-do-run-mail)
 
-;;; MENU BINDINGS
+
+;;; Menu bindings
 
 (when-let ((menu (lookup-key dired-mode-map [menu-bar])))
   (easy-menu-add-item menu '("Operate")
@@ -274,7 +278,7 @@ files"]
                       "Refresh"))
 
 
-;; Install into appropriate hooks.
+;;; Install into appropriate hooks
 
 (add-hook 'dired-mode-hook 'dired-extra-startup)
 (add-hook 'dired-after-readin-hook 'dired-omit-expunge)
@@ -303,7 +307,7 @@ See also the functions:
   (dired-omit-startup))
 
 
-;;; EXTENSION MARKING FUNCTIONS.
+;;; Extension marking functions
 
 (defun dired--mark-suffix-interactive-spec ()
   (let* ((default
@@ -432,7 +436,7 @@ See variables `dired-texinfo-unclean-extensions',
                                 (list ".dvi"))))
 
 
-;;; OMITTING.
+;;; Omitting
 
 ;; Enhanced omitting of lines from directory listings.
 ;; Marked files are never omitted.
@@ -570,7 +574,7 @@ files in the active region if `dired-mark-region' is 
non-nil."
      msg)))
 
 
-;;; VIRTUAL DIRED MODE.
+;;; Virtual dired mode
 
 ;; For browsing `ls -lR' listings in a dired-like fashion.
 
@@ -623,7 +627,7 @@ you can relist single subdirs using \\[dired-do-redisplay]."
                     (and (looking-at "^  wildcard ")
                          (buffer-substring (match-end 0)
                                            (line-end-position))))))
-  (if wildcard
+    (if wildcard
         (setq dirname (expand-file-name wildcard default-directory))))
   ;; If raw ls listing (not a saved old dired buffer), give it a
   ;; decent subdir headerline:
@@ -693,7 +697,7 @@ Also useful for `auto-mode-alist' like this:
   (dired-virtual (dired-virtual-guess-dir)))
 
 
-;;; SMART SHELL.
+;;; Smart shell
 
 ;; An Emacs buffer can have but one working directory, stored in the
 ;; buffer-local variable `default-directory'.  A Dired buffer may have
@@ -720,30 +724,30 @@ Also useful for `auto-mode-alist' like this:
     (shell-command command output-buffer error-buffer)))
 
 
-;;; GUESS SHELL COMMAND.
+;;; Guess shell command
 
 ;; Brief Description:
-;;;
+;;
 ;; * `dired-do-shell-command' is bound to `!' by dired.el.
-;;;
+;;
 ;; * `dired-guess-shell-command' provides smarter defaults for
-;;;    dired-aux.el's `dired-read-shell-command'.
-;;;
+;;    dired-aux.el's `dired-read-shell-command'.
+;;
 ;; * `dired-guess-shell-command' calls `dired-guess-default' with list of
-;;;    marked files.
-;;;
+;;    marked files.
+;;
 ;; * Parse `dired-guess-shell-alist-user' and
-;;;   `dired-guess-shell-alist-default' (in that order) for the first REGEXP
-;;;   that matches the first file in the file list.
-;;;
+;;   `dired-guess-shell-alist-default' (in that order) for the first REGEXP
+;;   that matches the first file in the file list.
+;;
 ;; * If the REGEXP matches all the entries of the file list then evaluate
-;;;   COMMAND, which is either a string or a Lisp expression returning a
-;;;   string.  COMMAND may be a list of commands.
-;;;
+;;   COMMAND, which is either a string or a Lisp expression returning a
+;;   string.  COMMAND may be a list of commands.
+;;
 ;; * Return this command to `dired-guess-shell-command' which prompts user
-;;;   with it.  The list of commands is put into the list of default values.
-;;;   If a command is used successfully then it is stored permanently in
-;;;   `dired-shell-command-history'.
+;;   with it.  The list of commands is put into the list of default values.
+;;   If a command is used successfully then it is stored permanently in
+;;   `dired-shell-command-history'.
 
 ;; Guess what shell command to apply to a file.
 (defvar dired-shell-command-history nil
@@ -1028,7 +1032,7 @@ See `dired-guess-shell-alist-user'."
       (if (equal val "") default val))))
 
 
-;;; RELATIVE SYMBOLIC LINKS.
+;;; Relative symbolic links
 
 (declare-function make-symbolic-link "fileio.c")
 
@@ -1089,7 +1093,7 @@ results in
 
 ;;;###autoload
 (defun dired-do-relsymlink (&optional arg)
-   "Relative symlink all marked (or next ARG) files into a directory.
+  "Relative symlink all marked (or next ARG) files into a directory.
 Otherwise make a relative symbolic link to the current file.
 This creates relative symbolic links like
 
@@ -1102,7 +1106,7 @@ not absolute ones like
 For absolute symlinks, use \\[dired-do-symlink]."
   (interactive "P")
   (dired-do-create-files 'relsymlink #'dired-make-relative-symlink
-                           "RelSymLink" arg dired-keep-marker-relsymlink))
+                         "RelSymLink" arg dired-keep-marker-relsymlink))
 
 (autoload 'dired-mark-read-regexp "dired-aux")
 (autoload 'dired-do-create-files-regexp "dired-aux")
@@ -1117,30 +1121,30 @@ for more info."
    "RelSymLink" arg regexp newname whole-name dired-keep-marker-relsymlink))
 
 
-;;; VISIT ALL MARKED FILES SIMULTANEOUSLY.
+;;; Visit all marked files simultaneously
 
 ;; Brief Description:
-;;;
+;;
 ;; `dired-do-find-marked-files' is bound to `F' by dired-x.el.
-;;;
+;;
 ;; * Use `dired-get-marked-files' to collect the marked files in the current
-;;;   Dired Buffer into a list of filenames `FILE-LIST'.
-;;;
+;;   Dired Buffer into a list of filenames `FILE-LIST'.
+;;
 ;; * Pass FILE-LIST to `dired-simultaneous-find-file' all with
-;;;   `dired-do-find-marked-files''s prefix argument NOSELECT.
-;;;
+;;   `dired-do-find-marked-files''s prefix argument NOSELECT.
+;;
 ;; * `dired-simultaneous-find-file' runs through FILE-LIST decrementing the
-;;;   list each time.
-;;;
+;;   list each time.
+;;
 ;; * If NOSELECT is non-nil then just run `find-file-noselect' on each
-;;;   element of FILE-LIST.
-;;;
+;;   element of FILE-LIST.
+;;
 ;; * If NOSELECT is nil then calculate the `size' of the window for each file
-;;;   by dividing the `window-height' by length of FILE-LIST.  Thus, `size' is
-;;;   cognizant of the window-configuration.
-;;;
+;;   by dividing the `window-height' by length of FILE-LIST.  Thus, `size' is
+;;   cognizant of the window-configuration.
+;;
 ;; * If `size' is too small abort, otherwise run `find-file' on each element
-;;;   of FILE-LIST giving each a window of height `size'.
+;;   of FILE-LIST giving each a window of height `size'.
 
 (defun dired-do-find-marked-files (&optional noselect)
   "Find all marked files displaying all of them simultaneously.
@@ -1186,7 +1190,7 @@ NOSELECT the files are merely found but not selected."
         (find-file file)))))
 
 
-;;; MISCELLANEOUS COMMANDS.
+;;; Miscellaneous commands
 
 ;; Run man on files.
 
@@ -1196,8 +1200,8 @@ NOSELECT the files are merely found but not selected."
 
 (defun dired-man ()
   "Run `man' on this file."
-;; Used also to say: "Display old buffer if buffer name matches filename."
-;; but I have no idea what that means.
+  ;; Used also to say: "Display old buffer if buffer name matches filename."
+  ;; but I have no idea what that means.
   (interactive)
   (require 'man)
   (let* ((file (dired-get-filename))
@@ -1254,7 +1258,7 @@ otherwise."
          (dired-rmail)))))
 
 
-;;; MISCELLANEOUS INTERNAL FUNCTIONS.
+;;; Miscellaneous internal functions
 
 ;; This should be a builtin
 (defun dired-buffer-more-recently-used-p (buffer1 buffer2)
@@ -1264,7 +1268,6 @@ Considers buffers closer to the car of `buffer-list' to 
be more recent."
        (memq buffer1 (buffer-list))
        (not (memq buffer1 (memq buffer2 (buffer-list))))))
 
-
 ;; Needed if ls -lh is supported and also for GNU ls -ls.
 (defun dired-x--string-to-number (str)
   "Like `string-to-number' but recognize a trailing unit prefix.
@@ -1437,7 +1440,7 @@ only in the active region if `dired-mark-region' is 
non-nil."
      (format "'%s file" predicate))))
 
 
-;;; FIND FILE AT POINT.
+;;; Find file at point
 
 (defcustom dired-x-hands-off-my-keys t
   "Non-nil means don't remap `find-file' to `dired-x-find-file'.
@@ -1484,7 +1487,8 @@ a prefix argument, when it offers the filename near point 
as a default."
   (interactive (list (dired-x-read-filename-at-point "Find file: ")))
   (find-file-other-window filename))
 
-;;; Internal functions.
+
+;;; Internal functions
 
 ;; Fixme: This should probably use `thing-at-point'.  -- fx
 (define-obsolete-function-alias 'dired-filename-at-point
@@ -1532,8 +1536,9 @@ If `current-prefix-arg' is non-nil, uses name at point as 
guess."
 
 (define-obsolete-function-alias 'read-filename-at-point
   'dired-x-read-filename-at-point "24.1") ; is this even needed?
+
 
-;;; BUG REPORTS
+;;; Epilog
 
 (define-obsolete-function-alias 'dired-x-submit-report 'report-emacs-bug 
"24.1")
 
diff --git a/lisp/dired.el b/lisp/dired.el
index bb428e2..9ddd2c5 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -41,6 +41,7 @@
 (declare-function dired-buffer-more-recently-used-p
                  "dired-x" (buffer1 buffer2))
 
+
 ;;; Customizable variables
 
 (defgroup dired nil
@@ -53,7 +54,6 @@
   :prefix "dired-"
   :group 'dired)
 
-
 ;;;###autoload
 (defcustom dired-listing-switches (purecopy "-al")
   "Switches passed to `ls' for Dired.  MUST contain the `l' option.
@@ -78,9 +78,9 @@ some of the `ls' switches are not supported; see the doc 
string of
 (defcustom dired-subdir-switches nil
   "If non-nil, switches passed to `ls' for inserting subdirectories.
 If nil, `dired-listing-switches' is used."
-   :group 'dired
-   :type '(choice (const :tag "Use dired-listing-switches" nil)
-                  (string :tag "Switches")))
+  :group 'dired
+  :type '(choice (const :tag "Use dired-listing-switches" nil)
+                 (string :tag "Switches")))
 
 (defcustom dired-maybe-use-globstar nil
   "If non-nil, enable globstar if the shell supports it.
@@ -144,8 +144,8 @@ For more details, see Info node `(emacs)ls in Lisp'."
 
 (defcustom dired-touch-program "touch"
   "Name of touch command (usually `touch')."
-   :group 'dired
-   :type 'file)
+  :group 'dired
+  :type 'file)
 
 (defcustom dired-ls-F-marks-symlinks nil
   "Informs Dired about how `ls -lF' marks symbolic links.
@@ -220,7 +220,7 @@ or the most recently used window with a Dired buffer, or to 
use any other
 function.  When the value is a function, it will be called with no
 arguments and is expected to return a list of directories which will
 be used as defaults (i.e. default target and \"future history\")
-(though, `dired-dwim-target-defaults' might modify it a bit).
+\(though, `dired-dwim-target-defaults' might modify it a bit).
 The value t prefers the next windows on the same frame.
 
 The target is used in the prompt for file copy, rename etc."
@@ -247,16 +247,14 @@ The target is used in the prompt for file copy, rename 
etc."
 This is similar to the \"-L\" option for the \"cp\" shell command."
   :type 'boolean
   :group 'dired)
-                                        ;
-; These variables were deleted and the replacements are on files.el.
-; We leave aliases behind for back-compatibility.
+
+;; These variables were deleted and the replacements are on files.el.
+;; We leave aliases behind for back-compatibility.
 (define-obsolete-variable-alias 'dired-free-space-program
   'directory-free-space-program "27.1")
 (define-obsolete-variable-alias 'dired-free-space-args
   'directory-free-space-args "27.1")
 
-;;; Hook variables
-
 (defcustom dired-load-hook nil
   "Run after loading Dired.
 You can customize key bindings or load extensions with this."
@@ -358,7 +356,8 @@ is anywhere on its Dired line, except the beginning of the 
line."
   :group 'dired
   :version "28.1")
 
-;; Internal variables
+
+;;; Internal variables
 
 (defvar dired-marker-char ?*           ; the answer is 42
   ;; so that you can write things like
@@ -376,8 +375,8 @@ This is what the do-commands look for, and what the 
mark-commands store.")
   "Character used to flag files for deletion.")
 
 (defvar dired-shrink-to-fit t
-;; I see no reason ever to make this nil -- rms.
-;;  (> baud-rate search-slow-speed)
+  ;; I see no reason ever to make this nil -- rms.
+  ;;  (> baud-rate search-slow-speed)
   "Non-nil means Dired shrinks the display buffer to fit the marked files.")
 (make-obsolete-variable 'dired-shrink-to-fit
                        "use the Customization interface to add a new rule
@@ -425,7 +424,7 @@ The directory name must be absolute, but need not be fully 
expanded.")
                                  "[bcsp][^:]"))
 (defvar dired-re-exe;; match ls permission string of an executable file
   (mapconcat (lambda (x)
-               (concat dired-re-maybe-mark dired-re-inode-size x))
+              (concat dired-re-maybe-mark dired-re-inode-size x))
             '("-[-r][-w][xs][-r][-w].[-r][-w]."
               "-[-r][-w].[-r][-w][xs][-r][-w]."
               "-[-r][-w].[-r][-w].[-r][-w][xst]")
@@ -458,6 +457,9 @@ The match starts at the beginning of the line and ends 
after the end
 of the line.
 Subexpression 2 must end right before the \\n.")
 
+
+;;; Faces
+
 (defgroup dired-faces nil
   "Faces used by Dired."
   :group 'dired
@@ -561,6 +563,9 @@ Subexpression 2 must end right before the \\n.")
 (defvar dired-ignored-face 'dired-ignored
   "Face name used for files suffixed with `completion-ignored-extensions'.")
 
+
+;;; Font-lock
+
 (defvar dired-font-lock-keywords
   (list
    ;;
@@ -684,12 +689,15 @@ Subexpression 2 must end right before the \\n.")
    ;;
    ;; Directory headers.
    (list dired-subdir-regexp '(1 dired-header-face))
-)
+   )
   "Additional expressions to highlight in Dired mode.")
 
 (defvar dnd-protocol-alist)
+
 
-;;; Macros must be defined before they are used, for the byte compiler.
+;;; Macros
+
+;; Macros must be defined before they are used, for the byte compiler.
 
 (defmacro dired-mark-if (predicate msg)
   "Mark files for PREDICATE, according to `dired-marker-char'.
@@ -884,7 +892,7 @@ ERROR can be a string with the error message."
     (point-max)))
 
 
-;; The dired command
+;;; The dired command
 
 (defun dired-read-dir-and-switches (str)
   ;; For use in interactive.
@@ -1264,7 +1272,7 @@ The return value is the target column for the file names."
       found)))
 
 
-;; Read in a new dired buffer
+;;; Read in a new dired buffer
 
 (defun dired-readin ()
   "Read in a new Dired buffer.
@@ -1628,8 +1636,9 @@ see `dired-use-ls-dired' for more details.")
            (put-text-property (+ (point) 4) (line-end-position)
                               'invisible 'dired-hide-details-link))))
       (forward-line 1))))
+
 
-;; Reverting a dired buffer
+;;; Reverting a dired buffer
 
 (defun dired-revert (&optional _arg _noconfirm)
   "Reread the Dired buffer.
@@ -1816,8 +1825,9 @@ Do so according to the former subdir alist 
OLD-SUBDIR-ALIST."
   (let ((handler (find-file-name-handler dir 'dired-uncache)))
     (if handler
        (funcall handler 'dired-uncache dir))))
+
 
-;; dired mode key bindings and initialization
+;;; Dired mode key bindings and menus
 
 (defvar dired-mode-map
   ;; This looks ugly when substitute-command-keys uses C-d instead d:
@@ -1969,7 +1979,7 @@ Do so according to the former subdir alist 
OLD-SUBDIR-ALIST."
     ;; No need to do this, now that top-level items are fewer.
     ;;;;
     ;; Get rid of the Edit menu bar item to save space.
-    ;(define-key map [menu-bar edit] 'undefined)
+    ;;(define-key map [menu-bar edit] 'undefined)
 
     map)
   "Local keymap for Dired mode buffers.")
@@ -2178,6 +2188,8 @@ Do so according to the former subdir alist 
OLD-SUBDIR-ALIST."
      :help "Delete image tag from current or marked files"]))
 
 
+;;; Dired mode
+
 ;; Dired mode is suitable only for specially formatted data.
 (put 'dired-mode 'mode-class 'special)
 
@@ -2275,14 +2287,16 @@ Keybindings:
   (add-hook 'file-name-at-point-functions #'dired-file-name-at-point nil t)
   (add-hook 'isearch-mode-hook #'dired-isearch-filenames-setup nil t)
   (run-mode-hooks 'dired-mode-hook))
+
 
-;; Idiosyncratic dired commands that don't deal with marks.
+;;; Idiosyncratic dired commands that don't deal with marks
 
 (defun dired-summary ()
   "Summarize basic Dired commands and show recent Dired errors."
   (interactive)
   (dired-why)
-  ;>> this should check the key-bindings and use substitute-command-keys if 
non-standard
+  ;; FIXME this should check the key-bindings and use
+  ;; substitute-command-keys if non-standard
   (message
    "d-elete, u-ndelete, x-punge, f-ind, o-ther window, R-ename, C-opy, h-elp"))
 
@@ -2473,8 +2487,9 @@ Otherwise, display it in another buffer."
   (interactive)
   (display-buffer (find-file-noselect (dired-get-file-for-visit))
                  t))
+
 
-;;; Functions for extracting and manipulating file names in Dired buffers.
+;;; Functions for extracting and manipulating file names in Dired buffers
 
 (defun dired-unhide-subdir ()
   (with-silent-modifications
@@ -2581,7 +2596,7 @@ Otherwise, an error occurs in these cases."
       (concat (dired-current-directory localp) file)))))
 
 (defun dired-string-replace-match (regexp string newtext
-                                   &optional literal global)
+                                          &optional literal global)
   "Replace first match of REGEXP in STRING with NEWTEXT.
 If it does not match, nil is returned instead of the new string.
 Optional arg LITERAL means to take NEWTEXT literally.
@@ -2592,7 +2607,7 @@ Optional arg GLOBAL means to replace all matches."
          (let ((from-end (- (length string) (match-end 0))))
            (setq ret (setq string (replace-match newtext t literal string)))
            (setq start (- (length string) from-end))))
-         ret)
+       ret)
     (if (not (string-match regexp string 0))
        nil
       (replace-match newtext t literal string))))
@@ -2619,7 +2634,10 @@ unchanged."
   (if (string-match (concat "^" (regexp-quote dir)) file)
       (substring file (match-end 0))
     file))
+
 
+;;; Mode to hide details
+
 (define-minor-mode dired-hide-details-mode
   "Toggle visibility of detailed information in current Dired buffer.
 When this minor mode is enabled, details such as file ownership and
@@ -2656,6 +2674,7 @@ See options: `dired-hide-details-hide-symlink-targets' and
               'add-to-invisibility-spec
             'remove-from-invisibility-spec)
           'dired-hide-details-link))
+
 
 ;;; Functions to hide/unhide text
 
@@ -2685,7 +2704,7 @@ See options: `dired-hide-details-hide-symlink-targets' and
      (progn (goto-char end) (line-end-position))
      '(invisible))))
 
-;;; Functions for finding the file name in a dired buffer line.
+;;; Functions for finding the file name in a dired buffer line
 
 (defvar dired-permission-flags-regexp
   "\\([^ ]\\)[-r][-w]\\([^ ]\\)[-r][-w]\\([^ ]\\)[-r][-w]\\([^ ]\\)"
@@ -2776,15 +2795,15 @@ If EOL, it should be an position to use instead of
       (or no-error
          (not (eq opoint (point)))
          (error "%s" (if hidden
-                    (substitute-command-keys
-                     "File line is hidden, type \\[dired-hide-subdir] to 
unhide")
-                  "No file on this line")))
+                          (substitute-command-keys
+                           "File line is hidden, type \\[dired-hide-subdir] to 
unhide")
+                        "No file on this line")))
       (if (eq opoint (point))
          nil
        (point)))))
 
 
-;;; COPY NAMES OF MARKED FILES INTO KILL-RING.
+;;; Copy names of marked files into kill-ring
 
 (defun dired-copy-filename-as-kill (&optional arg)
   "Copy names of marked (or next ARG) files into the kill ring.
@@ -2818,7 +2837,7 @@ You can then feed the file name(s) to other commands with 
\\[yank]."
       (message "%s" string))))
 
 
-;; Keeping Dired buffers in sync with the filesystem and with each other
+;;; Keeping Dired buffers in sync with the filesystem and with each other
 
 (defun dired-buffers-for-dir (dir &optional file subdirs)
   "Return a list of buffers for DIR (top level or in-situ subdir).
@@ -2887,8 +2906,6 @@ dired-buffers."
             (substring pattern matched-in-pattern))
            "\\'")))
 
-
-
 (defun dired-advertise ()
   ;;"Advertise in variable `dired-buffers' that we dired `default-directory'."
   ;; With wildcards we actually advertise too much.
@@ -2906,10 +2923,9 @@ dired-buffers."
   ;; Removing is also done as a side-effect in dired-buffer-for-dir.
   (setq dired-buffers
        (delq (assoc (expand-file-name dir) dired-buffers) dired-buffers)))
-
-;; Tree Dired
 
-;;; utility functions
+
+;;; Utility functions
 
 (defun dired-in-this-tree-p (file dir)
   ;;"Is FILE part of the directory tree starting at DIR?"
@@ -2936,8 +2952,8 @@ dired-buffers."
       (beginning-of-line)              ; alist stores b-o-l positions
       (and (zerop (- (point)
                      (cdr (assoc cur-dir
-                                                 dired-subdir-alist))))
-          cur-dir))))
+                                 dired-subdir-alist))))
+           cur-dir))))
 
 (define-obsolete-function-alias 'dired-get-subdir-min 'cdr "27.1")
 
@@ -3046,11 +3062,11 @@ instead of `dired-actual-switches'."
                    new-dir-name)
              (setq new-dir-name res)))
          (dired-alist-add-1 new-dir-name
-           ;; Place a sub directory boundary between lines.
-           (save-excursion
-             (goto-char (match-beginning 0))
-             (beginning-of-line)
-             (point-marker)))))
+                             ;; Place a sub directory boundary between lines.
+                             (save-excursion
+                               (goto-char (match-beginning 0))
+                               (beginning-of-line)
+                               (point-marker)))))
       (if (and (> count 1) (called-interactively-p 'interactive))
          (message "Buffer includes %d directories" count)))
     ;; We don't need to sort it because it is in buffer order per
@@ -3169,7 +3185,7 @@ It runs the hook `dired-initial-position-hook'."
        (dired-goto-subdir dirname))
   (if dired-trivial-filenames (dired-goto-next-nontrivial-file))
   (run-hooks 'dired-initial-position-hook))
-
+
 ;; These are hooks which make tree dired work.
 ;; They are in this file because other parts of dired need to call them.
 ;; But they don't call the rest of tree dired unless there are subdirs loaded.
@@ -3208,8 +3224,9 @@ is the directory where the file on this line resides."
     (if (or (null (cdr dired-subdir-alist)) (not (dired-next-subdir 1 t t)))
        (point-max)
       (point))))
+
 
-;; Deleting files
+;;; Deleting files
 
 (defcustom dired-recursive-deletes 'top
   "Whether Dired deletes directories recursively.
@@ -3378,7 +3395,7 @@ non-empty directories is allowed."
 (defun dired-fun-in-all-buffers (directory file fun &rest args)
   "In all buffers dired'ing DIRECTORY, run FUN with ARGS.
 If the buffer has a wildcard pattern, check that it matches FILE.
-(FILE does not include a directory component.)
+\(FILE does not include a directory component.)
 FILE may be nil, in which case ignore it.
 Return list of buffers where FUN succeeded (i.e., returned non-nil)."
   (let (success-list)
@@ -3450,7 +3467,7 @@ confirmation.  To disable the confirmation, see
              (kill-buffer buf))))))
 
 
-;; Confirmation
+;;; Confirmation
 
 (defun dired-marker-regexp ()
   (concat "^" (regexp-quote (char-to-string dired-marker-char))))
@@ -3569,8 +3586,9 @@ argument or confirmation)."
   (let ((beg (point)))
     (completion--insert-strings files)
     (put-text-property beg (point) 'mouse-face nil)))
+
 
-;; Commands to mark or flag file(s) at or near current line.
+;;; Commands to mark or flag file(s) at or near current line
 
 (defun dired-repeat-over-lines (arg function)
   ;; This version skips non-file lines.
@@ -3758,8 +3776,9 @@ on the whole buffer."
                        (list ?\s dired-marker-char)
                      (list dired-marker-char ?\s))))
         (forward-line 1)))))
+
 
-;;; Commands to mark or flag files based on their characteristics or names.
+;;; Commands to mark or flag files based on their characteristics or names
 
 (defvar dired-regexp-history nil
   "History list of regular expressions used in Dired commands.")
@@ -3860,8 +3879,7 @@ since it was last visited."
                  (with-temp-buffer
                    (insert-file-contents fn)
                    (goto-char (point-min))
-                   (re-search-forward regexp nil t))))
-                     )))
+                   (re-search-forward regexp nil t)))))))
      "matching file")))
 
 (defun dired-flag-files-regexp (regexp)
@@ -4036,8 +4054,9 @@ Type SPC or `y' to unmark one file, DEL or `n' to skip to 
next,
       (message (if (= count 1) "1 mark removed"
                 "%d marks removed")
               count))))
+
 
-;; Logging failures operating on files, and showing the results.
+;;; Logging failures operating on files, and showing the results
 
 (defvar dired-log-buffer "*Dired log*")
 
@@ -4102,6 +4121,7 @@ or nil if file names are not applicable."
   ;; Log a summary describing a bunch of errors.
   (dired-log (concat "\n" string "\n"))
   (dired-log t))
+
 
 ;;; Sorting
 
@@ -4283,9 +4303,9 @@ To be called first in body of `dired-sort-other', etc."
            ;; No pre-R subdir alist, so revert to main directory
            ;; listing:
            (list (car (reverse dired-subdir-alist))))))))
-
 
-;;;;  Drag and drop support
+
+;;; Drag and drop support
 
 (defcustom dired-recursive-copies 'top
   "Whether Dired copies directories recursively.
@@ -4387,9 +4407,9 @@ Ask means pop up a menu for the user to select one of 
copy, move or link."
   (let ((local-file (dnd-get-local-file-uri uri)))
     (if local-file (dired-dnd-handle-local-file local-file action)
       nil)))
-
 
-;;;;  Desktop support
+
+;;; Desktop support
 
 (eval-when-compile (require 'desktop))
 (declare-function desktop-file-name "desktop" (filename dirname))
@@ -4406,10 +4426,10 @@ Ask means pop up a menu for the user to select one of 
copy, move or link."
      (desktop-file-name dired-directory dirname))
    ;; Subdirectories in `dired-subdir-alist'.
    (cdr
-     (nreverse
-       (mapcar
-        (lambda (f) (desktop-file-name (car f) dirname))
-         dired-subdir-alist)))))
+    (nreverse
+     (mapcar
+      (lambda (f) (desktop-file-name (car f) dirname))
+      dired-subdir-alist)))))
 
 (defun dired-restore-desktop-buffer (_file-name
                                      _buffer-name
@@ -4435,7 +4455,7 @@ Ask means pop up a menu for the user to select one of 
copy, move or link."
             '(dired-mode . dired-restore-desktop-buffer))
 
 
-;;;; Jump to Dired
+;;; Jump to Dired
 
 (defvar archive-superior-buffer)
 (defvar tar-superior-buffer)
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 472e0ba..3e65db4 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -2066,73 +2066,73 @@ See also `emacs-lisp-byte-compile-and-load'."
          (message "Compiling %s...done" filename))
        (kill-buffer input-buffer)
        (with-current-buffer output-buffer
-         (goto-char (point-max))
-         (insert "\n")                 ; aaah, unix.
-         (cond
-          ((null target-file) nil)     ;We only wanted the warnings!
-          ((and (or (null byte-native-compiling)
-                     (and byte-native-compiling byte+native-compile))
-                 (file-writable-p target-file)
-                ;; We attempt to create a temporary file in the
-                ;; target directory, so the target directory must be
-                ;; writable.
-                (file-writable-p
-                 (file-name-directory
-                  ;; Need to expand in case TARGET-FILE doesn't
-                  ;; include a directory (Bug#45287).
-                  (expand-file-name target-file))))
-           ;; We must disable any code conversion here.
-           (let* ((coding-system-for-write 'no-conversion)
-                  ;; Write to a tempfile so that if another Emacs
-                  ;; process is trying to load target-file (eg in a
-                  ;; parallel bootstrap), it does not risk getting a
-                  ;; half-finished file.  (Bug#4196)
-                  (tempfile
-                   (make-temp-file (when (file-writable-p target-file)
-                                      (expand-file-name target-file))))
-                  (default-modes (default-file-modes))
-                  (temp-modes (logand default-modes #o600))
-                  (desired-modes (logand default-modes #o666))
-                  (kill-emacs-hook
-                   (cons (lambda () (ignore-errors
-                                 (delete-file tempfile)))
-                         kill-emacs-hook)))
-             (unless (= temp-modes desired-modes)
-               (set-file-modes tempfile desired-modes 'nofollow))
-             (write-region (point-min) (point-max) tempfile nil 1)
-             ;; This has the intentional side effect that any
-             ;; hard-links to target-file continue to
-             ;; point to the old file (this makes it possible
-             ;; for installed files to share disk space with
-             ;; the build tree, without causing problems when
-             ;; emacs-lisp files in the build tree are
-             ;; recompiled).  Previously this was accomplished by
-             ;; deleting target-file before writing it.
-             (if byte-native-compiling
-                  ;; Defer elc final renaming.
-                  (setf byte-to-native-output-file
-                        (cons tempfile target-file))
-                (rename-file tempfile target-file t)))
-           (or noninteractive
-               byte-native-compiling
-               (message "Wrote %s" target-file)))
-           ((file-writable-p target-file)
-            ;; In case the target directory isn't writable (see e.g. 
Bug#44631),
-            ;; try writing to the output file directly.  We must disable any
-            ;; code conversion here.
-            (let ((coding-system-for-write 'no-conversion))
-              (with-file-modes (logand (default-file-modes) #o666)
-                (write-region (point-min) (point-max) target-file nil 1)))
-            (or noninteractive (message "Wrote %s" target-file)))
-          (t
-           ;; This is just to give a better error message than write-region
-           (let ((exists (file-exists-p target-file)))
-             (signal (if exists 'file-error 'file-missing)
-                     (list "Opening output file"
-                           (if exists
-                               "Cannot overwrite file"
-                             "Directory not writable or nonexistent")
-                           target-file)))))
+          (when (and target-file
+                     (or (not byte-native-compiling)
+                         (and byte-native-compiling byte+native-compile)))
+           (goto-char (point-max))
+           (insert "\n")                       ; aaah, unix.
+           (cond
+            ((and (file-writable-p target-file)
+                  ;; We attempt to create a temporary file in the
+                  ;; target directory, so the target directory must be
+                  ;; writable.
+                  (file-writable-p
+                   (file-name-directory
+                    ;; Need to expand in case TARGET-FILE doesn't
+                    ;; include a directory (Bug#45287).
+                    (expand-file-name target-file))))
+             ;; We must disable any code conversion here.
+             (let* ((coding-system-for-write 'no-conversion)
+                    ;; Write to a tempfile so that if another Emacs
+                    ;; process is trying to load target-file (eg in a
+                    ;; parallel bootstrap), it does not risk getting a
+                    ;; half-finished file.  (Bug#4196)
+                    (tempfile
+                     (make-temp-file (when (file-writable-p target-file)
+                                        (expand-file-name target-file))))
+                    (default-modes (default-file-modes))
+                    (temp-modes (logand default-modes #o600))
+                    (desired-modes (logand default-modes #o666))
+                    (kill-emacs-hook
+                     (cons (lambda () (ignore-errors
+                                   (delete-file tempfile)))
+                           kill-emacs-hook)))
+               (unless (= temp-modes desired-modes)
+                 (set-file-modes tempfile desired-modes 'nofollow))
+               (write-region (point-min) (point-max) tempfile nil 1)
+               ;; This has the intentional side effect that any
+               ;; hard-links to target-file continue to
+               ;; point to the old file (this makes it possible
+               ;; for installed files to share disk space with
+               ;; the build tree, without causing problems when
+               ;; emacs-lisp files in the build tree are
+               ;; recompiled).  Previously this was accomplished by
+               ;; deleting target-file before writing it.
+               (if byte-native-compiling
+                    ;; Defer elc final renaming.
+                    (setf byte-to-native-output-file
+                          (cons tempfile target-file))
+                  (rename-file tempfile target-file t)))
+             (or noninteractive
+                 byte-native-compiling
+                 (message "Wrote %s" target-file)))
+             ((file-writable-p target-file)
+              ;; In case the target directory isn't writable (see e.g. 
Bug#44631),
+              ;; try writing to the output file directly.  We must disable any
+              ;; code conversion here.
+              (let ((coding-system-for-write 'no-conversion))
+                (with-file-modes (logand (default-file-modes) #o666)
+                  (write-region (point-min) (point-max) target-file nil 1)))
+              (or noninteractive (message "Wrote %s" target-file)))
+            (t
+             ;; This is just to give a better error message than write-region
+             (let ((exists (file-exists-p target-file)))
+               (signal (if exists 'file-error 'file-missing)
+                       (list "Opening output file"
+                             (if exists
+                                 "Cannot overwrite file"
+                               "Directory not writable or nonexistent")
+                             target-file))))))
          (kill-buffer (current-buffer)))
        (if (and byte-compile-generate-call-tree
                 (or (eq t byte-compile-generate-call-tree)
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index eabba27..3840d13 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -847,7 +847,7 @@ PROPLIST is a list of the sort returned by `symbol-plist'.
               "\n")))
    "\n"))
 
-(defun cl--print-table (header rows)
+(defun cl--print-table (header rows &optional last-slot-on-next-line)
   ;; FIXME: Isn't this functionality already implemented elsewhere?
   (let ((cols (apply #'vector (mapcar #'string-width header)))
         (col-space 2))
@@ -877,7 +877,11 @@ PROPLIST is a list of the sort returned by `symbol-plist'.
                                header))
                 "\n")
         (dolist (row rows)
-          (insert (apply #'format format row) "\n"))))))
+          (insert (apply #'format format row) "\n")
+          (when last-slot-on-next-line
+            (dolist (line (string-lines (car (last row))))
+              (insert "    " line "\n"))
+            (insert "\n")))))))
 
 (defun cl--describe-class-slots (class)
   "Print help description for the slots in CLASS.
@@ -897,14 +901,13 @@ Outputs to the current buffer."
                (list (cl-prin1-to-string (cl--slot-descriptor-name slot))
                      (cl-prin1-to-string (cl--slot-descriptor-type slot))
                      (cl-prin1-to-string (cl--slot-descriptor-initform slot))
-                     (let ((doc (plist-get (cl--slot-descriptor-props slot)
-                                           :documentation)))
+                     (let ((doc (alist-get :documentation
+                                           (cl--slot-descriptor-props slot))))
                        (if (not doc) ""
                          (setq has-doc t)
                          (substitute-command-keys doc)))))
              slots)))
-      (cl--print-table `("Name" "Type" "Default" . ,(if has-doc '("Doc")))
-                       slots-strings))
+      (cl--print-table `("Name" "Type" "Default") slots-strings has-doc))
     (insert "\n")
     (when (> (length cslots) 0)
       (insert (propertize "\nClass Allocated Slots:\n\n" 'face 'bold))
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index a59d42e..cff4368 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -3276,6 +3276,13 @@ STRUCT-TYPE is a symbol naming a struct type.  Return 
`record',
   (declare (side-effect-free t) (pure t))
   (cl--struct-class-type (cl--struct-get-class struct-type)))
 
+(defun cl--alist-to-plist (alist)
+  (let ((res '()))
+    (dolist (x alist)
+      (push (car x) res)
+      (push (cdr x) res))
+    (nreverse res)))
+
 (defun cl-struct-slot-info (struct-type)
   "Return a list of slot names of struct STRUCT-TYPE.
 Each entry is a list (SLOT-NAME . OPTS), where SLOT-NAME is a
@@ -3293,7 +3300,7 @@ slots skipped by :initial-offset may appear in the list."
                 ,(cl--slot-descriptor-initform slot)
                 ,@(if (not (eq (cl--slot-descriptor-type slot) t))
                       `(:type ,(cl--slot-descriptor-type slot)))
-                ,@(cl--slot-descriptor-props slot))
+                ,@(cl--alist-to-plist (cl--slot-descriptor-props slot)))
               descs)))
     (nreverse descs)))
 
diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el
index 7365e23..ef60b26 100644
--- a/lisp/emacs-lisp/cl-preloaded.el
+++ b/lisp/emacs-lisp/cl-preloaded.el
@@ -124,12 +124,11 @@ supertypes from the most specific to least specific.")
                             (get name 'cl-struct-print))
           (cl--find-class name)))))
 
-(defun cl--plist-remove (plist member)
-  (cond
-   ((null plist) nil)
-   ((null member) plist)
-   ((eq plist member) (cddr plist))
-   (t `(,(car plist) ,(cadr plist) ,@(cl--plist-remove (cddr plist) member)))))
+(defun cl--plist-to-alist (plist)
+  (let ((res '()))
+    (while plist
+      (push (cons (pop plist) (pop plist)) res))
+    (nreverse res)))
 
 (defun cl--struct-register-child (parent tag)
   ;; Can't use (cl-typep parent 'cl-structure-class) at this stage
@@ -164,12 +163,14 @@ supertypes from the most specific to least specific.")
                        (i 0)
                        (offset (if type 0 1)))
                    (dolist (slot slots)
-                     (let* ((props (cddr slot))
-                            (typep (plist-member props :type))
-                            (type (if typep (cadr typep) t)))
+                     (let* ((props (cl--plist-to-alist (cddr slot)))
+                            (typep (assq :type props))
+                            (type (if (null typep) t
+                                    (setq props (delq typep props))
+                                    (cdr typep))))
                        (aset v i (cl--make-slot-desc
                                   (car slot) (nth 1 slot)
-                                  type (cl--plist-remove props typep))))
+                                  type props)))
                      (puthash (car slot) (+ i offset) index-table)
                      (cl-incf i))
                    v))
diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index e106815..d24ea35 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -183,8 +183,7 @@ Return t if the current element is now a valid match; 
otherwise return nil."
 Like `minibuffer-complete-word' but for `completing-read-multiple'."
   (interactive)
   (crm--completion-command beg end
-    (completion-in-region--single-word
-     beg end minibuffer-completion-table minibuffer-completion-predicate)))
+    (completion-in-region--single-word beg end)))
 
 (defun crm-complete-and-exit ()
   "If all of the minibuffer elements are valid completions then exit.
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index 0a6d4ec..3a00fdb 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -84,18 +84,22 @@ replacing its case-insensitive matches with the literal 
string in LIGHTER."
 (defconst easy-mmode--arg-docstring
   "
 
-If called interactively, toggle `%s'.  If the prefix argument is
-positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `%s'
+mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.
 Enable the mode if ARG is nil, omitted, or is a positive number.
 Disable the mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `%S'.
+
 The mode's hook is called both when the mode is enabled and when
 it is disabled.")
 
-(defun easy-mmode--mode-docstring (doc mode-pretty-name keymap-sym)
+(defun easy-mmode--mode-docstring (doc mode-pretty-name keymap-sym
+                                       getter)
   (let ((doc (or doc (format "Toggle %s on or off.
 
 \\{%s}" mode-pretty-name keymap-sym))))
@@ -104,7 +108,8 @@ it is disabled.")
       (let* ((fill-prefix nil)
              (docs-fc (bound-and-true-p emacs-lisp-docstring-fill-column))
              (fill-column (if (integerp docs-fc) docs-fc 65))
-             (argdoc (format easy-mmode--arg-docstring mode-pretty-name))
+             (argdoc (format easy-mmode--arg-docstring mode-pretty-name
+                             getter))
              (filled (if (fboundp 'fill-region)
                          (with-temp-buffer
                            (insert argdoc)
@@ -308,7 +313,8 @@ or call the function `%s'."))))
        ,(funcall
          warnwrap
          `(defun ,modefun (&optional arg ,@extra-args)
-            ,(easy-mmode--mode-docstring doc pretty-name keymap-sym)
+            ,(easy-mmode--mode-docstring doc pretty-name keymap-sym
+                                         getter)
             ,(when interactive
               ;; Use `toggle' rather than (if ,mode 0 1) so that using
               ;; repeat-command still does the toggling correctly.
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index 6793b37..92acfe7 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -313,12 +313,13 @@ It should only be stopped when ran from inside 
ert--run-test-internal."
                                  (list :form `(,,fn ,@,args))
                                  (unless (eql ,value ',default-value)
                                    (list :value ,value))
-                                 (let ((-explainer-
-                                        (and (symbolp ',fn-name)
-                                             (get ',fn-name 'ert-explainer))))
-                                   (when -explainer-
-                                     (list :explanation
-                                           (apply -explainer- ,args)))))
+                                 (unless (eql ,value ',default-value)
+                                   (let ((-explainer-
+                                          (and (symbolp ',fn-name)
+                                               (get ',fn-name 
'ert-explainer))))
+                                     (when -explainer-
+                                       (list :explanation
+                                             (apply -explainer- ,args))))))
                          value)
                ,value))))))))
 
@@ -1300,7 +1301,7 @@ empty string."
   "Pretty-print OBJECT, indenting it to the current column of point.
 Ensures a final newline is inserted."
   (let ((begin (point))
-        (pp-escape-newlines nil)
+        (pp-escape-newlines t)
         (print-escape-control-characters t))
     (pp object (current-buffer))
     (unless (bolp) (insert "\n"))
@@ -1551,7 +1552,7 @@ Ran \\([0-9]+\\) tests, \\([0-9]+\\) results as expected\
     (when badtests
       (message "%d files did not finish:" (length badtests))
       (mapc (lambda (l) (message "  %s" l)) badtests)
-      (if (getenv "EMACS_HYDRA_CI")
+      (if (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI"))
           (with-temp-buffer
             (dolist (f badtests)
               (erase-buffer)
@@ -1567,8 +1568,8 @@ Ran \\([0-9]+\\) tests, \\([0-9]+\\) results as expected\
       (setq tests (sort tests (lambda (x y) (> (car x) (car y)))))
       (when (< high (length tests)) (setcdr (nthcdr (1- high) tests) nil))
       (message "%s" (mapconcat #'cdr tests "\n")))
-    ;; More details on hydra, where the logs are harder to get to.
-    (when (and (getenv "EMACS_HYDRA_CI")
+    ;; More details on hydra and emba, where the logs are harder to get to.
+    (when (and (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI"))
                (not (zerop (+ nunexpected nskipped))))
       (message "\nDETAILS")
       (message "-------")
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index 58876a4..7bc3e6b 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -123,10 +123,18 @@ should insert the feature name."
   :group 'xref
   :version "25.1")
 
+(defun find-function--defface (symbol)
+  (catch 'found
+    (while (re-search-forward (format find-face-regexp symbol) nil t)
+      (unless (ppss-comment-or-string-start
+               (save-excursion (syntax-ppss (match-beginning 0))))
+        ;; We're not in a comment or a string.
+        (throw 'found t)))))
+
 (defvar find-function-regexp-alist
   '((nil . find-function-regexp)
     (defvar . find-variable-regexp)
-    (defface . find-face-regexp)
+    (defface . find-function--defface)
     (feature . find-feature-regexp)
     (defalias . find-alias-regexp))
   "Alist mapping definition types into regexp variables.
diff --git a/lisp/emacs-lisp/lisp-mnt.el b/lisp/emacs-lisp/lisp-mnt.el
index 73a33a5..83da495 100644
--- a/lisp/emacs-lisp/lisp-mnt.el
+++ b/lisp/emacs-lisp/lisp-mnt.el
@@ -360,10 +360,10 @@ Return argument is of the form (\"HOLDER\" \"YEAR1\" ... 
\"YEARN\")"
   "Split up an email address X into full name and real email address.
 The value is a cons of the form (FULLNAME . ADDRESS)."
   (cond ((string-match "\\(.+\\) [(<]\\(\\S-+@\\S-+\\)[>)]" x)
-        (cons (match-string 1 x)
+        (cons (string-trim-right (match-string 1 x))
               (match-string 2 x)))
        ((string-match "\\(\\S-+@\\S-+\\) [(<]\\(.*\\)[>)]" x)
-        (cons (match-string 2 x)
+        (cons (string-trim-right (match-string 2 x))
               (match-string 1 x)))
        ((string-match "\\S-+@\\S-+" x)
         (cons nil x))
@@ -378,14 +378,22 @@ the cdr is an email address."
     (let ((authorlist (lm-header-multiline "author")))
       (mapcar #'lm-crack-address authorlist))))
 
+(defun lm-maintainers (&optional file)
+  "Return the maintainer list of file FILE, or current buffer if FILE is nil.
+If the maintainers are unspecified, then return the authors.
+Each element of the list is a cons; the car is the full name,
+the cdr is an email address."
+  (lm-with-file file
+    (mapcar #'lm-crack-address
+            (or (lm-header-multiline "maintainer")
+                (lm-header-multiline "author")))))
+
 (defun lm-maintainer (&optional file)
   "Return the maintainer of file FILE, or current buffer if FILE is nil.
+If the maintainer is unspecified, then return the author.
 The return value has the form (NAME . ADDRESS)."
-  (lm-with-file file
-    (let ((maint (lm-header "maintainer")))
-      (if maint
-         (lm-crack-address maint)
-       (car (lm-authors))))))
+  (declare (obsolete lm-maintainers "28.1"))
+  (car (lm-maintainers file)))
 
 (defun lm-creation-date (&optional file)
   "Return the created date given in file FILE, or current buffer if FILE is 
nil."
@@ -545,7 +553,7 @@ copyright notice is allowed."
                "Can't find package name")
               ((not (lm-authors))
                "`Author:' tag missing")
-              ((not (lm-maintainer))
+              ((not (lm-maintainers))
                "`Maintainer:' tag missing")
               ((not (lm-summary))
                "Can't find the one-line summary description")
@@ -613,7 +621,7 @@ Prompts for bug subject TOPIC.  Leaves you in a mail 
buffer."
   (interactive "sBug Subject: ")
   (require 'emacsbug)
   (let ((package (lm-get-package-name))
-       (addr (lm-maintainer))
+       (addr (car (lm-maintainers)))
        (version (lm-version)))
     (compose-mail (if addr
                      (concat (car addr) " <" (cdr addr) ">")
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 59325d6..51fb885 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -765,7 +765,7 @@ All commands in `lisp-mode-shared-map' are inherited by 
this map.")
      :help "Run an inferior Lisp process, input and output via buffer 
`*inferior-lisp*'"]))
 
 (define-derived-mode lisp-mode lisp-data-mode "Lisp"
-  "Major mode for editing Lisp code for Lisps other than GNU Emacs Lisp.
+  "Major mode for editing programs in Common Lisp and other similar Lisps.
 Commands:
 Delete converts tabs to spaces as it moves back.
 Blank lines separate paragraphs.  Semicolons start comments.
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 5df9b53..a0f1ab0 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -3374,7 +3374,8 @@ If optional arg BUTTON is non-nil, describe its 
associated package."
         (forward-line 1)))))
 
 (defvar package--quick-help-keys
-  '(("install," "delete," "unmark," ("execute" . 1))
+  '((("mark for installation," . 9)
+     ("mark for deletion," . 9) "unmark," ("execute marked actions" . 1))
     ("next," "previous")
     ("Hide-package," "(-toggle-hidden")
     ("g-refresh-contents," "/-filter," "help")))
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index 16e8307..4df4040 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -268,6 +268,9 @@ There can be any number of :example/:result elements."
    :eval (file-name-extension "/tmp/foo.txt"))
   (file-name-sans-extension
    :eval (file-name-sans-extension "/tmp/foo.txt"))
+  (file-name-with-extension
+   :eval (file-name-with-extension "foo.txt" "bin")
+   :eval (file-name-with-extension "foo" "bin"))
   (file-name-base
    :eval (file-name-base "/tmp/foo.txt"))
   (file-relative-name
@@ -887,7 +890,7 @@ There can be any number of :example/:result elements."
   (lock-buffer
    :no-value (lock-buffer "/tmp/foo"))
   (unlock-buffer
-   :no-value (lock-buffer)))
+   :no-value (unlock-buffer)))
 
 (define-short-documentation-group overlay
   "Predicates"
@@ -1283,11 +1286,11 @@ Example:
   (let ((glist (assq group shortdoc--groups)))
     (unless glist
       (setq glist (list group))
-      (setq shortdoc--groups (append shortdoc--groups (list glist))))
+      (push glist shortdoc--groups))
     (let ((slist (member section glist)))
       (unless slist
         (setq slist (list section))
-        (setq slist (append glist slist)))
+        (nconc glist slist))
       (while (and (cdr slist)
                   (not (stringp (cadr slist))))
         (setq slist (cdr slist)))
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 1c13c39..468d124 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -317,6 +317,7 @@ than this function."
      (end (substring string (- (length string) length)))
      (t (substring string 0 length)))))
 
+;;;###autoload
 (defun string-lines (string &optional omit-nulls)
   "Split STRING into a list of lines.
 If OMIT-NULLS, empty lines will be removed from the results."
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index ea9f9a3..7a17ee2 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -1761,7 +1761,7 @@ See `erc-display-server-message'." nil
      's324 ?c channel ?m modes)))
 
 (define-erc-response-handler (328)
-  "Channel URL (on freenode network)." nil
+  "Channel URL." nil
   (let ((channel (cadr (erc-response.command-args parsed)))
         (url (erc-response.contents parsed)))
     (erc-display-message parsed 'notice (erc-get-buffer channel proc)
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index aed02a9..54502b2 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -290,6 +290,13 @@
   ("LagNet: Random server" LagNet "irc.lagnet.org.za" 6667)
   ("LagNet: AF, ZA, Cape Town" LagNet "reaper.lagnet.org.za" 6667)
   ("LagNet: AF, ZA, Johannesburg" LagNet "mystery.lagnet.org.za" 6667)
+  ("Libera.Chat: Random server" Libera.Chat "irc.libera.chat" 6667)
+  ("Libera.Chat: Random Europe server" Libera.Chat "irc.eu.libera.chat" 6667)
+  ("Libera.Chat: Random US & Canada server" Libera.Chat "irc.us.libera.chat" 
6667)
+  ("Libera.Chat: Random Australia & New Zealand server" Libera.Chat 
"irc.au.libera.chat" 6667)
+  ("Libera.Chat: Random East Asia server" Libera.Chat "irc.ea.libera.chat" 
6667)
+  ("Libera.Chat: IPv4 only server" Libera.Chat "irc.ipv4.libera.chat" 6667)
+  ("Libera.Chat: IPv6 only server" Libera.Chat "irc.ipv6.libera.chat" 6667)
   ("Librenet: Random server" Librenet "irc.librenet.net" 6667)
   ("LinkNet: Random server" LinkNet "irc.link-net.org" ((6667 6669)))
   ("LinuxChix: Random server" LinuxChix "irc.linuxchix.org" 6667)
@@ -594,6 +601,7 @@ PORTS is either a number, a list of numbers, or a list of 
port ranges."
     (Krono "krono.net")
     (Krushnet "krushnet.org")
     (LagNet "lagnet.org.za")
+    (Libera.Chat "libera.chat")
     (Librenet "librenet.net")
     (LinkNet "link-net.org")
     (LinuxChix "cats\\.meow\\.at\\|linuxchix\\.org")
@@ -833,8 +841,8 @@ As an example:
 ;; think it is worth the effort.
 
 (defvar erc-settings
-  '((pals freenode ("kensanata" "shapr" "anti\\(fuchs\\|gone\\)"))
-    (format-nick-function (freenode "#emacs") erc-format-@nick))
+  '((pals Libera.Chat ("kensanata" "shapr" "anti\\(fuchs\\|gone\\)"))
+    (format-nick-function (Libera.Chat "#emacs") erc-format-@nick))
   "Experimental: Alist of configuration options.
 The format is (VARNAME SCOPE VALUE) where
 VARNAME is a symbol identifying the configuration option,
@@ -863,7 +871,7 @@ VALUE is the options value.")
                     items nil)))))
     val))
 
-(erc-get 'pals 'freenode)
+(erc-get 'pals 'Libera.Chat)
 
 (provide 'erc-networks)
 
diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el
index 073d164..61006e0 100644
--- a/lisp/erc/erc-services.el
+++ b/lisp/erc/erc-services.el
@@ -30,10 +30,10 @@
 ;; are made to test if NickServ is the real NickServ for a given network or
 ;; server.
 
-;; As a default, ERC has the data for the official nickname services on
-;; the networks Austnet, BrasNET, Dalnet, freenode, GalaxyNet, GRnet,
-;; Libera.Chat and Slashnet.  You can add more by using
-;;   M-x customize-variable RET erc-nickserv-alist.
+;; As a default, ERC has the data for the official nickname services
+;; on the networks Austnet, BrasNET, Dalnet, freenode, GalaxyNet,
+;; GRnet, Libera.Chat, and Slashnet.  You can add more by using
+;; M-x customize-variable RET erc-nickserv-alist.
 
 ;; Usage:
 ;;
@@ -43,9 +43,10 @@
 ;; (erc-services-mode 1)
 ;;
 ;; Add your nickname and NickServ password to `erc-nickserv-passwords'.
-;; Using the freenode network as an example:
+;; Using the Libera.Chat network as an example:
 ;;
-;; (setq erc-nickserv-passwords '((freenode (("nickname" "password")))))
+;; (setq erc-nickserv-passwords
+;;       '((Libera.Chat (("nickname" "password")))))
 ;;
 ;; The default automatic identification mode is autodetection of NickServ
 ;; identify requests.  Set the variable `erc-nickserv-identify-mode' if
@@ -181,8 +182,8 @@ passwords to be used.
 
 Example of use:
   (setq erc-nickserv-passwords
-        \\='((freenode ((\"nick-one\" . \"password\")
-                     (\"nick-two\" . \"password\")))
+        \\='((Libera.Chat ((\"nick-one\" . \"password\")
+                        (\"nick-two\" . \"password\")))
           (DALnet ((\"nick\" . \"password\")))))"
   :type '(repeat
          (list :tag "Network"
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 5245204..026c6f8 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -247,7 +247,7 @@ A typical value would be \(\"JOIN\" \"PART\" \"QUIT\")."
 
 (defcustom erc-network-hide-list nil
   "A list of IRC networks to hide message types from.
-A typical value would be \((\"freenode\" \"MODE\")
+A typical value would be \((\"Libera.Chat\" \"MODE\")
   \(\"OFTC\" \"JOIN\" \"QUIT\"))."
   :version "25.1"
   :group 'erc-ignore
@@ -1480,7 +1480,7 @@ Defaults to the server buffer."
 
 ;; activation
 
-(defconst erc-default-server "chat.freenode.net"
+(defconst erc-default-server "irc.libera.chat"
   "IRC server to use if it cannot be detected otherwise.")
 
 (defconst erc-default-port 6667
@@ -2225,7 +2225,7 @@ Non-interactively, it takes the keyword arguments
 
 That is, if called with
 
-   (erc :server \"chat.freenode.net\" :full-name \"J. Random Hacker\")
+   (erc :server \"irc.libera.chat\" :full-name \"J. Random Hacker\")
 
 then the server and full-name will be set to those values,
 whereas `erc-compute-port' and `erc-compute-nick' will be invoked
@@ -2260,7 +2260,7 @@ Non-interactively, it takes the keyword arguments
 
 That is, if called with
 
-   (erc-tls :server \"chat.freenode.net\" :full-name \"J. Random Hacker\")
+   (erc-tls :server \"irc.libera.chat\" :full-name \"J. Random Hacker\")
 
 then the server and full-name will be set to those values,
 whereas `erc-compute-port' and `erc-compute-nick' will be invoked
@@ -2276,7 +2276,7 @@ authentication by various IRC networks.
 
 Example usage:
 
-    (erc-tls :server \"chat.freenode.net\" :port 6697
+    (erc-tls :server \"irc.libera.chat\" :port 6697
              :client-certificate
              '(\"/home/bandali/my-cert.key\"
                \"/home/bandali/my-cert.crt\"))"
@@ -3447,8 +3447,9 @@ to send.
 
 If only one word is given, display the mode of that target.
 
-A list of valid mode strings for Freenode may be found at
-URL `https://freenode.net/kb/all'."
+A list of valid mode strings for Libera.Chat may be found at
+`https://libera.chat/guides/channelmodes' and
+`https://libera.chat/guides/usermodes'."
   (cond
    ((string-match "^\\s-\\(.*\\)$" line)
     (let ((s (match-string 1 line)))
diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el
index c04a1a6..ee9057f 100644
--- a/lisp/eshell/em-dirs.el
+++ b/lisp/eshell/em-dirs.el
@@ -224,7 +224,7 @@ Thus, this does not include the current directory.")
 
   (add-hook 'eshell-exit-hook #'eshell-write-last-dir-ring nil t)
 
-  (add-hook 'kill-emacs-hook #'eshell-save-some-last-dir))
+  (add-hook 'kill-emacs-query-functions #'eshell-save-some-last-dir))
 
 (defun eshell-save-some-last-dir ()
   "Save the list-dir-ring for any open Eshell buffers."
@@ -238,7 +238,8 @@ Thus, this does not include the current directory.")
                        (format-message
                         "Save last dir ring for Eshell buffer `%s'? "
                         (buffer-name buf)))))
-             (eshell-write-last-dir-ring))))))
+             (eshell-write-last-dir-ring)))))
+  t)
 
 (defun eshell-lone-directory-p (file)
   "Test whether FILE is just a directory name, and not a command name."
diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el
index 18e19a9..d82946a 100644
--- a/lisp/eshell/em-hist.el
+++ b/lisp/eshell/em-hist.el
@@ -293,7 +293,7 @@ Returns nil if INPUT is prepended by blank space, otherwise 
non-nil."
 
   (add-hook 'eshell-exit-hook #'eshell-write-history nil t)
 
-  (add-hook 'kill-emacs-hook #'eshell-save-some-history)
+  (add-hook 'kill-emacs-query-functions #'eshell-save-some-history)
 
   (add-hook 'eshell-input-filter-functions #'eshell-add-to-history nil t))
 
@@ -310,7 +310,8 @@ Returns nil if INPUT is prepended by blank space, otherwise 
non-nil."
                        (format-message
                         "Save input history for Eshell buffer `%s'? "
                         (buffer-name buf)))))
-             (eshell-write-history))))))
+             (eshell-write-history)))))
+  t)
 
 (defun eshell/history (&rest args)
   "List in help buffer the buffer's input history."
diff --git a/lisp/files.el b/lisp/files.el
index 2450daf..859c193 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1011,7 +1011,7 @@ Any directory whose name matches this regexp will be 
treated like
 a kind of root directory by `locate-dominating-file', which will stop its
 search when it bumps into it.
 The default regexp prevents fruitless and time-consuming attempts to find
-special files in directories in which filenames are interpreted as hostnames,
+special files in directories in which file names are interpreted as host names,
 or mount points potentially requiring authentication as a different user.")
 
 (defun locate-dominating-file (file name)
@@ -2288,7 +2288,8 @@ the various files."
        ;; Check to see if the file looks uncommonly large.
        (when (not (or buf nowarn))
           (when (eq (abort-if-file-too-large
-                     (file-attribute-size attributes) "open" filename t)
+                     (file-attribute-size attributes) "open" filename
+                     (not rawfile))
                     'raw)
             (setf rawfile t))
          (warn-maybe-out-of-memory (file-attribute-size attributes)))
@@ -2429,7 +2430,8 @@ Do you want to revisit the file normally now? ")))
           (set-buffer-multibyte t))
       (if rawfile
          (condition-case ()
-             (let ((inhibit-read-only t))
+             (let ((inhibit-read-only t)
+                    (enable-local-variables nil))
                (insert-file-contents-literally filename t))
            (file-error
             (when (and (file-exists-p filename)
@@ -2468,7 +2470,7 @@ Do you want to revisit the file normally now? ")))
           (not (funcall backup-enable-predicate buffer-file-name))
            (setq-local backup-inhibited t))
       (if rawfile
-         (progn
+         (let ((enable-local-variables nil))
            (set-buffer-multibyte nil)
            (setq buffer-file-coding-system 'no-conversion)
            (set-buffer-major-mode buf)
@@ -2957,7 +2959,7 @@ 
ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|CBR\\|7Z\\|SQUASHFS\\)\\'" .
      ("\\.xmp\\'" . image-mode)
      ("\\.xwd\\'" . image-mode)
      ("\\.yuv\\'" . image-mode)))
-  "Alist of filename patterns vs corresponding major mode functions.
+  "Alist of file name patterns vs corresponding major mode functions.
 Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL).
 \(NON-NIL stands for anything that is not nil; the value does not matter.)
 Visiting a file whose name matches REGEXP specifies FUNCTION as the
@@ -3150,7 +3152,7 @@ To find the right major mode, this function checks for a 
-*- mode tag
 checks for a `mode:' entry in the Local Variables section of the file,
 checks if it uses an interpreter listed in `interpreter-mode-alist',
 matches the buffer beginning against `magic-mode-alist',
-compares the filename against the entries in `auto-mode-alist',
+compares the file name against the entries in `auto-mode-alist',
 then matches the buffer beginning against `magic-fallback-mode-alist'.
 
 If `enable-local-variables' is nil, or if the file name matches
@@ -4039,7 +4041,7 @@ already the major mode."
     ('eval
      (pcase val
        (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook)))
-     (save-excursion (eval val)))
+     (save-excursion (eval val t)))
     (_
      (hack-one-local-variable--obsolete var)
      ;; Make sure the string has no text properties.
@@ -4892,6 +4894,27 @@ extension, the value is \"\"."
         (if period
             "")))))
 
+(defun file-name-with-extension (filename extension)
+  "Set the EXTENSION of a FILENAME.
+The extension (in a file name) is the part that begins with the last \".\".
+
+Trims a leading dot from the EXTENSION so that either \"foo\" or
+\".foo\" can be given.
+
+Errors if the FILENAME or EXTENSION are empty, or if the given
+FILENAME has the format of a directory.
+
+See also `file-name-sans-extension'."
+  (let ((extn (string-trim-left extension "[.]")))
+    (cond ((string-empty-p filename)
+           (error "Empty filename: %s" filename))
+          ((string-empty-p extn)
+           (error "Malformed extension: %s" extension))
+          ((directory-name-p filename)
+           (error "Filename is a directory: %s" filename))
+          (t
+           (concat (file-name-sans-extension filename) "." extn)))))
+
 (defun file-name-base (&optional filename)
   "Return the base name of the FILENAME: no directory, no extension."
   (declare (advertised-calling-convention (filename) "27.1"))
@@ -4918,7 +4941,7 @@ See also `backup-directory-alist'."
                 (function :tag "Function")))
 
 (defcustom backup-directory-alist nil
-  "Alist of filename patterns and backup directory names.
+  "Alist of file name patterns and backup directory names.
 Each element looks like (REGEXP . DIRECTORY).  Backups of files with
 names matching REGEXP will be made in DIRECTORY.  DIRECTORY may be
 relative or absolute.  If it is absolute, so that all matching files
@@ -4931,7 +4954,7 @@ For the common case of all backups going into one 
directory, the alist
 should contain a single element pairing \".\" with the appropriate
 directory name.
 
-If this variable is nil, or it fails to match a filename, the backup
+If this variable is nil, or it fails to match a file name, the backup
 is made in the original file's directory.
 
 On MS-DOS filesystems without long names this variable is always
@@ -6757,7 +6780,7 @@ See also `make-auto-save-file-name'."
 
 (defun wildcard-to-regexp (wildcard)
   "Given a shell file name pattern WILDCARD, return an equivalent regexp.
-The generated regexp will match a filename only if the filename
+The generated regexp will match a file name only if the file name
 matches that wildcard according to shell rules.  Only wildcards known
 by `sh' are supported."
   (let* ((i (string-match "[[.*+\\^$?]" wildcard))
@@ -7477,7 +7500,7 @@ If the current frame has no client, kill Emacs itself 
using
 
 With prefix ARG, silently save all file-visiting buffers, then kill.
 
-If emacsclient was started with a list of filenames to edit, then
+If emacsclient was started with a list of file names to edit, then
 only these files will be asked to be saved."
   (interactive "P")
   (if (frame-parameter nil 'client)
diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el
index fc9f868..70bde26 100644
--- a/lisp/gnus/gnus-search.el
+++ b/lisp/gnus/gnus-search.el
@@ -1278,17 +1278,23 @@ elements are present."
       str)))
 
 (defun gnus-search-imap-handle-flag (flag)
-  "Make sure string FLAG is something IMAP will recognize."
-  ;; What else?  What about the KEYWORD search key?
+  "Adjust string FLAG to help IMAP recognize it.
+If it's one of the RFC3501 flags, make sure it's upcased.
+Otherwise, if FLAG starts with a \"$\", treat as a KEYWORD
+search.  Otherwise, drop the flag."
   (setq flag
        (pcase flag
          ("flag" "flagged")
          ("read" "seen")
          ("replied" "answered")
          (_ flag)))
-  (if (member flag '("seen" "answered" "deleted" "draft" "flagged"))
-      (upcase flag)
-    ""))
+  (cond
+   ((member flag '("seen" "answered" "deleted" "draft" "flagged" "recent"))
+    (upcase flag))
+   ((string-prefix-p "$" flag)
+    (format "KEYWORD %s" flag))
+   ;; TODO: Provide a user option to treat *all* marks as a KEYWORDs?
+   (t "")))
 
 ;;; Methods for the indexed search engines.
 
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 908c10c..4bdc202 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -5083,17 +5083,17 @@ using some other form will lead to serious barfage."
   (gnus-article-sort-by-author
    (gnus-thread-header h1)  (gnus-thread-header h2)))
 
+(defsubst gnus-article-sort-extract-extra (name header)
+  (let ((extract
+        (funcall gnus-extract-address-components
+                 (or (cdr (assq name (mail-header-extra header)))
+                     ""))))
+    (or (car extract) (cadr extract))))
+
 (defsubst gnus-article-sort-by-recipient (h1 h2)
   "Sort articles by recipient."
-  (gnus-string<
-   (let ((extract (funcall
-                  gnus-extract-address-components
-                  (or (cdr (assq 'To (mail-header-extra h1))) ""))))
-     (or (car extract) (cadr extract)))
-   (let ((extract (funcall
-                  gnus-extract-address-components
-                  (or (cdr (assq 'To (mail-header-extra h2))) ""))))
-     (or (car extract) (cadr extract)))))
+  (let ((ex (lambda (h) (gnus-article-sort-extract-extra 'To h))))
+    (gnus-string< (funcall ex h1) (funcall ex h2))))
 
 (defun gnus-thread-sort-by-recipient (h1 h2)
   "Sort threads by root recipient."
@@ -5188,15 +5188,9 @@ Unscored articles will be counted as having a score of 
zero."
   "Sort threads such that the thread with the most recently dated article 
comes first."
   (> (gnus-thread-latest-date h1) (gnus-thread-latest-date h2)))
 
-(defun gnus-article-sort-by-newsgroups (h1 h2)
+(defsubst gnus-article-sort-by-newsgroups (h1 h2)
   "Sort articles by newsgroups."
-  (let ((ex
-         (lambda (h)
-           (let ((extract
-                  (funcall gnus-extract-address-components
-                          (or (cdr (assq 'Newsgroups (mail-header-extra h)))
-                               ""))))
-             (or (car extract) (cadr extract))))))
+  (let ((ex (lambda (h) (gnus-article-sort-extract-extra 'Newsgroups h))))
     (gnus-string< (funcall ex h1) (funcall ex h2))))
 
 (defun gnus-thread-sort-by-newsgroups (h1 h2)
@@ -5204,7 +5198,6 @@ Unscored articles will be counted as having a score of 
zero."
   (gnus-article-sort-by-newsgroups
    (gnus-thread-header h1) (gnus-thread-header h2)))
 
-
 ; Since this is called not only to sort the top-level threads, but
 ; also in recursive sorts to order the articles within a thread, each
 ; article will be processed many times.  Thus it speeds things up
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 0c027ca..a9be2d6 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -8730,12 +8730,10 @@ headers.  If FORCE, insert new field even if NEW-VALUE 
is empty."
       (message-narrow-to-headers)
       (message-remove-header header))
     (when (or force (> (length new-value) 0))
-      (when after
-        (if (listp after)
-            (apply #'message-position-on-field
-                   (append (list header) after))
-          (message-position-on-field header after))
-       (message-position-on-field header))
+      (apply #'message-position-on-field header
+             (if (listp after)
+                 after
+               (list after)))
       (insert new-value))))
 
 (make-obsolete-variable
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index 08b4ef2..576fced 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -276,8 +276,8 @@ Last entry becomes the first and can be selected with
            (setcdr last-but-one (cdr (cdr last-but-one)))))
     (completion--cache-all-sorted-completions beg end comps)))
 
-;;; Helpers for `fido-mode' (or `ido-mode' emulation)
-;;;
+;;;_* Helpers for `fido-mode' (or `ido-mode' emulation)
+
 (defun icomplete-fido-kill ()
   "Kill line or current completion, like `ido-mode'.
 If killing to the end of line make sense, call `kill-line',
@@ -859,13 +859,16 @@ matches exist."
                (base-size (prog1 (cdr last)
                             (if last (setcdr last nil))))
                (most-try
-                (if (and base-size (> base-size 0))
+                ;; icomplete-hide-common-prefix logic is used
+                ;; unconditionally when there is single match.
+                (when (or icomplete-hide-common-prefix (not (cdr comps)))
+                  (if (and base-size (> base-size 0))
+                      (completion-try-completion
+                       name candidates predicate (length name) md)
+                    ;; If the `comps' are 0-based, the result should be
+                    ;; the same with `comps'.
                     (completion-try-completion
-                     name candidates predicate (length name) md)
-                  ;; If the `comps' are 0-based, the result should be
-                  ;; the same with `comps'.
-                  (completion-try-completion
-                   name comps nil (length name) md)))
+                     name comps nil (length name) md))))
                (most (if (consp most-try) (car most-try)
                        (if most-try (car comps) "")))
                ;; Compare name and most, so we can determine if name is
@@ -966,7 +969,7 @@ matches exist."
             ;; is cached.
             (if last (setcdr last base-size))))))))
 
-;;; Iswitchb compatibility
+;;;_* Iswitchb compatibility
 
 ;; We moved Iswitchb to `obsolete' in 24.4, but autoloads in files in
 ;; `obsolete' aren't obeyed (since that would encourage people to keep using
@@ -981,7 +984,7 @@ matches exist."
 
 (provide 'icomplete)
 
-;;_* Local emacs vars.
+;;;_* Local emacs vars.
 ;;Local variables:
 ;;allout-layout: (-2 :)
 ;;End:
diff --git a/lisp/language/ethio-util.el b/lisp/language/ethio-util.el
index fa31cd5..dc385b0 100644
--- a/lisp/language/ethio-util.el
+++ b/lisp/language/ethio-util.el
@@ -98,48 +98,74 @@
 ;; users' preference
 ;;
 
-(defvar ethio-primary-language 'tigrigna
+(defgroup ethiopic nil
+  "Options for writing Ethiopic."
+  :version "28.1"
+  :group 'languages)
+
+(defcustom ethio-primary-language 'tigrigna
   "Symbol that defines the primary language in SERA --> FIDEL conversion.
-The value should be one of: `tigrigna', `amharic' or `english'.")
+The value should be one of: `tigrigna', `amharic' or `english'."
+  :version "28.1"
+  :type '(choice (const :tag "Tigrigna" tigrigna)
+                 (const :tag "Amharic" amharic)
+                 (const :tag "English" english)))
 
-(defvar ethio-secondary-language 'english
+(defcustom ethio-secondary-language 'english
   "Symbol that defines the secondary language in SERA --> FIDEL conversion.
-The value should be one of: `tigrigna', `amharic' or `english'.")
+The value should be one of: `tigrigna', `amharic' or `english'."
+  :version "28.1"
+  :type '(choice (const :tag "Tigrigna" tigrigna)
+                 (const :tag "Amharic" amharic)
+                 (const :tag "English" english)))
 
-(defvar ethio-use-colon-for-colon nil
+(defcustom ethio-use-colon-for-colon nil
   "Non-nil means associate ASCII colon with Ethiopic colon.
 If nil, associate ASCII colon with Ethiopic word separator, i.e., two
 vertically stacked dots.  All SERA <--> FIDEL converters refer this
-variable.")
+variable."
+  :version "28.1"
+  :type 'boolean)
 
-(defvar ethio-use-three-dot-question nil
+(defcustom ethio-use-three-dot-question nil
   "If non-nil, associate ASCII question mark with Ethiopic question mark.
 The Ethiopic old style question mark is three vertically stacked dots.
 If nil, associate ASCII question mark with Ethiopic stylized question
-mark.  All SERA <--> FIDEL converters refer this variable.")
+mark.  All SERA <--> FIDEL converters refer this variable."
+  :version "28.1"
+  :type 'boolean)
 
-(defvar ethio-quote-vowel-always nil
+(defcustom ethio-quote-vowel-always nil
   "Non-nil means always put an apostrophe before an isolated vowel.
 This happens in FIDEL --> SERA conversions.  Isolated vowels at
 word beginning do not get an apostrophe put before them.
 If nil, put an apostrophe only between a 6th-form consonant and an
-isolated vowel.")
+isolated vowel."
+  :version "28.1"
+  :type 'boolean)
 
-(defvar ethio-W-sixth-always nil
+(defcustom ethio-W-sixth-always nil
   "Non-nil means convert the Wu-form of a 12-form consonant to \"W'\".
-This is instead of \"Wu\" in FIDEL --> SERA conversion.")
+This is instead of \"Wu\" in FIDEL --> SERA conversion."
+  :version "28.1"
+  :type 'boolean)
 
-(defvar ethio-numeric-reduction 0
+(defcustom ethio-numeric-reduction 0
   "Degree of reduction in converting Ethiopic digits into Arabic digits.
 Should be 0, 1 or 2.
 For example, ({10}{9}{100}{80}{7}) is converted into:
     \\=`10\\=`9\\=`100\\=`80\\=`7  if `ethio-numeric-reduction' is 0,
     \\=`109100807          if `ethio-numeric-reduction' is 1,
-    \\=`10900807           if `ethio-numeric-reduction' is 2.")
+    \\=`10900807           if `ethio-numeric-reduction' is 2."
+  :version "28.1"
+  :type 'integer)
 
-(defvar ethio-java-save-lowercase nil
+(defcustom ethio-java-save-lowercase nil
   "Non-nil means save Ethiopic characters in lowercase hex numbers to Java 
files.
-If nil, use uppercases.")
+If nil, use uppercases."
+  :version "28.1"
+  :type 'boolean)
+
 
 (defun ethio-prefer-amharic-p ()
   (or (eq ethio-primary-language 'amharic)
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index f490bfb..efaf061 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -511,14 +511,17 @@ Return t if `allout-mode' is active in current buffer." 
nil t)
 (autoload 'allout-mode "allout" "\
 Toggle Allout outline mode.
 
-If called interactively, toggle `Allout mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Allout
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `allout-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -832,14 +835,17 @@ See `allout-widgets-mode' for allout widgets mode 
features.")
 (autoload 'allout-widgets-mode "allout-widgets" "\
 Toggle Allout Widgets mode.
 
-If called interactively, toggle `Allout-Widgets mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Allout-Widgets mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `allout-widgets-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -1258,14 +1264,17 @@ Entering array mode calls the function 
`array-mode-hook'.
 (autoload 'artist-mode "artist" "\
 Toggle Artist mode.
 
-If called interactively, toggle `Artist mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Artist
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `artist-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -1597,14 +1606,17 @@ or call the function `autoarg-kp-mode'.")
 (autoload 'autoarg-kp-mode "autoarg" "\
 Toggle Autoarg-KP mode, a global minor mode.
 
-If called interactively, toggle `Autoarg-Kp mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Autoarg-Kp
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'autoarg-kp-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -1659,14 +1671,17 @@ or call the function `auto-insert-mode'.")
 (autoload 'auto-insert-mode "autoinsert" "\
 Toggle Auto-insert mode, a global minor mode.
 
-If called interactively, toggle `Auto-Insert mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Auto-Insert mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'auto-insert-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -1752,14 +1767,17 @@ should be non-nil)." nil nil)
 (autoload 'auto-revert-mode "autorevert" "\
 Toggle reverting buffer when the file changes (Auto-Revert Mode).
 
-If called interactively, toggle `Auto-Revert mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Auto-Revert mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `auto-revert-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -1785,14 +1803,17 @@ This function is designed to be added to hooks, for 
example:
 (autoload 'auto-revert-tail-mode "autorevert" "\
 Toggle reverting tail of buffer when the file grows.
 
-If called interactively, toggle `Auto-Revert-Tail mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Auto-Revert-Tail mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `auto-revert-tail-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -1832,14 +1853,17 @@ or call the function `global-auto-revert-mode'.")
 (autoload 'global-auto-revert-mode "autorevert" "\
 Toggle Global Auto-Revert Mode.
 
-If called interactively, toggle `Global Auto-Revert mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the `Global
+Auto-Revert mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'global-auto-revert-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -1969,14 +1993,17 @@ or call the function `display-battery-mode'.")
 (autoload 'display-battery-mode "battery" "\
 Toggle battery status display in mode line (Display Battery mode).
 
-If called interactively, toggle `Display-Battery mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Display-Battery mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'display-battery-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -2592,7 +2619,7 @@ Emacs 28.1 and will be removed in a future release.
 \(fn URL &optional KIND)" nil nil)
 
 (autoload 'browse-url-of-file "browse-url" "\
-Ask a WWW browser to display FILE.
+Use a web browser to display FILE.
 Display the current buffer's file if FILE is nil or if called
 interactively.  Turn the filename into a URL with function
 `browse-url-file-url'.  Pass the URL to a browser using the
@@ -2601,7 +2628,9 @@ interactively.  Turn the filename into a URL with function
 \(fn &optional FILE)" t nil)
 
 (autoload 'browse-url-of-buffer "browse-url" "\
-Ask a WWW browser to display BUFFER.
+Use a web browser to display BUFFER.
+See `browse-url' for details.
+
 Display the current buffer if BUFFER is nil.  Display only the
 currently visible part of BUFFER (from a temporary file) if buffer is
 narrowed.
@@ -2612,19 +2641,24 @@ narrowed.
 In Dired, ask a WWW browser to display the file named on this line." t nil)
 
 (autoload 'browse-url-of-region "browse-url" "\
-Ask a WWW browser to display the current region.
+Use a web browser to display the current region.
+See `browse-url' for details.
 
 \(fn MIN MAX)" t nil)
 
 (autoload 'browse-url "browse-url" "\
-Ask a WWW browser to load URL.
-Prompt for a URL, defaulting to the URL at or before point.
-Invokes a suitable browser function which does the actual job.
+Open URL using a configurable method.
+This will typically (by default) open URL with an external web
+browser, but a wide variety of different methods can be used,
+depending on the URL type.
 
 The variables `browse-url-browser-function',
 `browse-url-handlers', and `browse-url-default-handlers'
 determine which browser function to use.
 
+This command prompts for a URL, defaulting to the URL at or
+before point.
+
 The additional ARGS are passed to the browser function.  See the
 doc strings of the actual functions, starting with
 `browse-url-browser-function', for information about the
@@ -2636,8 +2670,8 @@ If ARGS are omitted, the default is to pass
 \(fn URL &rest ARGS)" t nil)
 
 (autoload 'browse-url-at-point "browse-url" "\
-Ask a WWW browser to load the URL at or before point.
-Variable `browse-url-browser-function' says which browser to use.
+Open URL at point using a configurable method.
+See `browse-url' for details.
 Optional prefix argument ARG non-nil inverts the value of the option
 `browse-url-new-window-flag'.
 
@@ -2653,10 +2687,11 @@ opposite of the browser kind of 
`browse-url-browser-function'.
 \(fn KIND URL &optional ARG)" t nil)
 
 (autoload 'browse-url-at-mouse "browse-url" "\
-Ask a WWW browser to load a URL clicked with the mouse.
-The URL is the one around or before the position of the mouse click
-but point is not changed.  Variable `browse-url-browser-function'
-says which browser to use.
+Use a web browser to load a URL clicked with the mouse.
+See `browse-url' for details.
+
+The URL is the one around or before the position of the mouse
+click but point is not changed.
 
 \(fn EVENT)" t nil)
 
@@ -2894,6 +2929,13 @@ from `browse-url-elinks-wrapper'.
 
 \(fn URL &optional NEW-WINDOW)" t nil)
 
+(autoload 'browse-url-button-open-url "browse-url" "\
+Open URL using `browse-url'.
+If `current-prefix-arg' is non-nil, use
+`browse-url-secondary-browser-function' instead.
+
+\(fn URL)" nil nil)
+
 (register-definition-prefixes "browse-url" '("browse-url-"))
 
 ;;;***
@@ -2967,14 +3009,17 @@ columns on its right towards the left.
 (autoload 'bug-reference-mode "bug-reference" "\
 Toggle hyperlinking bug references in the buffer (Bug Reference mode).
 
-If called interactively, toggle `Bug-Reference mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Bug-Reference mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `bug-reference-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -2983,14 +3028,17 @@ disabled.
 (autoload 'bug-reference-prog-mode "bug-reference" "\
 Like `bug-reference-mode', but only buttonize in comments and strings.
 
-If called interactively, toggle `Bug-Reference-Prog mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Bug-Reference-Prog mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `bug-reference-prog-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -3140,7 +3188,7 @@ and corresponding effects.
 
 \(fn &optional ARG)" nil nil)
 
-(register-definition-prefixes "bytecomp" '("batch-byte-compile-file" "byte-" 
"displaying-byte-compile-warnings" "emacs-lisp-" "no-byte-compile"))
+(register-definition-prefixes "bytecomp" '("batch-byte-compile-file" "byte" 
"displaying-byte-compile-warnings" "emacs-lisp-" "no-byte-compile"))
 
 ;;;***
 
@@ -4727,14 +4775,17 @@ Prefix argument is the same as for `checkdoc-defun'." t 
nil)
 (autoload 'checkdoc-minor-mode "checkdoc" "\
 Toggle automatic docstring checking (Checkdoc minor mode).
 
-If called interactively, toggle `Checkdoc minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Checkdoc
+minor mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `checkdoc-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -4843,14 +4894,18 @@ or call the function `cl-font-lock-built-in-mode'.")
 (autoload 'cl-font-lock-built-in-mode "cl-font-lock" "\
 Highlight built-in functions, variables, and types in `lisp-mode'.
 
-If called interactively, toggle `Cl-Font-Lock-Built-In mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Cl-Font-Lock-Built-In mode' mode.  If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable the
+mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'cl-font-lock-built-in-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -5075,14 +5130,17 @@ This can be needed when using code byte-compiled using 
the old
 macro-expansion of `cl-defstruct' that used vectors objects instead
 of record objects.
 
-If called interactively, toggle `Cl-Old-Struct-Compat mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Cl-Old-Struct-Compat mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'cl-old-struct-compat-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -5370,13 +5428,13 @@ Use this from the command line, with ‘-batch’;
 it won’t work in an interactive Emacs.
 Native compilation equivalent to `batch-byte-compile'." nil nil)
 
-(autoload 'batch-byte-native-compile-for-bootstrap "comp" "\
+(autoload 'batch-byte+native-compile "comp" "\
 Like `batch-native-compile', but used for bootstrap.
 Generate .elc files in addition to the .eln files.
 Force the produced .eln to be outputted in the eln system
-directory (the last entry in `native-comp-eln-load-path').
-If the environment variable 'NATIVE_DISABLED' is set, only byte
-compile." nil nil)
+directory (the last entry in `native-comp-eln-load-path') unless
+`native-compile-target-directory' is non-nil.  If the environment
+variable 'NATIVE_DISABLED' is set, only byte compile." nil nil)
 
 (autoload 'native-compile-async "comp" "\
 Compile FILES asynchronously.
@@ -5604,14 +5662,18 @@ Runs `compilation-mode-hook' with `run-mode-hooks' 
(which see).
 (autoload 'compilation-shell-minor-mode "compile" "\
 Toggle Compilation Shell minor mode.
 
-If called interactively, toggle `Compilation-Shell minor mode'.  If
-the prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Compilation-Shell minor mode' mode.  If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable the
+mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `compilation-shell-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -5625,14 +5687,17 @@ See `compilation-mode'.
 (autoload 'compilation-minor-mode "compile" "\
 Toggle Compilation minor mode.
 
-If called interactively, toggle `Compilation minor mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Compilation minor mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `compilation-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -5668,14 +5733,17 @@ or call the function `dynamic-completion-mode'.")
 (autoload 'dynamic-completion-mode "completion" "\
 Toggle dynamic word-completion on or off.
 
-If called interactively, toggle `Dynamic-Completion mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Dynamic-Completion mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'dynamic-completion-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -6234,14 +6302,17 @@ or call the function `cua-mode'.")
 (autoload 'cua-mode "cua-base" "\
 Toggle Common User Access style editing (CUA mode).
 
-If called interactively, toggle `Cua mode'.  If the prefix argument is
-positive, enable the mode, and if it is zero or negative, disable the
-mode.
+This is a minor mode.  If called interactively, toggle the `Cua mode'
+mode.  If the prefix argument is positive, enable the mode, and if it
+is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'cua-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -6288,14 +6359,17 @@ Enable CUA selection mode without the C-z/C-x/C-c/C-v 
bindings.
 Toggle the region as rectangular.
 Activates the region if needed.  Only lasts until the region is deactivated.
 
-If called interactively, toggle `Cua-Rectangle-Mark mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Cua-Rectangle-Mark mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `cua-rectangle-mark-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -6317,14 +6391,17 @@ By convention, this is a list of symbols where each 
symbol stands for the
 (autoload 'cursor-intangible-mode "cursor-sensor" "\
 Keep cursor outside of any `cursor-intangible' text property.
 
-If called interactively, toggle `Cursor-Intangible mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Cursor-Intangible mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `cursor-intangible-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -6338,14 +6415,17 @@ where WINDOW is the affected window, OLDPOS is the last 
known position of
 the cursor and DIR can be `entered' or `left' depending on whether the cursor
 is entering the area covered by the text-property property or leaving it.
 
-If called interactively, toggle `Cursor-Sensor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Cursor-Sensor mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `cursor-sensor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -6724,14 +6804,17 @@ Mode used for cvs status output.
 (autoload 'cwarn-mode "cwarn" "\
 Minor mode that highlights suspicious C and C++ constructions.
 
-If called interactively, toggle `Cwarn mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Cwarn
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `cwarn-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -7189,14 +7272,17 @@ or call the function `delete-selection-mode'.")
 (autoload 'delete-selection-mode "delsel" "\
 Toggle Delete Selection mode.
 
-If called interactively, toggle `Delete-Selection mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Delete-Selection mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'delete-selection-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -7211,7 +7297,8 @@ information on adapting behavior of commands in Delete 
Selection mode.
 
 (autoload 'delete-active-region "delsel" "\
 Delete the active region.
-If KILLP in not-nil, the active region is killed instead of deleted.
+If KILLP is non-nil, or if called interactively with a prefix argument,
+the active region is killed instead of deleted.
 
 \(fn &optional KILLP)" t nil)
 
@@ -7373,14 +7460,17 @@ or call the function `desktop-save-mode'.")
 (autoload 'desktop-save-mode "desktop" "\
 Toggle desktop saving (Desktop Save mode).
 
-If called interactively, toggle `Desktop-Save mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Desktop-Save mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'desktop-save-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -7855,14 +7945,17 @@ a diff with \\[diff-reverse-direction].
 (autoload 'diff-minor-mode "diff-mode" "\
 Toggle Diff minor mode.
 
-If called interactively, toggle `Diff minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Diff minor
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `diff-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -7878,8 +7971,10 @@ disabled.
 ;;; Generated autoloads from net/dig.el
 
 (autoload 'dig "dig" "\
-Query addresses of a DOMAIN using dig, by calling `dig-invoke'.
-Optional arguments are passed to `dig-invoke'.
+Query addresses of a DOMAIN using dig.
+See `dig-invoke' for an explanation for the parameters.
+When called interactively, DOMAIN is prompted for.  If given a prefix,
+also prompt for the QUERY-TYPE parameter.
 
 \(fn DOMAIN &optional QUERY-TYPE QUERY-CLASS QUERY-OPTION DIG-OPTION SERVER)" 
t nil)
 
@@ -8042,14 +8137,17 @@ Like \\[dired-jump] (`dired-jump') but in other window.
 (autoload 'dirtrack-mode "dirtrack" "\
 Toggle directory tracking in shell buffers (Dirtrack mode).
 
-If called interactively, toggle `Dirtrack mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Dirtrack
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `dirtrack-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -8219,14 +8317,18 @@ in `.emacs'.
 Toggle display of fill-column indicator.
 This uses `display-fill-column-indicator' internally.
 
-If called interactively, toggle `Display-Fill-Column-Indicator mode'.
-If the prefix argument is positive, enable the mode, and if it is zero
-or negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Display-Fill-Column-Indicator mode' mode.  If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable the
+mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `display-fill-column-indicator-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -8296,14 +8398,17 @@ list.")
 Toggle display of line numbers in the buffer.
 This uses `display-line-numbers' internally.
 
-If called interactively, toggle `Display-Line-Numbers mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Display-Line-Numbers mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `display-line-numbers-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -8446,14 +8551,17 @@ to the next best mode." nil nil)
 (autoload 'doc-view-minor-mode "doc-view" "\
 Toggle displaying buffer via Doc View (Doc View minor mode).
 
-If called interactively, toggle `Doc-View minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Doc-View
+minor mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `doc-view-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -8514,14 +8622,17 @@ Switch to *doctor* buffer and start giving 
psychotherapy." t nil)
 (autoload 'double-mode "double" "\
 Toggle special insertion on double keypresses (Double mode).
 
-If called interactively, toggle `Double mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Double
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `double-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -9211,14 +9322,17 @@ or call the function `global-ede-mode'.")
 (autoload 'global-ede-mode "ede" "\
 Toggle global EDE (Emacs Development Environment) mode.
 
-If called interactively, toggle `Global Ede mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Global Ede
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'global-ede-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -10065,14 +10179,17 @@ or call the function `electric-pair-mode'.")
 (autoload 'electric-pair-mode "elec-pair" "\
 Toggle automatic parens pairing (Electric Pair mode).
 
-If called interactively, toggle `Electric-Pair mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Electric-Pair mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'electric-pair-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -10089,14 +10206,17 @@ To toggle the mode in a single buffer, use 
`electric-pair-local-mode'.
 (autoload 'electric-pair-local-mode "elec-pair" "\
 Toggle `electric-pair-mode' only in this buffer.
 
-If called interactively, toggle `Electric-Pair-Local mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Electric-Pair-Local mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(buffer-local-value 'electric-pair-mode (current-buffer))'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -10312,14 +10432,17 @@ Minor mode for editing text/enriched files.
 These are files with embedded formatting information in the MIME standard
 text/enriched format.
 
-If called interactively, toggle `Enriched mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Enriched
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `enriched-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -10597,14 +10720,17 @@ enough, since keyservers have strict timeout settings.
 (autoload 'epa-mail-mode "epa-mail" "\
 A minor-mode for composing encrypted/clearsigned mails.
 
-If called interactively, toggle `epa-mail mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `epa-mail
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `epa-mail-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -10667,14 +10793,17 @@ or call the function `epa-global-mail-mode'.")
 (autoload 'epa-global-mail-mode "epa-mail" "\
 Minor mode to hook EasyPG into Mail mode.
 
-If called interactively, toggle `Epa-Global-Mail mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Epa-Global-Mail mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'epa-global-mail-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -10759,7 +10888,7 @@ Non-interactively, it takes the keyword arguments
 
 That is, if called with
 
-   (erc :server \"chat.freenode.net\" :full-name \"Harry S Truman\")
+   (erc :server \"irc.libera.chat\" :full-name \"J. Random Hacker\")
 
 then the server and full-name will be set to those values,
 whereas `erc-compute-port' and `erc-compute-nick' will be invoked
@@ -10786,7 +10915,7 @@ Non-interactively, it takes the keyword arguments
 
 That is, if called with
 
-   (erc-tls :server \"chat.freenode.net\" :full-name \"Harry S Truman\")
+   (erc-tls :server \"irc.libera.chat\" :full-name \"J. Random Hacker\")
 
 then the server and full-name will be set to those values,
 whereas `erc-compute-port' and `erc-compute-nick' will be invoked
@@ -10802,7 +10931,7 @@ authentication by various IRC networks.
 
 Example usage:
 
-    (erc-tls :server \"chat.freenode.net\" :port 6697
+    (erc-tls :server \"irc.libera.chat\" :port 6697
              :client-certificate
              '(\"/home/bandali/my-cert.key\"
                \"/home/bandali/my-cert.crt\"))
@@ -11318,7 +11447,7 @@ argument is passed to `next-file', which see).
 (autoload 'tags-search "etags" "\
 Search through all files listed in tags table for match for REGEXP.
 Stops when a match is found.
-To continue searching for next match, use command \\[tags-loop-continue].
+To continue searching for next match, use the command \\[fileloop-continue].
 
 If FILES if non-nil should be a list or an iterator returning the
 files to search.  The search will be restricted to these files.
@@ -11331,7 +11460,7 @@ Also see the documentation of the `tags-file-name' 
variable.
 Do `query-replace-regexp' of FROM with TO on all files listed in tags table.
 Third arg DELIMITED (prefix arg) means replace only word-delimited matches.
 If you exit (\\[keyboard-quit], RET or q), you can resume the query replace
-with the command \\[tags-loop-continue].
+with the command \\[fileloop-continue].
 For non-interactive use, superseded by `fileloop-initialize-replace'.
 
 \(fn FROM TO &optional DELIMITED FILES)" t nil)
@@ -12078,14 +12207,17 @@ a top-level keymap, `text-scale-increase' or
 (autoload 'buffer-face-mode "face-remap" "\
 Minor mode for a buffer-specific default face.
 
-If called interactively, toggle `Buffer-Face mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Buffer-Face mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `buffer-face-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -13034,14 +13166,17 @@ region is invalid.  This function saves match data.
 (autoload 'flymake-mode "flymake" "\
 Toggle Flymake mode on or off.
 
-If called interactively, toggle `Flymake mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Flymake
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `flymake-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -13122,14 +13257,17 @@ Turn on `flyspell-mode' for comments and strings." t 
nil)
 (autoload 'flyspell-mode "flyspell" "\
 Toggle on-the-fly spell checking (Flyspell mode).
 
-If called interactively, toggle `Flyspell mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Flyspell
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `flyspell-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -13205,14 +13343,17 @@ Turn off Follow mode.  Please see the function 
`follow-mode'." nil nil)
 (autoload 'follow-mode "follow" "\
 Toggle Follow mode.
 
-If called interactively, toggle `Follow mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Follow
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `follow-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -13335,14 +13476,17 @@ selected if the original window is the first one in 
the frame.
 (autoload 'footnote-mode "footnote" "\
 Toggle Footnote mode.
 
-If called interactively, toggle `Footnote mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Footnote
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `footnote-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -13805,14 +13949,17 @@ being transferred.  This list may grow up to a size of
 `gdb-debug-log-max' after which the oldest element (at the end of
 the list) is deleted every time a new one is added (at the front).
 
-If called interactively, toggle `Gdb-Enable-Debug mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Gdb-Enable-Debug mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'gdb-enable-debug)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -13989,14 +14136,17 @@ regular expression that can be used as an element of
 (autoload 'glasses-mode "glasses" "\
 Minor mode for making identifiers likeThis readable.
 
-If called interactively, toggle `Glasses mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Glasses
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `glasses-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -14604,14 +14754,17 @@ If FORCE is non-nil, replace the old ones.
 (autoload 'gnus-mailing-list-mode "gnus-ml" "\
 Minor mode for providing mailing-list commands.
 
-If called interactively, toggle `Gnus-Mailing-List mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Gnus-Mailing-List mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `gnus-mailing-list-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -15071,14 +15224,17 @@ Also fontifies the buffer appropriately (see 
`goto-address-fontify-p' and
 (autoload 'goto-address-mode "goto-addr" "\
 Minor mode to buttonize URLs and e-mail addresses in the current buffer.
 
-If called interactively, toggle `Goto-Address mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Goto-Address mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `goto-address-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -15112,14 +15268,17 @@ See `goto-address-mode' for more information on 
Goto-Address mode.
 (autoload 'goto-address-prog-mode "goto-addr" "\
 Like `goto-address-mode', but only for comments and strings.
 
-If called interactively, toggle `Goto-Address-Prog mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Goto-Address-Prog mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `goto-address-prog-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -15452,14 +15611,17 @@ or call the function `gud-tooltip-mode'.")
 (autoload 'gud-tooltip-mode "gud" "\
 Toggle the display of GUD tooltips.
 
-If called interactively, toggle `Gud-Tooltip mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Gud-Tooltip mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'gud-tooltip-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -16190,14 +16352,17 @@ This discards the buffer's undo information." t nil)
 (autoload 'hi-lock-mode "hi-lock" "\
 Toggle selective highlighting of patterns (Hi Lock mode).
 
-If called interactively, toggle `Hi-Lock mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Hi-Lock
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `hi-lock-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -16401,14 +16566,17 @@ Add patterns from the current buffer to the list of 
hi-lock patterns." t nil)
 (autoload 'hide-ifdef-mode "hideif" "\
 Toggle features to hide/show #ifdef blocks (Hide-Ifdef mode).
 
-If called interactively, toggle `Hide-Ifdef mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Hide-Ifdef
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `hide-ifdef-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -16486,14 +16654,17 @@ whitespace.  Case does not matter.")
 (autoload 'hs-minor-mode "hideshow" "\
 Minor mode to selectively hide/show code and comment blocks.
 
-If called interactively, toggle `hs minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `hs minor
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `hs-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -16536,14 +16707,17 @@ Unconditionally turn off `hs-minor-mode'." nil nil)
 (autoload 'highlight-changes-mode "hilit-chg" "\
 Toggle highlighting changes in this buffer (Highlight Changes mode).
 
-If called interactively, toggle `Highlight-Changes mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Highlight-Changes mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `highlight-changes-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -16567,14 +16741,18 @@ buffer with the contents of a file
 (autoload 'highlight-changes-visible-mode "hilit-chg" "\
 Toggle visibility of highlighting due to Highlight Changes mode.
 
-If called interactively, toggle `Highlight-Changes-Visible mode'.  If
-the prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Highlight-Changes-Visible mode' mode.  If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable the
+mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `highlight-changes-visible-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -16717,14 +16895,17 @@ argument VERBOSE non-nil makes the function verbose.
 (autoload 'hl-line-mode "hl-line" "\
 Toggle highlighting of the current line (Hl-Line mode).
 
-If called interactively, toggle `Hl-Line mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Hl-Line
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `hl-line-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -16753,14 +16934,17 @@ or call the function `global-hl-line-mode'.")
 (autoload 'global-hl-line-mode "hl-line" "\
 Toggle line highlighting in all buffers (Global Hl-Line mode).
 
-If called interactively, toggle `Global Hl-Line mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Global
+Hl-Line mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'global-hl-line-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -17171,14 +17355,17 @@ or call the function `fido-mode'.")
 (autoload 'fido-mode "icomplete" "\
 An enhanced `icomplete-mode' that emulates `ido-mode'.
 
-If called interactively, toggle `Fido mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Fido mode'
+mode.  If the prefix argument is positive, enable the mode, and if it
+is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'fido-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -17200,14 +17387,17 @@ or call the function `icomplete-mode'.")
 (autoload 'icomplete-mode "icomplete" "\
 Toggle incremental minibuffer completion (Icomplete mode).
 
-If called interactively, toggle `Icomplete mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Icomplete
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'icomplete-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -17239,14 +17429,17 @@ or call the function `icomplete-vertical-mode'.")
 (autoload 'icomplete-vertical-mode "icomplete" "\
 Toggle vertical candidate display in `icomplete-mode' or `fido-mode'.
 
-If called interactively, toggle `Icomplete-Vertical mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Icomplete-Vertical mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'icomplete-vertical-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -17778,14 +17971,17 @@ See `inferior-emacs-lisp-mode' for details.
 (autoload 'iimage-mode "iimage" "\
 Toggle Iimage mode on or off.
 
-If called interactively, toggle `Iimage mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Iimage
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `iimage-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -18098,14 +18294,17 @@ Setup easy-to-use keybindings for the commands to be 
used in dired mode.
 Note that n, p and <down> and <up> will be hijacked and bound to
 `image-dired-dired-x-line'.
 
-If called interactively, toggle `Image-Dired minor mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Image-Dired minor mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `image-dired-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -18200,14 +18399,17 @@ or call the function `auto-image-file-mode'.")
 (autoload 'auto-image-file-mode "image-file" "\
 Toggle visiting of image files as images (Auto Image File mode).
 
-If called interactively, toggle `Auto-Image-File mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Auto-Image-File mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'auto-image-file-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -18235,14 +18437,17 @@ Key bindings:
 (autoload 'image-minor-mode "image-mode" "\
 Toggle Image minor mode in this buffer.
 
-If called interactively, toggle `Image minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Image
+minor mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `image-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -19179,14 +19384,17 @@ available on the net." t nil)
 (autoload 'ispell-minor-mode "ispell" "\
 Toggle last-word spell checking (Ispell minor mode).
 
-If called interactively, toggle `ISpell minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `ISpell
+minor mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `ispell-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -19874,14 +20082,17 @@ sleep in seconds.
 (autoload 'linum-mode "linum" "\
 Toggle display of line numbers in the left margin (Linum mode).
 
-If called interactively, toggle `Linum mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Linum
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `linum-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -20452,14 +20663,17 @@ or call the function `mail-abbrevs-mode'.")
 (autoload 'mail-abbrevs-mode "mailabbrev" "\
 Toggle abbrev expansion of mail aliases (Mail Abbrevs mode).
 
-If called interactively, toggle `Mail-Abbrevs mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Mail-Abbrevs mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'mail-abbrevs-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -20831,14 +21045,17 @@ Default bookmark handler for Man buffers.
 (autoload 'master-mode "master" "\
 Toggle Master mode.
 
-If called interactively, toggle `Master mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Master
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `master-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -20873,14 +21090,18 @@ or call the function 
`minibuffer-depth-indicate-mode'.")
 (autoload 'minibuffer-depth-indicate-mode "mb-depth" "\
 Toggle Minibuffer Depth Indication mode.
 
-If called interactively, toggle `Minibuffer-Depth-Indicate mode'.  If
-the prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Minibuffer-Depth-Indicate mode' mode.  If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable the
+mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'minibuffer-depth-indicate-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -21438,14 +21659,17 @@ or call the function `midnight-mode'.")
 (autoload 'midnight-mode "midnight" "\
 Non-nil means run `midnight-hook' at midnight.
 
-If called interactively, toggle `Midnight mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Midnight
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'midnight-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -21490,14 +21714,18 @@ or call the function 
`minibuffer-electric-default-mode'.")
 (autoload 'minibuffer-electric-default-mode "minibuf-eldef" "\
 Toggle Minibuffer Electric Default mode.
 
-If called interactively, toggle `Minibuffer-Electric-Default mode'.
-If the prefix argument is positive, enable the mode, and if it is zero
-or negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Minibuffer-Electric-Default mode' mode.  If the prefix argument is
+positive, enable the mode, and if it is zero or negative, disable the
+mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'minibuffer-electric-default-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -22071,14 +22299,17 @@ or call the function `msb-mode'.")
 (autoload 'msb-mode "msb" "\
 Toggle Msb mode.
 
-If called interactively, toggle `Msb mode'.  If the prefix argument is
-positive, enable the mode, and if it is zero or negative, disable the
-mode.
+This is a minor mode.  If called interactively, toggle the `Msb mode'
+mode.  If the prefix argument is positive, enable the mode, and if it
+is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'msb-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -22387,14 +22618,17 @@ or call the function `mouse-wheel-mode'." :set 
#'custom-set-minor-mode :initiali
 (autoload 'mouse-wheel-mode "mwheel" "\
 Toggle mouse wheel support (Mouse Wheel mode).
 
-If called interactively, toggle `Mouse-Wheel mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Mouse-Wheel mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'mouse-wheel-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -24360,14 +24594,17 @@ Turning on outline mode calls the value of 
`text-mode-hook' and then of
 (autoload 'outline-minor-mode "outline" "\
 Toggle Outline minor mode.
 
-If called interactively, toggle `Outline minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Outline
+minor mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `outline-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -24601,14 +24838,17 @@ or call the function `show-paren-mode'.")
 (autoload 'show-paren-mode "paren" "\
 Toggle visualization of matching parens (Show Paren mode).
 
-If called interactively, toggle `Show-Paren mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Show-Paren
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'show-paren-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -25314,14 +25554,17 @@ or call the function `pixel-scroll-mode'.")
 (autoload 'pixel-scroll-mode "pixel-scroll" "\
 A minor mode to scroll text pixel-by-pixel.
 
-If called interactively, toggle `Pixel-Scroll mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Pixel-Scroll mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'pixel-scroll-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -26006,8 +26249,12 @@ Proced buffers.
 (autoload 'profiler-start "profiler" "\
 Start/restart profilers.
 MODE can be one of `cpu', `mem', or `cpu+mem'.
-If MODE is `cpu' or `cpu+mem', time-based profiler will be started.
-Also, if MODE is `mem' or `cpu+mem', then memory profiler will be started.
+If MODE is `cpu' or `cpu+mem', start the time-based profiler,
+   whereby CPU is sampled periodically using the SIGPROF signal.
+If MODE is `mem' or `cpu+mem', start profiler that samples CPU
+   whenever memory-allocation functions are called -- this is useful
+   if SIGPROF is not supported, or is unreliable, or is not sampling
+   at a high enough frequency.
 
 \(fn MODE)" t nil)
 
@@ -27078,14 +27325,17 @@ or call the function `rcirc-track-minor-mode'.")
 (autoload 'rcirc-track-minor-mode "rcirc" "\
 Global minor mode for tracking activity in rcirc buffers.
 
-If called interactively, toggle `Rcirc-Track minor mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Rcirc-Track minor mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'rcirc-track-minor-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -27135,14 +27385,17 @@ or call the function `recentf-mode'.")
 (autoload 'recentf-mode "recentf" "\
 Toggle \"Open Recent\" menu (Recentf mode).
 
-If called interactively, toggle `Recentf mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Recentf
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'recentf-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -27300,14 +27553,17 @@ with a prefix argument, prompt for START-AT and 
FORMAT.
 (autoload 'rectangle-mark-mode "rect" "\
 Toggle the region as rectangular.
 
-If called interactively, toggle `Rectangle-Mark mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Rectangle-Mark mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `rectangle-mark-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -27339,14 +27595,17 @@ Activates the region if needed.  Only lasts until the 
region is deactivated.
 (autoload 'refill-mode "refill" "\
 Toggle automatic refilling (Refill mode).
 
-If called interactively, toggle `Refill mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Refill
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `refill-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -27376,14 +27635,17 @@ Turn on RefTeX mode." nil nil)
 (autoload 'reftex-mode "reftex" "\
 Minor mode with distinct support for \\label, \\ref and \\cite in LaTeX.
 
-If called interactively, toggle `Reftex mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Reftex
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `reftex-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -27606,20 +27868,23 @@ Toggle Repeat mode.
 When Repeat mode is enabled, and the command symbol has the property named
 `repeat-map', this map is activated temporarily for the next command.
 
-If called interactively, toggle `Repeat mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Repeat
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'repeat-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
 \(fn &optional ARG)" t nil)
 
-(register-definition-prefixes "repeat" '("repeat-"))
+(register-definition-prefixes "repeat" '("describe-repeat" "repeat-"))
 
 ;;;***
 
@@ -27692,14 +27957,17 @@ report errors as appropriate for this kind of usage.
 (autoload 'reveal-mode "reveal" "\
 Toggle uncloaking of invisible text near point (Reveal mode).
 
-If called interactively, toggle `Reveal mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Reveal
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `reveal-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -27724,14 +27992,17 @@ or call the function `global-reveal-mode'.")
 Toggle Reveal mode in all buffers (Global Reveal mode).
 Reveal mode renders invisible text around point visible again.
 
-If called interactively, toggle `Global Reveal mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Global
+Reveal mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'global-reveal-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28265,14 +28536,17 @@ Validation will be enabled if 
`rng-nxml-auto-validate-flag' is non-nil." t nil)
 (autoload 'rng-validate-mode "rng-valid" "\
 Minor mode performing continual validation against a RELAX NG schema.
 
-If called interactively, toggle `Rng-Validate mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Rng-Validate mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `rng-validate-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28422,14 +28696,17 @@ highlighting.
 (autoload 'rst-minor-mode "rst" "\
 Toggle ReST minor mode.
 
-If called interactively, toggle `Rst minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Rst minor
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `rst-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28478,14 +28755,17 @@ Use the command `ruler-mode' to change this 
variable.")
 (autoload 'ruler-mode "ruler-mode" "\
 Toggle display of ruler in header line (Ruler mode).
 
-If called interactively, toggle `Ruler mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Ruler
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `ruler-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28755,14 +29035,17 @@ or call the function `savehist-mode'.")
 (autoload 'savehist-mode "savehist" "\
 Toggle saving of minibuffer history (Savehist mode).
 
-If called interactively, toggle `Savehist mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Savehist
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'savehist-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28816,14 +29099,17 @@ Non-nil means automatically save place in each file.
 This means when you visit a file, point goes to the last place
 where it was when you previously visited the same file.
 
-If called interactively, toggle `Save-Place mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Save-Place
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'save-place-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28835,14 +29121,17 @@ If this mode is enabled, point is recorded when you 
kill the buffer
 or exit Emacs.  Visiting this file again will go to that position,
 even in a later Emacs session.
 
-If called interactively, toggle `Save-Place-Local mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Save-Place-Local mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `save-place-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28929,14 +29218,17 @@ or call the function `scroll-all-mode'.")
 (autoload 'scroll-all-mode "scroll-all" "\
 Toggle shared scrolling in same-frame windows (Scroll-All mode).
 
-If called interactively, toggle `Scroll-All mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Scroll-All
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'scroll-all-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -28962,14 +29254,17 @@ one window apply to all visible windows in the same 
frame.
 (autoload 'scroll-lock-mode "scroll-lock" "\
 Buffer-local minor mode for pager-like scrolling.
 
-If called interactively, toggle `Scroll-Lock mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Scroll-Lock mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `scroll-lock-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -29038,14 +29333,17 @@ or call the function `semantic-mode'.")
 (autoload 'semantic-mode "semantic" "\
 Toggle parser features (Semantic mode).
 
-If called interactively, toggle `Semantic mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Semantic
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'semantic-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -29707,14 +30005,17 @@ or call the function `server-mode'.")
 (autoload 'server-mode "server" "\
 Toggle Server mode.
 
-If called interactively, toggle `Server mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Server
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'server-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -30337,14 +30638,17 @@ buffer names.
 (autoload 'smerge-mode "smerge-mode" "\
 Minor mode to simplify editing output from the diff3 program.
 
-If called interactively, toggle `SMerge mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `SMerge
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `smerge-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -30470,14 +30774,17 @@ Open the so-long `customize' group." t nil)
 (autoload 'so-long-minor-mode "so-long" "\
 This is the minor mode equivalent of `so-long-mode'.
 
-If called interactively, toggle `So-Long minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `So-Long
+minor mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `so-long-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -30552,14 +30859,17 @@ or call the function `global-so-long-mode'.")
 (autoload 'global-so-long-mode "so-long" "\
 Toggle automated performance mitigations for files with long lines.
 
-If called interactively, toggle `Global So-Long mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Global
+So-Long mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'global-so-long-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -31670,14 +31980,17 @@ or call the function `strokes-mode'.")
 (autoload 'strokes-mode "strokes" "\
 Toggle Strokes mode, a global minor mode.
 
-If called interactively, toggle `Strokes mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Strokes
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'strokes-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -31768,6 +32081,12 @@ Truncate STRING to LENGTH, replacing initial surplus 
with \"...\".
 
 \(fn STRING LENGTH)" nil nil)
 
+(autoload 'string-lines "subr-x" "\
+Split STRING into a list of lines.
+If OMIT-NULLS, empty lines will be removed from the results.
+
+\(fn STRING &optional OMIT-NULLS)" nil nil)
+
 (register-definition-prefixes "subr-x" '("and-let*" "hash-table-" "if-let*" 
"internal--" "named-let" "replace-region-contents" "string-" "thread-" 
"when-let*"))
 
 ;;;***
@@ -31780,14 +32099,17 @@ Truncate STRING to LENGTH, replacing initial surplus 
with \"...\".
 (autoload 'subword-mode "subword" "\
 Toggle subword movement and editing (Subword mode).
 
-If called interactively, toggle `Subword mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Subword
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `subword-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -31839,14 +32161,17 @@ See `subword-mode' for more information on Subword 
mode.
 (autoload 'superword-mode "subword" "\
 Toggle superword movement and editing (Superword mode).
 
-If called interactively, toggle `Superword mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Superword
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `superword-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -31944,14 +32269,17 @@ or call the function `gpm-mouse-mode'.")
 (autoload 'gpm-mouse-mode "t-mouse" "\
 Toggle mouse support in GNU/Linux consoles (GPM Mouse mode).
 
-If called interactively, toggle `Gpm-Mouse mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Gpm-Mouse
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'gpm-mouse-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -31975,14 +32303,17 @@ GPM.  This is due to limitations in GPM and the Linux 
kernel.
 (autoload 'tab-line-mode "tab-line" "\
 Toggle display of window tab line in the buffer.
 
-If called interactively, toggle `Tab-Line mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Tab-Line
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `tab-line-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -32389,14 +32720,17 @@ location is indicated by 
`table-word-continuation-char'.  This
 variable's value can be toggled by \\[table-fixed-width-mode] at
 run-time.
 
-If called interactively, toggle `Table-Fixed-Width mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Table-Fixed-Width mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `table-fixed-width-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -33569,14 +33903,17 @@ This function is meant to be used as a 
`post-self-insert-hook'." t nil)
 (autoload 'tildify-mode "tildify" "\
 Adds electric behavior to space character.
 
-If called interactively, toggle `Tildify mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Tildify
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `tildify-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -33624,14 +33961,17 @@ or call the function `display-time-mode'.")
 (autoload 'display-time-mode "time" "\
 Toggle display of time, load level, and mail flag in mode lines.
 
-If called interactively, toggle `Display-Time mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Display-Time mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'display-time-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -33799,7 +34139,7 @@ look like one of the following:
       Time-stamp: <>
       Time-stamp: \" \"
 The time stamp is written between the brackets or quotes:
-      Time-stamp: <2001-02-18 10:20:51 gildea>
+      Time-stamp: <2020-08-07 17:10:21 gildea>
 
 The time stamp is updated only if the variable
 `time-stamp-active' is non-nil.
@@ -33811,7 +34151,7 @@ The variables `time-stamp-pattern', 
`time-stamp-line-limit',
 
 (autoload 'time-stamp-toggle-active "time-stamp" "\
 Toggle `time-stamp-active', setting whether \\[time-stamp] updates a buffer.
-With ARG, turn time stamping on if and only if arg is positive.
+With ARG, turn time stamping on if and only if ARG is positive.
 
 \(fn &optional ARG)" t nil)
 
@@ -34421,7 +34761,7 @@ Add archive file name handler to 
`file-name-handler-alist'." (when tramp-archive
 
 ;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0))
 ;;; Generated autoloads from net/trampver.el
-(push (purecopy '(tramp 2 5 1 -1)) package--builtin-versions)
+(push (purecopy '(tramp 2 5 1)) package--builtin-versions)
 
 (register-definition-prefixes "trampver" '("tramp-"))
 
@@ -34600,14 +34940,17 @@ or call the function `type-break-mode'.")
 Enable or disable typing-break mode.
 This is a minor mode, but it is global to all buffers by default.
 
-If called interactively, toggle `Type-Break mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Type-Break
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'type-break-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -35131,14 +35474,17 @@ or call the function `url-handler-mode'.")
 (autoload 'url-handler-mode "url-handlers" "\
 Toggle using `url' library for URL filenames (URL Handler mode).
 
-If called interactively, toggle `Url-Handler mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Url-Handler mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'url-handler-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -37311,14 +37657,17 @@ own View-like bindings.
 (autoload 'view-mode "view" "\
 Toggle View mode, a minor mode for viewing text but not editing it.
 
-If called interactively, toggle `View mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `View mode'
+mode.  If the prefix argument is positive, enable the mode, and if it
+is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `view-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -37690,14 +38039,17 @@ or call the function `which-function-mode'.")
 (autoload 'which-function-mode "which-func" "\
 Toggle mode line display of current function (Which Function mode).
 
-If called interactively, toggle `Which-Function mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Which-Function mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'which-function-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -37718,14 +38070,17 @@ in certain major modes.
 (autoload 'whitespace-mode "whitespace" "\
 Toggle whitespace visualization (Whitespace mode).
 
-If called interactively, toggle `Whitespace mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Whitespace
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `whitespace-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -37737,14 +38092,17 @@ See also `whitespace-style', `whitespace-newline' and
 (autoload 'whitespace-newline-mode "whitespace" "\
 Toggle newline visualization (Whitespace Newline mode).
 
-If called interactively, toggle `Whitespace-Newline mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Whitespace-Newline mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `whitespace-newline-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -37770,14 +38128,17 @@ or call the function `global-whitespace-mode'.")
 (autoload 'global-whitespace-mode "whitespace" "\
 Toggle whitespace visualization globally (Global Whitespace mode).
 
-If called interactively, toggle `Global Whitespace mode'.  If the
-prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the `Global
+Whitespace mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'global-whitespace-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -37799,14 +38160,17 @@ or call the function 
`global-whitespace-newline-mode'.")
 (autoload 'global-whitespace-newline-mode "whitespace" "\
 Toggle global newline visualization (Global Whitespace Newline mode).
 
-If called interactively, toggle `Global Whitespace-Newline mode'.  If
-the prefix argument is positive, enable the mode, and if it is zero or
-negative, disable the mode.
+This is a minor mode.  If called interactively, toggle the `Global
+Whitespace-Newline mode' mode.  If the prefix argument is positive,
+enable the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'global-whitespace-newline-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -38129,14 +38493,17 @@ Show widget browser for WIDGET in other window.
 (autoload 'widget-minor-mode "wid-browse" "\
 Minor mode for traversing widgets.
 
-If called interactively, toggle `Widget minor mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the `Widget
+minor mode' mode.  If the prefix argument is positive, enable the
+mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `widget-minor-mode'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -38239,31 +38606,37 @@ unless `windmove-create-window' is non-nil and a new 
window is created.
 Set up keybindings for `windmove'.
 Keybindings are of the form MODIFIERS-{left,right,up,down},
 where MODIFIERS is either a list of modifiers or a single modifier.
+If MODIFIERS is `none', the keybindings will be directly bound to
+the arrow keys.
 Default value of MODIFIERS is `shift'.
 
 \(fn &optional MODIFIERS)" t nil)
 
 (autoload 'windmove-display-left "windmove" "\
 Display the next buffer in window to the left of the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'.
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'.
 
 \(fn &optional ARG)" t nil)
 
 (autoload 'windmove-display-up "windmove" "\
 Display the next buffer in window above the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'.
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'.
 
 \(fn &optional ARG)" t nil)
 
 (autoload 'windmove-display-right "windmove" "\
 Display the next buffer in window to the right of the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'.
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'.
 
 \(fn &optional ARG)" t nil)
 
 (autoload 'windmove-display-down "windmove" "\
 Display the next buffer in window below the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'.
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'.
 
 \(fn &optional ARG)" t nil)
 
@@ -38287,6 +38660,8 @@ Set up keybindings for directional buffer display.
 Keys are bound to commands that display the next buffer in the specified
 direction.  Keybindings are of the form MODIFIERS-{left,right,up,down},
 where MODIFIERS is either a list of modifiers or a single modifier.
+If MODIFIERS is `none', the keybindings will be directly bound to
+the arrow keys.
 Default value of MODIFIERS is `shift-meta'.
 
 \(fn &optional MODIFIERS)" t nil)
@@ -38324,7 +38699,10 @@ Set up keybindings for directional window deletion.
 Keys are bound to commands that delete windows in the specified
 direction.  Keybindings are of the form PREFIX MODIFIERS-{left,right,up,down},
 where PREFIX is a prefix key and MODIFIERS is either a list of modifiers or
-a single modifier.  Default value of PREFIX is `C-x' and MODIFIERS is `shift'.
+a single modifier.
+If PREFIX is `none', no prefix is used. If MODIFIERS is `none', the keybindings
+are directly bound to the arrow keys.
+Default value of PREFIX is `C-x' and MODIFIERS is `shift'.
 
 \(fn &optional PREFIX MODIFIERS)" t nil)
 
@@ -38345,7 +38723,10 @@ Set up keybindings for directional window swap states.
 Keys are bound to commands that swap the states of the selected window
 with the window in the specified direction.  Keybindings are of the form
 MODIFIERS-{left,right,up,down}, where MODIFIERS is either a list of modifiers
-or a single modifier.  Default value of MODIFIERS is `shift-super'.
+or a single modifier.
+If MODIFIERS is `none', the keybindings will be directly bound to the
+arrow keys.
+Default value of MODIFIERS is `shift-super'.
 
 \(fn &optional MODIFIERS)" t nil)
 
@@ -38369,14 +38750,17 @@ or call the function `winner-mode'.")
 (autoload 'winner-mode "winner" "\
 Toggle Winner mode on or off.
 
-If called interactively, toggle `Winner mode'.  If the prefix argument
-is positive, enable the mode, and if it is zero or negative, disable
-the mode.
+This is a minor mode.  If called interactively, toggle the `Winner
+mode' mode.  If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'winner-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
@@ -38661,14 +39045,17 @@ or call the function `xterm-mouse-mode'.")
 (autoload 'xterm-mouse-mode "xt-mouse" "\
 Toggle XTerm mouse mode.
 
-If called interactively, toggle `Xterm-Mouse mode'.  If the prefix
-argument is positive, enable the mode, and if it is zero or negative,
-disable the mode.
+This is a minor mode.  If called interactively, toggle the
+`Xterm-Mouse mode' mode.  If the prefix argument is positive, enable
+the mode, and if it is zero or negative, disable the mode.
 
 If called from Lisp, toggle the mode if ARG is `toggle'.  Enable the
 mode if ARG is nil, omitted, or is a positive number.  Disable the
 mode if ARG is a negative number.
 
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value 'xterm-mouse-mode)'.
+
 The mode's hook is called both when the mode is enabled and when it is
 disabled.
 
diff --git a/lisp/leim/quail/latin-post.el b/lisp/leim/quail/latin-post.el
index 1040877..8329fff 100644
--- a/lisp/leim/quail/latin-post.el
+++ b/lisp/leim/quail/latin-post.el
@@ -1298,6 +1298,64 @@ Doubling the postfix separates the letter and postfix: 
e.g. a\\=`\\=` -> a\\=`
  ("a__" ["a_"])
  )
 
+;; Input modes of various orthographies for the Lakota language.
+;; I'd like to acknowledge the elders and ancestors who fought
+;; to keep the language and culture alive.
+;; Grant Shangreaux <grant@churls.world> 2021-05-23
+
+(quail-define-package
+ "lakota-white-hat-postfix" "Lakota" "Lak " t
+ "Lakota White Hat orthography input method with postfix modifiers.
+The `f' key produces the nasal ŋ while unused letters `r' and `v' add
+the combining dot above and macron diacritics respectively.  This allows
+production of all the consonants:
+
+cv -> c̄    hr -> ḣ    pv -> p̄    tv -> t̄
+cr -> ċ    kv -> k̄    pr -> ṗ    tr -> ṫ
+gr -> ġ    kr -> k̇    sr -> ṡ    zr -> ż
+
+The glottal stop is produced by repeating the ' character.  This orthography
+does not use stress diacritics on vowels. Mit̄ak̄uyep̄i p̄ilamayayap̄ilo."
+nil t nil nil nil nil nil nil nil nil t)
+
+(quail-define-rules
+ ("f" ?ŋ)
+ ("''" ?’)
+ ;; using hex representation as these characters combine with the ? syntax
+ ("r" #x307)                            ; COMBINING DOT ABOVE
+ ("v" #x304))                            ; COMBINING MACRON
+
+
+
+(quail-define-package
+ "lakota-slo-postfix" "Lakota" "SLO " t
+ "Suggested Lakota Orthography input method with postfix modifier.
+To add stress to a vowel, simply type the single quote ' after the vowel.
+The glottal stop is produced by repeating the ' character.  All other
+characters are bound to a single key.  Mitákuyepi philámayayapi ló."
+nil t nil nil nil nil nil nil nil nil t)
+
+(quail-define-rules
+ ;; accented vowels
+ ("a'" ?á) ("A'" ?Á)
+ ("e'" ?é) ("E'" ?É)
+ ("i'" ?í) ("I'" ?Í)
+ ("o'" ?ó) ("O'" ?Ó)
+ ("u'" ?ú) ("U'" ?Ú)
+
+ ;; consonants with caron
+ ("c" ?č) ("C" ?Č)
+ ("j" ?ȟ) ("J" ?Ȟ)
+ ("q" ?ǧ) ("Q" ?Ǧ)
+ ("x" ?ž) ("X" ?Ž)
+ ("r" ?š) ("R" ?Š)
+
+ ;; velar nasal n
+ ("f" ?ŋ)
+
+ ;; glottal stop
+ ("''" ?’))
+
 (quail-define-package
  "norwegian-postfix" "Latin-1" "NO<" t
  "Norwegian (Norsk) input method (rule: AE->Æ   OE->Ø   AA->Å   E\\='->É
diff --git a/lisp/leim/quail/latin-pre.el b/lisp/leim/quail/latin-pre.el
index b8b0fab..3b9c942 100644
--- a/lisp/leim/quail/latin-pre.el
+++ b/lisp/leim/quail/latin-pre.el
@@ -1337,4 +1337,33 @@ Doubling the prefix separates the letter and prefix. --a 
-> -a
  ("``"  ["`"])
  )
 
+(quail-define-package
+ "lakota-slo-prefix" "Lakota" "SLO " t
+ "Suggested Lakota Orthography input method with prefix modifier.
+To add stress to a vowel, simply type the single quote ' before the vowel.
+The glottal stop is produced by repeating the ' character.  All other
+characters are bound to a single key.  Mitákuyepi philámayayapi ló."
+nil t nil nil nil nil nil nil nil nil t)
+
+(quail-define-rules
+ ;; accented vowels
+ ("'a" ?á) ("'A" ?Á)
+ ("'e" ?é) ("'E" ?É)
+ ("'i" ?í) ("'I" ?Í)
+ ("'o" ?ó) ("'O" ?Ó)
+ ("'u" ?ú) ("'U" ?Ú)
+
+ ;; consonants with caron
+ ("c" ?č) ("C" ?Č)
+ ("j" ?ȟ) ("J" ?Ȟ)
+ ("q" ?ǧ) ("Q" ?Ǧ)
+ ("x" ?ž) ("X" ?Ž)
+ ("r" ?š) ("R" ?Š)
+
+ ;; velar nasal n
+ ("f" ?ŋ)
+
+ ;; glottal stop
+ ("''" ?’))
+
 ;;; latin-pre.el ends here
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index d09a348..813ce14 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -882,6 +882,12 @@ If the current buffer is not a minibuffer, erase its 
entire contents."
   ;; is on, the field doesn't cover the entire minibuffer contents.
   (delete-region (minibuffer-prompt-end) (point-max)))
 
+(defun minibuffer--completion-prompt-end ()
+  (let ((end (minibuffer-prompt-end)))
+    (if (< (point) end)
+        (user-error "Can't complete in prompt")
+      end)))
+
 (defvar completion-show-inline-help t
   "If non-nil, print helpful inline messages during completion.")
 
@@ -1349,10 +1355,9 @@ If no characters can be completed, display a list of 
possible completions.
 If you repeat this command after it displayed such a list,
 scroll the window of possible completions."
   (interactive)
-  (when (<= (minibuffer-prompt-end) (point))
-    (completion-in-region (minibuffer-prompt-end) (point-max)
-                          minibuffer-completion-table
-                          minibuffer-completion-predicate)))
+  (completion-in-region (minibuffer--completion-prompt-end) (point-max)
+                        minibuffer-completion-table
+                        minibuffer-completion-predicate))
 
 (defun completion--in-region-1 (beg end)
   ;; If the previous command was not this,
@@ -1530,7 +1535,7 @@ Remove completion BASE prefix string from history 
elements."
   (unless completion-cycling
     (minibuffer-force-complete nil nil 'dont-cycle))
   (completion--complete-and-exit
-   (minibuffer-prompt-end) (point-max) #'exit-minibuffer
+   (minibuffer--completion-prompt-end) (point-max) #'exit-minibuffer
    ;; If the previous completion completed to an element which fails
    ;; test-completion, then we shouldn't exit, but that should be rare.
    (lambda ()
@@ -1548,7 +1553,7 @@ DONT-CYCLE tells the function not to setup cycling."
   ;; FIXME: Need to deal with the extra-size issue here as well.
   ;; FIXME: ~/src/emacs/t<M-TAB>/lisp/minibuffer.el completes to
   ;; ~/src/emacs/trunk/ and throws away lisp/minibuffer.el.
-  (let* ((start (copy-marker (or start (minibuffer-prompt-end))))
+  (let* ((start (copy-marker (or start (minibuffer--completion-prompt-end))))
          (end (or end (point-max)))
          ;; (md (completion--field-metadata start))
          (all (completion-all-sorted-completions start end))
@@ -1619,7 +1624,7 @@ If `minibuffer-completion-confirm' is 
`confirm-after-completion',
  `minibuffer-confirm-exit-commands', and accept the input
  otherwise."
   (interactive)
-  (completion-complete-and-exit (minibuffer-prompt-end) (point-max)
+  (completion-complete-and-exit (minibuffer--completion-prompt-end) (point-max)
                                 #'exit-minibuffer))
 
 (defun completion-complete-and-exit (beg end exit-function)
@@ -1785,17 +1790,12 @@ is added, provided that matches some possible 
completion.
 Return nil if there is no valid completion, else t."
   (interactive)
   (completion-in-region--single-word
-   (minibuffer-prompt-end) (point-max)
-   minibuffer-completion-table minibuffer-completion-predicate))
-
-(defun completion-in-region--single-word (beg end collection
-                                              &optional predicate)
-  (let ((minibuffer-completion-table collection)
-        (minibuffer-completion-predicate predicate))
-    (pcase (completion--do-completion beg end
-                                      #'completion--try-word-completion)
+   (minibuffer--completion-prompt-end) (point-max)))
+
+(defun completion-in-region--single-word (beg end)
+  (pcase (completion--do-completion beg end #'completion--try-word-completion)
     (#b000 nil)
-      (_     t))))
+    (_     t)))
 
 (defface completions-annotations '((t :inherit (italic shadow)))
   "Face to use for annotations in the *Completions* buffer.")
@@ -2159,7 +2159,7 @@ variables.")
   "Display a list of possible completions of the current minibuffer contents."
   (interactive)
   (message "Making completion list...")
-  (let* ((start (or start (minibuffer-prompt-end)))
+  (let* ((start (or start (minibuffer--completion-prompt-end)))
          (end (or end (point-max)))
          (string (buffer-substring start end))
          (md (completion--field-metadata start))
@@ -3161,6 +3161,7 @@ See `read-file-name' for the meaning of the arguments."
         (unless val (error "No file name specified"))
 
         (if (and default-filename
+                (not (file-remote-p dir))
                  (string-equal val (if (consp insdef) (car insdef) insdef)))
             (setq val default-filename))
         (setq val (substitute-in-file-name val))
diff --git a/lisp/mouse.el b/lisp/mouse.el
index d0064ee..ab260d4 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -550,6 +550,18 @@ the frame instead."
         (when (frame-parameter frame 'drag-with-header-line)
           (mouse-drag-frame-move start-event))))))
 
+(defun mouse-drag-tab-line (start-event)
+  "Drag frame with tab line in its topmost window.
+START-EVENT is the starting mouse event of the drag action."
+  (interactive "e")
+  (let* ((start (event-start start-event))
+        (window (posn-window start)))
+    (when (and (window-live-p window)
+               (window-at-side-p window 'top))
+      (let ((frame (window-frame window)))
+        (when (frame-parameter frame 'drag-with-tab-line)
+          (mouse-drag-frame-move start-event))))))
+
 (defun mouse-drag-vertical-line (start-event)
   "Change the width of a window by dragging on a vertical line.
 START-EVENT is the starting mouse event of the drag action."
@@ -678,6 +690,7 @@ frame with the mouse."
              ;; with a mode-line, header-line or vertical-line prefix ...
              (define-key map [mode-line] map)
              (define-key map [header-line] map)
+             (define-key map [tab-line] map)
              (define-key map [vertical-line] map)
              ;; ... and some maybe even with a right- or bottom-divider
              ;; prefix.
@@ -904,6 +917,7 @@ frame with the mouse."
              ;; with a mode-line, header-line or vertical-line prefix ...
              (define-key map [mode-line] map)
              (define-key map [header-line] map)
+             (define-key map [tab-line] map)
              (define-key map [vertical-line] map)
              ;; ... and some maybe even with a right- or bottom-divider
              ;; prefix.
@@ -2908,6 +2922,7 @@ is copied instead of being cut."
 ;; versions.
 (global-set-key [header-line down-mouse-1] 'mouse-drag-header-line)
 (global-set-key [header-line mouse-1] 'mouse-select-window)
+(global-set-key [tab-line down-mouse-1] 'mouse-drag-tab-line)
 (global-set-key [tab-line mouse-1] 'mouse-select-window)
 ;; (global-set-key [mode-line drag-mouse-1] 'mouse-select-window)
 (global-set-key [mode-line down-mouse-1] 'mouse-drag-mode-line)
diff --git a/lisp/net/dig.el b/lisp/net/dig.el
index ddbfb95..4f0b0df 100644
--- a/lisp/net/dig.el
+++ b/lisp/net/dig.el
@@ -138,9 +138,14 @@ Buffer should contain output generated by `dig-invoke'."
 ;;;###autoload
 (defun dig (domain &optional
                   query-type query-class query-option dig-option server)
-  "Query addresses of a DOMAIN using dig, by calling `dig-invoke'.
-Optional arguments are passed to `dig-invoke'."
-  (interactive "sHost: ")
+  "Query addresses of a DOMAIN using dig.
+See `dig-invoke' for an explanation for the parameters.
+When called interactively, DOMAIN is prompted for.  If given a prefix,
+also prompt for the QUERY-TYPE parameter."
+  (interactive
+   (list (read-string "Host: ")
+         (and current-prefix-arg
+              (read-string "Query type: "))))
   (pop-to-buffer-same-window
    (dig-invoke domain query-type query-class query-option dig-option server))
   (goto-char (point-min))
diff --git a/lisp/net/eudc.el b/lisp/net/eudc.el
index 425217c..6459c52 100644
--- a/lisp/net/eudc.el
+++ b/lisp/net/eudc.el
@@ -1129,7 +1129,9 @@ queries the server for the existing fields and displays a 
corresponding form."
     (cons "Directory Servers"
          (easy-menu-create-menu "Directory Servers" (cdr (eudc-menu))))))
 
-;;; Load time initializations :
+;;}}}
+
+;;{{{ Load time initializations
 
 ;; Load the options file
 (if (and (not noninteractive)
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 4fdb63e..6c660d2 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -56,9 +56,9 @@
   :group 'applications)
 
 (defcustom rcirc-server-alist
-  '(("chat.freenode.net" :channels ("#rcirc")
+  '(("irc.libera.chat" :channels ("#rcirc")
      ;; Don't use the TLS port by default, in case gnutls is not available.
-     ;; :port 7000 :encryption tls
+     ;; :port 6697 :encryption tls
      ))
   "An alist of IRC connections to establish when running `rcirc'.
 Each element looks like (SERVER-NAME PARAMETERS).
@@ -245,13 +245,15 @@ The ARGUMENTS for each METHOD symbol are:
   `chanserv': NICK CHANNEL PASSWORD
   `bitlbee': NICK PASSWORD
   `quakenet': ACCOUNT PASSWORD
+  `sasl': NICK PASSWORD
 
 Examples:
- ((\"freenode\" nickserv \"bob\" \"p455w0rd\")
-  (\"freenode\" chanserv \"bob\" \"#bobland\" \"passwd99\")
+ ((\"Libera.Chat\" nickserv \"bob\" \"p455w0rd\")
+  (\"Libera.Chat\" chanserv \"bob\" \"#bobland\" \"passwd99\")
   (\"bitlbee\" bitlbee \"robert\" \"sekrit\")
   (\"dal.net\" nickserv \"bob\" \"sekrit\" \"NickServ@services.dal.net\")
-  (\"quakenet.org\" quakenet \"bobby\" \"sekrit\"))"
+  (\"quakenet.org\" quakenet \"bobby\" \"sekrit\")
+  (\"oftc\" sasl \"bob\" \"hunter2\"))"
   :type '(alist :key-type (regexp :tag "Server")
                :value-type (choice (list :tag "NickServ"
                                          (const nickserv)
@@ -269,6 +271,10 @@ Examples:
                                     (list :tag "QuakeNet"
                                           (const quakenet)
                                           (string :tag "Account")
+                                          (string :tag "Password"))
+                                    (list :tag "SASL"
+                                          (const sasl)
+                                          (string :tag "Nick")
                                           (string :tag "Password")))))
 
 (defcustom rcirc-auto-authenticate-flag t
@@ -543,6 +549,22 @@ If ARG is non-nil, instead prompt for connection 
parameters."
 (defvar rcirc-connection-info nil)
 (defvar rcirc-process nil)
 
+(defun rcirc-get-server-method (server)
+  (catch 'method
+    (dolist (i rcirc-authinfo)
+      (let ((server-i (car i))
+           (method (cadr i)))
+       (when (string-match server-i server)
+          (throw 'method method))))))
+
+(defun rcirc-get-server-password (server)
+  (catch 'pass
+    (dolist (i rcirc-authinfo)
+      (let ((server-i (car i))
+           (args (cdddr i)))
+       (when (string-match server-i server)
+          (throw 'pass (car args)))))))
+
 ;;;###autoload
 (defun rcirc-connect (server &optional port nick user-name
                              full-name startup-channels password encryption
@@ -559,6 +581,7 @@ If ARG is non-nil, instead prompt for connection 
parameters."
           (user-name (or user-name rcirc-default-user-name))
           (full-name (or full-name rcirc-default-full-name))
           (startup-channels startup-channels)
+           (use-sasl (eq (rcirc-get-server-method server) 'sasl))
            (process (open-network-stream
                      (or server-alias server) nil server port-number
                      :type (or encryption 'plain))))
@@ -591,6 +614,8 @@ If ARG is non-nil, instead prompt for connection 
parameters."
       (setq-local rcirc-server-parameters nil)
 
       (add-hook 'auto-save-hook 'rcirc-log-write)
+      (when use-sasl
+        (rcirc-send-string process "CAP REQ sasl"))
 
       ;; identify
       (unless (zerop (length password))
@@ -598,6 +623,10 @@ If ARG is non-nil, instead prompt for connection 
parameters."
       (rcirc-send-string process (concat "NICK " nick))
       (rcirc-send-string process (concat "USER " user-name
                                          " 0 * :" full-name))
+      ;; Setup sasl, and initiate authentication.
+      (when (and rcirc-auto-authenticate-flag
+                 use-sasl)
+        (rcirc-send-string process "AUTHENTICATE PLAIN"))
 
       ;; setup ping timer if necessary
       (unless rcirc-keepalive-timer
@@ -2923,7 +2952,8 @@ Passwords are stored in `rcirc-authinfo' (which see)."
                  (rcirc-send-privmsg
                   process
                   "&bitlbee"
-                  (concat "IDENTIFY " (car args)))))
+                  (concat "IDENTIFY " (car args))))
+                (sasl nil))
             ;; quakenet authentication doesn't rely on the user's nickname.
             ;; the variable `nick' here represents the Q account name.
             (when (eq method 'quakenet)
@@ -2969,6 +2999,16 @@ Passwords are stored in `rcirc-authinfo' (which see)."
 
 (defun rcirc-handler-CTCP-response (process _target sender message)
   (rcirc-print process sender "CTCP" nil message t))
+
+(defun rcirc-handler-AUTHENTICATE (process _cmd _args _text)
+  (rcirc-send-string
+   process
+   (format "AUTHENTICATE %s"
+           (base64-encode-string
+            ;; use connection user-name
+            (concat "\0" (nth 3 rcirc-connection-info)
+                    "\0" (rcirc-get-server-password rcirc-server))))))
+
 
 (defgroup rcirc-faces nil
   "Faces for rcirc."
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index aacf83e..7fb0ff5 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -549,8 +549,7 @@ But handle the case, if the \"test\" command is not 
available."
       (when (and append (file-exists-p filename))
        (copy-file filename tmpfile 'ok)
        (set-file-modes tmpfile (logior (or (file-modes tmpfile) 0) #o0600)))
-      (tramp-run-real-handler
-       #'write-region (list start end tmpfile append 'no-message lockname))
+      (write-region start end tmpfile append 'no-message lockname)
       (with-tramp-progress-reporter
         v 3 (format-message
              "Moving tmp file `%s' to `%s'" tmpfile filename)
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index b613ad3..88caa2f 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -2667,56 +2667,63 @@ the result will be a local, non-Tramp, file name."
   (setq dir (or dir default-directory "/"))
   ;; Handle empty NAME.
   (when (zerop (length name)) (setq name "."))
-  ;; Unless NAME is absolute, concat DIR and NAME.
-  (unless (file-name-absolute-p name)
-    (setq name (concat (file-name-as-directory dir) name)))
-  ;; If connection is not established yet, run the real handler.
-  (if (not (tramp-connectable-p name))
-      (tramp-run-real-handler #'expand-file-name (list name nil))
-    ;; Dissect NAME.
-    (with-parsed-tramp-file-name name nil
-      (unless (tramp-run-real-handler #'file-name-absolute-p (list localname))
-       (setq localname (concat "~/" localname)))
-      ;; Tilde expansion if necessary.  This needs a shell which
-      ;; groks tilde expansion!  The function `tramp-find-shell' is
-      ;; supposed to find such a shell on the remote host.  Please
-      ;; tell me about it when this doesn't work on your system.
-      (when (string-match "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
-       (let ((uname (match-string 1 localname))
-             (fname (match-string 2 localname)))
-         ;; We cannot simply apply "~/", because under sudo "~/" is
-         ;; expanded to the local user home directory but to the
-         ;; root home directory.  On the other hand, using always
-         ;; the default user name for tilde expansion is not
-         ;; appropriate either, because ssh and companions might
-         ;; use a user name from the config file.
-         (when (and (string-equal uname "~")
-                    (string-match-p "\\`su\\(do\\)?\\'" method))
-           (setq uname (concat uname user)))
-         (setq uname
-               (with-tramp-connection-property v uname
-                 (tramp-send-command
-                  v (format "cd %s && pwd" (tramp-shell-quote-argument uname)))
-                 (with-current-buffer (tramp-get-buffer v)
-                   (goto-char (point-min))
-                   (buffer-substring (point) (point-at-eol)))))
-         (setq localname (concat uname fname))))
-      ;; There might be a double slash, for example when "~/"
-      ;; expands to "/".  Remove this.
-      (while (string-match "//" localname)
-       (setq localname (replace-match "/" t t localname)))
-      ;; Do not keep "/..".
-      (when (string-match-p "^/\\.\\.?$" localname)
-       (setq localname "/"))
-      ;; No tilde characters in file name, do normal
-      ;; `expand-file-name' (this does "/./" and "/../").
-      ;; `default-directory' is bound, because on Windows there would
-      ;; be problems with UNC shares or Cygwin mounts.
-      (let ((default-directory (tramp-compat-temporary-file-directory)))
-       (tramp-make-tramp-file-name
-        v (tramp-drop-volume-letter
-           (tramp-run-real-handler
-            #'expand-file-name (list localname))))))))
+  ;; On MS Windows, some special file names are not returned properly
+  ;; by `file-name-absolute-p'.
+  (if (and (eq system-type 'windows-nt)
+          (string-match-p
+           (concat "^\\([[:alpha:]]:\\|" null-device "$\\)") name))
+      (tramp-run-real-handler #'expand-file-name (list name dir))
+    ;; Unless NAME is absolute, concat DIR and NAME.
+    (unless (file-name-absolute-p name)
+      (setq name (concat (file-name-as-directory dir) name)))
+    ;; If connection is not established yet, run the real handler.
+    (if (not (tramp-connectable-p name))
+       (tramp-run-real-handler #'expand-file-name (list name nil))
+      ;; Dissect NAME.
+      (with-parsed-tramp-file-name name nil
+       (unless (tramp-run-real-handler #'file-name-absolute-p (list localname))
+         (setq localname (concat "~/" localname)))
+       ;; Tilde expansion if necessary.  This needs a shell which
+       ;; groks tilde expansion!  The function `tramp-find-shell' is
+       ;; supposed to find such a shell on the remote host.  Please
+       ;; tell me about it when this doesn't work on your system.
+       (when (string-match "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
+         (let ((uname (match-string 1 localname))
+               (fname (match-string 2 localname)))
+           ;; We cannot simply apply "~/", because under sudo "~/" is
+           ;; expanded to the local user home directory but to the
+           ;; root home directory.  On the other hand, using always
+           ;; the default user name for tilde expansion is not
+           ;; appropriate either, because ssh and companions might
+           ;; use a user name from the config file.
+           (when (and (string-equal uname "~")
+                      (string-match-p "\\`su\\(do\\)?\\'" method))
+             (setq uname (concat uname user)))
+           (setq uname
+                 (with-tramp-connection-property v uname
+                   (tramp-send-command
+                    v
+                    (format "cd %s && pwd" (tramp-shell-quote-argument uname)))
+                   (with-current-buffer (tramp-get-buffer v)
+                     (goto-char (point-min))
+                     (buffer-substring (point) (point-at-eol)))))
+           (setq localname (concat uname fname))))
+       ;; There might be a double slash, for example when "~/"
+       ;; expands to "/".  Remove this.
+       (while (string-match "//" localname)
+         (setq localname (replace-match "/" t t localname)))
+       ;; Do not keep "/..".
+       (when (string-match-p "^/\\.\\.?$" localname)
+         (setq localname "/"))
+       ;; No tilde characters in file name, do normal
+       ;; `expand-file-name' (this does "/./" and "/../").
+       ;; `default-directory' is bound, because on Windows there
+       ;; would be problems with UNC shares or Cygwin mounts.
+       (let ((default-directory (tramp-compat-temporary-file-directory)))
+         (tramp-make-tramp-file-name
+          v (tramp-drop-volume-letter
+             (tramp-run-real-handler
+              #'expand-file-name (list localname)))))))))
 
 ;;; Remote commands:
 
@@ -3225,7 +3232,6 @@ implementation will be used."
       (run-hooks 'tramp-handle-file-local-copy-hook)
       tmpfile)))
 
-;; CCC grok LOCKNAME
 (defun tramp-sh-handle-write-region
   (start end filename &optional append visit lockname mustbenew)
   "Like `write-region' for Tramp files."
@@ -3254,9 +3260,7 @@ implementation will be used."
                  (or (file-directory-p localname)
                      (file-writable-p localname)))))
          ;; Short track: if we are on the local host, we can run directly.
-         (tramp-run-real-handler
-          #'write-region
-          (list start end localname append 'no-message lockname))
+         (write-region start end localname append 'no-message lockname)
 
        (let* ((modes (tramp-default-file-modes
                       filename (and (eq mustbenew 'excl) 'nofollow)))
@@ -3289,13 +3293,10 @@ implementation will be used."
          ;; file.  We call `set-visited-file-modtime' ourselves later
          ;; on.  We must ensure that `file-coding-system-alist'
          ;; matches `tmpfile'.
-         (let (file-name-handler-alist
-               (file-coding-system-alist
+         (let ((file-coding-system-alist
                 (tramp-find-file-name-coding-system-alist filename tmpfile)))
            (condition-case err
-               (tramp-run-real-handler
-                #'write-region
-                (list start end tmpfile append 'no-message lockname))
+               (write-region start end tmpfile append 'no-message lockname)
              ((error quit)
               (setq tramp-temp-buffer-file-name nil)
               (delete-file tmpfile)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 5284981..75e4455 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -3648,17 +3648,17 @@ User is always nil."
                     (cdr x))))
                tramp-backup-directory-alist)
             backup-directory-alist))
-         (uid (tramp-compat-file-attribute-user-id
-               (file-attributes filename 'integer)))
          result)
       (prog1 ;; Run plain `find-backup-file-name'.
          (setq result
                (tramp-run-real-handler
                 #'find-backup-file-name (list filename)))
         ;; Protect against security hole.
-       (when (and (natnump uid) (zerop uid)
+       (when (and (not tramp-allow-unsafe-temporary-files)
                   (file-in-directory-p (car result) temporary-file-directory)
-                  (not tramp-allow-unsafe-temporary-files)
+                  (zerop (or (tramp-compat-file-attribute-user-id
+                              (file-attributes filename 'integer))
+                             tramp-unknown-id-integer))
                   (not (with-tramp-connection-property
                            (tramp-get-process v) "unsafe-temporary-file"
                          (yes-or-no-p
@@ -4386,8 +4386,7 @@ of."
       ;; We say `no-message' here because we don't want the visited file
       ;; modtime data to be clobbered from the temp file.  We call
       ;; `set-visited-file-modtime' ourselves later on.
-      (tramp-run-real-handler
-       #'write-region (list start end tmpfile append 'no-message lockname))
+      (write-region start end tmpfile append 'no-message lockname)
       (condition-case nil
          (rename-file tmpfile filename 'ok-if-already-exists)
        (error
@@ -5264,8 +5263,7 @@ this file, if that variable is non-nil."
          (auto-save-file-name-transforms
           (if (null tramp-auto-save-directory)
               auto-save-file-name-transforms))
-         (uid (tramp-compat-file-attribute-user-id
-               (file-attributes buffer-file-name 'integer)))
+         (filename buffer-file-name)
          (buffer-file-name
           (if (null tramp-auto-save-directory)
               buffer-file-name
@@ -5283,9 +5281,11 @@ this file, if that variable is non-nil."
       (prog1 ;; Run plain `make-auto-save-file-name'.
          (setq result (tramp-run-real-handler #'make-auto-save-file-name nil))
        ;; Protect against security hole.
-       (when (and (natnump uid) (zerop uid)
+       (when (and (not tramp-allow-unsafe-temporary-files)
                   (file-in-directory-p result temporary-file-directory)
-                  (not tramp-allow-unsafe-temporary-files)
+                  (zerop (or (tramp-compat-file-attribute-user-id
+                              (file-attributes filename 'integer))
+                             tramp-unknown-id-integer))
                   (not (with-tramp-connection-property
                            (tramp-get-process v) "unsafe-temporary-file"
                          (yes-or-no-p
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index abd9221..e6cf4c6 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -7,7 +7,7 @@
 ;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
 ;; Keywords: comm, processes
 ;; Package: tramp
-;; Version: 2.5.1-pre
+;; Version: 2.5.1
 ;; Package-Requires: ((emacs "25.1"))
 ;; Package-Type: multi
 ;; URL: https://www.gnu.org/software/tramp/
@@ -40,7 +40,7 @@
 ;; ./configure" to change them.
 
 ;;;###tramp-autoload
-(defconst tramp-version "2.5.1-pre"
+(defconst tramp-version "2.5.1"
   "This version of Tramp.")
 
 ;;;###tramp-autoload
@@ -76,7 +76,7 @@
 ;; Check for Emacs version.
 (let ((x   (if (not (string-lessp emacs-version "25.1"))
       "ok"
-    (format "Tramp 2.5.1-pre is not fit for %s"
+    (format "Tramp 2.5.1 is not fit for %s"
             (replace-regexp-in-string "\n" "" (emacs-version))))))
   (unless (string-equal "ok" x) (error "%s" x)))
 
diff --git a/lisp/org/ol-irc.el b/lisp/org/ol-irc.el
index e3d7651..df62dd0 100644
--- a/lisp/org/ol-irc.el
+++ b/lisp/org/ol-irc.el
@@ -39,9 +39,9 @@
 ;;
 ;; Links within an org buffer might look like this:
 ;;
-;; [[irc:/irc.freenode.net/#emacs/bob][chat with bob in #emacs on freenode]]
-;; [[irc:/irc.freenode.net/#emacs][#emacs on freenode]]
-;; [[irc:/irc.freenode.net/]]
+;; [[irc:/irc.libera.chat/#emacs/bob][chat with bob in #emacs on Libera.Chat]]
+;; [[irc:/irc.libera.chat/#emacs][#emacs on Libera.Chat]]
+;; [[irc:/irc.libera.chat/]]
 ;;
 ;; If, when the resulting link is visited, there is no connection to a
 ;; requested server then one will be created.
diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el
index 1f4e2e8..b68e5b5 100644
--- a/lisp/org/org-compat.el
+++ b/lisp/org/org-compat.el
@@ -1151,8 +1151,8 @@ key."
     ((guard (not (lookup-key calendar-mode-map "c")))
      (local-set-key "c" #'org-calendar-goto-agenda))
     (_ nil))
-  (unless (and (boundp 'org-agenda-diary-file)
-              (eq org-agenda-diary-file 'diary-file))
+  (when (and (boundp 'org-agenda-diary-file)
+            (not (eq org-agenda-diary-file 'diary-file)))
     (local-set-key org-calendar-insert-diary-entry-key
                   #'org-agenda-diary-entry)))
 
diff --git a/lisp/printing.el b/lisp/printing.el
index 5c7da96..e7aab90 100644
--- a/lisp/printing.el
+++ b/lisp/printing.el
@@ -1081,24 +1081,15 @@ Used by `pr-menu-bind' and `pr-update-menus'.")
   "Specify Printing menu-bar entry.")
 
 (defun pr-global-menubar (menu-spec)
-  (let ((menu-file '("menu-bar" "file")))
-    (cond
-     (pr-menu-print-item
-      (easy-menu-add-item global-map menu-file
-                          (easy-menu-create-menu "Print" menu-spec)
-                          "print-buffer")
-      (dolist (item '("print-buffer"          "print-region"
-                      "ps-print-buffer-faces" "ps-print-region-faces"
-                      "ps-print-buffer"       "ps-print-region"))
-        (easy-menu-remove-item global-map menu-file item))
-      (setq pr-menu-print-item nil
-            pr-menu-bar (vector 'menu-bar
-                                (easy-menu-intern (nth 1 menu-file))
-                                (easy-menu-intern "Print"))))
-     (t
-      (easy-menu-add-item global-map menu-file
-                          (easy-menu-create-menu "Print" menu-spec)))
-     )))
+  (let ((menu-file '("menu-bar" "file"))
+        (submenu-path [menu-bar file Print])
+        (submenu (easy-menu-create-menu "Print" menu-spec)))
+    (cond (pr-menu-print-item
+           (easy-menu-add-item global-map menu-file submenu "Print")
+           (easy-menu-remove-item global-map menu-file "print")
+           (setq pr-menu-print-item nil
+                 pr-menu-bar submenu-path))
+          (t (easy-menu-add-item global-map menu-file submenu)))))
 
 (defun pr-menu-position (entry index horizontal)
   (let ((pos (cdr (mouse-pixel-position))))
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index f1ec522..e502cbb 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -362,7 +362,7 @@ From, and Cc against HEADER-REGEXP in
 (defvar bug-reference-setup-from-irc-alist
   `((,(concat "#" (regexp-opt '("emacs" "gnus" "org-mode" "rcirc"
                                 "erc") 'words))
-     "freenode"
+     "Libera.Chat"
      "\\([Bb]ug ?#?\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)"
      "https://debbugs.gnu.org/%s";))
   "An alist for setting up `bug-reference-mode' in IRC modes.
@@ -377,8 +377,8 @@ Each element has the form
 
 CHANNEL-REGEXP is a regexp matched against the current IRC
 channel name (e.g. #emacs).  NETWORK-REGEXP is matched against
-the IRC network name (e.g. freenode).  Both entries are optional.
-If all given entries match, BUG-REGEXP is set as
+the IRC network name (e.g. Libera.Chat).  Both entries are
+optional.  If all given entries match, BUG-REGEXP is set as
 `bug-reference-bug-regexp' and URL-FORMAT is set as
 `bug-reference-url-format'.")
 
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 622d951..984a75c 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6942,8 +6942,10 @@ comment at the start of cc-engine.el for more info."
        (c-go-list-forward))
       (when (equal (c-get-char-property (1- (point)) 'syntax-table)
                   c->-as-paren-syntax) ; should always be true.
-       (c-unmark-<->-as-paren (1- (point))))
-      (c-unmark-<->-as-paren pos))))
+       (c-unmark-<->-as-paren (1- (point)))
+       (c-truncate-lit-pos-cache (1- (point))))
+      (c-unmark-<->-as-paren pos)
+      (c-truncate-lit-pos-cache pos))))
 
 (defun c-clear->-pair-props (&optional pos)
   ;; POS (default point) is at a > character.  If it is marked with
@@ -6959,8 +6961,10 @@ comment at the start of cc-engine.el for more info."
        (c-go-up-list-backward))
       (when (equal (c-get-char-property (point) 'syntax-table)
                        c-<-as-paren-syntax) ; should always be true.
-       (c-unmark-<->-as-paren (point)))
-      (c-unmark-<->-as-paren pos))))
+       (c-unmark-<->-as-paren (point))
+       (c-truncate-lit-pos-cache (point)))
+      (c-unmark-<->-as-paren pos)
+      (c-truncate-lit-pos-cache pos))))
 
 (defun c-clear-<>-pair-props (&optional pos)
   ;; POS (default point) is at a < or > character.  If it has an
@@ -6993,7 +6997,8 @@ comment at the start of cc-engine.el for more info."
                 (equal (c-get-char-property (1- (point)) 'syntax-table)
                        c->-as-paren-syntax)) ; should always be true.
        (c-unmark-<->-as-paren (1- (point)))
-       (c-unmark-<->-as-paren pos))
+       (c-unmark-<->-as-paren pos)
+       (c-truncate-lit-pos-cache pos))
       t)))
 
 (defun c-clear->-pair-props-if-match-before (lim &optional pos)
@@ -7014,6 +7019,7 @@ comment at the start of cc-engine.el for more info."
                 (equal (c-get-char-property (point) 'syntax-table)
                        c-<-as-paren-syntax)) ; should always be true.
        (c-unmark-<->-as-paren (point))
+       (c-truncate-lit-pos-cache (point))
        (c-unmark-<->-as-paren pos))
       t)))
 
@@ -8057,13 +8063,14 @@ comment at the start of cc-engine.el for more info."
        ;; bracket arglist.  It's propagated through the return value
        ;; on successful completion.
        (c-record-found-types c-record-found-types)
+       (syntax-table-prop-on-< (c-get-char-property (point) 'syntax-table))
        ;; List that collects the positions after the argument
        ;; separating ',' in the arglist.
        arg-start-pos)
     ;; If the '<' has paren open syntax then we've marked it as an angle
     ;; bracket arglist before, so skip to the end.
     (if (and (not c-parse-and-markup-<>-arglists)
-            (c-get-char-property (point) 'syntax-table))
+            syntax-table-prop-on-<)
 
        (progn
          (forward-char)
@@ -8148,8 +8155,20 @@ comment at the start of cc-engine.el for more info."
                        (c-put-c-type-property (1- (car arg-start-pos))
                                               'c-<>-arg-sep)
                        (setq arg-start-pos (cdr arg-start-pos)))
+                     (when (and (not syntax-table-prop-on-<)
+                                (c-get-char-property (1- (point))
+                                                     'syntax-table))
+                       ;; Clear the now spuriously matching < of its
+                       ;; syntax-table property.  This could happen on
+                       ;; inserting "_cast" into "static <" with C-y.
+                       (save-excursion
+                         (and (c-go-list-backward)
+                              (eq (char-after) ?<)
+                              (c-truncate-lit-pos-cache (point))
+                              (c-unmark-<->-as-paren (point)))))
                      (c-mark-<-as-paren start)
-                     (c-mark->-as-paren (1- (point))))
+                     (c-mark->-as-paren (1- (point)))
+                     (c-truncate-lit-pos-cache start))
                    (setq res t)
                    nil))               ; Exit the loop.
 
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index f664849..35efadf 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -2743,7 +2743,8 @@ if this isn't nil."
 `c-recognize-<>-arglists' for details.  That language constant is
 assumed to be set if this isn't nil."
   t    nil
-  c++  '("template")
+  c++  '("template" "const_cast" "dynamic_cast" "reinterpret_cast"
+        "static_cast")
   idl  '("fixed" "string" "wstring"))
 
 (c-lang-defconst c-<>-sexp-kwds
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el
index edcd88c..0f7c8c6 100644
--- a/lisp/progmodes/cmacexp.el
+++ b/lisp/progmodes/cmacexp.el
@@ -141,7 +141,7 @@ Normally display output in temp buffer, but
 prefix arg means replace the region with it.
 
 `c-macro-preprocessor' specifies the preprocessor to use.
-Tf the user option `c-macro-prompt-flag' is non-nil
+If the user option `c-macro-prompt-flag' is non-nil
 prompt for arguments to the preprocessor \(e.g. `-DDEBUG -I ./include'),
 otherwise use `c-macro-cppflags'.
 
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index fa384bc..3370df6 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -3981,7 +3981,7 @@ the sections using `cperl-pod-head-face', 
`cperl-pod-face',
                                              (not (memq (preceding-char)
                                                         '(?$ ?@ ?& ?%)))
                                              (looking-at
-                                              
"\\(while\\|if\\|unless\\|until\\|and\\|or\\|not\\|xor\\|split\\|grep\\|map\\|print\\|say\\|return\\)\\>"))))
+                                              
"\\(while\\|if\\|unless\\|until\\|for\\(each\\)?\\|and\\|or\\|not\\|xor\\|split\\|grep\\|map\\|print\\|say\\|return\\)\\>"))))
                                    (and (eq (preceding-char) ?.)
                                         (eq (char-after (- (point) 2)) ?.))
                                    (bobp))
diff --git a/lisp/ps-print.el b/lisp/ps-print.el
index fcc6e1f..1b8654e 100644
--- a/lisp/ps-print.el
+++ b/lisp/ps-print.el
@@ -6506,10 +6506,11 @@ If FACE is not a valid face name, use default face."
     (and (buffer-live-p ps-buffer)
         (buffer-modified-p ps-buffer)
         (not (yes-or-no-p "Unprinted PostScript waiting; exit anyway? "))
-        (error "Unprinted PostScript"))))
+        (error "Unprinted PostScript")))
+  t)
 
 (unless noninteractive
-  (add-hook 'kill-emacs-hook #'ps-kill-emacs-check))
+  (add-hook 'kill-emacs-query-functions #'ps-kill-emacs-check))
 
 (provide 'ps-print)
 
diff --git a/lisp/repeat.el b/lisp/repeat.el
index 46c880d..503cb34 100644
--- a/lisp/repeat.el
+++ b/lisp/repeat.el
@@ -397,7 +397,7 @@ When Repeat mode is enabled, and the command symbol has the 
property named
                                    (and (commandp s)
                                         (get s 'repeat-map)
                                         (push (get s 'repeat-map) keymaps))))))
-      (message "Repeat mode is enabled for %d commands and %d keymaps"
+      (message "Repeat mode is enabled for %d commands and %d keymaps; see 
`describe-repeat'."
                (length commands)
                (length (delete-dups keymaps))))))
 
@@ -489,6 +489,28 @@ When Repeat mode is enabled, and the command symbol has 
the property named
                                             repeat-echo-mode-line-string)))
     (force-mode-line-update t)))
 
+(defun describe-repeat ()
+  "Describe repeatable commands and keymaps."
+  (interactive)
+  (help-setup-xref (list #'describe-repeat)
+                   (called-interactively-p 'interactive))
+  (let ((keymaps nil))
+    (all-completions
+     "" obarray (lambda (s)
+                  (and (commandp s)
+                       (get s 'repeat-map)
+                       (push s (alist-get (get s 'repeat-map) keymaps)))))
+    (with-help-window (help-buffer)
+      (with-current-buffer standard-output
+        (princ "This is a list of repeatable keymaps and commands.\n\n")
+
+        (dolist (keymap (sort keymaps (lambda (a b) (string-lessp (car a) (car 
b)))))
+          (princ (format-message "`%s' keymap is repeatable by these 
commands:\n"
+                                 (car keymap)))
+          (dolist (command (sort (cdr keymap) 'string-lessp))
+            (princ (format-message " `%s'\n" command)))
+          (princ "\n"))))))
+
 (provide 'repeat)
 
 ;;; repeat.el ends here
diff --git a/lisp/server.el b/lisp/server.el
index 5cb5452..8a9796b 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1313,7 +1313,17 @@ The following commands are accepted by the client:
                                                       frame-parameters))
                   ;; When resuming on a tty, tty-name is nil.
                   (tty-name
-                   (server-create-tty-frame tty-name tty-type proc))))
+                   (server-create-tty-frame tty-name tty-type proc))
+
+                   ;; If there won't be a current frame to use, fall
+                   ;; back to trying to create a new one.
+                  ((and use-current-frame
+                        (daemonp)
+                        (null (cdr (frame-list)))
+                        (eq (selected-frame) terminal-frame)
+                        display)
+                   (setq tty-name nil tty-type nil)
+                   (server-select-display display))))
 
             (process-put
              proc 'continuation
diff --git a/lisp/shell.el b/lisp/shell.el
index 62de5be..4339e8c 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -759,7 +759,8 @@ Make the shell buffer the current buffer, and return it.
                  (file-local-name
                   (expand-file-name
                    (read-file-name "Remote shell path: " default-directory
-                                   shell-file-name t shell-file-name)))))
+                                   shell-file-name t shell-file-name
+                                   #'file-remote-p)))))
 
    ;; Rain or shine, BUFFER must be current by now.
    (unless (comint-check-proc buffer)
diff --git a/lisp/simple.el b/lisp/simple.el
index a2dc633..cceb171 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5060,6 +5060,16 @@ The comparison is done using 
`equal-including-properties'."
   :group 'killing
   :version "23.2")
 
+(defcustom kill-transform-function nil
+  "Function to call to transform a string before it's put on the kill ring.
+The function is called with one parameter (the string that's to
+be put on the kill ring).  It should return a string or nil.  If
+the latter, the string is not put on the kill ring."
+  :type '(choice (const :tag "No transform" nil)
+                 function)
+  :group 'killing
+  :version "28.1")
+
 (defun kill-new (string &optional replace)
   "Make STRING the latest kill in the kill ring.
 Set `kill-ring-yank-pointer' to point to it.
@@ -5075,38 +5085,41 @@ When the yank handler has a non-nil PARAM element, the 
original STRING
 argument is not used by `insert-for-yank'.  However, since Lisp code
 may access and use elements from the kill ring directly, the STRING
 argument should still be a \"useful\" string for such uses."
-  (unless (and kill-do-not-save-duplicates
-              ;; Due to text properties such as 'yank-handler that
-              ;; can alter the contents to yank, comparison using
-              ;; `equal' is unsafe.
-              (equal-including-properties string (car kill-ring)))
-    (if (fboundp 'menu-bar-update-yank-menu)
-       (menu-bar-update-yank-menu string (and replace (car kill-ring)))))
-  (when save-interprogram-paste-before-kill
-    (let ((interprogram-paste (and interprogram-paste-function
-                                   (funcall interprogram-paste-function))))
-      (when interprogram-paste
-        (setq interprogram-paste
-              (if (listp interprogram-paste)
-                  ;; Use `reverse' to avoid modifying external data.
-                  (reverse interprogram-paste)
-               (list interprogram-paste)))
-        (when (or (not (numberp save-interprogram-paste-before-kill))
-                  (< (seq-reduce #'+ (mapcar #'length interprogram-paste) 0)
-                     save-interprogram-paste-before-kill))
-          (dolist (s interprogram-paste)
-           (unless (and kill-do-not-save-duplicates
-                         (equal-including-properties s (car kill-ring)))
-             (push s kill-ring)))))))
-  (unless (and kill-do-not-save-duplicates
-              (equal-including-properties string (car kill-ring)))
-    (if (and replace kill-ring)
-       (setcar kill-ring string)
-      (let ((history-delete-duplicates nil))
-        (add-to-history 'kill-ring string kill-ring-max t))))
-  (setq kill-ring-yank-pointer kill-ring)
-  (if interprogram-cut-function
-      (funcall interprogram-cut-function string)))
+  ;; Allow the user to transform or ignore the string.
+  (when (or (not kill-transform-function)
+            (setq string (funcall kill-transform-function string)))
+    (unless (and kill-do-not-save-duplicates
+                ;; Due to text properties such as 'yank-handler that
+                ;; can alter the contents to yank, comparison using
+                ;; `equal' is unsafe.
+                (equal-including-properties string (car kill-ring)))
+      (if (fboundp 'menu-bar-update-yank-menu)
+         (menu-bar-update-yank-menu string (and replace (car kill-ring)))))
+    (when save-interprogram-paste-before-kill
+      (let ((interprogram-paste (and interprogram-paste-function
+                                     (funcall interprogram-paste-function))))
+        (when interprogram-paste
+          (setq interprogram-paste
+                (if (listp interprogram-paste)
+                    ;; Use `reverse' to avoid modifying external data.
+                    (reverse interprogram-paste)
+                 (list interprogram-paste)))
+          (when (or (not (numberp save-interprogram-paste-before-kill))
+                    (< (seq-reduce #'+ (mapcar #'length interprogram-paste) 0)
+                       save-interprogram-paste-before-kill))
+            (dolist (s interprogram-paste)
+             (unless (and kill-do-not-save-duplicates
+                           (equal-including-properties s (car kill-ring)))
+               (push s kill-ring)))))))
+    (unless (and kill-do-not-save-duplicates
+                (equal-including-properties string (car kill-ring)))
+      (if (and replace kill-ring)
+         (setcar kill-ring string)
+        (let ((history-delete-duplicates nil))
+          (add-to-history 'kill-ring string kill-ring-max t))))
+    (setq kill-ring-yank-pointer kill-ring)
+    (if interprogram-cut-function
+        (funcall interprogram-cut-function string))))
 
 ;; It has been argued that this should work like `self-insert-command'
 ;; which merges insertions in `buffer-undo-list' in groups of 20
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index f3c2fb7..41d565a 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -138,15 +138,12 @@ Possible modifier keys are `control', `meta', `shift', 
`hyper', `super' and
   (when (and (memq 'tab-bar-format-global tab-bar-format)
              (member '(global-mode-string ("" global-mode-string " "))
                      mode-line-misc-info))
-    (setq mode-line-misc-info
-          (append '(global-mode-string
-                    ("" (:eval (if (and tab-bar-mode
-                                        (memq 'tab-bar-format-global
-                                              tab-bar-format))
-                                   "" global-mode-string))
-                     " "))
-                  (remove '(global-mode-string ("" global-mode-string " "))
-                          mode-line-misc-info)))))
+    (setf (alist-get 'global-mode-string mode-line-misc-info)
+          '(("" (:eval (if (and tab-bar-mode
+                                (memq 'tab-bar-format-global
+                                      tab-bar-format))
+                           "" global-mode-string))
+             " ")))))
 
 (defun tab-bar--undefine-keys ()
   "Uninstall key bindings previously bound by `tab-bar--define-keys'."
diff --git a/lisp/textmodes/flyspell.el b/lisp/textmodes/flyspell.el
index ba48e5d..836d889 100644
--- a/lisp/textmodes/flyspell.el
+++ b/lisp/textmodes/flyspell.el
@@ -401,18 +401,12 @@ like <img alt=\"Some thing.\">."
     (let ((f (get-text-property (1- (point)) 'face)))
       (memq f flyspell-prog-text-faces))))
 
-(defvar flyspell--prev-meta-tab-binding nil
-  "Records the binding of M-TAB in effect before flyspell was activated.")
-
 ;;;###autoload
 (defun flyspell-prog-mode ()
   "Turn on `flyspell-mode' for comments and strings."
   (interactive)
   (setq flyspell-generic-check-word-predicate
         #'flyspell-generic-progmode-verify)
-  (setq-local flyspell--prev-meta-tab-binding
-              (or (local-key-binding "\M-\t" t)
-                  (global-key-binding "\M-\t" t)))
   (flyspell-mode 1)
   (run-hooks 'flyspell-prog-mode-hook))
 
@@ -1990,15 +1984,14 @@ spell-check."
   (interactive)
   ;; If we are not in the construct where flyspell should be active,
   ;; invoke the original binding of M-TAB, if that was recorded.
-  (if (and (local-variable-p 'flyspell--prev-meta-tab-binding)
-           (commandp flyspell--prev-meta-tab-binding t)
-           (functionp flyspell-generic-check-word-predicate)
-           (not (funcall flyspell-generic-check-word-predicate))
-           (equal (where-is-internal 'flyspell-auto-correct-word nil t)
-                  [?\M-\t]))
-      (call-interactively flyspell--prev-meta-tab-binding)
-    (let ((pos     (point))
-          (old-max (point-max)))
+  (let ((pos     (point))
+        (old-max (point-max))
+        (next-cmd (and (functionp flyspell-generic-check-word-predicate)
+                       (not (funcall flyspell-generic-check-word-predicate))
+                       (let ((flyspell-mode nil))
+                         (key-binding (this-command-keys))))))
+    (if next-cmd
+        (command-execute next-cmd)
       ;; Flush a possibly stale cache from previous invocations of
       ;; flyspell-auto-correct-word/flyspell-auto-correct-previous-word.
       (if (not (memq last-command '(flyspell-auto-correct-word
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 4dbc764..0a82bf5 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -1076,7 +1076,7 @@ dictionary from that list was found."
           (split-string
            (with-temp-buffer
              (ispell-call-process ispell-program-name
-                            null-device
+                            nil
                             t
                             nil
                             "-D"
@@ -1211,18 +1211,7 @@ If LANG is omitted, get the extra word characters for 
the default language."
                     `(,lang "[[:alpha:]]" "[^[:alpha:]]"
                             ,(ispell--get-extra-word-characters lang) t nil 
nil utf-8))
                   dictionaries)))
-    ;; Merge into FOUND any elements from the standard 
ispell-dictionary-base-alist
-    ;; which have no element in FOUND at all.
-    (dolist (dict ispell-dictionary-base-alist)
-      (unless (assoc (car dict) found)
-       (setq found (nconc found (list dict)))))
-    (setq ispell-enchant-dictionary-alist found)
-    ;; Add a default entry
-    (let ((default-dict
-            `(nil "[[:alpha:]]" "[^[:alpha:]]"
-                  ,(ispell--get-extra-word-characters)
-                  t nil nil utf-8)))
-      (push default-dict ispell-enchant-dictionary-alist))))
+    (setq ispell-enchant-dictionary-alist found)))
 
 ;; Set params according to the selected spellchecker
 
@@ -1765,10 +1754,12 @@ You can set this variable in hooks in your init file -- 
eg:
 If asynchronous subprocesses are not supported, call function `ispell-filter'
 and pass it the output of the last Ispell invocation."
   (if ispell-async-processp
-      (let ((timeout (if timeout-msecs
-                        (+ (or timeout-secs 0) (/ timeout-msecs 1000.0))
-                      timeout-secs)))
-       (accept-process-output ispell-process timeout))
+      (if (process-live-p ispell-process)
+       (let ((timeout (if timeout-msecs
+                         (+ (or timeout-secs 0) (/ timeout-msecs 1000.0))
+                       timeout-secs)))
+        (accept-process-output ispell-process timeout))
+       (error "No Ispell process to read output from!"))
     (if (null ispell-process)
        (error "No Ispell process to read output from!")
       (let ((buf ispell-output-buffer)
@@ -1793,7 +1784,8 @@ Only works for Aspell and Enchant."
 (defun ispell-send-string (string)
   "Send the string STRING to the Ispell process."
   (if ispell-async-processp
-      (process-send-string ispell-process string)
+      (if (process-live-p ispell-process)
+       (process-send-string ispell-process string))
     ;; Asynchronous subprocesses aren't supported on this losing system.
     ;; We keep all the directives passed to Ispell during the entire
     ;; session in a buffer, and pass them anew each time we invoke
diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el
index a805c89..8b8108c 100644
--- a/lisp/textmodes/tex-mode.el
+++ b/lisp/textmodes/tex-mode.el
@@ -2132,6 +2132,7 @@ If NOT-ALL is non-nil, save the `.dvi' file."
 (defvar tex-compile-commands
   `(,@(mapcar (lambda (prefix)
                 `((concat ,prefix tex-command
+                          " " tex-start-options
                           " " (if (< 0 (length tex-start-commands))
                                   (shell-quote-argument tex-start-commands))
                           " %f")
diff --git a/lisp/textmodes/text-mode.el b/lisp/textmodes/text-mode.el
index ffeb9e6..74c6d41 100644
--- a/lisp/textmodes/text-mode.el
+++ b/lisp/textmodes/text-mode.el
@@ -49,7 +49,7 @@
     (modify-syntax-entry ?' "w p" st)
     ;; UAX #29 says HEBREW PUNCTUATION GERESH behaves like a letter
     ;; for the purposes of finding word boundaries.
-    (modify-syntax-entry #x5f3 "w   ") ; GERESH
+    (modify-syntax-entry #x5f3 "w   " st) ; GERESH
     ;; UAX #29 says HEBREW PUNCTUATION GERSHAYIM should not be a word
     ;; boundary when surrounded by letters.  Our infrastructure for
     ;; finding a word boundary doesn't support 3-character
@@ -57,13 +57,13 @@
     ;; character.  This leaves a problem of having GERSHAYIM at the
     ;; beginning or end of a word, where it should be a boundary;
     ;; FIXME.
-    (modify-syntax-entry #x5f4 "w   ") ; GERSHAYIM
+    (modify-syntax-entry #x5f4 "w   " st) ; GERSHAYIM
     ;; These all should not be a word boundary when between letters,
     ;; according to UAX #29, so they again are prone to the same
     ;; problem as GERSHAYIM; FIXME.
-    (modify-syntax-entry #xb7 "w   ")  ; MIDDLE DOT
-    (modify-syntax-entry #x2027 "w   ")        ; HYPHENATION POINT
-    (modify-syntax-entry #xff1a "w   ")        ; FULLWIDTH COLON
+    (modify-syntax-entry #xb7 "w   " st)   ; MIDDLE DOT
+    (modify-syntax-entry #x2027 "w   " st) ; HYPHENATION POINT
+    (modify-syntax-entry #xff1a "w   " st) ; FULLWIDTH COLON
     st)
   "Syntax table used while in `text-mode'.")
 
diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el
index 0cc566f..ae91171 100644
--- a/lisp/time-stamp.el
+++ b/lisp/time-stamp.el
@@ -25,7 +25,7 @@
 
 ;; A template in a file can be updated with a new time stamp when
 ;; you save the file.  For example:
-;;     static char *ts = "sdmain.c Time-stamp: <2001-08-13 10:20:51 gildea>";
+;;     static char *ts = "sdmain.c Time-stamp: <2020-04-18 14:10:21 gildea>";
 
 ;; To use time-stamping, add this line to your init file:
 ;;     (add-hook 'before-save-hook 'time-stamp)
@@ -278,7 +278,7 @@ look like one of the following:
       Time-stamp: <>
       Time-stamp: \" \"
 The time stamp is written between the brackets or quotes:
-      Time-stamp: <2001-02-18 10:20:51 gildea>
+      Time-stamp: <2020-08-07 17:10:21 gildea>
 
 The time stamp is updated only if the variable
 `time-stamp-active' is non-nil.
@@ -422,7 +422,7 @@ Returns the end point, which is where `time-stamp' begins 
the next search."
 ;;;###autoload
 (defun time-stamp-toggle-active (&optional arg)
   "Toggle `time-stamp-active', setting whether \\[time-stamp] updates a buffer.
-With ARG, turn time stamping on if and only if arg is positive."
+With ARG, turn time stamping on if and only if ARG is positive."
   (interactive "P")
   (setq time-stamp-active
        (if (null arg)
@@ -457,7 +457,7 @@ normally the current time is used."
 (defun time-stamp-string-preprocess (format &optional time)
   "Use a FORMAT to format date, time, file, and user information.
 Optional second argument TIME is only for testing.
-Implements non-time extensions to `format-time-string'
+Implements extensions to `format-time-string'
 and all `time-stamp-format' compatibility."
   (let ((fmt-len (length format))
        (ind 0)
@@ -477,6 +477,9 @@ and all `time-stamp-format' compatibility."
                (alt-form 0)
                (change-case nil)
                (upcase nil)
+               (flag-pad-with-spaces nil)
+               (flag-pad-with-zeros nil)
+               (flag-minimize nil)
                (paren-level 0))
            ;; eat any additional args to allow for future expansion
            (while (progn
@@ -521,10 +524,12 @@ and all `time-stamp-format' compatibility."
                     (setq change-case t))
                    ((eq cur-char ?^)
                     (setq upcase t))
+                   ((eq cur-char ?0)
+                    (setq flag-pad-with-zeros t))
                    ((eq cur-char ?-)
-                    (setq field-width "1"))
+                    (setq field-width "1" flag-minimize t))
                    ((eq cur-char ?_)
-                    (setq field-width "2"))))
+                    (setq field-width "2" flag-pad-with-spaces t))))
            (setq field-result
                  (cond
                   ((eq cur-char ?%)
@@ -586,26 +591,37 @@ and all `time-stamp-format' compatibility."
                   ((eq cur-char ?Y)    ;4-digit year
                    (string-to-number (time-stamp--format "%Y" time)))
                   ((eq cur-char ?z)    ;time zone offset
-                   (if change-case
-                       ""              ;discourage %z variations
-                      (cond ((= alt-form 0)
-                             (if (string-equal field-width "")
-                                 (progn
-                                   (time-stamp-conv-warn "%z" "%#Z")
-                                   (time-stamp--format "%#Z" time))
-                               (cond ((string-equal field-width "1")
-                                      (setq field-width "3")) ;%-z -> "+00"
-                                     ((string-equal field-width "2")
-                                      (setq field-width "5")) ;%_z -> "+0000"
-                                     ((string-equal field-width "4")
-                                      (setq field-width "0"))) ;discourage %4z
-                               (time-stamp--format "%z" time)))
-                            ((= alt-form 1)
-                             (time-stamp--format "%:z" time))
-                            ((= alt-form 2)
-                             (time-stamp--format "%::z" time))
-                            ((= alt-form 3)
-                             (time-stamp--format "%:::z" time)))))
+                    (let ((field-width-num (string-to-number field-width))
+                          ;; Handle numeric time zone ourselves, because
+                          ;; current-time-zone cannot handle offsets
+                          ;; greater than 24 hours.
+                          (offset-secs
+                           (cond ((numberp time-stamp-time-zone)
+                                  time-stamp-time-zone)
+                                 ((and (consp time-stamp-time-zone)
+                                       (numberp (car time-stamp-time-zone)))
+                                  (car time-stamp-time-zone))
+                                 ;; interpret text time zone
+                                 (t (car (current-time-zone
+                                          time time-stamp-time-zone))))))
+                     ;; we do our own padding; do not let it be updated further
+                     (setq field-width "")
+                     (cond (change-case
+                            "")        ;discourage %z variations
+                           ((and (= alt-form 0)
+                                 (not flag-minimize)
+                                 (not flag-pad-with-spaces)
+                                 (not flag-pad-with-zeros)
+                                 (= field-width-num 0))
+                            (time-stamp-conv-warn "%z" "%#Z")
+                            (time-stamp--format "%#Z" time))
+                           (t (time-stamp-formatz-from-parsed-options
+                               flag-minimize
+                               flag-pad-with-spaces
+                               flag-pad-with-zeros
+                               alt-form
+                               field-width-num
+                               offset-secs)))))
                   ((eq cur-char ?Z)    ;time zone name
                    (if change-case
                        (time-stamp--format "%#Z" time)
@@ -653,7 +669,8 @@ and all `time-stamp-format' compatibility."
                                       (string-to-number field-width))))
                (if (> initial-length desired-length)
                    ;; truncate strings on right
-                   (if (stringp field-result)
+                   (if (and (stringp field-result)
+                            (not (eq cur-char ?z))) ;offset does not truncate
                        (substring padded-result 0 desired-length)
                       padded-result)   ;numbers don't truncate
                  padded-result)))))
@@ -698,6 +715,176 @@ Suggests replacing OLD-FORM with NEW-FORM."
       (insert "\"" old-form "\" -- use " new-form "\n"))
     (display-buffer "*Time-stamp-compatibility*"))))
 
+;;; A principled, expressive implementation of time zone offset
+;;; formatting ("%z" and variants).
+
+;;; * Overarching principle for %z
+
+;; The output should be clear and complete.
+;;
+;; That is,
+;; a) it should be unambiguous what offset is represented, and
+;; b) it should be possible to exactly recreate the offset.
+
+;;; * Principles for %z
+
+;; - The numeric fields are HHMMSS.
+;; - The fixed point is at the left.  The first 2 digits are always
+;;   hours, the next 2 (if they exist) minutes, and next 2 (if they
+;;   exist) seconds.  "+11" is 11 hours (not 11 minutes, not 11 seconds).
+;;   "+1015" is 10 hours 15 minutes (not 10 minutes 15 seconds).
+;; - Each of the three numeric fields is two digits.
+;;   "+1" and "+100" are illegal.  (Is that 1 hour? 10 hours? 100 hours?)
+;; - The MMSS fields may be omitted only if both are 00.  Thus, the width
+;;   of the field depends on the data.  (This is similar to how
+;;   %B is always long enough to spell the entire month name.)
+;; - The SS field may be omitted only if it is 00.
+;; - Colons between the numeric fields are an option, unless the hours
+;;   field is greater than 99, when colons are needed to prevent ambiguity.
+;; - If padding with zeros, we must pad on the right, because the
+;;   fixed point is at the left.  (This is similar to how %N,
+;;   fractional seconds, must add its zeros on the right.)
+;; - After zero-padding has filled out minutes and seconds with zeros,
+;;   further padding can be blanks only.
+;;   Any additional zeros would be confusing.
+
+;;; * Padding for %z
+
+;; Padding is under-specified, so we had to make choices.
+;;
+;; Principles guiding our choices:
+;;
+;; - The syntax should be easy to remember and the effect predictable.
+;; - It should be possible to produces as many useful effects as possible.
+;;
+;; Padding choices:
+;;
+;; - By default, pad with spaces, as other formats with non-digits do.
+;;   The "0" flag pads first with zeros, until seconds are filled out.
+;; - If padding with spaces, pad on the right.  This is consistent with
+;;   how zero-padding works.  Padding on the right also keeps the fixed
+;;   point in the same place, as other formats do for any given width.
+;; - The %_z format always outputs seconds, allowing all added padding
+;;   to be spaces.  Without this rule, there would be no way to
+;;   request seconds that worked for both 2- and 3-digit hours.
+;; - Conflicting options are rejected, lest users depend
+;;   on incidental behavior.
+;;
+;; Padding combos that make no sense and are thus disallowed:
+;;
+;; %-:z   - minus minimizes to hours, : expands to minutes
+;; %-::z  - minus minimizes to hours, :: expands to seconds
+;; %_:z   - underscore requires seconds, : displays minutes
+;; %_:::z - underscore requires seconds, ::: minimizes to hours
+;;
+;; Example padding effects (with offsets of 99 and 100 hours):
+;;
+;; %-7z   "+99    "   "+100:00"
+;;  %7z   "+9900  "   "+100:00"
+;; %07z   "+990000"   "+100:00"
+;; %_7z   "+990000"   "+100:00:00"
+;;
+;; %7:::z "+99    "   "+100:00"
+;; %7:z   "+99:00 "   "+100:00"
+;; %07:z  "+99:00:00" "+100:00"
+;; %7::z  "+99:00:00" "+100:00:00"
+
+;;; * BNF syntax of the offset string produced by %z
+
+;; <offset> ::= <sign><hours>[<minutes>[<seconds>]]<padding> |
+;;              <sign><hours>[<colonminutes>[<colonseconds>]]<padding> |
+;;              <sign><bighours><colonminutes>[<colonseconds>]<padding>
+;; <sign> ::= "+"|"-"
+;; <hours> ::= <2digits>
+;; <minutes> ::= <2digits>
+;; <seconds> ::= <2digits>
+;; <colonminutes> ::= ":"<minutes>
+;; <colonseconds> ::= ":"<seconds>
+;; <2digits> ::= <digit><digit>
+;; <digit> ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
+;; <bighours> ::= <digit>*<digit><2digits>
+;; <padding> ::= " "*
+
+(defun time-stamp-formatz-from-parsed-options (flag-minimize
+                                               flag-pad-spaces-only
+                                               flag-pad-zeros-first
+                                               colon-count
+                                               field-width
+                                               offset-secs)
+  "Formats a time offset according to a %z variation.
+The caller of this function must have already parsed the %z format
+string; this function accepts just the parts of the format.
+
+With no flags, the output includes hours and minutes: +-HHMM
+unless there is a non-zero seconds part, in which case the seconds
+are included: +-HHMMSS
+
+FLAG-MINIMIZE is whether \"-\" was specified.  If non-nil, the
+output may be limited to hours if minutes and seconds are zero.
+
+FLAG-PAD-SPACES-ONLY is whether \"_\" was specified.  If non-nil,
+seconds must be output, so that any padding can be spaces only.
+
+FLAG-PAD-ZEROS-FIRST is whether \"0\" was specified.  If non-nil,
+padding to the requested FIELD-WIDTH (if any) is done by adding
+00 seconds before padding with spaces.
+
+COLON-COUNT is the number of colons preceding the \"z\" (0-3).  One or
+two colons put that many colons in the output (+-HH:MM or +-HH:MM:SS).
+Three colons outputs only hours if minutes and seconds are zero and
+includes colon separators if minutes and seconds are output.
+
+FIELD-WIDTH is a whole number giving the minimum number of characters
+in the output; 0 specifies no minimum.  Additional characters will be
+added on the right if necessary.  The added characters will be spaces
+unless FLAG-PAD-ZEROS-FIRST is non-nil.
+
+OFFSET-SECS is the time zone offset (in seconds east of UTC) to be
+formatted according to the preceding parameters."
+  (let ((hrs (/ (abs offset-secs) 3600))
+        (mins (/ (% (abs offset-secs) 3600) 60))
+        (secs (% (abs offset-secs) 60))
+        (result ""))
+    ;; valid option combo?
+    (cond
+     ((not (or (and flag-minimize (> colon-count 0))
+               (and flag-pad-spaces-only (> colon-count 0))
+               (and flag-pad-spaces-only flag-minimize)
+               (and flag-pad-spaces-only flag-pad-zeros-first)
+               (and flag-pad-zeros-first flag-minimize)))
+      (setq result (concat result (if (>= offset-secs 0) "+" "-")))
+      (setq result (concat result (format "%02d" hrs)))
+      ;; Need minutes?
+      (cond
+       ((or (> hrs 99)
+            (> mins 0)
+            (> secs 0)
+            (not (or flag-minimize (= colon-count 3)))
+            (and (> field-width (length result))
+                 flag-pad-zeros-first))
+        ;; Need colon before minutes?
+        (if (or (> colon-count 0)
+                (> hrs 99))
+            (setq result (concat result ":")))
+        (setq result (concat result (format "%02d" mins)))
+        ;; Need seconds, too?
+        (cond
+         ((or (> secs 0)
+              (= colon-count 2)
+              flag-pad-spaces-only
+              (and (> field-width (length result))
+                   flag-pad-zeros-first))
+          ;; Need colon before seconds?
+          (if (or (> colon-count 0)
+                  (> hrs 99))
+              (setq result (concat result ":")))
+          (setq result (concat result (format "%02d" secs)))))))
+      ;; Need padding?
+      (let ((needed-padding (- field-width (length result))))
+        (if (> needed-padding 0)
+            (setq result (concat result (make-string needed-padding ?\s)))))))
+    result))
+
 (provide 'time-stamp)
 
 ;;; time-stamp.el ends here
diff --git a/lisp/transient.el b/lisp/transient.el
index 6153b50..5f66a13 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -7,7 +7,7 @@
 ;; Keywords: bindings
 
 ;; Package-Requires: ((emacs "25.1"))
-;; Package-Version: 0.3.4
+;; Package-Version: 0.3.6
 
 ;; SPDX-License-Identifier: GPL-3.0-or-later
 
@@ -161,7 +161,12 @@ function should accept two arguments: a buffer to display 
and
 an alist of the same form as ALIST.  See `display-buffer' for
 details.
 
-The default is (display-buffer-in-side-window (side . bottom)).
+The default is:
+
+  (display-buffer-in-side-window
+    (side . bottom)
+    (inhibit-same-window . t))
+
 This displays the window at the bottom of the selected frame.
 Another useful value is (display-buffer-below-selected).  This
 is what `magit-popup' used by default.  For more alternatives
@@ -234,6 +239,20 @@ and `transient-nonstandard-key'."
   :group 'transient
   :type 'boolean)
 
+(defcustom transient-highlight-higher-levels nil
+  "Whether to highlight suffixes on higher levels.
+
+This is primarily intended for package authors.
+
+When non-nil then highlight the description of suffixes whose
+level is above 4, the default of `transient-default-level'.
+Assuming you have set that variable to 7, this highlights all
+suffixes that won't be available to users without them making
+the same customization."
+  :package-version '(transient . "0.3.6")
+  :group 'transient
+  :type 'boolean)
+
 (defcustom transient-substitute-key-function nil
   "Function used to modify key bindings.
 
@@ -296,7 +315,20 @@ be remapped to `fixed-pitch' in that buffer."
   :group 'transient
   :type 'boolean)
 
-(defcustom transient-default-level 4
+(defcustom transient-force-single-column nil
+  "Whether to force use of a single column to display suffixes.
+
+This might be useful for users with low vision who use large
+text and might otherwise have to scroll in two dimensions."
+  :package-version '(transient . "0.3.6")
+  :group 'transient
+  :type 'boolean)
+
+(defconst transient--default-child-level 1)
+
+(defconst transient--default-prefix-level 4)
+
+(defcustom transient-default-level transient--default-prefix-level
   "Control what suffix levels are made available by default.
 
 Each suffix command is placed on a level and each prefix command
@@ -430,6 +462,11 @@ See info node `(transient)Enabling and Disabling 
Suffixes'."
 See info node `(transient)Enabling and Disabling Suffixes'."
   :group 'transient-faces)
 
+(defface transient-higher-level '((t :underline t))
+  "Face optionally used to highlight suffixes on higher levels.
+Also see option `transient-highlight-higher-levels'."
+  :group 'transient-faces)
+
 (defface transient-separator
   `((((class color) (background light))
      ,@(and (>= emacs-major-version 27) '(:extend t))
@@ -569,7 +606,7 @@ the prototype is stored in the clone's `prototype' slot.")
 (defclass transient-child ()
   ((level
     :initarg :level
-    :initform 1
+    :initform (symbol-value 'transient--default-child-level)
     :documentation "Enable if level of prefix is equal or greater.")
    (if
     :initarg :if
@@ -932,7 +969,7 @@ example, sets a variable use `transient-define-infix' 
instead.
           (if (eq k :class)
               (setq class pop)
             (setq args (plist-put args k pop)))))
-      (vector (or level 1)
+      (vector (or level transient--default-child-level)
               (or class
                   (if (vectorp car)
                       'transient-columns
@@ -1003,7 +1040,7 @@ example, sets a variable use `transient-define-infix' 
instead.
     (unless (plist-get args :key)
       (when-let ((shortarg (plist-get args :shortarg)))
         (setq args (plist-put args :key shortarg))))
-    (list (or level 1)
+    (list (or level transient--default-child-level)
           (or class 'transient-suffix)
           args)))
 
@@ -1968,6 +2005,11 @@ value.  Otherwise return CHILDREN as is."
 
 (defun transient--post-command ()
   (transient--debug 'post-command)
+  (unless this-command
+    (transient--debug "-- force pre-exit from post-command")
+    (message "Quit transient!")
+    (transient--pre-exit)
+    (setq transient--exitp t))
   (if transient--exitp
       (progn
         (unless (and (eq transient--exitp 'replace)
@@ -2043,7 +2085,8 @@ value.  Otherwise return CHILDREN as is."
     (if (symbolp arg)
         (message "-- %-16s (cmd: %s, event: %S, exit: %s)"
                  arg
-                 (transient--suffix-symbol this-command)
+                 (or (transient--suffix-symbol this-command)
+                     (list this-command this-original-command last-command))
                  (key-description (this-command-keys-vector))
                  transient--exitp)
       (apply #'message arg args))))
@@ -2913,13 +2956,21 @@ have a history of their own.")
          (cw (mapcar (lambda (col) (apply #'max (mapcar #'length col)))
                      columns))
          (cc (transient--seq-reductions-from (apply-partially #'+ 3) cw 0)))
-    (dotimes (r rs)
-      (dotimes (c cs)
-        (insert (make-string (- (nth c cc) (current-column)) ?\s))
-        (when-let ((cell (nth r (nth c columns))))
-          (insert cell))
-        (when (= c (1- cs))
-          (insert ?\n))))))
+    (if transient-force-single-column
+        (dotimes (c cs)
+          (dotimes (r rs)
+            (when-let ((cell (nth r (nth c columns))))
+              (unless (equal cell "")
+                (insert cell ?\n))))
+          (unless (= c (1- cs))
+            (insert ?\n)))
+      (dotimes (r rs)
+        (dotimes (c cs)
+          (insert (make-string (- (nth c cc) (current-column)) ?\s))
+          (when-let ((cell (nth r (nth c columns))))
+            (insert cell))
+          (when (= c (1- cs))
+            (insert ?\n)))))))
 
 (cl-defmethod transient--insert-group ((group transient-subgroups))
   (let* ((subgroups (oref group suffixes))
@@ -2974,9 +3025,7 @@ Optional support for popup buttons is also implemented 
here."
                                          'transient-disabled-suffix))))
               (cl-call-next-method obj))))
     (when (oref obj inapt)
-      (set-text-properties 0 (length str)
-                           (list 'face 'transient-inapt-suffix)
-                           str))
+      (add-face-text-property 0 (length str) 'transient-inapt-suffix nil str))
     (if transient-enable-popup-navigation
         (make-text-button str nil
                           'type 'transient-button
@@ -3088,9 +3137,15 @@ If the OBJ's `key' is currently unreachable, then apply 
the face
                        (funcall (oref transient--prefix suffix-description)
                                 obj))
                   (propertize "(BUG: no description)" 'face 'error))))
-    (if (transient--key-unreachable-p obj)
-        (propertize desc 'face 'transient-unreachable)
-      desc)))
+    (cond ((transient--key-unreachable-p obj)
+           (propertize desc 'face 'transient-unreachable))
+          ((and transient-highlight-higher-levels
+                (> (oref obj level) transient--default-prefix-level))
+           (add-face-text-property
+            0 (length desc) 'transient-higher-level nil desc)
+           desc)
+          (t
+           desc))))
 
 (cl-defgeneric transient-format-value (obj)
   "Format OBJ's value for display and return the result.")
@@ -3192,13 +3247,16 @@ Show the first one that is specified."
         (transient--show-manpage manpage)
       (transient--describe-function (oref obj command)))))
 
-(cl-defmethod transient-show-help ((_   transient-suffix))
+(cl-defmethod transient-show-help ((obj transient-suffix))
   "Show the command doc-string."
   (if (eq this-original-command 'transient-help)
       (if-let ((manpage (oref transient--prefix man-page)))
           (transient--show-manpage manpage)
         (transient--describe-function (oref transient--prefix command)))
-    (transient--describe-function this-original-command)))
+    (if-let ((prefix (get (transient--suffix-command obj) 'transient--prefix))
+             (manpage (oref prefix man-page)))
+        (transient--show-manpage manpage)
+      (transient--describe-function this-original-command))))
 
 (cl-defmethod transient-show-help ((obj transient-infix))
   "Show the manpage if defined or the command doc-string.
diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el
index 7c913bc..8b79736 100644
--- a/lisp/url/url-util.el
+++ b/lisp/url/url-util.el
@@ -335,10 +335,13 @@ instead of just \"key\" as in the example above."
 
 ;;;###autoload
 (defun url-unhex-string (str &optional allow-newlines)
-  "Remove %XX embedded spaces, etc in a URL.
+  "Decode %XX sequences in a percent-encoded URL.
 If optional second argument ALLOW-NEWLINES is non-nil, then allow the
 decoding of carriage returns and line feeds in the string, which is normally
-forbidden in URL encoding."
+forbidden in URL encoding.
+
+The resulting string in general requires decoding using an
+appropriate coding-system; see `decode-coding-string'."
   (setq str (or str ""))
   (let ((tmp "")
        (case-fold-search t))
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index a009339..4652afa 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -2265,17 +2265,20 @@ Call FUN with two args (BEG and END) for each hunk."
       ;; same hunk.
       (goto-char (next-single-char-property-change
                   (point) 'diff--font-lock-refined nil max)))
-    (diff--iterate-hunks
-     max
-     (lambda (beg end)
-       (unless (get-char-property beg 'diff--font-lock-refined)
-         (diff--refine-hunk beg end)
-         (let ((ol (make-overlay beg end)))
-           (overlay-put ol 'diff--font-lock-refined t)
-           (overlay-put ol 'diff-mode 'fine)
-           (overlay-put ol 'evaporate t)
-           (overlay-put ol 'modification-hooks
-                        '(diff--overlay-auto-delete))))))))
+    ;; Ignore errors that diff cannot be found so that custom font-lock
+    ;; keywords after `diff--font-lock-refined' can still be evaluated.
+    (ignore-error file-missing
+      (diff--iterate-hunks
+       max
+       (lambda (beg end)
+         (unless (get-char-property beg 'diff--font-lock-refined)
+           (diff--refine-hunk beg end)
+           (let ((ol (make-overlay beg end)))
+             (overlay-put ol 'diff--font-lock-refined t)
+             (overlay-put ol 'diff-mode 'fine)
+             (overlay-put ol 'evaporate t)
+             (overlay-put ol 'modification-hooks
+                          '(diff--overlay-auto-delete)))))))))
 
 (defun diff--overlay-auto-delete (ol _after _beg _end &optional _len)
   (delete-overlay ol))
diff --git a/nextstep/Makefile.in b/nextstep/Makefile.in
index 3168fee..42b2ab2 100644
--- a/nextstep/Makefile.in
+++ b/nextstep/Makefile.in
@@ -36,6 +36,7 @@ MKDIR_P = @MKDIR_P@
 ns_appdir = @ns_appdir@
 ## GNUstep: ns_appdir; macOS: ns_appdir/Contents/MacOS
 ns_appbindir = @ns_appbindir@
+ns_applibexecdir = @ns_applibexecdir@
 ## GNUstep/Emacs.base or Cocoa/Emacs.base.
 ns_appsrc = @ns_appsrc@
 ## GNUstep: GNUstep/Emacs.base/Resources/Info-gnustep.plist
@@ -44,7 +45,7 @@ ns_check_file = @ns_appdir@/@ns_check_file@
 
 .PHONY: all
 
-all: ${ns_appdir} ${ns_appbindir}/Emacs ${ns_appbindir}/Emacs.pdmp
+all: ${ns_appdir} ${ns_appbindir}/Emacs ${ns_applibexecdir}/Emacs.pdmp
 
 ${ns_check_file} ${ns_appdir}: ${srcdir}/${ns_appsrc} ${ns_appsrc}
        rm -rf ${ns_appdir}
@@ -63,8 +64,10 @@ ${ns_appbindir}/Emacs: ${ns_appdir} ${ns_check_file} 
../src/emacs${EXEEXT}
        ${MKDIR_P} ${ns_appbindir}
        cp -f ../src/emacs${EXEEXT} $@
 
-${ns_appbindir}/Emacs.pdmp: ${ns_appdir} ${ns_check_file} 
../src/emacs${EXEEXT}.pdmp
-       ${MKDIR_P} ${ns_appbindir}
+# FIXME: Don't install the dump file into the app bundle when
+# self-contained install is disabled.
+${ns_applibexecdir}/Emacs.pdmp: ${ns_appdir} ${ns_check_file} 
../src/emacs${EXEEXT}.pdmp
+       ${MKDIR_P} ${ns_applibexecdir}
        cp -f ../src/emacs${EXEEXT}.pdmp $@
 
 .PHONY: FORCE
@@ -85,9 +88,8 @@ links: ../src/emacs${EXEEXT}
        ln -s $(top_srcdir_abs)/info ${ns_appdir}/Contents/Resources
        ${MKDIR_P} ${ns_appbindir}
        ln -s $(abs_top_builddir)/src/emacs${EXEEXT} ${ns_appbindir}/Emacs
-       ln -s $(abs_top_builddir)/src/emacs${EXEEXT}.pdmp 
${ns_appbindir}/Emacs.pdmp
        ln -s $(abs_top_builddir)/lib-src ${ns_appbindir}/bin
-       ln -s $(abs_top_builddir)/lib-src ${ns_appbindir}/libexec
+       ln -s $(abs_top_builddir)/lib-src ${ns_applibexecdir}
        ${MKDIR_P} ${ns_appdir}/Contents/Resources/etc
        for f in $(shell cd $(top_srcdir_abs)/etc; ls); do ln -s 
$(top_srcdir_abs)/etc/$$f ${ns_appdir}/Contents/Resources/etc; done
        ln -s $(abs_top_builddir)/etc/DOC ${ns_appdir}/Contents/Resources/etc
diff --git a/src/Makefile.in b/src/Makefile.in
index 40a423d..8c28e82 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -55,7 +55,7 @@ lwlibdir = ../lwlib
 # Configuration files for .o files to depend on.
 config_h = config.h $(srcdir)/conf_post.h
 
-## ns-app if HAVE_NS, else empty.
+## ns-app if NS self contained app, else empty.
 OTHER_FILES = @OTHER_FILES@
 
 ## Flags to pass for profiling builds
diff --git a/src/callproc.c b/src/callproc.c
index e44e243..675b78d 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -116,11 +116,13 @@ static CHILD_SETUP_TYPE child_setup (int, int, int, char 
**, char **,
                                     const char *);
 
 /* Return the current buffer's working directory, or the home
-   directory if it's unreachable, as a string suitable for a system call.
-   Signal an error if the result would not be an accessible directory.  */
+   directory if it's unreachable.  If ENCODE is true, return as a string
+   suitable for a system call; otherwise, return a string in its
+   internal representation.  Signal an error if the result would not be
+   an accessible directory.  */
 
 Lisp_Object
-encode_current_directory (void)
+get_current_directory (bool encode)
 {
   Lisp_Object curdir = BVAR (current_buffer, directory);
   Lisp_Object dir = Funhandled_file_name_directory (curdir);
@@ -131,12 +133,12 @@ encode_current_directory (void)
     dir = build_string ("~");
 
   dir = expand_and_dir_to_file (dir);
-  dir = ENCODE_FILE (remove_slash_colon (dir));
+  Lisp_Object encoded_dir = ENCODE_FILE (remove_slash_colon (dir));
 
-  if (! file_accessible_directory_p (dir))
+  if (! file_accessible_directory_p (encoded_dir))
     report_file_error ("Setting current directory", curdir);
 
-  return dir;
+  return encode ? encoded_dir : dir;
 }
 
 /* If P is reapable, record it as a deleted process and kill it.
@@ -225,8 +227,9 @@ DEFUN ("call-process", Fcall_process, Scall_process, 1, 
MANY, 0,
 The remaining arguments are optional.
 
 The program's input comes from file INFILE (nil means `null-device').
-If you want to make the input come from an Emacs buffer, use
-`call-process-region' instead.
+If INFILE is a relative path, it will be looked for relative to the
+directory where the process is run (see below).  If you want to make the
+input come from an Emacs buffer, use `call-process-region' instead.
 
 Third argument DESTINATION specifies how to handle program's output.
 If DESTINATION is a buffer, or t that stands for the current buffer,
@@ -270,7 +273,9 @@ usage: (call-process PROGRAM &optional INFILE DESTINATION 
DISPLAY &rest ARGS)  *
 
   if (nargs >= 2 && ! NILP (args[1]))
     {
-      infile = Fexpand_file_name (args[1], BVAR (current_buffer, directory));
+      /* Expand infile relative to the current buffer's current
+        directory, or its unhandled equivalent ("~").  */
+      infile = Fexpand_file_name (args[1], get_current_directory (false));
       CHECK_STRING (infile);
     }
   else
@@ -439,7 +444,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int 
filefd,
      buffer's current directory, or its unhandled equivalent.  We
      can't just have the child check for an error when it does the
      chdir, since it's in a vfork.  */
-  current_dir = encode_current_directory ();
+  current_dir = get_current_directory (true);
 
   if (STRINGP (error_file))
     {
@@ -1661,32 +1666,15 @@ make_environment_block (Lisp_Object current_dir)
 void
 init_callproc_1 (void)
 {
-#ifdef HAVE_NS
-  const char *etc_dir = ns_etc_directory ();
-  const char *path_exec = ns_exec_path ();
-#endif
-
-  Vdata_directory = decode_env_path ("EMACSDATA",
-#ifdef HAVE_NS
-                                             etc_dir ? etc_dir :
-#endif
-                                             PATH_DATA, 0);
+  Vdata_directory = decode_env_path ("EMACSDATA", PATH_DATA, 0);
   Vdata_directory = Ffile_name_as_directory (Fcar (Vdata_directory));
 
-  Vdoc_directory = decode_env_path ("EMACSDOC",
-#ifdef HAVE_NS
-                                             etc_dir ? etc_dir :
-#endif
-                                             PATH_DOC, 0);
+  Vdoc_directory = decode_env_path ("EMACSDOC", PATH_DOC, 0);
   Vdoc_directory = Ffile_name_as_directory (Fcar (Vdoc_directory));
 
   /* Check the EMACSPATH environment variable, defaulting to the
      PATH_EXEC path from epaths.h.  */
-  Vexec_path = decode_env_path ("EMACSPATH",
-#ifdef HAVE_NS
-                                path_exec ? path_exec :
-#endif
-                                PATH_EXEC, 0);
+  Vexec_path = decode_env_path ("EMACSPATH", PATH_EXEC, 0);
   Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path));
   /* FIXME?  For ns, path_exec should go at the front?  */
   Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path);
@@ -1701,10 +1689,6 @@ init_callproc (void)
 
   char *sh;
   Lisp_Object tempdir;
-#ifdef HAVE_NS
-  if (data_dir == 0)
-    data_dir = ns_etc_directory () != 0;
-#endif
 
   if (!NILP (Vinstallation_directory))
     {
@@ -1716,15 +1700,8 @@ init_callproc (void)
          /* MSDOS uses wrapped binaries, so don't do this.  */
       if (NILP (Fmember (tem, Vexec_path)))
        {
-#ifdef HAVE_NS
-         const char *path_exec = ns_exec_path ();
-#endif
          /* Running uninstalled, so default to tem rather than PATH_EXEC.  */
-         Vexec_path = decode_env_path ("EMACSPATH",
-#ifdef HAVE_NS
-                                       path_exec ? path_exec :
-#endif
-                                       SSDATA (tem), 0);
+         Vexec_path = decode_env_path ("EMACSPATH", SSDATA (tem), 0);
          Vexec_path = nconc2 (decode_env_path ("PATH", "", 0), Vexec_path);
        }
 
diff --git a/src/comp.c b/src/comp.c
index ea05952..c380346 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -744,8 +744,34 @@ hash_native_abi (void)
                        Vsystem_configuration_options),
               Fmapconcat (intern_c_string ("comp--subr-signature"),
                           Vcomp_subr_list, build_string (""))));
+
+  Lisp_Object version = Vemacs_version;
+
+#ifdef NS_SELF_CONTAINED
+  /* MacOS self contained app bundles do not like having dots in the
+     directory names under the Contents/Frameworks directory, so
+     convert them to underscores.  */
+  version = STRING_MULTIBYTE (Vemacs_version)
+    ? make_uninit_multibyte_string (SCHARS (Vemacs_version),
+                                   SBYTES (Vemacs_version))
+    : make_uninit_string (SBYTES (Vemacs_version));
+
+  const unsigned char *from = SDATA (Vemacs_version);
+  unsigned char *to = SDATA (version);
+
+  while (from < SDATA (Vemacs_version) + SBYTES (Vemacs_version))
+    {
+      unsigned char c = *from++;
+
+      if (c == '.')
+       c = '_';
+
+      *to++ = c;
+    }
+#endif
+
   Vcomp_native_version_dir =
-    concat3 (Vemacs_version, build_string ("-"), Vcomp_abi_hash);
+    concat3 (version, build_string ("-"), Vcomp_abi_hash);
 }
 
 static void
diff --git a/src/emacs.c b/src/emacs.c
index c8bc0ba..fd265b4 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -835,7 +835,13 @@ load_pdump (int argc, char **argv)
     NULL
 #endif
     ;
-  const char *argv0_base = "emacs";
+  const char *argv0_base =
+#ifdef NS_SELF_CONTAINED
+    "Emacs"
+#else
+    "emacs"
+#endif
+    ;
 
   /* TODO: maybe more thoroughly scrub process environment in order to
      make this use case (loading a dump file in an unexeced emacs)
@@ -912,6 +918,8 @@ load_pdump (int argc, char **argv)
   /* On MS-Windows, PATH_EXEC normally starts with a literal
      "%emacs_dir%", so it will never work without some tweaking.  */
   path_exec = w32_relocate (path_exec);
+#elif defined (HAVE_NS)
+  path_exec = ns_relocate (path_exec);
 #endif
 
   /* Look for "emacs.pdmp" in PATH_EXEC.  We hardcode "emacs" in
@@ -929,6 +937,7 @@ load_pdump (int argc, char **argv)
     }
   sprintf (dump_file, "%s%c%s%s",
            path_exec, DIRECTORY_SEP, argv0_base, suffix);
+#if !defined (NS_SELF_CONTAINED)
   /* Assume the Emacs binary lives in a sibling directory as set up by
      the default installation configuration.  */
   const char *go_up = "../../../../bin/";
@@ -943,6 +952,7 @@ load_pdump (int argc, char **argv)
   sprintf (emacs_executable, "%s%c%s%s%s",
           path_exec, DIRECTORY_SEP, go_up, argv0_base,
           strip_suffix ? strip_suffix : "");
+#endif
   result = pdumper_load (dump_file, emacs_executable);
 
   if (result == PDUMPER_LOAD_FILE_NOT_FOUND)
@@ -2975,7 +2985,11 @@ decode_env_path (const char *evarname, const char 
*defalt, bool empty)
     path = 0;
   if (!path)
     {
+#ifdef NS_SELF_CONTAINED
+      path = ns_relocate (defalt);
+#else
       path = defalt;
+#endif
 #ifdef WINDOWSNT
       defaulted = 1;
 #endif
diff --git a/src/lread.c b/src/lread.c
index 0b33fd0..a6c2db5 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4769,14 +4769,8 @@ load_path_default (void)
     return decode_env_path (0, PATH_DUMPLOADSEARCH, 0);
 
   Lisp_Object lpath = Qnil;
-  const char *normal = PATH_LOADSEARCH;
-  const char *loadpath = NULL;
 
-#ifdef HAVE_NS
-  loadpath = ns_load_path ();
-#endif
-
-  lpath = decode_env_path (0, loadpath ? loadpath : normal, 0);
+  lpath = decode_env_path (0, PATH_LOADSEARCH, 0);
 
   if (!NILP (Vinstallation_directory))
     {
diff --git a/src/minibuf.c b/src/minibuf.c
index 00069ea..1b842b7 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1210,7 +1210,7 @@ read_minibuf_unwind (void)
                     WINDOW_FRAME (XWINDOW (minibuf_window))))
            Fset_frame_selected_window (selected_frame, prev, Qnil);
        }
-      else
+      else if (WINDOW_LIVE_P (calling_window))
        Fset_frame_selected_window (calling_frame, calling_window, Qnil);
     }
 
diff --git a/src/nsfont.m b/src/nsfont.m
index f4f0d28..5a9cdfe 100644
--- a/src/nsfont.m
+++ b/src/nsfont.m
@@ -277,30 +277,36 @@ ns_ascii_average_width (NSFont *sfont)
 
 
 /* Return whether set1 covers set2 to a reasonable extent given by pct.
-   We check, out of each 16 Unicode char range containing chars in set2,
-   whether at least one character is present in set1.
-   This must be true for pct of the pairs to consider it covering.  */
+
+   The GNUstep bitmap representation doesn't match Apple's
+   description.  It appears to be a single block of bytes, not broken
+   up into planes, where the last byte contains the highest character
+   the character set supports.  */
 static BOOL
 ns_charset_covers(NSCharacterSet *set1, NSCharacterSet *set2, float pct)
 {
-    const unsigned short *bytes1 = [[set1 bitmapRepresentation] bytes];
-    const unsigned short *bytes2 = [[set2 bitmapRepresentation] bytes];
-    int i, off = 0, tot = 0;
+  NSData *font = [set1 bitmapRepresentation];
+  NSData *script = [set2 bitmapRepresentation];
 
-    /* Work around what appears to be a GNUstep bug.
-       See <https://bugs.gnu.org/11853>.  */
-    if (! (bytes1 && bytes2))
-      return NO;
+  uint8_t *fontPlane = (uint8_t *)[font bytes];
+  uint8_t *scriptPlane = (uint8_t *)[script bytes];
 
-    for (i=0; i<4096; i++, bytes1++, bytes2++)
-       if (*bytes2)
-         {
-           tot++;
-           if (*bytes1 == 0)  // *bytes1 & *bytes2 != *bytes2
-               off++;
-         }
-    // fprintf(stderr, "off = %d\ttot = %d\n", off,tot);
-    return (float)off / tot < 1.0F - pct;
+  int covered = 0, total = 0;
+
+  for (ptrdiff_t b = 0 ; b < [script length] ; b++)
+    for (int i = 0 ; i < 8 ; i++)
+      {
+        if (*(scriptPlane + b) & (1 << i))
+          {
+            total++;
+
+            if (b < [font length]
+                && *(fontPlane + b) & (1 << i))
+              covered++;
+          }
+      }
+
+  return (float)covered / total >= 1.0F - pct;
 }
 
 
@@ -700,7 +706,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int 
pixel_size)
      when setting family in ns_spec_to_descriptor().  */
   if (ns_attribute_fvalue (fontDesc, NSFontWeightTrait) > 0.50F)
       traits |= NSBoldFontMask;
-  if (fabs (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F))
+  if (ns_attribute_fvalue (fontDesc, NSFontSlantTrait) > 0.05F)
       traits |= NSItalicFontMask;
 
   /* see 
https://web.archive.org/web/20100201175731/http://cocoadev.com/forums/comments.php?DiscussionID=74
 */
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 24aa5a0..1b03fe9 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -73,7 +73,7 @@ free_frame_menubar (struct frame *f)
   id menu = [NSApp mainMenu];
   for (int i = [menu numberOfItems] - 1 ; i >= 0; i--)
     {
-      NSMenuItem *item = [menu itemAtIndex:i];
+      NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i];
       NSString *title = [item title];
 
       if ([ns_app_name isEqualToString:title])
@@ -358,8 +358,12 @@ ns_update_menubar (struct frame *f, bool deep_p)
       if (i < [menu numberOfItems])
         {
           NSString *titleStr = [NSString stringWithUTF8String: wv->name];
-          NSMenuItem *item = [menu itemAtIndex:i];
-          submenu = (EmacsMenu*)[item submenu];
+          NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i];
+          submenu = (EmacsMenu *)[item submenu];
+
+#ifdef NS_IMPL_GNUSTEP
+          [submenu close];
+#endif
 
           [item setTitle:titleStr];
           [submenu setTitle:titleStr];
@@ -368,8 +372,10 @@ ns_update_menubar (struct frame *f, bool deep_p)
       else
         submenu = [menu addSubmenuWithTitle: wv->name];
 
+#ifdef NS_IMPL_COCOA
       if ([[submenu title] isEqualToString:@"Help"])
         [NSApp setHelpMenu:submenu];
+#endif
 
       if (deep_p)
         [submenu fillWithWidgetValue: wv->contents];
@@ -380,6 +386,12 @@ ns_update_menubar (struct frame *f, bool deep_p)
   while (i < [menu numberOfItems])
     {
       /* Remove any extra items.  */
+#ifdef NS_IMPL_GNUSTEP
+      NSMenuItem *item = (NSMenuItem *)[menu itemAtIndex:i];
+      EmacsMenu *submenu = (EmacsMenu *)[item submenu];
+      [submenu close];
+#endif
+
       [menu removeItemAtIndex:i];
     }
 
@@ -472,7 +484,7 @@ set_frame_menubar (struct frame *f, bool deep_p)
 
   if (menu_separator_name_p (wv->name))
     {
-      item = [NSMenuItem separatorItem];
+      item = (NSMenuItem *)[NSMenuItem separatorItem];
     }
   else
     {
@@ -534,7 +546,7 @@ set_frame_menubar (struct frame *f, bool deep_p)
   needsUpdate = YES;
 }
 
-
+#ifdef NS_IMPL_COCOA
 typedef struct {
   const char *from, *to;
 } subst_t;
@@ -591,17 +603,18 @@ prettify_key (const char *key)
   xfree (buf);
   return SSDATA (result);
 }
+#endif /* NS_IMPL_COCOA */
 
 - (void)fillWithWidgetValue: (void *)wvptr
 {
   widget_value *first_wv = (widget_value *)wvptr;
-  NSFont *menuFont = [NSFont menuFontOfSize:0];
   NSDictionary *attributes = nil;
 
 #ifdef NS_IMPL_COCOA
   /* Cocoa doesn't allow multi-key sequences in its menu display, so
      work around it by using tabs to split the title into two
      columns.  */
+  NSFont *menuFont = [NSFont menuFontOfSize:0];
   NSDictionary *font_attribs = @{NSFontAttributeName: menuFont};
   CGFloat maxNameWidth = 0;
   CGFloat maxKeyWidth = 0;
@@ -672,9 +685,9 @@ prettify_key (const char *key)
 - (EmacsMenu *)addSubmenuWithTitle: (const char *)title
 {
   NSString *titleStr = [NSString stringWithUTF8String: title];
-  NSMenuItem *item = [self addItemWithTitle: titleStr
-                                     action: (SEL)nil /*@selector (menuDown:) 
*/
-                              keyEquivalent: @""];
+  NSMenuItem *item = (NSMenuItem *)[self addItemWithTitle: titleStr
+                                                   action: (SEL)nil
+                                            keyEquivalent: @""];
   EmacsMenu *submenu = [[EmacsMenu alloc] initWithTitle: titleStr];
   [self setSubmenu: submenu forItem: item];
   [submenu release];
@@ -711,6 +724,44 @@ prettify_key (const char *key)
       : Qnil;
 }
 
+#ifdef NS_IMPL_GNUSTEP
+- (void) close
+{
+    /* Close all the submenus.  This has the unfortunate side-effect of
+     breaking tear-off menus, however if we don't do this then we get
+     a crash when the menus are removed during updates.  */
+  for (int i = 0 ; i < [self numberOfItems] ; i++)
+    {
+      NSMenuItem *item = [self itemAtIndex:i];
+      if ([item hasSubmenu])
+        [(EmacsMenu *)[item submenu] close];
+    }
+
+  [super close];
+}
+
+/* GNUstep seems to have a number of required methods in
+   NSMenuDelegate that are optional in Cocoa.  */
+
+- (void) menuWillOpen:(NSMenu *)menu
+{
+}
+
+- (void) menuDidClose:(NSMenu *)menu
+{
+}
+
+- (NSRect)confinementRectForMenu:(NSMenu *)menu
+                        onScreen:(NSScreen *)screen
+{
+  return NSZeroRect;
+}
+
+- (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item
+{
+}
+#endif
+
 @end  /* EmacsMenu */
 
 
diff --git a/src/nsterm.h b/src/nsterm.h
index e7ea907..b29e76c 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -504,6 +504,10 @@ typedef id instancetype;
   NSPoint grabOffset;
 }
 
+#ifdef NS_IMPL_GNUSTEP
+- (NSInteger) orderedIndex;
+#endif
+
 - (BOOL)restackWindow:(NSWindow *)win above:(BOOL)above;
 - (void)setAppearance;
 @end
@@ -1186,9 +1190,7 @@ extern void ns_run_ascript (void);
 #define NSAPP_DATA2_RUNFILEDIALOG 11
 extern void ns_run_file_dialog (void);
 
-extern const char *ns_etc_directory (void);
-extern const char *ns_exec_path (void);
-extern const char *ns_load_path (void);
+extern const char *ns_relocate (const char *epath);
 extern void syms_of_nsterm (void);
 extern void syms_of_nsfns (void);
 extern void syms_of_nsmenu (void);
diff --git a/src/nsterm.m b/src/nsterm.m
index 838c14d..b9e2c9b 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -277,11 +277,9 @@ static NSView *focus_view = NULL;
 #endif
 static int ns_window_num = 0;
 static BOOL gsaved = NO;
-static BOOL ns_fake_keydown = NO;
 #ifdef NS_IMPL_COCOA
 static BOOL ns_menu_bar_is_hidden = NO;
 #endif
-/* static int debug_lock = 0; */
 
 /* event loop */
 static BOOL send_appdefined = YES;
@@ -499,118 +497,37 @@ append2 (Lisp_Object list, Lisp_Object item)
 
 
 const char *
-ns_etc_directory (void)
-/* If running as a self-contained app bundle, return as a string the
-   filename of the etc directory, if present; else nil.  */
-{
-  NSBundle *bundle = [NSBundle mainBundle];
-  NSString *resourceDir = [bundle resourcePath];
-  NSString *resourcePath;
-  NSFileManager *fileManager = [NSFileManager defaultManager];
-  BOOL isDir;
-
-  resourcePath = [resourceDir stringByAppendingPathComponent: @"etc"];
-  if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
-    {
-      if (isDir) return [resourcePath UTF8String];
-    }
-  return NULL;
-}
-
+ns_relocate (const char *epath)
+/* If we're running in a self-contained app bundle some hard-coded
+   paths are relative to the root of the bundle, so work out the full
+   path.
 
-const char *
-ns_exec_path (void)
-/* If running as a self-contained app bundle, return as a path string
-   the filenames of the libexec and bin directories, ie libexec:bin.
-   Otherwise, return nil.
-   Normally, Emacs does not add its own bin/ directory to the PATH.
-   However, a self-contained NS build has a different layout, with
-   bin/ and libexec/ subdirectories in the directory that contains
-   Emacs.app itself.
-   We put libexec first, because init_callproc_1 uses the first
-   element to initialize exec-directory.  An alternative would be
-   for init_callproc to check for invocation-directory/libexec.
-*/
+   FIXME: I think this should be able to handle cases where multiple
+   directories are separated by colons.  */
 {
+#ifdef NS_SELF_CONTAINED
   NSBundle *bundle = [NSBundle mainBundle];
-  NSString *resourceDir = [bundle resourcePath];
-  NSString *binDir = [bundle bundlePath];
-  NSString *resourcePath, *resourcePaths;
-  NSRange range;
-  NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR];
+  NSString *root = [bundle bundlePath];
+  NSString *original = [NSString stringWithUTF8String:epath];
+  NSString *fixedPath = [NSString pathWithComponents:
+                                    [NSArray arrayWithObjects:
+                                               root, original, nil]];
   NSFileManager *fileManager = [NSFileManager defaultManager];
-  NSArray *paths;
-  NSEnumerator *pathEnum;
-  BOOL isDir;
 
-  range = [resourceDir rangeOfString: @"Contents"];
-  if (range.location != NSNotFound)
-    {
-      binDir = [binDir stringByAppendingPathComponent: @"Contents"];
-#ifdef NS_IMPL_COCOA
-      binDir = [binDir stringByAppendingPathComponent: @"MacOS"];
-#endif
-    }
-
-  paths = [binDir stringsByAppendingPaths:
-                [NSArray arrayWithObjects: @"libexec", @"bin", nil]];
-  pathEnum = [paths objectEnumerator];
-  resourcePaths = @"";
+  if (![original isAbsolutePath]
+      && [fileManager fileExistsAtPath:fixedPath isDirectory:NULL])
+    return [fixedPath UTF8String];
 
-  while ((resourcePath = [pathEnum nextObject]))
-    {
-      if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
-        if (isDir)
-          {
-            if ([resourcePaths length] > 0)
-              resourcePaths
-                = [resourcePaths stringByAppendingString: pathSeparator];
-            resourcePaths
-              = [resourcePaths stringByAppendingString: resourcePath];
-          }
-    }
-  if ([resourcePaths length] > 0) return [resourcePaths UTF8String];
+  /* If we reach here either the path is absolute and therefore we
+     don't need to complete it, or we're unable to relocate the
+     file/directory.  If it's the latter it may be because the user is
+     trying to use a bundled app as though it's a Unix style install
+     and we have no way to guess what was intended, so return the
+     original string unaltered.  */
 
-  return NULL;
-}
-
-
-const char *
-ns_load_path (void)
-/* If running as a self-contained app bundle, return as a path string
-   the filenames of the site-lisp and lisp directories.
-   Ie, site-lisp:lisp.  Otherwise, return nil.  */
-{
-  NSBundle *bundle = [NSBundle mainBundle];
-  NSString *resourceDir = [bundle resourcePath];
-  NSString *resourcePath, *resourcePaths;
-  NSString *pathSeparator = [NSString stringWithFormat: @"%c", SEPCHAR];
-  NSFileManager *fileManager = [NSFileManager defaultManager];
-  BOOL isDir;
-  NSArray *paths = [resourceDir stringsByAppendingPaths:
-                              [NSArray arrayWithObjects:
-                                         @"site-lisp", @"lisp", nil]];
-  NSEnumerator *pathEnum = [paths objectEnumerator];
-  resourcePaths = @"";
-
-  /* Hack to skip site-lisp.  */
-  if (no_site_lisp) resourcePath = [pathEnum nextObject];
-
-  while ((resourcePath = [pathEnum nextObject]))
-    {
-      if ([fileManager fileExistsAtPath: resourcePath isDirectory: &isDir])
-        if (isDir)
-          {
-            if ([resourcePaths length] > 0)
-              resourcePaths
-                = [resourcePaths stringByAppendingString: pathSeparator];
-            resourcePaths
-              = [resourcePaths stringByAppendingString: resourcePath];
-          }
-    }
-  if ([resourcePaths length] > 0) return [resourcePaths UTF8String];
+#endif
 
-  return NULL;
+  return epath;
 }
 
 
@@ -6374,9 +6291,7 @@ not_in_argv (NSString *arg)
   NSTRACE ("[EmacsView keyDown:]");
 
   /* Rhapsody and macOS give up and down events for the arrow keys.  */
-  if (ns_fake_keydown == YES)
-    ns_fake_keydown = NO;
-  else if ([theEvent type] != NSEventTypeKeyDown)
+  if ([theEvent type] != NSEventTypeKeyDown)
     return;
 
   if (!emacs_event)
@@ -8763,6 +8678,16 @@ not_in_argv (NSString *arg)
 }
 
 
+#ifdef NS_IMPL_GNUSTEP
+/* orderedIndex isn't yet available in GNUstep, but it seems pretty
+   easy to implement.  */
+- (NSInteger) orderedIndex
+{
+  return [[NSApp orderedWindows] indexOfObjectIdenticalTo:self];
+}
+#endif
+
+
 /* The array returned by [NSWindow parentWindow] may already be
    sorted, but the documentation doesn't tell us whether or not it is,
    so to be safe we'll sort it.  */
diff --git a/src/process.c b/src/process.c
index ce71545..cc1afa8 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1755,7 +1755,7 @@ usage: (make-process &rest ARGS)  */)
      buffer's current directory, or its unhandled equivalent.  We
      can't just have the child check for an error when it does the
      chdir, since it's in a vfork.  */
-  current_dir = encode_current_directory ();
+  current_dir = get_current_directory (true);
 
   name = Fplist_get (contact, QCname);
   CHECK_STRING (name);
diff --git a/src/process.h b/src/process.h
index 0890f25..4a25d13 100644
--- a/src/process.h
+++ b/src/process.h
@@ -264,7 +264,7 @@ enum
 
 /* Defined in callproc.c.  */
 
-extern Lisp_Object encode_current_directory (void);
+extern Lisp_Object get_current_directory (bool);
 extern void record_kill_process (struct Lisp_Process *, Lisp_Object);
 
 /* Defined in sysdep.c.  */
diff --git a/src/sysdep.c b/src/sysdep.c
index 51d8b5e..b8ec22d 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -657,7 +657,7 @@ sys_subshell (void)
 #endif
   pid_t pid;
   struct save_signal saved_handlers[5];
-  char *str = SSDATA (encode_current_directory ());
+  char *str = SSDATA (get_current_directory (true));
 
 #ifdef DOS_NT
   pid = 0;
diff --git a/src/thread.c b/src/thread.c
index f74f611..714b1cd 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -28,6 +28,10 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "pdumper.h"
 #include "keyboard.h"
 
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+
 #if defined HAVE_GLIB && ! defined (HAVE_NS)
 #include <xgselect.h>
 #else
@@ -735,6 +739,15 @@ run_thread (void *state)
   struct thread_state *self = state;
   struct thread_state **iter;
 
+#ifdef HAVE_NS
+  /* Allocate an autorelease pool in case this thread calls any
+     Objective C code.
+
+     FIXME: In long running threads we may want to drain the pool
+     regularly instead of just at the end.  */
+  void *pool = ns_alloc_autorelease_pool ();
+#endif
+
   self->m_stack_bottom = self->stack_top = &stack_pos.c;
   self->thread_id = sys_thread_self ();
 
@@ -777,6 +790,10 @@ run_thread (void *state)
   current_thread = NULL;
   sys_cond_broadcast (&self->thread_condvar);
 
+#ifdef HAVE_NS
+  ns_release_autorelease_pool (pool);
+#endif
+
   /* Unlink this thread from the list of all threads.  Note that we
      have to do this very late, after broadcasting our death.
      Otherwise the GC may decide to reap the thread_state object,
diff --git a/src/xgselect.c b/src/xgselect.c
index 0d91d55..92b118b 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -34,12 +34,27 @@ static GMainContext *glib_main_context;
 
 void release_select_lock (void)
 {
+#if GNUC_PREREQ (4, 7, 0)
+  if (__atomic_sub_fetch (&threads_holding_glib_lock, 1, __ATOMIC_ACQ_REL) == 
0)
+    g_main_context_release (glib_main_context);
+#else
   if (--threads_holding_glib_lock == 0)
     g_main_context_release (glib_main_context);
+#endif
 }
 
 static void acquire_select_lock (GMainContext *context)
 {
+#if GNUC_PREREQ (4, 7, 0)
+  if (__atomic_fetch_add (&threads_holding_glib_lock, 1, __ATOMIC_ACQ_REL) == 
0)
+    {
+      glib_main_context = context;
+      while (!g_main_context_acquire (context))
+       {
+         /* Spin. */
+       }
+    }
+#else
   if (threads_holding_glib_lock++ == 0)
     {
       glib_main_context = context;
@@ -48,6 +63,7 @@ static void acquire_select_lock (GMainContext *context)
          /* Spin. */
        }
     }
+#endif
 }
 
 /* `xg_select' is a `pselect' replacement.  Why do we need a separate function?
diff --git a/test/README b/test/README
index 0c8d5a4..97611cf 100644
--- a/test/README
+++ b/test/README
@@ -105,6 +105,11 @@ debugging.  To do that, use
 
     make TEST_INTERACTIVE=yes ...
 
+By default, ERT test failure summaries are quite brief in batch
+mode--only the names of the failed tests are listed.  If the
+$EMACS_TEST_VERBOSE environment variable is set, the failure summaries
+will also include the data from the failing test.
+
 Some of the tests require a remote temporary directory
 (autorevert-tests.el, filenotify-tests.el, shadowfile-tests.el and
 tramp-tests.el).  Per default, a mock-up connection method is used
diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml
index fa10fa6..6876a8b 100644
--- a/test/infra/gitlab-ci.yml
+++ b/test/infra/gitlab-ci.yml
@@ -44,6 +44,7 @@ workflow:
 variables:
   GIT_STRATEGY: fetch
   EMACS_EMBA_CI: 1
+  EMACS_TEST_VERBOSE: 1
   # # Use TLS 
https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
   # DOCKER_HOST: tcp://docker:2376
   # DOCKER_TLS_CERTDIR: "/certs"
diff --git a/test/lisp/auth-source-pass-tests.el 
b/test/lisp/auth-source-pass-tests.el
index bfbef53..d050ac5 100644
--- a/test/lisp/auth-source-pass-tests.el
+++ b/test/lisp/auth-source-pass-tests.el
@@ -49,6 +49,12 @@
                    '(("key1" . "val1")
                      ("key2" . "val2"))))))
 
+(ert-deftest auth-source-pass-parse-with-colons-in-data ()
+  (let ((content "pass\n--\nkey1 :val1\nkey2: please: keep my space after 
colon\n\n"))
+    (should (equal (auth-source-pass--parse-data content)
+                   '(("key1" . "val1")
+                     ("key2" . "please: keep my space after colon"))))))
+
 (defvar auth-source-pass--debug-log nil
   "Contains a list of all messages passed to `auth-source-do-debug`.")
 
@@ -424,21 +430,37 @@ HOSTNAME, USER and PORT are passed unchanged to
   (auth-source-pass--with-store-find-foo
       '(("foo" ("secret" . "foo password")))
     (let ((result (auth-source-pass--build-result "foo" 512 "user")))
+      (should (equal (plist-get result :host) "foo"))
       (should (equal (plist-get result :port) 512))
       (should (equal (plist-get result :user) "user")))))
 
 (ert-deftest auth-source-pass-build-result-return-entry-values ()
   (auth-source-pass--with-store-find-foo '(("foo" ("port" . 512) ("user" . 
"anuser")))
     (let ((result (auth-source-pass--build-result "foo" nil nil)))
+      (should (equal (plist-get result :host) "foo"))
       (should (equal (plist-get result :port) 512))
       (should (equal (plist-get result :user) "anuser")))))
 
 (ert-deftest auth-source-pass-build-result-entry-takes-precedence ()
-  (auth-source-pass--with-store-find-foo '(("foo" ("port" . 512) ("user" . 
"anuser")))
+  (auth-source-pass--with-store-find-foo '(("foo" ("host" . "bar") ("port" . 
512) ("user" . "anuser")))
     (let ((result (auth-source-pass--build-result "foo" 1024 "anotheruser")))
+      (should (equal (plist-get result :host) "bar"))
       (should (equal (plist-get result :port) 512))
       (should (equal (plist-get result :user) "anuser")))))
 
+(ert-deftest auth-source-pass-build-result-with-multiple-hosts ()
+  (auth-source-pass--with-store-find-foo
+      '(("foo" ("secret" . "foo password")))
+    (let ((result (auth-source-pass--build-result '("bar" "foo") 512 "user")))
+      (should (equal (plist-get result :host) "foo"))
+      (should (equal (plist-get result :port) 512))
+      (should (equal (plist-get result :user) "user")))))
+
+(ert-deftest auth-source-pass-build-result-with-multiple-hosts-no-match ()
+  (auth-source-pass--with-store-find-foo
+      '(("foo" ("secret" . "foo password")))
+    (should-not (auth-source-pass--build-result '("bar" "baz") 512 "user"))))
+
 (ert-deftest auth-source-pass-can-start-from-auth-source-search ()
   (auth-source-pass--with-store '(("gitlab.com" ("user" . "someone")))
     (auth-source-pass-enable)
diff --git a/test/lisp/emacs-lisp/shortdoc-tests.el 
b/test/lisp/emacs-lisp/shortdoc-tests.el
index 050aac3..3bb3185 100644
--- a/test/lisp/emacs-lisp/shortdoc-tests.el
+++ b/test/lisp/emacs-lisp/shortdoc-tests.el
@@ -34,7 +34,7 @@
         (let ((fun (car item))
               (props (cdr item)))
           (while props
-            (when (memq (car props) '(:eval :no-eval :no-eval*))
+            (when (memq (car props) '(:eval :no-eval :no-eval* :no-value))
               (let* ((example (cadr props))
                      (expr (cond
                             ((consp example) example)
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index dc96dff..257cbc2 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1478,5 +1478,23 @@ The door of all subtleties!
                                (buffer-substring (point-min) (point-max))
                                nil nil)))))
 
+(ert-deftest files-tests-file-name-with-extension-good ()
+  "Test that `file-name-with-extension' succeeds with reasonable input."
+  (should (string= (file-name-with-extension "Jack" "css") "Jack.css"))
+  (should (string= (file-name-with-extension "Jack" ".css") "Jack.css"))
+  (should (string= (file-name-with-extension "Jack.scss" "css") "Jack.css"))
+  (should (string= (file-name-with-extension "/path/to/Jack.md" "org") 
"/path/to/Jack.org")))
+
+(ert-deftest files-tests-file-name-with-extension-bad ()
+  "Test that `file-name-with-extension' fails on malformed input."
+  (should-error (file-name-with-extension nil nil))
+  (should-error (file-name-with-extension "Jack" nil))
+  (should-error (file-name-with-extension nil "css"))
+  (should-error (file-name-with-extension "" ""))
+  (should-error (file-name-with-extension "" "css"))
+  (should-error (file-name-with-extension "Jack" ""))
+  (should-error (file-name-with-extension "Jack" "."))
+  (should-error (file-name-with-extension "/is/a/directory/" "css")))
+
 (provide 'files-tests)
 ;;; files-tests.el ends here
diff --git a/test/lisp/gnus/message-tests.el b/test/lisp/gnus/message-tests.el
index 36ec8c5..b4f2b7f 100644
--- a/test/lisp/gnus/message-tests.el
+++ b/test/lisp/gnus/message-tests.el
@@ -154,6 +154,35 @@
                       "\"larsi@gnus.org\" <larsi@gnus.org>")
                      "larsi@gnus.org")))
 
+(ert-deftest message-replace-header ()
+  (with-temp-buffer
+    (save-excursion
+      (insert "From: dang@gnus.org
+To: user1,
+    user2
+Cc: user3,
+    user4
+--text follows this line--
+Hello.
+"))
+    (save-excursion
+      (message-replace-header "From" "ding@gnus.org")
+      (should (cl-search "ding" (message-field-value "From"))))
+    (save-excursion
+      (message-replace-header "From" "dong@gnus.org" "To")
+      (should (cl-search "dong" (message-field-value "From")))
+      (should (re-search-forward "From:"))
+      (should-error (re-search-forward "To:"))
+      (should (re-search-forward "Cc:")))
+    (save-excursion
+      (message-replace-header "From" "dang@gnus.org" (split-string "To Cc"))
+      (should (cl-search "dang" (message-field-value "From")))
+      (should (re-search-forward "From:"))
+      (should-error (re-search-forward "To:"))
+      ;; That this isn't so is probably a bug from 1997.
+      ;; (should-error (re-search-forward "Cc:"))
+      )))
+
 (provide 'message-mode-tests)
 
 ;;; message-mode-tests.el ends here
diff --git a/test/lisp/net/tramp-archive-tests.el 
b/test/lisp/net/tramp-archive-tests.el
index 9a97974..ca1163b 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -292,15 +292,26 @@ variables, so we check the Emacs version directly."
   "Check `expand-file-name'."
   (should
    (string-equal
-    (expand-file-name "/foo.tar/path/./file") "/foo.tar/path/file"))
+    (expand-file-name (concat tramp-archive-test-archive "path/./file"))
+    (concat tramp-archive-test-archive "path/file")))
   (should
-   (string-equal (expand-file-name "/foo.tar/path/../file") "/foo.tar/file"))
+   (string-equal
+    (expand-file-name (concat tramp-archive-test-archive "path/../file"))
+    (concat tramp-archive-test-archive "file")))
   ;; `expand-file-name' does not care "~/" in archive file names.
   (should
-   (string-equal (expand-file-name "/foo.tar/~/file") "/foo.tar/~/file"))
+   (string-equal
+    (expand-file-name (concat tramp-archive-test-archive "~/file"))
+    (concat tramp-archive-test-archive "~/file")))
   ;; `expand-file-name' does not care file archive boundaries.
-  (should (string-equal (expand-file-name "/foo.tar/./file") "/foo.tar/file"))
-  (should (string-equal (expand-file-name "/foo.tar/../file") "/file")))
+  (should
+   (string-equal
+    (expand-file-name (concat tramp-archive-test-archive "./file"))
+    (concat tramp-archive-test-archive "file")))
+  (should
+   (string-equal
+    (expand-file-name (concat tramp-archive-test-archive "../file"))
+    (concat (ert-resource-directory) "file"))))
 
 ;; This test is inspired by Bug#30293.
 (ert-deftest tramp-archive-test05-expand-file-name-non-archive-directory ()
@@ -321,43 +332,63 @@ They shall still be supported"
   "Check `directory-file-name'.
 This checks also `file-name-as-directory', `file-name-directory',
 `file-name-nondirectory' and `unhandled-file-name-directory'."
-  :tags '(:unstable) ;; Temporarily.
   (skip-unless tramp-archive-enabled)
 
   (should
    (string-equal
-    (directory-file-name "/foo.tar/path/to/file") "/foo.tar/path/to/file"))
+    (directory-file-name (concat tramp-archive-test-archive "path/to/file"))
+    (concat tramp-archive-test-archive "path/to/file")))
   (should
    (string-equal
-    (directory-file-name "/foo.tar/path/to/file/") "/foo.tar/path/to/file"))
+    (directory-file-name (concat tramp-archive-test-archive "path/to/file/"))
+    (concat tramp-archive-test-archive "path/to/file")))
   ;; `directory-file-name' does not leave file archive boundaries.
-  (should (string-equal (directory-file-name "/foo.tar/") "/foo.tar/"))
+  (should
+   (string-equal
+    (directory-file-name tramp-archive-test-archive) 
tramp-archive-test-archive))
 
   (should
    (string-equal
-    (file-name-as-directory "/foo.tar/path/to/file") "/foo.tar/path/to/file/"))
+    (file-name-as-directory (concat tramp-archive-test-archive "path/to/file"))
+    (concat tramp-archive-test-archive "path/to/file/")))
   (should
    (string-equal
-    (file-name-as-directory "/foo.tar/path/to/file/") 
"/foo.tar/path/to/file/"))
-  (should (string-equal (file-name-as-directory "/foo.tar/") "/foo.tar/"))
-  (should (string-equal (file-name-as-directory "/foo.tar") "/foo.tar/"))
+    (file-name-as-directory (concat tramp-archive-test-archive 
"path/to/file/"))
+    (concat tramp-archive-test-archive "path/to/file/")))
+  (should
+   (string-equal
+    (file-name-as-directory tramp-archive-test-archive)
+    tramp-archive-test-archive))
+  (should
+   (string-equal
+    (file-name-as-directory tramp-archive-test-file-archive)
+    tramp-archive-test-archive))
 
   (should
    (string-equal
-    (file-name-directory "/foo.tar/path/to/file") "/foo.tar/path/to/"))
+    (file-name-directory (concat tramp-archive-test-archive "path/to/file"))
+    (concat tramp-archive-test-archive "path/to/")))
   (should
    (string-equal
-    (file-name-directory "/foo.tar/path/to/file/") "/foo.tar/path/to/file/"))
-  (should (string-equal (file-name-directory "/foo.tar/") "/foo.tar/"))
+    (file-name-directory (concat tramp-archive-test-archive "path/to/file/"))
+    (concat tramp-archive-test-archive "path/to/file/")))
+  (should
+   (string-equal
+    (file-name-directory tramp-archive-test-archive) 
tramp-archive-test-archive))
 
   (should
-   (string-equal (file-name-nondirectory "/foo.tar/path/to/file") "file"))
+   (string-equal
+    (file-name-nondirectory (concat tramp-archive-test-archive "path/to/file"))
+    "file"))
   (should
-   (string-equal (file-name-nondirectory "/foo.tar/path/to/file/") ""))
-  (should (string-equal (file-name-nondirectory "/foo.tar/") ""))
+   (string-equal
+    (file-name-nondirectory (concat tramp-archive-test-archive 
"path/to/file/"))
+    ""))
+  (should (string-equal (file-name-nondirectory tramp-archive-test-archive) 
""))
 
   (should-not
-   (unhandled-file-name-directory "/foo.tar/path/to/file")))
+   (unhandled-file-name-directory
+    (concat tramp-archive-test-archive "path/to/file"))))
 
 (ert-deftest tramp-archive-test07-file-exists-p ()
   "Check `file-exist-p', `write-region' and `delete-file'."
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 37cd701..6aa8629 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -6280,8 +6280,9 @@ Use the `ls' command."
                      x ""))
              (not (string-empty-p x))
             ;; ?\n and ?/ shouldn't be part of any file name.  ?\t,
-            ;; ?. and ?? do not work for "smb" method.
-            (replace-regexp-in-string "[\t\n/.?]" "" x)))
+            ;; ?. and ?? do not work for "smb" method.  " " does not
+            ;; work at begin or end of the string for MS Windows.
+            (replace-regexp-in-string "[ \t\n/.?]" "" x)))
          language-info-alist)))))))
 
 (ert-deftest tramp-test41-utf8 ()
diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el
index b42271e..e42a58a 100644
--- a/test/lisp/time-stamp-tests.el
+++ b/test/lisp/time-stamp-tests.el
@@ -525,7 +525,7 @@
       (should (equal (time-stamp-string "%#Z" ref-time1) utc-abbr)))))
 
 (ert-deftest time-stamp-format-time-zone-offset ()
-  "Tests time-stamp legacy format %z and new offset format %5z."
+  "Tests time-stamp legacy format %z and spot tests of new offset format %5z."
   (with-time-stamp-test-env
     (let ((utc-abbr (format-time-string "%#Z" ref-time1 t)))
     ;; documented 1995-2019, warned since 2019, will change
@@ -540,8 +540,9 @@
     (let ((time-stamp-time-zone "CET-1"))
       (should (equal (time-stamp-string "%5z" ref-time1) "+0100")))
     ;; implemented since 2019, verify that these don't warn
+    ;; See also the "formatz" tests below, which since 2021 test more
+    ;; variants with more offsets.
     (should (equal (time-stamp-string "%-z" ref-time1) "+00"))
-    (should (equal (time-stamp-string "%_z" ref-time1) "+0000"))
     (should (equal (time-stamp-string "%:z" ref-time1) "+00:00"))
     (should (equal (time-stamp-string "%::z" ref-time1) "+00:00:00"))
     (should (equal (time-stamp-string "%9::z" ref-time1) "+00:00:00"))
@@ -615,16 +616,24 @@
                      (concat Mon "." MON "." Mon)))
       ;; underscore flag is independent
       (should (equal (time-stamp-string "%_d.%d.%_d" ref-time1) " 2.02. 2"))
-      ;; minus flag is independendent
+      (should (equal (time-stamp-string "%_7z.%7z.%_7z" ref-time1)
+                     "+000000.+0000  .+000000"))
+      ;; minus flag is independent
       (should (equal (time-stamp-string "%d.%-d.%d" ref-time1) "02.2.02"))
-      ;; 0 flag is independendent
+      (should (equal (time-stamp-string "%3z.%-3z.%3z" ref-time1)
+                     "+0000.+00.+0000"))
+      ;; 0 flag is independent
       (should (equal (time-stamp-string "%2d.%02d.%2d" ref-time1) " 2.02. 2"))
+      (should (equal (time-stamp-string "%6:::z.%06:::z.%6:::z" ref-time1)
+                     "+00   .+00:00.+00   "))
       ;; field width is independent
       (should (equal
                (time-stamp-string "%6Y.%Y.%6Y" ref-time1) "  2006.2006.  
2006"))
       ;; colon modifier is independent
       (should (equal (time-stamp-string "%a.%:a.%a" ref-time1)
                      (concat Mon "." Monday "." Mon)))
+      (should (equal (time-stamp-string "%5z.%5::z.%5z" ref-time1)
+                     "+0000.+00:00:00.+0000"))
       ;; format letter is independent
       (should (equal (time-stamp-string "%H:%M" ref-time1) "15:04")))))
 
@@ -691,4 +700,401 @@
   (should (safe-local-variable-p 'time-stamp-pattern "a string"))
   (should-not (safe-local-variable-p 'time-stamp-pattern 17)))
 
+;;;; Setup for tests of time offset formatting with %z
+
+(defun formatz (format zone)
+  "Uses time FORMAT string to format the offset of ZONE, returning the result.
+FORMAT is \"%z\" or a variation.
+ZONE is as the ZONE argument of the `format-time-string' function."
+  (with-time-stamp-test-env
+   (let ((time-stamp-time-zone zone))
+     ;; Call your favorite time formatter here.
+     ;; For narrower-scope unit testing,
+     ;; instead of calling time-stamp-string here,
+     ;; we could directly call (format-time-offset format zone)
+     (time-stamp-string format)
+     )))
+
+(defun format-time-offset (format offset-secs)
+  "Uses FORMAT to format the time zone represented by OFFSET-SECS.
+FORMAT must be \"%z\", possibly with a flag and padding.
+This function is a wrapper around `time-stamp-formatz-from-parsed-options'
+and is used for testing."
+  ;; This wrapper adds a simple regexp-based parser that handles only
+  ;; %z and variants.  In normal use, time-stamp-formatz-from-parsed-options
+  ;; is called from a parser that handles all time string formats.
+  (string-match
+   
"\\`\\([^%]*\\)%\\([-_]?\\)\\(0?\\)\\([1-9][0-9]*\\)?\\([EO]?\\)\\(:*\\)\\([^a-zA-Z]+\\)?z\\(.*\\)"
+   format)
+  (let ((leading-string (match-string 1 format))
+        (flag-minimize (seq-find (lambda (x) (eq x ?-))
+                                 (match-string 2 format)))
+        (flag-pad-with-spaces (seq-find (lambda (x) (eq x ?_))
+                                        (match-string 2 format)))
+        (flag-pad-with-zeros (equal (match-string 3 format) "0"))
+        (field-width (string-to-number (or (match-string 4 format) "")))
+        (colon-count (length (match-string 6 format)))
+        (garbage (match-string 7 format))
+        (trailing-string (match-string 8 format)))
+    (concat leading-string
+            (if garbage
+                ""
+              (time-stamp-formatz-from-parsed-options flag-minimize
+                                                      flag-pad-with-spaces
+                                                      flag-pad-with-zeros
+                                                      colon-count
+                                                      field-width
+                                                      offset-secs))
+            trailing-string)))
+
+(defun fz-make+zone (h &optional m s)
+  "Creates a non-negative offset."
+  (let ((m (or m 0))
+        (s (or s 0)))
+    (+ (* 3600 h) (* 60 m) s)))
+
+(defun fz-make-zone (h &optional m s)
+  "Creates a negative offset.  The arguments are all non-negative."
+  (- (fz-make+zone h m s)))
+
+(defmacro formatz-should-equal (zone expect)
+  "Formats ZONE and compares it to EXPECT.
+Uses the free variables `form-string' and `pattern-mod'.
+The functions in `pattern-mod' are composed left to right."
+  `(let ((result ,expect))
+     (dolist (fn pattern-mod)
+       (setq result (funcall fn result)))
+     (should (equal (formatz form-string ,zone) result))))
+
+;; These test cases have zeros in all places (first, last, none, both)
+;; for hours, minutes, and seconds.
+
+(defun formatz-hours-exact-helper (form-string pattern-mod)
+  "Tests format %z with whole hours."
+  (formatz-should-equal (fz-make+zone 0) "+00") ;0 sign always +, both digits
+  (formatz-should-equal (fz-make+zone 10) "+10")
+  (formatz-should-equal (fz-make-zone 10) "-10")
+  (formatz-should-equal (fz-make+zone 2) "+02")
+  (formatz-should-equal (fz-make-zone 2) "-02")
+  (formatz-should-equal (fz-make+zone 13) "+13")
+  (formatz-should-equal (fz-make-zone 13) "-13")
+  )
+
+(defun formatz-nonzero-minutes-helper (form-string pattern-mod)
+  "Tests format %z with whole minutes."
+  (formatz-should-equal (fz-make+zone 0 30) "+00:30") ;has hours even though 0
+  (formatz-should-equal (fz-make-zone 0 30) "-00:30")
+  (formatz-should-equal (fz-make+zone 0 4) "+00:04")
+  (formatz-should-equal (fz-make-zone 0 4) "-00:04")
+  (formatz-should-equal (fz-make+zone 8 40) "+08:40")
+  (formatz-should-equal (fz-make-zone 8 40) "-08:40")
+  (formatz-should-equal (fz-make+zone 0 15) "+00:15")
+  (formatz-should-equal (fz-make-zone 0 15) "-00:15")
+  (formatz-should-equal (fz-make+zone 11 30) "+11:30")
+  (formatz-should-equal (fz-make-zone 11 30) "-11:30")
+  (formatz-should-equal (fz-make+zone 3 17) "+03:17")
+  (formatz-should-equal (fz-make-zone 3 17) "-03:17")
+  (formatz-should-equal (fz-make+zone 12 45) "+12:45")
+  (formatz-should-equal (fz-make-zone 12 45) "-12:45")
+  )
+
+(defun formatz-nonzero-seconds-helper (form-string pattern-mod)
+  "Tests format %z with non-0 seconds."
+  ;; non-0 seconds are always included
+  (formatz-should-equal (fz-make+zone 0 0 50) "+00:00:50")
+  (formatz-should-equal (fz-make-zone 0 0 50) "-00:00:50")
+  (formatz-should-equal (fz-make+zone 0 0 06) "+00:00:06")
+  (formatz-should-equal (fz-make-zone 0 0 06) "-00:00:06")
+  (formatz-should-equal (fz-make+zone 0 7 50) "+00:07:50")
+  (formatz-should-equal (fz-make-zone 0 7 50) "-00:07:50")
+  (formatz-should-equal (fz-make+zone 0 0 16) "+00:00:16")
+  (formatz-should-equal (fz-make-zone 0 0 16) "-00:00:16")
+  (formatz-should-equal (fz-make+zone 0 12 36) "+00:12:36")
+  (formatz-should-equal (fz-make-zone 0 12 36) "-00:12:36")
+  (formatz-should-equal (fz-make+zone 0 3 45) "+00:03:45")
+  (formatz-should-equal (fz-make-zone 0 3 45) "-00:03:45")
+  (formatz-should-equal (fz-make+zone 8 45 30) "+08:45:30")
+  (formatz-should-equal (fz-make-zone 8 45 30) "-08:45:30")
+  (formatz-should-equal (fz-make+zone 0 11 45) "+00:11:45")
+  (formatz-should-equal (fz-make-zone 0 11 45) "-00:11:45")
+  (formatz-should-equal (fz-make+zone 3 20 15) "+03:20:15")
+  (formatz-should-equal (fz-make-zone 3 20 15) "-03:20:15")
+  (formatz-should-equal (fz-make+zone 11 14 30) "+11:14:30")
+  (formatz-should-equal (fz-make-zone 11 14 30) "-11:14:30")
+  (formatz-should-equal (fz-make+zone 12 30 49) "+12:30:49")
+  (formatz-should-equal (fz-make-zone 12 30 49) "-12:30:49")
+  (formatz-should-equal (fz-make+zone 12 0 34) "+12:00:34")
+  (formatz-should-equal (fz-make-zone 12 0 34) "-12:00:34")
+  )
+
+(defun formatz-hours-big-helper (form-string pattern-mod)
+  "Tests format %z with hours that don't fit in two digits."
+  (formatz-should-equal (fz-make+zone 101) "+101:00")
+  (formatz-should-equal (fz-make+zone 123 10) "+123:10")
+  (formatz-should-equal (fz-make-zone 123 10) "-123:10")
+  (formatz-should-equal (fz-make+zone 123 2) "+123:02")
+  (formatz-should-equal (fz-make-zone 123 2) "-123:02")
+  )
+
+(defun formatz-seconds-big-helper (form-string pattern-mod)
+  "Tests format %z with hours greater than 99 and non-zero seconds."
+  (formatz-should-equal (fz-make+zone 123 0 30) "+123:00:30")
+  (formatz-should-equal (fz-make-zone 123 0 30) "-123:00:30")
+  (formatz-should-equal (fz-make+zone 120 0 4) "+120:00:04")
+  (formatz-should-equal (fz-make-zone 120 0 4) "-120:00:04")
+  )
+
+;; Functions that modify the expected output string, so that we can
+;; use the above test cases for multiple formats.
+
+(defun formatz-mod-del-colons (string)
+  "Returns STRING with any colons removed."
+  (replace-regexp-in-string ":" "" string))
+
+(defun formatz-mod-add-00 (string)
+  "Returns STRING with \"00\" appended."
+  (concat string "00"))
+
+(defun formatz-mod-add-colon00 (string)
+  "Returns STRING with \":00\" appended."
+  (concat string ":00"))
+
+(defun formatz-mod-pad-r10 (string)
+  "Returns STRING padded on the right to 10 characters."
+  (concat string (make-string (- 10 (length string)) ?\s)))
+
+(defun formatz-mod-pad-r12 (string)
+  "Returns STRING padded on the right to 12 characters."
+  (concat string (make-string (- 12 (length string)) ?\s)))
+
+;; Convenience macro for generating groups of test cases.
+
+(defmacro formatz-generate-tests
+    (form-strings hour-mod mins-mod secs-mod big-mod secbig-mod)
+  "Defines ert-deftest tests for time formats FORM-STRINGS.
+FORM-STRINGS is a list of formats, each \"%z\" or some variation thereof.
+
+Each of the remaining arguments is an unquoted list of the form
+(SAMPLE-OUTPUT . MODIFIERS).  SAMPLE-OUTPUT is the result of the
+FORM-STRINGS for a particular offset, detailed below for each argument.
+The remaining elements of the list, the MODIFIERS, are the names of
+functions to modify the expected results for sets of tests.
+The MODIFIERS do not modify the SAMPLE-OUTPUT.
+
+The one, literal sample output is given in the call to this macro
+to provide a visual check at the call site that the format
+behaves as expected.
+
+HOUR-MOD is the result for offset 0 and modifiers for the other
+expected results for whole hours.
+MINS-MOD is the result for offset +30 minutes and modifiers for the
+other expected results for whole minutes.
+SECS-MOD is the result for offset +30 seconds and modifiers for the
+other expected results for offsets with non-zero seconds.
+BIG-MOD is the result for offset +100 hours and modifiers for the other
+expected results for hours greater than 99 with a whole number of minutes.
+SECBIG-MOD is the result for offset +100 hours 30 seconds and modifiers for
+the other expected results for hours greater than 99 with non-zero seconds."
+  (declare (indent 1))
+  ;; Generate a form to create a list of tests to define.  When this
+  ;; macro is called, the form is evaluated, thus defining the tests.
+  (let ((ert-test-list '(list)))
+    (dolist (form-string form-strings ert-test-list)
+      (nconc
+       ert-test-list
+       (list
+        `(ert-deftest ,(intern (concat "formatz-" form-string "-hhmm")) ()
+           (should (equal (formatz ,form-string (fz-make+zone 0))
+                          ,(car hour-mod)))
+           (formatz-hours-exact-helper ,form-string ',(cdr hour-mod))
+           (should (equal (formatz ,form-string (fz-make+zone 0 30))
+                          ,(car mins-mod)))
+           (formatz-nonzero-minutes-helper ,form-string ',(cdr mins-mod)))
+        `(ert-deftest ,(intern (concat "formatz-" form-string "-secs")) ()
+           (should (equal (formatz ,form-string (fz-make+zone 0 0 30))
+                          ,(car secs-mod)))
+           (formatz-nonzero-seconds-helper ,form-string ',(cdr secs-mod)))
+        `(ert-deftest ,(intern (concat "formatz-" form-string "-big")) ()
+           (should (equal (formatz ,form-string (fz-make+zone 100))
+                          ,(car big-mod)))
+           (formatz-hours-big-helper ,form-string ',(cdr big-mod))
+           (should (equal (formatz ,form-string (fz-make+zone 100 0 30))
+                          ,(car secbig-mod)))
+           (formatz-seconds-big-helper ,form-string ',(cdr secbig-mod)))
+        )))))
+
+;;;; The actual test cases for %z
+
+;;; %z formats without colons.
+
+;; Option character "-" (minus) minimizes; it removes "00" minutes.
+(formatz-generate-tests ("%-z" "%-3z")
+  ("+00")
+  ("+0030" formatz-mod-del-colons)
+  ("+000030" formatz-mod-del-colons)
+  ("+100:00")
+  ("+100:00:30"))
+;; Tests that minus with padding pads with spaces.
+(formatz-generate-tests ("%-12z")
+  ("+00         " formatz-mod-pad-r12)
+  ("+0030       " formatz-mod-del-colons formatz-mod-pad-r12)
+  ("+000030     " formatz-mod-del-colons formatz-mod-pad-r12)
+  ("+100:00     " formatz-mod-pad-r12)
+  ("+100:00:30  " formatz-mod-pad-r12))
+;; Tests that 0 after other digits becomes padding of ten, not zero flag.
+(formatz-generate-tests ("%-10z")
+  ("+00       " formatz-mod-pad-r10)
+  ("+0030     " formatz-mod-del-colons formatz-mod-pad-r10)
+  ("+000030   " formatz-mod-del-colons formatz-mod-pad-r10)
+  ("+100:00   " formatz-mod-pad-r10)
+  ("+100:00:30"))
+
+;; Although time-stamp doesn't call us for %z, we do want to spot-check
+;; it here, to verify the implementation we will eventually use.
+;; The legacy exception for %z in time-stamp will need to remain
+;; through at least 2024 and Emacs 28.
+(ert-deftest formatz-%z-spotcheck ()
+  (should (equal (format-time-offset "%z" (fz-make+zone 0)) "+0000"))
+  (should (equal (format-time-offset "%z" (fz-make+zone 0 30)) "+0030"))
+  (should (equal (format-time-offset "%z" (fz-make+zone 0 0 30)) "+000030"))
+  (should (equal (format-time-offset "%z" (fz-make+zone 100)) "+100:00"))
+  (should (equal (format-time-offset "%z" (fz-make+zone 100 0 30)) 
"+100:00:30"))
+  )
+
+;; Basic %z outputs 4 digits.
+;; Small padding values do not extend the result.
+(formatz-generate-tests (;; We don't check %z here because time-stamp
+                         ;; has a legacy behavior for it.
+                         ;;"%z"
+                         "%5z" "%0z" "%05z")
+  ("+0000" formatz-mod-add-00)
+  ("+0030" formatz-mod-del-colons)
+  ("+000030" formatz-mod-del-colons)
+  ("+100:00")
+  ("+100:00:30"))
+
+;; Tests that padding adds spaces.
+(formatz-generate-tests ("%12z")
+  ("+0000       " formatz-mod-add-00 formatz-mod-pad-r12)
+  ("+0030       " formatz-mod-del-colons formatz-mod-pad-r12)
+  ("+000030     " formatz-mod-del-colons formatz-mod-pad-r12)
+  ("+100:00     " formatz-mod-pad-r12)
+  ("+100:00:30  " formatz-mod-pad-r12))
+
+;; Requiring 0-padding to 6 adds seconds (only) as needed.
+(formatz-generate-tests ("%06z")
+  ("+000000" formatz-mod-add-00 formatz-mod-add-00)
+  ("+003000" formatz-mod-del-colons formatz-mod-add-00)
+  ("+000030" formatz-mod-del-colons)
+  ("+100:00")
+  ("+100:00:30"))
+
+;; Option character "_" always adds seconds.
+(formatz-generate-tests ("%_z" "%_7z")
+  ("+000000" formatz-mod-add-00 formatz-mod-add-00)
+  ("+003000" formatz-mod-del-colons formatz-mod-add-00)
+  ("+000030" formatz-mod-del-colons)
+  ("+100:00:00" formatz-mod-add-colon00)
+  ("+100:00:30"))
+
+;; Enough 0-padding adds seconds, then adds spaces.
+(formatz-generate-tests ("%012z" "%_12z")
+  ("+000000     " formatz-mod-add-00 formatz-mod-add-00 formatz-mod-pad-r12)
+  ("+003000     " formatz-mod-del-colons formatz-mod-add-00 
formatz-mod-pad-r12)
+  ("+000030     " formatz-mod-del-colons formatz-mod-pad-r12)
+  ("+100:00:00  " formatz-mod-add-colon00 formatz-mod-pad-r12)
+  ("+100:00:30  " formatz-mod-pad-r12))
+
+;;; %z formats with colons
+
+;; Three colons can output hours only,
+;; like %-z, but uses colons with non-zero minutes and seconds.
+(formatz-generate-tests ("%:::z" "%0:::z"
+                         "%3:::z" "%03:::z")
+  ("+00")
+  ("+00:30")
+  ("+00:00:30")
+  ("+100:00")
+  ("+100:00:30"))
+
+;; Padding with three colons adds spaces
+(formatz-generate-tests ("%12:::z")
+  ("+00         " formatz-mod-pad-r12)
+  ("+00:30      " formatz-mod-pad-r12)
+  ("+00:00:30   " formatz-mod-pad-r12)
+  ("+100:00     " formatz-mod-pad-r12)
+  ("+100:00:30  " formatz-mod-pad-r12))
+;; Tests that 0 after other digits becomes padding of ten, not zero flag.
+(formatz-generate-tests ("%10:::z")
+  ("+00       " formatz-mod-pad-r10)
+  ("+00:30    " formatz-mod-pad-r10)
+  ("+00:00:30 " formatz-mod-pad-r10)
+  ("+100:00   " formatz-mod-pad-r10)
+  ("+100:00:30"))
+
+;; One colon outputs minutes, like %z but with colon.
+(formatz-generate-tests ("%:z" "%6:z" "%0:z" "%06:z" "%06:::z")
+  ("+00:00" formatz-mod-add-colon00)
+  ("+00:30")
+  ("+00:00:30")
+  ("+100:00")
+  ("+100:00:30"))
+
+;; Padding with one colon adds spaces
+(formatz-generate-tests ("%12:z")
+  ("+00:00      " formatz-mod-add-colon00 formatz-mod-pad-r12)
+  ("+00:30      " formatz-mod-pad-r12)
+  ("+00:00:30   " formatz-mod-pad-r12)
+  ("+100:00     " formatz-mod-pad-r12)
+  ("+100:00:30  " formatz-mod-pad-r12))
+
+;; Requiring 0-padding to 7 adds seconds (only) as needed.
+(formatz-generate-tests ("%07:z" "%07:::z")
+  ("+00:00:00" formatz-mod-add-colon00 formatz-mod-add-colon00)
+  ("+00:30:00" formatz-mod-add-colon00)
+  ("+00:00:30")
+  ("+100:00")
+  ("+100:00:30"))
+
+;; Two colons outputs HH:MM:SS, like %_z but with colons.
+(formatz-generate-tests ("%::z" "%9::z" "%0::z" "%09::z")
+  ("+00:00:00" formatz-mod-add-colon00 formatz-mod-add-colon00)
+  ("+00:30:00" formatz-mod-add-colon00)
+  ("+00:00:30")
+  ("+100:00:00" formatz-mod-add-colon00)
+  ("+100:00:30"))
+
+;; Enough padding adds minutes and seconds, then adds spaces.
+(formatz-generate-tests ("%012:z" "%012::z" "%12::z" "%012:::z")
+  ("+00:00:00   " formatz-mod-add-colon00 formatz-mod-add-colon00
+                  formatz-mod-pad-r12)
+  ("+00:30:00   " formatz-mod-add-colon00 formatz-mod-pad-r12)
+  ("+00:00:30   " formatz-mod-pad-r12)
+  ("+100:00:00  " formatz-mod-add-colon00 formatz-mod-pad-r12)
+  ("+100:00:30  " formatz-mod-pad-r12))
+
+;;; Illegal %z formats
+
+(ert-deftest formatz-illegal-options ()
+  "Tests that illegal/nonsensical/ambiguous %z formats don't produce output."
+  ;; multiple options
+  (should (equal "" (formatz "%_-z" 0)))
+  (should (equal "" (formatz "%-_z" 0)))
+  (should (equal "" (formatz "%_0z" 0)))
+  (should (equal "" (formatz "%0_z" 0)))
+  (should (equal "" (formatz "%0-z" 0)))
+  (should (equal "" (formatz "%-0z" 0)))
+  ;; inconsistent to both minimize and require mins or secs
+  (should (equal "" (formatz "%-:z" 0)))
+  (should (equal "" (formatz "%-::z" 0)))
+  ;; consistent, but redundant
+  (should (equal "" (formatz "%-:::z" 0)))
+  (should (equal "" (formatz "%_::z" 0)))
+  ;; inconsistent to both pre-expand and default to hours or mins
+  (should (equal "" (formatz "%_:::z" 0)))
+  (should (equal "" (formatz "%_:z" 0)))
+  ;; options that don't make sense with %z
+  (should (equal "" (formatz "%#z" 0)))
+  )
+
 ;;; time-stamp-tests.el ends here



reply via email to

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