emacs-diffs
[Top][All Lists]
Advanced

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

feature/native-comp 2a8bf22: Merge remote-tracking branch 'savannah/mast


From: Andrea Corallo
Subject: feature/native-comp 2a8bf22: Merge remote-tracking branch 'savannah/master' into dev
Date: Sat, 14 Nov 2020 16:35:27 -0500 (EST)

branch: feature/native-comp
commit 2a8bf2222dd5d786375c131aa13dd1ea6f0cf104
Merge: f702426 ad29bc7
Author: Andrea Corallo <akrl@sdf.org>
Commit: Andrea Corallo <akrl@sdf.org>

    Merge remote-tracking branch 'savannah/master' into dev
---
 .gitignore                                         |   1 +
 admin/make-tarball.txt                             |  12 +-
 admin/release-process                              |   5 +-
 configure.ac                                       |  21 +-
 doc/emacs/basic.texi                               |   6 +
 doc/emacs/windows.texi                             |   4 +-
 doc/misc/erc.texi                                  |   4 +-
 doc/misc/widget.texi                               |  19 +-
 etc/NEWS                                           |  34 +++
 lisp/align.el                                      |   5 +-
 lisp/allout-widgets.el                             |  28 +-
 lisp/ansi-color.el                                 |  50 ++--
 lisp/bookmark.el                                   |   3 +-
 lisp/calc/calc.el                                  |  12 +-
 lisp/calendar/timeclock.el                         |   2 -
 lisp/case-table.el                                 |  40 +--
 lisp/cedet/semantic.el                             |   2 -
 lisp/dired-aux.el                                  |   2 +-
 lisp/disp-table.el                                 |   2 -
 lisp/doc-view.el                                   |  21 +-
 lisp/ehelp.el                                      |   1 -
 lisp/emacs-lisp/advice.el                          |  28 +-
 lisp/emacs-lisp/byte-opt.el                        |   8 +-
 lisp/emacs-lisp/checkdoc.el                        |   1 -
 lisp/emacs-lisp/edebug.el                          |   1 -
 lisp/emacs-lisp/lisp-mode.el                       |   4 +-
 lisp/emacs-lisp/rx.el                              |   2 +-
 lisp/emacs-lisp/shortdoc.el                        |   4 +-
 lisp/faces.el                                      |   2 +-
 lisp/filesets.el                                   |   2 +-
 lisp/foldout.el                                    |  25 +-
 lisp/gnus/gnus-agent.el                            |  10 +-
 lisp/gnus/gnus-bookmark.el                         |   3 +-
 lisp/gnus/gnus-group.el                            |  26 +-
 lisp/gnus/gnus-search.el                           | 106 +++++---
 lisp/gnus/nnselect.el                              |  10 +-
 lisp/help.el                                       |   4 +-
 lisp/hippie-exp.el                                 |  28 +-
 lisp/international/mule-cmds.el                    |  16 +-
 lisp/international/mule-conf.el                    |   4 +-
 lisp/international/mule.el                         |  11 +-
 lisp/international/quail.el                        |  28 +-
 lisp/international/ucs-normalize.el                |   2 +-
 lisp/jka-compr.el                                  |  10 +-
 lisp/leim/quail/compose.el                         |  26 ++
 lisp/leim/quail/latin-ltx.el                       |   2 +-
 lisp/loadup.el                                     |   2 +-
 lisp/locate.el                                     |  10 +-
 lisp/mail/mailabbrev.el                            |  20 +-
 lisp/mail/reporter.el                              |   1 -
 lisp/mail/rfc822.el                                |  10 +-
 lisp/mail/uudecode.el                              |  36 ++-
 lisp/mh-e/mh-seq.el                                |   6 +-
 lisp/net/eudcb-ldap.el                             |  19 +-
 lisp/net/eww.el                                    |   2 +-
 lisp/net/net-utils.el                              |   5 +-
 lisp/net/newsticker.el                             |   8 -
 lisp/net/rfc2104.el                                |   2 -
 lisp/net/sieve-mode.el                             |   5 -
 lisp/net/socks.el                                  |   9 +-
 lisp/net/tramp-adb.el                              |   5 +-
 lisp/net/tramp-gvfs.el                             |  23 +-
 lisp/net/tramp-integration.el                      |   2 +-
 lisp/net/tramp-sh.el                               |   3 +-
 lisp/net/tramp-smb.el                              |   5 +-
 lisp/net/tramp.el                                  |   5 +-
 lisp/net/webjump.el                                |   1 -
 lisp/obsolete/nnir.el                              |  30 +--
 lisp/org/ob-ruby.el                                |  12 +-
 lisp/org/org-element.el                            |   4 +-
 lisp/org/ox-odt.el                                 |   8 +-
 lisp/pcomplete.el                                  |  15 +-
 lisp/pixel-scroll.el                               |   3 +-
 lisp/play/bubbles.el                               |   7 -
 lisp/play/fortune.el                               |  68 +++--
 lisp/play/handwrite.el                             |  12 +-
 lisp/progmodes/cc-align.el                         |   6 +-
 lisp/progmodes/cc-cmds.el                          |   3 +-
 lisp/progmodes/cc-defs.el                          |   5 +-
 lisp/progmodes/cc-engine.el                        |  71 ++---
 lisp/progmodes/cc-mode.el                          |   2 +-
 lisp/progmodes/cperl-mode.el                       |  53 ++--
 lisp/progmodes/make-mode.el                        |  33 ++-
 lisp/progmodes/project.el                          |  10 +-
 lisp/progmodes/python.el                           |  26 +-
 lisp/progmodes/ruby-mode.el                        |   9 +-
 lisp/progmodes/vhdl-mode.el                        |  11 +-
 lisp/progmodes/xref.el                             |   6 +-
 lisp/server.el                                     | 104 +++++---
 lisp/shadowfile.el                                 |  31 +--
 lisp/sort.el                                       |  60 ++---
 lisp/speedbar.el                                   |   4 +-
 lisp/strokes.el                                    |   5 +-
 lisp/subr.el                                       |  68 ++---
 lisp/tar-mode.el                                   |   7 -
 lisp/tempo.el                                      |  21 +-
 lisp/term/ns-win.el                                |   5 +-
 lisp/term/wyse50.el                                |   6 +-
 lisp/textmodes/artist.el                           |   7 +-
 lisp/textmodes/ispell.el                           |  37 ++-
 lisp/textmodes/page-ext.el                         |  21 +-
 lisp/textmodes/refer.el                            |   6 +-
 lisp/url/url-auth.el                               |  26 +-
 lisp/url/url-cache.el                              |  23 +-
 lisp/url/url-expand.el                             |   8 +-
 lisp/vc/log-view.el                                |  14 +-
 lisp/vc/vc-hg.el                                   |   7 +-
 lisp/vc/vc.el                                      |   4 +-
 lisp/vcursor.el                                    |  17 +-
 lisp/whitespace.el                                 |  13 -
 lisp/window.el                                     |   8 +-
 lisp/xt-mouse.el                                   |   7 +
 src/alloc.c                                        |  17 ++
 src/bidi.c                                         |  12 +
 src/dispextern.h                                   |   1 +
 src/dispnew.c                                      |  52 ++++
 src/doc.c                                          |  40 +--
 src/doprnt.c                                       |   8 +-
 src/editfns.c                                      |  13 +-
 src/image.c                                        | 121 ++++++++-
 src/keymap.c                                       |   2 +-
 src/lisp.h                                         |  12 -
 src/minibuf.c                                      |   7 +-
 src/nsterm.m                                       |  23 +-
 src/pdumper.c                                      |   2 +-
 src/process.c                                      |  26 +-
 src/term.c                                         |  52 +---
 src/w32fns.c                                       |  27 +-
 src/xdisp.c                                        |  17 +-
 src/xwidget.c                                      |  10 +
 test/lisp/ansi-color-tests.el                      |  49 ++++
 test/lisp/emacs-lisp/rx-tests.el                   |   8 +-
 test/lisp/help-fns-tests.el                        |   3 +-
 test/lisp/help-tests.el                            |  15 +-
 test/lisp/hfy-cmap-resources/rgb.txt               |   1 +
 test/lisp/net/tramp-tests.el                       |  15 +-
 test/lisp/play/fortune-resources/fortunes          |  11 +
 test/lisp/play/fortune-tests.el                    |  41 +++
 .../cperl-mode-resources/cperl-bug-19709.pl        |  25 ++
 .../cperl-mode-resources/cperl-indent-styles.pl    |  10 +
 test/lisp/progmodes/cperl-mode-tests.el            | 296 +++++++++++----------
 test/lisp/textmodes/reftex-tests.el                |  35 ++-
 test/src/keymap-tests.el                           |   4 -
 143 files changed, 1550 insertions(+), 1124 deletions(-)

diff --git a/.gitignore b/.gitignore
index 638d541..b152243 100644
--- a/.gitignore
+++ b/.gitignore
@@ -154,6 +154,7 @@ test/manual/etags/ETAGS
 test/manual/etags/CTAGS
 test/manual/indent/*.new
 test/lisp/gnus/mml-sec-resources/random_seed
+test/lisp/play/fortune-resources/fortunes.dat
 
 # ctags, etags.
 TAGS
diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt
index 64c6170..2c81a49 100644
--- a/admin/make-tarball.txt
+++ b/admin/make-tarball.txt
@@ -87,10 +87,14 @@ General steps (for each step, check for possible errors):
      make -C etc/refcards
      make -C etc/refcards clean
 
-    If some of the non-English etc/refcards fail to build, you
-    probably need to install some TeX foreign language packages.
-    For more information, search for the string "refcard" in the file
-    admin/release-process.
+    If some of the etc/refcards, especially the non-English ones, fail
+    to build, you probably need to install some TeX/LaTeX packages, in
+    particular for foreign language support.  For more information,
+    search for the string "refcard" in the file admin/release-process.
+
+    (ru-refcard causes numerous "Underfull hbox" and "Overfull hbox"
+    messages from TeX, but those seem to be harmless, as the result
+    looks just fine.)
 
 5.  Copy lisp/loaddefs.el to lisp/ldefs-boot.el.
 
diff --git a/admin/release-process b/admin/release-process
index 4d973d3..ef698f5 100644
--- a/admin/release-process
+++ b/admin/release-process
@@ -179,8 +179,9 @@ What paper size are the English versions supposed to be on?
 On Debian testing, the packages texlive-lang-czechslovak and
 texlive-lang-polish will let you generate the cs-* and sk-* pdfs.
 (You may need texlive-lang-cyrillic, texlive-lang-german,
-and texlive-fonts-extra for others.)  On Fedora-like systems,
-texlive-lh may help.
+and texlive-fonts-extra for others.)  Gnus refcards need
+texlive-latex-extra and/or texlive-latex-recommended.  On Fedora-like
+systems, texlive-lh may help.
 
 ** Ask maintainers of refcard translations to update them.
 
diff --git a/configure.ac b/configure.ac
index 100fbba..e3a96a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3447,16 +3447,17 @@ else # "${HAVE_X11}" != "yes"
 fi   # "${HAVE_X11}" != "yes"
 
 HAVE_HARFBUZZ=no
+### On MS-Windows we use hb_font_get_nominal_glyph, which appeared
+### in HarfBuzz version 1.2.3
+if test "${HAVE_W32}" = "yes"; then
+  harfbuzz_required_ver=1.2.3
+else
+  harfbuzz_required_ver=0.9.42
+fi
 if test "${HAVE_X11}" = "yes" && test "${HAVE_FREETYPE}" = "yes" \
         || test "${HAVE_W32}" = "yes"; then
   if test "${with_harfbuzz}" != "no"; then
-    ### On MS-Windows we use hb_font_get_nominal_glyph, which appeared
-    ### in HarfBuzz version 1.2.3
-    if test "${HAVE_W32}" = "yes"; then
-      EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= 1.2.3])
-    else
-      EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= 0.9.42])
-    fi
+    EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= $harfbuzz_required_ver])
     if test "$HAVE_HARFBUZZ" = "yes"; then
       AC_DEFINE(HAVE_HARFBUZZ, 1, [Define to 1 if using HarfBuzz.])
       ### mingw32 and Cygwin-w32 don't use -lharfbuzz, since they load
@@ -6026,9 +6027,9 @@ fi
 
 if test "${HAVE_CAIRO}" = "yes" && test "${HAVE_HARFBUZZ}" = no; then
   AC_MSG_WARN([This configuration uses the Cairo graphics library,
-    but not the HarfBuzz font shaping library.  We recommend the use
-    of HarfBuzz when using Cairo, please install HarfBuzz development
-    packages.])
+    but not the HarfBuzz font shaping library (minimum version 
$harfbuzz_required_ver).
+    We recommend the use of HarfBuzz when using Cairo, please install
+    appropriate HarfBuzz development packages.])
 fi
 
 # Let plain 'make' work.
diff --git a/doc/emacs/basic.texi b/doc/emacs/basic.texi
index 2e03d0c..cd1ffbe 100644
--- a/doc/emacs/basic.texi
+++ b/doc/emacs/basic.texi
@@ -145,6 +145,12 @@ the buffer.
   A numeric argument to @kbd{C-q} or @kbd{C-x 8 ...} specifies
 how many copies of the character to insert (@pxref{Arguments}).
 
+  As an alternative to @kbd{C-x 8}, you can select the corresponding
+transient input method by typing @kbd{C-u C-x \ iso-transl @key{RET}},
+then temporarily activating this transient input method by typing
+@kbd{C-x \ [} will insert the same character @t{‘} (@pxref{transient
+input method}).
+
   In addition, in some contexts, if you type a quotation using grave
 accent and apostrophe @kbd{`like this'}, it is converted to a form
 @t{‘like this’} using single quotation marks, even without @kbd{C-x 8}
diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index bc1dcd7..07f8269 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -589,7 +589,7 @@ buffer.  @xref{Follow Mode}.
 @findex windmove-default-keybindings
 @findex windmove-display-default-keybindings
 @findex windmove-delete-default-keybindings
-@findex windmove-swap-states-in-direction
+@findex windmove-swap-states-default-keybindings
   The Windmove package defines commands for moving directionally
 between neighboring windows in a frame.  @kbd{M-x windmove-right}
 selects the window immediately to the right of the currently selected
@@ -603,7 +603,7 @@ keybindings for commands that specify in what direction to 
display the
 window for the buffer that the next command is going to display.
 Also there is @w{@kbd{M-x windmove-delete-default-keybindings}} to
 define keybindings for commands that delete windows directionally, and
-@w{@kbd{M-x windmove-swap-states-in-direction}} that define
+@w{@kbd{M-x windmove-swap-states-default-keybindings}} that defines
 keybindings for commands that swap the window contents of the selected
 window with the window in the specified direction.
 
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index cb2e832..c39d2f9 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -284,8 +284,8 @@ Complete the given word, using ispell.
 @item C-c C-a (@code{erc-bol})
 Go to beginning of line or end of prompt.
 
-@item C-c C-b (@code{erc-iswitchb})
-Use @code{iswitchb-read-buffer} to prompt for a ERC buffer to switch to.
+@item C-c C-b (@code{erc-switch-to-buffer})
+Use @code{read-buffer} to prompt for a ERC buffer to switch to.
 
 @item C-c C-c (@code{erc-toggle-interpret-controls})
 Toggle interpretation of control sequences in messages.
diff --git a/doc/misc/widget.texi b/doc/misc/widget.texi
index 3ce27a1..83a6c4c 100644
--- a/doc/misc/widget.texi
+++ b/doc/misc/widget.texi
@@ -484,9 +484,21 @@ are interpreted in a widget specific way.
 The following keyword arguments apply to all widgets:
 
 @table @code
+@cindex internal format
+@cindex external format
 @vindex value@r{ keyword}
 @item :value
-The initial value for widgets of this type.
+The initial value for widgets of this type.  Typically, a widget
+represents its value in two formats: external and internal.  The
+external format is the value as the rest of Emacs sees it, and the
+internal format is a representation that the widget defines and uses
+in a widget specific way.
+
+Both formats might be the same for certain widgets and might differ
+for others, and there is no guarantee about which format the value
+stored in the @code{:value} property has.  However, when creating a
+widget or defining a new one (@pxref{Defining New Widgets}), the
+@code{:value} should be in the external format.
 
 @vindex format@r{ keyword}
 @item :format
@@ -629,8 +641,9 @@ representation of the @code{:value} property if not.
 
 @vindex match@r{ keyword}
 @item :match
-Should be a function called with two arguments, the widget and a value,
-and returning non-@code{nil} if the widget can represent the specified value.
+Should be a function called with two arguments, the widget and an
+external value, and should return non-@code{nil} if the widget can
+represent the specified value.
 
 @vindex validate@r{ keyword}
 @item :validate
diff --git a/etc/NEWS b/etc/NEWS
index 8b5acaf..7aa5488 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -436,6 +436,11 @@ their 'default-directory' under VC.
 *** New command 'vc-dir-root' uses the root directory without asking.
 
 ---
+*** New face 'log-view-commit-body'.
+This is used when expanding commit messages from 'vc-print-root-log'
+and similar commands.
+
+---
 *** The responsible VC backend is now the most specific one.
 'vc-responsible-backend' loops over the backends in
 'vc-handled-backends' to determine which backend is responsible for a
@@ -659,6 +664,13 @@ to the search string.
 *** New input method 'compose' based on X Multi_key sequences.
 
 ---
+*** New input method 'iso-transl' with the same keys as 'C-x 8'.
+After selecting it as a transient input method with 'C-u C-x \
+iso-transl RET', it supports the same key sequences as 'C-x 8',
+so e.g. like 'C-x 8 [' inserts a left single quotation mark,
+'C-x \ [' does the same.
+
+---
 *** Improved language transliteration in Malayalam input methods.
 Added a new Mozhi scheme.  The inapplicable ITRANS scheme is now
 deprecated.  Errors in the Inscript method were corrected.
@@ -1122,6 +1134,13 @@ project's root directory, respectively.
 +++
 *** New user option 'project-list-file'.
 
+** xref
+
+---
+*** Prefix arg of 'xref-goto-xref' quits the *xref* buffer.
+So typing 'C-u RET' in the *xref* buffer quits its window
+before navigating to the selected location.
+
 ** json.el
 
 ---
@@ -1238,6 +1257,11 @@ and the result is not truncated in any way.
 *** The '/' operator now has higher precedence in (La)TeX input mode.
 It no longer has lower precedence than '+' and '-'.
 
+---
+*** Calc now marks its windows dedicated.
+The new user option 'calc-make-windows-dedicated' controls this.  It
+is t by default; set to nil to get back the old behavior.
+
 ** term-mode
 
 ---
@@ -1310,6 +1334,11 @@ If 'tab-always-indent' is 'complete', this new user 
option can be used to
 further tweak whether to complete or indent.
 
 ---
+*** 'dired-query' now uses 'read-char-from-minibuffer'.
+Using it instead of 'read-char-choice' allows using 'C-x o'
+to switch to the help window displayed after typing 'C-h'.
+
+---
 *** 'zap-up-to-char' now uses 'read-char-from-minibuffer'.
 This allows navigating through the history of characters that have
 been input.  This is mostly useful for characters that have complex
@@ -1957,6 +1986,11 @@ image API via 'M-x report-emacs-bug'.
 ---
 ** The user option 'make-pointer-invisible' is now honored on macOS.
 
+--
+** On macOS, 's-<left>' and 's-<right>' are now bound to
+'move-beginning-of-line' and 'move-end-of-line' respectively. The commands
+to select previous/next frame are still bound to 's-~' and 's-`'.
+
 
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/lisp/align.el b/lisp/align.el
index e3bdf77..b2cab1c 100644
--- a/lisp/align.el
+++ b/lisp/align.el
@@ -1004,9 +1004,8 @@ to be colored."
         (completing-read
          "Title of rule to highlight: "
          (mapcar
-          (function
-           (lambda (rule)
-             (list (symbol-name (car rule)))))
+           (lambda (rule)
+             (list (symbol-name (car rule))))
           (append (or align-mode-rules-list align-rules-list)
                   (or align-mode-exclude-rules-list
                       align-exclude-rules-list))) nil t)))
diff --git a/lisp/allout-widgets.el b/lisp/allout-widgets.el
index ac49d3b..7e79577 100644
--- a/lisp/allout-widgets.el
+++ b/lisp/allout-widgets.el
@@ -916,15 +916,15 @@ posting threshold criteria."
           (let ((min (point-max))
                 (max 0)
                 first second)
-            (mapc (function (lambda (entry)
-                              (if (eq :undone-exposure (car entry))
-                                  nil
-                                (setq first (cadr entry)
-                                      second (caddr entry))
-                                (if (< (min first second) min)
-                                    (setq min (min first second)))
-                                (if (> (max first second) max)
-                                    (setq max (max first second))))))
+            (mapc (lambda (entry)
+                    (if (eq :undone-exposure (car entry))
+                        nil
+                      (setq first (cadr entry)
+                            second (caddr entry))
+                      (if (< (min first second) min)
+                          (setq min (min first second)))
+                      (if (> (max first second) max)
+                          (setq max (max first second)))))
                     allout-widgets-changes-record)
             (> (- max min) allout-widgets-adjust-message-size-threshold)))
       (let ((prior (current-message)))
@@ -975,8 +975,8 @@ Records changes in `allout-widgets-changes-record'."
 
 Generally invoked via `allout-exposure-change-functions'."
 
-  (let ((changes (sort changes (function (lambda (this next)
-                                           (< (cadr this) (cadr next))))))
+  (let ((changes (sort changes (lambda (this next)
+                                 (< (cadr this) (cadr next)))))
         ;; have to distinguish between concealing and exposing so that, eg,
         ;; `allout-expose-topic's mix is handled properly.
         handled-expose
@@ -2301,9 +2301,9 @@ The elements of LIST are not copied, just the list 
structure itself."
         end (or end (point-max)))
   (if (> start end) (let ((interim start)) (setq start end end interim)))
   (let ((button-overlays (delq nil
-                               (mapcar (function (lambda (o)
-                                                   (if (overlay-get o 'button)
-                                                       o)))
+                               (mapcar (lambda (o)
+                                         (if (overlay-get o 'button)
+                                             o))
                                        (overlays-in start end)))))
     (length button-overlays)))
 
diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el
index d20260b..d5432a6 100644
--- a/lisp/ansi-color.el
+++ b/lisp/ansi-color.el
@@ -363,7 +363,7 @@ it will override BEGIN, the start of the region.  Set
          (setq ansi-color-context-region (list nil (match-beginning 0)))
        (setq ansi-color-context-region nil)))))
 
-(defun ansi-color-apply-on-region (begin end)
+(defun ansi-color-apply-on-region (begin end &optional preserve-sequences)
   "Translates SGR control sequences into overlays or extents.
 Delete all other control sequences without processing them.
 
@@ -380,18 +380,28 @@ ansi codes.  This information will be used for the next 
call to
 `ansi-color-apply-on-region'.  Specifically, it will override
 BEGIN, the start of the region and set the face with which to
 start.  Set `ansi-color-context-region' to nil if you don't want
-this."
+this.
+
+If PRESERVE-SEQUENCES is t, the sequences are hidden instead of
+being deleted."
   (let ((codes (car ansi-color-context-region))
-       (start-marker (or (cadr ansi-color-context-region)
-                         (copy-marker begin)))
-       (end-marker (copy-marker end)))
+        (start-marker (or (cadr ansi-color-context-region)
+                          (copy-marker begin)))
+        (end-marker (copy-marker end)))
     (save-excursion
       (goto-char start-marker)
       ;; Find the next escape sequence.
       (while (re-search-forward ansi-color-control-seq-regexp end-marker t)
-        ;; Remove escape sequence.
-        (let ((esc-seq (delete-and-extract-region
+        ;; Extract escape sequence.
+        (let ((esc-seq (buffer-substring
                         (match-beginning 0) (point))))
+          (if preserve-sequences
+              ;; Make the escape sequence transparent.
+              (overlay-put (make-overlay (match-beginning 0) (point))
+                           'invisible t)
+            ;; Otherwise, strip.
+            (delete-region (match-beginning 0) (point)))
+
           ;; Colorize the old block from start to end using old face.
           (funcall ansi-color-apply-face-function
                    (prog1 (marker-position start-marker)
@@ -572,27 +582,27 @@ The face definitions are based upon the variables
         (index 0))
     ;; miscellaneous attributes
     (mapc
-     (function (lambda (e)
-                 (aset map index e)
-                 (setq index (1+ index)) ))
+     (lambda (e)
+       (aset map index e)
+       (setq index (1+ index)) )
      ansi-color-faces-vector)
     ;; foreground attributes
     (setq index 30)
     (mapc
-     (function (lambda (e)
-                 (aset map index
-                      (ansi-color-make-face 'foreground
-                                             (if (consp e) (car e) e)))
-                 (setq index (1+ index)) ))
+     (lambda (e)
+       (aset map index
+             (ansi-color-make-face 'foreground
+                         (if (consp e) (car e) e)))
+       (setq index (1+ index)) )
      ansi-color-names-vector)
     ;; background attributes
     (setq index 40)
     (mapc
-     (function (lambda (e)
-                 (aset map index
-                      (ansi-color-make-face 'background
-                                             (if (consp e) (cdr e) e)))
-                 (setq index (1+ index)) ))
+     (lambda (e)
+       (aset map index
+             (ansi-color-make-face 'background
+                         (if (consp e) (cdr e) e)))
+       (setq index (1+ index)) )
      ansi-color-names-vector)
     map))
 
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index ab7b04d..d703458 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -1065,8 +1065,7 @@ it to the name of the bookmark currently being set, 
advancing
 If `bookmark-sort-flag' is non-nil, then return a sorted copy of the alist."
   (if bookmark-sort-flag
       (sort (copy-alist bookmark-alist)
-            (function
-             (lambda (x y) (string-lessp (car x) (car y)))))
+            (lambda (x y) (string-lessp (car x) (car y))))
     bookmark-alist))
 
 
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index bde7bd4..5716189 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -1435,6 +1435,12 @@ commands given here will actually operate on the 
*Calculator* stack."
     (require 'calc-ext)
     (calc-set-language calc-language calc-language-option t)))
 
+(defcustom calc-make-windows-dedicated t
+  "If non-nil, windows displaying Calc buffers will be marked dedicated.
+See `window-dedicated-p' for what that means."
+  :version "28.1"
+  :type 'boolean)
+
 ;;;###autoload
 (defun calc (&optional arg full-display interactive)
   "The Emacs Calculator.  Full documentation is listed under `calc-mode'."
@@ -1480,6 +1486,8 @@ commands given here will actually operate on the 
*Calculator* stack."
       (and (windowp full-display)
            (window-point full-display)
            (select-window full-display))
+      (and calc-make-windows-dedicated
+           (set-window-dedicated-p nil t))
       (calc-check-defines)
       (when (and calc-said-hello interactive)
         (sit-for 2)
@@ -2140,7 +2148,9 @@ the United States."
               (if calc-trail-window-hook
                   (run-hooks 'calc-trail-window-hook)
                 (let ((w (split-window nil (/ (* (window-width) 2) 3) t)))
-                  (set-window-buffer w calc-trail-buffer)))
+                  (set-window-buffer w calc-trail-buffer)
+                  (and calc-make-windows-dedicated
+                       (set-window-dedicated-p nil t))))
               (calc-wrapper
                (setq overlay-arrow-string calc-trail-overlay
                      overlay-arrow-position calc-trail-pointer)
diff --git a/lisp/calendar/timeclock.el b/lisp/calendar/timeclock.el
index a26da26..48028dd 100644
--- a/lisp/calendar/timeclock.el
+++ b/lisp/calendar/timeclock.el
@@ -37,8 +37,6 @@
 ;; You'll probably want to bind the timeclock commands to some handy
 ;; keystrokes.  At the moment, C-x t is unused:
 ;;
-;;   (require 'timeclock)
-;;
 ;;   (define-key ctl-x-map "ti" 'timeclock-in)
 ;;   (define-key ctl-x-map "to" 'timeclock-out)
 ;;   (define-key ctl-x-map "tc" 'timeclock-change)
diff --git a/lisp/case-table.el b/lisp/case-table.el
index 7379f37..bdfe5c2 100644
--- a/lisp/case-table.el
+++ b/lisp/case-table.el
@@ -38,26 +38,26 @@
   (interactive)
   (let ((description (make-char-table 'case-table)))
     (map-char-table
-     (function (lambda (key value)
-                (if (not (natnump value))
-                    (if (consp key)
-                        (set-char-table-range description key "case-invariant")
-                      (aset description key "case-invariant"))
-                  (let (from to)
-                    (if (consp key)
-                        (setq from (car key) to (cdr key))
-                      (setq from (setq to key)))
-                    (while (<= from to)
-                      (aset
-                       description from
-                       (cond ((/= from (downcase from))
-                              (concat "uppercase, matches "
-                                      (char-to-string (downcase from))))
-                             ((/= from (upcase from))
-                              (concat "lowercase, matches "
-                                      (char-to-string (upcase from))))
-                             (t "case-invariant")))
-                      (setq from (1+ from)))))))
+     (lambda (key value)
+       (if (not (natnump value))
+           (if (consp key)
+               (set-char-table-range description key "case-invariant")
+             (aset description key "case-invariant"))
+         (let (from to)
+           (if (consp key)
+               (setq from (car key) to (cdr key))
+             (setq from (setq to key)))
+           (while (<= from to)
+             (aset
+              description from
+              (cond ((/= from (downcase from))
+                     (concat "uppercase, matches "
+                             (char-to-string (downcase from))))
+                    ((/= from (upcase from))
+                     (concat "lowercase, matches "
+                             (char-to-string (upcase from))))
+                    (t "case-invariant")))
+             (setq from (1+ from))))))
      (current-case-table))
     (save-excursion
      (with-output-to-temp-buffer "*Help*"
diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el
index 71321e1..1be0e33 100644
--- a/lisp/cedet/semantic.el
+++ b/lisp/cedet/semantic.el
@@ -978,7 +978,6 @@ Prevent this load system from loading files in twice.")
     global-semanticdb-minor-mode
     global-semantic-idle-summary-mode
     global-semantic-mru-bookmark-mode
-    global-cedet-m3-minor-mode
     global-semantic-idle-local-symbol-highlight-mode
     global-semantic-highlight-edits-mode
     global-semantic-show-unmatched-syntax-mode
@@ -1000,7 +999,6 @@ The possible elements of this list include the following:
  `global-semantic-stickyfunc-mode'     - Show current fun in header line.
  `global-semantic-mru-bookmark-mode'   - Provide `switch-to-buffer'-like
                                          keybinding for tag names.
- `global-cedet-m3-minor-mode'          - A mouse 3 context menu.
  `global-semantic-idle-local-symbol-highlight-mode' - Highlight references
                                          of the symbol under point.
 The following modes are more targeted at people who want to see
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 6034d12..94a2bbf 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1380,7 +1380,7 @@ return t; if SYM is q or ESC, return nil."
                             (format " [Type yn!q or %s] "
                                     (key-description (vector help-char)))
                           " [Type y, n, q or !] ")))
-          (set sym (setq char (read-char-choice prompt char-choices)))
+          (set sym (setq char (read-char-from-minibuffer prompt char-choices)))
           (if (memq char '(?y ?\s ?!)) t)))))
 
 
diff --git a/lisp/disp-table.el b/lisp/disp-table.el
index 2e88d35..70343a3 100644
--- a/lisp/disp-table.el
+++ b/lisp/disp-table.el
@@ -220,8 +220,6 @@ for a graphical frame."
 ;;;###autoload
 (defun make-glyph-code (char &optional face)
   "Return a glyph code representing char CHAR with face FACE."
-  ;; Due to limitations on Emacs integer values, faces with
-  ;; face id greater than 512 are silently ignored.
   (if (not face)
       char
     (let ((fid (face-id face)))
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 02d8965..9997c1a 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1,4 +1,4 @@
-;;; doc-view.el --- View PDF/PostScript/DVI files in Emacs -*- 
lexical-binding: t -*-
+;;; doc-view.el --- Document viewer for Emacs -*- lexical-binding: t -*-
 
 ;; Copyright (C) 2007-2020 Free Software Foundation, Inc.
 ;;
@@ -22,17 +22,20 @@
 
 ;;; Requirements:
 
-;; doc-view.el requires GNU Emacs 22.1 or newer.  You also need Ghostscript,
-;; `dvipdf' (comes with Ghostscript) or `dvipdfm' (comes with teTeX or TeXLive)
-;; and `pdftotext', which comes with xpdf (https://www.foolabs.com/xpdf/) or
-;; poppler (https://poppler.freedesktop.org/).
+;; Viewing PS/PDF/DVI files requires Ghostscript, `dvipdf' (comes with
+;; Ghostscript) or `dvipdfm' (comes with teTeX or TeXLive) and
+;; `pdftotext', which comes with xpdf (https://www.foolabs.com/xpdf/)
+;; or poppler (https://poppler.freedesktop.org/).
+;; Djvu documents require `ddjvu' (from DjVuLibre).
+;; ODF files require `soffice' (from LibreOffice).
 
 ;;; Commentary:
 
-;; DocView is a document viewer for Emacs.  It converts PDF, PS and DVI files
-;; to a set of PNG files, one PNG for each page, and displays the PNG images
-;; inside an Emacs buffer.  This buffer uses `doc-view-mode' which provides
-;; convenient key bindings for browsing the document.
+;; DocView is a document viewer for Emacs.  It converts a number of
+;; document formats (including PDF, PS, DVI, Djvu and ODF files) to a
+;; set of PNG files, one PNG for each page, and displays the PNG
+;; images inside an Emacs buffer.  This buffer uses `doc-view-mode'
+;; which provides convenient key bindings for browsing the document.
 ;;
 ;; To use it simply open a document file with
 ;;
diff --git a/lisp/ehelp.el b/lisp/ehelp.el
index 8137320..7da9aed 100644
--- a/lisp/ehelp.el
+++ b/lisp/ehelp.el
@@ -31,7 +31,6 @@
 ;; buffer.
 
 ;; To make this the default, you must do
-;; (require 'ehelp)
 ;; (define-key global-map "\C-h" 'ehelp-command)
 ;; (define-key global-map [help] 'ehelp-command)
 ;; (define-key global-map [f1] 'ehelp-command)
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 086aa98..fb35187 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -1894,8 +1894,8 @@ class of FUNCTION)."
   "Read name of existing advice of CLASS for FUNCTION with completion.
 An optional PROMPT is used to prompt for the name."
   (let* ((name-completion-table
-          (mapcar (function (lambda (advice)
-                             (list (symbol-name (ad-advice-name advice)))))
+          (mapcar (lambda (advice)
+                    (list (symbol-name (ad-advice-name advice))))
                  (ad-get-advice-info-field function class)))
         (default
           (if (null name-completion-table)
@@ -2260,13 +2260,11 @@ element is its actual current value, and the third 
element is either
   (let* ((parsed-arglist (ad-parse-arglist arglist))
         (rest (nth 2 parsed-arglist)))
     `(list
-      ,@(mapcar (function
-                 (lambda (req)
-                  `(list ',req ,req 'required)))
+      ,@(mapcar (lambda (req)
+                  `(list ',req ,req 'required))
                 (nth 0 parsed-arglist))
-      ,@(mapcar (function
-                 (lambda (opt)
-                  `(list ',opt ,opt 'optional)))
+      ,@(mapcar (lambda (opt)
+                  `(list ',opt ,opt 'optional))
                 (nth 1 parsed-arglist))
       ,@(if rest (list `(list ',rest ,rest 'rest))))))
 
@@ -2628,8 +2626,8 @@ should be modified.  The assembled function will be 
returned."
 (defun ad-make-hook-form (function hook-name)
   "Make hook-form from FUNCTION's advice bodies in class HOOK-NAME."
   (let ((hook-forms
-        (mapcar (function (lambda (advice)
-                            (ad-body-forms (ad-advice-definition advice))))
+         (mapcar (lambda (advice)
+                   (ad-body-forms (ad-advice-definition advice)))
                 (ad-get-enabled-advices function hook-name))))
     (if hook-forms
        (macroexp-progn (apply 'append hook-forms)))))
@@ -3172,15 +3170,14 @@ usage: (defadvice FUNCTION (CLASS NAME [POSITION] 
[ARGLIST] FLAG...)
                        (setq args (cdr args)))))
         (flags
          (mapcar
-          (function
-           (lambda (flag)
+           (lambda (flag)
              (let ((completion
                     (try-completion (symbol-name flag) ad-defadvice-flags)))
                (cond ((eq completion t) flag)
                      ((member completion ad-defadvice-flags)
                       (intern completion))
                      (t (error "defadvice: Invalid or ambiguous flag: %s"
-                               flag))))))
+                               flag)))))
           args))
         (advice (ad-make-advice
                  name (memq 'protect flags)
@@ -3222,11 +3219,10 @@ undone on exit of this macro."
   (let* ((index -1)
         ;; Make let-variables to store current definitions:
         (current-bindings
-         (mapcar (function
-                  (lambda (function)
+          (mapcar (lambda (function)
                     (setq index (1+ index))
                     (list (intern (format "ad-oRiGdEf-%d" index))
-                          `(symbol-function ',function))))
+                          `(symbol-function ',function)))
                  functions)))
     `(let ,current-bindings
       (unwind-protect
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 530a086..469bbe6 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1459,10 +1459,10 @@
        (setq rest (cdr rest))))
     (if tags (error "optimizer error: missed tags %s" tags))
     ;; Remove addrs, lap = ( [ (op . arg) | (TAG tagno) ]* )
-    (mapcar (function (lambda (elt)
-                       (if (numberp elt)
-                           elt
-                         (cdr elt))))
+    (mapcar (lambda (elt)
+              (if (numberp elt)
+                  elt
+                (cdr elt)))
            (nreverse lap))))
 
 
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index a485378..61384c0 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -37,7 +37,6 @@
 ;;      documentation whenever you evaluate Lisp code with C-M-x
 ;;      or [menu-bar emacs-lisp eval-buffer].  Additional key-bindings
 ;;      are also provided under C-c ? KEY
-;;        (require 'checkdoc)
 ;;        (add-hook 'emacs-lisp-mode-hook 'checkdoc-minor-mode)
 ;;
 ;; Using `checkdoc':
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index fe73363..e310313 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -4018,7 +4018,6 @@ Options:
 `edebug-print-circle'
 `edebug-on-error'
 `edebug-on-quit'
-`edebug-on-signal'
 `edebug-unwrap-results'
 `edebug-global-break-condition'"
   :lighter " *Debugging*"
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index daf4967..cc40af7 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -481,7 +481,7 @@ This will generate compile-time constants from BINDINGS."
            (3 'font-lock-regexp-grouping-construct prepend))
          (lisp--match-hidden-arg
           (0 '(face font-lock-warning-face
-               help-echo "Hidden behind deeper element; move to another line?")
+               help-echo "Easy to misread; consider moving the element to the 
next line")
              prepend))
          (lisp--match-confusable-symbol-character
           0 '(face font-lock-warning-face
@@ -526,7 +526,7 @@ This will generate compile-time constants from BINDINGS."
            (1 font-lock-keyword-face))
          (lisp--match-hidden-arg
           (0 '(face font-lock-warning-face
-               help-echo "Hidden behind deeper element; move to another line?")
+               help-echo "Easy to misread; consider moving the element to the 
next line")
              prepend))
          ))
       "Gaudy level highlighting for Lisp modes.")))
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 8d8d071..76c3ac3 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -1413,7 +1413,7 @@ into a plain rx-expression, collecting names into 
`rx--pcase-vars'."
                 (mapconcat #'symbol-name rx--pcase-vars " ")))
        `(backref ,index)))
     ((and `(,head . ,rest)
-          (guard (and (symbolp head)
+          (guard (and (or (symbolp head) (memq head '(?\s ??)))
                       (not (memq head '(literal regexp regex eval))))))
      (cons head (mapcar #'rx--pcase-transform rest)))
     (_ rx)))
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index dd9cbd5..37d6170 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -689,8 +689,8 @@ There can be any number of :example/:result elements."
 (define-short-documentation-group sequence
   "Sequence Predicates"
   (seq-contains-p
-   :eval (seq-contains '(a b c) 'b)
-   :eval (seq-contains '(a b c) 'd))
+   :eval (seq-contains-p '(a b c) 'b)
+   :eval (seq-contains-p '(a b c) 'd))
   (seq-every-p
    :eval (seq-every-p #'numberp '(1 2 3)))
   (seq-empty-p
diff --git a/lisp/faces.el b/lisp/faces.el
index 728f8b0..7355e1d 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2578,7 +2578,7 @@ non-nil."
   :group 'basic-faces)
 
 (defface mode-line-highlight
-  '((((class color) (min-colors 88))
+  '((((supports :box t) (class color) (min-colors 88))
      :box (:line-width 2 :color "grey40" :style released-button))
     (t
      :inherit highlight))
diff --git a/lisp/filesets.el b/lisp/filesets.el
index 4f23faa..2cad202 100644
--- a/lisp/filesets.el
+++ b/lisp/filesets.el
@@ -35,7 +35,7 @@
 ;; inclusion group (i.e. a base file including other files).
 
 ;; Usage:
-;; 1. Put (require 'filesets) and (filesets-init) in your init file.
+;; 1. Put (filesets-init) in your init file.
 ;; 2. Type ;; M-x filesets-edit or choose "Edit Filesets" from the menu.
 ;; 3. Save your customizations.
 
diff --git a/lisp/foldout.el b/lisp/foldout.el
index 0d7a7a8..58455c2 100644
--- a/lisp/foldout.el
+++ b/lisp/foldout.el
@@ -527,19 +527,18 @@ Valid modifiers are shift, control, meta, alt, hyper and 
super.")
     (define-key map "\C-z" 'foldout-zoom-subtree)
     (define-key map "\C-x" 'foldout-exit-fold))
   (let* ((modifiers (apply 'concat
-                          (mapcar (function
-                                   (lambda (modifier)
-                                     (vector
-                                      (cond
-                                        ((eq modifier 'shift) ?S)
-                                        ((eq modifier 'control) ?C)
-                                        ((eq modifier 'meta) ?M)
-                                        ((eq modifier 'alt) ?A)
-                                        ((eq modifier 'hyper) ?H)
-                                        ((eq modifier 'super) ?s)
-                                        (t (error "invalid mouse modifier %s"
-                                                  modifier)))
-                                      ?-)))
+                           (mapcar (lambda (modifier)
+                                     (vector
+                                      (cond
+                                       ((eq modifier 'shift) ?S)
+                                       ((eq modifier 'control) ?C)
+                                       ((eq modifier 'meta) ?M)
+                                       ((eq modifier 'alt) ?A)
+                                       ((eq modifier 'hyper) ?H)
+                                       ((eq modifier 'super) ?s)
+                                       (t (error "invalid mouse modifier %s"
+                                                 modifier)))
+                                      ?-))
                                   foldout-mouse-modifiers)))
         (mouse-1 (vector (intern (concat modifiers "down-mouse-1"))))
         (mouse-2 (vector (intern (concat modifiers "down-mouse-2"))))
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index 6a7e81b..76c2904 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -4033,11 +4033,11 @@ If REREAD is not nil, downloaded articles are marked as 
unread."
         (list (list
                (if (listp reread)
                    reread
-                 (delq nil (mapcar (function (lambda (c)
-                                               (cond ((eq reread t)
-                                                      (car c))
-                                                     ((cdr c)
-                                                      (car c)))))
+                  (delq nil (mapcar (lambda (c)
+                                      (cond ((eq reread t)
+                                             (car c))
+                                            ((cdr c)
+                                             (car c))))
                                    gnus-agent-article-alist)))
                'del '(read)))
         gnus-command-method)
diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el
index 1b00bbb..4f85349 100644
--- a/lisp/gnus/gnus-bookmark.el
+++ b/lisp/gnus/gnus-bookmark.el
@@ -345,8 +345,7 @@ copy of the alist."
   (when gnus-bookmark-sort-flag
     (setq gnus-bookmark-alist
          (sort (copy-alist gnus-bookmark-alist)
-               (function
-                (lambda (x y) (string-lessp (car x) (car y))))))))
+                (lambda (x y) (string-lessp (car x) (car y)))))))
 
 ;;;###autoload
 (defun gnus-bookmark-bmenu-list ()
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index c6f7e1c..73fda66 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -52,6 +52,8 @@
 (autoload 'gnus-cloud-upload-all-data "gnus-cloud")
 (autoload 'gnus-cloud-download-all-data "gnus-cloud")
 
+(autoload 'gnus-topic-find-groups "gnus-topic")
+
 (defcustom gnus-no-groups-message "No news is good news"
   "Message displayed by Gnus when no groups are available."
   :group 'gnus-start
@@ -3186,6 +3188,7 @@ non-nil SPECS arg must be an alist with 
`search-query-spec' and
       (let* ((group-spec
              (or
               (cdr (assq 'search-group-spec specs))
+              (cdr (assq 'nnir-group-spec specs))
               (if (gnus-server-server-name)
                   (list (list (gnus-server-server-name)))
                 (seq-group-by
@@ -3193,12 +3196,19 @@ non-nil SPECS arg must be an alist with 
`search-query-spec' and
                  (or gnus-group-marked
                      (if (gnus-group-group-name)
                          (list (gnus-group-group-name))
-                       (cdr
-                        (assoc (gnus-group-topic-name) gnus-topic-alist))))))))
+                       (mapcar #'caadr
+                               (gnus-topic-find-groups
+                                (gnus-group-topic-name)
+                                nil 'all nil t))))))))
             (query-spec
              (or
               (cdr (assq 'search-query-spec specs))
+              (cdr (assq 'nnir-query-spec specs))
               (gnus-search-make-spec no-parse))))
+       ;; If our query came via an old call to nnir, we know not to
+       ;; parse the query.
+       (when (assq 'nnir-query-spec specs)
+         (setf (alist-get 'raw query-spec) t))
        (gnus-group-make-group
         name
         (list 'nnselect "nnselect")
@@ -3229,6 +3239,7 @@ non-nil SPECS arg must be an alist with 
`search-query-spec' and
   (interactive "P")
   (let* ((group-spec
          (or (cdr (assq 'search-group-spec specs))
+             (cdr (assq 'nnir-group-spec specs))
              (if (gnus-server-server-name)
                  (list (list (gnus-server-server-name)))
                (seq-group-by
@@ -3236,11 +3247,18 @@ non-nil SPECS arg must be an alist with 
`search-query-spec' and
                 (or gnus-group-marked
                     (if (gnus-group-group-name)
                         (list (gnus-group-group-name))
-                      (cdr
-                       (assoc (gnus-group-topic-name) gnus-topic-alist))))))))
+                      (mapcar #'caadr
+                               (gnus-topic-find-groups
+                                (gnus-group-topic-name)
+                                nil 'all nil t))))))))
         (query-spec
          (or (cdr (assq 'search-query-spec specs))
+             (cdr (assq 'nnir-query-spec specs))
              (gnus-search-make-spec no-parse))))
+    ;; If our query came via an old call to nnir, we know not to parse
+    ;; the query.
+    (when (assq 'nnir-query-spec specs)
+      (setf (alist-get 'raw query-spec) t))
     (gnus-group-read-ephemeral-group
      (concat "nnselect-" (message-unique-id))
      (list 'nnselect "nnselect")
diff --git a/lisp/gnus/gnus-search.el b/lisp/gnus/gnus-search.el
index 07bd2bc..17f1108 100644
--- a/lisp/gnus/gnus-search.el
+++ b/lisp/gnus/gnus-search.el
@@ -90,15 +90,19 @@
 
 ;;; Internal Variables:
 
-(defvar gnus-search-memo-query nil
-  "Internal: stores current query.")
-
-(defvar gnus-search-memo-server nil
-  "Internal: stores current server.")
+;; When Gnus servers are implemented as objects or structs, give them
+;; a `search-engine' slot and get rid of this variable.
+(defvar gnus-search-engine-instance-alist nil
+  "Mapping between servers and instantiated search engines.")
 
 (defvar gnus-search-history ()
   "Internal history of Gnus searches.")
 
+(defun gnus-search-shutdown ()
+  (setq gnus-search-engine-instance-alist nil))
+
+(gnus-add-shutdown #'gnus-search-shutdown 'gnus)
+
 (define-error 'gnus-search-parse-error "Gnus search parsing error")
 
 ;;; User Customizable Variables:
@@ -782,8 +786,7 @@ the files in ARTLIST by that search key.")
 (cl-defmethod shared-initialize ((engine gnus-search-process)
                                 slots)
   (setq slots (plist-put slots :proc-buffer
-                        (get-buffer-create
-                         (generate-new-buffer-name " *gnus-search-"))))
+                        (generate-new-buffer " *gnus-search-")))
   (cl-call-next-method engine slots))
 
 (defclass gnus-search-imap (gnus-search-engine)
@@ -963,12 +966,18 @@ Responsible for handling and, or, and parenthetical 
expressions.")
 
 (cl-defmethod gnus-search-make-query-string ((engine gnus-search-engine)
                                             query-spec)
-  (if (and gnus-search-use-parsed-queries
-          (null (alist-get 'raw query-spec))
-          (null (slot-value engine 'raw-queries-p)))
-      (gnus-search-transform
-       engine (alist-get 'parsed-query query-spec))
-    (alist-get 'query query-spec)))
+  (let ((parsed-query (alist-get 'parsed-query query-spec))
+       (raw-query (alist-get 'query query-spec)))
+    (if (and gnus-search-use-parsed-queries
+            (null (alist-get 'raw query-spec))
+            (null (slot-value engine 'raw-queries-p))
+            parsed-query)
+       (gnus-search-transform engine parsed-query)
+      (if (listp raw-query)
+         ;; Some callers are sending this in as (query "query"), not
+         ;; as a cons cell?
+         (car raw-query)
+       raw-query))))
 
 (defsubst gnus-search-single-p (query)
   "Return t if QUERY is a search for a single message."
@@ -1109,7 +1118,7 @@ Other capabilities could be tested here."
 ;; TODO: Don't exclude booleans and date keys, just check for them
 ;; before checking for general keywords.
 (defvar gnus-search-imap-search-keys
-  '(body cc bcc from header keyword larger smaller subject text to uid)
+  '(body cc bcc from header keyword larger smaller subject text to uid 
x-gm-raw)
   "Known IMAP search keys, excluding booleans and date keys.")
 
 (cl-defmethod gnus-search-transform ((_ gnus-search-imap)
@@ -1310,7 +1319,7 @@ filenames, sometimes with additional information.  
Returns a list
 of viable results, in the form of a list of [group article score]
 vectors.")
 
-(cl-defgeneric gnus-search-index-extract (engine)
+(cl-defgeneric gnus-search-indexed-extract (engine)
   "Extract a single article result from the current buffer.
 Returns a list of two values: a file name, and a relevancy score.
 Advances point to the beginning of the next result.")
@@ -1953,7 +1962,8 @@ remaining string, then adds all that to the top-level 
spec."
        (setq query
              (string-trim (replace-match "" t t query 0)))
        (setf (alist-get 'query query-spec) query)))
-    (when gnus-search-use-parsed-queries
+    (when (and gnus-search-use-parsed-queries
+              (null (alist-get 'raw query-spec)))
       (setf (alist-get 'parsed-query query-spec)
            (gnus-search-parse-query query)))
     query-spec))
@@ -1964,38 +1974,46 @@ remaining string, then adds all that to the top-level 
spec."
 (defun gnus-search-server-to-engine (srv)
   (let* ((method (gnus-server-to-method srv))
         (engine-config (assoc 'gnus-search-engine (cddr method)))
-        (server
-         (or (nth 1 engine-config)
-             (cdr-safe (assoc (car method) gnus-search-default-engines))
-             (when-let ((old (assoc 'nnir-search-engine
-                                    (cddr method))))
-               (nnheader-message
-                8 "\"nnir-search-engine\" is no longer a valid parameter")
-               (pcase (nth 1 old)
-                 ('notmuch 'gnus-search-notmuch)
-                 ('namazu 'gnus-search-namazu)
-                 ('find-grep 'gnus-search-find-grep)))))
-        (inst
+        (server (or (cdr-safe
+                     (assoc-string srv gnus-search-engine-instance-alist t))
+                    (nth 1 engine-config)
+                    (cdr-safe (assoc (car method) gnus-search-default-engines))
+                    (when-let ((old (assoc 'nnir-search-engine
+                                           (cddr method))))
+                      (nnheader-message
+                       8 "\"nnir-search-engine\" is no longer a valid 
parameter")
+                      (nth 1 old))))
+        inst)
+    (setq server
+         (pcase server
+           ('notmuch 'gnus-search-notmuch)
+           ('namazu 'gnus-search-namazu)
+           ('find-grep 'gnus-search-find-grep)
+           ('imap 'gnus-search-imap)
+           (_ server))
+         inst
          (cond
           ((null server) nil)
           ((eieio-object-p server)
            server)
           ((class-p server)
            (make-instance server))
-          (t nil))))
+          (t nil)))
     (if inst
-       (when (cddr engine-config)
-         ;; We're not being completely backward-compatible here,
-         ;; because we're not checking for nnir-specific config
-         ;; options in the server definition.
-         (pcase-dolist (`(,key ,value) (cddr engine-config))
-           (condition-case nil
-               (setf (slot-value inst key) value)
-             ((invalid-slot-name invalid-slot-type)
-              (nnheader-message
-               5 "Invalid search engine parameter: (%s %s)"
-               key value)))))
-      (nnheader-message 5 "No search engine defined for %s" srv))
+       (unless (assoc-string srv gnus-search-engine-instance-alist t)
+         (when (cddr engine-config)
+           ;; We're not being completely backward-compatible here,
+           ;; because we're not checking for nnir-specific config
+           ;; options in the server definition.
+           (pcase-dolist (`(,key ,value) (cddr engine-config))
+             (condition-case nil
+                 (setf (slot-value inst key) value)
+               ((invalid-slot-name invalid-slot-type)
+                (nnheader-message
+                 5 "Invalid search engine parameter: (%s %s)"
+                 key value)))))
+         (push (cons srv inst) gnus-search-engine-instance-alist))
+      (error "No search engine defined for %s" srv))
     inst))
 
 (declare-function gnus-registry-get-id-key "gnus-registry" (id key))
@@ -2108,7 +2126,8 @@ article came from is also searched."
                  ;; If the value contains spaces, make sure it's
                  ;; quoted.
                  (when (and (memql status '(exact finished))
-                            (string-match-p " " str))
+                            (or (string-match-p " " str)
+                                in-string))
                    (unless (looking-at-p "\\s\"")
                      (insert "\""))
                    ;; Unless we already have an opening quote...
@@ -2127,7 +2146,8 @@ article came from is also searched."
              (minibuffer-with-setup-hook
                  (lambda ()
                    (add-hook 'completion-at-point-functions
-                             #'gnus-search--complete-key-data))
+                             #'gnus-search--complete-key-data
+                             nil t))
                (read-from-minibuffer
                 "Query: " nil gnus-search-minibuffer-map
                 nil 'gnus-search-history)))
diff --git a/lisp/gnus/nnselect.el b/lisp/gnus/nnselect.el
index ce2e99d..e4753fe 100644
--- a/lisp/gnus/nnselect.el
+++ b/lisp/gnus/nnselect.el
@@ -295,6 +295,10 @@ If this variable is nil, or if the provided function 
returns nil,
     (if (zerop (setq length (nnselect-artlist-length nnselect-artlist)))
        (progn
          (nnheader-report 'nnselect "Selection produced empty results.")
+         (when (gnus-ephemeral-group-p group)
+           (gnus-kill-ephemeral-group group)
+           (setq gnus-ephemeral-servers
+                 (assq-delete-all 'nnselect gnus-ephemeral-servers)))
          (nnheader-insert ""))
       (with-current-buffer nntp-server-buffer
        (nnheader-insert "211 %d %d %d %s\n"
@@ -769,8 +773,10 @@ If this variable is nil, or if the provided function 
returns nil,
 Return an article list."
   (let ((func (alist-get 'nnselect-function specs))
        (args (alist-get 'nnselect-args specs)))
-    (funcall func args)))
-
+    (condition-case err
+       (funcall func args)
+      (error (gnus-error 3 "nnselect-run: %s on %s gave error %s" func args 
err)
+            []))))
 
 (defun nnselect-search-thread (header)
   "Make an nnselect group containing the thread with article HEADER.
diff --git a/lisp/help.el b/lisp/help.el
index 6399a12..7eb50fd 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1103,13 +1103,13 @@ Otherwise, return a new string (without any text 
properties)."
                       (describe-map-tree this-keymap t (nreverse earlier-maps)
                                          nil nil t nil nil t))))))))
              ;; 2. Handle quotes.
-             ((and (eq (get-quoting-style) 'curve)
+             ((and (eq (text-quoting-style) 'curve)
                    (or (and (= (following-char) ?\`)
                             (prog1 t (insert "‘")))
                        (and (= (following-char) ?')
                             (prog1 t (insert "’")))))
               (delete-char 1))
-             ((and (eq (get-quoting-style) 'straight)
+             ((and (eq (text-quoting-style) 'straight)
                    (= (following-char) ?\`))
               (insert "'")
               (delete-char 1))
diff --git a/lisp/hippie-exp.el b/lisp/hippie-exp.el
index ce5fc58..b521dda 100644
--- a/lisp/hippie-exp.el
+++ b/lisp/hippie-exp.el
@@ -411,14 +411,14 @@ undoes the expansion."
   "Construct a function similar to `hippie-expand'.
 Make it use the expansion functions in TRY-LIST.  An optional second
 argument VERBOSE non-nil makes the function verbose."
-  `(function (lambda (arg)
-    ,(concat
-      "Try to expand text before point, using the following functions: \n"
-      (mapconcat 'prin1-to-string (eval try-list) ", "))
-    (interactive "P")
-    (let ((hippie-expand-try-functions-list ,try-list)
-          (hippie-expand-verbose ,verbose))
-      (hippie-expand arg)))))
+  `(lambda (arg)
+     ,(concat
+       "Try to expand text before point, using the following functions: \n"
+       (mapconcat 'prin1-to-string (eval try-list) ", "))
+     (interactive "P")
+     (let ((hippie-expand-try-functions-list ,try-list)
+           (hippie-expand-verbose ,verbose))
+       (hippie-expand arg))))
 
 
 ;;;  Here follows the try-functions and their requisites:
@@ -534,10 +534,10 @@ string).  It returns t if a new completion is found, nil 
otherwise."
        (setq he-expand-list
              (and (not (equal he-search-string ""))
                   (sort (all-completions he-search-string obarray
-                                         (function (lambda (sym)
+                                          (lambda (sym)
                                            (or (boundp sym)
                                                (fboundp sym)
-                                               (symbol-plist sym)))))
+                                                (symbol-plist sym))))
                         'string-lessp)))))
   (while (and he-expand-list
              (he-string-member (car he-expand-list) he-tried-table))
@@ -563,10 +563,10 @@ otherwise."
          (if (not (string= he-search-string ""))
              (setq expansion
                    (try-completion he-search-string obarray
-                                   (function (lambda (sym)
+                                    (lambda (sym)
                                      (or (boundp sym)
                                          (fboundp sym)
-                                         (symbol-plist sym)))))))
+                                          (symbol-plist sym))))))
          (if (or (eq expansion t)
                  (string= expansion he-search-string)
                  (he-string-member expansion he-tried-table))
@@ -821,10 +821,10 @@ string).  It returns t if a new expansion is found, nil 
otherwise."
        (he-init-string (he-dabbrev-beg) (point))
        (setq he-expand-list
              (and (not (equal he-search-string ""))
-                  (mapcar (function (lambda (sym)
+                   (mapcar (lambda (sym)
                             (if (and (boundp sym) (vectorp (eval sym)))
                                 (abbrev-expansion (downcase he-search-string)
-                                                  (eval sym)))))
+                                                   (eval sym))))
                           (append '(local-abbrev-table
                                     global-abbrev-table)
                                   abbrev-table-name-list))))))
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index 439843a..1e6fea8 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -491,8 +491,8 @@ non-nil, it is used to sort CODINGS instead."
                                 0)))
                           1)
                         ))))))
-      (sort codings (function (lambda (x y)
-                               (> (funcall func x) (funcall func y))))))))
+      (sort codings (lambda (x y)
+                      (> (funcall func x) (funcall func y)))))))
 
 (defun find-coding-systems-region (from to)
   "Return a list of proper coding systems to encode a text between FROM and TO.
@@ -888,7 +888,7 @@ It is highly recommended to fix it before writing to a 
file."
 
     ;; Change elements of the list to (coding . base-coding).
     (setq default-coding-system
-         (mapcar (function (lambda (x) (cons x (coding-system-base x))))
+          (mapcar (lambda (x) (cons x (coding-system-base x)))
                  default-coding-system))
 
     (if (and auto-cs (not no-other-defaults))
@@ -1082,7 +1082,7 @@ it asks the user to select a proper coding system."
     (if (fboundp select-safe-coding-system-function)
        (funcall select-safe-coding-system-function
                 (point-min) (point-max) coding
-                (function (lambda (x) (coding-system-get x :mime-charset))))
+                 (lambda (x) (coding-system-get x :mime-charset)))
       coding)))
 
 ;;; Language support stuff.
@@ -1261,7 +1261,7 @@ This returns a language environment name as a string."
         (name (completing-read prompt
                                language-info-alist
                                (and key
-                                    (function (lambda (elm) (and (listp elm) 
(assq key elm)))))
+                                     (lambda (elm) (and (listp elm) (assq key 
elm))))
                                t nil nil default)))
     (if (and (> (length name) 0)
             (or (not key)
@@ -2965,9 +2965,9 @@ STR should be a unibyte string."
   (mapconcat
    (if (and coding-system (eq (coding-system-type coding-system) 'iso-2022))
        ;; Try to get a pretty description for ISO 2022 escape sequences.
-       (function (lambda (x) (or (cdr (assq x iso-2022-control-alist))
-                                (format "#x%02X" x))))
-     (function (lambda (x) (format "#x%02X" x))))
+       (lambda (x) (or (cdr (assq x iso-2022-control-alist))
+                  (format "#x%02X" x)))
+     (lambda (x) (format "#x%02X" x)))
    str " "))
 
 (defun encode-coding-char (char coding-system &optional charset)
diff --git a/lisp/international/mule-conf.el b/lisp/international/mule-conf.el
index 42dd198..99449ad 100644
--- a/lisp/international/mule-conf.el
+++ b/lisp/international/mule-conf.el
@@ -1251,7 +1251,9 @@ by UTF-8."
   :coding-type 'undecided
   :mnemonic ?-
   :charset-list '(emacs)
-  :prefer-utf-8 t)
+  :prefer-utf-8 t
+  :inhibit-null-byte-detection 0
+  :inhibit-iso-escape-detection 0)
 
 (define-coding-system 'raw-text
   "Raw text, which means text contains random 8-bit codes.
diff --git a/lisp/international/mule.el b/lisp/international/mule.el
index 5292abf..66abc98 100644
--- a/lisp/international/mule.el
+++ b/lisp/international/mule.el
@@ -858,16 +858,23 @@ as an encoding result.
 
 `:inhibit-null-byte-detection'
 
-VALUE non-nil means Emacs ignore null bytes on code detection.
+VALUE non-nil means Emacs should ignore null bytes on code detection.
 See the variable `inhibit-null-byte-detection'.  This attribute
 is meaningful only when `:coding-type' is `undecided'.
+If VALUE is t, Emacs will ignore null bytes unconditionally while
+detecting encoding.  If VALUE is non-nil and not t, Emacs will
+ignore null bytes if `inhibit-null-byte-detection' is non-nil.
 
 `:inhibit-iso-escape-detection'
 
-VALUE non-nil means Emacs ignores ISO-2022 escape sequences on
+VALUE non-nil means Emacs should ignore ISO-2022 escape sequences on
 code detection.  See the variable `inhibit-iso-escape-detection'.
 This attribute is meaningful only when `:coding-type' is
 `undecided'.
+If VALUE is t, Emacs will ignore escape sequences unconditionally
+while detecting encoding.  If VALUE is non-nil and not t, Emacs
+will ignore escape sequences if `inhibit-iso-escape-detection' is
+non-nil.
 
 `:prefer-utf-8'
 
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index 3299cc5..5abd668 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -787,7 +787,7 @@ you type is correctly handled."
 
 (defun quail-keyseq-translate (keyseq)
   (apply 'string
-        (mapcar (function (lambda (x) (quail-keyboard-translate x)))
+         (mapcar (lambda (x) (quail-keyboard-translate x))
                 keyseq)))
 
 (defun quail-insert-kbd-layout (kbd-layout)
@@ -2145,7 +2145,7 @@ minibuffer and the selected frame has no other windows)."
          (setq str
                (format "%s[%s]"
                        str
-                       (concat (sort (mapcar (function (lambda (x) (car x)))
+                        (concat (sort (mapcar (lambda (x) (car x))
                                              (cdr map))
                                      '<)))))
       ;; Show list of translations.
@@ -2349,13 +2349,13 @@ Optional 6th arg IGNORES is a list of translations to 
ignore."
          ((consp translation)
           (setq translation (cdr translation))
           (let ((multibyte nil))
-            (mapc (function (lambda (x)
-                              ;; Accept only non-ASCII chars not
-                              ;; listed in IGNORES.
-                              (if (and (if (integerp x) (> x 127)
-                                          (string-match-p "[^[:ascii:]]" x))
-                                       (not (member x ignores)))
-                                  (setq multibyte t))))
+             (mapc (lambda (x)
+                     ;; Accept only non-ASCII chars not
+                     ;; listed in IGNORES.
+                     (if (and (if (integerp x) (> x 127)
+                                (string-match-p "[^[:ascii:]]" x))
+                              (not (member x ignores)))
+                         (setq multibyte t)))
                   translation)
             (when multibyte
               (setcdr decode-map
@@ -2380,11 +2380,11 @@ These are stored in DECODE-MAP using the concise 
format.  DECODE-MAP
 should be made by `quail-build-decode-map' (which see)."
   (setq decode-map
        (sort (cdr decode-map)
-             (function (lambda (x y)
-                         (setq x (car x) y (car y))
-                         (or (> (length x) (length y))
-                             (and (= (length x) (length y))
-                                  (not (string< x y))))))))
+              (lambda (x y)
+                (setq x (car x) y (car y))
+                (or (> (length x) (length y))
+                    (and (= (length x) (length y))
+                         (not (string< x y)))))))
   (let ((window-width (window-width (get-buffer-window
                                      (current-buffer) 'visible)))
        (single-trans-width 4)
diff --git a/lisp/international/ucs-normalize.el 
b/lisp/international/ucs-normalize.el
index 33d0f0d..7822450 100644
--- a/lisp/international/ucs-normalize.el
+++ b/lisp/international/ucs-normalize.el
@@ -441,7 +441,7 @@ decomposition."
     (concat (quick-check-list-to-regexp quick-check-list) "\\|[가-힣]"))
 
   (defun quick-check-composition-list-to-regexp (quick-check-list)
-    (concat (quick-check-list-to-regexp quick-check-list) "\\|[ᅡ-ᅵᆨ-ᇂ]"))
+    (quick-check-list-to-regexp quick-check-list))
 )
 
 
diff --git a/lisp/jka-compr.el b/lisp/jka-compr.el
index eef3d14..e1a3058 100644
--- a/lisp/jka-compr.el
+++ b/lisp/jka-compr.el
@@ -664,11 +664,11 @@ and `inhibit-local-variables-suffixes' that were added
 by `jka-compr-installed'."
   ;; Delete from inhibit-local-variables-suffixes what jka-compr-install added.
   (mapc
-     (function (lambda (x)
-                (and (jka-compr-info-strip-extension x)
-                     (setq inhibit-local-variables-suffixes
-                           (delete (jka-compr-info-regexp x)
-                                   inhibit-local-variables-suffixes)))))
+     (lambda (x)
+       (and (jka-compr-info-strip-extension x)
+            (setq inhibit-local-variables-suffixes
+                  (delete (jka-compr-info-regexp x)
+                          inhibit-local-variables-suffixes))))
      jka-compr-compression-info-list--internal)
 
   (let* ((fnha (cons nil file-name-handler-alist))
diff --git a/lisp/leim/quail/compose.el b/lisp/leim/quail/compose.el
index eb37a42..de251a3 100644
--- a/lisp/leim/quail/compose.el
+++ b/lisp/leim/quail/compose.el
@@ -2922,5 +2922,31 @@ Examples:
  ("_⍵" ?⍹)
  )
 
+;; Quail package `iso-transl' is based on `C-x 8' key sequences.
+;; This input method supports the same key sequences as defined
+;; by the `C-x 8' keymap in iso-transl.el.
+
+(quail-define-package
+ "iso-transl" "UTF-8" "X8" t
+ "Use the same key sequences as in `C-x 8' keymap defined in iso-transl.el.
+Examples:
+ * E -> €   1 / 2 -> ½   ^ 3 -> ³"
+ '(("\t" . quail-completion))
+ t nil nil nil nil nil nil nil nil t)
+
+(eval-when-compile
+  (require 'iso-transl)
+  (defmacro iso-transl--define-rules ()
+    `(quail-define-rules
+      ,@(mapcar (lambda (rule)
+                  (let ((from (car rule))
+                        (to (cdr rule)))
+                    (list from (if (stringp to)
+                                   (vector to)
+                                 to))))
+                iso-transl-char-map))))
+
+(iso-transl--define-rules)
+
 (provide 'compose)
 ;;; compose.el ends here
diff --git a/lisp/leim/quail/latin-ltx.el b/lisp/leim/quail/latin-ltx.el
index 6a2508b..f1a24bb 100644
--- a/lisp/leim/quail/latin-ltx.el
+++ b/lisp/leim/quail/latin-ltx.el
@@ -8,7 +8,7 @@
 
 ;; Author: TAKAHASHI Naoto <ntakahas@m17n.org>
 ;;         Dave Love <fx@gnu.org>
-;; Keywords: multilingual, input, Greek, i18n
+;; Keywords: multilingual, input method, i18n
 
 ;; This file is part of GNU Emacs.
 
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 827087f..158a4bf 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -57,7 +57,7 @@
 ;; bidi.c needs for its job.
 (setq redisplay--inhibit-bidi t)
 
-(message "dump mode: %s" dump-mode)
+(message "Dump mode: %s" dump-mode)
 
 ;; Add subdirectories to the load-path for files that might get
 ;; autoloaded when bootstrapping or running Emacs normally.
diff --git a/lisp/locate.el b/lisp/locate.el
index bc78e06..44a67ab 100644
--- a/lisp/locate.el
+++ b/lisp/locate.el
@@ -668,11 +668,11 @@ the database on the command line."
   (or (file-exists-p database)
       (error "Database file %s does not exist" database))
   (let ((locate-make-command-line
-        (function (lambda (string)
-                    (cons locate-command
-                          (list (concat "--database="
-                                        (expand-file-name database))
-                                string))))))
+         (lambda (string)
+           (cons locate-command
+                 (list (concat "--database="
+                               (expand-file-name database))
+                       string)))))
     (locate search-string)))
 
 (defun locate-do-redisplay (&optional arg test-for-subdir)
diff --git a/lisp/mail/mailabbrev.el b/lisp/mail/mailabbrev.el
index 09afad7..de4fe25 100644
--- a/lisp/mail/mailabbrev.el
+++ b/lisp/mail/mailabbrev.el
@@ -377,11 +377,11 @@ double-quotes."
              (setq result (cons (substring definition start end) result)
                    start (and end (match-end 0)))))
          (setq definition
-               (mapconcat (function (lambda (x)
+                (mapconcat (lambda (x)
                             (or (mail-resolve-all-aliases-1
-                                  (intern-soft (downcase x) mail-abbrevs)
-                                  (cons sym so-far))
-                                x)))
+                                  (intern-soft (downcase x) mail-abbrevs)
+                                  (cons sym so-far))
+                                 x))
                           (nreverse result)
                           mail-alias-separator-string))
          (set sym definition))))
@@ -436,12 +436,12 @@ of a mail alias.  The value is set up, buffer-local, when 
first needed.")
          (_ (aref (standard-syntax-table) ?_))
          (w (aref (standard-syntax-table) ?w)))
       (map-char-table
-       (function (lambda (key value)
-                  (if (null value)
-                      ;; Fetch the inherited value
-                      (setq value (aref tab key)))
-                  (if (equal value _)
-                      (set-char-table-range tab key w))))
+       (lambda (key value)
+         (if (null value)
+             ;; Fetch the inherited value
+             (setq value (aref tab key)))
+         (if (equal value _)
+             (set-char-table-range tab key w)))
        tab)
       (modify-syntax-entry ?@ "w" tab)
       (modify-syntax-entry ?% "w" tab)
diff --git a/lisp/mail/reporter.el b/lisp/mail/reporter.el
index edfceb3..0c8b8d4 100644
--- a/lisp/mail/reporter.el
+++ b/lisp/mail/reporter.el
@@ -51,7 +51,6 @@
 ;;(defun mypkg-submit-bug-report ()
 ;;  "Submit via mail a bug report on mypkg"
 ;;  (interactive)
-;;  (require 'reporter)
 ;;  (reporter-submit-bug-report
 ;;   mypkg-maintainer-address
 ;;   (concat "mypkg.el " mypkg-version)
diff --git a/lisp/mail/rfc822.el b/lisp/mail/rfc822.el
index f2fe1cd..4572f27 100644
--- a/lisp/mail/rfc822.el
+++ b/lisp/mail/rfc822.el
@@ -226,11 +226,11 @@
                       ((and (not (eobp)) (= (following-char) ?\@))
                        ;; <@foo.bar,@baz:quux@abcd.efg>
                        (rfc822-snarf-frob-list "<...> address" ?\, ?\:
-                         (function (lambda ()
-                                     (if (rfc822-looking-at ?\@)
-                                         (rfc822-snarf-domain)
-                                       (rfc822-bad-address
-                                         "Gubbish in route-addr")))))
+                          (lambda ()
+                            (if (rfc822-looking-at ?\@)
+                                (rfc822-snarf-domain)
+                              (rfc822-bad-address
+                               "Gubbish in route-addr"))))
                        (rfc822-snarf-words)
                        (or (rfc822-looking-at ?@)
                            (rfc822-bad-address "Malformed <..@..> address"))
diff --git a/lisp/mail/uudecode.el b/lisp/mail/uudecode.el
index bcbd571..0dce9b7 100644
--- a/lisp/mail/uudecode.el
+++ b/lisp/mail/uudecode.el
@@ -149,12 +149,10 @@ If FILE-NAME is non-nil, save the result to FILE-NAME."
              (setq counter (1+ counter)
                    inputpos (1+ inputpos))
              (cond ((= counter 4)
-                    (setq result (cons
-                                  (concat
-                                   (char-to-string (ash bits -16))
-                                   (char-to-string (logand (ash bits -8) 255))
-                                   (char-to-string (logand bits 255)))
-                                  result))
+                    (setq result (cons (logand bits 255)
+                                       (cons (logand (ash bits -8) 255)
+                                             (cons (ash bits -16)
+                                                   result))))
                     (setq bits 0 counter 0))
                    (t (setq bits (ash bits 6)))))))
          (cond
@@ -166,26 +164,26 @@ If FILE-NAME is non-nil, save the result to FILE-NAME."
            ;;(error "uucode ends unexpectedly")
            (setq done t))
           ((= counter 3)
-           (setq result (cons
-                         (concat
-                          (char-to-string (logand (ash bits -16) 255))
-                          (char-to-string (logand (ash bits -8) 255)))
-                         result)))
+           (setq result (cons (logand (ash bits -8) 255)
+                              (cons (logand (ash bits -16) 255)
+                                    result))))
           ((= counter 2)
-           (setq result (cons
-                         (char-to-string (logand (ash bits -10) 255))
-                         result))))
+           (setq result (cons (logand (ash bits -10) 255)
+                              result))))
          (skip-chars-forward non-data-chars end))
        (if file-name
             (with-temp-file file-name
               (set-buffer-multibyte nil)
-              (insert (apply #'concat (nreverse result))))
+              (apply #'insert (nreverse result)))
          (or (markerp end) (setq end (set-marker (make-marker) end)))
          (goto-char start)
-         (if enable-multibyte-characters
-             (dolist (x (nreverse result))
-                (insert (decode-coding-string x 'binary)))
-           (insert (apply #'concat (nreverse result))))
+          (apply #'insert
+                 (nreverse
+                  (if enable-multibyte-characters
+                      (mapcar (lambda (ch)
+                                (or (decode-char 'eight-bit ch) ch))
+                              result)
+                    result)))
          (delete-region (point) end))))))
 
 ;;;###autoload
diff --git a/lisp/mh-e/mh-seq.el b/lisp/mh-e/mh-seq.el
index 41c8489..a8fb46d 100644
--- a/lisp/mh-e/mh-seq.el
+++ b/lisp/mh-e/mh-seq.el
@@ -794,9 +794,9 @@ If SAVE-REFILES is non-nil, then keep the sequences
 that note messages to be refiled."
   (let ((seqs ()))
     (cond (save-refiles
-           (mh-mapc (function (lambda (seq) ; Save the refiling sequences
-                                (if (mh-folder-name-p (mh-seq-name seq))
-                                    (setq seqs (cons seq seqs)))))
+           (mh-mapc (lambda (seq) ; Save the refiling sequences
+                      (if (mh-folder-name-p (mh-seq-name seq))
+                          (setq seqs (cons seq seqs))))
                     mh-seq-list)))
     (save-excursion
       (if (eq 0 (mh-exec-cmd-quiet nil "mark" folder "-list"))
diff --git a/lisp/net/eudcb-ldap.el b/lisp/net/eudcb-ldap.el
index 88c58f5..14cc7db 100644
--- a/lisp/net/eudcb-ldap.el
+++ b/lisp/net/eudcb-ldap.el
@@ -76,12 +76,11 @@
   "Do some cleanup in a RECORD to make it suitable for EUDC."
   (declare (obsolete eudc-ldap-cleanup-record-filtering-addresses "25.1"))
   (mapcar
-   (function
-    (lambda (field)
-      (cons (intern (downcase (car field)))
-           (if (cdr (cdr field))
-               (cdr field)
-             (car (cdr field))))))
+   (lambda (field)
+     (cons (intern (downcase (car field)))
+           (if (cdr (cdr field))
+               (cdr field)
+             (car (cdr field)))))
    record))
 
 (defun eudc-filter-$ (string)
@@ -138,10 +137,10 @@ RETURN-ATTRS is a list of attributes to return, 
defaulting to
     ;; Apply eudc-duplicate-attribute-handling-method
     (if (not (eq 'list eudc-duplicate-attribute-handling-method))
        (mapc
-        (function (lambda (record)
-                    (setq final-result
-                          (append (eudc-filter-duplicate-attributes record)
-                                  final-result))))
+         (lambda (record)
+           (setq final-result
+                 (append (eudc-filter-duplicate-attributes record)
+                         final-result)))
         result))
     final-result))
 
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 43405fb..9ed01ec 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -420,7 +420,7 @@ killed after rendering."
       (narrow-to-region start end)
       (goto-char start)
       (let ((case-fold-search t))
-        (while (re-search-forward "<[^0-9a-z!/]" nil t)
+        (while (re-search-forward "<[^0-9a-z!?/]" nil t)
           (goto-char (match-beginning 0))
           (delete-region (point) (1+ (point)))
           (insert "&lt;"))))))
diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el
index 8c7d33a..8777fe4 100644
--- a/lisp/net/net-utils.el
+++ b/lisp/net/net-utils.el
@@ -985,9 +985,8 @@ This command uses `network-connection-service-alist', which 
see."
     (read-from-minibuffer "Host: " (net-utils-machine-at-point))
     (completing-read "Service: "
                     (mapcar
-                     (function
-                      (lambda (elt)
-                        (list (symbol-name (car elt)))))
+                      (lambda (elt)
+                        (list (symbol-name (car elt))))
                      network-connection-service-alist))))
   (network-connection
    host
diff --git a/lisp/net/newsticker.el b/lisp/net/newsticker.el
index 535122a..c949915 100644
--- a/lisp/net/newsticker.el
+++ b/lisp/net/newsticker.el
@@ -78,14 +78,6 @@
 ;; Installation
 ;; ------------
 
-;; If you are using Newsticker as part of GNU Emacs there is no need to
-;; perform any installation steps in order to use Newsticker.  Otherwise
-;; place Newsticker in a directory where Emacs can find it.  Add the
-;; following line to your init file:
-;;   (add-to-list 'load-path "/path/to/newsticker/")
-;;   (autoload 'newsticker-start "newsticker" "Emacs Newsticker" t)
-;;   (autoload 'newsticker-show-news "newsticker" "Emacs Newsticker" t)
-
 ;; If you are using `imenu', which allows for navigating with the help of a
 ;; menu, you should add the following to your Emacs startup file
 ;; (`~/.emacs').
diff --git a/lisp/net/rfc2104.el b/lisp/net/rfc2104.el
index 50d5476..b008c9a 100644
--- a/lisp/net/rfc2104.el
+++ b/lisp/net/rfc2104.el
@@ -26,11 +26,9 @@
 ;;
 ;; Example:
 ;;
-;; (require 'md5)
 ;; (rfc2104-hash 'md5 64 16 "Jefe" "what do ya want for nothing?")
 ;; "750c783e6ab0b503eaa86e310a5db738"
 ;;
-;; (require 'sha1)
 ;; (rfc2104-hash 'sha1 64 20 "Jefe" "what do ya want for nothing?")
 ;; "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"
 ;;
diff --git a/lisp/net/sieve-mode.el b/lisp/net/sieve-mode.el
index 7475a7b..c5f4491 100644
--- a/lisp/net/sieve-mode.el
+++ b/lisp/net/sieve-mode.el
@@ -26,11 +26,6 @@
 ;; sieve-style #-comments and a lightly hacked syntax table.  It was
 ;; strongly influenced by awk-mode.el.
 ;;
-;; Put something similar to the following in your .emacs to use this file:
-;;
-;; (load "~/lisp/sieve")
-;; (setq auto-mode-alist (cons '("\\.siv\\'" . sieve-mode) auto-mode-alist))
-;;
 ;; References:
 ;;
 ;; RFC 3028,
diff --git a/lisp/net/socks.el b/lisp/net/socks.el
index 84fc5dc..9b22a50 100644
--- a/lisp/net/socks.el
+++ b/lisp/net/socks.el
@@ -235,11 +235,10 @@
   (let ((num 0)
        (retval ""))
     (mapc
-     (function
-      (lambda (x)
-       (if (fboundp (cdr (cdr x)))
-           (setq retval (format "%s%c" retval (car x))
-                 num (1+ num)))))
+     (lambda (x)
+       (if (fboundp (cdr (cdr x)))
+           (setq retval (format "%s%c" retval (car x))
+                 num (1+ num))))
      (reverse socks-authentication-methods))
     (format "%c%s" num retval)))
 
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index be83f67..7cdb7eb 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -575,8 +575,9 @@ But handle the case, if the \"test\" command is not 
available."
       ;; Set file modification time.
       (when (or (eq visit t) (stringp visit))
        (set-visited-file-modtime
-        (tramp-compat-file-attribute-modification-time
-         (file-attributes filename))))
+        (or (tramp-compat-file-attribute-modification-time
+             (file-attributes filename))
+            (current-time))))
 
       ;; The end.
       (when (and (null noninteractive)
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 8f8e628a..098fba5 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -689,7 +689,6 @@ It has been changed in GVFS 1.14.")
     ("gvfs-monitor-file" . "monitor")
     ("gvfs-mount" . "mount")
     ("gvfs-move" . "move")
-    ("gvfs-rename" . "rename")
     ("gvfs-rm" . "remove")
     ("gvfs-set-attribute" . "set"))
   "List of cons cells, mapping \"gvfs-<command>\" to \"gio <command>\".")
@@ -876,7 +875,7 @@ Return nil for null BYTE-ARRAY."
                  byte-array (car byte-array))))
     (dbus-byte-array-to-string
      (if (and (consp byte-array) (zerop (car (last byte-array))))
-        (nbutlast byte-array) byte-array))))
+        (butlast byte-array) byte-array))))
 
 (defun tramp-gvfs-stringify-dbus-message (message)
   "Convert a D-Bus MESSAGE into readable UTF8 strings, used for traces."
@@ -985,15 +984,12 @@ file names."
        (copy-directory filename newname keep-date t)
        (when (eq op 'rename) (delete-directory filename 'recursive)))
 
-    (let* ((t1 (tramp-tramp-file-p filename))
-          (t2 (tramp-tramp-file-p newname))
-          (equal-remote (tramp-equal-remote filename newname))
-          (gvfs-operation
-           (cond
-            ((eq op 'copy) "gvfs-copy")
-            (equal-remote "gvfs-rename")
-            (t "gvfs-move")))
-          (msg-operation (if (eq op 'copy) "Copying" "Renaming")))
+    (let ((t1 (tramp-tramp-file-p filename))
+         (t2 (tramp-tramp-file-p newname))
+         (equal-remote (tramp-equal-remote filename newname))
+         ;; "gvfs-rename" is not trustworthy.
+         (gvfs-operation (if (eq op 'copy) "gvfs-copy" "gvfs-move"))
+         (msg-operation (if (eq op 'copy) "Copying" "Renaming")))
 
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
@@ -2439,7 +2435,10 @@ This uses \"avahi-browse\" in case D-Bus is not enabled 
in Avahi."
 
 (when tramp-gvfs-enabled
   ;; Suppress D-Bus error messages and Tramp traces.
-  (let ((tramp-verbose 0)
+  (let (;; Sometimes, it fails with "Variable binding depth exceeds
+       ;; max-specpdl-size".  Shall be fixed in Emacs 27.
+       (max-specpdl-size (* 2 max-specpdl-size))
+       (tramp-verbose 0)
        tramp-gvfs-dbus-event-vector fun)
     ;; Add completion functions for services announced by DNS-SD.
     ;; See <http://www.dns-sd.org/ServiceTypes.html> for valid service types.
diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el
index f712600..7e4a9bf 100644
--- a/lisp/net/tramp-integration.el
+++ b/lisp/net/tramp-integration.el
@@ -132,7 +132,7 @@ been set up by `rfn-eshadow-setup-minibuffer'."
   ;; Use `path-separator' as it does eshell.
   (setq eshell-path-env
        (mapconcat
-        #'identity (nbutlast (tramp-compat-exec-path)) path-separator)))
+        #'identity (butlast (tramp-compat-exec-path)) path-separator)))
 
 (with-eval-after-load 'esh-util
   (add-hook 'eshell-mode-hook
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 51e15af..ccf0c0d 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -3530,7 +3530,8 @@ implementation will be used."
              ;; We must pass modtime explicitly, because FILENAME can
              ;; be different from (buffer-file-name), f.e. if
              ;; `file-precious-flag' is set.
-             (tramp-compat-file-attribute-modification-time file-attr))
+            (or (tramp-compat-file-attribute-modification-time file-attr)
+                (current-time)))
             (when (and (= (tramp-compat-file-attribute-user-id file-attr) uid)
                        (= (tramp-compat-file-attribute-group-id file-attr) 
gid))
               (setq need-chown nil))))
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 0dd233a..8a48ffc 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -1630,8 +1630,9 @@ errors for shares like \"C$/\", which are common in 
Microsoft Windows."
       ;; Set file modification time.
       (when (or (eq visit t) (stringp visit))
        (set-visited-file-modtime
-        (tramp-compat-file-attribute-modification-time
-         (file-attributes filename))))
+        (or (tramp-compat-file-attribute-modification-time
+             (file-attributes filename))
+            (current-time))))
 
       ;; The end.
       (when (and (null noninteractive)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 55f652f..a98d478 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -4181,8 +4181,9 @@ of."
       ;; Set file modification time.
       (when (or (eq visit t) (stringp visit))
        (set-visited-file-modtime
-        (tramp-compat-file-attribute-modification-time
-         (file-attributes filename))))
+        (or (tramp-compat-file-attribute-modification-time
+             (file-attributes filename))
+            (current-time))))
 
       ;; Set the ownership.
       (tramp-set-file-uid-gid filename uid gid))
diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el
index 8bb1561..9fbc434 100644
--- a/lisp/net/webjump.el
+++ b/lisp/net/webjump.el
@@ -40,7 +40,6 @@
 
 ;; You may wish to add something like the following to your init file:
 ;;
-;;   (require 'webjump)
 ;;   (global-set-key "\C-cj" 'webjump)
 ;;   (setq webjump-sites
 ;;         (append '(
diff --git a/lisp/obsolete/nnir.el b/lisp/obsolete/nnir.el
index aec5ed3..6f17854 100644
--- a/lisp/obsolete/nnir.el
+++ b/lisp/obsolete/nnir.el
@@ -874,9 +874,9 @@ Windows NT 4.0."
       ;; Sort by score
       (apply #'vector
              (sort artlist
-                   (function (lambda (x y)
-                               (> (nnir-artitem-rsv x)
-                                  (nnir-artitem-rsv y)))))))))
+                   (lambda (x y)
+                     (> (nnir-artitem-rsv x)
+                        (nnir-artitem-rsv y))))))))
 
 ;; Swish-E interface.
 (defun nnir-run-swish-e (query server &optional _group)
@@ -969,9 +969,9 @@ Tested with swish-e-2.0.1 on Windows NT 4.0."
       ;; Sort by score
       (apply #'vector
              (sort artlist
-                   (function (lambda (x y)
-                               (> (nnir-artitem-rsv x)
-                                  (nnir-artitem-rsv y)))))))))
+                   (lambda (x y)
+                     (> (nnir-artitem-rsv x)
+                        (nnir-artitem-rsv y))))))))
 
 ;; HyREX interface
 (defun nnir-run-hyrex (query server &optional group)
@@ -1037,12 +1037,12 @@ Tested with swish-e-2.0.1 on Windows NT 4.0."
       (message "Massaging hyrex-search output...done.")
       (apply #'vector
             (sort artlist
-                   (function (lambda (x y)
-                               (if (string-lessp (nnir-artitem-group x)
-                                                 (nnir-artitem-group y))
-                                   t
-                                 (< (nnir-artitem-number x)
-                                    (nnir-artitem-number y)))))))
+                   (lambda (x y)
+                     (if (string-lessp (nnir-artitem-group x)
+                                       (nnir-artitem-group y))
+                         t
+                       (< (nnir-artitem-number x)
+                          (nnir-artitem-number y))))))
       )))
 
 ;; Namazu interface
@@ -1112,9 +1112,9 @@ Tested with Namazu 2.0.6 on a GNU/Linux system."
       ;; sort artlist by score
       (apply #'vector
              (sort artlist
-                   (function (lambda (x y)
-                               (> (nnir-artitem-rsv x)
-                                  (nnir-artitem-rsv y)))))))))
+                   (lambda (x y)
+                     (> (nnir-artitem-rsv x)
+                        (nnir-artitem-rsv y))))))))
 
 (defun nnir-run-notmuch (query server &optional groups)
   "Run QUERY with GROUPS from SERVER against notmuch.
diff --git a/lisp/org/ob-ruby.el b/lisp/org/ob-ruby.el
index 1b8088e..aa28bf1 100644
--- a/lisp/org/ob-ruby.el
+++ b/lisp/org/ob-ruby.el
@@ -51,7 +51,8 @@
 (defvar org-babel-default-header-args:ruby '())
 
 (defvar org-babel-ruby-command "ruby"
-  "Name of command to use for executing ruby code.")
+  "Name of command to use for executing ruby code.
+It's possible to override it by using a header argument `:ruby'")
 
 (defcustom org-babel-ruby-hline-to "nil"
   "Replace hlines in incoming tables with this when translating to ruby."
@@ -71,7 +72,7 @@
   "Execute a block of Ruby code with Babel.
 This function is called by `org-babel-execute-src-block'."
   (let* ((session (org-babel-ruby-initiate-session
-                  (cdr (assq :session params))))
+                  (cdr (assq :session params)) params))
          (result-params (cdr (assq :result-params params)))
          (result-type (cdr (assq :result-type params)))
          (full-body (org-babel-expand-body:generic
@@ -147,14 +148,15 @@ Emacs-lisp table, otherwise return the results as a 
string."
                 res)
       res)))
 
-(defun org-babel-ruby-initiate-session (&optional session _params)
+(defun org-babel-ruby-initiate-session (&optional session params)
   "Initiate a ruby session.
 If there is not a current inferior-process-buffer in SESSION
 then create one.  Return the initialized session."
   (unless (string= session "none")
     (require 'inf-ruby)
-    (let* ((cmd (cdr (assoc inf-ruby-default-implementation
-                           inf-ruby-implementations)))
+    (let* ((cmd (cdr (or (assq :ruby params)
+                        (assoc inf-ruby-default-implementation
+                               inf-ruby-implementations))))
           (buffer (get-buffer (format "*%s*" session)))
           (session-buffer (or buffer (save-window-excursion
                                        (run-ruby cmd session)
diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el
index be74dfd..ef64f58 100644
--- a/lisp/org/org-element.el
+++ b/lisp/org/org-element.el
@@ -4144,7 +4144,9 @@ If STRING is the empty string or nil, return nil."
          (dolist (v local-variables)
            (ignore-errors
              (if (symbolp v) (makunbound v)
-               (set (make-local-variable (car v)) (cdr v)))))
+               ;; Don't set file name to avoid mishandling hooks (bug#44524)
+               (unless (memq (car v) '(buffer-file-name buffer-file-truename))
+                 (set (make-local-variable (car v)) (cdr v))))))
          ;; Transferring local variables may put the temporary buffer
          ;; into a read-only state.  Make sure we can insert STRING.
          (let ((inhibit-read-only t)) (insert string))
diff --git a/lisp/org/ox-odt.el b/lisp/org/ox-odt.el
index a148631..229b524 100644
--- a/lisp/org/ox-odt.el
+++ b/lisp/org/ox-odt.el
@@ -2199,10 +2199,10 @@ SHORT-CAPTION are strings."
 (defun org-odt--image-size
   (file info &optional user-width user-height scale dpi embed-as)
   (let* ((--pixels-to-cms
-         (function (lambda (pixels dpi)
-                     (let ((cms-per-inch 2.54)
-                           (inches (/ pixels dpi)))
-                       (* cms-per-inch inches)))))
+          (lambda (pixels dpi)
+            (let ((cms-per-inch 2.54)
+                  (inches (/ pixels dpi)))
+              (* cms-per-inch inches))))
         (--size-in-cms
          (function
           (lambda (size-in-pixels dpi)
diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el
index 679f2e9..a744165 100644
--- a/lisp/pcomplete.el
+++ b/lisp/pcomplete.el
@@ -291,9 +291,8 @@ generate the completions list.  This means that the hook
   `(pcomplete--here (lambda () ,form) ,stub ,paring ,form-only))
 
 (defcustom pcomplete-command-completion-function
-  (function
-   (lambda ()
-     (pcomplete-here (pcomplete-executables))))
+  (lambda ()
+    (pcomplete-here (pcomplete-executables)))
   "Function called for completing the initial command argument."
   :type 'function)
 
@@ -302,9 +301,8 @@ generate the completions list.  This means that the hook
   :type 'function)
 
 (defcustom pcomplete-default-completion-function
-  (function
-   (lambda ()
-     (while (pcomplete-here (pcomplete-entries)))))
+  (lambda ()
+    (while (pcomplete-here (pcomplete-entries))))
   "Function called when no completion rule can be found.
 This function is used to generate completions for every argument."
   :type 'function)
@@ -988,9 +986,8 @@ Arguments NO-GANGING and ARGS-FOLLOW are currently ignored."
            (setq index (1+ index))))
        (throw 'pcomplete-completions
               (mapcar
-               (function
-                (lambda (opt)
-                  (concat "-" opt)))
+                (lambda (opt)
+                  (concat "-" opt))
                (pcomplete-uniquify-list choices))))
     (let ((arg (pcomplete-arg)))
       (when (and (> (length arg) 1)
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index bd05d91..9e86e46 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -26,9 +26,8 @@
 ;;
 ;;   M-x pixel-scroll-mode RET
 ;;
-;; To make the mode permanent, put these in your init file:
+;; To make the mode permanent, put this in your Init file:
 ;;
-;;   (require 'pixel-scroll)
 ;;   (pixel-scroll-mode 1)
 
 ;;; Commentary:
diff --git a/lisp/play/bubbles.el b/lisp/play/bubbles.el
index d512a71..ca23a78 100644
--- a/lisp/play/bubbles.el
+++ b/lisp/play/bubbles.el
@@ -30,13 +30,6 @@
 ;; Bubbles is an implementation of the "Same Game", similar to "Same
 ;; GNOME" and many others, see <https://en.wikipedia.org/wiki/SameGame>.
 
-;; Installation
-;; ------------
-
-;; Add the following lines to your init file:
-;; (add-to-list 'load-path "/path/to/bubbles/")
-;; (autoload 'bubbles "bubbles" "Play Bubbles" t)
-
 ;; ======================================================================
 
 ;;; History:
diff --git a/lisp/play/fortune.el b/lisp/play/fortune.el
index f8859d9..c180fd0 100644
--- a/lisp/play/fortune.el
+++ b/lisp/play/fortune.el
@@ -1,4 +1,4 @@
-;;; fortune.el --- use fortune to create signatures
+;;; fortune.el --- use fortune to create signatures  -*- lexical-binding: t -*-
 
 ;; Copyright (C) 1999, 2001-2020 Free Software Foundation, Inc.
 
@@ -63,76 +63,75 @@
   :link '(emacs-commentary-link "fortune.el")
   :version "21.1"
   :group 'games)
-(defgroup fortune-signature nil
-  "Settings for use of fortune for signatures."
-  :group 'fortune
-  :group 'mail)
 
 (defcustom fortune-dir "~/docs/ascii/misc/fortunes/"
   "The directory to look in for local fortune cookies files."
-  :type 'directory
-  :group 'fortune)
+  :type 'directory)
+
 (defcustom fortune-file
   (expand-file-name "usenet" fortune-dir)
   "The file in which local fortune cookies will be stored."
-  :type 'file
-  :group 'fortune)
+  :type 'file)
+
 (defcustom fortune-database-extension  ".dat"
   "The extension of the corresponding fortune database.
 Normally you won't have a reason to change it."
-  :type 'string
-  :group 'fortune)
+  :type 'string)
+
 (defcustom fortune-program "fortune"
   "Program to select a fortune cookie."
-  :type 'string
-  :group 'fortune)
+  :type 'string)
+
 (defcustom fortune-program-options ()
   "List of options to pass to the fortune program."
   :type '(choice (repeat (string :tag "Option"))
                  (string :tag "Obsolete string of options"))
-  :version "23.1"
-  :group 'fortune)
+  :version "23.1")
+
 (defcustom fortune-strfile "strfile"
   "Program to compute a new fortune database."
-  :type 'string
-  :group 'fortune)
+  :type 'string)
+
 (defcustom fortune-strfile-options ""
   "Options to pass to the strfile program (a string)."
-  :type 'string
-  :group 'fortune)
+  :type 'string)
+
 (defcustom fortune-quiet-strfile-options "> /dev/null"
   "Text added to the command for running `strfile'.
 By default it discards the output produced by `strfile'.
 Set this to \"\" if you would like to see the output."
-  :type 'string
-  :group 'fortune)
+  :type 'string)
 
 (defcustom fortune-always-compile t
   "Non-nil means automatically compile fortune files.
 If nil, you must invoke `fortune-compile' manually to do that."
-  :type 'boolean
-  :group 'fortune)
+  :type 'boolean)
+
+(defgroup fortune-signature nil
+  "Settings for use of fortune for signatures."
+  :group 'fortune
+  :group 'mail)
+
 (defcustom fortune-author-line-prefix "                  -- "
   "Prefix to put before the author name of a fortunate."
-  :type 'string
-  :group 'fortune-signature)
+  :type 'string)
+
 (defcustom fortune-fill-column fill-column
   "Fill column for fortune files."
-  :type 'integer
-  :group 'fortune-signature)
+  :type 'integer)
+
 (defcustom fortune-from-mail "private e-mail"
   "String to use to characterize that the fortune comes from an e-mail.
 No need to add an `in'."
-  :type 'string
-  :group 'fortune-signature)
+  :type 'string)
+
 (defcustom fortune-sigstart ""
   "Some text to insert before the fortune cookie, in a mail signature."
-  :type 'string
-  :group 'fortune-signature)
+  :type 'string)
+
 (defcustom fortune-sigend ""
   "Some text to insert after the fortune cookie, in a mail signature."
-  :type 'string
-  :group 'fortune-signature)
+  :type 'string)
 
 
 ;; not customizable settings
@@ -297,7 +296,7 @@ specifies the file to choose the fortune from."
         (erase-buffer)
         (if fortune-always-compile
             (fortune-compile fort-file))
-        (apply 'call-process
+        (apply #'call-process
                fortune-program            ; program to call
                nil fortune-buffer nil     ; INFILE BUFFER DISPLAY
                (append (if (stringp fortune-program-options)
@@ -334,7 +333,6 @@ and choose the directory as the fortune-file."
   (setq buffer-read-only t))
 
 
-;;; Provide ourselves.
 (provide 'fortune)
 
 ;;; fortune.el ends here
diff --git a/lisp/play/handwrite.el b/lisp/play/handwrite.el
index 7b4a59b..1cf690a 100644
--- a/lisp/play/handwrite.el
+++ b/lisp/play/handwrite.el
@@ -41,16 +41,8 @@
 ;; If you are not satisfied with the type page there are a number of
 ;; variables you may want to set.
 ;;
-;;
-;;  Installation
-;;
-;; type at your prompt "emacs -l handwrite.el" or put this file on your
-;; Emacs Lisp load path, add the following into your init file:
-;;
-;;                (require 'handwrite)
-;;
-;; "M-x handwrite"  or "Write by hand"  in the edit menu should work now.
-;;
+;; To use this, say "M-x handwrite" or type at your prompt
+;; "emacs -l handwrite.el".
 ;;
 ;; I tried to make it `iso_8859_1'-friendly, but there are some exotic
 ;; characters missing.
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index 6172afe..7884d4b 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -1115,7 +1115,7 @@ arglist-cont."
              (vector (+ (current-column) c-basic-offset))))
        (vector 0)))))
 
-(defun c-lineup-2nd-brace-entry-in-arglist (langelem)
+(defun c-lineup-2nd-brace-entry-in-arglist (_langelem)
   "Lineup the second entry of a brace block under the first, when the first
 line is also contained in an arglist or an enclosing brace ON THAT LINE.
 
@@ -1156,7 +1156,7 @@ Works with brace-list-intro."
              (eq (char-after) ?{))))
        'c-lineup-arglist-intro-after-paren))
 
-(defun c-lineup-class-decl-init-+ (langelem)
+(defun c-lineup-class-decl-init-+ (_langelem)
   "Line up the second entry of a class (etc.) initializer c-basic-offset
 characters in from the identifier when:
 \(i) The type is a class, struct, union, etc. (but not an enum);
@@ -1197,7 +1197,7 @@ Works with: brace-list-intro."
            (eq (point) init-pos)
            (vector (+ (current-column) c-basic-offset)))))))
 
-(defun c-lineup-class-decl-init-after-brace (langelem)
+(defun c-lineup-class-decl-init-after-brace (_langelem)
   "Line up the second entry of a class (etc.) initializer after its opening
 brace when:
 \(i) The type is a class, struct, union, etc. (but not an enum);
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 4425e27..0ce3b3f 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -907,7 +907,6 @@ settings of `c-cleanup-list' are done."
     (when (and (boundp 'electric-pair-mode)
               electric-pair-mode)
       (let ((size (buffer-size))
-           (c-in-electric-pair-functionality t)
            post-self-insert-hook)
        (electric-pair-post-self-insert-function)
        (setq got-pair-} (and at-eol
@@ -2327,7 +2326,7 @@ with a brace block, at the outermost level of nesting."
        (c-save-buffer-state ((paren-state (c-parse-state))
                              (orig-point-min (point-min))
                              (orig-point-max (point-max))
-                             lim name where limits fdoc)
+                             lim name limits where)
          (setq lim (c-widen-to-enclosing-decl-scope
                     paren-state orig-point-min orig-point-max))
          (and lim (setq lim (1- lim)))
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index 77e263f..c82b3a3 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -434,9 +434,8 @@ to it is returned.  This function does not modify the point 
or the mark."
         (setq count (+ count (skip-chars-backward "\\\\"))))
        (not (zerop (logand count 1))))))
 
-(defmacro c-will-be-unescaped (beg end)
-  ;; Would the character after END be unescaped after the removal of (BEG END)?
-  ;; This is regardless of its current status.  It is assumed that (>= POS 
END).
+(defmacro c-will-be-unescaped (beg)
+  ;; Would the character after BEG be unescaped?
   `(save-excursion
     (let (count)
       (goto-char ,beg)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 75e2f0d..252eec1 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -2705,7 +2705,7 @@ comment at the start of cc-engine.el for more info."
   (if (and (consp elt) (>= (length elt) 3))
       ;; Inside a string or comment
       (let ((depth 0) (containing nil) (last nil)
-           in-string in-comment (after-quote nil)
+           in-string in-comment
            (min-depth 0) com-style com-str-start (intermediate nil)
            (char-1 (nth 3 elt))        ; first char of poss. 2-char construct
            (pos (car elt))
@@ -3024,7 +3024,7 @@ comment at the start of cc-engine.el for more info."
 (defun c-full-trim-near-cache ()
   ;; Remove stale entries in `c-full-lit-near-cache', i.e. those whose END
   ;; entries, or positions, are above `c-full-near-cache-limit'.
-  (let ((nc-list c-full-lit-near-cache) elt)
+  (let ((nc-list c-full-lit-near-cache))
     (while nc-list
       (let ((elt (car nc-list)))
        (if (if (car (cddr elt))
@@ -7625,8 +7625,7 @@ comment at the start of cc-engine.el for more info."
   ;; entire raw string (when properly terminated) or just the delimiter
   ;; (otherwise).  In either of these cases, return t, otherwise return nil.
   ;;
-  (let ((here (point))
-       in-macro macro-end id Rquote found)
+  (let (in-macro macro-end)
     (when
        (and
         (eq (char-before (1- (point))) ?R)
@@ -9377,8 +9376,8 @@ This function might do hidden buffer changes."
        maybe-typeless
        ;; Save the value of kwd-sym between loops of the "Check for a
        ;; type" loop.  Needed to distinguish a C++11 "auto" from a pre
-       ;; C++11 one.
-       prev-kwd-sym
+       ;; C++11 one.  (Commented out, 2020-11-01).
+       ;; prev-kwd-sym
        ;; If a specifier is found that also can be a type prefix,
        ;; these flags are set instead of those above.  If we need to
        ;; back up an identifier, they are copied to the real flag
@@ -9537,7 +9536,7 @@ This function might do hidden buffer changes."
                    ;; specifier keyword and we know we're in a
                    ;; declaration.
                    (setq at-decl-or-cast t)
-                   (setq prev-kwd-sym kwd-sym)
+                   ;; (setq prev-kwd-sym kwd-sym)
 
                    (goto-char kwd-clause-end))))
 
@@ -11252,7 +11251,7 @@ comment at the start of cc-engine.el for more info."
               (c-syntactic-re-search-forward ";" nil 'move t)))
       nil)))
 
-(defun c-looking-at-decl-block (_containing-sexp goto-start &optional limit)
+(defun c-looking-at-decl-block (goto-start &optional limit)
   ;; Assuming the point is at an open brace, check if it starts a
   ;; block that contains another declaration level, i.e. that isn't a
   ;; statement block or a brace list, and if so return non-nil.
@@ -11432,9 +11431,7 @@ comment at the start of cc-engine.el for more info."
                                        ; *c-looking-at-decl-block
                                        ; containing-sexp goto-start &optional
                                        ; limit)
-       (when (and (c-looking-at-decl-block
-                   (c-pull-open-brace paren-state)
-                   nil)
+       (when (and (c-looking-at-decl-block nil)
                   (looking-at c-class-key))
          (goto-char (match-end 1))
          (c-forward-syntactic-ws)
@@ -11453,9 +11450,7 @@ comment at the start of cc-engine.el for more info."
       (save-excursion
        (goto-char open-paren-pos)
        (when (and (eq (char-after) ?{)
-                  (c-looking-at-decl-block
-                   (c-safe-position open-paren-pos paren-state)
-                   nil))
+                  (c-looking-at-decl-block nil))
          (back-to-indentation)
          (vector (point) open-paren-pos))))))
 
@@ -11468,7 +11463,7 @@ comment at the start of cc-engine.el for more info."
     (while (and open-brace
                (save-excursion
                  (goto-char open-brace)
-                 (not (c-looking-at-decl-block next-open-brace nil))))
+                 (not (c-looking-at-decl-block nil))))
       (setq open-brace next-open-brace
            next-open-brace (c-pull-open-brace paren-state)))
     open-brace))
@@ -11786,7 +11781,7 @@ comment at the start of cc-engine.el for more info."
                               (goto-char (car res))
                               (c-do-declarators
                                (point-max) t nil nil
-                               (lambda (id-start id-end tok not-top func init)
+                               (lambda (id-start _id-end _tok _not-top _func 
_init)
                                  (cond
                                   ((> id-start after-type-id-pos)
                                    (throw 'find-decl nil))
@@ -11876,7 +11871,7 @@ comment at the start of cc-engine.el for more info."
            (or accept-in-paren (not (eq (cdr bufpos) 'in-paren)))
            (car bufpos))))))
 
-(defun c-looking-at-special-brace-list (&optional _lim)
+(defun c-looking-at-special-brace-list ()
   ;; If we're looking at the start of a pike-style list, i.e., `({ })',
   ;; `([ ])', `(< >)', etc., a cons of a cons of its starting and ending
   ;; positions and its entry in c-special-brace-lists is returned, nil
@@ -12506,8 +12501,7 @@ comment at the start of cc-engine.el for more info."
 (defun c-add-class-syntax (symbol
                           containing-decl-open
                           containing-decl-start
-                          containing-decl-kwd
-                          _paren-state)
+                          containing-decl-kwd)
   ;; The inclass and class-close syntactic symbols are added in
   ;; several places and some work is needed to fix everything.
   ;; Therefore it's collected here.
@@ -12556,7 +12550,7 @@ comment at the start of cc-engine.el for more info."
        ;; CASE B.1: class-open
        ((save-excursion
          (and (eq (char-after) ?{)
-              (c-looking-at-decl-block containing-sexp t)
+              (c-looking-at-decl-block t)
               (setq beg-of-same-or-containing-stmt (point))))
        (c-add-syntax 'class-open beg-of-same-or-containing-stmt))
 
@@ -12759,10 +12753,7 @@ comment at the start of cc-engine.el for more info."
                   (goto-char containing-sexp)
                   (eq (char-after) ?{))
                 (setq placeholder
-                      (c-looking-at-decl-block
-                       (c-most-enclosing-brace paren-state
-                                               containing-sexp)
-                       t)))
+                      (c-looking-at-decl-block t)))
        (setq containing-decl-open containing-sexp
              containing-decl-start (point)
              containing-sexp nil)
@@ -13004,8 +12995,7 @@ comment at the start of cc-engine.el for more info."
               (setq placeholder (c-add-class-syntax 'inclass
                                                     containing-decl-open
                                                     containing-decl-start
-                                                    containing-decl-kwd
-                                                    paren-state))
+                                                    containing-decl-kwd))
               ;; Append access-label with the same anchor point as
               ;; inclass gets.
               (c-append-syntax 'access-label placeholder))
@@ -13077,7 +13067,7 @@ comment at the start of cc-engine.el for more info."
           ((save-excursion
              (let (tmp)
                (and (eq char-after-ip ?{)
-                    (setq tmp (c-looking-at-decl-block containing-sexp t))
+                    (setq tmp (c-looking-at-decl-block t))
                     (progn
                       (setq placeholder (point))
                       (goto-char tmp)
@@ -13098,7 +13088,7 @@ comment at the start of cc-engine.el for more info."
              (goto-char indent-point)
              (skip-chars-forward " \t")
              (and (eq (char-after) ?{)
-                  (c-looking-at-decl-block containing-sexp t)
+                  (c-looking-at-decl-block t)
                   (setq placeholder (point))))
            (c-add-syntax 'class-open placeholder))
 
@@ -13138,8 +13128,7 @@ comment at the start of cc-engine.el for more info."
            (c-add-class-syntax 'inclass
                                containing-decl-open
                                containing-decl-start
-                               containing-decl-kwd
-                               paren-state))
+                               containing-decl-kwd))
 
           ;; CASE 5A.5: ordinary defun open
           (t
@@ -13202,8 +13191,7 @@ comment at the start of cc-engine.el for more info."
                (c-add-class-syntax 'inclass
                                    containing-decl-open
                                    containing-decl-start
-                                   containing-decl-kwd
-                                   paren-state)))
+                                   containing-decl-kwd)))
 
           ;; CASE 5B.4: Nether region after a C++ or Java func
           ;; decl, which could include a `throws' declaration.
@@ -13273,8 +13261,7 @@ comment at the start of cc-engine.el for more info."
                (c-add-class-syntax 'inclass
                                    containing-decl-open
                                    containing-decl-start
-                                   containing-decl-kwd
-                                   paren-state)))
+                                   containing-decl-kwd)))
 
           ;; CASE 5C.3: in a Java implements/extends
           (injava-inher
@@ -13460,8 +13447,7 @@ comment at the start of cc-engine.el for more info."
          (c-add-class-syntax 'class-close
                              containing-decl-open
                              containing-decl-start
-                             containing-decl-kwd
-                             paren-state))
+                             containing-decl-kwd))
 
         ;; CASE 5H: we could be looking at subsequent knr-argdecls
         ((and c-recognize-knr-p
@@ -13582,8 +13568,7 @@ comment at the start of cc-engine.el for more info."
                (c-add-class-syntax 'inclass
                                    containing-decl-open
                                    containing-decl-start
-                                   containing-decl-kwd
-                                   paren-state)))
+                                   containing-decl-kwd)))
          (when (and c-syntactic-indentation-in-macros
                     macro-start
                     (/= macro-start (c-point 'boi indent-point)))
@@ -13899,7 +13884,7 @@ comment at the start of cc-engine.el for more info."
                           (save-excursion
                             (goto-char indent-point)
                             (c-forward-syntactic-ws (c-point 'eol))
-                            (c-looking-at-special-brace-list (point)))))
+                            (c-looking-at-special-brace-list))))
                  (c-add-syntax 'brace-entry-open (point))
                (c-add-stmt-syntax 'brace-list-entry nil t containing-sexp
                                   paren-state (point))
@@ -13965,9 +13950,7 @@ comment at the start of cc-engine.el for more info."
            (and lim
                 (progn
                   (goto-char lim)
-                  (c-looking-at-decl-block
-                   (c-most-enclosing-brace paren-state lim)
-                   nil))
+                  (c-looking-at-decl-block nil))
                 (setq placeholder (point))))
          (c-backward-to-decl-anchor lim)
          (back-to-indentation)
@@ -14135,9 +14118,7 @@ comment at the start of cc-engine.el for more info."
                (and (progn
                       (goto-char placeholder)
                       (eq (char-after) ?{))
-                    (c-looking-at-decl-block (c-most-enclosing-brace
-                                              paren-state (point))
-                                             nil))))
+                    (c-looking-at-decl-block nil))))
          (c-backward-to-decl-anchor lim)
          (back-to-indentation)
          (c-add-syntax 'defun-block-intro (point)))
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index c6dd671..c5201d1 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1482,7 +1482,7 @@ Note that the style variables are always made local to 
the buffer."
           ((and
             (c-is-escaped end)
             (or (eq beg end) ; .... by inserting stuff between \ and \n?
-                (c-will-be-unescaped beg end))) ;  ... by removing an odd 
number of \s?
+                (c-will-be-unescaped beg))) ;  ... by removing an odd number 
of \s?
            (goto-char (1+ end))) ; To after the NL which is being unescaped.
           (t
            (goto-char end)))
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 6178cdf..a42ace1 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -3441,8 +3441,8 @@ Should be called with the point before leading colon of 
an attribute."
           (match-beginning 4) (match-end 4)
           'face dashface))
       ;; save match data (for looking-at)
-      (setq lll (mapcar (function (lambda (elt) (cons (match-beginning elt)
-                                                (match-end elt))))
+      (setq lll (mapcar (lambda (elt) (cons (match-beginning elt)
+                                       (match-end elt)))
                         l))
       (while lll
        (setq ll (car lll))
@@ -5983,6 +5983,7 @@ else
      (cperl-continued-brace-offset     .  0)
      (cperl-label-offset               . -2)
      (cperl-continued-statement-offset .  4)
+     (cperl-close-paren-offset         . -4)
      (cperl-extra-newline-before-brace .  nil)
      (cperl-extra-newline-before-brace-multiline .  nil)
      (cperl-merge-trailing-else        .  nil)
@@ -6757,10 +6758,10 @@ One may build such TAGS files from CPerl mode menu."
   (require 'etags)
   (require 'imenu)
   (if (or update (null (nth 2 cperl-hierarchy)))
-      (let ((remover (function (lambda (elt) ; (name (file1...) (file2..))
-                                (or (nthcdr 2 elt)
-                                    ;; Only in one file
-                                    (setcdr elt (cdr (nth 1 elt)))))))
+      (let ((remover (lambda (elt) ; (name (file1...) (file2..))
+                       (or (nthcdr 2 elt)
+                           ;; Only in one file
+                           (setcdr elt (cdr (nth 1 elt))))))
            to l1 l2 l3)
        ;; (setq cperl-hierarchy '(() () ())) ; Would write into '() later!
        (setq cperl-hierarchy (list l1 l2 l3))
@@ -6840,33 +6841,33 @@ One may build such TAGS files from CPerl mode menu."
     (setq ord 2)
     (mapc move-deeper methods)
     (if recurse
-       (mapc (function (lambda (elt)
-                         (cperl-tags-treeify elt (1+ level))))
+        (mapc (lambda (elt)
+                (cperl-tags-treeify elt (1+ level)))
              (cdr to)))
     ;;Now clean up leaders with one child only
-    (mapc (function (lambda (elt)
-                     (if (not (and (listp (cdr elt))
-                                   (eq (length elt) 2)))
-                          nil
-                       (setcar elt (car (nth 1 elt)))
-                       (setcdr elt (cdr (nth 1 elt))))))
+    (mapc (lambda (elt)
+            (if (not (and (listp (cdr elt))
+                          (eq (length elt) 2)))
+                nil
+              (setcar elt (car (nth 1 elt)))
+              (setcdr elt (cdr (nth 1 elt)))))
          (cdr to))
     ;; Sort the roots of subtrees
     (if (default-value 'imenu-sort-function)
        (setcdr to
                (sort (cdr to) (default-value 'imenu-sort-function))))
     ;; Now add back functions removed from display
-    (mapc (function (lambda (elt)
-                     (setcdr to (cons elt (cdr to)))))
+    (mapc (lambda (elt)
+            (setcdr to (cons elt (cdr to))))
          (if (default-value 'imenu-sort-function)
              (nreverse
               (sort root-functions (default-value 'imenu-sort-function)))
            root-functions))
     ;; Now add back packages removed from display
-    (mapc (function (lambda (elt)
-                     (setcdr to (cons (cons (concat "package " (car elt))
-                                            (cdr elt))
-                                      (cdr to)))))
+    (mapc (lambda (elt)
+            (setcdr to (cons (cons (concat "package " (car elt))
+                                   (cdr elt))
+                             (cdr to))))
          (if (default-value 'imenu-sort-function)
              (nreverse
               (sort root-packages (default-value 'imenu-sort-function)))
@@ -8210,11 +8211,11 @@ a result of qr//, this is not a performance hit), t for 
the rest."
     (and (eq (get-text-property beg 'syntax-type) 'string)
         (setq beg (next-single-property-change beg 'syntax-type nil limit)))
     (cperl-map-pods-heres
-     (function (lambda (s _e _p)
-                (if (memq (get-text-property s 'REx-interpolated) skip)
-                    t
-                  (setq pp s)
-                  nil)))       ; nil stops
+     (lambda (s _e _p)
+       (if (memq (get-text-property s 'REx-interpolated) skip)
+           t
+         (setq pp s)
+         nil)) ; nil stops
      'REx-interpolated beg limit)
     (if pp (goto-char pp)
       (message "No more interpolated REx"))))
@@ -8333,7 +8334,7 @@ start with default arguments, then refine the slowdown 
regions."
   (or l (setq l 1))
   (or step (setq step 500))
   (or lim (setq lim 40))
-  (let* ((timems (function (lambda () (car (cperl--time-convert nil 1000)))))
+  (let* ((timems (lambda () (car (cperl--time-convert nil 1000))))
         (tt (funcall timems)) (c 0) delta tot)
     (goto-char (point-min))
     (forward-line (1- l))
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
index ac3d081..8596d78 100644
--- a/lisp/progmodes/make-mode.el
+++ b/lisp/progmodes/make-mode.el
@@ -1600,20 +1600,19 @@ Checks each target in TARGET-TABLE using
 and generates the overview, one line per target name."
   (insert
    (mapconcat
-    (function (lambda (item)
-               (let* ((target-name (car item))
-                      (no-prereqs (not (member target-name prereq-list)))
-                      (needs-rebuild (or no-prereqs
-                                         (funcall
-                                          
makefile-query-one-target-method-function
-                                          target-name
-                                          filename))))
-                 (format "\t%s%s"
-                         target-name
-                         (cond (no-prereqs "  .. has no prerequisites")
-                               (needs-rebuild "  .. NEEDS REBUILD")
-                               (t "  .. is up to date"))))
-               ))
+    (lambda (item)
+      (let* ((target-name (car item))
+             (no-prereqs (not (member target-name prereq-list)))
+             (needs-rebuild (or no-prereqs
+                                (funcall
+                                 makefile-query-one-target-method-function
+                                 target-name
+                                 filename))))
+        (format "\t%s%s"
+                target-name
+                (cond (no-prereqs "  .. has no prerequisites")
+                      (needs-rebuild "  .. NEEDS REBUILD")
+                      (t "  .. is up to date")))))
     target-table "\n"))
   (goto-char (point-min))
   (delete-file filename))              ; remove the tmpfile
@@ -1687,9 +1686,9 @@ Then prompts for all required parameters."
 
 (defun makefile-prompt-for-gmake-funargs (function-name prompt-list)
   (mapconcat
-   (function (lambda (one-prompt)
-              (read-string (format "[%s] %s: " function-name one-prompt)
-                           nil)))
+   (lambda (one-prompt)
+     (read-string (format "[%s] %s: " function-name one-prompt)
+                  nil))
    prompt-list
    ","))
 
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 6c647a0..a395453 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -745,8 +745,7 @@ pattern to search for."
 ;;;###autoload
 (defun project-find-file ()
   "Visit a file (with completion) in the current project.
-The completion default is the filename at point, if one is
-recognized."
+The completion default is the string at point."
   (interactive)
   (let* ((pr (project-current t))
          (dirs (list (project-root pr))))
@@ -755,8 +754,7 @@ recognized."
 ;;;###autoload
 (defun project-or-external-find-file ()
   "Visit a file (with completion) in the current project or external roots.
-The completion default is the filename at point, if one is
-recognized."
+The completion default is the string at point."
   (interactive)
   (let* ((pr (project-current t))
          (dirs (cons
@@ -1160,7 +1158,9 @@ With some possible metadata (to be decided).")
   (let ((filename project-list-file))
     (with-temp-buffer
       (insert ";;; -*- lisp-data -*-\n")
-      (pp project--list (current-buffer))
+      (let ((print-length nil)
+            (print-level nil))
+        (pp project--list (current-buffer)))
       (write-region nil nil filename nil 'silent))))
 
 ;;;###autoload
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index d6feba2..091456a 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -29,7 +29,7 @@
 
 ;; Major mode for editing Python files with some fontification and
 ;; indentation bits extracted from original Dave Love's python.el
-;; found in GNU/Emacs.
+;; found in GNU Emacs.
 
 ;; Implements Syntax highlighting, Indentation, Movement, Shell
 ;; interaction, Shell completion, Shell virtualenv support, Shell
@@ -247,13 +247,6 @@
 ;; I'd recommend the first one since you'll get the same behavior for
 ;; all modes out-of-the-box.
 
-;;; Installation:
-
-;; Add this to your .emacs:
-
-;; (add-to-list 'load-path "/folder/containing/file")
-;; (require 'python)
-
 ;;; TODO:
 
 ;;; Code:
@@ -662,10 +655,11 @@ builtins.")
     ;; assignments
     ;; support for a = b = c = 5
     (,(lambda (limit)
-        (let ((re (python-rx (group (+ (any word ?. ?_)))
-                             (? ?\[ (+ (not (any  ?\]))) ?\]) (* space)
-                             ;; A type, like " : int ".
-                             (? ?: (* space) (+ (any word ?. ?_)) (* space))
+        (let ((re (python-rx (group symbol-name)
+                             ;; subscript, like "[5]"
+                             (? ?\[ (+ (not ?\])) ?\]) (* space)
+                             ;; type hint, like ": int" or ": Mapping[int, 
str]"
+                             (? ?: (* space) (+ not-simple-operator) (* space))
                              assignment-operator))
               (res nil))
           (while (and (setq res (re-search-forward re limit t))
@@ -675,9 +669,9 @@ builtins.")
      (1 font-lock-variable-name-face nil nil))
     ;; support for a, b, c = (1, 2, 3)
     (,(lambda (limit)
-        (let ((re (python-rx (group (+ (any word ?. ?_))) (* space)
-                             (* ?, (* space) (+ (any word ?. ?_)) (* space))
-                             ?, (* space) (+ (any word ?. ?_)) (* space)
+        (let ((re (python-rx (group symbol-name) (* space)
+                             (* ?, (* space) symbol-name (* space))
+                             ?, (* space) symbol-name (* space)
                              assignment-operator))
               (res nil))
           (while (and (setq res (re-search-forward re limit t))
@@ -2921,7 +2915,7 @@ process buffer for a list of commands.)"
          (python-shell-make-comint
           (or cmd (python-shell-calculate-command))
           (python-shell-get-process-name dedicated) show)))
-    (pop-to-buffer buffer)
+    (set-buffer buffer)
     (get-buffer-process buffer)))
 
 (defun run-python-internal ()
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 14f0059..fbc6e42 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -28,13 +28,6 @@
 
 ;; Provides font-locking, indentation support, and navigation for Ruby code.
 ;;
-;; If you're installing manually, you should add this to your .emacs
-;; file after putting it on your load path:
-;;
-;;    (autoload 'ruby-mode "ruby-mode" "Major mode for ruby files" t)
-;;    (add-to-list 'auto-mode-alist '("\\.rb\\'" . ruby-mode))
-;;    (add-to-list 'interpreter-mode-alist '("ruby" . ruby-mode))
-;;
 ;; Still needs more docstrings; search below for TODO.
 
 ;;; Code:
@@ -2436,7 +2429,7 @@ If there is no Rubocop config file, Rubocop will be 
passed a flag
                                      "\\)"
                                      "\\|/"
                                      "\\(?:Gem\\|Rake\\|Cap\\|Thor"
-                                     "\\|Puppet\\|Berks"
+                                     "\\|Puppet\\|Berks\\|Brew"
                                      "\\|Vagrant\\|Guard\\|Pod\\)file"
                                      "\\)\\'"))
                    'ruby-mode))
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 3d66483..f288fac 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -5336,9 +5336,6 @@ Key bindings:
 (defvar vhdl-reserved-words-regexp nil
   "Regexp for additional reserved words.")
 
-(defvar vhdl-directive-keywords-regexp nil
-  "Regexp for compiler directive keywords.")
-
 (defun vhdl-upcase-list (condition list)
   "Upcase all elements in LIST based on CONDITION."
   (when condition
@@ -5416,9 +5413,6 @@ Key bindings:
                  (concat vhdl-forbidden-syntax "\\|"))
                (regexp-opt vhdl-reserved-words)
                "\\)\\>"))
-  (setq vhdl-directive-keywords-regexp
-       (concat "\\<\\(" (mapconcat 'regexp-quote
-                                   vhdl-directive-keywords "\\|") "\\)\\>"))
   (vhdl-abbrev-list-init))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -13631,7 +13625,10 @@ This does background highlighting of translate-off 
regions.")
                            vhdl-template-prompt-syntax ">\\)")
                    2 'vhdl-font-lock-prompt-face t)
              (list (concat "--\\s-*"
-                           vhdl-directive-keywords-regexp "\\s-+\\(.*\\)$")
+                            "\\<"
+                            (regexp-opt vhdl-directive-keywords t)
+                            "\\>"
+                            "\\s-+\\(.*\\)$")
                    2 'vhdl-font-lock-directive-face t)
              ;; highlight c-preprocessor directives
              (list "^#[ \t]*\\(\\w+\\)\\([ \t]+\\(\\w+\\)\\)?"
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index a1c4c08..e1dd6e5 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -600,9 +600,9 @@ SELECT is `quit', also quit the *xref* window."
 
 (defun xref-goto-xref (&optional quit)
   "Jump to the xref on the current line and select its window.
-Non-interactively, non-nil QUIT means to first quit the *xref*
-buffer."
-  (interactive)
+Non-interactively, non-nil QUIT, or interactively, with prefix argument
+means to first quit the *xref* buffer."
+  (interactive "P")
   (let* ((buffer (current-buffer))
          (xref (or (xref--item-at-point)
                    (user-error "No reference at point")))
diff --git a/lisp/server.el b/lisp/server.el
index a660dea..763f651 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -354,9 +354,11 @@ Updates `server-clients'."
 
       (setq server-clients (delq proc server-clients))
 
-      ;; Delete the client's tty, except on Windows (both GUI and console),
-      ;; where there's only one terminal and does not make sense to delete it.
-      (unless (eq system-type 'windows-nt)
+      ;; Delete the client's tty, except on Windows (both GUI and
+      ;; console), where there's only one terminal and does not make
+      ;; sense to delete it, or if we are explicitly told not.
+      (unless (or (eq system-type 'windows-nt)
+                  (process-get proc 'no-delete-terminal))
        (let ((terminal (process-get proc 'terminal)))
          ;; Only delete the terminal if it is non-nil.
          (when (and terminal (eq (terminal-live-p terminal) t))
@@ -830,7 +832,6 @@ This handles splitting the command if it would be bigger 
than
     (error "Invalid terminal device"))
   (unless type
     (error "Invalid terminal type"))
-  (add-to-list 'frame-inherited-parameters 'client)
   (let ((frame
          (server-with-environment
              (process-get proc 'env)
@@ -842,32 +843,19 @@ This handles splitting the command if it would be bigger 
than
                "TERMINFO_DIRS" "TERMPATH"
                ;; rxvt wants these
                "COLORFGBG" "COLORTERM")
-           (make-frame `((window-system . nil)
-                         (tty . ,tty)
-                         (tty-type . ,type)
-                         ;; Ignore nowait here; we always need to
-                         ;; clean up opened ttys when the client dies.
-                         (client . ,proc)
-                         ;; This is a leftover from an earlier
-                         ;; attempt at making it possible for process
-                         ;; run in the server process to use the
-                         ;; environment of the client process.
-                         ;; It has no effect now and to make it work
-                         ;; we'd need to decide how to make
-                         ;; process-environment interact with client
-                         ;; envvars, and then to change the
-                         ;; C functions `child_setup' and
-                         ;; `getenv_internal' accordingly.
-                         (environment . ,(process-get proc 'env))
-                         ,@parameters)))))
+           (server--create-frame
+            ;; Ignore nowait here; we always need to
+            ;; clean up opened ttys when the client dies.
+            nil proc
+            `((window-system . nil)
+              (tty . ,tty)
+              (tty-type . ,type)
+              ,@parameters)))))
 
     ;; ttys don't use the `display' parameter, but callproc.c does to set
     ;; the DISPLAY environment on subprocesses.
     (set-frame-parameter frame 'display
                          (getenv-internal "DISPLAY" (process-get proc 'env)))
-    (select-frame frame)
-    (process-put proc 'frame frame)
-    (process-put proc 'terminal (frame-terminal frame))
     frame))
 
 (defun server-create-window-system-frame (display nowait proc parent-id
@@ -893,31 +881,56 @@ This handles splitting the command if it would be bigger 
than
       )
 
     (cond (w
-           ;; Flag frame as client-created, but use a dummy client.
-           ;; This will prevent the frame from being deleted when
-           ;; emacsclient quits while also preventing
-           ;; `server-save-buffers-kill-terminal' from unexpectedly
-           ;; killing emacs on that frame.
-           (let* ((params `((client . ,(if nowait 'nowait proc))
-                            ;; This is a leftover, see above.
-                            (environment . ,(process-get proc 'env))
-                            ,@parameters))
-                  frame)
-             (if parent-id
-                 (push (cons 'parent-id (string-to-number parent-id)) params))
-             (add-to-list 'frame-inherited-parameters 'client)
-             (setq frame (make-frame-on-display display params))
-             (server-log (format "%s created" frame) proc)
-             (select-frame frame)
-             (process-put proc 'frame frame)
-             (process-put proc 'terminal (frame-terminal frame))
-             frame))
+           (server--create-frame
+            nowait proc
+            `((display . ,display)
+              ,@(if parent-id
+                    `((parent-id . ,(string-to-number parent-id))))
+              ,@parameters)))
 
           (t
            (server-log "Window system unsupported" proc)
            (server-send-string proc "-window-system-unsupported \n")
            nil))))
 
+(defun server-create-dumb-terminal-frame (nowait proc &optional parameters)
+  ;; If the destination is a dumb terminal, we can't really run Emacs
+  ;; in its tty.  So instead, we use whichever terminal is currently
+  ;; selected.  This situation typically occurs when `emacsclient' is
+  ;; running inside something like an Emacs shell buffer (bug#25547).
+  (let ((frame (server--create-frame nowait proc parameters)))
+    ;; The client is not the exclusive owner of this terminal, so don't
+    ;; delete the terminal when the client exits.
+    ;; FIXME: Maybe we just shouldn't set the `terminal' property instead?
+    (process-put proc 'no-delete-terminal t)
+    frame))
+
+(defun server--create-frame (nowait proc parameters)
+  (add-to-list 'frame-inherited-parameters 'client)
+  ;; When `nowait' is set, flag frame as client-created, but use
+  ;; a dummy client.  This will prevent the frame from being deleted
+  ;; when emacsclient quits while also preventing
+  ;; `server-save-buffers-kill-terminal' from unexpectedly killing
+  ;; emacs on that frame.
+  (let ((frame (make-frame `((client . ,(if nowait 'nowait proc))
+                             ;; This is a leftover from an earlier
+                             ;; attempt at making it possible for process
+                             ;; run in the server process to use the
+                             ;; environment of the client process.
+                             ;; It has no effect now and to make it work
+                             ;; we'd need to decide how to make
+                             ;; process-environment interact with client
+                             ;; envvars, and then to change the
+                             ;; C functions `child_setup' and
+                             ;; `getenv_internal' accordingly.
+                             (environment . ,(process-get proc 'env))
+                             ,@parameters))))
+    (server-log (format "%s created" frame) proc)
+    (select-frame frame)
+    (process-put proc 'frame frame)
+    (process-put proc 'terminal (frame-terminal frame))
+    frame))
+
 (defun server-goto-toplevel (proc)
   (condition-case nil
       ;; If we're running isearch, we must abort it to allow Emacs to
@@ -1264,6 +1277,9 @@ The following commands are accepted by the client:
                                           terminal-frame)))))
                    (setq tty-name nil tty-type nil)
                    (if display (server-select-display display)))
+                   ((equal tty-type "dumb")
+                    (server-create-dumb-terminal-frame nowait proc
+                                                       frame-parameters))
                   ((or (and (eq system-type 'windows-nt)
                             (daemonp)
                             (setq display "w32"))
diff --git a/lisp/shadowfile.el b/lisp/shadowfile.el
index 6bea5e2..a7343a9 100644
--- a/lisp/shadowfile.el
+++ b/lisp/shadowfile.el
@@ -524,10 +524,9 @@ call it manually."
       (if (called-interactively-p 'interactive)
          (message "No files need to be shadowed."))
     (save-excursion
-      (map-y-or-n-p (function
-                    (lambda (pair)
-                      (or arg shadow-noquery
-                          (format "Copy shadow file %s? " (cdr pair)))))
+      (map-y-or-n-p (lambda (pair)
+                      (or arg shadow-noquery
+                          (format "Copy shadow file %s? " (cdr pair))))
                    (function shadow-copy-file)
                    shadow-files-to-copy
                    '("shadow" "shadows" "copy"))
@@ -540,11 +539,11 @@ them again, unless you make more changes to the files.  
To cancel a shadow
 permanently, remove the group from `shadow-literal-groups' or
 `shadow-regexp-groups'."
   (interactive)
-  (map-y-or-n-p (function (lambda (pair)
-                           (format "Cancel copying %s to %s? "
-                                   (car pair) (cdr pair))))
-               (function (lambda (pair)
-                           (shadow-remove-from-todo pair)))
+  (map-y-or-n-p (lambda (pair)
+                  (format "Cancel copying %s to %s? "
+                          (car pair) (cdr pair)))
+                (lambda (pair)
+                  (shadow-remove-from-todo pair))
                shadow-files-to-copy
                '("shadow" "shadows" "cancel copy"))
   (message "There are %d shadows to be updated."
@@ -601,8 +600,8 @@ and to are absolute file names."
                             shadow-homedir))
             (canonical-file (shadow-contract-file-name absolute-file))
             (shadows
-             (mapcar (function (lambda (shadow)
-                                 (cons absolute-file shadow)))
+              (mapcar (lambda (shadow)
+                        (cons absolute-file shadow))
                      (append
                       (shadow-shadows-of-1
                        canonical-file shadow-literal-groups nil)
@@ -632,9 +631,8 @@ Consider them as regular expressions if third arg REGEXP is 
true."
                             "shadow-shadows-of-1: %s %s %s"
                             file (shadow-parse-name file) realname))
                         (mapcar
-                         (function
-                          (lambda (x)
-                            (shadow-replace-name-component x realname)))
+                          (lambda (x)
+                            (shadow-replace-name-component x realname))
                          nonmatching)))
                      (t nonmatching))
                (shadow-shadows-of-1 file (cdr groups) regexp)))))
@@ -791,9 +789,8 @@ look for files that have been changed and need to be copied 
to other systems."
   (save-some-buffers arg t)
   (shadow-copy-files)
   (shadow-save-todo-file)
-  (and (or (not (memq t (mapcar (function
-                                (lambda (buf) (and (buffer-file-name buf)
-                                                   (buffer-modified-p buf))))
+  (and (or (not (memq t (mapcar (lambda (buf) (and (buffer-file-name buf)
+                                              (buffer-modified-p buf)))
                                (buffer-list))))
           (yes-or-no-p "Modified buffers exist; exit anyway? "))
        (or (not (fboundp 'process-list))
diff --git a/lisp/sort.el b/lisp/sort.el
index f878db2..b9a27a8 100644
--- a/lisp/sort.el
+++ b/lisp/sort.el
@@ -251,7 +251,7 @@ the sort order."
       (narrow-to-region beg end)
       (goto-char (point-min))
       (sort-subr reverse
-                (function (lambda () (skip-chars-forward "\n")))
+                 (lambda () (skip-chars-forward "\n"))
                 'forward-page))))
 
 (defvar sort-fields-syntax-table nil)
@@ -316,16 +316,16 @@ FIELD, BEG and END.  BEG and END specify region to sort."
 ;;region to sort."
 ;;  (interactive "p\nr")
 ;;  (sort-fields-1 field beg end
-;;              (function (lambda ()
-;;                          (sort-skip-fields field)
-;;                          (string-to-number
-;;                           (buffer-substring
-;;                            (point)
-;;                            (save-excursion
-;;                              (re-search-forward
-;;                               "[+-]?[0-9]*\\.?[0-9]*\\([eE][+-]?[0-9]+\\)?")
-;;                              (point))))))
-;;              nil))
+;;              (lambda ()
+;;                (sort-skip-fields field)
+;;                (string-to-number
+;;                 (buffer-substring
+;;                  (point)
+;;                  (save-excursion
+;;                    (re-search-forward
+;;                     "[+-]?[0-9]*\\.?[0-9]*\\([eE][+-]?[0-9]+\\)?")
+;;                    (point)))))
+;;              nil))
 
 ;;;###autoload
 (defun sort-fields (field beg end)
@@ -340,10 +340,10 @@ the sort order."
   (let ;; To make `end-of-line' and etc. to ignore fields.
       ((inhibit-field-text-motion t))
     (sort-fields-1 field beg end
-                  (function (lambda ()
-                              (sort-skip-fields field)
-                              nil))
-                  (function (lambda () (skip-chars-forward "^ \t\n"))))))
+                   (lambda ()
+                     (sort-skip-fields field)
+                     nil)
+                   (lambda () (skip-chars-forward "^ \t\n")))))
 
 (defun sort-fields-1 (field beg end startkeyfun endkeyfun)
   (let ((tbl (syntax-table)))
@@ -457,21 +457,21 @@ sRegexp specifying key within record: \nr")
        (goto-char (match-beginning 0))
        (sort-subr reverse
                   'sort-regexp-fields-next-record
-                  (function (lambda ()
-                              (goto-char sort-regexp-record-end)))
-                  (function (lambda ()
-                              (let ((n 0))
-                                (cond ((numberp key-regexp)
-                                       (setq n key-regexp))
-                                      ((re-search-forward
-                                         key-regexp sort-regexp-record-end t)
-                                       (setq n 0))
-                                      (t (throw 'key nil)))
-                                (condition-case ()
-                                    (cons (match-beginning n)
-                                          (match-end n))
-                                  ;; if there was no such register
-                                  (error (throw 'key nil)))))))))))
+                   (lambda ()
+                     (goto-char sort-regexp-record-end))
+                   (lambda ()
+                     (let ((n 0))
+                       (cond ((numberp key-regexp)
+                              (setq n key-regexp))
+                             ((re-search-forward
+                               key-regexp sort-regexp-record-end t)
+                              (setq n 0))
+                             (t (throw 'key nil)))
+                       (condition-case ()
+                           (cons (match-beginning n)
+                                 (match-end n))
+                         ;; if there was no such register
+                         (error (throw 'key nil))))))))))
 
 
 (defvar sort-columns-subprocess t)
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index 991c8a3..3619b23 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -1874,9 +1874,9 @@ matches the user directory ~, then it is replaced with a 
~.
 INDEX is not used, but is required by the caller."
   (let* ((tilde (expand-file-name "~/"))
         (dd (expand-file-name directory))
-        (junk (string-match (regexp-quote tilde) dd))
+        (junk (string-prefix-p "~/" dd))
         (displayme (if junk
-                       (concat "~/" (substring dd (match-end 0)))
+                       (concat "~/" (substring dd 2 nil))
                      dd))
         (p (point)))
     (if (string-match "^~[/\\]?\\'" displayme) (setq displayme tilde))
diff --git a/lisp/strokes.el b/lisp/strokes.el
index c2f03ca..11bc07a 100644
--- a/lisp/strokes.el
+++ b/lisp/strokes.el
@@ -574,9 +574,8 @@ Optional GRID-RESOLUTION may be used in place of 
`strokes-grid-resolution'.
 The grid is a square whose dimension is [0,GRID-RESOLUTION)."
   (or grid-resolution (setq grid-resolution strokes-grid-resolution))
   (let ((stroke-extent (strokes-get-stroke-extent positions)))
-    (mapcar (function
-            (lambda (pos)
-              (strokes-get-grid-position stroke-extent pos grid-resolution)))
+    (mapcar (lambda (pos)
+              (strokes-get-grid-position stroke-extent pos grid-resolution))
            positions)))
 
 (defun strokes-fill-stroke (unfilled-stroke &optional force)
diff --git a/lisp/subr.el b/lisp/subr.el
index 547cf5c..2f35165 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1283,10 +1283,10 @@ The normal global definition of the character C-x 
indirects to this keymap.")
   "Convert a key sequence to a list of events."
   (if (vectorp key)
       (append key nil)
-    (mapcar (function (lambda (c)
-                       (if (> c 127)
-                           (logxor c listify-key-sequence-1)
-                         c)))
+    (mapcar (lambda (c)
+              (if (> c 127)
+                  (logxor c listify-key-sequence-1)
+                c))
            key)))
 
 (defun eventp (object)
@@ -2623,15 +2623,7 @@ keyboard-quit events while waiting for a valid input."
          (unless (get-text-property 0 'face prompt)
            (setq prompt (propertize prompt 'face 'minibuffer-prompt)))
          (setq char (let ((inhibit-quit inhibit-keyboard-quit))
-                      (read-char-from-minibuffer
-                        prompt
-                        ;; If we have a dynamically bound `help-form'
-                        ;; here, then the `C-h' (i.e., `help-char')
-                        ;; character should output that instead of
-                        ;; being a command char.
-                        (if help-form
-                            (cons help-char chars)
-                          chars))))
+                      (read-key prompt)))
          (and show-help (buffer-live-p (get-buffer helpbuf))
               (kill-buffer helpbuf))
          (cond
@@ -2748,7 +2740,7 @@ floating point support."
   "Keymap for the `read-char-from-minibuffer' function.")
 
 (defconst read-char-from-minibuffer-map-hash
-  (make-hash-table :weakness 'key :test 'equal))
+  (make-hash-table :test 'equal))
 
 (defun read-char-from-minibuffer-insert-char ()
   "Insert the character you type in the minibuffer and exit.
@@ -2772,25 +2764,41 @@ Also discard all previous input in the minibuffer."
 (defvar empty-history)
 
 (defun read-char-from-minibuffer (prompt &optional chars history)
-  "Read a character from the minibuffer, prompting for PROMPT.
+  "Read a character from the minibuffer, prompting for it with PROMPT.
 Like `read-char', but uses the minibuffer to read and return a character.
-When CHARS is non-nil, any input that is not one of CHARS is ignored.
-When HISTORY is a symbol, then allows navigating in a history.
-The navigation commands are `M-p' and `M-n', with `RET' to select
-a character from history."
+Optional argument CHARS, if non-nil, should be a list of characters;
+the function will ignore any input that is not one of CHARS.
+Optional argument HISTORY, if non-nil, should be a symbol that
+specifies the history list variable to use for navigating in input
+history using `M-p' and `M-n', with `RET' to select a character from
+history.
+If the caller has set `help-form', there is no need to explicitly add
+`help-char' to chars.  It's bound automatically to `help-form-show'."
   (let* ((empty-history '())
          (map (if (consp chars)
-                  (or (gethash chars read-char-from-minibuffer-map-hash)
-                      (puthash chars
-                               (let ((map (make-sparse-keymap)))
-                                 (set-keymap-parent map 
read-char-from-minibuffer-map)
-                                 (dolist (char chars)
-                                   (define-key map (vector char)
-                                     'read-char-from-minibuffer-insert-char))
-                                 (define-key map [remap self-insert-command]
-                                   'read-char-from-minibuffer-insert-other)
-                                 map)
-                               read-char-from-minibuffer-map-hash))
+                  (or (gethash (list help-form (cons help-char chars))
+                               read-char-from-minibuffer-map-hash)
+                      (let ((map (make-sparse-keymap))
+                            (msg help-form))
+                        (set-keymap-parent map read-char-from-minibuffer-map)
+                        ;; If we have a dynamically bound `help-form'
+                        ;; here, then the `C-h' (i.e., `help-char')
+                        ;; character should output that instead of
+                        ;; being a command char.
+                        (when help-form
+                          (define-key map (vector help-char)
+                            (lambda ()
+                              (interactive)
+                              (let ((help-form msg)) ; lexically bound msg
+                                (help-form-show)))))
+                        (dolist (char chars)
+                          (define-key map (vector char)
+                            'read-char-from-minibuffer-insert-char))
+                        (define-key map [remap self-insert-command]
+                          'read-char-from-minibuffer-insert-other)
+                        (puthash (list help-form (cons help-char chars))
+                                 map read-char-from-minibuffer-map-hash)
+                        map))
                 read-char-from-minibuffer-map))
          (result
           (read-from-minibuffer prompt nil map nil
diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el
index 5cf09f9..d460c8a 100644
--- a/lisp/tar-mode.el
+++ b/lisp/tar-mode.el
@@ -37,13 +37,6 @@
 
 ;; This code now understands the extra fields that GNU tar adds to tar files.
 
-;; This interacts correctly with "uncompress.el" in the Emacs library,
-;; which you get with
-;;
-;;  (autoload 'uncompress-while-visiting "uncompress")
-;;  (setq auto-mode-alist (cons '("\\.Z$" . uncompress-while-visiting)
-;;                        auto-mode-alist))
-;;
 ;; Do not attempt to use tar-mode.el with crypt.el, you will lose.
 
 ;;    ***************   TO DO   ***************
diff --git a/lisp/tempo.el b/lisp/tempo.el
index f661235..9ee0eef 100644
--- a/lisp/tempo.el
+++ b/lisp/tempo.el
@@ -353,9 +353,8 @@ possible."
        ((and (consp element)
              (eq (car element) 's)) (tempo-insert-named (car (cdr element))))
        ((and (consp element)
-             (eq (car element) 'l)) (mapcar (function
-                                             (lambda (elt)
-                                               (tempo-insert elt on-region)))
+              (eq (car element) 'l)) (mapcar (lambda (elt)
+                                               (tempo-insert elt on-region))
                                             (cdr element)))
        ((eq element 'p) (tempo-insert-mark (point-marker)))
        ((eq element 'r) (if on-region
@@ -546,10 +545,9 @@ and insert the results."
   (interactive)
   (let ((next-mark (catch 'found
                     (mapc
-                     (function
-                      (lambda (mark)
-                        (if (< (point) mark)
-                            (throw 'found mark))))
+                      (lambda (mark)
+                        (if (< (point) mark)
+                            (throw 'found mark)))
                      tempo-marks)
                     ;; return nil if not found
                     nil)))
@@ -565,11 +563,10 @@ and insert the results."
   (let ((prev-mark (catch 'found
                     (let (last)
                       (mapc
-                       (function
-                        (lambda (mark)
-                          (if (<= (point) mark)
-                              (throw 'found last))
-                          (setq last mark)))
+                        (lambda (mark)
+                          (if (<= (point) mark)
+                              (throw 'found last))
+                          (setq last mark))
                        tempo-marks)
                       last))))
     (if prev-mark
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index cc7a376..8273c06 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -148,9 +148,8 @@ The properties returned may include `top', `left', 
`height', and `width'."
 (define-key global-map [?\s-|] 'shell-command-on-region)
 (define-key global-map [s-kp-bar] 'shell-command-on-region)
 (define-key global-map [?\C-\s- ] 'ns-do-show-character-palette)
-;; (as in Terminal.app)
-(define-key global-map [s-right] 'ns-next-frame)
-(define-key global-map [s-left] 'ns-prev-frame)
+(define-key global-map [s-right] 'move-end-of-line)
+(define-key global-map [s-left] 'move-beginning-of-line)
 
 (define-key global-map [home] 'beginning-of-buffer)
 (define-key global-map [end] 'end-of-buffer)
diff --git a/lisp/term/wyse50.el b/lisp/term/wyse50.el
index 6d72d4a..f06563e 100644
--- a/lisp/term/wyse50.el
+++ b/lisp/term/wyse50.el
@@ -126,9 +126,9 @@
   ;; On such terminals, Emacs should sacrifice the first and last character of
   ;; each mode line, rather than a whole screen column!
   (add-hook 'kill-emacs-hook
-           (function (lambda () (interactive)
-                       (send-string-to-terminal
-                        (concat "\ea23R" (1+ (frame-width)) "C\eG0"))))))
+            (lambda () (interactive)
+              (send-string-to-terminal
+               (concat "\ea23R" (1+ (frame-width)) "C\eG0")))))
 
 (defun enable-arrow-keys ()
   "To be called by `tty-setup-hook'.  Overrides 6 Emacs standard keys
diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el
index 5ce9a90..90e8d36 100644
--- a/lisp/textmodes/artist.el
+++ b/lisp/textmodes/artist.el
@@ -5398,10 +5398,9 @@ The event, EV, is the mouse event."
                    artist-arrow-point-2)))
        ;; Remove those variables from vars that are not bound
        (mapc
-        (function
-         (lambda (x)
-           (if (not (and (boundp x) (symbol-value x)))
-               (setq vars (delq x vars))))) vars)
+         (lambda (x)
+           (if (not (and (boundp x) (symbol-value x)))
+               (setq vars (delq x vars)))) vars)
        (reporter-submit-bug-report
         artist-maintainer-address
         (concat "artist.el " artist-version)
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index 3358cf1..14de77c 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -2464,14 +2464,14 @@ SPC:   Accept word this time.
       (progn
        (require 'ehelp)
        (with-electric-help
-        (function (lambda ()
-                    ;;This shouldn't be necessary: with-electric-help needs
-                    ;; an optional argument telling it about the smallest
-                    ;; acceptable window-height of the help buffer.
-                    ;;(if (< (window-height) 15)
-                    ;;  (enlarge-window
-                    ;;   (- 15 (ispell-adjusted-window-height))))
-                    (princ "Selections are:
+         (lambda ()
+           ;;This shouldn't be necessary: with-electric-help needs
+           ;; an optional argument telling it about the smallest
+           ;; acceptable window-height of the help buffer.
+           ;;(if (< (window-height) 15)
+           ;;   (enlarge-window
+           ;;    (- 15 (ispell-adjusted-window-height))))
+           (princ "Selections are:
 
 DIGIT: Replace the word with a digit offered in the *Choices* buffer.
 SPC:   Accept word this time.
@@ -2491,7 +2491,7 @@ SPC:   Accept word this time.
 `C-l':  Redraw screen.
 `C-r':  Recursive edit.
 `C-z':  Suspend Emacs or iconify frame.")
-                    nil))))
+           nil)))
 
 
     (let ((help-1 (concat "[r/R]eplace word; [a/A]ccept for this session; "
@@ -3274,15 +3274,15 @@ otherwise, the current line is skipped."
 Generated from `ispell-tex-skip-alists'."
   (concat
    ;; raw tex keys
-   (mapconcat (function (lambda (lst) (car lst)))
+   (mapconcat (lambda (lst) (car lst))
              (car ispell-tex-skip-alists)
              "\\|")
    "\\|"
    ;; keys wrapped in begin{}
-   (mapconcat (function (lambda (lst)
-                         (concat "\\\\begin[ \t\n]*{[ \t\n]*"
-                                 (car lst)
-                                 "[ \t\n]*}")))
+   (mapconcat (lambda (lst)
+                (concat "\\\\begin[ \t\n]*{[ \t\n]*"
+                        (car lst)
+                        "[ \t\n]*}"))
              (car (cdr ispell-tex-skip-alists))
              "\\|")))
 
@@ -3704,11 +3704,10 @@ Standard ispell choices are then available."
            ((string-equal (upcase word) word)
             (setq possibilities (mapcar #'upcase possibilities)))
            ((eq (upcase (aref word 0)) (aref word 0))
-             (setq possibilities (mapcar (function
-                                          (lambda (pos)
-                                            (if (eq (aref word 0) (aref pos 0))
-                                               pos
-                                              (capitalize pos))))
+             (setq possibilities (mapcar (lambda (pos)
+                                           (if (eq (aref word 0) (aref pos 0))
+                                               pos
+                                             (capitalize pos)))
                                          possibilities))))
           (setq case-fold-search case-fold-search-val)
           (save-window-excursion
diff --git a/lisp/textmodes/page-ext.el b/lisp/textmodes/page-ext.el
index c2b7b66..b357bbb 100644
--- a/lisp/textmodes/page-ext.el
+++ b/lisp/textmodes/page-ext.el
@@ -429,20 +429,19 @@ REVERSE (non-nil means reverse order), BEG and END 
(region to sort)."
                ;; NEXTRECFUN is called with point at the end of the
                ;; previous record. It moves point to the start of the
                ;; next record.
-              (function (lambda ()
-                           (re-search-forward page-delimiter nil t)
-                           (skip-chars-forward " \t\n")
-                           ))
+               (lambda ()
+                 (re-search-forward page-delimiter nil t)
+                 (skip-chars-forward " \t\n"))
 
                ;; ENDRECFUN is called with point within the record.
                ;; It should move point to the end of the record.
-              (function (lambda ()
-                           (if (re-search-forward
-                                page-delimiter
-                                nil
-                                t)
-                               (goto-char (match-beginning 0))
-                             (goto-char (point-max))))))))
+               (lambda ()
+                 (if (re-search-forward
+                      page-delimiter
+                      nil
+                      t)
+                     (goto-char (match-beginning 0))
+                   (goto-char (point-max)))))))
 
 (define-obsolete-function-alias 'sort-pages-buffer #'pages-sort-buffer "27.1")
 (defun pages-sort-buffer (&optional reverse)
diff --git a/lisp/textmodes/refer.el b/lisp/textmodes/refer.el
index c8fd0be..888c310 100644
--- a/lisp/textmodes/refer.el
+++ b/lisp/textmodes/refer.el
@@ -249,9 +249,9 @@ found on the last `refer-find-entry' or 
`refer-find-next-entry'."
        (forward-paragraph 1)
        (setq end (point))
        (setq found
-             (refer-every (function (lambda (keyword)
-                                (goto-char begin)
-                                (re-search-forward keyword end t)))
+             (refer-every (lambda (keyword)
+                       (goto-char begin)
+                       (re-search-forward keyword end t))
                     keywords-list))
        (if (not found)
            (progn
diff --git a/lisp/url/url-auth.el b/lisp/url/url-auth.el
index 8f39b5a..fd800cd 100644
--- a/lisp/url/url-auth.el
+++ b/lisp/url/url-auth.el
@@ -494,21 +494,19 @@ PROMPT is boolean - specifies whether to ask the user for 
a username/password
        (car-safe
        (sort
         (mapcar
-         (function
-          (lambda (scheme)
-            (if (fboundp (car (cdr scheme)))
-                (cons (cdr (cdr scheme))
-                      (funcall (car (cdr scheme)) url nil nil realm))
-              (cons 0 nil))))
+          (lambda (scheme)
+            (if (fboundp (car (cdr scheme)))
+                (cons (cdr (cdr scheme))
+                      (funcall (car (cdr scheme)) url nil nil realm))
+              (cons 0 nil)))
          url-registered-auth-schemes)
-        (function
-         (lambda (x y)
-           (cond
-            ((null (cdr x)) nil)
-            ((and (cdr x) (null (cdr y))) t)
-            ((and (cdr x) (cdr y))
-             (>= (car x) (car y)))
-            (t nil)))))))
+         (lambda (x y)
+           (cond
+            ((null (cdr x)) nil)
+            ((and (cdr x) (null (cdr y))) t)
+            ((and (cdr x) (cdr y))
+             (>= (car x) (car y)))
+            (t nil))))))
     (if (symbolp type) (setq type (symbol-name type)))
     (let* ((scheme (car-safe
                    (cdr-safe (assoc (downcase type)
diff --git a/lisp/url/url-cache.el b/lisp/url/url-cache.el
index 056ad1e..ea14e60 100644
--- a/lisp/url/url-cache.el
+++ b/lisp/url/url-cache.el
@@ -110,18 +110,17 @@ The actual return value is the last modification time of 
the cache file."
            (let ((slash nil))
              (setq fname
                    (mapconcat
-                    (function
-                     (lambda (x)
-                       (cond
-                        ((and (= ?/ x) slash)
-                         (setq slash nil)
-                         "%2F")
-                        ((= ?/ x)
-                         (setq slash t)
-                         "/")
-                        (t
-                         (setq slash nil)
-                         (char-to-string x))))) fname ""))))
+                     (lambda (x)
+                       (cond
+                        ((and (= ?/ x) slash)
+                         (setq slash nil)
+                         "%2F")
+                        ((= ?/ x)
+                         (setq slash t)
+                         "/")
+                        (t
+                         (setq slash nil)
+                         (char-to-string x)))) fname ""))))
 
        (setq fname (and fname
                         (mapconcat
diff --git a/lisp/url/url-expand.el b/lisp/url/url-expand.el
index be9b542..9f52f25 100644
--- a/lisp/url/url-expand.el
+++ b/lisp/url/url-expand.el
@@ -65,10 +65,10 @@ path components followed by `..' are removed, along with 
the `..' itself."
   (if (and url (not (string-match "^#" url)))
       ;; Need to nuke newlines and spaces in the URL, or we open
       ;; ourselves up to potential security holes.
-      (setq url (mapconcat (function (lambda (x)
-                                      (if (memq x '(?  ?\n ?\r))
-                                          ""
-                                        (char-to-string x))))
+      (setq url (mapconcat (lambda (x)
+                             (if (memq x '(?  ?\n ?\r))
+                                 ""
+                               (char-to-string x)))
                           url "")))
 
   ;; Need to figure out how/where to expand the fragment relative to
diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el
index e1c2b97..56ecc64 100644
--- a/lisp/vc/log-view.el
+++ b/lisp/vc/log-view.el
@@ -208,6 +208,18 @@ If it is nil, `log-view-toggle-entry-display' does 
nothing.")
   "Face for the message header line in `log-view-mode'."
   :group 'log-view)
 
+(defface log-view-commit-body
+  '((((class color) (min-colors 88) (background light))
+     :background "gray95" :foreground "black" :extend t)
+    (((class color) (min-colors 88) (background dark))
+     :background "gray5" :foreground "white" :extend t)
+    (((class color) (min-colors 8) (background light))
+     :foreground "black")
+    (((class color) (min-colors 8) (background dark))
+     :foreground "white"))
+  "Face for the commit body in `log-view-mode'."
+  :version "28.1")
+
 (defvar log-view-file-re
   (concat "^\\(?:Working file: \\(?1:.+\\)"                ;RCS and CVS.
           ;; Subversion has no such thing??
@@ -415,7 +427,7 @@ This calls `log-view-expanded-log-entry-function' to do the 
work."
              (insert long-entry "\n")
              (add-text-properties
               beg (point)
-              '(font-lock-face font-lock-comment-face log-view-comment t))
+              '(font-lock-face log-view-commit-body log-view-comment t))
              (goto-char opoint))))))))
 
 (defun log-view-beginning-of-defun (&optional arg)
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el
index cb0657e..67e1290 100644
--- a/lisp/vc/vc-hg.el
+++ b/lisp/vc/vc-hg.el
@@ -222,8 +222,11 @@ If `ask', you will be prompted for a branch type."
 (defun vc-hg-registered (file)
   "Return non-nil if FILE is registered with hg."
   (when (vc-hg-root file)           ; short cut
-    (let ((state (vc-hg-state file)))  ; expensive
-      (and state (not (memq state '(ignored unregistered)))))))
+    (let ((state (vc-state file 'Hg)))  ; expensive
+      (if (memq state '(ignored unregistered nil))
+          ;; Clear the cache for proper fallback to another backend.
+          (ignore (vc-file-setprop file 'vc-state nil))
+        t))))
 
 (defun vc-hg-state (file)
   "Hg-specific version of `vc-state'."
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 8def7da..83f2596 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -1045,7 +1045,7 @@ requesting the fileset doesn't intend to change the VC 
state,
 such as when printing the log or showing the diffs.
 
 If the current buffer is in `vc-dir' or Dired mode, FILESET is the
-list of marked files, or the current directory if no files are
+list of marked files, or the file under point if no files are
 marked.
 Otherwise, if the current buffer is visiting a version-controlled
 file or is an indirect buffer whose base buffer visits a
@@ -1391,7 +1391,7 @@ first backend that could register the file is used."
        (unless fname
          (setq fname buffer-file-name))
        (when (vc-call-backend backend 'registered fname)
-         (error "This file is already registered"))
+         (error "This file is already registered: %s" fname))
        ;; Watch out for new buffers of size 0: the corresponding file
        ;; does not exist yet, even though buffer-modified-p is nil.
        (when bname
diff --git a/lisp/vcursor.el b/lisp/vcursor.el
index 3601abc..e5e9f06 100644
--- a/lisp/vcursor.el
+++ b/lisp/vcursor.el
@@ -602,15 +602,14 @@ Set `vcursor-window' to the returned value as a side 
effect."
               (pos-visible-in-window-p (point) vcursor-window))
          (progn
            (walk-windows
-            (function
-             (lambda (win)
-               (and (not winok)
-                    (eq (current-buffer) (window-buffer win))
-                    (not (and not-this (eq thiswin win)))
-                    (cond
-                     ((pos-visible-in-window-p (point) win) (setq winok win))
-                     ((eq thiswin win))
-                     ((not winbuf) (setq winbuf win))))))
+             (lambda (win)
+               (and (not winok)
+                    (eq (current-buffer) (window-buffer win))
+                    (not (and not-this (eq thiswin win)))
+                    (cond
+                     ((pos-visible-in-window-p (point) win) (setq winok win))
+                     ((eq thiswin win))
+                     ((not winbuf) (setq winbuf win)))))
             nil (not this-frame))
            (setq vcursor-window
                  (cond
diff --git a/lisp/whitespace.el b/lisp/whitespace.el
index 94ed6dc..02ee7bc 100644
--- a/lisp/whitespace.el
+++ b/lisp/whitespace.el
@@ -86,19 +86,6 @@
 ;; * if global whitespace is turned off, whitespace continues on only
 ;;   in the buffers in which local whitespace is on.
 ;;
-;; To use whitespace, insert in your ~/.emacs:
-;;
-;;    (require 'whitespace)
-;;
-;; Or autoload at least one of the commands`whitespace-mode',
-;; `whitespace-toggle-options', `global-whitespace-mode' or
-;; `global-whitespace-toggle-options'.  For example:
-;;
-;;    (autoload 'whitespace-mode           "whitespace"
-;;      "Toggle whitespace visualization."        t)
-;;    (autoload 'whitespace-toggle-options "whitespace"
-;;      "Toggle local `whitespace-mode' options." t)
-;;
 ;; whitespace was inspired by:
 ;;
 ;;    whitespace.el            Rajesh Vaidheeswarran <rv@gnu.org>
diff --git a/lisp/window.el b/lisp/window.el
index 865f6fd..d564ec5 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -5488,7 +5488,13 @@ frame.  The selected window is not changed by this 
function."
              (set-window-parameter (window-parent new) 'window-atom t))
            (set-window-parameter new 'window-atom t)))
 
-         ;; Sanitize sizes unless SIZE was specified.
+          ;; Make the new window inherit the `min-margins' parameter of
+          ;; WINDOW (Bug#44483).
+          (let ((min-margins (window-parameter window 'min-margins)))
+            (when min-margins
+              (set-window-parameter new 'min-margins min-margins)))
+
+          ;; Sanitize sizes unless SIZE was specified.
          (unless size
             (window--sanitize-window-sizes horizontal))
 
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index f9c08f9..9301476 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -77,6 +77,7 @@ https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)."
               (copy-sequence event))
        vec)
        (is-move
+        (xterm-mouse--handle-mouse-movement)
         (if track-mouse vec
           ;; Mouse movement events are currently supposed to be
           ;; suppressed.  Return no event.
@@ -106,8 +107,14 @@ https://invisible-island.net/xterm/ctlseqs/ctlseqs.html)."
              (if (null track-mouse)
                  (vector drag)
                (push drag unread-command-events)
+                (xterm-mouse--handle-mouse-movement)
                (vector (list 'mouse-movement ev-data))))))))))))
 
+(defun xterm-mouse--handle-mouse-movement ()
+  "Handle mouse motion that was just generated for XTerm mouse."
+  (display--update-for-mouse-movement (terminal-parameter nil 'xterm-mouse-x)
+                                      (terminal-parameter nil 'xterm-mouse-y)))
+
 ;; These two variables have been converted to terminal parameters.
 ;;
 ;;(defvar xterm-mouse-x 0
diff --git a/src/alloc.c b/src/alloc.c
index fbfa814..ff6681c 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -7225,6 +7225,20 @@ Frames, windows, buffers, and subprocesses count as 
vectors
                make_int (strings_consed));
 }
 
+#ifdef GNU_LINUX
+DEFUN ("malloc-info", Fmalloc_info, Smalloc_info, 0, 0, "",
+       doc: /* Report malloc information to stderr.
+This function outputs to stderr an XML-formatted
+description of the current state of the memory-allocation
+arenas.  */)
+  (void)
+{
+  if (malloc_info (0, stderr))
+    error ("malloc_info failed: %s", emacs_strerror (errno));
+  return Qnil;
+}
+#endif
+
 static bool
 symbol_uses_obj (Lisp_Object symbol, Lisp_Object obj)
 {
@@ -7569,6 +7583,9 @@ N should be nonnegative.  */);
   defsubr (&Sgarbage_collect);
   defsubr (&Smemory_info);
   defsubr (&Smemory_use_counts);
+#ifdef GNU_LINUX
+  defsubr (&Smalloc_info);
+#endif
   defsubr (&Ssuspicious_object);
 
   Lisp_Object watcher;
diff --git a/src/bidi.c b/src/bidi.c
index 225b27b..ef062ad 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -1460,6 +1460,11 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t 
bytepos)
   else
     start_re = paragraph_start_re;
 
+  /* Prevent quitting inside re_match_2, as redisplay_window could
+     have temporarily moved point.  */
+  ptrdiff_t count = SPECPDL_INDEX ();
+  specbind (Qinhibit_quit, Qt);
+
   val = fast_looking_at (sep_re, charpos, bytepos, ZV, ZV_BYTE, Qnil);
   if (val < 0)
     {
@@ -1469,6 +1474,7 @@ bidi_at_paragraph_end (ptrdiff_t charpos, ptrdiff_t 
bytepos)
        val = -2;
     }
 
+  unbind_to (count, Qnil);
   return val;
 }
 
@@ -1544,6 +1550,11 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t 
pos_byte)
   if (cache_buffer->base_buffer)
     cache_buffer = cache_buffer->base_buffer;
 
+  /* Prevent quitting inside re_match_2, as redisplay_window could
+     have temporarily moved point.  */
+  ptrdiff_t count = SPECPDL_INDEX ();
+  specbind (Qinhibit_quit, Qt);
+
   while (pos_byte > BEGV_BYTE
         && n++ < MAX_PARAGRAPH_SEARCH
         && fast_looking_at (re, pos, pos_byte, limit, limit_byte, Qnil) < 0)
@@ -1561,6 +1572,7 @@ bidi_find_paragraph_start (ptrdiff_t pos, ptrdiff_t 
pos_byte)
       else
        pos = find_newline_no_quit (pos, pos_byte, -1, &pos_byte);
     }
+  unbind_to (count, Qnil);
   if (n >= MAX_PARAGRAPH_SEARCH)
     pos = BEGV, pos_byte = BEGV_BYTE;
   if (bpc)
diff --git a/src/dispextern.h b/src/dispextern.h
index 848d3bc..da51772 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3606,6 +3606,7 @@ extern Lisp_Object marginal_area_string (struct window *, 
enum window_part,
 extern void redraw_frame (struct frame *);
 extern bool update_frame (struct frame *, bool, bool);
 extern void update_frame_with_menu (struct frame *, int, int);
+extern int update_mouse_position (struct frame *, int, int);
 extern void bitch_at_user (void);
 extern void adjust_frame_glyphs (struct frame *);
 void free_glyphs (struct frame *);
diff --git a/src/dispnew.c b/src/dispnew.c
index 3f2ae3e..479fccb 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -3323,6 +3323,53 @@ update_frame_with_menu (struct frame *f, int row, int 
col)
   display_completed = !paused_p;
 }
 
+/* Update the mouse position for a frame F.  This handles both
+   updating the display for mouse-face propreties and updating the
+   help echo text.
+
+   Returns the number of events generated.  */
+int
+update_mouse_position (struct frame *f, int x, int y)
+{
+  previous_help_echo_string = help_echo_string;
+  help_echo_string = Qnil;
+
+  note_mouse_highlight (f, x, y);
+
+  /* If the contents of the global variable help_echo_string
+     has changed, generate a HELP_EVENT.  */
+  if (!NILP (help_echo_string)
+      || !NILP (previous_help_echo_string))
+    {
+      Lisp_Object frame;
+      XSETFRAME (frame, f);
+
+      gen_help_event (help_echo_string, frame, help_echo_window,
+                      help_echo_object, help_echo_pos);
+      return 1;
+    }
+
+  return 0;
+}
+
+DEFUN ("display--update-for-mouse-movement", 
Fdisplay__update_for_mouse_movement,
+       Sdisplay__update_for_mouse_movement, 2, 2, 0,
+       doc: /* Handle mouse movement detected by Lisp code.
+
+This function should be called when Lisp code detects the mouse has
+moved, even if `track-mouse' is nil.  This handles updates that do not
+rely on input events such as updating display for mouse-face
+properties or updating the help echo text.  */)
+  (Lisp_Object mouse_x, Lisp_Object mouse_y)
+{
+  CHECK_FIXNUM (mouse_x);
+  CHECK_FIXNUM (mouse_y);
+
+  update_mouse_position (SELECTED_FRAME (), XFIXNUM (mouse_x),
+                         XFIXNUM (mouse_y));
+  return Qnil;
+}
+
 
 /************************************************************************
                         Window-based updates
@@ -5904,8 +5951,12 @@ when TERMINAL is nil.  */)
        }
       out = tty->output;
     }
+  /* STRING might be very long, in which case fwrite could be
+     interrupted by SIGIO.  So we temporarily block SIGIO.  */
+  unrequest_sigio ();
   fwrite (SDATA (string), 1, SBYTES (string), out);
   fflush (out);
+  request_sigio ();
   unblock_input ();
   return Qnil;
 }
@@ -6490,6 +6541,7 @@ syms_of_display (void)
 {
   defsubr (&Sredraw_frame);
   defsubr (&Sredraw_display);
+  defsubr (&Sdisplay__update_for_mouse_movement);
   defsubr (&Sframe_or_buffer_changed_p);
   defsubr (&Sopen_termscript);
   defsubr (&Sding);
diff --git a/src/doc.c b/src/doc.c
index d4e3ce2..de904b4 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -688,37 +688,25 @@ default_to_grave_quoting_style (void)
          && EQ (AREF (dv, 0), make_fixnum ('`')));
 }
 
-/* Return the current effective text quoting style.  */
-enum text_quoting_style
-text_quoting_style (void)
+DEFUN ("text-quoting-style", Ftext_quoting_style,
+       Stext_quoting_style, 0, 0, 0,
+       doc: /* Return the current effective text quoting style.
+See variable `text-quoting-style'.  */)
+  (void)
 {
+  /* Use grave accent and apostrophe `like this'.  */
   if (NILP (Vtext_quoting_style)
       ? default_to_grave_quoting_style ()
       : EQ (Vtext_quoting_style, Qgrave))
-    return GRAVE_QUOTING_STYLE;
+    return Qgrave;
+
+  /* Use apostrophes 'like this'.  */
   else if (EQ (Vtext_quoting_style, Qstraight))
-    return STRAIGHT_QUOTING_STYLE;
-  else
-    return CURVE_QUOTING_STYLE;
-}
+    return Qstraight;
 
-/* This is just a Lisp wrapper for text_quoting_style above.  */
-DEFUN ("get-quoting-style", Fget_quoting_style,
-       Sget_quoting_style, 0, 0, 0,
-       doc: /* Return the current effective text quoting style.
-See variable `text-quoting-style'.  */)
-  (void)
-{
-  switch (text_quoting_style ())
-    {
-    case STRAIGHT_QUOTING_STYLE:
-      return Qstraight;
-    case CURVE_QUOTING_STYLE:
-      return Qcurve;
-    case GRAVE_QUOTING_STYLE:
-    default:
-      return Qgrave;
-    }
+  /* Use curved single quotes ‘like this’.  */
+  else
+    return Qcurve;
 }
 
 
@@ -761,5 +749,5 @@ otherwise.  */);
   defsubr (&Sdocumentation);
   defsubr (&Sdocumentation_property);
   defsubr (&Ssnarf_documentation);
-  defsubr (&Sget_quoting_style);
+  defsubr (&Stext_quoting_style);
 }
diff --git a/src/doprnt.c b/src/doprnt.c
index ce259d0..9316497 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -199,7 +199,7 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
   /* Buffer we have got with malloc.  */
   char *big_buffer = NULL;
 
-  enum text_quoting_style quoting_style = text_quoting_style ();
+  Lisp_Object quoting_style = Ftext_quoting_style ();
 
   bufsize--;
 
@@ -482,13 +482,13 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char 
*format,
 
       char const *src;
       ptrdiff_t srclen;
-      if (quoting_style == CURVE_QUOTING_STYLE && fmtchar == '`')
+      if (EQ (quoting_style, Qcurve) && fmtchar == '`')
        src = uLSQM, srclen = sizeof uLSQM - 1;
-      else if (quoting_style == CURVE_QUOTING_STYLE && fmtchar == '\'')
+      else if (EQ (quoting_style, Qcurve) && fmtchar == '\'')
        src = uRSQM, srclen = sizeof uRSQM - 1;
       else
        {
-         if (quoting_style == STRAIGHT_QUOTING_STYLE && fmtchar == '`')
+         if (EQ (quoting_style, Qstraight) && fmtchar == '`')
            fmtchar = '\'';
          eassert (ASCII_CHAR_P (fmtchar));
          *bufptr++ = fmtchar;
diff --git a/src/editfns.c b/src/editfns.c
index ca6b898..4104edd 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -2117,6 +2117,13 @@ nil.  */)
     {
       signal_after_change (BEGV, size_a, ZV - BEGV);
       update_compositions (BEGV, ZV, CHECK_INSIDE);
+      /* We've locked the buffer's file above in
+        prepare_to_modify_buffer; if the buffer is unchanged at this
+        point, i.e. no insertions or deletions have been made, unlock
+        the file now.  */
+      if (SAVE_MODIFF == MODIFF
+         && STRINGP (BVAR (a, file_truename)))
+       unlock_file (BVAR (a, file_truename));
     }
 
   return Qt;
@@ -3147,7 +3154,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
     if (STRINGP (args[i]) && STRING_MULTIBYTE (args[i]))
       multibyte = true;
 
-  int quoting_style = message ? text_quoting_style () : -1;
+  Lisp_Object quoting_style = message ? Ftext_quoting_style () : Qnil;
 
   ptrdiff_t ispec;
   ptrdiff_t nspec = 0;
@@ -3767,7 +3774,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
          unsigned char str[MAX_MULTIBYTE_LENGTH];
 
          if ((format_char == '`' || format_char == '\'')
-             && quoting_style == CURVE_QUOTING_STYLE)
+             && EQ (quoting_style, Qcurve))
            {
              if (! multibyte)
                {
@@ -3778,7 +3785,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
              convbytes = 3;
              new_result = true;
            }
-         else if (format_char == '`' && quoting_style == 
STRAIGHT_QUOTING_STYLE)
+         else if (format_char == '`' && EQ (quoting_style, Qstraight))
            {
              convsrc = "'";
              new_result = true;
diff --git a/src/image.c b/src/image.c
index c857b8e..3858f3c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -9542,16 +9542,19 @@ DEF_DLL_FN (void, rsvg_handle_set_base_uri, (RsvgHandle 
*, const char *));
 DEF_DLL_FN (gboolean, rsvg_handle_write,
            (RsvgHandle *, const guchar *, gsize, GError **));
 DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
-#endif
+#  endif
 
-#if LIBRSVG_CHECK_VERSION (2, 46, 0)
+#  if LIBRSVG_CHECK_VERSION (2, 46, 0)
+DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions,
+            (RsvgHandle *, gboolean *, RsvgLength *, gboolean *,
+            RsvgLength *, gboolean *, RsvgRectangle *));
 DEF_DLL_FN (gboolean, rsvg_handle_get_geometry_for_layer,
            (RsvgHandle *, const char *, const RsvgRectangle *,
             RsvgRectangle *, RsvgRectangle *, GError **));
-#else
+#  else
 DEF_DLL_FN (void, rsvg_handle_get_dimensions,
            (RsvgHandle *, RsvgDimensionData *));
-#endif
+#  endif
 DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
 DEF_DLL_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
 DEF_DLL_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
@@ -9599,6 +9602,7 @@ init_svg_functions (void)
   LOAD_DLL_FN (library, rsvg_handle_close);
 #endif
 #if LIBRSVG_CHECK_VERSION (2, 46, 0)
+  LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions);
   LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer);
 #else
   LOAD_DLL_FN (library, rsvg_handle_get_dimensions);
@@ -9638,6 +9642,7 @@ init_svg_functions (void)
 #  undef g_object_unref
 #  undef g_type_init
 #  if LIBRSVG_CHECK_VERSION (2, 46, 0)
+#   undef rsvg_handle_get_intrinsic_dimensions
 #   undef rsvg_handle_get_geometry_for_layer
 #  else
 #   undef rsvg_handle_get_dimensions
@@ -9668,7 +9673,10 @@ init_svg_functions (void)
 #   define g_type_init fn_g_type_init
 #  endif
 #  if LIBRSVG_CHECK_VERSION (2, 46, 0)
-#   define rsvg_handle_get_geometry_for_layer 
fn_rsvg_handle_get_geometry_for_layer
+#   define rsvg_handle_get_intrinsic_dimensions \
+       fn_rsvg_handle_get_intrinsic_dimensions
+#   define rsvg_handle_get_geometry_for_layer  \
+       fn_rsvg_handle_get_geometry_for_layer
 #  else
 #   define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
 #  endif
@@ -9742,6 +9750,49 @@ svg_load (struct frame *f, struct image *img)
   return success_p;
 }
 
+#if LIBRSVG_CHECK_VERSION (2, 46, 0)
+static double
+svg_css_length_to_pixels (RsvgLength length)
+{
+  /* FIXME: 96 appears to be a pretty standard DPI but we should
+     probably use the real DPI if we can get it.  */
+  double dpi = 96;
+  double value = length.length;
+
+  switch (length.unit)
+    {
+    case RSVG_UNIT_PX:
+      /* Already a pixel value.  */
+      break;
+    case RSVG_UNIT_CM:
+      /* 2.54 cm in an inch.  */
+      value = dpi * value / 2.54;
+      break;
+    case RSVG_UNIT_MM:
+      /* 25.4 mm in an inch.  */
+      value = dpi * value / 25.4;
+      break;
+    case RSVG_UNIT_PT:
+      /* 72 points in an inch.  */
+      value = dpi * value / 72;
+      break;
+    case RSVG_UNIT_PC:
+      /* 6 picas in an inch.  */
+      value = dpi * value / 6;
+      break;
+    case RSVG_UNIT_IN:
+      value *= dpi;
+      break;
+    default:
+      /* Probably one of em, ex, or %.  We can't know what the pixel
+         value is without more information.  */
+      value = 0;
+    }
+
+  return value;
+}
+#endif
+
 /* Load frame F and image IMG.  CONTENTS contains the SVG XML data to
    be parsed, SIZE is its size, and FILENAME is the name of the SVG
    file being loaded.
@@ -9810,11 +9861,48 @@ svg_load_image (struct frame *f, struct image *img, 
char *contents,
 #if LIBRSVG_CHECK_VERSION (2, 46, 0)
   RsvgRectangle zero_rect, viewbox, out_logical_rect;
 
-  rsvg_handle_get_geometry_for_layer (rsvg_handle, NULL,
-                                      &zero_rect, &viewbox,
-                                      &out_logical_rect, NULL);
-  viewbox_width = viewbox.x + viewbox.width;
-  viewbox_height = viewbox.y + viewbox.height;
+  /* Try the instrinsic dimensions first.  */
+  gboolean has_width, has_height, has_viewbox;
+  RsvgLength iwidth, iheight;
+
+  rsvg_handle_get_intrinsic_dimensions (rsvg_handle,
+                                        &has_width, &iwidth,
+                                        &has_height, &iheight,
+                                        &has_viewbox, &viewbox);
+
+  if (has_width && has_height)
+    {
+      /* Success!  We can use these values directly.  */
+      viewbox_width = svg_css_length_to_pixels (iwidth);
+      viewbox_height = svg_css_length_to_pixels (iheight);
+    }
+  else if (has_width && has_viewbox)
+    {
+      viewbox_width = svg_css_length_to_pixels (iwidth);
+      viewbox_height = svg_css_length_to_pixels (iwidth)
+        * viewbox.width / viewbox.height;
+    }
+  else if (has_height && has_viewbox)
+    {
+      viewbox_height = svg_css_length_to_pixels (iheight);
+      viewbox_width = svg_css_length_to_pixels (iheight)
+        * viewbox.height / viewbox.width;
+    }
+  else if (has_viewbox)
+    {
+      viewbox_width = viewbox.width;
+      viewbox_height = viewbox.height;
+    }
+  else
+    {
+      /* We haven't found a useable set of sizes, so try working out
+         the visible area.  */
+      rsvg_handle_get_geometry_for_layer (rsvg_handle, NULL,
+                                          &zero_rect, &viewbox,
+                                          &out_logical_rect, NULL);
+      viewbox_width = viewbox.x + viewbox.width;
+      viewbox_height = viewbox.y + viewbox.height;
+    }
 #else
   /* The function used above to get the geometry of the visible area
      of the SVG are only available in librsvg 2.46 and above, so in
@@ -9827,6 +9915,19 @@ svg_load_image (struct frame *f, struct image *img, char 
*contents,
   viewbox_width = dimension_data.width;
   viewbox_height = dimension_data.height;
 #endif
+
+  if (viewbox_width == 0 || viewbox_height == 0)
+    {
+      /* We do not have any usable dimensions, so make some up.  The
+         values below are supposedly the default values most web
+         browsers use for SVGs with no set size.  */
+      /* FIXME: At this stage we should perhaps consider rendering the
+         image out to a bitmap and getting the dimensions from
+         that.  */
+      viewbox_width = 300;
+      viewbox_height = 150;
+    }
+
   compute_image_size (viewbox_width, viewbox_height, img->spec,
                       &width, &height);
 
diff --git a/src/keymap.c b/src/keymap.c
index e5b4781..181dcda 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -2926,7 +2926,7 @@ You type        Translation\n\
       CALLN (Ffuncall,
             Qdescribe_map_tree,
             KVAR (current_kboard, Vlocal_function_key_map), Qnil, Qnil, prefix,
-            msg, nomenu, Qt, Qt, Qt);
+            msg, nomenu, Qt, Qnil, Qnil);
     }
 
   /* Print the input-decode-map translations under this prefix.  */
diff --git a/src/lisp.h b/src/lisp.h
index 31d2b5f..b956f39 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4518,18 +4518,6 @@ extern void set_initial_environment (void);
 extern void syms_of_callproc (void);
 
 /* Defined in doc.c.  */
-enum text_quoting_style
-  {
-    /* Use curved single quotes ‘like this’.  */
-    CURVE_QUOTING_STYLE,
-
-    /* Use grave accent and apostrophe  `like this'.  */
-    GRAVE_QUOTING_STYLE,
-
-    /* Use apostrophes 'like this'.  */
-    STRAIGHT_QUOTING_STYLE
-  };
-extern enum text_quoting_style text_quoting_style (void);
 extern Lisp_Object read_doc_string (Lisp_Object);
 extern Lisp_Object get_doc_string (Lisp_Object, bool, bool);
 extern void syms_of_doc (void);
diff --git a/src/minibuf.c b/src/minibuf.c
index 068086e..c4adca1 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -142,10 +142,6 @@ void move_minibuffer_onto_frame (void)
 
       set_window_buffer (sf->minibuffer_window, buffer, 0, 0);
       minibuf_window = sf->minibuffer_window;
-      if (EQ (XWINDOW (minibuf_window)->frame, selected_frame))
-        /* The minibuffer might be on another frame. */
-        Fset_frame_selected_window (selected_frame, sf->minibuffer_window,
-                                    Qnil);
       set_window_buffer (of->minibuffer_window, get_minibuffer (0), 0, 0);
     }
 }
@@ -732,7 +728,8 @@ read_minibuf (Lisp_Object map, Lisp_Object initial, 
Lisp_Object prompt,
   /* If cursor is on the minibuffer line,
      show the user we have exited by putting it in column 0.  */
   if (XWINDOW (minibuf_window)->cursor.vpos >= 0
-      && !noninteractive)
+      && !noninteractive
+      && !FRAME_INITIAL_P (SELECTED_FRAME ()))
     {
       XWINDOW (minibuf_window)->cursor.hpos = 0;
       XWINDOW (minibuf_window)->cursor.x = 0;
diff --git a/src/nsterm.m b/src/nsterm.m
index fa38350..a9280eb 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1782,6 +1782,8 @@ ns_destroy_window (struct frame *f)
 {
   NSTRACE ("ns_destroy_window");
 
+  check_window_system (f);
+
   /* If this frame has a parent window, detach it as not doing so can
      cause a crash in GNUStep.  */
   if (FRAME_PARENT_FRAME (f) != NULL)
@@ -1792,7 +1794,7 @@ ns_destroy_window (struct frame *f)
       [parent removeChildWindow: child];
     }
 
-  check_window_system (f);
+  [[FRAME_NS_VIEW (f) window] close];
   ns_free_frame_resources (f);
   ns_window_num--;
 }
@@ -6529,6 +6531,14 @@ not_in_argv (NSString *arg)
             code = 0xFF08; /* backspace */
           else
             code = fnKeysym;
+
+          /* Function keys (such as the F-keys, arrow keys, etc.) set
+             modifiers as though the fn key has been pressed when it
+             hasn't.  Also some combinations of fn and a function key
+             return a different key than was pressed (e.g. fn-<left>
+             gives <home>).  We need to unset the fn key flag in these
+             cases.  */
+          flags &= ~NS_FUNCTION_KEY_MASK;
         }
 
       /* The ⌘ and ⌥ modifiers can be either shift-like (for alternate
@@ -6550,17 +6560,6 @@ not_in_argv (NSString *arg)
       Lisp_Object kind = fnKeysym ? QCfunction : QCordinary;
       emacs_event->modifiers = EV_MODIFIERS2 (flags, kind);
 
-      /* Function keys (such as the F-keys, arrow keys, etc.) set
-         modifiers as though the fn key has been pressed when it
-         hasn't.  Also some combinations of fn and a function key
-         return a different key than was pressed (e.g. fn-<left> gives
-         <home>).  We need to unset the fn modifier in these cases.
-         FIXME: Can we avoid setting it in the first place?  */
-      if (fnKeysym && (flags & NS_FUNCTION_KEY_MASK))
-        emacs_event->modifiers
-          ^= parse_solitary_modifier (mod_of_kind (ns_function_modifier,
-                                                   QCfunction));
-
       if (NS_KEYLOG)
         fprintf (stderr, "keyDown: code =%x\tfnKey =%x\tflags = %x\tmods = 
%x\n",
                  code, fnKeysym, flags, emacs_event->modifiers);
diff --git a/src/pdumper.c b/src/pdumper.c
index 0528219..c253fc5 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -4123,7 +4123,7 @@ types.  */)
     ctx->header.fingerprint[i] = fingerprint[i];
 
   const dump_off header_start = ctx->offset;
-  dump_fingerprint ("dumping fingerprint", ctx->header.fingerprint);
+  dump_fingerprint ("Dumping fingerprint", ctx->header.fingerprint);
   dump_write (ctx, &ctx->header, sizeof (ctx->header));
   const dump_off header_end = ctx->offset;
 
diff --git a/src/process.c b/src/process.c
index 50c4250..bf64ead 100644
--- a/src/process.c
+++ b/src/process.c
@@ -8217,13 +8217,29 @@ init_process_emacs (int sockfd)
   if (!will_dump_with_unexec_p ())
     {
 #if defined HAVE_GLIB && !defined WINDOWSNT
-      /* Tickle glib's child-handling code.  Ask glib to wait for Emacs itself;
-        this should always fail, but is enough to initialize glib's
+      /* Tickle glib's child-handling code.  Ask glib to install a
+        watch source for Emacs itself which will initialize glib's
         private SIGCHLD handler, allowing catch_child_signal to copy
-        it into lib_child_handler.  */
-      g_source_unref (g_child_watch_source_new (getpid ()));
-#endif
+        it into lib_child_handler.
+
+         Unfortunatly in glib commit 2e471acf, the behavior changed to
+         always install a signal handler when g_child_watch_source_new
+         is called and not just the first time it's called.  Glib also
+         now resets signal handlers to SIG_DFL when it no longer has a
+         watcher on that signal.  This is a hackey work around to get
+         glib's g_unix_signal_handler into lib_child_handler.  */
+      GSource *source = g_child_watch_source_new (getpid ());
+      catch_child_signal ();
+      g_source_unref (source);
+
+      eassert (lib_child_handler != dummy_handler);
+      signal_handler_t lib_child_handler_glib = lib_child_handler;
       catch_child_signal ();
+      eassert (lib_child_handler == dummy_handler);
+      lib_child_handler = lib_child_handler_glib;
+#else
+      catch_child_signal ();
+#endif
     }
 
 #ifdef HAVE_SETRLIMIT
diff --git a/src/term.c b/src/term.c
index 3a13da1..a073859 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2430,22 +2430,6 @@ tty_draw_row_with_mouse_face (struct window *w, struct 
glyph_row *row,
   cursor_to (f, save_y, save_x);
 }
 
-static bool
-term_mouse_movement (struct frame *frame, Gpm_Event *event)
-{
-  /* Has the mouse moved off the glyph it was on at the last sighting?  */
-  if (event->x != last_mouse_x || event->y != last_mouse_y)
-    {
-      frame->mouse_moved = 1;
-      note_mouse_highlight (frame, event->x, event->y);
-      /* Remember which glyph we're now on.  */
-      last_mouse_x = event->x;
-      last_mouse_y = event->y;
-      return 1;
-    }
-  return 0;
-}
-
 /* Return the current time, as a Time value.  Wrap around on overflow.  */
 static Time
 current_Time (void)
@@ -2562,30 +2546,22 @@ handle_one_term_event (struct tty_display_info *tty, 
Gpm_Event *event)
 
   if (event->type & (GPM_MOVE | GPM_DRAG))
     {
-      previous_help_echo_string = help_echo_string;
-      help_echo_string = Qnil;
-
       Gpm_DrawPointer (event->x, event->y, fileno (tty->output));
 
-      if (!term_mouse_movement (f, event))
-        help_echo_string = previous_help_echo_string;
-
-      /* If the contents of the global variable help_echo_string
-         has changed, generate a HELP_EVENT.  */
-      if (!NILP (help_echo_string)
-         || !NILP (previous_help_echo_string))
-       {
-         Lisp_Object frame;
-
-         if (f)
-           XSETFRAME (frame, f);
-         else
-           frame = Qnil;
-
-         gen_help_event (help_echo_string, frame, help_echo_window,
-                         help_echo_object, help_echo_pos);
-         count++;
-       }
+      /* Has the mouse moved off the glyph it was on at the last
+         sighting?  */
+      if (event->x != last_mouse_x || event->y != last_mouse_y)
+        {
+          /* FIXME: These three lines can not be moved into
+             update_mouse_position unless xterm-mouse gets updated to
+             generate mouse events via C code.  See
+             
https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00163.html */
+          last_mouse_x = event->x;
+          last_mouse_y = event->y;
+          f->mouse_moved = 1;
+
+          count += update_mouse_position (f, event->x, event->y);
+        }
     }
   else
     {
diff --git a/src/w32fns.c b/src/w32fns.c
index ef69f40..7bb9689 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -8498,8 +8498,8 @@ DEFUN ("w32-register-hot-key", Fw32_register_hot_key,
        doc: /* Register KEY as a hot-key combination.
 Certain key combinations like Alt-Tab and Win-R are reserved for
 system use on Windows, and therefore are normally intercepted by the
-system.  These key combinations can be received by registering them
-as hot-keys, except for Win-L which always locks the computer.
+system.  These key combinations can be used in Emacs by registering
+them as hot-keys, except for Win-L which always locks the computer.
 
 On Windows 98 and ME, KEY must be a one element key definition in
 vector form that would be acceptable to `define-key' (e.g. [A-tab] for
@@ -8508,16 +8508,19 @@ Alt-Tab).  The meta modifier is interpreted as Alt if
 modifier keys.  The return value is the hotkey-id if registered,
 otherwise nil.
 
-On Windows versions since NT, KEY can also be specified as [M-], [s-] or
-[h-] to indicate that all combinations of that key should be processed
-by Emacs instead of the operating system.  The super and hyper
-modifiers are interpreted according to the current values of
-`w32-lwindow-modifier' and `w32-rwindow-modifier'.  For instance,
-setting `w32-lwindow-modifier' to `super' and then calling
-`(w32-register-hot-key [s-])' grabs all combinations of the left Windows
-key to Emacs, but leaves the right Windows key free for the operating
-system keyboard shortcuts.  The return value is t if the call affected
-any key combinations, otherwise nil.  */)
+On Windows versions since NT, KEY can also be specified as just a
+modifier key, [M-], [s-] or [H-], to indicate that all combinations
+of the respective modifier key should be processed by Emacs instead
+of the operating system.  The super and hyper modifiers are
+interpreted according to the current values of `w32-lwindow-modifier'
+and `w32-rwindow-modifier'.  For instance, setting `w32-lwindow-modifier'
+to `super' and then calling `(w32-register-hot-key [s-])' grabs all
+combinations of the left Windows key to Emacs as keys with the Super
+modifier, but leaves the right Windows key free for the operating
+system keyboard shortcuts.
+
+The return value is t if the call affected any key combinations,
+otherwise nil.  */)
   (Lisp_Object key)
 {
   key = w32_parse_and_hook_hot_key (key, 1);
diff --git a/src/xdisp.c b/src/xdisp.c
index 0001bcd..2344fe7 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -7323,14 +7323,21 @@ static next_element_function const 
get_next_element[NUM_IT_METHODS] =
 
 
 /* Return true iff a character at CHARPOS (and BYTEPOS) is composed
-   (possibly with the following characters).  */
+   (possibly with the following characters).
+
+  Note: we pass -1 as the "resolved bidi level" when the iterator
+  doesn't have the bidi_p flag set, because in that case we really
+  don't know what is the directionality of the text, so we leave it to
+  the shaping engine to figure that out.  */
 
 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS)                        
\
   ((IT)->cmp_it.id >= 0                                                        
\
    || ((IT)->cmp_it.stop_pos == (CHARPOS)                              \
        && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS,      \
                                 END_CHARPOS, (IT)->w,                  \
-                                (IT)->bidi_it.resolved_level,          \
+                                (IT)->bidi_p                           \
+                                ? (IT)->bidi_it.resolved_level         \
+                                : -1,                                  \
                                 FACE_FROM_ID_OR_NULL ((IT)->f,         \
                                                       (IT)->face_id),  \
                                 (IT)->string)))
@@ -8317,10 +8324,10 @@ next_element_from_display_vector (struct it *it)
            next_face_id = it->dpvec_face_id;
          else
            {
-             int lface_id =
-               GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
+              Lisp_Object gc = it->dpvec[it->current.dpvec_index + 1];
+              int lface_id = GLYPH_CODE_P (gc) ? GLYPH_CODE_FACE (gc) : 0;
 
-             if (lface_id > 0)
+              if (lface_id > 0)
                next_face_id = merge_faces (it->w, Qt, lface_id,
                                            it->saved_face_id);
            }
diff --git a/src/xwidget.c b/src/xwidget.c
index 031975f..e078a28 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -128,6 +128,16 @@ Returns the newly constructed xwidget, or nil if 
construction fails.  */)
       if (EQ (xw->type, Qwebkit))
         {
           xw->widget_osr = webkit_web_view_new ();
+
+          /* webkitgtk uses GSubprocess which sets sigaction causing
+             Emacs to not catch SIGCHLD with its usual handle setup in
+             catch_child_signal().  This resets the SIGCHLD
+             sigaction.  */
+          struct sigaction old_action;
+          sigaction (SIGCHLD, NULL, &old_action);
+          webkit_web_view_load_uri(WEBKIT_WEB_VIEW (xw->widget_osr),
+                                   "about:blank");
+          sigaction (SIGCHLD, &old_action, NULL);
         }
 
       gtk_widget_set_size_request (GTK_WIDGET (xw->widget_osr), xw->width,
diff --git a/test/lisp/ansi-color-tests.el b/test/lisp/ansi-color-tests.el
new file mode 100644
index 0000000..5c3da87
--- /dev/null
+++ b/test/lisp/ansi-color-tests.el
@@ -0,0 +1,49 @@
+;;; ansi-color-tests.el --- Test suite for ansi-color  -*- lexical-binding: t; 
-*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; Author: Pablo Barbáchano <pablob@amazon.com>
+;; Keywords: ansi
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ansi-color)
+
+(defvar test-strings '(("\e[33mHello World\e[0m" . "Hello World")
+                       ("\e[1m\e[3m\e[5mbold italics blink\e[0m" . "bold 
italics blink")))
+
+(ert-deftest ansi-color-apply-on-region-test ()
+    (dolist (pair test-strings)
+      (with-temp-buffer
+        (insert (car pair))
+        (ansi-color-apply-on-region (point-min) (point-max))
+        (should (equal (buffer-string) (cdr pair)))
+        (should (not (equal (overlays-at (point-min)) nil))))))
+
+(ert-deftest ansi-color-apply-on-region-preserving-test ()
+    (dolist (pair test-strings)
+      (with-temp-buffer
+        (insert (car pair))
+        (ansi-color-apply-on-region (point-min) (point-max) t)
+        (should (equal (buffer-string) (car pair))))))
+
+(provide 'ansi-color-tests)
+
+;;; ansi-color-tests.el ends here
diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el
index 59d8c60..d2e11cf 100644
--- a/test/lisp/emacs-lisp/rx-tests.el
+++ b/test/lisp/emacs-lisp/rx-tests.el
@@ -167,7 +167,11 @@
   (let ((k "blue"))
     (should (equal (pcase "<blue>"
                      ((rx "<" (literal k) ">") 'ok))
-                   'ok))))
+                   'ok)))
+  (should (equal (pcase "abc"
+                   ((rx (? (let x alpha)) (?? (let y alnum)) ?c)
+                    (list x y)))
+                 '("a" "b"))))
 
 (ert-deftest rx-kleene ()
   "Test greedy and non-greedy repetition operators."
@@ -540,7 +544,7 @@
 (ert-deftest rx-compat ()
   "Test old symbol retained for compatibility (bug#37517)."
   (should (equal
-           (with-suppressed-warnings ((obsolete rx-submatch-n))
+           (with-no-warnings
              (rx-submatch-n '(group-n 3 (+ nonl) eol)))
            "\\(?3:.+$\\)")))
 
diff --git a/test/lisp/help-fns-tests.el b/test/lisp/help-fns-tests.el
index d9344c3..11dbca4 100644
--- a/test/lisp/help-fns-tests.el
+++ b/test/lisp/help-fns-tests.el
@@ -24,8 +24,9 @@
 ;;; Code:
 
 (require 'ert)
+(require 'help-fns)
 
-(autoload 'help-fns-test--macro "help-fns" nil nil t)
+(autoload 'help-fns-test--macro "foo" nil nil t)
 
 
 ;;; Several tests for describe-function
diff --git a/test/lisp/help-tests.el b/test/lisp/help-tests.el
index b6dffb2..42be029 100644
--- a/test/lisp/help-tests.el
+++ b/test/lisp/help-tests.el
@@ -91,7 +91,7 @@
 (ert-deftest help-tests-substitute-command-keys/keymaps ()
   (with-substitute-command-keys-test
    (test "\\{minibuffer-local-must-match-map}"
-               "\
+         "\
 key             binding
 ---             -------
 
@@ -125,10 +125,21 @@ M-s               next-matching-history-element
    (test "\\<minibuffer-local-must-match-map>\\[abort-recursive-edit]" "C-g")
    (test "\\<emacs-lisp-mode-map>\\[eval-defun]" "C-M-x")))
 
+(defvar help-tests-remap-map
+  (let ((map (make-keymap)))
+    (define-key map (kbd "x") 'foo)
+    (define-key map (kbd "y") 'bar)
+    (define-key map [remap foo] 'bar)
+    map))
+
+(ert-deftest help-tests-substitute-command-keys/remap ()
+  (should (equal (substitute-command-keys "\\<help-tests-remap-map>\\[foo]") 
"y"))
+  (should (equal (substitute-command-keys "\\<help-tests-remap-map>\\[bar]") 
"y")))
+
 (ert-deftest help-tests-substitute-command-keys/undefined-map ()
   (with-substitute-command-keys-test
    (test-re "\\{foobar-map}"
-                  "\nUses keymap [`'‘]foobar-map['’], which is not currently 
defined.\n")))
+            "\nUses keymap [`'‘]foobar-map['’], which is not currently 
defined.\n")))
 
 (ert-deftest help-tests-substitute-command-keys/quotes ()
  (with-substitute-command-keys-test
diff --git a/test/lisp/hfy-cmap-resources/rgb.txt 
b/test/lisp/hfy-cmap-resources/rgb.txt
index 86a0053..f8e369f 100644
--- a/test/lisp/hfy-cmap-resources/rgb.txt
+++ b/test/lisp/hfy-cmap-resources/rgb.txt
@@ -1,3 +1,4 @@
+# test comment
 255 250 250            snow
 248 248 255            ghost white
 248 248 255            GhostWhite
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 7b83a8d..00d08ea 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -2281,9 +2281,13 @@ This checks also `file-name-as-directory', 
`file-name-directory',
          (delete-file tmp-name 'trash)
          (should-not (file-exists-p tmp-name))
          (should
-          (file-exists-p
-           (expand-file-name
-            (file-name-nondirectory tmp-name) trash-directory)))
+          (or (file-exists-p
+               (expand-file-name
+                (file-name-nondirectory tmp-name) trash-directory))
+              ;; Gdrive.
+              (file-symlink-p
+               (expand-file-name
+                (file-name-nondirectory tmp-name) trash-directory))))
          (delete-directory trash-directory 'recursive)
          (should-not (file-exists-p trash-directory)))))))
 
@@ -3473,7 +3477,10 @@ This tests also `file-executable-p', `file-writable-p' 
and `set-file-modes'."
   (skip-unless
    (or (tramp--test-sh-p) (tramp--test-sudoedit-p)
        ;; Not all tramp-gvfs.el methods support changing the file mode.
-       (tramp--test-gvfs-p "afp") (tramp--test-gvfs-p "ftp")))
+       (and
+       (tramp--test-gvfs-p)
+       (string-match-p
+        "ftp" (file-remote-p tramp-test-temporary-file-directory 'method)))))
 
   (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
     (let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
diff --git a/test/lisp/play/fortune-resources/fortunes 
b/test/lisp/play/fortune-resources/fortunes
new file mode 100644
index 0000000..f1ddc51
--- /dev/null
+++ b/test/lisp/play/fortune-resources/fortunes
@@ -0,0 +1,11 @@
+Embarrassed
+Manual-Writer
+Accused of
+Communist
+Subversion
+%
+Embarrassingly
+Mundane
+Advertising
+Cuts
+Sales
diff --git a/test/lisp/play/fortune-tests.el b/test/lisp/play/fortune-tests.el
new file mode 100644
index 0000000..9726340
--- /dev/null
+++ b/test/lisp/play/fortune-tests.el
@@ -0,0 +1,41 @@
+;;; fortune-tests.el --- Tests for fortune.el  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2020 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'fortune)
+
+(defvar fortune-tests--regexp
+  (rx (| "Embarrassed" "Embarrassingly")))
+
+(ert-deftest test-fortune ()
+  (skip-unless (executable-find "fortune"))
+  (unwind-protect
+      (let ((fortune-file (ert-resource-file "fortunes")))
+        (fortune)
+        (goto-char (point-min))
+        (should (looking-at fortune-tests--regexp)))
+    (kill-buffer fortune-buffer-name)))
+
+(provide 'fortune-tests)
+;;; fortune-tests.el ends here
diff --git a/test/lisp/progmodes/cperl-mode-resources/cperl-bug-19709.pl 
b/test/lisp/progmodes/cperl-mode-resources/cperl-bug-19709.pl
new file mode 100644
index 0000000..f7c51a2
--- /dev/null
+++ b/test/lisp/progmodes/cperl-mode-resources/cperl-bug-19709.pl
@@ -0,0 +1,25 @@
+# -------- bug#19709: input --------
+my $a = func1(
+    Module::test()
+  );
+
+my $b = func2(
+    test()
+);
+
+my $c = func3(
+    Module::test(),
+);
+# -------- bug#19709: expected output --------
+my $a = func1(
+    Module::test()
+);
+
+my $b = func2(
+    test()
+);
+
+my $c = func3(
+    Module::test(),
+);
+# -------- bug#19709: end --------
diff --git a/test/lisp/progmodes/cperl-mode-resources/cperl-indent-styles.pl 
b/test/lisp/progmodes/cperl-mode-resources/cperl-indent-styles.pl
index 0832f86..371b19b 100644
--- a/test/lisp/progmodes/cperl-mode-resources/cperl-indent-styles.pl
+++ b/test/lisp/progmodes/cperl-mode-resources/cperl-indent-styles.pl
@@ -42,3 +42,13 @@ die "This world is backwards";
     }
 }
 # -------- PBP uncuddle else: end --------
+
+# -------- PBP closing paren offset: input --------
+my $a = func1(
+    Module::test()
+  );
+# -------- PBP closing paren offset: expected output --------
+my $a = func1(
+    Module::test()
+);
+# -------- PBP closing paren offset: end --------
diff --git a/test/lisp/progmodes/cperl-mode-tests.el 
b/test/lisp/progmodes/cperl-mode-tests.el
index effebc8..a0dd391 100644
--- a/test/lisp/progmodes/cperl-mode-tests.el
+++ b/test/lisp/progmodes/cperl-mode-tests.el
@@ -34,6 +34,8 @@
 (require 'ert)
 (require 'ert-x)
 
+;;; Utilities
+
 (defun cperl-test-ppss (text regexp)
   "Return the `syntax-ppss' of the first character matched by REGEXP in TEXT."
   (interactive)
@@ -44,48 +46,98 @@
     (re-search-forward regexp)
     (syntax-ppss)))
 
-(ert-deftest cperl-mode-test-bug-42168 ()
-  "Verify that '/' is a division after ++ or --, not a regexp.
-Reported in https://github.com/jrockway/cperl-mode/issues/45.
-If seen as regular expression, then the slash is displayed using
-font-lock-constant-face.  If seen as a division, then it doesn't
-have a face property."
-  :tags '(:fontification)
-  ;; The next two Perl expressions have divisions.  Perl "punctuation"
-  ;; operators don't get a face.
-  (let ((code "{ $a++ / $b }"))
-    (should (equal (nth 8 (cperl-test-ppss code "/")) nil)))
-  (let ((code "{ $a-- / $b }"))
-    (should (equal (nth 8 (cperl-test-ppss code "/")) nil)))
-  ;; The next two Perl expressions have regular expressions.  The
-  ;; delimiter of a RE is fontified with font-lock-constant-face.
-  (let ((code "{ $a+ / $b } # /"))
-    (should (equal (nth 8 (cperl-test-ppss code "/")) 7)))
-  (let ((code "{ $a- / $b } # /"))
-    (should (equal (nth 8 (cperl-test-ppss code "/")) 7))))
+(defmacro cperl--run-test-cases (file &rest body)
+  "Run all test cases in FILE with BODY.
+This macro helps with tests which reformat Perl code, e.g. when
+indenting or rearranging flow control.  It extracts source code
+snippets and corresponding expected results from a resource file,
+runs BODY on the snippets, and compares the resulting buffer with
+the expected results.
 
-(ert-deftest cperl-mode-test-bug-16368 ()
-  "Verify that `cperl-forward-group-in-re' doesn't hide errors."
+Test cases in FILE are formatted like this:
+
+# -------- NAME: input --------
+Your input to the test case comes here.
+Both input and expected output may span several lines.
+# -------- NAME: expected output --------
+The expected output from running BODY on the input goes here.
+# -------- NAME: end --------
+
+You can have many of these blocks in one test file.  You can
+chose a NAME for each block, which is passed to the 'should'
+clause for easy identification of the first test case that
+failed (if any).  Text outside these the blocks is ignored by the
+tests, so you can use it to document the test cases if you wish."
+  `(with-temp-buffer
+     (insert-file-contents ,file)
+     (goto-char (point-min))
+     (while (re-search-forward
+             (concat "^# ?-+ \\_<\\(?1:.+?\\)\\_>: input ?-+\n"
+                     "\\(?2:\\(?:.*\n\\)+?\\)"
+                     "# ?-+ \\1: expected output ?-+\n"
+                     "\\(?3:\\(?:.*\n\\)+?\\)"
+                     "# ?-+ \\1: end ?-+")
+             nil t)
+       (let ((name (match-string 1))
+             (code (match-string 2))
+             (expected (match-string 3))
+             got)
+         (with-temp-buffer
+           (insert code)
+           (goto-char (point-min))
+           (funcall cperl-test-mode)
+           ,@body
+           (setq expected (concat "test case " name ":\n" expected))
+           (setq got (concat "test case " name ":\n" (buffer-string)))
+           (should (equal got expected)))))))
+
+;;; Indentation tests
+
+(ert-deftest cperl-test-indent-exp ()
+  "Run various tests for `cperl-indent-exp' edge cases.
+These exercise some standard blocks and also the special
+treatment for Perl expressions where a closing paren isn't the
+end of the statement."
   (skip-unless (eq cperl-test-mode #'cperl-mode))
-  (let ((code "/(\\d{4})(?{2}/;")     ; the regex from the bug report
-        (result))
-    (with-temp-buffer
-      (insert code)
-      (goto-char 9)
-      (setq result (cperl-forward-group-in-re))
-      (should (equal (car result) 'scan-error))
-      (should (equal (nth 1 result) "Unbalanced parentheses"))
-      (should (= (point) 9))))        ; point remains unchanged on error
-  (let ((code "/(\\d{4})(?{2})/;")    ; here all parens are balanced
-        (result))
+  (cperl--run-test-cases
+   (ert-resource-file "cperl-indent-exp.pl")
+   (cperl-indent-exp))) ; here we go!
+
+(ert-deftest cperl-test-indent-styles ()
+  (skip-unless (eq cperl-test-mode #'cperl-mode))
+  (cperl--run-test-cases
+   (ert-resource-file "cperl-indent-styles.pl")
+   (cperl-set-style "PBP")
+   (indent-region (point-min) (point-max)) ; here we go!
+   (cperl-set-style-back)))
+
+;;; Fontification tests
+
+(ert-deftest cperl-test-fontify-punct-vars ()
+  "Test fontification of Perl's punctiation variables.
+Perl has variable names containing unbalanced quotes for the list
+separator $\" and pre- and postmatch $` and $'.  A reference to
+these variables, for example \\$\", should not cause the dollar
+to be escaped, which would then start a string beginning with the
+quote character.  This used to be broken in cperl-mode at some
+point in the distant past, and is still broken in perl-mode. "
+  (skip-unless (eq cperl-test-mode #'cperl-mode))
+  (let ((file (ert-resource-file "fontify-punctuation-vars.pl")))
     (with-temp-buffer
-      (insert code)
-      (goto-char 9)
-      (setq result (cperl-forward-group-in-re))
-      (should (equal result nil))
-      (should (= (point) 15)))))      ; point has skipped the group
+      (insert-file-contents file)
+      (goto-char (point-min))
+      (funcall cperl-test-mode)
+      (while (search-forward "##" nil t)
+        ;; The third element of syntax-ppss is true if in a string,
+        ;; which would indicate bad interpretation of the quote.  The
+        ;; fourth element is true if in a comment, which should be the
+        ;; case.
+        (should (equal (nth 3 (syntax-ppss)) nil))
+        (should (equal (nth 4 (syntax-ppss)) t))))))
+
+;;; Tests for issues reported in the Bug Tracker
 
-(defun cperl-mode-test--run-bug-10483 ()
+(defun cperl-test--run-bug-10483 ()
   "Runs a short program, intended to be under timer scrutiny.
 This function is intended to be used by an Emacs subprocess in
 batch mode.  The message buffer is used to report the result of
@@ -102,7 +154,7 @@ indentation actually takes place.."
       (cperl-indent-exp)
       (message "%s" (buffer-string)))))
 
-(ert-deftest cperl-mode-test-bug-10483 ()
+(ert-deftest cperl-test-bug-10483 ()
   "Check that indenting certain perl code does not loop forever.
 This verifies that indenting a piece of code that ends in a paren
 without a statement terminator on the same line does not loop
@@ -113,7 +165,7 @@ under timeout control."
   (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; FIXME times out
   (skip-unless (not (< emacs-major-version 28))) ; times out in older Emacsen
   (let* ((emacs (concat invocation-directory invocation-name))
-         (test-function 'cperl-mode-test--run-bug-10483)
+         (test-function 'cperl-test--run-bug-10483)
          (test-function-name (symbol-name test-function))
          (test-file (symbol-file test-function 'defun))
          (ran-out-of-time nil)
@@ -138,118 +190,54 @@ under timeout control."
       (should (string-match
                "poop ('foo', \n      'bar')" (buffer-string))))))
 
-(ert-deftest cperl-mode-test-indent-exp ()
-  "Run various tests for `cperl-indent-exp' edge cases.
-These exercise some standard blocks and also the special
-treatment for Perl expressions where a closing paren isn't the
-end of the statement."
+(ert-deftest cperl-test-bug-16368 ()
+  "Verify that `cperl-forward-group-in-re' doesn't hide errors."
   (skip-unless (eq cperl-test-mode #'cperl-mode))
-  (let ((file (ert-resource-file "cperl-indent-exp.pl")))
+  (let ((code "/(\\d{4})(?{2}/;")     ; the regex from the bug report
+        (result))
     (with-temp-buffer
-      (insert-file-contents file)
-      (goto-char (point-min))
-      (while (re-search-forward
-              (concat "^# ?-+ \\_<\\(?1:.+?\\)\\_>: input ?-+\n"
-                      "\\(?2:\\(?:.*\n\\)+?\\)"
-                      "# ?-+ \\1: expected output ?-+\n"
-                      "\\(?3:\\(?:.*\n\\)+?\\)"
-                      "# ?-+ \\1: end ?-+")
-              nil t)
-        (let ((name (match-string 1))
-              (code (match-string 2))
-              (expected (match-string 3))
-              got)
-          (with-temp-buffer
-            (insert code)
-           (cperl-mode)
-            (goto-char (point-min))
-            (cperl-indent-exp) ; here we go!
-            (setq expected (concat "test case " name ":\n" expected))
-            (setq got (concat "test case " name ":\n" (buffer-string)))
-            (should (equal got expected))))))))
-
-(ert-deftest cperl-mode-test-indent-styles ()
-  "Verify correct indentation by style \"PBP\".
-Perl Best Practices sets some indentation values different from
-  the defaults, and also wants an \"else\" or \"elsif\" keyword
-  to align with the \"if\"."
-  (let ((file (ert-resource-file "cperl-indent-styles.pl")))
+      (insert code)
+      (goto-char 9)
+      (setq result (cperl-forward-group-in-re))
+      (should (equal (car result) 'scan-error))
+      (should (equal (nth 1 result) "Unbalanced parentheses"))
+      (should (= (point) 9))))        ; point remains unchanged on error
+  (let ((code "/(\\d{4})(?{2})/;")    ; here all parens are balanced
+        (result))
     (with-temp-buffer
-      (cperl-set-style "PBP")
-      (insert-file-contents file)
-      (goto-char (point-min))
-      (while (re-search-forward
-              (concat "^# ?-+ \\_<\\(?1:.+?\\)\\_>: input ?-+\n"
-                      "\\(?2:\\(?:.*\n\\)+?\\)"
-                      "# ?-+ \\1: expected output ?-+\n"
-                      "\\(?3:\\(?:.*\n\\)+?\\)"
-                      "# ?-+ \\1: end ?-+")
-              nil t)
-        (let ((name (match-string 1))
-              (code (match-string 2))
-              (expected (match-string 3))
-              got)
-          (with-temp-buffer
-            (insert code)
-           (cperl-mode)
-           (indent-region (point-min) (point-max)) ; here we go!
-            (setq expected (concat "test case " name ":\n" expected))
-            (setq got (concat "test case " name ":\n" (buffer-string)))
-            (should (equal got expected)))))
-      (cperl-set-style "CPerl"))))
+      (insert code)
+      (goto-char 9)
+      (setq result (cperl-forward-group-in-re))
+      (should (equal result nil))
+      (should (= (point) 15)))))      ; point has skipped the group
 
-(ert-deftest cperl-mode-fontify-punct-vars ()
-  "Test fontification of Perl's punctiation variables.
-Perl has variable names containing unbalanced quotes for the list
-separator $\" and pre- and postmatch $` and $'.  A reference to
-these variables, for example \\$\", should not cause the dollar
-to be escaped, which would then start a string beginning with the
-quote character.  This used to be broken in cperl-mode at some
-point in the distant past, and is still broken in perl-mode. "
-  (skip-unless (eq cperl-test-mode #'cperl-mode))
-  (let ((file (ert-resource-file "fontify-punctuation-vars.pl")))
-    (with-temp-buffer
-      (insert-file-contents file)
-      (goto-char (point-min))
-      (funcall cperl-test-mode)
-      (while (search-forward "##" nil t)
-        ;; The third element of syntax-ppss is true if in a string,
-        ;; which would indicate bad interpretation of the quote.  The
-        ;; fourth element is true if in a comment, which should be the
-        ;; case.
-        (should (equal (nth 3 (syntax-ppss)) nil))
-        (should (equal (nth 4 (syntax-ppss)) t))))))
+(ert-deftest cperl-test-bug-19709 ()
+  "Verify that indentation of closing paren works as intended.
+Note that Perl mode has no setting for close paren offset, per
+documentation it does the right thing anyway."
+  (cperl--run-test-cases
+   (ert-resource-file "cperl-bug-19709.pl")
+   ;; settings from the bug report
+   (setq-local cperl-indent-level 4)
+   (setq-local cperl-indent-parens-as-block t)
+   (setq-local  cperl-close-paren-offset -4)
+   ;; same, adapted for per-mode
+   (setq-local perl-indent-level 4)
+   (setq-local perl-indent-parens-as-block t)
+   (while (null (eobp))
+     (cperl-indent-command)
+     (forward-line 1))))
 
-(ert-deftest cperl-bug30393 ()
+(ert-deftest cperl-test-bug-30393 ()
   "Verify that indentation is not disturbed by an open paren in col 0.
 Perl is not Lisp: An open paren in column 0 does not start a function."
-  (let ((file (ert-resource-file "cperl-bug-30393.pl")))
-    (with-temp-buffer
-      (insert-file-contents file)
-      (goto-char (point-min))
-      (while (re-search-forward
-              (concat "^# ?-+ \\_<\\(?1:.+?\\)\\_>: input ?-+\n"
-                      "\\(?2:\\(?:.*\n\\)+?\\)"
-                      "# ?-+ \\1: expected output ?-+\n"
-                      "\\(?3:\\(?:.*\n\\)+?\\)"
-                      "# ?-+ \\1: end ?-+")
-              nil t)
-        (let ((name (match-string 1))
-              (code (match-string 2))
-              (expected (match-string 3))
-              got)
-          (with-temp-buffer
-            (insert code)
-           (funcall cperl-test-mode)
-            (goto-char (point-min))
-            (while (null (eobp))
-              (cperl-indent-command)
-              (forward-line 1))
-            (setq expected (concat "test case " name ":\n" expected))
-            (setq got (concat "test case " name ":\n" (buffer-string)))
-            (should (equal got expected))))))))
+  (cperl--run-test-cases
+   (ert-resource-file "cperl-bug-30393.pl")
+   (while (null (eobp))
+     (cperl-indent-command)
+     (forward-line 1))))
 
-(ert-deftest cperl-bug37127 ()
+(ert-deftest cperl-test-bug-37127 ()
   "Verify that closing a paren in a regex goes without a message.
 Also check that the message is issued if the regex terminator is
 missing."
@@ -289,4 +277,24 @@ missing."
       (should (string-match "^End of .* string/RE"
                             collected-messages)))))
 
+(ert-deftest cperl-test-bug-42168 ()
+  "Verify that '/' is a division after ++ or --, not a regexp.
+Reported in https://github.com/jrockway/cperl-mode/issues/45.
+If seen as regular expression, then the slash is displayed using
+font-lock-constant-face.  If seen as a division, then it doesn't
+have a face property."
+  :tags '(:fontification)
+  ;; The next two Perl expressions have divisions.  Perl "punctuation"
+  ;; operators don't get a face.
+  (let ((code "{ $a++ / $b }"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) nil)))
+  (let ((code "{ $a-- / $b }"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) nil)))
+  ;; The next two Perl expressions have regular expressions.  The
+  ;; delimiter of a RE is fontified with font-lock-constant-face.
+  (let ((code "{ $a+ / $b } # /"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) 7)))
+  (let ((code "{ $a- / $b } # /"))
+    (should (equal (nth 8 (cperl-test-ppss code "/")) 7))))
+
 ;;; cperl-mode-tests.el ends here
diff --git a/test/lisp/textmodes/reftex-tests.el 
b/test/lisp/textmodes/reftex-tests.el
index 2350326..42a060b 100644
--- a/test/lisp/textmodes/reftex-tests.el
+++ b/test/lisp/textmodes/reftex-tests.el
@@ -153,24 +153,23 @@
   edition =   {17th},
   note   =      {Updated for Emacs   Version 24.2}
 }")
-        (check (function
-                (lambda (parsed)
-                  (should (string= (reftex-get-bib-field "&key" parsed)
-                                   "Stallman12"))
-                  (should (string= (reftex-get-bib-field "&type" parsed)
-                                   "book"))
-                  (should (string= (reftex-get-bib-field "author" parsed)
-                                   "Richard Stallman et al."))
-                  (should (string= (reftex-get-bib-field "title" parsed)
-                                   "The Emacs Editor"))
-                  (should (string= (reftex-get-bib-field "publisher" parsed)
-                                   "GNU Press"))
-                  (should (string= (reftex-get-bib-field "year" parsed)
-                                   "2012"))
-                  (should (string= (reftex-get-bib-field "edition" parsed)
-                                   "17th"))
-                  (should (string= (reftex-get-bib-field "note" parsed)
-                                   "Updated for Emacs Version 24.2"))))))
+        (check (lambda (parsed)
+                 (should (string= (reftex-get-bib-field "&key" parsed)
+                                  "Stallman12"))
+                 (should (string= (reftex-get-bib-field "&type" parsed)
+                                  "book"))
+                 (should (string= (reftex-get-bib-field "author" parsed)
+                                  "Richard Stallman et al."))
+                 (should (string= (reftex-get-bib-field "title" parsed)
+                                  "The Emacs Editor"))
+                 (should (string= (reftex-get-bib-field "publisher" parsed)
+                                  "GNU Press"))
+                 (should (string= (reftex-get-bib-field "year" parsed)
+                                  "2012"))
+                 (should (string= (reftex-get-bib-field "edition" parsed)
+                                  "17th"))
+                 (should (string= (reftex-get-bib-field "note" parsed)
+                                  "Updated for Emacs Version 24.2")))))
     (funcall check (reftex-parse-bibtex-entry entry))
     (with-temp-buffer
       (insert entry)
diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el
index 8331a41..e3dd842 100644
--- a/test/src/keymap-tests.el
+++ b/test/src/keymap-tests.el
@@ -48,10 +48,6 @@
     (set-keymap-parent map help-mode-map)
     (should (equal (keymap-parent map) help-mode-map))))
 
-(ert-deftest keymap-keymap-set-parent/returns-parent ()
-  (let ((map (make-keymap)))
-    (should (equal (set-keymap-parent map help-mode-map) help-mode-map))))
-
 (ert-deftest keymap-copy-keymap/is-equal ()
   (should (equal (copy-keymap help-mode-map) help-mode-map)))
 



reply via email to

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