emacs-diffs
[Top][All Lists]
Advanced

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

scratch/pkg ec4bdca4924: Merge remote-tracking branch 'origin/master' in


From: Gerd Moellmann
Subject: scratch/pkg ec4bdca4924: Merge remote-tracking branch 'origin/master' into scratch/pkg
Date: Tue, 31 Oct 2023 08:47:12 -0400 (EDT)

branch: scratch/pkg
commit ec4bdca49247f70cf138b4b2d12de1e110ea5778
Merge: 553785862f7 bdec2d2d464
Author: Gerd Möllmann <gerd@gnu.org>
Commit: Gerd Möllmann <gerd@gnu.org>

    Merge remote-tracking branch 'origin/master' into scratch/pkg
---
 ChangeLog.1                                        |    2 +-
 ChangeLog.2                                        |   13 +-
 ChangeLog.3                                        |   12 +-
 ChangeLog.4                                        | 1983 +++++++++++++++++++-
 Makefile.in                                        |    2 +-
 admin/MAINTAINERS                                  |    4 -
 admin/notes/emba                                   |    2 +-
 doc/emacs/ChangeLog.1                              |    2 +-
 doc/emacs/custom.texi                              |   17 +-
 doc/emacs/input.texi                               |   85 +-
 doc/emacs/misc.texi                                |   24 +-
 doc/emacs/screen.texi                              |    8 +-
 doc/emacs/windows.texi                             |   22 +
 doc/lispintro/emacs-lisp-intro.texi                |    1 +
 doc/lispref/ChangeLog.1                            |    2 +-
 doc/lispref/buffers.texi                           |   22 +-
 doc/lispref/commands.texi                          |   11 +-
 doc/lispref/elisp.texi                             |    6 +-
 doc/lispref/errors.texi                            |    3 +-
 doc/lispref/eval.texi                              |   14 +-
 doc/lispref/files.texi                             |    2 +-
 doc/lispref/frames.texi                            |  844 +++++----
 doc/lispref/modes.texi                             |    5 +-
 doc/lispref/strings.texi                           |   11 +-
 doc/lispref/tips.texi                              |    2 +-
 doc/lispref/variables.texi                         |  390 ++--
 doc/man/ChangeLog.1                                |    4 +-
 doc/man/emacsclient.1                              |   30 +-
 doc/misc/ChangeLog.1                               |    4 +-
 doc/misc/ede.texi                                  |  210 ++-
 doc/misc/efaq.texi                                 |   15 +-
 doc/misc/erc.texi                                  |   81 +-
 doc/misc/eshell.texi                               |   13 +-
 doc/misc/gnus.texi                                 |   26 +-
 doc/misc/octave-mode.texi                          |    4 +-
 doc/misc/tramp.texi                                |   27 +-
 doc/misc/use-package.texi                          |    4 +-
 doc/misc/wisent.texi                               |    3 +-
 etc/AUTHORS                                        |  128 +-
 etc/CALC-NEWS                                      |    2 +-
 etc/ChangeLog.1                                    |    6 +-
 etc/ERC-NEWS                                       |   51 +-
 etc/NEWS                                           |  162 +-
 etc/emacsclient-mail.desktop                       |    7 +-
 etc/publicsuffix.txt                               |    2 +-
 java/org/gnu/emacs/EmacsNative.java                |    3 +
 java/org/gnu/emacs/EmacsOpenActivity.java          |   20 +
 java/org/gnu/emacs/EmacsSdk11Clipboard.java        |   24 +
 java/org/gnu/emacs/EmacsWindow.java                |  100 +-
 lib-src/ChangeLog.1                                |    8 +-
 lisp/ChangeLog.12                                  |    4 +-
 lisp/ChangeLog.13                                  |    4 +-
 lisp/ChangeLog.14                                  |   20 +-
 lisp/ChangeLog.15                                  |   10 +-
 lisp/ChangeLog.16                                  |    6 +-
 lisp/ChangeLog.17                                  |    2 +-
 lisp/ChangeLog.4                                   |    6 +-
 lisp/ChangeLog.5                                   |    2 +-
 lisp/ChangeLog.6                                   |    2 +-
 lisp/align.el                                      |   13 +-
 lisp/auth-source.el                                |    6 -
 lisp/bindings.el                                   |   34 +-
 lisp/calc/calc-units.el                            |    4 +-
 lisp/cedet/semantic/imenu.el                       |    6 +-
 lisp/cus-edit.el                                   |  360 +++-
 lisp/dired.el                                      |    4 +-
 lisp/dnd.el                                        |  106 +-
 lisp/emacs-lisp/bytecomp.el                        |    4 +
 lisp/emacs-lisp/checkdoc.el                        |   39 -
 lisp/emacs-lisp/cl-macs.el                         |    8 +-
 lisp/emacs-lisp/cl-preloaded.el                    |    9 +-
 lisp/emacs-lisp/comp-cstr.el                       |  160 +-
 lisp/emacs-lisp/comp.el                            |    5 +-
 lisp/emacs-lisp/icons.el                           |    6 +-
 lisp/emacs-lisp/nadvice.el                         |   20 +-
 lisp/emacs-lisp/smie.el                            |    4 +-
 lisp/erc/erc-backend.el                            |    9 +-
 lisp/erc/erc-common.el                             |   22 +-
 lisp/erc/erc-fill.el                               |   33 +-
 lisp/erc/erc-goodies.el                            |   27 +-
 lisp/erc/erc-log.el                                |    4 +-
 lisp/erc/erc-match.el                              |    4 +-
 lisp/erc/erc-networks.el                           |   12 +-
 lisp/erc/erc-notify.el                             |    4 +-
 lisp/erc/erc-speedbar.el                           |    2 +-
 lisp/erc/erc-stamp.el                              |   60 +-
 lisp/erc/erc-track.el                              |   18 +-
 lisp/erc/erc.el                                    |  405 ++--
 lisp/eshell/em-cmpl.el                             |    3 +-
 lisp/eshell/em-extpipe.el                          |  161 +-
 lisp/eshell/em-smart.el                            |   81 +-
 lisp/eshell/esh-arg.el                             |  261 ++-
 lisp/eshell/esh-cmd.el                             |   43 -
 lisp/eshell/esh-io.el                              |    3 +-
 lisp/eshell/esh-proc.el                            |   51 +-
 lisp/eshell/esh-util.el                            |   43 +
 lisp/ffap.el                                       |    8 +-
 lisp/files-x.el                                    |  120 +-
 lisp/files.el                                      |   44 +-
 lisp/gnus/ChangeLog.3                              |    2 +-
 lisp/gnus/gnus-art.el                              |   12 +-
 lisp/gnus/gnus-bookmark.el                         |    8 +-
 lisp/gnus/gnus-group.el                            |   20 +-
 lisp/gnus/gnus-sum.el                              |    5 +-
 lisp/gnus/message.el                               |   13 +-
 lisp/gnus/mml.el                                   |   59 +-
 lisp/gnus/mml2015.el                               |    4 +-
 lisp/gnus/nnheader.el                              |    2 +-
 lisp/gnus/nnrss.el                                 |    2 +-
 lisp/gnus/nnweb.el                                 |   39 +-
 lisp/gnus/spam-report.el                           |    6 +-
 lisp/ido.el                                        |    2 +-
 lisp/info-look.el                                  |    9 +-
 lisp/language/hanja-util.el                        |   18 +-
 lisp/loadup.el                                     |   50 +-
 lisp/mh-e/mh-mime.el                               |    1 +
 lisp/net/browse-url.el                             |    8 +-
 lisp/net/newst-backend.el                          |    4 +-
 lisp/net/newst-reader.el                           |    5 +-
 lisp/net/nsm.el                                    |   24 +-
 lisp/net/rcirc.el                                  |   11 +-
 lisp/net/sieve-manage.el                           |    2 +-
 lisp/net/tramp-sh.el                               |    3 +-
 lisp/net/tramp.el                                  |    6 +-
 lisp/net/trampver.el                               |    2 +-
 lisp/net/webjump.el                                |   55 +-
 lisp/obsolete/terminal.el                          |    2 +-
 lisp/org/ob-lua.el                                 |    2 +-
 lisp/org/ob-python.el                              |    4 +-
 lisp/org/org.el                                    |    2 +-
 lisp/pcmpl-unix.el                                 |    8 +
 lisp/pgtk-dnd.el                                   |   30 +-
 lisp/progmodes/cc-mode.el                          |    2 +-
 lisp/progmodes/cperl-mode.el                       |  120 +-
 lisp/progmodes/eglot.el                            |    4 +-
 lisp/progmodes/elixir-ts-mode.el                   |    7 +-
 lisp/progmodes/flymake.el                          |    4 +-
 lisp/progmodes/gdb-mi.el                           |   44 +-
 lisp/progmodes/gud.el                              |  146 +-
 lisp/progmodes/idlw-shell.el                       |    4 +-
 lisp/progmodes/js.el                               |    2 +-
 lisp/progmodes/lua-ts-mode.el                      |  428 ++++-
 lisp/progmodes/octave.el                           |    4 +-
 lisp/progmodes/project.el                          |   97 +-
 lisp/progmodes/typescript-ts-mode.el               |    2 +-
 lisp/progmodes/vhdl-mode.el                        |   17 +-
 lisp/progmodes/which-func.el                       |   39 +-
 lisp/progmodes/xref.el                             |    7 +-
 lisp/select.el                                     |   39 +-
 lisp/server.el                                     |   27 +-
 lisp/so-long.el                                    |   25 +-
 lisp/speedbar.el                                   |    2 +-
 lisp/sqlite-mode.el                                |    1 +
 lisp/startup.el                                    |    5 +-
 lisp/subr.el                                       |   40 +-
 lisp/tab-bar.el                                    |    4 +-
 lisp/term/android-win.el                           |    6 +-
 lisp/term/haiku-win.el                             |   11 +-
 lisp/term/ns-win.el                                |   11 +-
 lisp/term/pgtk-win.el                              |   40 -
 lisp/term/w32-win.el                               |   14 +-
 lisp/term/xterm.el                                 |    2 +-
 lisp/textmodes/dns-mode.el                         |    1 +
 lisp/textmodes/fill.el                             |    2 +-
 lisp/thingatpt.el                                  |    4 +-
 lisp/touch-screen.el                               |   35 +-
 lisp/treesit.el                                    |   64 +-
 lisp/url/url-vars.el                               |    2 +-
 lisp/vc/log-view.el                                |   12 +-
 lisp/window.el                                     |   65 +-
 lisp/x-dnd.el                                      |   31 +-
 nextstep/ChangeLog.1                               |    2 +-
 oldXMenu/ChangeLog.1                               |    4 +-
 src/ChangeLog.11                                   |   12 +-
 src/ChangeLog.4                                    |    2 +-
 src/android.c                                      |   40 +-
 src/androidselect.c                                |    6 +-
 src/androidterm.c                                  |   29 +-
 src/androidvfs.c                                   |   48 +-
 src/casefiddle.c                                   |   25 +-
 src/dispnew.c                                      |    6 +-
 src/eval.c                                         |   10 +-
 src/haiku_support.cc                               |   38 +-
 src/haikuterm.c                                    |    8 +-
 src/indent.c                                       |    4 +-
 src/keyboard.c                                     |   65 +-
 src/lisp.h                                         |    1 +
 src/msdos.c                                        |    2 +-
 src/nsterm.m                                       |    4 +-
 src/pdumper.c                                      |   16 +-
 src/pgtkterm.c                                     |    4 +-
 src/print.c                                        |    2 +-
 src/profiler.c                                     |   71 +-
 src/search.c                                       |   11 +-
 src/sfnt.c                                         |  128 +-
 src/sfnt.h                                         |    6 +
 src/sfntfont.c                                     |   68 +-
 src/w32.c                                          |    2 +-
 src/w32inevt.c                                     |    2 +-
 src/w32term.c                                      |    8 +-
 src/window.c                                       |   20 +-
 src/window.h                                       |    2 +-
 src/xdisp.c                                        |   14 +-
 src/xterm.c                                        |   31 +-
 test/lisp/align-resources/lua-ts-mode.erts         |   67 +
 test/lisp/align-tests.el                           |    9 +
 test/lisp/dnd-tests.el                             |  158 ++
 .../bytecomp-resources/no-byte-compile.el          |    2 +-
 test/lisp/emacs-lisp/bytecomp-tests.el             |   39 +-
 test/lisp/emacs-lisp/comp-cstr-tests.el            |   12 +-
 test/lisp/erc/erc-fill-tests.el                    |   80 +-
 test/lisp/erc/erc-networks-tests.el                |    7 +-
 test/lisp/erc/erc-scenarios-base-reuse-buffers.el  |    2 +
 test/lisp/erc/erc-scenarios-display-message.el     |   64 +
 test/lisp/erc/erc-scenarios-log.el                 |    2 +-
 test/lisp/erc/erc-scenarios-stamp.el               |  116 ++
 test/lisp/erc/erc-tests.el                         |  167 +-
 .../resources/base/display-message/multibuf.eld    |   45 +
 .../erc/resources/base/renick/queries/solo.eld     |    2 +-
 .../base/reuse-buffers/channel/barnet.eld          |    2 +-
 .../base/reuse-buffers/channel/foonet.eld          |    2 +-
 test/lisp/erc/resources/erc-d/erc-d-t.el           |    1 +
 test/lisp/erc/resources/erc-scenarios-common.el    |    4 +-
 .../resources/fill/snapshots/merge-01-start.eld    |    2 +-
 .../resources/fill/snapshots/merge-02-right.eld    |    2 +-
 .../erc/resources/fill/snapshots/merge-wrap-01.eld |    2 +-
 .../fill/snapshots/monospace-01-start.eld          |    2 +-
 .../fill/snapshots/monospace-02-right.eld          |    2 +-
 .../resources/fill/snapshots/monospace-03-left.eld |    2 +-
 .../fill/snapshots/monospace-04-reset.eld          |    2 +-
 .../resources/fill/snapshots/spacing-01-mono.eld   |    2 +-
 .../resources/fill/snapshots/stamps-left-01.eld    |    2 +-
 test/lisp/erc/resources/join/network-id/foonet.eld |    4 +-
 test/lisp/eshell/em-cmpl-tests.el                  |   32 +-
 test/lisp/eshell/em-extpipe-tests.el               |    8 +-
 test/lisp/eshell/esh-arg-tests.el                  |   63 +-
 test/lisp/gnus/gnus-group-tests.el                 |    2 +-
 test/lisp/net/webjump-tests.el                     |    2 +-
 .../progmodes/lua-ts-mode-resources/indent.erts    |  705 ++++++-
 .../progmodes/lua-ts-mode-resources/movement.erts  |  156 +-
 test/lisp/progmodes/which-func-tests.el            |   58 +
 test/lisp/subr-tests.el                            |   16 +-
 test/src/casefiddle-tests.el                       |   12 +
 test/src/filelock-tests.el                         |    2 +-
 244 files changed, 8291 insertions(+), 2734 deletions(-)

diff --git a/ChangeLog.1 b/ChangeLog.1
index 654cb43d4dc..597b320dff4 100644
--- a/ChangeLog.1
+++ b/ChangeLog.1
@@ -1494,7 +1494,7 @@
 2014-01-05  Paul Eggert  <eggert@cs.ucla.edu>
 
        Port to GNU/Linux with recent grsecurity/PaX patches (Bug#16343).
-       Problem and proposed patch reported by Ulrich Mueller;
+       Problem and proposed patch reported by Ulrich Müller;
        this patch uses a somewhat-different approach.
        * configure.ac (SETFATTR): New variable.
 
diff --git a/ChangeLog.2 b/ChangeLog.2
index 11e6049b0bd..d40401093c5 100644
--- a/ChangeLog.2
+++ b/ChangeLog.2
@@ -10661,8 +10661,8 @@
 
        * lisp/gnus/nnir.el (nnir-request-update-mark):
        Default to the original mark.
-       cf. <http://thread.gmane.org/gmane.emacs.gnus.general/86583>
-       and <http://thread.gmane.org/gmane.emacs.gnus.general/86640>
+       cf. <http://thread.gmane.org/gmane.emacs.gnus.general/86583> [dead link]
+       and <http://thread.gmane.org/gmane.emacs.gnus.general/86640> [dead link]
 
 2016-01-19  Glenn Morris  <rgm@gnu.org>
 
@@ -12012,7 +12012,7 @@
        (Maybe this is the last merge from Gnus git to Emacs git)
 
        Cf. discussion on ding mailing list, messages in
-       <http://thread.gmane.org/gmane.emacs.gnus.general/86228>.
+       <http://thread.gmane.org/gmane.emacs.gnus.general/86228>. [dead link]
        Common code from the three files mml-smime.el, mml1991.el, and
        mml2015.el is moved to mml-sec.el.  Auxiliary functions are added
        to gnus-util.el.
@@ -15206,8 +15206,9 @@
        Remove nnml-retrieve-groups that is unnecessary and somewhat problematic
 
        * lisp/gnus/nnml.el (nnml-retrieve-groups): Remove.  See:
-       <http://thread.gmane.org/gmane.emacs.gnus.general/86308> and
-       <http://thread.gmane.org/gmane.emacs.gnus.general/86321>
+       <http://thread.gmane.org/gmane.emacs.gnus.general/86308> [dead link]
+       and
+       <http://thread.gmane.org/gmane.emacs.gnus.general/86321> [dead link]
 
 2015-11-25  Paul Eggert  <eggert@cs.ucla.edu>
 
@@ -30968,7 +30969,7 @@
 2015-05-28  Katsumi Yamaoka  <yamaoka@jpl.org>
 
        * lisp/gnus/gnus-art.el (gnus-button-alist): Re-revert last change.
-       cf. <http://news.gmane.org/group/gmane.emacs.devel/thread=186896>
+       cf. <http://news.gmane.org/group/gmane.emacs.devel/thread=186896> [dead 
link]
 
 2015-05-28  Samer Masterson  <samer@samertm.com>
 
diff --git a/ChangeLog.3 b/ChangeLog.3
index 85cccf0d6ed..d831b14178c 100644
--- a/ChangeLog.3
+++ b/ChangeLog.3
@@ -3672,7 +3672,7 @@
        * lib-src/emacsclient.c (set_local_socket): Revert to the Emacs 27
        behavior of not trying TMPDIR if XDG_RUNTIME_DIR is set.
        This is one of the suggestions made by Jim Porter and
-       independently by Ulrich Mueller in Bug#51327.
+       independently by Ulrich Müller in Bug#51327.
 
 2021-12-09  Cameron Desautels  <camdez@gmail.com>
 
@@ -44923,7 +44923,7 @@
 
        * etc/NEWS: Announce the new 'cham' input method.
        * etc/HELLO: Fix the order of letters in the Cham greeting.
-       Remove redundant newlines (reported by Ulrich Mueller
+       Remove redundant newlines (reported by Ulrich Müller
        <ulm@gentoo.org>).
 
        * lisp/language/cham.el ("Cham"): Add input-method entry.
@@ -155306,7 +155306,7 @@
 
        Set group when installing, too
 
-       From a patch by Ulrich Mueller in:
+       From a patch by Ulrich Müller in:
        https://lists.gnu.org/r/emacs-devel/2018-06/msg00687.html
        * Makefile.in (set_installuser): Also set the group, in order
        to match install(1) behavior.  Also, don’t clutter stderr
@@ -161872,7 +161872,7 @@
 
        Port to 32-bit sparc64
 
-       Problem reported by Ulrich Mueller; fix suggested by Eli Zaretskii
+       Problem reported by Ulrich Müller; fix suggested by Eli Zaretskii
        and Andreas Schwab (Bug#30855).
        * src/alloc.c (mark_memory): Call mark_maybe_object only on
        pointers that are properly aligned for Lisp_Object.
@@ -178544,7 +178544,7 @@
        Port to 32-bit sparc64
 
        Backport from master.
-       Problem reported by Ulrich Mueller; fix suggested by Eli Zaretskii
+       Problem reported by Ulrich Müller; fix suggested by Eli Zaretskii
        and Andreas Schwab (Bug#30855).
        * src/alloc.c (mark_memory): Call mark_maybe_object only on
        pointers that are properly aligned for Lisp_Object.
@@ -234791,7 +234791,7 @@
        (Maybe this is the last merge from Gnus git to Emacs git)
 
        Cf. discussion on ding mailing list, messages in
-       <http://thread.gmane.org/gmane.emacs.gnus.general/86228>.
+       <http://thread.gmane.org/gmane.emacs.gnus.general/86228>. [dead link]
        Common code from the three files mml-smime.el, mml1991.el, and
        mml2015.el is moved to mml-sec.el.  Auxiliary functions are added
        to gnus-util.el.
diff --git a/ChangeLog.4 b/ChangeLog.4
index 1c9b8f43377..24afabdbbb1 100644
--- a/ChangeLog.4
+++ b/ChangeLog.4
@@ -1,3 +1,1984 @@
+2023-10-16  Po Lu  <luangruo@yahoo.com>
+
+       Correctly register focus events concomitant with alpha changes
+
+       * src/xterm.c (x_frame_highlight, x_frame_unhighlight): Skip
+       changing the frame alpha when the frame is not eligible for
+       focus state-specific alpha values; otherwise, the alpha might be
+       reset by the time a alpha change wrought by a focus change
+       arrives, impeding handle_one_xevent from subsequently restoring
+       the initial value.  (bug#66398)
+
+2023-10-16  Michael Albinus  <michael.albinus@gmx.de>
+
+       * doc/man/emacsclient.1: Add missing options.
+
+2023-10-15  Michael Albinus  <michael.albinus@gmx.de>
+
+       Fix test in files-tests
+
+       * test/lisp/files-tests.el
+       (files-tests-file-name-non-special-expand-file-name-tilde): Fix test.
+
+2023-10-14  Stefan Kangas  <stefankangas@gmail.com>
+
+       Add missing :version to two defcustoms
+
+       * lisp/emacs-lisp/eldoc.el (eldoc-print-after-edit)
+       (eldoc-echo-area-prefer-doc-buffer): Add missing custom :version.
+
+2023-10-14  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix a defcustom :type in eldoc.el
+
+       * lisp/emacs-lisp/eldoc.el (eldoc-echo-area-prefer-doc-buffer): Make
+       :type a choice, to allow for the value 'maybe'.  (Bug##66539)
+
+2023-10-14  Eshel Yaron  <me@eshelyaron.com>
+
+       Document 'M-x align' in the Emacs manual
+
+       * doc/emacs/indent.texi (Alignment): New section.
+       * doc/emacs/emacs.texi: Update menu. (Bug#66303)
+
+2023-10-14  Bob Rogers  <rogers@rgrjr.com>
+
+       Document that time-to-days and days-to-time use different epochs
+
+       * doc/lispref/os.texi (Time Calculations):
+       * lisp/calendar/time-date.el (days-to-time, time-to-days): Doc fixes.
+       (Bug#66502)
+
+2023-10-14  Michael Albinus  <michael.albinus@gmx.de>
+
+       * lisp/files.el (file-name-non-special): Handle quoted tilde.
+
+       (Bug#65685)
+
+       * test/lisp/files-tests.el
+       (files-tests-file-name-non-special-expand-file-name-tilde):
+       New test.
+
+2023-10-13  Michael Albinus  <michael.albinus@gmx.de>
+
+       Handle quoted tilde in Tramp
+
+       * lisp/net/tramp.el (tramp-handle-expand-file-name):
+       * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-expand-file-name):
+       * lisp/net/tramp-sh.el (tramp-sh-handle-expand-file-name):
+       * lisp/net/tramp-smb.el (tramp-smb-handle-expand-file-name):
+       * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-expand-file-name):
+       Handle quoted tilde.  (Bug#65685)
+
+       * test/lisp/net/tramp-tests.el (tramp-test05-expand-file-name-tilde):
+       New test.
+
+2023-10-09  Kyle Meyer  <kyle@kyleam.com>
+
+       Update to Org 9.6.10
+
+2023-10-09  Yuan Fu  <casouri@gmail.com>
+
+       Don't call font-lock-mode in treesit-major-mode-setup (bug#66223)
+
+       * lisp/treesit.el (treesit-major-mode-setup): Remove.
+
+       (cherry picked from commit a3a840c80a217db7d4d125c667ff7d4946507fbb)
+
+2023-10-09  Noah Peart  <noah.v.peart@gmail.com>
+
+       Fix treesit-query-validate for string input (bug#66400)
+
+       * lisp/treesit.el (treesit-query-validate): Don't expand if QUERY is
+       string.
+
+2023-10-07  Stefan Kangas  <stefankangas@gmail.com>
+
+       Recommend `M-x man` in woman.el docs
+
+       * lisp/woman.el (Commentary, woman): Recommend using 'M-x man' where
+       available.  The added sentence is copied from the emacs manual.
+       Ref: https://lists.gnu.org/r/emacs-devel/2023-10/msg00090.html
+
+2023-10-07  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix updating process-mark position in 'set-process-buffer'
+
+       * src/process.c (update_process_mark): Update marker position only
+       if P's process-mark is not already associated with P's buffer.
+       (Bug#66313)
+
+2023-10-07  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix a defcustom :type
+
+       * lisp/cedet/srecode/map.el (srecode-map-save-file): Expand :type to
+       allow nil.  (Bug#66377)
+
+2023-10-07  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix 'ido--ffap-find-file'
+
+       * lisp/ido.el (ido--ffap-find-file): Make the signature consistent
+       with that of 'find-file', and pass the optional second argument to
+       'find-file'.  (Bug#66382)
+
+2023-10-06  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix setting the pipe capacity for subprocesses
+
+       * src/process.c (create_process) [F_SETPIPE_SZ]: Set the pipe
+       capacity only if the required read-process-max is larger than the
+       default capacity of the pipe.  (Bug#66288)
+
+2023-10-05  Gerd Möllmann  <gerd@gnu.org>
+
+       Handle LANG on macOS differently (bug#65908)
+
+       * src/nsterm.m (ns_init_locale): If LANG is set, try to use that,
+       otherwise try to deduce what LANG should be.  Check is the result is
+       valid, and use LANG="en_US.UTF-8" if not.
+
+2023-10-05  Jens Schmidt  <jschmidt4gnu@vodafonemail.de>
+
+       Silence macro expansion during completion at point
+
+       To keep risk in the current release branch low, do not avoid compiler
+       macros as suggested by Stefan in the bug, but rather suppress all 
errors.
+
+       * lisp/progmodes/elisp-mode.el (elisp--local-variables): Silence
+       messages.  Suppress all errors during macro expansion.  (Bug#58148)
+
+       Do not merge to master.
+
+2023-10-05  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix a defcustom :type
+
+       * lisp/cedet/ede/base.el (ede-project-placeholder-cache-file): Expand
+       :type to allow nil.  (Bug#66361)
+
+2023-10-04  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix pulse-flag :type
+
+       * lisp/cedet/pulse.el (pulse-flag): Expand :type to allow 'never as
+       value.  (Bug#66341)
+
+2023-10-03  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix defcustoms in timeclock.el
+
+       * lisp/calendar/timeclock.el (timeclock-get-project-function)
+       (timeclock-get-reason-function): Fix :type to allow nil.  (Bug#66320)
+
+2023-10-01  Stefan Kangas  <stefankangas@gmail.com>
+
+       Improve documentation of `ns-use-proxy-icon`
+
+       * doc/emacs/macos.texi (Mac / GNUstep Customization):
+       * src/nsfns.m (syms_of_nsfns): Fix documentation of
+       'ns-use-proxy-icon'; explain what it does and how it's
+       used.  (Bug#66190)
+
+2023-10-01  Stefan Kangas  <stefankangas@gmail.com>
+
+       Document assigning libraries to packages in make-tarball.txt
+
+       * admin/make-tarball.txt: Add new step to ensure that new libraries
+       are assigned to packages.
+
+2023-10-01  Stefan Kangas  <stefankangas@gmail.com>
+
+       Doc fix; more consistently refer to "text terminals"
+
+       In the Emacs Lisp manual, we refer to "text terminals" and "graphical
+       terminals" (see Info node `(elisp) Frames').  But in some places,
+       including the user manual, the alternative terminology "non-window
+       terminals" is used instead.
+
+       In other places, we use the terminology "non-windowing display"
+       instead of the more canonical "non-graphical display".
+
+       This is less clear than it could be.  Let's consolidate our
+       terminology to prefer the wording from the Emacs Lisp manual; in other
+       words, prefer "text" and "non-graphical" to "non-window".
+
+       * doc/emacs/frames.texi (Non-Window Terminals): Rename node from this...
+       (Text Terminals): ...to this.  (Bug#66282)
+       * doc/emacs/display.texi (Standard Faces):
+       * doc/emacs/emacs.texi (Top):
+       * doc/emacs/misc.texi (emacsclient Options):
+       * doc/misc/viper.texi (Rudimentary Changes)
+       (Packages that Change Keymaps):
+       * doc/emacs/frames.texi (Frames, Frame Commands, Mouse Avoidance):
+       Replace instances of "non-window terminals" with "text terminals".
+       * doc/misc/ediff.texi (Quick Help Customization):
+       (Window and Frame Configuration):
+       * lisp/vc/ediff.el (ediff-windows-wordwise)
+       (ediff-windows-linewise): Prefer saying 'non-graphical display' to
+       'non-windowing display'.
+       * lisp/net/tramp.el (tramp-default-method):
+       * lisp/printing.el (pr-find-command): Capitalize 'Windows' where it
+       clearly refers to the non-free operating system with that name.
+
+2023-09-30  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix defcustoms in type-break.el (Bug#66210)
+
+       * lisp/type-break.el (type-break-good-rest-interval)
+       (type-break-file-name): Allow nil.
+
+2023-09-30  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix term-scroll-to-bottom-on-output :type
+
+       * lisp/term.el (term-scroll-to-bottom-on-output): Add missing choices.
+       Don't advertise the value 'all' in docstring.  (Bug#66071)
+
+2023-09-28  Stefan Kangas  <stefankangas@gmail.com>
+
+       Doc fix in let-alist for keys with nil value
+
+       * lisp/emacs-lisp/let-alist.el (let-alist): Clarify that keys with a
+       nil value will give the same result as if they were missing.
+
+2023-09-28  Michael Albinus  <michael.albinus@gmx.de>
+
+       Fix tramp-test.el (don't merge with master)
+
+       * test/lisp/net/tramp-tests.el (tramp--test-check-files):
+       Don't err out when "printenv" doesn't exist on remote side.
+
+2023-09-25  Michael Albinus  <michael.albinus@gmx.de>
+
+       Improve Emacs 30 compatibility in tramp-tests.el (don't merge)
+
+       * test/lisp/net/tramp-tests.el 
(tramp--test-deftest-direct-async-process)
+       (tramp-test30-make-process): Improve Emacs 30 compatibility.
+
+2023-09-25  Michael Albinus  <michael.albinus@gmx.de>
+
+       Add new Tramp test
+
+       * test/lisp/net/tramp-tests.el (tramp-test46-read-password):
+       Use `copy-tree' but `copy-sequence'.
+       (tramp-test46-read-otp-password): New test.
+
+2023-09-25  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix tmm-mid-prompt :type (Bug#66179)
+
+       * lisp/tmm.el (tmm-mid-prompt): Allow nil.
+
+2023-09-24  Augustin Chéneau  <btuin@mailo.com>  (tiny change)
+
+       Fix tree-sitter indentation conflict with multiple languages
+
+       * lisp/treesit.el (treesit--indent-1): Use bol instead of point.
+
+2023-09-24  Michael Albinus  <michael.albinus@gmx.de>
+
+       Fix bug#66093 in Tramp
+
+       * lisp/net/tramp-sshfs.el (tramp-methods): Use "%a".
+       (tramp-sshfs-handle-process-file): Replace ?a by "-t".
+
+       * lisp/net/tramp.el (tramp-methods): Adapt docstring.  (Bug#66093)
+       (tramp-handle-make-process): Replace ?a by "-t" if indicated.
+
+2023-09-24  Eli Zaretskii  <eliz@gnu.org>
+
+       Support regeneration of ja-dic.el under '--with-small-ja-dic'
+
+       * lisp/international/ja-dic-cnv.el (skkdic-convert): Record the
+       value of SMALL_JA_DIC option used to produce ja-dic.el.
+       * leim/Makefile.in (small-ja-dic-option): New target, triggers
+       regeneration of ja-dic.el when the value of SMALL_JA_DIC option
+       changes by the configure script.  Suggested by Ulrich Müller
+       <ulm@gentoo.org>.
+       (${leimdir}/ja-dic/ja-dic.el): Depend on 'small-ja-dic-option'.
+       (Bug#66125)
+
+       * make-dist (possibly_non_vc_files):
+       * .gitignore: Add 'leim/small-ja-dic-option'.
+
+2023-09-22  Basil L. Contovounesios  <contovob@tcd.ie>
+
+       Improve remote-file-name-inhibit-cache :type
+
+       * lisp/files.el (remote-file-name-inhibit-cache)
+       (shell-highlight-undef-remote-file-name-inhibit-cache): Avoid
+       duplicated :tag string.  Try to clarify wording and
+       formatting (bug#66150).
+       * lisp/shell.el (shell--highlight-undef-exec-cache): Reference
+       correct user option in docstring.
+
+2023-09-22  Stefan Kangas  <stefankangas@gmail.com>
+
+       Ensure bind-key is its own package
+
+       * lisp/finder.el (finder--builtins-alist): Remove "use-package"
+       directory.
+       * lisp/use-package/bind-key.el: Declare library as part of the
+       'bind-key' package.
+       * lisp/use-package/use-package-bind-key.el:
+       * lisp/use-package/use-package-core.el:
+       * lisp/use-package/use-package-delight.el:
+       * lisp/use-package/use-package-diminish.el:
+       * lisp/use-package/use-package-ensure-system-package.el:
+       * lisp/use-package/use-package-ensure.el:
+       * lisp/use-package/use-package-jump.el:
+       * lisp/use-package/use-package-lint.el: Declare library as part of the
+       'use-package' package.  (Bug#62751)
+
+       Do not merge to master.
+
+2023-09-21  Michael Albinus  <michael.albinus@gmx.de>
+
+       * lisp/net/tramp.el (tramp-skeleton-write-region): Fix missing comma.
+
+       (Bug#66123)
+
+2023-09-18  Yuan Fu  <casouri@gmail.com>
+
+       Fix tree-sitter range update function
+
+       * lisp/treesit.el (treesit-update-ranges): If an embedded language
+       doesn't have any range, don't set its range to nil (which means whole
+       buffer), instead, set its range to a dummy (1 . 1) zero range.
+
+2023-09-18  Ihor Radchenko  <yantar92@posteo.net>
+
+       Announce handling 'org-protocol' URI scheme in NEWS
+
+       * etc/NEWS: Document handling 'org-protocol' URI scheme.  The commit
+       implementing the new functionality is 05a7c91b91c.  (Bug#65469)
+
+2023-09-18  Ihor Radchenko  <yantar92@posteo.net>
+
+       Make emacsclient handle org-protocol:// links
+
+       Org mode provides a way to quickly capture bookmarks, notes, and links
+       using emacsclient:
+
+           emacsclient "org-protocol://store-link?url=URL&title=TITLE"
+
+       * etc/emacsclient.desktop: Make Emacs the default application for
+       org-protocol.  (Bug#65469)
+
+       (cherry picked from commit 05a7c91b91c02c34ec6527119a465e5408dea2b1)
+
+2023-09-18  Robert Pluim  <rpluim@gmail.com>
+
+       Ensure ucs-names is consistent with Unicode names
+
+       * lisp/international/mule-cmds.el (ucs-names): Skip adding an old-name
+       if it conflicts with the offical name of a codepoint.  Adjust the
+       ranges iterated over to account for new Unicode codepoints.
+       * test/lisp/international/mule-tests.el
+       (mule-cmds-tests--ucs-names-old-name-override,
+       mule-cmds-tests--ucs-names-missing-names): New tests for checking
+       'ucs-names' consistency.
+
+       Bug#65997
+
+2023-09-18  Shynur  <one.last.kiss@outlook.com>
+
+       Make key-translate actually work
+
+       * lisp/keymap.el (key-translate): Use the first element of the parsed
+       keys rather than the whole vector.  (Bug#65735)
+
+2023-09-17  Kyle Meyer  <kyle@kyleam.com>
+
+       Update to Org 9.6.9
+
+2023-09-17  Stefan Kangas  <stefankangas@gmail.com>
+
+       Add leim subdirectories to emacs package
+
+       * lisp/finder.el (finder--builtins-alist): Add subdirectories
+       'leim/ja-dic' and 'leim/quail' as part of the 'emacs'
+       package.  (Bug#62751)
+
+2023-09-17  Stefan Kangas  <stefankangas@gmail.com>
+
+       Add missing builtin package declarations
+
+       * lisp/finder.el (finder--builtins-alist): Add new package
+       directories 'leim' and 'obsolete' as part of the 'emacs' package.
+       Add new package directory 'use-package' as part of the
+       'use-package' package.
+       * lisp/net/eudc-capf.el:
+       * lisp/net/eudcb-ecomplete.el:
+       * lisp/net/eudcb-macos-contacts.el:
+       * lisp/net/eudcb-mailabbrev.el: Declare library as part of the
+       'eudc' package.
+       * lisp/mail/ietf-drums-date.el: Declare library as part of the
+       'ietf-drums' package.
+       * lisp/image/image-dired-dired.el:
+       * lisp/image/image-dired-external.el:
+       * lisp/image/image-dired-tags.el:
+       * lisp/image/image-dired-util.el: Declare library as part of the
+       'image-dired' package.
+       * lisp/emacs-lisp/oclosure.el:
+       * lisp/keymap.el:
+       * lisp/progmodes/c-ts-common.el: Declare library as part of the
+       'emacs' package.  (Bug#62751)
+
+       (cherry picked from commit 94b1de2774b5c1fa3c28285229900657638f5c3f)
+
+2023-09-17  Stefan Kangas  <stefankangas@gmail.com>
+
+       Add more missing builtin package declarations
+
+       * lisp/emacs-lisp/shorthands.el: Declare library as part of the
+       'emacs' package.
+       * lisp/epa-ks.el: Declare library as part of the 'epa'
+       package.  (Bug#55388)
+
+2023-09-17  Stefan Kangas  <stefankangas@gmail.com>
+
+       Document shell-command-to-string security considerations
+
+       * lisp/simple.el (shell-command-to-string): Document security
+       considerations in docstring.
+
+2023-09-17  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix shell-indirect-setup-hook :type (Bug#66051)
+
+       * lisp/shell.el (shell-indirect-setup-hook): It's a hook, not a
+       boolean.
+
+2023-09-17  Thomas Hilke  <t.hilke@rollomatic.ch>  (tiny change)
+
+       Remove column quoting from sqlite-mode
+
+       * lisp/sqlite-mode.el (sqlite-mode--column-names): Unquote column
+       name.  (Bug#65998)
+
+2023-09-17  Theodor Thornhill  <theo@thornhill.no>
+
+       Add indentation rules for type_arguments
+
+       * lisp/progmodes/java-ts-mode.el (java-ts-mode--indent-rules): Indent
+       as opening braces.
+
+2023-09-16  Dmitry Gutov  <dmitry@gutov.dev>
+
+       typescript-ts-mode.el: Minor touches
+
+       * lisp/progmodes/typescript-ts-mode.el
+       (tsx-ts-mode--indent-compatibility-b893426)
+       (tsx-ts-mode--font-lock-compatibility-bb1f97b):
+       Catch specific error.
+       (typescript-ts-base-mode): Improve docstring (bug#65470).
+
+2023-09-16  Dmitry Gutov  <dmitry@gutov.dev>
+
+       Improve namespacing situation WRT to recent change in 
typescript-ts-mode.el
+
+       * lisp/progmodes/typescript-ts-mode.el
+       (typescript-ts--syntax-propertize):
+       Rename from ts-ts--syntax-propertize.
+       (tsx-ts--syntax-propertize-captures):
+       Rename from ts-ts--syntax-propertize-captures.
+       (typescript-ts--s-p-query):
+       Rename from ts-ts--s-p-query.
+       Update all references (bug#65470).
+
+2023-09-16  Stephen Berman  <stephen.berman@gmx.net>
+
+       Make move-end-of-line in minibuffer consistent (bug#65980)
+
+       * lisp/simple.el (move-end-of-line): Always move to eol when
+       invoking `C-e' from within the minibuffer's prompt string.
+
+2023-09-16  Jens Schmidt  <jschmidt4gnu@vodafonemail.de>
+
+       Fix loss of encrypted data in plstore.el
+
+       * lisp/plstore.el (plstore--insert-buffer): Fix loss of encrypted
+       data when a plstore gets opened and saved without being decrypted
+       between these steps.  (Bug#63627)
+
+2023-09-16  Thomas Hilke  <t.hilke@rollomatic.ch>  (tiny change)
+
+       Close SQL database when corresponding 'sqlite-mode' buffer is killed
+
+       * lisp/sqlite-mode.el (sqlite-mode-open-file): Close DB when the
+       buffer is killed.  (Bug#65998)
+
+2023-09-16  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix Unicode normalization of characters
+
+       * lisp/international/ucs-normalize.el
+       (ucs-normalize-composition-exclusions, check-range): Update from
+       Unicode 15.0 data.  (Bug#65996)
+
+       * test/lisp/international/ucs-normalize-tests.el
+       (ucs-normalize-tests--failing-lines-part1)
+       (ucs-normalize-tests--failing-lines-part2): Update to reflect
+       changes in ucs-normalize.el.
+
+       * admin/notes/unicode: Mention the updates in ucs-normalize.el.
+
+2023-09-16  Michael Albinus  <michael.albinus@gmx.de>
+
+       Support one-time passwords in Tramp
+
+       * doc/misc/tramp.texi (Remote shell setup):
+       Describe tramp-otp-password-prompt-regexp.
+
+       * lisp/net/tramp-sh.el (tramp-actions-before-shell)
+       (tramp-actions-copy-out-of-band):
+       Use `tramp-otp-password-prompt-regexp'.
+
+       * lisp/net/tramp.el (tramp-otp-password-prompt-regexp): New defcustom.
+       (tramp-action-otp-password): New defun.
+
+2023-09-16  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix the 'C' and 'c' categories of characters
+
+       * lisp/international/characters.el: Fix categories of Chinese
+       characters.  (Bug65995)
+
+2023-09-16  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix Emoji zooming commands
+
+       * lisp/international/emoji.el (emoji-zoom-increase): Handle the
+       case where face property at point is a list of faces.  (Bug#65994)
+
+2023-09-15  Dmitry Gutov  <dmitry@gutov.dev>
+
+       tsx-ts-mode--font-lock-compatibility-bb1f97b: Improve
+
+       * lisp/progmodes/typescript-ts-mode.el
+       (tsx-ts-mode--font-lock-compatibility-bb1f97b):
+       Test the more complex query, because the current one leads to
+       false positives (mentioned in bug#65470).
+
+2023-09-15  Davide Masserut  <dm@mssdvd.com>
+
+       Avoid using --display in emacsclient to reuse frames on PGTK
+
+       Using hard-coded display values can cause PGTK graphical frames to
+       open using the wrong backend or not open at all.
+       * Makefile.in (install-etc): Use --reuse-frame instead of
+       --display=$DISPLAY.  (Bug#65509)
+
+2023-09-15  Eli Zaretskii  <eliz@gnu.org>
+
+       Support emacsclient on Windows with server on GNU or Unix systems
+
+       * lisp/server.el (server-process-filter): If 'tty-name' is literally
+       "CONOUT$", assume the client runs on MS-Windows and force the
+       frame type to GUI.  This allows to run emacsclient on MS-Windows
+       when the server runs on a Posix host.  (Bug#65812)
+
+2023-09-14  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix defcustom in saveplace.el (Bug#65977)
+
+       * lisp/saveplace.el (save-place-ignore-files-regexp): Allow nil.
+
+2023-09-14  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix 'window-text-pixel-size' when there are several images at START
+
+       * src/xdisp.c (window_text_pixel_size): Remove unnecessary call to
+       'move_it_to'.  (Bug#65899)  (Bug#54862)
+
+2023-09-14  Eli Zaretskii  <eliz@gnu.org>
+
+       : Doc fix.
+
+       * lisp/progmodes/prog-mode.el
+       (prettify-symbols-unprettify-at-point): Doc fix.
+
+2023-09-14  Stefan Kangas  <stefankangas@gmail.com>
+
+       Doc fix for prettify-symbols-unprettify-at-point
+
+       * lisp/progmodes/prog-mode.el
+       (prettify-symbols-unprettify-at-point): Document that it has to be
+       set before enabling 'prettify-symbols-mode'.  (Bug#65884)
+
+2023-09-13  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       (report_overlay_modification): Fix bug#65929
+
+       Somehow the new overlay code in Emacs-29 changed slightly
+       the test to decide when to run the `modification-hooks` of overlays,
+       with the consequence that these hook functions end up being executed
+       also when text is deleted right after an empty overlay, which is
+       contrary to Emacs-28 behavior as well as contrary to the Texinfo doc.
+
+       * src/buffer.c (report_overlay_modification): Better reproduce the
+       Emacs-28 code.
+
+       * test/src/buffer-tests.el (overlay-modification-hooks):
+       Add corresponding test.
+
+2023-09-13  Alan Third  <alan@idiocy.org>
+
+       Fix SVG colors (bug#56182)
+
+       * src/image.c (svg_load_image): Reverse the R and B bytes in the
+       Windows colors before using them to generate the SVG.
+
+2023-09-13  Juri Linkov  <juri@linkov.net>
+
+       * doc/emacs/text.texi (Outline Minor Mode): Add a note about value 
'insert'.
+
+       * lisp/outline.el (outline-minor-mode-use-buttons): Add a note and
+       a comment about the value 'insert' (bug#65874).
+
+2023-09-13  Eli Zaretskii  <eliz@gnu.org>
+
+       Improve documentation of 'list-abbrevs'
+
+       * doc/emacs/abbrevs.texi (Editing Abbrevs): Describe how system
+       abbrevs are shown by 'list-abbrevs'.  Suggested by Shynur Xie
+       <one.last.kiss@outlook.com>.  (Bug#65907)
+
+2023-09-12  Dmitry Gutov  <dmitry@gutov.dev>
+
+       Tweak s-p-f for js-ts-mode
+
+       * lisp/progmodes/js.el (js-ts--s-p-query):
+       Consider two more contexts (bug#65470).
+
+2023-09-12  Jostein Kjønigsen  <jostein@kjonigsen.net>
+
+       typescript-ts-mode, tsx-ts-mode: Fix syntax properties for regexp and 
jsx
+
+       Propertize regexps as strings and JSX elements as generic strings.
+
+       * lisp/progmodes/typescript-ts-mode.el (ts-ts--s-p-query)
+       (tsx-ts--s-p-query): New variables.
+       (ts-ts--syntax-propertize, tsx-ts--syntax-propertize)
+       (ts-ts--syntax-propertize-captures): New functions.
+       (typescript-ts-mode, tsx-ts-mode): Use them (bug#65470).
+
+2023-09-12  Eli Zaretskii  <eliz@gnu.org>
+
+       * lisp/progmodes/c-ts-mode.el (c++-ts-mode): Provide (bug#65895).
+
+2023-09-11  Yuan Fu  <casouri@gmail.com>
+
+       Fix regression of treesit_cursor_helper_1
+
+       * src/treesit.c (treesit_cursor_helper_1)
+       (treesit_cursor_first_child_for_byte): Use
+       ts_tree_cursor_goto_first_child_for_byte first, and
+       ts_tree_cursor_goto_first_child second.
+
+2023-09-10  Stefan Kangas  <stefankangas@gmail.com>
+
+       Update docs for passing of Thien-Thi Nguyen
+
+       * doc/emacs/ack.texi (Acknowledgments): Add Thien-Thi Nguyen.
+       * lisp/play/zone.el: Set maintainer to emacs-devel.
+
+2023-09-10  Stefan Kangas  <stefankangas@gmail.com>
+
+       Update defvar usage tips example in manual
+
+       * doc/lispref/variables.texi (Tips for Defining): Change example
+       to be about syntax tables instead of old way of defining keymaps
+       using 'defvar' and 'make-sparse-keymap'.  (Bug#59224)
+
+2023-09-10  Stefan Kangas  <stefankangas@gmail.com>
+
+       Document using Flymake together with Eglot
+
+       * doc/misc/flymake.texi (Top, Using Flymake): Document using
+       Flymake together with Eglot.  (Bug#60040)
+
+2023-09-08  Mauro Aranda  <maurooaranda@gmail.com>
+
+       Fix defcustom :type of ielm-indirect-setup-hook
+
+       * lisp/ielm.el (ielm-indirect-setup-hook): Fix :type and remove :safe
+       property, since it was probably a copy-pasta.  (Bug#65821)
+
+2023-09-08  Stefan Kangas  <stefankangas@gmail.com>
+
+       Document NonGNU ELPA in FAQ
+
+       * doc/misc/efaq.texi (Packages that do not come with Emacs):
+       Document NonGNU ELPA.  (Bug#65818)
+
+2023-09-07  Jim Porter  <jporterbugs@gmail.com>
+
+       Fix remote path setting in Eshell
+
+       This ensures that we supply Tramp with the local PATH so that it can
+       do its job of starting the local "ssh", or whatever the method uses
+       (bug#65551).
+
+       * lisp/eshell/esh-proc.el (eshell-gather-process-output): Add special
+       handling for remote processes.
+
+       * test/lisp/eshell/esh-proc-tests.el
+       (esh-var-test/remote/remote-path): New test.
+
+2023-09-07  Stefan Kangas  <stefankangas@gmail.com>
+
+       Update docs for (co-)maintainer changes
+
+       * admin/MAINTAINERS: Add information on current maintainers as a
+       canonical place to find this information.
+       * doc/emacs/ack.texi (Acknowledgments): Update for recent
+       Emacs (co-)maintainer changes.
+       * admin/make-tarball.txt: Add note as a reminder to update the above
+       before making a new release.
+
+2023-09-07  Sebastian Miele  <iota@whxvd.name>
+
+       * doc/lispref/strings.texi (Text Comparison): Fix typo (bug#65799).
+
+2023-09-07  Michael Albinus  <michael.albinus@gmx.de>
+
+       Adapt Tramp manual
+
+       * doc/misc/tramp.texi (Frequently Asked Questions): Do not use
+       `defadvice'.  Add indices.  (Bug#65481)
+
+2023-09-07  Stefan Kangas  <stefankangas@gmail.com>
+
+       Improve docstring of message-sendmail-envelope-from
+
+       * lisp/gnus/message.el (message-sendmail-envelope-from): Doc fix.
+
+2023-09-07  Philipp Stephani  <phst@google.com>
+
+       Unbreak builds with CHECK_STRUCTS.
+
+       * src/pdumper.c (dump_buffer): Fix hash for 'struct buffer'.  The
+       recent changes to that structure where commits
+       8f3091defb3ec4396ccea563f67c005044b822ca and
+       0bd46619413e83fe3c85c8a1dfbf5e20dfce8605, both of which just affected
+       comments.
+
+2023-09-07  Jens Schmidt  <jschmidt4gnu@vodafonemail.de>
+
+       Improve documentation of EPG
+
+       * lisp/epg.el (epg-context-set-passphrase-callback): Update
+       GnuPG-version-dependent information in docstring and refer to
+       Info node `(epa)' for details.
+       (epg-start-edit-key): Replace description of arguments by a
+       reference to `epg-edit-key'.
+       (epg-edit-key): More precisely describe callback operation and
+       arguments and provide an example of how to edit a key.  (Bug#65603)
+
+2023-09-07  Daniel Martín  <mardani29@yahoo.es>
+
+       Avoid crashes on macOS with context menus
+
+       * src/nsmenu.m ([EmacsMenu menuNeedsUpdate:]): Avoid crashes with
+       context menus.  (Bug#63495)
+
+2023-09-07  Yuan Fu  <casouri@gmail.com>
+
+       Fix c-ts-mode BSD style indentation
+
+       * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles):
+       Add else_clause.
+
+       (cherry picked from commit d392a5d3c11b7e7479d31421f8237f29952c909e)
+
+2023-09-06  David Ponce  <da_vid@orange.fr>
+
+       Fix regexp for recognizing PBM images
+
+       * lisp/image.el (image-type-header-regexps): Don't use [:space:],
+       as its meaning depends on the current buffer's syntax tables.
+       (Bug#65496)
+
+2023-09-06  Eli Zaretskii  <eliz@gnu.org>
+
+       Improve wording in ELisp manual
+
+       * doc/lispref/objects.texi (Printed Representation): Improve
+       wording.  Suggested by Xie Shynur <one.last.kiss@outlook.com>.
+       (Bug# 60639)
+
+2023-09-06  Joseph Turner  <joseph@breatheoutbreathe.in>
+
+       Fix typo (Bug#65764)
+
+       * lisp/subr.el (backward-word-strictly): Fix typo.
+
+2023-09-05  Po Lu  <luangruo@yahoo.com>
+
+       Fix libgccjit build on Haiku
+
+       * configure.ac (LIBGCCJIT_LIBS): Link only with -lgccjit under
+       Haiku.
+
+2023-09-05  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       (regexp-tests-backtrack-optimization): Mark it as failing
+
+       * test/src/regex-emacs-tests.el (regexp-tests-backtrack-optimization):
+       The fix for bug#65726 broke some of the optimization added for 
bug#61514.
+
+2023-09-04  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * src/regex-emacs.c (mutually_exclusive_p): Fix inf-loop (bug#65726)
+
+2023-09-04  Stefan Kangas  <stefankangas@gmail.com>
+
+       Bump seq version to 2.24
+
+       * lisp/emacs-lisp/seq.el: Bump version to 2.24.  (Bug#60990)
+
+2023-09-04  Stefan Kangas  <stefankangas@gmail.com>
+
+       Add note on ELPA to admin/notes/bug-triage
+
+       * admin/notes/bug-triage: Add section on (Non-)GNU ELPA packages and
+       do some copy editing.
+
+2023-09-02  Po Lu  <luangruo@yahoo.com>
+
+       * etc/PROBLEMS: Mention bug#65432 and its remedy.
+
+2023-09-02  Theodor Thornhill  <theo@thornhill.no>
+
+       Ignore errors when checking for object initializers (bug#63379)
+
+       Since this is merely a check for syntax, we don't really care about
+       any internal errors inside of backward-up-list.
+
+       * lisp/progmodes/csharp-mode.el (csharp-guess-basic-syntax): Wrap
+       command in ignore-errors.
+
+2023-09-02  Stefan Kangas  <stefankangas@gmail.com>
+
+       * CONTRIBUTE: Document making ChangeLogs with Magit.
+
+2023-09-02  Stefan Kangas  <stefankangas@gmail.com>
+
+       Doc fixes for obsolete functions and variables
+
+       * admin/notes/multi-tty:
+       * doc/emacs/building.texi (Debugger Operation):
+       * doc/misc/efaq-w32.texi (Line ends by file system):
+       * doc/misc/gnus.texi (Hashcash):
+       * lisp/emacs-lisp/eieio.el (eieio-class-parents)
+       (eieio-class-children):
+       * lisp/progmodes/perl-mode.el:
+       * lisp/textmodes/ispell.el (ispell-lookup-words):
+       * src/buffer.h: Update or delete references to variables and functions
+       made obsolete in Emacs 24.4.
+
+2023-09-02  Mauro Aranda  <maurooaranda@gmail.com>
+
+       A revision to the Widget manual
+
+       * doc/misc/widget.texi (Widgets Basics, Working with Widgets)
+       (Widgets and the Buffer, Widget Gallery, Customization): New chapters.
+       (Basic Types, Sexp Types): Demote to subsections.
+       (Widget Browser): Rename to Inspecting Widgets.
+       (Widget Properties): Remove.
+
+       (Top): Adapt menu to changes.
+       (Introduction): Rearrange text.  Move warnings to a better place, and
+       user options to the Customization chapter.
+       (User Interface): Don't fully describe commands and customization
+       options here.
+       (Setting Up the Buffer): Expand on widget creation process and add
+       documentation for useful functions which deal with
+       creation/conversion.
+       (Defining New Widgets): Expand the documentation on define-widget.
+       All relevant properties moved to the description of the default
+       widget, in Widget Gallery.
+       (Utilities): Add some more useful functions not previously documented.
+       (Wishlist): Remove out-of-date items.
+
+2023-09-02  Stefan Kangas  <stefankangas@gmail.com>
+
+       Fix fontification of " in edit-kbd-macro
+
+       * lisp/edmacro.el (edit-kbd-macro): Fix fontification when editing
+       keyboard macros containing the " character.
+
+2023-09-02  Eli Zaretskii  <eliz@gnu.org>
+
+       * lisp/emacs-lisp/gv.el (buffer-local-value): Unobsolete (bug#65555).
+
+2023-09-02  Jens Schmidt  <jschmidt4gnu@vodafonemail.de>
+
+       Add documentation to plstore.el
+
+       * lisp/plstore.el: Add link to epa manual.  Describe more
+       restrictions.  Fix a typo in the examples.  Fix terminology.  Mark
+       FIXMEs as such.
+       * lisp/plstore.el (plstore-save): Describe edge case when no recipient
+       matches and mark as FIXME.  (Bug#63627)
+
+2023-09-01  Stefan Kangas  <stefankangas@gmail.com>
+
+       * lisp/help.el (substitute-quotes): Improve docstring.
+
+2023-09-01  Stefan Kangas  <stefankangas@gmail.com>
+
+       Fix two defcustom :types
+
+       * lisp/frame.el (blink-cursor-blinks):
+       * lisp/url/url-vars.el (url-max-redirections): Revert defcustom :types
+       back to integer.  (Bug#65655)
+
+2023-09-01  Manuel Giraud  <manuel@ledu-giraud.fr>
+
+       Fix `image-auto-resize-on-window-resize' custom :type
+
+       * lisp/image-mode.el (image-auto-resize-on-window-resize): Change
+       custom :type from integer to number to be able to set below 1
+       second.  (Bug#65626)
+
+2023-09-01  Ross Timson  <me@rosstimson.com>  (tiny change)
+
+       Add "terraform-ls" LSP server to Eglot
+
+       * lisp/progmodes/eglot.el (eglot-server-programs): Add "terraform-ls",
+       the official Terraform LSP server.  (Bug#65671)
+
+2023-09-01  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix minor bugs in vc-git and vc-hg on Windows uncovered by vc-tests
+
+       * lisp/vc/vc-hg.el (vc-hg-state-slow): Non-existing files emit a
+       different message on MS-Windows; support that.
+       * lisp/vc/vc-git.el (vc-git-checkin): Make sure
+       'default-directory' is not nil when calling
+       'make-nearby-temp-file' on MS-Windows.
+
+       * test/lisp/vc/vc-tests.el (vc-test--version-diff): Run
+       'default-directory' through 'file-truename', otherwise the
+       'vc-test-cvs06-version-diff' test might fail on MS-Windows.
+
+2023-08-31  Dmitry Gutov  <dmitry@gutov.dev>
+
+       Add syntax-propertize-function to js-ts-mode
+
+       * lisp/progmodes/js.el (js-ts--s-p-query):
+       New variable (bug#65470).
+       (js-ts--syntax-propertize): New function.
+       (js-ts-mode): Use it.
+
+2023-08-30  Yuan Fu  <casouri@gmail.com>
+
+       Improve performance of treesit_cursor_helper_1
+
+       * src/treesit.c: (treesit_cursor_helper_1): Use
+       ts_tree_cursor_goto_first_child_for_byte to speed up traversing among
+       siblings.  The "while (ts_node_end_byte (cursor_node) < end_pos)" can
+       be removed with the check added in the loop below.
+
+2023-08-28  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * lisp/subr.el (combine-change-calls-1): Fix bug#64989
+
+       Silence the spurious warning, and improve the warning while at it.
+       Do not merge to master.
+
+2023-08-27  Kyle Meyer  <kyle@kyleam.com>
+
+       Update to Org 9.6.8-3-g21171d
+
+2023-08-27  Yuan Fu  <casouri@gmail.com>
+
+       Escape percent character in treesit--inspect-name (bug#65540)
+
+       * lisp/treesit.el (treesit-inspect-node-at-point): Escape percent.
+
+2023-08-27  Jim Porter  <jporterbugs@gmail.com>
+
+       Don't add an extraneous slash in remote PATH list in Eshell
+
+       Previously, in a remote directory, '(eshell-get-path)' would return a
+       list of strings like "/ssh:localhost://usr/bin".  While that shouldn't
+       break most things, it's not strictly correct either.  See bug#65551.
+
+       * lisp/eshell/esh-util.el (eshell-get-path): Use 'concat' instead of
+       'file-name-concat'.
+
+       * test/lisp/eshell/esh-util-tests.el: Require 'tramp' and
+       'eshell-tests-helpers'.
+       (esh-util-test/path/get, eshell-util-test/path/get-remote): New tests.
+
+2023-08-27  Michael Albinus  <michael.albinus@gmx.de>
+
+       Fix Tramp on MS Windows
+
+       * lisp/net/tramp-sh.el (tramp-sh-handle-expand-file-name):
+       Apply `tramp-drop-volume-letter' consequently.
+
+2023-08-27  Andrea Corallo  <acorallo@gnu.org>
+
+       * Fix native disassemble on Windows platforms (bug#65455)
+
+       * lisp/emacs-lisp/disass.el (disassemble-internal): Improve regexp.
+
+2023-08-27  Andrea Corallo  <acorallo@gnu.org>
+
+       * Handle missing eln file when trying to disassble (bug#65455)
+
+       * lisp/emacs-lisp/disass.el (disassemble-internal): Handle missing
+       eln file.
+
+2023-08-27  Andrea Corallo  <acorallo@gnu.org>
+
+       * lisp/emacs-lisp/comp.el (comp--native-compile): Fix OUTPUT for non 
abs paths
+
+2023-08-27  Jonas Bernoulli  <jonas@bernoul.li>
+
+       Update to Transient v0.4.3
+
+2023-08-27  Michael Albinus  <michael.albinus@gmx.de>
+
+       Adapt Eshell manual
+
+       * doc/misc/eshell.texi (Arguments): Mention more special
+       characters to be quoted in remote file names.  (Bug#65431)
+
+2023-08-27  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix applying patches with Git on MS-Windows
+
+       * lisp/vc/vc.el (vc-diff-internal): For Git, always suppress EOL
+       conversion when reading the diffs into a buffer.  Doc fix.
+       * lisp/vc/vc-git.el (vc-git-checkin): Make sure to suppress EOL
+       conversion when the patch file is written.  (Bug#65049)
+
+2023-08-26  Po Lu  <luangruo@yahoo.com>
+
+       Repair bug#65068 on Emacs 29
+
+       * src/xterm.c (x_term_init): Disable ControlFallback library
+       control wherever present.  (bug#65068)
+
+       Do not merge to master.
+
+2023-08-24  Stefan Kangas  <stefankangas@gmail.com>
+
+       Fix custom :type of dired-mouse-drag-files
+
+       * lisp/dired.el (dired-mouse-drag-files): Fix :type to allow
+       specifying 'move'.  (Bug#65497)
+
+2023-08-24  James Thomas  <jimjoe@gmx.net>
+
+       Account for string names in active file
+
+       Account also for strings when reading in group names from an active
+       file (bug#62812).
+       * lisp/gnus/nnmail.el (nnmail-parse-active): Make it similar to
+       gnus-active-to-gnus-format
+
+2023-08-24  Christoph Göttschkes  <just.mychris@googlemail.com>  (tiny change)
+
+       Fix 'makefile-browser-client' variable initialization
+
+       * lisp/progmodes/make-mode.el (makefile-browser-client):
+       Initialize to nil.  (Bug#65487)
+
+2023-08-19  Yuan Fu  <casouri@gmail.com>
+
+       Support defun navigation for DEFUN in c-ts-mode (bug#64442)
+
+       Before this change, beginning/end-of-defun just ignores DEFUN in
+       c-ts-mode. After this change, beginning/end-of-defun can recognize
+       DEFUN, but a DEFUN definition is considered two defuns. Eg,
+       beginning/end-of-defun will stop at (1) (2) and (3) in the following
+       snippet:
+
+       (1)DEFUN ("treesit-node-parser",
+              Ftreesit_node_parser, Streesit_node_parser,
+              1, 1, 0,
+              doc: /* Return the parser to which NODE belongs.  */)
+         (Lisp_Object node)
+       (2){
+         CHECK_TS_NODE (node);
+         return XTS_NODE (node)->parser;
+       }
+       (3)
+
+       Ideally we want point to only stop at (1) and (3), but that'll be a
+       lot harder to do.
+
+       * lisp/progmodes/c-ts-mode.el:
+       (c-ts-mode--defun-valid-p): Refactor to take in account of DEFUN body.
+       (c-ts-mode--emacs-defun-body-p): New function.
+       (c-ts-base-mode): Add DEFUN and DEFUN body to recognized types.
+       (c-ts-mode--emacs-defun-at-point): Now that we recognize both parts of
+       a DEFUN as defun, c-ts-mode--emacs-defun-at-point needs to be updated
+       to adapt to it.
+
+2023-08-19  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix touchpad scrolling on MS-Windows
+
+       * src/w32term.c (w32_construct_mouse_wheel): The number of lines
+       to scroll should always be positive in wheel-scroll events.
+       Whether to scroll up or down is encoded in the modifiers, which
+       produce either wheel-up or wheel-down event.  (Bug#65070)
+
+       * doc/lispref/commands.texi (Misc Events): Clarify the
+       documentation of 'wheel-up' and 'wheel-down' events.
+
+2023-08-19  Philip Kaludercic  <philipk@posteo.net>
+
+       Fix order in which package-vc dependencies are resolved
+
+       * lisp/emacs-lisp/package-vc.el (package-vc-install-dependencies):
+       Avoid a type-mismatch when comparing two packages.  (Bug#65283)
+
+2023-08-19  Joseph Turner  <joseph@breatheoutbreathe.in>
+
+       Fix building of VC package manuals with relative org links/includes
+
+       * lisp/emacs-lisp/package-vc.el (package-vc--build-documentation):
+       Ensure that default-default is the docs-directory around
+       org-export-to-file to ensure that links to relative files work
+       correctly.  (Bug#65243)
+
+2023-08-19  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix the documentation of 'cl-flet'
+
+       * doc/misc/cl.texi (Function Bindings): Update the description.
+       (Bug#65362)
+
+2023-08-17  Jens Schmidt  <jschmidt4gnu@vodafonemail.de>
+
+       Avoid false "wrong passphrase" messages in EPA
+
+       * lisp/epa-file.el (epa--wrong-password-p): Use a stricter regexp
+       to match "wrong passphrase" errors generated by GnuPG.  (Bug#65316)
+
+2023-08-17  dannyfreeman  <danny@dfreeman.email>
+
+       Fix jsx font-lock in older tree-sitter-js grammars
+
+       * lisp/progmodes/js.el (js--treesit-font-lock-settings): Use
+       queries that are backwards compatible with
+       tree-sitter-javascript bb1f97b.
+       * lisp/progmodes/js.el
+       (-jsx--treesit-font-lock-compatibility-bb1f97b): Delete unused
+       function.  (Bug#65234)
+
+2023-08-17  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix cloning 'face-remapping-alist' for indirect buffers
+
+       * lisp/face-remap.el (face-remap--copy-face): Remove.
+       (face-attrs--make-indirect-safe): Use 'copy-tree'.  Suggested by
+       Stefan Monnier <monnier@iro.umontreal.ca>.
+
+2023-08-17  Eli Zaretskii  <eliz@gnu.org>
+
+       Improve documentation of case transfer in replacement commands
+
+       * doc/emacs/search.texi (Replacement and Lax Matches):
+       * src/search.c (Freplace_match):
+       * lisp/replace.el (query-replace, query-replace-regexp): Clarify
+       in the doc string and the manual how letter-case is transferred
+       from the replaced text to the replacement text.  (Bug#65347)
+
+2023-08-16  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix horizontal scrolling of images with C-f
+
+       * lisp/image-mode.el (image-forward-hscroll): Calculate the
+       window-width more accurately, as the number of full columns that
+       fits in the window's text-area.  (Bug#65187)
+
+2023-08-16  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix unpacking ZIP archives on MS-Windows
+
+       * lisp/arc-mode.el (archive-zip-summarize): Decode file names as
+       UTF-8 when bit 11 of flags is set, even on MS-Windows.
+       (Bug#65305)
+
+2023-08-16  Jim Porter  <jporterbugs@gmail.com>
+
+       Fix command example in Eshell manual
+
+       * doc/misc/eshell.texi (Introduction): Fix example (bug#65303).
+
+       Reported by Eric Gillespie <brickviking@gmail.com>.
+
+2023-08-14  Jim Porter  <jporterbugs@gmail.com>
+
+       Add user options mentioned in the Eshell manual to the variable index
+
+       * doc/misc/eshell.texi: Make variable index entries use "code" style,
+       and add indexing for any options already in the manual.
+
+2023-08-14  Andrea Corallo  <acorallo@gnu.org>
+
+       * Add missing alias to `native-comp-enable-subr-trampolines'.
+
+       * lisp/subr.el (native-comp-deferred-compilation): Alias to
+       native-comp-jit-compilation.
+
+2023-08-14  Andrea Corallo  <acorallo@gnu.org>
+
+       * Add missing alias to `native-comp-enable-subr-trampolines'.
+
+       * lisp/subr.el (comp-enable-subr-trampolines): Alias to
+       native-comp-enable-subr-trampolines.
+
+2023-08-13  Kyle Meyer  <kyle@kyleam.com>
+
+       Update to Org 9.6.7-13-g99cc96
+
+2023-08-13  Michael Albinus  <michael.albinus@gmx.de>
+
+       Handle last-coding-system-used in Tramp for all backends
+
+       * lisp/net/tramp.el (tramp-skeleton-write-region):
+       Handle `last-coding-system-used'.
+       (tramp-handle-write-region):
+       * lisp/net/tramp-adb.el (tramp-adb-handle-write-region):
+       * lisp/net/tramp-smb.el (tramp-smb-handle-write-region):
+       * lisp/net/tramp-sshfs.el (tramp-sshfs-handle-write-region):
+       Set `coding-system-used'.  (Bug#65022)
+
+       * lisp/net/tramp-sh.el (tramp-sh-handle-write-region):
+       Move `last-coding-system-used' handling to
+       `tramp-skeleton-write-region'.
+
+2023-08-13  Devon Sean McCullough  <emacs-hacker2017@jovi.net>
+
+       Add 2 Welsh characters to iso-transl.el
+
+       * lisp/international/iso-transl.el (iso-transl-char-map): Add two
+       Welsh characters.  (Bug#65248)
+
+2023-08-12  Andrea Corallo  <acorallo@gnu.org>
+
+       * Fix `batch-byte+native-compile' target directory.
+
+       * lisp/emacs-lisp/comp.el (batch-native-compile): Don't shadow
+       `native-compile-target-directory' unless necessary.
+
+2023-08-12  Eli Zaretskii  <eliz@gnu.org>
+
+       Avoid crashes in 'display_count_lines' when current buffer was killed
+
+       * src/xdisp.c (Fformat_mode_line):
+       * src/fns.c (Fline_number_at_pos): Don't allow to count lines in a
+       dead buffer.  (Bug#65060)
+
+2023-08-12  J M  <jean@tbm.email>
+
+       Update csharp tree-sitter support due to upstream changes
+
+       A change in tree-sitter-c-sharp grammar for csharp (commit
+       18a531), has removed the keyword void_keyword and advised
+       we should use predefined_type.
+       * lisp/progmodes/csharp-mode.el (csharp-ts-mode--font-lock-settings):
+       Support both old and new style of keywords in tree-sitter-c-sharp
+       grammar.  (Bug#65113)
+
+2023-08-12  Matthew Tromp  <matthewktromp@gmail.com>  (tiny change)
+
+       Substitute command keys in 'ielm-header' at use time
+
+       Before, command keys were substituted into the ielm-header when
+       ielm.el was loaded, which resulted in the substitutions depending on
+       the user's current buffer instead of the ielm buffer.
+       For example, if the user was in an info-mode buffer, the key would
+       appear as 'H' instead of 'C-h m'.
+       Now, the command key is substituted after the ielm buffer has been
+       created.
+       * lisp/ielm.el (ielm-header): Remove substitute-command-keys.
+       (inferior-emacs-lisp-mode): Add substitute-command-keys.  (Bug#65213)
+
+2023-08-12  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix rare crashes in redisplay due to problems with fontsets
+
+       * src/xdisp.c (get_next_display_element): If we have no usable
+       face to display a character/composition, treat that as glyphless.
+       (produce_glyphless_glyph): If neither it->face nor its ASCII face
+       are usable, fall back to the frame's default font.  (Bug#65198)
+
+2023-08-12  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix a typo in 'leuven-dark-theme.el'
+
+       * etc/themes/leuven-dark-theme.el (leuven-dark): Fix a typo.
+       Reported by John Poole <saxcos@posteo.es>.  (Bug#65239)
+
+2023-08-10  Michael Albinus  <michael.albinus@gmx.de>
+
+       Adapt Tramp test
+
+       * test/lisp/net/tramp-tests.el (tramp-test41-special-characters):
+       Skip for macOS.
+
+2023-08-10  dannyfreeman  <danny@dfreeman.email>
+
+       Properly expand the JSX indentation rules in 'js-ts-mode'
+
+       * lisp/progmodes/js.el (js--treesit-indent-rules): Fix
+       'js-ts-mode' indent bug in JSX expressions. Before this
+       change, treesit indent mechanisms were trying to call this
+       compatibility function like a matching or anchor rule.
+       This resulted in an error when running `indent-for-tab-command`
+       while the cursor was in a JSX expression:
+
+       treesit--simple-indent-eval: Wrong number of
+       arguments: ((cl-struct-js--pitem-tags ido-cur-list t) nil "Indent rules
+       helper, to handle different releases of tree-sitter-javascript."
+
+       (Bug#65134)
+
+2023-08-10  Andrea Corallo  <acorallo@gnu.org>
+
+       * Add `emacs-lisp-native-compile' to easy-menu.
+
+       * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-menu): Add menu
+       item for emacs-lisp-native-compile.
+
+2023-08-10  Andrea Corallo  <acorallo@gnu.org>
+
+       * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-menu): Simplify 
condition.
+
+2023-08-10  Andrea Corallo  <acorallo@gnu.org>
+
+       * Introduce `emacs-lisp-native-compile'.
+
+       * lisp/progmodes/elisp-mode.el (emacs-lisp-native-compile): New command.
+       (emacs-lisp-native-compile-and-load): Make use of.
+
+2023-08-10  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix the -x switch in non-X builds
+
+       * src/emacs.c (main): Move the handling of the -x switch out of
+       the HAVE_X_WINDOWS condition, and simplify the rest of the code by
+       avoiding code duplication in HAVE_X_WINDOWS and !HAVE_X_WINDOWS
+       cases.  (Bug#65048)
+
+2023-08-10  Po Lu  <luangruo@yahoo.com>
+
+       Document that `set-mouse-color' does not work everywhere
+
+       * etc/PROBLEMS (Miscellaneous Problems): Mention where
+       `set-mouse-color' does not work.
+
+2023-08-10  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix the effects and documentation of 'dired-free-space'
+
+       * lisp/dired.el (dired-free-space): Fix doc string and Custom tags.
+       (dired--insert-disk-space): When 'dired-free-space' is 'separate',
+       return the position of the beginning of the disk-space line, to be
+       compatible with pre-Emacs 29 behavior under
+       'dired-hide-details-mode'.  (Bug#65186)
+
+       * doc/emacs/dired.texi (Misc Dired Features): Fix wording in
+       documentation of 'dired-free-space'.
+
+2023-08-09  Stefan Kangas  <stefankangas@gmail.com>
+
+       Fix cross-reference to eldoc in eglot manual
+
+       * doc/misc/eglot.texi (Eglot Features): Fix cross-reference to eldoc
+       node in the Emacs manual.
+
+2023-08-09  Eli Zaretskii  <eliz@gnu.org>
+
+       Add native-compilation to Emacs Lisp mode menu
+
+       * lisp/progmodes/elisp-mode.el (emacs-lisp-mode-menu): Add menu
+       item for emacs-lisp-native-compile-and-load.
+
+2023-08-09  Andrea Corallo  <acorallo@gnu.org>
+
+       Fix emacs-lisp-native-compile-and-load eln target directory (bug#64226)
+
+       * lisp/emacs-lisp/comp.el (comp-spill-lap-function): Don't use
+       `byte+native-compile' to select output directory but always axpect
+       it explicit through `native-compile-target-directory'.
+       (batch-byte+native-compile): Set `native-compile-target-directory'.
+       * test/src/comp-tests.el (comp-tests-bootstrap): Set
+       `native-compile-target-directory'.
+
+2023-08-09  Mattias Engdegård  <mattiase@acm.org>
+
+       Disable failing test (bug#65156)
+
+       * test/src/fileio-tests.el (fileio-tests--non-regular-insert):
+       Mark as :unstable, since /dev/urandom is seekable.
+
+       Do not merge to master.
+
+2023-08-08  Po Lu  <luangruo@yahoo.com>
+
+       Better fix for bug#65156
+
+       * src/fileio.c (Finsert_file_contents): Correct seek-ability
+       test, since lseek returns -1 upon failure.  (Bug#65156)
+
+2023-08-08  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix insert-file-contents with pipes and /dev/stdin
+
+       * src/fileio.c (Finsert_file_contents): Restore logic of
+       non-regular but seekable files.  (Bug#65156)
+
+2023-08-07  Po Lu  <luangruo@yahoo.com>
+
+       Fix bug#65042
+
+       * src/pgtkterm.c (fill_background_by_face): Respect the frame's
+       background alpha property.
+
+2023-08-07  Eli Zaretskii  <eliz@gnu.org>
+
+       * configure.ac (HAVE_TREE_SITTER): Set NEED_DYNLIB=yes (bug#65123).
+
+2023-08-06  Michael Albinus  <michael.albinus@gmx.de>
+
+       * etc/NEWS: Mention tramp-show-ad-hoc-proxies.
+
+       * test/lisp/net/tramp-tests.el (tramp-test42-utf8): Skip for macOS.
+
+       * test/lisp/net/tramp-tests.el (tramp-test10-write-region): Extend test.
+
+2023-08-06  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix reverting Rmail buffers
+
+       This bug happened because rmail.el relied on 'revert-buffer' to
+       return non-nil when it succeeds to revert, but a recent change
+       in 'revert-buffer' broke that promise in Emacs 29.1.
+       * lisp/files.el (revert-buffer--default, revert-buffer): Doc fix.
+       (revert-buffer): Return whatever 'revert-buffer-function' returns.
+       (Bug#65071)
+
+2023-08-05  Jim Porter  <jporterbugs@gmail.com>
+
+       Fix handling of 'byte-compile-ignore-files' when nil
+
+       Before this fix, when 'byte-compile-ignore-files' was nil,
+       'byte-recompile-directory' would ignore every file (bug#64985).
+
+       * lisp/emacs-lisp/bytecomp.el (byte-recompile-directory): Handle case
+       when 'byte-compile-ignore-files' is nil.
+
+2023-08-05  Michael Albinus  <michael.albinus@gmx.de>
+
+       Sync with Tramp 2.6.2-pre
+
+       * doc/misc/tramp.texi (Overview): Use "scp" in example.
+       (Obtaining @value{tramp}): Prefer https: to git: URIs on Savannah.
+       (Ssh setup): Extend for MS Windows and ssh.  Explain
+       tramp-use-ssh-controlmaster-options value `suppress'.
+       (File name completion): Remove completion styles restrictions.
+       (Ad-hoc multi-hops): Describe tramp-show-ad-hoc-proxies.
+       (Remote processes): Add reference to "Using ssh connection sharing".
+
+       * doc/misc/trampver.texi:
+       * lisp/net/trampver.el (tramp-version): Set to "2.6.2-pre".
+
+       * lisp/net/tramp-adb.el (tramp-adb-handle-file-name-all-completions):
+       * lisp/net/tramp-archive.el
+       (tramp-archive-handle-file-name-all-completions):
+       * lisp/net/tramp-crypt.el 
(tramp-crypt-handle-file-name-all-completions):
+       * lisp/net/tramp-fuse.el (tramp-fuse-handle-file-name-all-completions):
+       * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-name-all-completions):
+       * lisp/net/tramp-sh.el (tramp-sh-handle-file-name-all-completions):
+       * lisp/net/tramp-smb.el (tramp-smb-handle-file-name-all-completions):
+       * lisp/net/tramp-sudoedit.el
+       (tramp-sudoedit-handle-file-name-all-completions): Return nil when
+       DIRECTORY is missing.  (Bug#61890)
+
+       * lisp/net/tramp.el (tramp-accept-process-output): Don't use TIMEOUT
+       anymore, default it to 0.  When the connection uses a shared
+       socket possibly, accept also the output from other processes over
+       the same connection.  (Bug#61350)
+       (tramp-handle-file-notify-rm-watch, tramp-action-process-alive)
+       (tramp-action-out-of-band, tramp-process-one-action)
+       (tramp-interrupt-process):
+       * lisp/net/tramp-adb.el (tramp-adb-handle-make-process):
+       * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-notify-add-watch):
+       * lisp/net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch):
+       * lisp/net/tramp-smb.el (tramp-smb-action-get-acl)
+       (tramp-smb-action-set-acl, tramp-smb-wait-for-output):
+       * lisp/net/tramp-sudoedit.el (tramp-sudoedit-action-sudo): Adapt 
callees.
+
+       * lisp/net/tramp.el (tramp-get-process, tramp-message)
+       (tramp-handle-make-process, tramp-handle-file-notify-valid-p)
+       (tramp-process-actions, tramp-accept-process-output)
+       (tramp-process-sentinel, tramp-read-passwd)
+       (tramp-interrupt-process, tramp-signal-process):
+       * lisp/net/tramp-adb.el (tramp-adb-maybe-open-connection):
+       * lisp/net/tramp-cmds.el (tramp-cleanup-connection):
+       * lisp/net/tramp-crypt.el (tramp-crypt-maybe-open-connection):
+       * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-notify-add-watch)
+       (tramp-gvfs-monitor-process-filter)
+       (tramp-gvfs-maybe-open-connection):
+       * lisp/net/tramp-rclone.el (tramp-rclone-maybe-open-connection):
+       * lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band)
+       (tramp-sh-handle-file-notify-add-watch)
+       (tramp-sh-gio-monitor-process-filter)
+       (tramp-sh-inotifywait-process-filter)
+       (tramp-barf-if-no-shell-prompt, tramp-maybe-open-connection):
+       * lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory)
+       (tramp-smb-handle-file-acl, tramp-smb-handle-set-file-acl)
+       (tramp-smb-maybe-open-connection):
+       * lisp/net/tramp-sshfs.el (tramp-sshfs-maybe-open-connection):
+       * lisp/net/tramp-sudoedit.el (tramp-sudoedit-maybe-open-connection)
+       (tramp-sudoedit-send-command): Prefix internal process properties
+       with "tramp-".
+
+       * lisp/net/tramp.el (tramp-skeleton-file-exists-p): New defmacro,
+       which also handles host name completion.
+       (tramp-handle-file-exists-p):
+       * lisp/net/tramp-adb.el (tramp-adb-handle-file-exists-p):
+       * lisp/net/tramp-sh.el (tramp-sh-handle-file-exists-p):
+       * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-file-exists-p): Use 
it.
+
+       * lisp/net/tramp.el (tramp-wrong-passwd-regexp):
+       * lisp/net/tramp-adb.el (tramp-adb-prompt):
+       * lisp/net/tramp-sh.el (tramp-sh-inotifywait-process-filter):
+       * lisp/net/tramp-smb.el (tramp-smb-maybe-open-connection): Unify 
regexps.
+
+       * lisp/net/tramp.el:
+       * lisp/net/tramp-cmds.el:
+       * lisp/net/tramp-crypt.el:
+       * lisp/net/tramp-gvfs.el:
+       * lisp/net/tramp-sh.el:
+       * lisp/net/tramp-smb.el: Fix error messages.
+
+       * lisp/net/tramp-cmds.el (tramp-cleanup-connection):
+       Protect `delete-process'.
+
+       * lisp/net/tramp.el (tramp-prefix-format, tramp-prefix-regexp)
+       (tramp-method-regexp, tramp-postfix-method-format)
+       (tramp-postfix-method-regexp, tramp-prefix-ipv6-format)
+       (tramp-prefix-ipv6-regexp, tramp-postfix-ipv6-format)
+       (tramp-postfix-ipv6-regexp, tramp-postfix-host-format)
+       (tramp-postfix-host-regexp, tramp-remote-file-name-spec-regexp)
+       (tramp-file-name-structure, tramp-file-name-regexp)
+       (tramp-completion-method-regexp)
+       (tramp-completion-file-name-regexp):
+       * lisp/net/tramp-compat.el (tramp-syntax):
+       * lisp/net/tramp-gvfs.el (tramp-gvfs-dbus-event-vector):
+       Rearrange declarations.
+
+       * lisp/net/tramp-compat.el (ansi-color): Require.
+       (ls-lisp): Don't require.  (Bug#64124)
+       (tramp-compat-replace-regexp-in-region): Move up.
+       (tramp-compat-length<, tramp-compat-length>)
+       (tramp-compat-length=): New defaliases.
+       (tramp-compat-file-name-unquote, tramp-compat-take)
+       (tramp-compat-ntake): Use them.
+
+       * lisp/net/tramp-container.el (tramp-container--completion-function):
+       Rename from `tramp-docker--completion-function'.  Add argument
+       PROGRAM.  Use it for "docker" and "podman" host name completion.
+
+       * lisp/net/tramp-crypt.el (tramp-crypt-handle-file-exists-p):
+       New defun.
+       (tramp-crypt-file-name-handler-alist): Add it.
+
+       * lisp/net/tramp-fuse.el (tramp-fuse-handle-file-exists-p): New defun.
+       (tramp-fuse-mount-timeout): Move up.
+       (tramp-fuse-mount-point): Use `tramp-fuse-mount-timeout'.
+       (tramp-fuse-unmount): Flush "mount-point" file property.
+       (tramp-fuse-mount-point, tramp-fuse-mounted-p): Support existing
+       mount points.
+       (tramp-fuse-mounted-p): The mount-spec could contain an optional
+       trailing slash.  (Bug#64278)
+
+       * lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file)
+       * lisp/net/tramp-rclone.el (tramp-rclone-do-copy-or-rename-file):
+       Improve stability for WebDAV.
+       (tramp-rclone-handle-file-system-info): Check return code of
+       command.
+
+       * lisp/net/tramp-gvfs.el (while-no-input-ignore-events):
+       Add `dbus-event' for older Emacs versions.
+       (tramp-gvfs-parse-device-names): Ignore errors.
+
+       * lisp/net/tramp-sh.el (tramp-display-escape-sequence-regexp)
+       (tramp-device-escape-sequence-regexp): Delete.
+       (tramp-sh-handle-insert-directory, tramp-barf-if-no-shell-prompt)
+       (tramp-wait-for-output): Use `ansi-color-control-seq-regexp'.
+       (tramp-use-ssh-controlmaster-options): Allow new value `suppress'.
+       (tramp-ssh-option-exists-p): New defun.
+       (tramp-ssh-controlmaster-options): Implement `suppress' actions.
+       Should never return nil, but empty string.
+       (tramp-perl-file-name-all-completions): Don't print status message.
+       (tramp-sh-handle-file-name-all-completions): Return nil when check
+       fails.  (Bug#61890)
+       (tramp-run-test): Add VEC argument.
+       (tramp-sh-handle-file-executable-p)
+       (tramp-sh-handle-file-readable-p)
+       (tramp-sh-handle-file-directory-p)
+       (tramp-sh-handle-file-writable-p): Adapt callees.
+       (tramp-sh-handle-insert-directory):
+       (tramp-sh-handle-insert-directory): Test whether -N is understood
+       by ls since that option is used along with --dired.  Remove -N
+       when we remove --dired.  (Bug#63142)
+       (tramp-sh-handle-insert-directory, tramp-barf-if-no-shell-prompt)
+       (tramp-wait-for-output): Use `ansi-color-control-seq-regexp'.
+       (tramp-sh-handle-expand-file-name): `null-device' could be nil.
+       Reported by Richard Copley <rcopley@gmail.com>.
+       (tramp-sh-handle-make-process): Improve handling of
+       connection-type `pipe'.  (Bug#61341)
+
+       * lisp/net/tramp-smb.el (tramp-smb-handle-make-symbolic-link):
+       * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-make-symbolic-link):
+       Flush TARGET file properties.
+
+       * lisp/net/tramp-smb.el (tramp-smb-handle-copy-file): Flush proper
+       file properties.
+       (tramp-smb-handle-file-acl, tramp-smb-handle-set-file-acl):
+       Remove superfluous `unwind-protect'.
+
+       * lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
+       Use `tramp-fuse-handle-file-exists-p'.
+       (tramp-sshfs-handle-insert-file-contents): Move result out of
+       unwindform.
+
+       * lisp/net/tramp.el (tramp-string-empty-or-nil-p): New defsubst.
+       Use it everywhere when appropriate.
+
+       * lisp/net/tramp.el (tramp-methods) <->: Add.
+       (tramp-completion-file-name-handler-alist):
+       Add `expand-file-name', `file-exists-p', `file-name-directory' and
+       `file-name-nondirectory'.
+       (tramp-dissect-file-name): Do not extra check for
+       `tramp-default-method-marker'.
+       (tramp-completion-handle-expand-file-name)
+       (tramp-completion-handle-file-exists-p)
+       (tramp-completion-handle-file-name-directory)
+       (tramp-completion-handle-file-name-nondirectory): New defuns.
+       (tramp-completion-handle-file-name-all-completions): Remove duplicates.
+       (tramp-show-ad-hoc-proxies): New defcustom.
+       (tramp-make-tramp-file-name): Use it.
+       (tramp-make-tramp-hop-name): Don't add hop twice.
+       (tramp-shell-prompt-pattern): Remove escape characters.
+       (tramp-process-one-action, tramp-convert-file-attributes):
+       Use `ansi-color-control-seq-regexp'.  (Bug#63539)
+       (tramp-wrong-passwd-regexp): Add "Authentication failed" string
+       (from doas).
+       (tramp-terminal-type): Fix docstring.
+       (tramp-process-one-action): Delete ANSI control escape sequences
+       in buffer.  (Bug#63539)
+       (tramp-build-completion-file-name-regexp): Support user name
+       completion.
+       (tramp-make-tramp-file-name): Keep hop while in file
+       (tramp-set-completion-function): Check, that cdr of FUNCTION-LIST
+       entries is a string.
+       (tramp-completion-file-name-handler): Run only when
+       `minibuffer-completing-file-name' is non-nil.
+       (tramp-skeleton-write-region): Fix scoping.  (Bug#65022)
+       (tramp-handle-memory-info): Work on newly created objects, or use
+       non-destructive operations.
+       (tramp-accept-process-output): Use `with-local-quit'.
+       (tramp-call-process, tramp-call-process-region):
+       Let-bind `temporary-file-directory'.
+
+       * test/lisp/net/tramp-archive-tests.el (tramp-archive--test-emacs28-p):
+       New defun.
+       (tramp-archive-test16-directory-files): Don't mutate.
+       (tramp-archive-test47-auto-load): Adapt test.
+
+       * test/lisp/net/tramp-tests.el (tramp-display-escape-sequence-regexp):
+       Dont't declare.
+       (tramp-action-yesno): Suppress run in tests.
+       (tramp-test02-file-name-dissect):
+       (tramp-test02-file-name-dissect-simplified)
+       (tramp-test02-file-name-dissect-separate): Adapt tests.
+       (tramp-test21-file-links):
+       (tramp-test21-file-links, tramp-test26-file-name-completion)
+       (tramp-test28-process-file, tramp-test29-start-file-process)
+       (tramp-test30-make-process, tramp-test33-environment-variables)
+       (tramp-test38-find-backup-file-name, tramp-test47-auto-load)
+       (tramp-test39-detect-external-change, tramp-test42-utf8)
+       (tramp-test47-auto-load, tramp-test47-delay-load)
+       (tramp-test48-unload): Adapt tests.
+       (tramp-test26-file-name-completion-with-perl):
+       (tramp-test26-file-name-completion-with-ls)
+       (tramp-test26-interactive-file-name-completion): New tests.
+       (tramp-test44-asynchronous-requests): Mark as :unstable.
+
+2023-08-05  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix documentation of saveplace facilities for Dired
+
+       * lisp/saveplace.el (save-place-dired-hook, save-place-alist):
+       * lisp/dired.el (dired-initial-position-hook)
+       (dired-initial-position): Doc fixes.  (Bug#65055)
+
+2023-08-04  Jim Porter  <jporterbugs@gmail.com>
+
+       Fix loaddef generation with ";;;foo-autoload" cookies in external 
packages
+
+       This caused an issue where package-specific autoload cookies weren't
+       being correctly recognized, so they got dumped into the package's main
+       "<pkg>-autoloads.el" file, instead of "<pkg>-loaddefs.el" as they
+       should (bug#65023).
+
+       * lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate--parse-file):
+       Save match data when checking syntax.
+
+2023-08-04  Stefan Kangas  <stefankangas@gmail.com>
+
+       Delete comment saying that project.el is experimental
+
+       * lisp/progmodes/project.el (Commentary): Delete comment saying that
+       the API is "still experimental".  It is to be considered stable
+       starting with the version released with Emacs 29.
+       Ref: https://lists.gnu.org/r/emacs-devel/2023-07/msg00415.html
+
+2023-08-04  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix byte-compiled files that use 'bind-key' from use-package
+
+       * lisp/use-package/bind-key.el (bind-key): Ensure 'bind-key' is
+       loaded at run time.  Patch by John Wiegley <johnw@gnu.org>.
+       (Bug#64901)
+
+2023-08-04  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix "Paste from Kill Menu" in non X toolkit builds
+
+       * src/keymap.c (possibly_translate_key_sequence): Don't signal an
+       error if 'key-valid-p' returns nil.  Suggested by Stefan Monnier
+       <monnier@iro.umontreal.ca>. (Bug#64927)
+
+2023-08-03  john muhl  <jm@pub.pink>
+
+       Handle tabs in the SQL shown in the column listing
+
+       * lisp/sqlite-mode.el (sqlite-mode-list-columns): Handle tabs.
+       (Bug#64964)
+
+2023-08-03  Eli Zaretskii  <eliz@gnu.org>
+
+       Add new keyword to 'typescript-ts-mode'
+
+       * lisp/progmodes/typescript-ts-mode.el
+       (typescript-ts-mode--keywords): Add "satisfies", a new operator in
+       Typescript 4.9.  (Bug#64924)
+
+2023-08-03  Stefan Kangas  <stefankangas@gmail.com>
+
+       Fix link to info node in prin1 docstring
+
+       * src/print.c (Fprin1): Fix linking to info node in docstring.
+
+       (cherry picked from commit 4b73edb8d1da74fd1bda8894e982d9768fd1f18c)
+
+2023-08-03  Eli Zaretskii  <eliz@gnu.org>
+
+       Clarify the meaning of the argument of ':align-to' space spec
+
+       * doc/lispref/display.texi (Specified Space): Clarify the meaning
+       and measurement of HPOS in ':align-to' space specs.  (Bug#65015)
+
+2023-08-01  Jim Porter  <jporterbugs@gmail.com>
+
+       Fix handling of ".elpaignore" file when compiling packages
+
+       * lisp/emacs-lisp/bytecomp.el (byte-recompile-directory): Treat
+       'byte-compile-ignore-files' as a list of regexps per its docstring
+       (bug#64985).
+
+2023-08-01  Amritpal Singh  <sysgrammer@protonmail.com>  (tiny change)
+
+       Support files compressed by 'pigz'
+
+       * src/decompress.c (md5_gz_stream): Check 'stream.avail_in' as
+       well.  (Bug#63832)
+
+       (cherry picked from commit 46b6d175054e8f6bf7cb45e112048c0cf02bfee9)
+
+2023-07-31  Eli Zaretskii  <eliz@gnu.org>
+
+       Fix 'string-pixel-width' under 'line-prefix'
+
+       * lisp/emacs-lisp/subr-x.el (string-pixel-width): Disable
+       'line-prefix' and 'wrap-prefix' to avoid their effect on the
+       calculated string width.  (Bug#64971)
+
+2023-07-31  Michael Albinus  <michael.albinus@gmx.de>
+
+       Fix find-dired-with-command for remote directories
+
+       * lisp/find-dired.el (find-dired-with-command):
+       Use `start-file-process-shell-command'.  (Bug#64897)
+
+2023-07-30  Kyle Meyer  <kyle@kyleam.com>
+
+       Update to Org 9.6.7-5-gd1d0c3
+
+2023-07-30  Mattias Engdegård  <mattiase@acm.org>
+
+       Fix rx wrong-code bug: ranges starting with ^
+
+       (rx (in (?^ . ?a))) was incorrectly translated to "[^-a]".
+       Change it so that we get "[_-a^]" instead.
+
+       * lisp/emacs-lisp/rx.el (rx--generate-alt): Split ranges starting with
+       `^` occurring first in a non-negated character alternative.
+       * test/lisp/emacs-lisp/rx-tests.el (rx-any): Add and adapt tests.
+
+       (cherry picked from commit 5f5d668ac7917d61e9366fe0c3efd7b542671c3d)
+
+2023-07-30  Basil L. Contovounesios  <contovob@tcd.ie>
+
+       Backport: Fix some tree-sitter :match regexps
+
+       This was originally installed on 2023-06-17 in the emacs-29 release
+       branch and later reverted.  This backport follows the Emacs 29.1
+       release (bug#64019).
+
+       The shy groups were caught by modified versions of the GNU ELPA
+       packages xr and relint:
+       - https://github.com/mattiase/xr/pull/6
+       - https://github.com/mattiase/relint/pull/14
+
+       * lisp/progmodes/ruby-ts-mode.el (ruby-ts--s-p-query): Quote special
+       character in regexp.
+       * lisp/progmodes/java-ts-mode.el (java-ts-mode--font-lock-settings):
+       * lisp/progmodes/js.el (js--plain-method-re):
+       (js--treesit-font-lock-settings):
+       * lisp/progmodes/rust-ts-mode.el (rust-ts-mode--font-lock-settings):
+       * lisp/progmodes/typescript-ts-mode.el
+       (typescript-ts-mode--font-lock-settings): Replace character
+       alternative [\\d], which matches '\' or 'd', with the most likely
+       intention [0-9].  Fix shy groups mistyped as optional colons.
+       Remove unneeded numbered :match group in rust-ts-mode.
+
+       (cherry picked from commit cd8d3f3379ec7179fac4bb8e9c40658be15a64f6)
+
+2023-07-30  Po Lu  <luangruo@yahoo.com>
+
+       Fix bug#64923
+
+       * src/xfns.c (Fx_create_frame): Prevent cairo surface from being
+       left without a desired size.  (bug#64923)
+
+2023-07-30  Ulrich Müller  <ulm@gentoo.org>
+
+       Avoid spurious whitespace in the modeline of emacsclient frames
+
+       * lisp/bindings.el (mode-line-client): Compute 'help-echotext
+       property in advance.  (Bug#58183)
+
+       (cherry picked from commit 8c3338f6ba354218aee12c223d778be4180f892b)
+
+2023-07-30  Mattias Engdegård  <mattiase@acm.org>
+
+       Fix function help for advised aliases (bug#64797)
+
+       * lisp/help-fns.el (help-fns--analyze-function):
+       For aliases, use the base function name if at the end of the chain.
+       This fixes a regression introduced in d30fde6b0cc.
+
+       Reported by Michael Heerdegen.
+
+       (cherry picked from commit 024bd1f09099ae186442001a75e578638070e296)
+
+2023-07-30  Eli Zaretskii  <eliz@gnu.org>
+
+       Avoid crashes due to invalid 'mode-line-format'
+
+       * src/xdisp.c (display_mode_element, redisplay_window_error):
+       Don't take XCAR of what can be Qnil.  (Bug#64893)
+
+       (cherry picked from commit 7ea3f39deec3d54914077455e70605a14eb7d200)
+
+2023-07-30  Eli Zaretskii  <eliz@gnu.org>
+
+       Avoid crashes under 'which-key-mode'
+
+       * src/keyboard.c (Fthis_single_command_keys): Don't allow calls to
+       Fvector with negative first argument.  (Bug#64857)
+
+       (cherry picked from commit 65834b8f8d53402517da7fe2446f5bac0aa30c39)
+
+2023-07-30  Eli Zaretskii  <eliz@gnu.org>
+
+       Bump Emacs version
+
+       * README:
+       * configure.ac:
+       * nt/README.W32:
+       * msdos/sed2v2.inp:
+       * etc/NEWS: Bump Emacs version to 29.1.50.
+
+2023-07-29  Vincenzo Pupillo  <v.pupillo@gmail.com>
+
+       Update CMake support due to upstream changes (bug#64922)
+
+       A recent change in tree-sitter-cmake grammar support for CMake (commit
+       fe9b5e0), now put arguments are wrapped in a new argument_list node.
+       To support the old and new version of the grammar, a new function was
+       added on which string syntax highlighting now depends.
+
+       * lisp/progmodes/cmake-ts-mode.el
+       (cmake-ts-mode--font-lock-compatibility-fe9b5e0): Indent helper
+       function to handle different tree-sitter-cmake version.
+       * lisp/progmodes/cmake-ts-mode.el
+       (cmake-ts-mode--font-lock-settings): Use the new function to handle
+       the new argument_list node.
+
+2023-07-24  Theodor Thornhill  <theo@thornhill.no>
+
+       Remove nullptr named node from c++-ts-mode (bug#64818)
+
+       The nullptr node was changed from a named node to an unnamed node
+       upstream[0], which caused font locking to break. As this is a small
+       enough regression, no compat code is required.
+
+       * lisp/progmodes/c-ts-mode.el (c-ts-mode--font-lock-settings): Remove
+       node no longer in use.
+
+       [0]:
+       
https://github.com/tree-sitter/tree-sitter-c/commit/c75868f8b508ae32a0c8490da91bb31b2b96430e
+
+2023-07-24  Theodor Thornhill  <theo@thornhill.no>
+
+       Make compat check also check typescript
+
+       * lisp/progmodes/typescript-ts-mode.el
+       (tsx-ts-mode--font-lock-compatibility-bb1f97b):
+       Add argument so that we run the 'treesit-query-capture' when the
+       language is 'typescript', not only 'tsx'.
+
+       * lisp/progmodes/typescript-ts-mode.el
+       (typescript-ts-mode--font-lock-settings): Use supplied argument.
+
+2023-07-23  Eli Zaretskii  <eliz@gnu.org>
+
+       Update HISTORY and ChangeLog.4
+
+       * etc/HISTORY:
+       * ChangeLog.4: Update for the Emacs 29.1 release.
+
 2023-07-30  Eli Zaretskii  <eliz@maintain0p.gnu.org>
 
        * Version 29.1 released.
@@ -117380,7 +119361,7 @@
 
 This file records repository revisions from
 commit f2ae39829812098d8269eafbc0fcb98959ee5bb7 (exclusive) to
-commit 7d1737071fba1fd83039aac34f34f6b90c9579b8 (inclusive).
+commit d9e1605122b4ba70a55f7b168505b7d7f8d2bdd6 (inclusive).
 See ChangeLog.3 for earlier changes.
 
 ;; Local Variables:
diff --git a/Makefile.in b/Makefile.in
index 51a27cc1814..45540d2742f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -421,7 +421,7 @@ advice-on-failure:
 
 sanity-check:
        @[ -f .no-advice-on-failure ] && exit 0; true
-       @v=`src/emacs${EXEEXT} --batch --eval \
+       @v=`src/emacs${EXEEXT} --batch -Q --eval \
          '(progn (defun f (n) (if (= 0 n) 1 (* n (f (- n 1))))) (princ (f 
10)))' \
          2> /dev/null`; \
        [ "X$$v" = "X3628800" ] && exit 0; \
diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS
index 1801842bdcb..a6e1baf85e1 100644
--- a/admin/MAINTAINERS
+++ b/admin/MAINTAINERS
@@ -124,10 +124,6 @@ Ulf Jasper
            lisp/net/newsticker.el
            test/lisp/net/newsticker-tests.el
 
-       Icalendar
-           lisp/calendar/icalendar.el
-           test/lisp/calendar/icalendar-tests.el
-
 Amin Bandali
        ERC
            lisp/erc/*
diff --git a/admin/notes/emba b/admin/notes/emba
index cad7a2e121c..88ac3ebe351 100644
--- a/admin/notes/emba
+++ b/admin/notes/emba
@@ -21,7 +21,7 @@ If you want to receive these notifications, please subscribe 
at
 <https://lists.gnu.org/mailman/listinfo/emacs-buildstatus>.
 
 Alternatively, these notifications can be read via gmane at
-<nntp+news.gmane.org:gmane.emacs.buildstatus>.
+<nntp+news.gmane.io:gmane.emacs.buildstatus>.
 
 The messages contain a URL to the log file of the failed job, like
 <https://emba.gnu.org/emacs/emacs/-/jobs/739/raw>.
diff --git a/doc/emacs/ChangeLog.1 b/doc/emacs/ChangeLog.1
index 1cf26aeff06..6e20eb942ce 100644
--- a/doc/emacs/ChangeLog.1
+++ b/doc/emacs/ChangeLog.1
@@ -5771,7 +5771,7 @@
        Add view-external-packages on C-h C-e.
        Add view-order-manuals on C-h C-m.
 
-2008-02-17  Ulrich Mueller  <ulm@kph.uni-mainz.de>
+2008-02-17  Ulrich Müller  <ulm@kph.uni-mainz.de>
 
        * msdog-xtra.texi (MS-DOS): Docstring fix.
 
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index 8c30f26bbf7..e2d35863bd0 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1507,7 +1507,18 @@ mode or subdirectory, and for variable and value, and 
adds the
 entry defining the directory-local variable.  @kbd{M-x
 delete-dir-local-variable} deletes an entry.  @kbd{M-x
 copy-file-locals-to-dir-locals} copies the file-local variables in the
-current file into @file{.dir-locals.el}.
+current file into @file{.dir-locals.el}, or @file{.dir-locals-2.el} if
+that file is also present.
+
+With a prefix argument, all three commands prompt for the file you
+want to modify.  Although it doesn't have to exist, you must enter a
+valid filename, either @file{.dir-locals.el} or
+@file{.dir-locals-2.el}.
+
+@findex customize-dirlocals
+There's also a command to pop up an Easy Customization buffer
+(@pxref{Easy Customization}) to edit directory local variables,
+@code{customize-dirlocals}.
 
 @findex dir-locals-set-class-variables
 @findex dir-locals-set-directory-class
@@ -1591,6 +1602,10 @@ discriminate for the properties @code{:protocol} (this 
is the Tramp
 method) or @code{:user} (a remote user name).  The @code{nil} criteria
 matches all buffers with a remote default directory.
 
+  Be careful when declaring different profiles with the same variable,
+and setting these profiles to criteria which could match in parallel.
+It is unspecified which variable value is used then.
+
 @node Key Bindings
 @section Customizing Key Bindings
 @cindex key bindings
diff --git a/doc/emacs/input.texi b/doc/emacs/input.texi
index db0e88a1c9c..0dd7fca41cc 100644
--- a/doc/emacs/input.texi
+++ b/doc/emacs/input.texi
@@ -23,56 +23,57 @@ which is detailed here.
 @section Using Emacs on Touchscreens
 @cindex touchscreen input
 
-  Touchscreen input works by pressing and moving tools (which include
-fingers and some pointing devices--styluses, for example) onto a frame
-in order to manipulate its contents.
+  Touchscreen input is the manipulation of a frame's contents by the
+placement and motion of tools (instanced by fingers and such pointing
+devices as styluses) on a monitor or computer terminal where it is
+displayed.
 
-  When running under the X Window System or Android, Emacs
-automatically detects and maps the following sequences of movements
-(``gestures'') to common actions:
+  Under the X Window System or Android, Emacs detects and translates
+the following sequences of movements (@dfn{gestures}) to common
+actions:
 
 @itemize @bullet
 @item
 @cindex tapping, touchscreens
-  ``Tapping'', briefly placing and lifting a tool from the display,
-will result in Emacs selecting the window that was tapped, and
-executing any command bound to @code{mouse-1} at that location in the
-window.  If the tap happened on top of a link (@pxref{Mouse
-References}), then Emacs will follow the link instead.
-
-  If a command bound to @code{down-mouse-1} is bound to the location
-where the tap took place, Emacs will execute that command as well.
+  @dfn{Tapping}, briefly placing and lifting a tool from the display,
+will select the window that was tapped, and execute any command bound
+to @code{mouse-1} at that location in the window.  If a link
+(@pxref{Mouse References}) exists there, then Emacs will follow that
+link instead (insofar as such action differs from that taken upon the
+simulation of a @code{mouse-1} event).
 
 @item
 @cindex scrolling, touchscreens
-  ``Scrolling'', meaning to place a tool on the display and move it up
-or down, will result in Emacs scrolling the window contents in the
-direction where the tool moves.
-
-  If the tool is moved left or right, Emacs additionally scrolls the
-window horizontally to follow (@pxref{Horizontal Scrolling}.)
+@vindex touch-screen-enable-hscroll
+  @dfn{Scrolling}, which is continuous vertical or horizontal motion
+on the screen, will scroll the contents of the window beneath the
+tool's initial location in the direction of movement.  The user option
+@code{touch-screen-enable-hscroll} governs whether horizontal
+scrolling (@pxref{Horizontal Scrolling}) is performed in reaction to
+this gesture.
 
 @item
 @cindex dragging, touchscreens
 @cindex long-press, touchscreens
-  ``Dragging'', which is performing a @dfn{long-press} by placing a
-tool on the display and leaving it there for a while prior to moving
-the tool around will make Emacs set the point to where the tool was
-and begin selecting text under the tool as it moves around, as if
-@code{mouse-1} were to be held down.  @xref{Mouse Commands}.
+  @dfn{Dragging}, which is performing a @dfn{long-press} by placing a
+tool on the display and leaving it there awhile before moving it to
+another position, will move point to the tool's initial position, and
+commence selecting text under the tool as it continues its motion, as
+if @code{mouse-1} were to be held down and a mouse moved analogously.
+@xref{Mouse Commands}.
 
 @vindex touch-screen-word-select
 @cindex word selection mode, touchscreens
-  Some people find it difficult to position a tool accurately on a
-touch screen display, to the detriment of text selection.  The user
-option @code{touch-screen-word-select} enables ``word selection
-mode'', causing dragging to select the complete word, not only the
-character containing the position of the tool.
+  To the detriment of text selection, it can prove challenging to
+position a tool accurately on a touch screen display.  The user option
+@code{touch-screen-word-select}, which when enabled, prompts dragging
+to select the complete word under the tool.  (Normally, the selection
+is only extended to encompass the character beneath the tool.)
 
 @vindex touch-screen-extend-selection
 @cindex extending the selection, touchscreens
-  Similarly, it may be difficult to select all of the text intended
-within a single gesture.  If the user option
+  In the same vein, it may be difficult to select all of the text
+intended within a single gesture.  If the user option
 @code{touch-screen-extend-selection} is enabled, taps on the locations
 of the point or the mark within a window will begin a new ``drag''
 gesture, where the region will be extended in the direction of any
@@ -80,21 +81,19 @@ subsequent movement.
 
 @vindex touch-screen-preview-select
 @cindex previewing the region during selection, touchscreens
-  Difficulties in making accurate adjustments to the region can also
-be alleviated by indicating the position of the point relative to its
-containing line within the echo area, since the window cursor may be
-physically obscured by the tool.  If
+  Difficulties in making accurate adjustments to the region from the
+cursor being physically obscured by the tool can be mitigated by
+indicating the position of the point within the echo area.  If
 @code{touch-screen-preview-select} is non-@code{nil}, the line
-containing point is displayed in the echo area (@pxref{Echo Area})
-during the motion of the tool, followed by another line indicating the
-position of point within the first line.
+surrounding point is displayed in the echo area (@pxref{Echo Area})
+during the motion of the tool, below which is another line indicating
+the position of point relative to the first.
 @end itemize
 
 @vindex touch-screen-delay
-  By default, Emacs considers a tool as having been left on the
-display long enough to trigger a ``long-press'' after 0.7 seconds, but
-this can be changed by customizing the variable
-@code{touch-screen-delay}.
+  Emacs registers a long-press after the time a tool has been placed
+upon the screen exceeds 0.7 seconds.  This delay can be adjusted
+through customizing the variable @code{touch-screen-delay}.
 
 @node On-Screen Keyboards
 @section Using Emacs with Virtual Keyboards
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index a05b7f6c6ea..d3c5712099d 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -399,18 +399,18 @@ vulnerable to a variety of attacks, and you may want to 
avoid using
 these if what you're doing requires higher security.  (This is the
 @code{ssl} check in @code{network-security-protocol-checks}).
 
+@item Triple DES (or @acronym{3DES}) cipher
+The @acronym{3DES} stream cipher provides at most 112 bits of
+effective security, and a major security vulnerability in it was
+disclosed in 2016 (CVE-2016-2183).  It has been deprecated by NIST in
+all applications from late 2023 onwards.  (This is the
+@code{3des-cipher} check in @code{network-security-protocol-checks}).
 @end table
 
 If @code{network-security-level} is @code{high}, the following checks
 will be made, in addition to the above:
 
 @table @asis
-@item @acronym{3DES} cipher
-The @acronym{3DES} stream cipher provides at most 112 bits of
-effective security, which is considered to be towards the low end.
-(This is the @code{3des} check in
-@code{network-security-protocol-checks}).
-
 @item a validated certificate changes the public key
 Servers change their keys occasionally, and that is normally nothing
 to be concerned about.  However, if you are worried that your network
@@ -2078,6 +2078,18 @@ files.  When this option is given, the arguments to
 @command{emacsclient} are interpreted as a list of expressions to
 evaluate, @emph{not} as a list of files to visit.
 
+@vindex server-eval-args-left
+Passing complex Lisp expression via the @option{--eval} command-line
+option sometimes requires elaborate escaping of characters special to
+the shell.  To avoid this, you can pass arguments to Lisp functions in
+your expression as additional separate arguments to
+@command{emacsclient}, and use @var{server-eval-args-left} in the
+expression to access those arguments.  Be careful to have your
+expression remove the processed arguments from
+@var{server-eval-args-left} regardless of whether your code succeeds,
+for example by using @code{pop}, otherwise Emacs will attempt to
+evaluate those arguments as separate Lisp expressions.
+
 @item -f @var{server-file}
 @itemx --server-file=@var{server-file}
 Specify a server file (@pxref{TCP Emacs server}) for connecting to an
diff --git a/doc/emacs/screen.texi b/doc/emacs/screen.texi
index 5e9e89e6b11..3b910587260 100644
--- a/doc/emacs/screen.texi
+++ b/doc/emacs/screen.texi
@@ -173,7 +173,7 @@ unselected windows, in order to make it stand out.
   The text displayed in the mode line has the following format:
 
 @example
- @var{cs}:@var{ch}-@var{fr}  @var{buf}      @var{pos} @var{line}   
(@var{major} @var{minor})
+ @var{cs}:@var{ch}-@var{d}@var{fr}  @var{buf}      @var{pos} @var{line}   
(@var{major} @var{minor})
 @end example
 
 @noindent
@@ -231,6 +231,12 @@ shows @samp{%*} if the buffer is modified, and @samp{%%} 
otherwise.
 However, if @code{default-directory} (@pxref{File Names}) for the
 current buffer is on a remote machine, @samp{@@} is displayed instead.
 
+  @var{d} appears if the window is dedicated to its current buffer.
+It appears as @samp{D} for strong dedication and @samp{d} for other
+forms of dedication.  If the window is not dedicated, @var{d} does not
+appear.  @xref{Dedicated Windows,, elisp, The Emacs Lisp Reference
+Manual}.
+
   @var{fr} gives the selected frame name (@pxref{Frames}).  It appears
 only on text terminals.  The initial frame's name is @samp{F1}.
 
diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index 665fd80e53b..ca5e424d939 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -411,6 +411,28 @@ selected window and (ii) prefer to either create a new 
frame or use a
 window on some other frame to display the desired buffer.  Several of
 these commands are bound in the @kbd{C-x 5} prefix key.
 
+@cindex dedicated window
+  Sometimes, a window is ``dedicated'' to its current buffer.
+@xref{Dedicated Windows,, elisp, The Emacs Lisp Reference Manual}.
+@code{display-buffer} will avoid reusing dedicated windows most of the
+time.  This is indicated by a @samp{d} in the mode line (@pxref{Mode
+Line}).  A window can also be strongly dedicated, which prevents any
+changes to the buffer displayed in the window.  This is indicated by a
+@samp{D} in the mode line.
+
+Usually, dedicated windows are used to display specialized buffers,
+but dedication can sometimes be useful interactively.  For example,
+when viewing errors with @kbd{M-g M-n} @code{next-error}, newly
+displayed source code may replace a buffer you want to refer to.  If
+you dedicate a window to that buffer, the command (through
+@code{display-buffer}) will prefer to use a different window instead.
+
+@kindex C-x w d
+@findex toggle-window-dedicated
+  Toggle whether the selected window is dedicated to the current
+buffer.  With a prefix argument, make the window strongly dedicated
+instead.
+
 @menu
 * Window Choice::   How @code{display-buffer} works.
 * Temporary Displays::   Displaying non-editable buffers.
diff --git a/doc/lispintro/emacs-lisp-intro.texi 
b/doc/lispintro/emacs-lisp-intro.texi
index fce7583fe91..c5b33ac5eaa 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -15793,6 +15793,7 @@ of the @code{and} expression.
 
 @c colon in printed section title causes problem in Info cross reference
 This way, we avoid an error.
+
 @iftex
 @noindent
 (For information about @code{and}, see
diff --git a/doc/lispref/ChangeLog.1 b/doc/lispref/ChangeLog.1
index c96ba40dbe5..95a23e981cc 100644
--- a/doc/lispref/ChangeLog.1
+++ b/doc/lispref/ChangeLog.1
@@ -5792,7 +5792,7 @@
 
        * display.texi (Face Functions): Mention define-obsolete-face-alias.
 
-2009-08-26  Ulrich Mueller  <ulm@gentoo.org>
+2009-08-26  Ulrich Müller  <ulm@gentoo.org>
 
        * nonascii.texi (Character Codes): Fix typos.
 
diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi
index 86c47ae7310..a2d0f5687ba 100644
--- a/doc/lispref/buffers.texi
+++ b/doc/lispref/buffers.texi
@@ -957,10 +957,10 @@ with a @code{nil} @var{norecord} argument since this may 
lead to
 infinite recursion.
 @end defvar
 
-@defun buffer-match-p condition buffer-or-name &optional arg
+@defun buffer-match-p condition buffer-or-name &rest args
 This function checks if a buffer designated by @code{buffer-or-name}
-satisfies the specified @code{condition}.  Optional third argument
-@var{arg} is passed to the predicate function in @var{condition}.  A
+satisfies the specified @code{condition}.  Optional arguments
+@var{args} are passed to the predicate function in @var{condition}.  A
 valid @var{condition} can be one of the following:
 @itemize @bullet{}
 @item
@@ -969,23 +969,21 @@ satisfies the condition if the regular expression matches 
the buffer
 name.
 @item
 A predicate function, which should return non-@code{nil} if the buffer
-matches.  If the function expects one argument, it is called with
-@var{buffer-or-name} as the argument; if it expects 2 arguments, the
-first argument is @var{buffer-or-name} and the second is @var{arg}
-(or @code{nil} if @var{arg} is omitted).
+matches.  It is called with
+@var{buffer-or-name} as the first argument followed by @var{args}.
 @item
 A cons-cell @code{(@var{oper} . @var{expr})} where @var{oper} is one
 of
 @table @code
 @item (not @var{cond})
 Satisfied if @var{cond} doesn't satisfy @code{buffer-match-p} with
-the same buffer and @code{arg}.
+the same buffer and @code{args}.
 @item (or @var{conds}@dots{})
 Satisfied if @emph{any} condition in @var{conds} satisfies
-@code{buffer-match-p}, with the same buffer and @code{arg}.
+@code{buffer-match-p}, with the same buffer and @code{args}.
 @item (and @var{conds}@dots{})
 Satisfied if @emph{all} the conditions in @var{conds} satisfy
-@code{buffer-match-p}, with the same buffer and @code{arg}.
+@code{buffer-match-p}, with the same buffer and @code{args}.
 @item derived-mode
 Satisfied if the buffer's major mode derives from @var{expr}.
 @item major-mode
@@ -998,14 +996,14 @@ string) or @code{(and)} (empty conjunction).
 @end itemize
 @end defun
 
-@defun match-buffers condition &optional buffer-list arg
+@defun match-buffers condition &optional buffer-list &rest args
 This function returns a list of all buffers that satisfy the
 @code{condition}.  If no buffers match, the function returns
 @code{nil}.  The argument @var{condition} is as defined in
 @code{buffer-match-p} above.  By default, all the buffers are
 considered, but this can be restricted via the optional argument
 @code{buffer-list}, which should be a list of buffers to consider.
-Optional third argument @var{arg} will be passed to @var{condition} in
+Remaining arguments @var{args} will be passed to @var{condition} in
 the same way as @code{buffer-match-p} does.
 @end defun
 
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index fdf5ec1d7fe..41c30437dce 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -3969,20 +3969,17 @@ interrupted, even by input from the standard input 
descriptor.  It is
 thus equivalent to @code{sleep-for}, which is described below.
 @end defun
 
-@defun sleep-for seconds &optional millisec
+@defun sleep-for seconds
 This function simply pauses for @var{seconds} seconds without updating
 the display.  It pays no attention to available input.  It returns
 @code{nil}.
 
 The argument @var{seconds} need not be an integer.  If it is floating
 point, @code{sleep-for} waits for a fractional number of seconds.
-Some systems support only a whole number of seconds; on these systems,
-@var{seconds} is rounded down.
 
-The optional argument @var{millisec} specifies an additional waiting
-period measured in milliseconds.  This adds to the period specified by
-@var{seconds}.  If the system doesn't support waiting fractions of a
-second, you get an error if you specify nonzero @var{millisec}.
+It is also possible to call @code{sleep-for} with two arguments,
+as @code{(sleep-for @var{seconds} @var{millisec})},
+but that is considered obsolete and will be removed in the future.
 
 Use @code{sleep-for} when you wish to guarantee a delay.
 @end defun
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 72441c8d442..c357c8cb35d 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -534,10 +534,10 @@ Variables
 
 Scoping Rules for Variable Bindings
 
-* Dynamic Binding::         The default for binding local variables in Emacs.
+* Lexical Binding::         The standard type of local variable binding.
+* Dynamic Binding::         A different type of local variable binding.
 * Dynamic Binding Tips::    Avoiding problems with dynamic binding.
-* Lexical Binding::         A different type of local variable binding.
-* Using Lexical Binding::   How to enable lexical binding.
+* Selecting Lisp Dialect::   How to select the Emacs Lisp dialect to use.
 * Converting to Lexical Binding:: Convert existing code to lexical binding.
 
 Buffer-Local Variables
diff --git a/doc/lispref/errors.texi b/doc/lispref/errors.texi
index db46a6aaf59..4eafe608302 100644
--- a/doc/lispref/errors.texi
+++ b/doc/lispref/errors.texi
@@ -246,7 +246,8 @@ signaled when @code{inhibit-interaction} is non-@code{nil} 
and a user
 interaction function (like @code{read-from-minibuffer}) is called.
 @end table
 
-@ignore    The following seem to be unused now.
+@c The following seem to be unused now.
+@ignore
   The following kinds of error, which are classified as special cases of
 @code{arith-error}, can occur on certain systems for invalid use of
 mathematical functions.  @xref{Math Functions}.
diff --git a/doc/lispref/eval.texi b/doc/lispref/eval.texi
index a45517287b7..8af0ee49d02 100644
--- a/doc/lispref/eval.texi
+++ b/doc/lispref/eval.texi
@@ -740,13 +740,17 @@ type of the @var{form} object determines how it is 
evaluated.
 @xref{Forms}.
 
 The argument @var{lexical} specifies the scoping rule for local
-variables (@pxref{Variable Scoping}).  If it is omitted or @code{nil},
-that means to evaluate @var{form} using the default dynamic scoping
-rule.  If it is @code{t}, that means to use the lexical scoping rule.
-The value of @var{lexical} can also be a non-empty alist specifying a
+variables (@pxref{Variable Scoping}).  If it is @code{t}, that means
+to evaluate @var{form} using lexical scoping; this is the recommended
+value.  If it is omitted or @code{nil}, that means to use the old
+dynamic-only variable scoping rule.
+
+The value of @var{lexical} can also be a non-empty list specifying a
 particular @dfn{lexical environment} for lexical bindings; however,
 this feature is only useful for specialized purposes, such as in Emacs
-Lisp debuggers.  @xref{Lexical Binding}.
+Lisp debuggers.  Each member of the list is either a cons cell which
+represents a lexical symbol-value pair, or a symbol representing a
+(special) variable that would use dynamic scoping if bound.
 
 Since @code{eval} is a function, the argument expression that appears
 in a call to @code{eval} is evaluated twice: once as preparation before
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi
index afedf776c86..dc66ea8bc9c 100644
--- a/doc/lispref/files.texi
+++ b/doc/lispref/files.texi
@@ -1803,7 +1803,7 @@ If @var{newname} exists, then it must be an empty 
directory if
 @var{oldname} is a directory and a non-directory otherwise.
 @end deffn
 
-@deffn Command copy-file oldname newname &optional ok-if-already-exists time 
preserve-uid-gid preserve-extended-attributes
+@deffn Command copy-file oldname newname &optional ok-if-already-exists time 
preserve-uid-gid preserve-permissions
 This command copies the file @var{oldname} to @var{newname}.  An
 error is signaled if @var{oldname} is not a regular file.  If @var{newname}
 names a directory, it copies @var{oldname} into that directory,
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 75bc4de4f61..6193a4fe1cd 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -60,8 +60,12 @@ The frame is displayed on a GNUstep or Macintosh Cocoa 
graphical
 terminal.
 @item pc
 The frame is displayed on an MS-DOS terminal.
+@item haiku
+The frame is displayed using the Haiku Application Kit.
 @item pgtk
 The frame is displayed using pure GTK facilities.
+@item android
+The frame is displayed on an Android device.
 @end table
 @end defun
 
@@ -224,8 +228,8 @@ The terminal and keyboard coding systems used on the 
terminal.
 @item
 The kind of display associated with the terminal.  This is the symbol
 returned by the function @code{terminal-live-p} (i.e., @code{x},
-@code{t}, @code{w32}, @code{ns}, @code{pc}, @code{haiku}, or @code{pgtk}).
-@xref{Frames}.
+@code{t}, @code{w32}, @code{ns}, @code{pc}, @code{haiku}, @code{pgtk},
+or @code{android}).  @xref{Frames}.
 
 @item
 A list of terminal parameters.  @xref{Terminal Parameters}.
@@ -4003,22 +4007,24 @@ defined in the file @file{lisp/term/x-win.el}.  Use 
@kbd{M-x apropos
 @cindex secondary selection
 
   In window systems, such as X, data can be transferred between
-different applications by means of @dfn{selections}.  X defines an
-arbitrary number of @dfn{selection types}, each of which can store its
-own data; however, only three are commonly used: the @dfn{clipboard},
-@dfn{primary selection}, and @dfn{secondary selection}.  Other window
-systems support only the clipboard.  @xref{Cut and Paste,, Cut and
-Paste, emacs, The GNU Emacs Manual}, for Emacs commands that make use
-of these selections.  This section documents the low-level functions
-for reading and setting window-system selections.
+different applications by means of @dfn{selections}.  Each window
+system defines an arbitrary number of @dfn{selection types}, all
+storing their own data; however, only three are commonly used: the
+@dfn{clipboard}, @dfn{primary selection}, and @dfn{secondary
+selection}.  @xref{Cut and Paste,, Cut and Paste, emacs, The GNU Emacs
+Manual}, for Emacs commands that make use of these selections.  This
+section documents the low-level functions for reading and setting
+window-system selections; @xref{Accessing Selections} for
+documentation concerning selection types and data formats under
+particular window systems.
 
 @deffn Command gui-set-selection type data
 This function sets a window-system selection.  It takes two arguments:
 a selection type @var{type}, and the value to assign to it, @var{data}.
 
 @var{type} should be a symbol; it is usually one of @code{PRIMARY},
-@code{SECONDARY} or @code{CLIPBOARD}.  These are symbols with
-upper-case names, in accord with X Window System conventions.  If
+@code{SECONDARY} or @code{CLIPBOARD}.  These are generally symbols
+with upper-case names, in accord with X Window System conventions.  If
 @var{type} is @code{nil}, that stands for @code{PRIMARY}.
 
 If @var{data} is @code{nil}, it means to clear out the selection.
@@ -4046,31 +4052,37 @@ programs.  It takes two optional arguments, @var{type} 
and
 
 The @var{data-type} argument specifies the form of data conversion to
 use, to convert the raw data obtained from another program into Lisp
-data.  Meaningful values include @code{TEXT}, @code{STRING},
-@code{UTF8_STRING}, @code{TARGETS}, @code{LENGTH}, @code{DELETE},
-@code{FILE_NAME}, @code{CHARACTER_POSITION}, @code{NAME},
-@code{LINE_NUMBER}, @code{COLUMN_NUMBER}, @code{OWNER_OS},
-@code{HOST_NAME}, @code{USER}, @code{CLASS}, @code{ATOM}, and
-@code{INTEGER}.  (These are symbols with upper-case names in accord
-with X conventions.)  The default for @var{data-type} is
-@code{STRING}.  Window systems other than X usually support only a
-small subset of these types, in addition to @code{STRING}.
+data.  @xref{X Selections} for an enumeration of data types valid
+under X, and @xref{Other Selections} for those elsewhere.
 @end defun
 
 @defopt selection-coding-system
-This variable specifies the coding system to use when reading and
-writing selections or the clipboard.  @xref{Coding
-Systems}.  The default is @code{compound-text-with-extensions}, which
-converts to the text representation that X11 normally uses.
+This variable provides a coding system (@pxref{Coding Systems}) which
+is used to encode selection data, and takes effect on MS-Windows and
+X@.  It is also used in the MS-DOS port when it runs on MS-Windows and
+can access the Windows clipboard text.
+
+On X, the value of this variable provides the coding system which
+@code{gui-get-selection} will use to decode selection data for a
+subset of text data types, and also forces replies to selection
+requests for the polymorphic @code{TEXT} data type to be encoded by
+the @code{compound-text-with-extensions} coding system rather than
+Unicode.
+
+On MS-Windows, this variable is generally ignored, as the MS-Windows
+clipboard provides the information about decoding as part of the
+clipboard data, and uses either UTF-16 or locale-specific encoding
+automatically as appropriate.  We recommend to set the value of this
+variable only on the older Windows 9X, as it is otherwise used only in
+the very rare cases when the information provided by the clipboard
+data is unusable for some reason.
+
+The default value of this variable is the system code page under
+MS-Windows 95, 98 or Me, @code{utf-16le-dos} on Windows
+NT/W2K/XP/Vista/7/8/10/11, @code{iso-latin-1-dos} on MS-DOS, and
+@code{nil} elsewhere.
 @end defopt
 
-@cindex clipboard support (for MS-Windows)
-When Emacs runs on MS-Windows, it does not implement X selections in
-general, but it does support the clipboard.  @code{gui-get-selection}
-and @code{gui-set-selection} on MS-Windows support the text data type
-only; if the clipboard holds other types of data, Emacs treats the
-clipboard as empty.  The supported data type is @code{STRING}.
-
 For backward compatibility, there are obsolete aliases
 @code{x-get-selection} and @code{x-set-selection}, which were the
 names of @code{gui-get-selection} and @code{gui-set-selection} before
@@ -4079,44 +4091,42 @@ Emacs 25.1.
 @node Accessing Selections
 @section Accessing Selections
 
-  @code{gui-get-selection} is able to retrieve multiple different
-kinds of selection data from any number of selections.  However, the
-data types and selections that Emacs understands is not precisely
-specified and differs depending on the window system on which Emacs is
-running.
-
-  At the same time, @code{gui-set-selection} hides a great deal of
-complexity behind its back, at least on some systems: its @var{data}
-argument need not be a string, but is actually given verbatim to
-system specific code.
-
-  Emacs's implementation of selections is most complete on the X
-Window System.  This is both an artifact of history (X was the first
-window system supported by Emacs) and one of technical reasons:
-instead of using selections only to transfer text and multimedia
-content between clients, X uses selections as a general inter-client
-communication system, leading to a great proliferation of selection
-data types.
-
-  Even more confusingly, X also supports another inter-client
-communication mechanism: the Inter-Client Exchange.  However, ICE is
+  The data types and selections that @code{gui-get-selection} and
+@code{gui-set-selection} understand are not precisely specified and
+differ subject to the window system on which Emacs is running.
+
+  At the same time, @code{gui-set-selection} abstracts over plenty of
+complexity: its @var{data} argument is given verbatim to
+system-specific code to be rendered suitable for transfer to the
+window system or requesting clients.
+
+  The most comprehensive implementation of selections exists under the
+X Window System.  This is both an artifact of history (X was the first
+window system supported by Emacs) and one occasioned by technical
+considerations: X selections are not merely an expedient for the
+transfer of text and multimedia content between clients, but a general
+inter-client communication system, a design that has yielded a
+proliferation of selection and data types.
+
+  Compounding this confusion, there is another inter-client
+communication mechanism under X: the Inter-Client Exchange.  ICE is
 only used by Emacs to communicate with session managers, and is a
 separate topic.
 
 @menu
-* X Selections::        Selection data types (and more) on X.
+* X Selections::        Selection data types (and more) on X@.
 * Other Selections::    How they work on other window systems.
 @end menu
 
 @node X Selections
 @subsection X Selections
 
-  X refrains from defining fixed data types for selection data, or a
-fixed number of selections.  Selections are instead identified by X
-``atoms'', which are unique 29-bit identifiers issued by the X server
-for a corresponding name.  In Emacs, you can simply write a symbol
-with the name of the atom, and Emacs will transparently request these
-identifiers where necessary.
+  X refrains from defining fixed data types for selection data or a
+fixed number of selections.  Selections are identified by X ``atoms'',
+which are unique 29-bit identifiers issued by the X server for string
+names.  This complexity is hidden by Emacs: when Lisp provides a
+symbol whose name is that of the atom, Emacs will request these
+identifiers without further intervention.
 
   When a program ``sets'' a selection under X, it actually makes
 itself the ``owner'' of the selection---the X server will then deliver
@@ -4125,27 +4135,29 @@ requesting client with the selection data.
 
   Similarly, a program does not ``get'' selection data from the X
 server.  Instead, its selection requests are sent to the client with
-the window which last took ownership over the selection, which then
-replies with the requested data.
+the window which last asserted ownership over the selection, which is
+expected to respond with the requested data.
 
-  Each selection request contains three parameters:
+  Each selection request incorporates three parameters:
 
 @itemize @bullet
 @item
-The window which requested the selection; this is used to identify the
+The window which requested the selection, which identifies the
 @c Not a typo: X spells ``requestor'' with an o.
 requesting program, otherwise known as the @dfn{requestor}.
 
 @item
-An atom identifying the ``target'' to which the owner should convert
+An atom identifying the @dfn{target} to which the owner should convert
 the selection.  It is easiest to think of the conversion target as the
 kind of data that the requestor wants: in selection requests made by
-Emacs, the target is determined by the @dfn{type} argument to
+Emacs, the target is determined by the @var{type} argument to
 @code{gui-get-selection}.
 
 @item
-A 32-bit timestamp containing the X server time at which the requestor
-last obtained input.
+A 32-bit timestamp representing the X server time at which the
+requestor last received input; this parameter is not relevant to Lisp
+code, for it's only meant to abet synchronization between the X
+server, owner and requestor.
 @end itemize
 
   The selection owner responds by tranferring to the requestor a
@@ -4156,31 +4168,30 @@ format and data type to convert the data transferred by 
the selection
 owner to a Lisp representation, which @code{gui-get-selection}
 returns.
 
-  By default, Emacs converts selection data consisting of any series
-of bytes to a unibyte string containing those bytes, selection data
-consisting of a single 16-bit or 32-bit word as an unsigned number,
-and selection data consisting of multiple such words as a vector of
-unsigned numbers.  However, Emacs applies special treatment for
-several selection data types:
+  Emacs converts selection data consisting of any series of bytes to a
+unibyte string holding those bytes, that consisting of a single 16-bit
+or 32-bit word as an unsigned number, and that consisting of multiple
+such words as a vector of unsigned numbers.  The exceptions to this
+general pattern are that Emacs applies special treatment for data from
+the following conversion targets:
 
 @table @code
 @item INTEGER
-16-bit or 32-bit words of this type are treated as signed integers,
-instead of unsigned ones.  If there are multiple words in the
-selection data, a vector is returned; otherwise, the integer is
-returned by itself.
+16-bit or 32-bit words of this type are treated as signed rather than
+unsigned integers.  If there are multiple words in the selection data,
+a vector is returned; otherwise, the integer is returned by itself.
 
 @item ATOM
 32-bit words of this type are treated as X atoms, and returned (either
-alone or as vectors) as Lisp symbols containing the names they
-identify.  Invalid atoms are returned as @code{nil}.
+alone or as vectors) as Lisp symbols by the names they identify.
+Invalid atoms are replaced by @code{nil}.
 
 @item COMPOUND_TEXT
 @item UTF8_STRING
 @item STRING
-Unibyte strings returned for these data types will have a single
-@code{foreign-selection} text property set to a symbol with the type
-of the selection data.
+A single @code{foreign-selection} text property set to the type of the
+selection data will be placed in unibyte strings derived from a
+request for these data types.
 @end table
 
   Each selection owner must return at least two selection targets:
@@ -4191,21 +4202,21 @@ number of other targets, some of which may be 
standardized by the X
 Consortium's
 @url{http://x.org/releases/X11R7.6/doc/xorg-docs/specs/ICCCM/icccm.html,
 Inter-Client Communication Conventions Manual}, while others, such as
-@code{UTF8_STRING}, were supposed to be standardized by the XFree86
-Project, which unfortunately did not happen.
+@code{UTF8_STRING}, were meant to be standardized by the XFree86
+Project, but their standardization was never completed.
 
   Requests for a given selection target may, by convention, return
 data in a specific type, or it may return data in one of several
 types, whichever is most convenient for the selection owner; the
 latter type of selection target is dubbed a @dfn{polymorphic target}.
-A selection target may also return no data at all: by convention, the
-selection owner performs some action a side effect upon responding to
-a selection request with that target, and as such these targets are
-referred to as @dfn{side-effect targets}.
+In response to a request, a selection target may also return no data
+at all, whereafter the selection owner executes some action as a side
+effect.  Targets that are thus replied to are termed @dfn{side-effect
+targets}.
 
-  Here are some selection targets which behave in a reasonably
-standard manner when used with the @code{CLIPBOARD}, @code{PRIMARY},
-or @code{SECONDARY} selections.
+  Here are some selection targets whose behavior is generally
+consistent with a standard when requested from the @code{CLIPBOARD},
+@code{PRIMARY}, or @code{SECONDARY} selections.
 
 @table @code
 @item ADOBE_PORTABLE_DOCUMENT_FORMAT
@@ -4271,7 +4282,7 @@ positions of the selection data in the text field 
containing it.
 
 @item MODULE
 This target returns the name of any function containing the selection
-data.  It is mainly used by text editors.
+data.  It is principally requested by text editors.
 
 @item STRING
 This target returns the selection data as a string of type
@@ -4303,17 +4314,18 @@ selection owner.
   When a request for the targets @code{STRING}, @code{COMPOUND_TEXT},
 or @code{UTF8_STRING} is made using the function
 @code{gui-get-selection}, and neither @code{selection-coding-system}
-nor @code{next-selection-coding-system} are set, the returned strings
-are additionally decoded using the appropriate coding system for those
-data types: @code{iso-8859-1}, @code{compound-text-with-extensions}
-and @code{utf-8} respectively.
+nor @code{next-selection-coding-system} is set, the resultant strings
+are decoded by the proper coding systems for those targets:
+@code{iso-8859-1}, @code{compound-text-with-extensions} and
+@code{utf-8} respectively.
 
   In addition to the targets specified above (and the many targets
 used by various programs for their own purposes), several popular
-programs and toolkits have decided to define selection data types of
-their own, without consulting the appropriate X standards bodies.
-These targets are usually named after MIME types, such as
-@code{text/html} or @code{image/jpeg}, and have been known to contain:
+programs and toolkits have defined selection data types of their own,
+without consulting the appropriate X standards bodies.  These targets
+are generally named after such MIME types as @code{text/html} or
+@code{image/jpeg}; they have been witnessed returning the following
+forms of data:
 
 @itemize @bullet
 @item
@@ -4324,54 +4336,56 @@ names of an image or text file.
 Image or text data in the appropriate format.
 
 @item
-@code{file://} URIs (or possibly newline or NUL terminated lists of
-URIs) leading to files in the appropriate format.
+@code{file://} URIs (or conceivably newline or NUL terminated lists of
+URIs) identifying files in the appropriate format.
 @end itemize
 
   These selection targets were first used by Netscape, but are now
-found in all kinds of programs, especially those based on recent
+proffered by all kinds of programs, especially those based on recent
 versions of the GTK+ or Qt toolkits.
 
-  Emacs is also capable of acting as a selection owner.  When
-@code{gui-set-selection} is called, the selection data specified is
-not transferred to the X server; instead, Emacs records it internally
-and obtains ownership of the selection.
+  Emacs is also capable of serving as a selection owner.  When
+@code{gui-set-selection} is called, the selection data provided is
+recorded internally and Emacs obtains ownership of the selection being
+set.
 
 @defvar selection-converter-alist
-  Alist of selection targets to ``selection converter'' functions.
-When a selection request is received, Emacs looks up the selection
-converter associated with the requested selection target.
+Alist of selection targets to ``selection converter'' functions.  When
+a selection request is received, Emacs looks up the selection
+converter pertaining to the requested selection target.
 
-  The selection converter is called with three arguments: the symbol
+Selection converters are called with three arguments: the symbol
 corresponding to the atom identifying the selection being requested,
 the selection target that is being requested, and the value set with
-@code{gui-set-selection}.  The value which it returns is either a cons
-of a symbol specifying the data type and a number, symbol, or a vector
-of numbers or symbols, or its cdr by itself.
+@code{gui-set-selection}.  The values which they must return are
+either conses of symbols designating the data type and numbers,
+symbols, vectors of numbers or symbols, or the cdrs of such conses by
+themselves.
 
-  If the value is the special symbol @code{NULL}, the data type is set
-to @code{NULL}, and no data is returned to the requestor.
+If a selection converter's value is the special symbol @code{NULL},
+the data type returned to its requestor is set to @code{NULL}, and no
+data is sent in response.
 
-  If the value is a string, it must be a unibyte string; should no
-data type be explicitly specified, the data is transferred to the
+If such a value is a string, it must be a unibyte string; should no
+data type be explicitly specified, the data is transferred to its
 requestor with the type @code{STRING}.
 
-  If the value is a symbol, its ``atom'' is retrieved, and it is
-transferred to the requestor as a 32-bit value---if no data type was
-specified, its type is @code{ATOM}.
+If it is a symbol, its ``atom'' is retrieved, and it is transferred to
+its requestor as a 32-bit value---if no data type is specified, its
+type is @code{ATOM}.
 
-  If the value is a number between @code{-32769} and @code{32768}, it
-is transferred to the requestor as a 16 bit value---if no data type
-was specified, its type is @code{INTEGER}.
+If it is a number between @code{-32769} and @code{32768}, it is
+transferred to its requestor as a 16 bit value---if no data type is
+specified, its type is @code{INTEGER}.
 
-  If the value is any other number, it is returned as a 32 bit value.
-Even if the number returned is unsigned, the requestor will treat
-words of type @code{INTEGER} as signed.  To return an unsigned value,
-specify the type @code{CARDINAL} instead.
+If it is any other number, it is accounted a 32 bit value.  Even if
+the number returned is unsigned, its requestor will treat words of
+type @code{INTEGER} as signed.  To return an unsigned value, specify
+the type @code{CARDINAL} in its place.
 
-  If the value is a vector of symbols or numbers, it is returned as a
-list of multiple atoms or numbers.  The data type returned by default
-is determined by that of its first element.
+If it is a vector of symbols or numbers, the response to its requestor
+will be a list of multiple atoms or numbers.  The data type returned
+when not expressly set is that of the list's first element.
 @end defvar
 
   By default, Emacs is configured with selection converters for the
@@ -4384,8 +4398,8 @@ This selection converter returns selection data as:
 @itemize @bullet
 @item
 A string of type @code{C_STRING}, if the selection contents contain no
-multibyte characters, or contains 8-bit characters with all 8 bits
-set.
+multibyte characters, or contain ``raw 8-bit bytes'' (@pxref{Text
+Representations}).
 
 @item
 A string of type @code{STRING}, if the selection contents can be
@@ -4481,7 +4495,7 @@ These selection converters are used for internal purposes.
 @end table
 
   With the exception of @code{INTEGER}, all selection converters
-expect the value given to @code{gui-set-selection} to be one of the
+expect the data provided to @code{gui-set-selection} to be one of the
 following:
 
 @itemize @bullet
@@ -4497,28 +4511,69 @@ bounds of the selection data in the buffer @var{buf}.
 @node Other Selections
 @subsection Other Selections
 
-  Window systems such as MS-Windows, Nextstep, Haiku and Android do
-not provide selections corresponding to the X semantics.  Each window
-system provides its own ad-hoc emulation of selections, none of which
-make use of the ``selection converter'' mechanism described above.  In
-addition, only the @code{PRIMARY}, @code{CLIPBOARD}, and
-@code{SECONDARY} selections are typically supported, alongside the
-@code{XdndSelection} used for drag-and-drop operations.
-
-  GTK itself exposes emulations of X selections to applications, but
-those emulations are of varying completeness.  While Emacs built with
-PGTK will use the same selection interface as Emacs built with X, many
+  Selections under such window systems as MS-Windows, Nextstep, Haiku
+and Android are not aligned with those under X@.  Each of these window
+system improvises its own selection mechanism without employing the
+``selection converter'' mechanism illustrated in the preceeding node.
+Only the @code{PRIMARY}, @code{CLIPBOARD}, and @code{SECONDARY}
+selections are generally supported, with the @code{XdndSelection}
+selection that records drag-and-drop data also available under
+Nextstep and Haiku.
+
+@cindex PGTK selections
+  GTK seeks to emulate the X selection system, but its emulations are
+not altogether dependable, with the overall quality of each subject to
+the GDK backend being used.  Therefore, Emacs built with PGTK will
+supply the same selection interface as Emacs built with X, but many
 selection targets will not be useful.
 
-  On MS-Windows, @code{gui-get-selection} accepts a single target,
-@code{STRING}.  The value returned is the selection data decoded
-using @code{selection-coding-system}.
-
-  @code{gui-set-selection} also only accepts strings, encodes them
-in the selection coding system, and saves them to the clipboard.
-
-  On Nextstep, Emacs only supports saving strings to selections.
-However, requests for the following targets are accepted:
+@cindex MS-Windows selection emulation
+@cindex MS-Windows primary and secondary selection
+  Although a clipboard exists, there is no concept of primary or
+secondary selections within the MS-Windows operating system.  On this
+system, Emacs simulates the presence of a primary and secondary
+selection, while saving to and retrieving from the clipboard when so
+requested.
+
+  The simulation of the primary and secondary selections is conducted
+by saving values supplied to @code{gui-set-selection} within the
+@code{x-selections} property of the symbol designating the pertinent
+selection, namely the @var{type} argument to @code{gui-get-selection}.
+Each subsequent call to @code{gui-get-selection} in turn returns its
+value, which is not subject to further examination (such as type
+checks and the like).  Under such circumstances, @var{data-type}
+argument is generally disregarded.  (But see below for the
+qualification regarding @code{TARGETS}.)
+
+@cindex MS-Windows clipboard
+  Where the clipboard selection is concerned (whenever @var{type} is
+@code{CLIPBOARD}), @code{gui-set-selection} verifies that the value
+provided is a string and saves it within the system clipboard once it
+is encoded by the coding system configured in
+@code{selection-coding-system}.  Callers of @code{gui-get-selection}
+are required to set @var{data-type} to either @code{STRING} or
+@code{TARGETS}.
+
+  When @var{data-type} is set to @code{TARGETS} in a call to
+@code{gui-get-selection}, a vector of symbols is returned when
+selection data exists, much as it is under X@.  It is impossible to
+request clipboard data in any format besides @code{STRING}, for the
+prerequisite data conversion routines are absent.  Just as strings
+saved into the clipboard are encoded by the
+@code{selection-coding-system}, so those read from the clipboard are
+decoded by that same coding system; this variable and its cousin
+@code{next-selection-coding-system} merit particular scrutiny when
+difficulties are encountered with saving selection text into the
+clipboard.
+
+@cindex Nextstep selections
+  All three selections standard in X exist in Nextstep as well, but
+Emacs is only capable of saving strings to such selections.
+Restrictions imposed upon calls to @code{gui-set-selection} there are
+much the same as those on MS-Windows, though text is uniformly encoded
+as @code{utf-8-unix} without regard to the value of
+@code{selection-coding-system}.  @code{gui-get-selection} is more
+charitable, and accepts requests for the following selection targets:
 
 @c FIXME: how is the text coding system determined, and do image/* or
 @c application/* return image data or file names?
@@ -4534,29 +4589,34 @@ However, requests for the following targets are 
accepted:
 @item image/tiff
 @end itemize
 
-  On Haiku, Emacs supports the same selection values as on X.  In
-addition, Emacs fully implements the primary and secondary selections.
-However, instead of taking ownership over the selection data, Emacs
-transfers the selection data to the window server when
-@code{gui-set-selection} is called.  The Haiku window server expects
-selection data to be provided in the form of a ``message'', containing
-associations between data types and selection data.
+  The @code{XdndSelection} selection is also present under Nextstep,
+in the form of a repository that records values supplied to
+@code{gui-set-selection}.  Its sole purpose is to save such values for
+the fundamental drag-and-drop function @code{x-begin-drag}
+(@pxref{Drag and Drop}); no guarantees exist concerning its value when
+read by anything else.
 
-@defvar haiku-normal-selection-encoders
-List of functions which act as selection encoders.  When
-@code{gui-set-selection} is called, each function in this list is
-successively called with its @var{selection} and @var{value}
-arguments.  If the function returns non-@code{nil}, it should return a
-list of the form @w{@code{(@var{key} @var{type} @var{value})}}, where
-@var{key} is the name of the data type being transferred, @var{type}
-is either a number identifying a data type (in which case @var{value}
-should be a unibyte string that is directly transferred to the window
-server), or a symbol identifying both a data type and how @var{value}
-should be interpreted.
-@end defvar
+@cindex Haiku selections
+  Selections on Haiku systems comprise all three selections customary
+under X and the @code{XdndSelection} that records drag-and-drop data.
+
+  When @code{gui-set-selection} is called for the former three
+selections, the data supplied is converted into a window server
+``message'' by a list of @dfn{selection encoder} functions, which is
+sent to the window server.
 
-  Here are the meaningful values of @var{type}, and what they will
-cause Emacs to interpret @var{value} as:
+@defvar haiku-normal-selection-encoders
+List of selection encoder functions.  When @code{gui-set-selection} is
+called, each function in this list is successively called with its
+@var{selection} and @var{value} arguments.  If such a function returns
+non-@code{nil}, its return value must be a list of the form
+@w{@code{(@var{key} @var{type} @var{value})}}.  In this list,
+@var{key} must be the name of the data being transferred, generally
+that of a MIME type, for example @samp{"text/plain"}, and @var{type}
+is a symbol or a number designating the type of the data; thus also
+governing the interpretation of @var{value}; following is a list of
+valid data types and how each of them will cause @var{value} to be
+interpreted.
 
 @table @code
 @item string
@@ -4564,8 +4624,8 @@ A unibyte string.  The string is NULL-terminated after 
being placed in
 the message.
 
 @item ref
-A file name.  The file is looked up and file system information
-identifying the file is placed in the message.
+A file name.  The file is located and the inode identifying the file
+is placed in the message.
 
 @item short
 A 16-bit integer value.
@@ -4598,141 +4658,214 @@ format.
 @item (haiku-numeric-enum MIME)
 A unibyte string containing data in a certain MIME type.
 @end table
+@end defvar
 
-  Under Haiku, @code{gui-get-selection} accepts either the targets
-@code{TARGETS} and @code{TIMESTAMP}, where the former returns a vector
-containing supported data types (much like on X), and the latter
-returns the number of times the selection has been set, the targets
-@code{STRING} and @code{UTF8_STRING}, which return text in ISO-Latin-1
-and UTF-8 format, or a MIME type, in which the data is returned
-undecoded as a unibyte string.
+  A call to @code{gui-get-selection} generally returns the the data
+named @var{data-type} within the selection message, albeit with
+@var{data-type} replaced by an alternative name should it be one of
+the following X selection targets:
 
-  Under Android, @code{gui-get-selection} is restricted to returning
-UTF-8 string data of the type @code{STRING}, or image and application
-data associated with a MIME type.  @code{gui-set-selection} will only
-set string data, as on MS-Windows.
+@table @code
+@item STRING
+This represents Latin-1 text under X: ``text/plain;charset=iso-8859-1''
+
+@item UTF8_STRING
+This represents UTF-8 text: ``text/plain''
+@end table
+
+  If @var{data-type} is a text type such as @code{STRING} or a MIME
+type matching the pattern @samp{`text/*}, the string data is decoded
+with the coding system apposite for it before being returned.
+
+  Furthermore, the two data types @var{TIMESTAMP} and @code{TARGETS}
+are afforded special treatment; the value returned for the first is
+the number of times the selection has been modified since system
+startup (@emph{not} a timestamp), and that for the other is a vector
+of available selection data types, as elsewhere.
+
+@cindex Android selections
+  Much like MS-Windows, Android provides a clipboard but no primary or
+secondary selection; @code{gui-set-selection} simulates the primary
+selection by saving the value supplied into a variable subsequent
+calls to @code{gui-get-selection} return.
+
+  From the clipboard, @code{gui-get-selection} is capable of returning
+UTF-8 string data of the type @code{STRING}, the @code{TAREGTS} data
+type, or image and application data of any MIME type.
+@code{gui-set-selection} sets only string data, much as under
+MS-Windows, although this data is not affected by the value of
+@code{selection-coding-system}.
 
 @node Yanking Media
 @section Yanking Media
 
-  If you choose, for instance, ``Copy Image'' in a web browser, that
-image is put onto the clipboard, and Emacs can access it via
-@code{gui-get-selection}.  But in general, inserting image data into
-an arbitrary buffer isn't very useful---you can't really do much with
-it by default.
-
-  So Emacs has a system to let modes register handlers for these
-``complicated'' selections.
+  Data saved within window system selections is not restricted to
+plain text.  It is possible for selection data to encompass images or
+other binary data of the like, as well as rich text content instanced
+by HTML, and also PostScript.  Since the selection data types incident
+to this data are at variance with those for plain text, the insertion
+of such data is facilitated by a set of functions dubbed
+@dfn{yank-media handlers}, which are registered by each major mode
+undertaking its insertion and called where warranted upon the
+execution of the @code{yank-media} command.
 
 @defun yank-media-handler types handler
-@var{types} can be a @acronym{MIME} media type symbol, a regexp to
-match these, or a list of these symbols and regexps.  For instance:
+Register a yank-media handler which applies to the current buffer.
+
+@var{types} can be a symbol designating a selection data type
+(@pxref{Accessing Selections}), a regexp against which such types are
+matched, or a list of these symbols and regexps.  For instance:
 
 @example
 (yank-media-handler 'text/html #'my-html-handler)
 (yank-media-handler "image/.*" #'my-image-handler)
 @end example
 
-A mode can register as many handlers as required.
-
-  The @var{handler} function is called with two parameters: The
-@acronym{MIME} media type symbol and the data (as a string).  The
-handler should then insert the object into the buffer, or save it, or
-do whatever is appropriate for the mode.
+When a selection offers a data type matching @var{types}, the function
+@var{handler} is called to insert its data, with the symbol
+designating the matching selection data type, and the data returned by
+@code{gui-get-selection}.
 @end defun
 
-  The @code{yank-media} command will consult the registered handlers in
-the current buffer, compare that with the available media types on the
-clipboard, and then pass on the matching selection to the handler (if
-any).  If there's more than one matching selection, the user is
-queried first.
-
-  The @code{yank-media-types} command can be used to explore the
-clipboard/primary selection.  It lists all the media types that are
-currently available, and can be handy when creating handlers---to see
-what data is actually available.  Some applications put a surprising
-amount of different data types on the clipboard.
+The @code{yank-media-types} command presents a list of selection data
+types that are currently available, which is useful when implementing
+yank-media handlers; for programs generally offer an eclectic and
+seldom consistent medley of data types.
 
 @node Drag and Drop
 @section Drag and Drop
 @cindex drag and drop
 
-  When the user drops something from another application over Emacs,
-Emacs will try to insert any text and open any URL that was dropped.
-If text was dropped, then it will always be inserted at the location
-of the mouse pointer where the drop happened, or saved in the kill
-ring if insertion failed, which could happen if the buffer was
-read-only.  If a URL was dropped instead, then Emacs will first try to
-call an appropriate handler function by matching the URL against
-regexps defined in the variable @code{dnd-protocol-alist}, and then
-against those defined in the variables @code{browse-url-handlers} and
-@code{browse-url-default-handlers}.  Should no suitable handler be
-located, Emacs will fall back to inserting the URL as plain text.
+  Data transferred by drag and drop is generally either plain text or
+a list of URLs designating files or other resources.  When text is
+dropped, it is inserted at the location of the drop, with recourse to
+saving it into the kill ring if that is not possible.
+
+  URLs dropped are supplied to pertinent @dfn{DND handler functions}
+in the variable @code{dnd-protocol-alist}, or alternatively ``URL
+handlers'' as set forth by the variables @code{browse-url-handlers}
+and @code{browse-url-default-handlers}; absent matching handlers of
+either type, they are treated as plain text and inserted in the
+buffer.
 
 @defvar dnd-protocol-alist
-  This variable is a list of cons cells of the form
-@w{@code{(@var{pattern} . @var{action})}}.  @var{pattern} is a regexp
-that URLs are matched against after being dropped.  @var{action} is a
-function that is called with two arguments, should a URL being dropped
-match @var{pattern}: the URL being dropped, and the action being
-performed for the drop, which is one of the symbols @code{copy},
-@code{move}, @code{link}, @code{private} or @code{ask}.
-
-If @var{action} is @var{private}, then it means the program that
-initiated the drop wants Emacs to perform an unspecified action with
-the URL; a reasonable action to perform in that case is to open the URL
-or copy its contents into the current buffer.  Otherwise, @var{action}
-has the same meaning as the @var{action} argument to
+This variable is an alist between regexps against which URLs are
+matched and DND handler functions called on the dropping of matching
+URLs.
+
+@cindex dnd-multiple-handler, a symbol property
+If a handler function is a symbol whose @code{dnd-multiple-handler}
+property (@pxref{Symbol Properties}) is set, then upon a drop it is
+given a list of every URL that matches its regexp; absent this
+property, it is called once for each of those URLs.  Following this
+first argument is one of the symbols @code{copy}, @code{move},
+@code{link}, @code{private} or @code{ask} identifying the action to be
+taken.
+
+If @var{action} is @code{private}, the program that initiated the drop
+does not insist on any particular behavior on the part of its
+recipient; a reasonable action to take in that case is to open the URL
+or copy its contents into the current buffer.  The other values of
+@var{action} imply much the same as in the @var{action} argument to
 @code{dnd-begin-file-drag}.
+
+Once its work completes, a handler function must return a symbol
+designating the action it took: either the action it was provided, or
+the symbol @code{private}, which communicates to the source of the
+drop that the action it prescribed has not been executed.
+
+When multiple handlers match an overlapping subset of items within a
+drop, the handler matched against by the greatest number of items is
+called to open that subset.  The items it is supplied are subsequently
+withheld from other handlers, even those they also match.
 @end defvar
 
 @cindex drag and drop, X
 @cindex drag and drop, other formats
-  Emacs implements receiving text and URLs individually for each
-window system, and does not by default support receiving other kinds
-of data as drops.  To support receiving other kinds of data, use the
-X-specific interface described below.
-
-@vindex x-dnd-test-function
-@vindex x-dnd-known-types
-  When a user drags something from another application over Emacs
-under the X Window System, that other application expects Emacs to
-tell it if Emacs understands the data being dragged.  The function in
-the variable @code{x-dnd-test-function} is called by Emacs to
-determine what to reply to any such inquiry.  The default value is
-@code{x-dnd-default-test-function}, which accepts drops if the type of
-the data to be dropped is present in @code{x-dnd-known-types}.
-Changing the variables @code{x-dnd-test-function} and
-@code{x-dnd-known-types} can make Emacs accept or reject drops based
-on some other criteria.
-
-@vindex x-dnd-types-alist
-  If you want to change the way Emacs receives drops of different data
-types, or you want to enable it to understand a new type, change the variable
-@code{x-dnd-types-alist}.  Doing so correctly requires detailed
-knowledge of what data types other applications use for drag and drop.
-
-  These data types are typically implemented as special data types
-that can be obtained from an X selection provided by the other
-application.  In most cases, they are either the same data types that
-are typically accepted by @code{gui-set-selection}, or MIME types,
-depending on the specific drag-and-drop protocol being used.  For
-example, the data type used for plain text may be either
-@code{"STRING"} or @code{"text/plain"}.
+  Emacs does not take measures to accept data besides text and URLs,
+for the window system interfaces which enable this are too far removed
+from each other to abstract over consistently.  Nor are DND handlers
+accorded influence over the actions they are meant to take, as
+particular drag-and-drop protocols deny recipients such control.  The
+X11 drag-and-drop implementation rests on several underlying protocols
+that make use of selection transfer and share much in common, to which
+low level access is provided through the following functions and
+variables:
+
+@defvar x-dnd-test-function
+This function is called to ascertain whether Emacs should accept a
+drop.  It is called with three arguments:
+
+@itemize @bullet
+@item
+The window under the item being dragged, which is to say the window
+whose buffer is to receive the drop.  If the item is situated over a
+non-window component of a frame (such as scroll bars, tool bars and
+things to that effect), the frame itself is provided in its place.
+
+@item
+One of the symbols @code{move}, @code{copy}, @code{link} or
+@code{ask}, representing an action to take on the item data suggested
+by the drop source.  These symbols carry the same implications as in
+@code{x-begin-drag}.
+
+@item
+A vector of selection data types (@pxref{X Selections}) the item
+provides.
+@end itemize
+
+This function must return @code{nil} to reject the drop or a cons of
+the action that will be taken (such as through transfer to a DND
+handler function) and the selection data type to be requested.  The
+action returned in that cons may also be the symbol @code{private},
+which intimates that the action taken is as yet indeterminate.
+@end defvar
+
+@defvar x-dnd-known-types
+Modifying @code{x-dnd-test-function} is generally unwarranted, for its
+default set of criteria for accepting a drop can be adjusted by
+changing this list of selection data types.  Each element is a string,
+which if found as the symbol name of an element within the list of
+data types by the default ``test function'', will induce that function
+to accept the drop.
+
+Introducing a new entry into this list is not useful unless a
+counterpart handler function is appended to @code{x-dnd-types-alist}.
+@end defvar
+
+@defvar x-dnd-types-alist
+This variable is an alist between strings designating selection data
+types and functions which are called when things of such types are
+dropped.
+
+Each such function is supplied three arguments; the first is the
+window or frame below the location of the drop, as in
+@code{x-dnd-test-function}; the second is the action to be taken,
+which may be any of the actions returned by test functions, and third
+is the selection data itself (@pxref{Accessing Selections}).
+@end defvar
+
+  Selection data types as provided by X11 drag-and-drop protocols are
+sometimes distinct from those provided by the ICCCM and conforming
+clipboard or primary selection owners.  Frequently, the name of a MIME
+type, such as @code{"text/plain;charset=utf-8"} (with discrepant
+capitalization of the ``utf-8''), is substitued for a standard X
+selection name such as @code{UTF8_STRING}.
 
 @cindex XDS
 @cindex direct save protocol
 @vindex x-dnd-direct-save-function
-  When Emacs runs on X window system, it supports the X Direct Save
-(@acronym{XDS}) protocol, which allows users to save a file by
-dragging and dropping it onto an Emacs window, such as a Dired window.
-To comply with the unique requirements of @acronym{XDS}, these
-drag-and-drop requests are processed specially: instead of being
-handled according to @code{x-dnd-types-alist}, they are handled by the
-@dfn{direct-save function} that is the value of the variable
-@code{x-dnd-direct-save-function}.  The value should be a function of
-two arguments, @var{need-name} and @var{filename}.  The @acronym{XDS}
-protocol uses a two-step procedure for dragging files:
+  The X Direct Save (@acronym{XDS}) protocol enables programs to
+devolve responsibility for naming a dropped file upon the recipient.
+When such a drop transpires, DND handlers and the foregoing X-specific
+interface are largely circumvented, tasking a different function with
+responding to the drop.
+
+@defvar x-dnd-direct-save-function
+This variable should be set to a function that registers and names
+files dropped using the @acronym{XDS} protocol in a two-step
+procedure.  It is provided two arguments, @var{need-name} and
+@var{filename}.
 
 @enumerate 1
 @item
@@ -4760,8 +4893,9 @@ Dired should update the directory on display by showing 
the new file
 there.
 @end enumerate
 
-The default value of @code{x-dnd-direct-save-function} is
+Its default @code{x-dnd-direct-save-function} is
 @code{x-dnd-save-direct}.
+@end defvar
 
 @defun x-dnd-save-direct need-name filename
 When called with the @var{need-name} argument non-@code{nil}, this
@@ -4787,48 +4921,47 @@ default directory.)
 @end defun
 
 @cindex initiating drag-and-drop
-  On capable window systems, Emacs also supports dragging contents
-from its frames to windows of other applications.
+  It is also possible to drag content from Emacs to other programs
+when this is supported by the current window-system.  The functions
+which provide for this are as follows:
 
 @cindex drop target, in drag-and-drop operations
 @defun dnd-begin-text-drag text &optional frame action allow-same-frame
-This function begins dragging text from @var{frame} to another program
-(known as the @dfn{drop target}), and returns the result of
-drag-and-drop operation when the text is dropped or the drag-and-drop
-operation is canceled.  @var{text} is the text that will be inserted
-by the drop target.
+This function starts a drag-and-drop operation from @var{frame} to
+another program (dubbed the @dfn{drop target}), and returns when
+@var{text} is dropped or the operation is canceled.
 
 @var{action} must be one of the symbols @code{copy} or @code{move},
 where @code{copy} means that @var{text} should be inserted by the drop
-target, and @code{move} means the same as @code{copy}, but in addition
-the caller may have to delete @var{text} from its source as explained
+target, and @code{move} means the same as @code{copy}, but the caller
+must also delete @var{text} from its source as explained in the list
 below.
 
 @var{frame} is the frame where the mouse is currently held down, or
-@code{nil}, which means to use the selected frame.  This function may
-return immediately if no mouse buttons are held down, so it should be
-only called immediately after a @code{down-mouse-1} or similar event
-(@pxref{Mouse Events}), with @var{frame} set to the frame where that
-event was generated (@pxref{Click Events}).
+@code{nil}, which means to use the selected frame.  Since this
+function might return promptly if no mouse buttons are held down, it
+should be only called in response to a @code{down-mouse-1} or
+analogous event (@pxref{Mouse Events}), with @var{frame} set to the
+frame where that event was generated (@pxref{Click Events}).
 
-@var{allow-same-frame} specifies whether or not drops on top of
-@var{frame} itself are to be ignored.
+If @var{allow-same-frame} is @code{nil}, drops on top of @var{frame}
+will be ignored.
 
-The return value specifies the action that the drop target actually
-performed, and optionally what the caller should do.  It can be one of
-the following symbols:
+The return value reflects the action that the drop target actually
+performed, and thus also what action, if any, the caller should in
+turn take.  It is one of the following symbols:
 
 @table @code
 @item copy
 The drop target inserted the dropped text.
 
 @item move
-The drop target inserted the dropped text, but in addition the caller
-should delete @var{text} from wherever it originated, such as its
-buffer.
+The drop target inserted the dropped text, and the caller should
+delete @var{text} from the buffer where it was extracted from, if
+applicable.
 
 @item private
-The drop target performed some other unspecified action.
+The drop target took some other unspecified action.
 
 @item nil
 The drag-and-drop operation was canceled.
@@ -4837,11 +4970,12 @@ The drag-and-drop operation was canceled.
 @end defun
 
 @defun dnd-begin-file-drag file &optional frame action allow-same-frame
-This function begins dragging @var{file} from @var{frame} to another
-program, and returns the result of the drag-and-drop operation when
-the file is dropped or the drag-and-drop operation is canceled.
+This function starts a drag-and-drop operation from @var{frame} to
+another program (dubbed the @dfn{drop target}), and returns when
+@var{file} is dropped or the operation is canceled.
 
-If @var{file} is a remote file, then a temporary copy will be made.
+If @var{file} is a remote file, then a temporary local copy will be
+made.
 
 @var{action} must be one of the symbols @code{copy}, @code{move} or
 @code{link}, where @code{copy} means that @var{file} should be opened
@@ -4850,11 +4984,11 @@ move the file to another location, and @code{link} 
means the drop
 target should create a symbolic link to @var{file}.  It is an error to
 specify @code{link} as the action if @var{file} is a remote file.
 
-@var{frame} and @var{allow-same-frame} have the same meaning as in
-@code{dnd-begin-text-drag}.
+@var{frame} and @var{allow-same-frame} mean the same as they do in
+calls to @code{dnd-begin-text-drag}.
 
 The return value is the action that the drop target actually
-performed, which can be one of the following symbols:
+performed, which is one of the following symbols:
 
 @table @code
 @item copy
@@ -4883,19 +5017,18 @@ dropping multiple files, then the first file will be 
used instead.
 @end defun
 
 @defun dnd-direct-save file name &optional frame allow-same-frame
-This function is similar to @code{dnd-begin-file-drag} (with the
-default action of copy), but instead of specifying the action you
-specify the name of the copy created by the target program in
-@code{name}.
+The behavior of this function is akin to that of
+@code{dnd-begin-file-drag} (when the default action @code{copy} is
+used), except that it accepts a name under which the copy is meant to
+be filed.
 @end defun
 
 @cindex initiating drag-and-drop, low-level
   The high-level interfaces described above are implemented on top of
-a lower-level primitive.  If you need to drag content other than files
-or text, use the low-level interface @code{x-begin-drag}
-instead.  However, using it will require detailed knowledge of the
-data types and actions used by the programs to transfer content via
-drag-and-drop on each platform you want to support.
+a lower-level primitive.  The low-level interface @code{x-begin-drag}
+is also available for dragging content besides text and files.  It
+demands detailed knowledge of the data types and actions understood by
+programs on each platform its callers wish to support.
 
 @defun x-begin-drag targets &optional action frame return-frame 
allow-current-frame follow-tooltip
 This function begins a drag from @var{frame}, and returns when the
@@ -4907,60 +5040,59 @@ non-@code{nil}.  If no mouse buttons are held down when 
the
 drag-and-drop operation begins, this function may immediately return
 @code{nil}.
 
-@var{targets} is a list of strings describing selection targets, much
-like the @var{data-type} argument to @code{gui-get-selection}, that
-the drop target can request from Emacs (@pxref{Window System
+@var{targets} is a list of strings representing selection targets,
+much like the @var{data-type} argument to @code{gui-get-selection},
+that the drop target can request from Emacs (@pxref{Window System
 Selections}).
 
-@var{action} is a symbol describing the action recommended to the
-target.  It can either be @code{XdndActionCopy}, which
-means to copy the contents of the selection @code{XdndSelection} to
-the drop target; or @code{XdndActionMove}, which means copy as with
-@code{XdndActionCopy}, and in addition the caller should delete
-whatever was stored in that selection after copying it.
+@var{action} is a symbol designating the action recommended to the
+target.  It can either be @code{XdndActionCopy} or
+@code{XdndActionMove}; both imply copying the contents of the
+selection @code{XdndSelection} to the drop target, but the latter
+moreover conveys a promise to delete the contents of the selection
+after the copying.
 
 @var{action} may also be an alist which associates between symbols
-describing the available actions, and strings that the drop target is
-expected to present to the user to choose between the available
-actions.
+representing available actions, and strings that the drop target
+presents to the user for him to select between those actions.
 
 If @var{return-frame} is non-@code{nil} and the mouse moves over an
 Emacs frame after first moving out of @var{frame}, then the frame to
 which the mouse moves will be returned immediately.  If
-@var{return-frame} is the symbol @code{now}, then any frame underneath
+@var{return-frame} is the symbol @code{now}, then any frame beneath
 the mouse pointer will be returned without waiting for the mouse to
 first move out of @var{frame}.  @var{return-frame} is useful when you
 want to treat dragging content from one frame to another specially,
-while also being able to drag content to other programs, but it is not
-guaranteed to work on all systems and with all window managers.
+while also dragging content to other programs, but it is not
+guaranteed to function on all systems and with all window managers.
 
 If @var{follow-tooltip} is non-@code{nil}, the position of any tooltip
-(such as one shown by @code{tooltip-show}) will follow the location of
-the mouse pointer whenever it moves during the drag-and-drop
+(such as one displayed by @code{tooltip-show}) will follow the
+location of the mouse pointer as it moves during the drag-and-drop
 operation.  The tooltip will be hidden once all mouse buttons are
 released.
 
 If the drop was rejected or no drop target was found, this function
-returns @code{nil}.  Otherwise, it returns a symbol describing the
-action the target chose to perform, which can differ from @var{action}
-if that isn't supported by the drop target.  @code{XdndActionPrivate}
-is also a valid return value in addition to @code{XdndActionCopy} and
-@code{XdndActionMove}; it means that the drop target chose to perform
-an unspecified action, and no further processing is required by the
-caller.
-
-The caller must cooperate with the target to fully perform the action
-chosen by the target.  For example, callers should delete the buffer
-text that was dragged if this function returns @code{XdndActionMove}.
+returns @code{nil}.  Otherwise, it returns a symbol representing the
+action the target opted to take, which can differ from @var{action} if
+that isn't supported by the drop target.  @code{XdndActionPrivate} is
+also a valid return value in addition to @code{XdndActionCopy} and
+@code{XdndActionMove}; it suggests that the drop target opted for an
+indeterminate action, and no further action is required of the caller.
+
+The caller must cooperate with the target to complete the action
+selected by the target.  For example, callers should delete any buffer
+text that was dragged if this function returns @code{XdndActionMove},
+and likewise for other drag data where comparable criteria apply.
 @end defun
 
 @cindex drag and drop protocols, X
 
-  On X Windows, several different drag-and-drop protocols are
-supported by @code{x-begin-drag}.  When dragging content that is known
-to not be supported by a specific drag-and-drop protocol, it might be
-desirable to turn that protocol off, by changing the values of the
-following variables:
+  The function @code{x-begin-drag} leverages several drag-and-drop
+protocols ``behind the scenes''.  When dragging content that is known
+to not be supported by a specific drag-and-drop protocol, that
+protocol can be disabled by changing the values of the following
+variables:
 
 @defvar x-dnd-disable-motif-protocol
 When this is non-@code{nil}, the Motif drag and drop protocols are
@@ -4984,8 +5116,8 @@ events and the primary selection to insert the text if 
the drop target
 doesn't support any drag-and-drop protocol at all.
 
 A side effect is that Emacs will become the owner of the primary
-selection upon such a drop.  If that is not desired, then the drop
-emulation can be disabled by setting this variable to @code{nil}.
+selection upon such a drop.  Such emulation can be disabled by setting
+this variable to @code{nil}.
 @end defvar
 
 @node Color Names
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 00148420893..f365d88fade 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -4149,7 +4149,7 @@ it add meta information to it.  The @code{:language} 
keyword declares
 name of @var{query}.  Users can control which features are enabled
 with @code{treesit-font-lock-level} and
 @code{treesit-font-lock-feature-list} (described below).  These two
-keywords are mandatory.
+keywords are mandatory (with exceptions).
 
 Other keywords are optional:
 
@@ -4161,6 +4161,9 @@ Other keywords are optional:
 @item @tab @code{append} @tab Append the new face to existing ones
 @item @tab @code{prepend} @tab Prepend the new face to existing ones
 @item @tab @code{keep} @tab Fill-in regions without an existing face
+@item @code{:default-language} @tab @var{language}
+@tab Every @var{query} after this keyword will use @var{language}
+by default.
 @end multitable
 
 Lisp programs mark patterns in @var{query} with capture names (names
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 7d11db49def..d05b0b36475 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -1508,9 +1508,12 @@ has been capitalized.  This means that the first 
character of each
 word is converted to upper case, and the rest are converted to lower
 case.
 
+@vindex case-symbols-as-words
 The definition of a word is any sequence of consecutive characters that
 are assigned to the word constituent syntax class in the current syntax
-table (@pxref{Syntax Class Table}).
+table (@pxref{Syntax Class Table}); if @code{case-symbols-as-words}
+is non-nil, characters assigned to the symbol constituent syntax
+class are also considered as word constituent.
 
 When @var{string-or-char} is a character, this function does the same
 thing as @code{upcase}.
@@ -1540,9 +1543,9 @@ letters other than the initials.  It returns a new string 
whose
 contents are a copy of @var{string-or-char}, in which each word has
 had its initial letter converted to upper case.
 
-The definition of a word is any sequence of consecutive characters that
-are assigned to the word constituent syntax class in the current syntax
-table (@pxref{Syntax Class Table}).
+The definition of a word for this function is the same as described
+for @code{capitalize} above, and @code{case-symbols-as-words} has the
+same effect on word constituent characters.
 
 When the argument to @code{upcase-initials} is a character,
 @code{upcase-initials} has the same result as @code{upcase}.
diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi
index f594d684338..6128fef5d99 100644
--- a/doc/lispref/tips.texi
+++ b/doc/lispref/tips.texi
@@ -97,7 +97,7 @@ alternative common prefixes, so long as they make sense.
 @item
 We recommend enabling @code{lexical-binding} in new code, and
 converting existing Emacs Lisp code to enable @code{lexical-binding}
-if it doesn't already.  @xref{Using Lexical Binding}.
+if it doesn't already.  @xref{Selecting Lisp Dialect}.
 
 @item
 Put a call to @code{provide} at the end of each separate Lisp file.
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index dea35a04d4f..f575b188fc6 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -976,184 +976,57 @@ Variables}).  This section describes exactly what this 
means.
 binding can be accessed.  @dfn{Extent} refers to @emph{when}, as the
 program is executing, the binding exists.
 
-@cindex dynamic binding
-@cindex dynamic scope
-@cindex dynamic extent
-  By default, the local bindings that Emacs creates are @dfn{dynamic
-bindings}.  Such a binding has @dfn{dynamic scope}, meaning that any
-part of the program can potentially access the variable binding.  It
-also has @dfn{dynamic extent}, meaning that the binding lasts only
-while the binding construct (such as the body of a @code{let} form) is
-being executed.
-
 @cindex lexical binding
 @cindex lexical scope
 @cindex indefinite extent
-  Emacs can optionally create @dfn{lexical bindings}.  A lexical
-binding has @dfn{lexical scope}, meaning that any reference to the
-variable must be located textually within the binding
+  For historical reasons, there are two dialects of Emacs Lisp,
+selected via the @code{lexical-binding} buffer-local variable.
+In the modern Emacs Lisp dialect, local bindings are lexical by default.
+A @dfn{lexical binding} has @dfn{lexical scope}, meaning that any
+reference to the variable must be located textually within the binding
 construct@footnote{With some exceptions; for instance, a lexical
 binding can also be accessed from the Lisp debugger.}.  It also has
 @dfn{indefinite extent}, meaning that under some circumstances the
 binding can live on even after the binding construct has finished
-executing, by means of special objects called @dfn{closures}.
+executing, by means of objects called @dfn{closures}.
 
-  The dynamic binding was (and still is) the default in Emacs for many
-years, but lately Emacs is moving towards using lexical binding in
-more and more places, with the goal of eventually making that the
-default.
+@cindex dynamic binding
+@cindex dynamic scope
+@cindex dynamic extent
+  Local bindings can also be dynamic, which they always are in the
+old Emacs Lisp dialect and optionally in the modern dialect.
+A @dfn{dynamic binding} has @dfn{dynamic scope}, meaning that any
+part of the program can potentially access the variable binding.  It
+also has @dfn{dynamic extent}, meaning that the binding lasts only
+while the binding construct (such as the body of a @code{let} form) is
+being executed.
 
-  The following subsections describe dynamic binding and lexical
+  The old dynamic-only Emacs Lisp dialect is still the default in code
+loaded or evaluated from Lisp files that lack a dialect declaration.
+Eventually the modern dialect will be made the default.
+All Lisp files should declare the dialect used to ensure that they
+keep working correctly in the future.
+
+  The following subsections describe lexical binding and dynamic
 binding in greater detail, and how to enable lexical binding in Emacs
 Lisp programs.
 
 @menu
-* Dynamic Binding::         The default for binding local variables in Emacs.
+* Lexical Binding::         The standard type of local variable binding.
+* Dynamic Binding::         A different type of local variable binding.
 * Dynamic Binding Tips::    Avoiding problems with dynamic binding.
-* Lexical Binding::         A different type of local variable binding.
-* Using Lexical Binding::   How to enable lexical binding.
+* Selecting Lisp Dialect::   How to select the Emacs Lisp dialect to use.
 * Converting to Lexical Binding:: Convert existing code to lexical binding.
 @end menu
 
-@node Dynamic Binding
-@subsection Dynamic Binding
-
-  By default, the local variable bindings made by Emacs are dynamic
-bindings.  When a variable is dynamically bound, its current binding
-at any point in the execution of the Lisp program is simply the most
-recently-created dynamic local binding for that symbol, or the global
-binding if there is no such local binding.
-
-  Dynamic bindings have dynamic scope and extent, as shown by the
-following example:
-
-@example
-@group
-(defvar x -99)  ; @r{@code{x} receives an initial value of @minus{}99.}
-
-(defun getx ()
-  x)            ; @r{@code{x} is used free in this function.}
-
-(let ((x 1))    ; @r{@code{x} is dynamically bound.}
-  (getx))
-     @result{} 1
-
-;; @r{After the @code{let} form finishes, @code{x} reverts to its}
-;; @r{previous value, which is @minus{}99.}
-
-(getx)
-     @result{} -99
-@end group
-@end example
-
-@noindent
-The function @code{getx} refers to @code{x}.  This is a @dfn{free}
-reference, in the sense that there is no binding for @code{x} within
-that @code{defun} construct itself.  When we call @code{getx} from
-within a @code{let} form in which @code{x} is (dynamically) bound, it
-retrieves the local value (i.e., 1).  But when we call @code{getx}
-outside the @code{let} form, it retrieves the global value (i.e.,
-@minus{}99).
-
-  Here is another example, which illustrates setting a dynamically
-bound variable using @code{setq}:
-
-@example
-@group
-(defvar x -99)      ; @r{@code{x} receives an initial value of @minus{}99.}
-
-(defun addx ()
-  (setq x (1+ x)))  ; @r{Add 1 to @code{x} and return its new value.}
-
-(let ((x 1))
-  (addx)
-  (addx))
-     @result{} 3           ; @r{The two @code{addx} calls add to @code{x} 
twice.}
-
-;; @r{After the @code{let} form finishes, @code{x} reverts to its}
-;; @r{previous value, which is @minus{}99.}
-
-(addx)
-     @result{} -98
-@end group
-@end example
-
-  Dynamic binding is implemented in Emacs Lisp in a simple way.  Each
-symbol has a value cell, which specifies its current dynamic value (or
-absence of value).  @xref{Symbol Components}.  When a symbol is given
-a dynamic local binding, Emacs records the contents of the value cell
-(or absence thereof) in a stack, and stores the new local value in the
-value cell.  When the binding construct finishes executing, Emacs pops
-the old value off the stack, and puts it in the value cell.
-
-  Note that when code using Dynamic Binding is native compiled the
-native compiler will not perform any Lisp specific optimization.
-
-@node Dynamic Binding Tips
-@subsection Proper Use of Dynamic Binding
-
-  Dynamic binding is a powerful feature, as it allows programs to
-refer to variables that are not defined within their local textual
-scope.  However, if used without restraint, this can also make
-programs hard to understand.  There are two clean ways to use this
-technique:
-
-@itemize @bullet
-@item
-If a variable has no global definition, use it as a local variable
-only within a binding construct, such as the body of the @code{let}
-form where the variable was bound.  If this convention is followed
-consistently throughout a program, the value of the variable will not
-affect, nor be affected by, any uses of the same variable symbol
-elsewhere in the program.
-
-@item
-Otherwise, define the variable with @code{defvar}, @code{defconst}
-(@pxref{Defining Variables}), or @code{defcustom} (@pxref{Variable
-Definitions}).  Usually, the definition should be at top-level in an
-Emacs Lisp file.  As far as possible, it should include a
-documentation string which explains the meaning and purpose of the
-variable.  You should also choose the variable's name to avoid name
-conflicts (@pxref{Coding Conventions}).
-
-Then you can bind the variable anywhere in a program, knowing reliably
-what the effect will be.  Wherever you encounter the variable, it will
-be easy to refer back to the definition, e.g., via the @kbd{C-h v}
-command (provided the variable definition has been loaded into Emacs).
-@xref{Name Help,,, emacs, The GNU Emacs Manual}.
-
-For example, it is common to use local bindings for customizable
-variables like @code{case-fold-search}:
-
-@example
-@group
-(defun search-for-abc ()
-  "Search for the string \"abc\", ignoring case differences."
-  (let ((case-fold-search t))
-    (re-search-forward "abc")))
-@end group
-@end example
-@end itemize
-
 @node Lexical Binding
 @subsection Lexical Binding
 
-  Lexical binding was introduced to Emacs, as an optional feature, in
-version 24.1.  We expect its importance to increase with time.
-Lexical binding opens up many more opportunities for optimization, so
-programs using it are likely to run faster in future Emacs versions.
-Lexical binding is also more compatible with concurrency, which was
-added to Emacs in version 26.1.
-
-  A lexically-bound variable has @dfn{lexical scope}, meaning that any
+Lexical binding is only available in the modern Emacs Lisp dialect.
+(@xref{Selecting Lisp Dialect}.)
+A lexically-bound variable has @dfn{lexical scope}, meaning that any
 reference to the variable must be located textually within the binding
 construct.  Here is an example
-@iftex
-(see the next subsection, for how to actually enable lexical binding):
-@end iftex
-@ifnottex
-(@pxref{Using Lexical Binding}, for how to actually enable lexical binding):
-@end ifnottex
 
 @example
 @group
@@ -1186,17 +1059,6 @@ wants the current value of a variable, it looks first in 
the lexical
 environment; if the variable is not specified in there, it looks in
 the symbol's value cell, where the dynamic value is stored.
 
-  (Internally, the lexical environment is a list whose members are
-usually cons cells that are symbol-value pairs, but some of its
-members can be symbols rather than cons cells.  A symbol in the list
-means the lexical environment declared that symbol's variable as
-locally considered to be dynamically bound.  This list can be passed
-as the second argument to the @code{eval} function, in order to
-specify a lexical environment in which to evaluate a form.
-@xref{Eval}.  Most Emacs Lisp programs, however, should not interact
-directly with lexical environments in this way; only specialized
-programs like debuggers.)
-
 @cindex closures, example of using
   Lexical bindings have indefinite extent.  Even after a binding
 construct has finished executing, its lexical environment can be
@@ -1249,37 +1111,74 @@ functions which take a symbol argument (like 
@code{symbol-value},
 variable's dynamic binding (i.e., the contents of its symbol's value
 cell).
 
-@node Using Lexical Binding
-@subsection Using Lexical Binding
+@node Dynamic Binding
+@subsection Dynamic Binding
 
-  When loading an Emacs Lisp file or evaluating a Lisp buffer, lexical
-binding is enabled if the buffer-local variable @code{lexical-binding}
-is non-@code{nil}:
+  Local variable bindings are dynamic in the modern Lisp dialect for
+special variables (see below), and for all variables in the old Lisp
+dialect.  (@xref{Selecting Lisp Dialect}.)
+Dynamic variable bindings have their uses but are in general more
+error-prone and less efficient than lexical bindings, and the compiler
+is less able to find mistakes in code using dynamic bindings.
 
-@defvar lexical-binding
-If this buffer-local variable is non-@code{nil}, Emacs Lisp files and
-buffers are evaluated using lexical binding instead of dynamic
-binding.  (However, special variables are still dynamically bound; see
-below.)  If @code{nil}, dynamic binding is used for all local
-variables.  This variable is typically set for a whole Emacs Lisp
-file, as a file local variable (@pxref{File Local Variables}).
-Note that unlike other such variables, this one must be set in the
-first line of a file.
-@end defvar
+  When a variable is dynamically bound, its current binding
+at any point in the execution of the Lisp program is simply the most
+recently-created dynamic local binding for that symbol, or the global
+binding if there is no such local binding.
+
+  Dynamic bindings have dynamic scope and extent, as shown by the
+following example:
+
+@example
+@group
+(defvar x -99)  ; @r{@code{x} receives an initial value of @minus{}99.}
+
+(defun getx ()
+  x)            ; @r{@code{x} is used free in this function.}
+
+(let ((x 1))    ; @r{@code{x} is dynamically bound.}
+  (getx))
+     @result{} 1
+
+;; @r{After the @code{let} form finishes, @code{x} reverts to its}
+;; @r{previous value, which is @minus{}99.}
+
+(getx)
+     @result{} -99
+@end group
+@end example
 
 @noindent
-When evaluating Emacs Lisp code directly using an @code{eval} call,
-lexical binding is enabled if the @var{lexical} argument to
-@code{eval} is non-@code{nil}.  @xref{Eval}.
+The function @code{getx} refers to @code{x}.  This is a @dfn{free}
+reference, in the sense that there is no binding for @code{x} within
+that @code{defun} construct itself.  When we call @code{getx} from
+within a @code{let} form in which @code{x} is (dynamically) bound, it
+retrieves the local value (i.e., 1).  But when we call @code{getx}
+outside the @code{let} form, it retrieves the global value (i.e.,
+@minus{}99).
 
-@findex eval-expression@r{, and }lexical-binding
-Lexical binding is also enabled in Lisp Interaction and IELM mode,
-used in the @file{*scratch*} and @file{*ielm*} buffers, and also when
-evaluating expressions via @kbd{M-:} (@code{eval-expression}) and when
-processing the @option{--eval} command-line options of Emacs
-(@pxref{Action Arguments,,, emacs, The GNU Emacs Manual}) and
-@command{emacsclient} (@pxref{emacsclient Options,,, emacs, The GNU
-Emacs Manual}).
+  Here is another example, which illustrates setting a dynamically
+bound variable using @code{setq}:
+
+@example
+@group
+(defvar x -99)      ; @r{@code{x} receives an initial value of @minus{}99.}
+
+(defun addx ()
+  (setq x (1+ x)))  ; @r{Add 1 to @code{x} and return its new value.}
+
+(let ((x 1))
+  (addx)
+  (addx))
+     @result{} 3           ; @r{The two @code{addx} calls add to @code{x} 
twice.}
+
+;; @r{After the @code{let} form finishes, @code{x} reverts to its}
+;; @r{previous value, which is @minus{}99.}
+
+(addx)
+     @result{} -98
+@end group
+@end example
 
 @cindex special variables
   Even when lexical binding is enabled, certain variables will
@@ -1329,6 +1228,111 @@ for those that are only special in the current lexical 
scope.
   The use of a special variable as a formal argument in a function is
 not supported.
 
+  Dynamic binding is implemented in Emacs Lisp in a simple way.  Each
+symbol has a value cell, which specifies its current dynamic value (or
+absence of value).  @xref{Symbol Components}.  When a symbol is given
+a dynamic local binding, Emacs records the contents of the value cell
+(or absence thereof) in a stack, and stores the new local value in the
+value cell.  When the binding construct finishes executing, Emacs pops
+the old value off the stack, and puts it in the value cell.
+
+@node Dynamic Binding Tips
+@subsection Proper Use of Dynamic Binding
+
+  Dynamic binding is a powerful feature, as it allows programs to
+refer to variables that are not defined within their local textual
+scope.  However, if used without restraint, this can also make
+programs hard to understand.
+
+First, choose the variable's name to avoid name conflicts
+(@pxref{Coding Conventions}).
+
+@itemize @bullet
+@item
+If the variable is only used when locally bound to a value, declare it
+special using a @code{defvar} form without an initial value, and never
+assign to it unless it is already bound.  This way, any attempt to
+refer to the variable when unbound will result in a
+@code{void-variable} error.
+
+@item
+Otherwise, define the variable with @code{defvar}, @code{defconst}
+(@pxref{Defining Variables}), or @code{defcustom} (@pxref{Variable
+Definitions}).  Usually, the definition should be at top-level in an
+Emacs Lisp file.  As far as possible, it should include a
+documentation string which explains the meaning and purpose of the
+variable.
+
+Then you can bind the variable anywhere in a program, knowing reliably
+what the effect will be.  Wherever you encounter the variable, it will
+be easy to refer back to the definition, e.g., via the @kbd{C-h v}
+command (provided the variable definition has been loaded into Emacs).
+@xref{Name Help,,, emacs, The GNU Emacs Manual}.
+
+For example, it is common to use local bindings for customizable
+variables like @code{case-fold-search}:
+
+@example
+@group
+(defun search-for-abc ()
+  "Search for the string \"abc\", ignoring case differences."
+  (let ((case-fold-search t))
+    (re-search-forward "abc")))
+@end group
+@end example
+@end itemize
+
+@node Selecting Lisp Dialect
+@subsection Selecting Lisp Dialect
+
+  When loading an Emacs Lisp file or evaluating a Lisp buffer, the
+Lisp dialect is selected using the buffer-local variable
+@code{lexical-binding}.
+
+@defvar lexical-binding
+If this buffer-local variable is non-@code{nil}, Emacs Lisp files and
+buffers are evaluated using the modern Lisp dialect that by default
+uses lexical binding instead of dynamic binding.  If @code{nil}, the
+old dialect is used that uses dynamic binding for all local variables.
+This variable is typically set for a whole Emacs Lisp file, as a
+file-local variable (@pxref{File Local Variables}).  Note that unlike
+other such variables, this one must be set in the first line of a
+file.
+@end defvar
+
+@noindent
+In practice, dialect selection means that the first line in an Emacs
+Lisp file looks like:
+
+@example
+;;; ...  -*- lexical-binding: t -*-
+@end example
+
+@noindent
+for the modern lexical-binding dialect, and
+
+@example
+;;; ...  -*- lexical-binding: nil -*-
+@end example
+
+@noindent
+for the old dynamic-only dialect.  When no declaration is present the
+old dialect is used, but this may change in a future release.
+The compiler will warn if no declaration is present.
+
+When evaluating Emacs Lisp code directly using an @code{eval} call,
+lexical binding is enabled if the @var{lexical} argument to
+@code{eval} is non-@code{nil}.  @xref{Eval}.
+
+@findex eval-expression@r{, and }lexical-binding
+Lexical binding is also enabled in Lisp Interaction and IELM mode,
+used in the @file{*scratch*} and @file{*ielm*} buffers, and also when
+evaluating expressions via @kbd{M-:} (@code{eval-expression}) and when
+processing the @option{--eval} command-line options of Emacs
+(@pxref{Action Arguments,,, emacs, The GNU Emacs Manual}) and
+@command{emacsclient} (@pxref{emacsclient Options,,, emacs, The GNU
+Emacs Manual}).
+
 @node Converting to Lexical Binding
 @subsection Converting to Lexical Binding
 
diff --git a/doc/man/ChangeLog.1 b/doc/man/ChangeLog.1
index ccc53810547..71662625fb9 100644
--- a/doc/man/ChangeLog.1
+++ b/doc/man/ChangeLog.1
@@ -74,7 +74,7 @@
 
        * emacs.1: Small fixes.
 
-2010-10-12  Ulrich Mueller  <ulm@gentoo.org>
+2010-10-12  Ulrich Müller  <ulm@gentoo.org>
 
        * emacs.1: Update license description.
 
@@ -82,7 +82,7 @@
 
        * b2m.1: Remove file.
 
-2010-09-25  Ulrich Mueller  <ulm@gentoo.org>
+2010-09-25  Ulrich Müller  <ulm@gentoo.org>
 
        * etags.1: xz compression is now supported.
 
diff --git a/doc/man/emacsclient.1 b/doc/man/emacsclient.1
index 83c8a366f8b..acc2edd4609 100644
--- a/doc/man/emacsclient.1
+++ b/doc/man/emacsclient.1
@@ -1,5 +1,5 @@
 .\" See section COPYING for conditions for redistribution.
-.TH EMACSCLIENT 1 "2022-09-05" "GNU Emacs" "GNU"
+.TH EMACSCLIENT 1 "2023-10-16" "GNU Emacs" "GNU"
 .\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection
 .\" other params are allowed: see man(7), man(1)
 .SH NAME
@@ -94,13 +94,37 @@ Emacs.  If combined with --eval, this option is ignored.
 How long to wait, in seconds, for Emacs to respond before giving up.
 The default is 0, which means to wait forever.
 .TP
-.B \-nw, \-t, \-\-tty
-Open a new Emacs frame on the current terminal.
+.B \-\-parent-id=ID
+Open an
+.B emacsclient
+frame as a client frame in the parent X window with id ID.
+.TP
+.B \-q, \-\-quiet
+Do not let
+.B emacsclient
+display messages about waiting for Emacs or connecting to remote
+server sockets.
+.TP
+.B \-u, \-\-suppress-output
+Do not let
+.B emacsclient
+display results returned from the server.  Mostly useful in
+combination with --eval when the evaluation performed is for
+side-effect rather than result.
 .TP
 .B \-s, \-\-socket-name=FILENAME
 Use socket named FILENAME for communication.
 This can also be specified via the EMACS_SOCKET_NAME environment variable.
 .TP
+.B \-nw, \-t, \-\-tty
+Open a new Emacs frame on the current terminal.
+.TP
+.B \-T, \-\-tramp-prefix=PREFIX
+Set PREFIX to add to filenames for Emacs to locate files on remote
+machines using TRAMP.  This is mostly useful in combination with using
+the Emacs server over TCP with --server-file.  This can also be
+specified via the EMACSCLIENT_TRAMP environment variable.
+.TP
 .B \-V, \-\-version
 Print version information and exit.
 .TP
diff --git a/doc/misc/ChangeLog.1 b/doc/misc/ChangeLog.1
index 2cd3c3f6b54..832dbd846a6 100644
--- a/doc/misc/ChangeLog.1
+++ b/doc/misc/ChangeLog.1
@@ -4374,7 +4374,7 @@
 
        * sc.texi (Getting Connected): Remove old index entries.
 
-2011-02-12  Ulrich Mueller  <ulm@gentoo.org>
+2011-02-12  Ulrich Müller  <ulm@gentoo.org>
 
        * url.texi: Remove duplicate @dircategory (Bug#7942).
 
@@ -5126,7 +5126,7 @@
        * gnus.texi (NoCeM): Remove.
        (Startup Variables): No jingle.
 
-2010-09-25  Ulrich Mueller  <ulm@gentoo.org>
+2010-09-25  Ulrich Müller  <ulm@gentoo.org>
 
        * woman.texi (Interface Options): xz compression is now supported.
 
diff --git a/doc/misc/ede.texi b/doc/misc/ede.texi
index d49d2296aa7..b4f08b7c4b9 100644
--- a/doc/misc/ede.texi
+++ b/doc/misc/ede.texi
@@ -1515,7 +1515,8 @@ Make sure placeholder @var{THIS} is replaced with the 
real thing, and pass throu
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-project-placeholder}.
+@item ede-project-placeholder
+@xref{ede-project-placeholder}.
 @table @code
 @item ede-project
 @table @asis
@@ -1801,9 +1802,11 @@ Commit change to local variables in @var{PROJ}.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-project-placeholder}.
+@item ede-project-placeholder
+@xref{ede-project-placeholder}.
 @table @code
-@item @xref{ede-project}.
+@item ede-project
+@xref{ede-project}.
 @table @code
 @item ede-cpp-root-project
 No children
@@ -1923,9 +1926,11 @@ This knows details about or source tree.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-project-placeholder}.
+@item ede-project-placeholder
+@xref{ede-project-placeholder}.
 @table @code
-@item @xref{ede-project}.
+@item ede-project
+@xref{ede-project}.
 @table @code
 @item ede-simple-project
 No children
@@ -1953,9 +1958,11 @@ Commit any change to @var{PROJ} to its file.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-project-placeholder}.
+@item ede-project-placeholder
+@xref{ede-project-placeholder}.
 @table @code
-@item @xref{ede-project}.
+@item ede-project
+@xref{ede-project}.
 @table @code
 @item ede-simple-base-project
 No children
@@ -1983,9 +1990,11 @@ This one project could control a tree of subdirectories.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-project-placeholder}.
+@item ede-project-placeholder
+@xref{ede-project-placeholder}.
 @table @code
-@item @xref{ede-project}.
+@item ede-project
+@xref{ede-project}.
 @table @code
 @item ede-proj-project
 No children
@@ -2173,9 +2182,11 @@ Commit change to local variables in @var{PROJ}.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-project-placeholder}.
+@item ede-project-placeholder
+@xref{ede-project-placeholder}.
 @table @code
-@item @xref{ede-project}.
+@item ede-project
+@xref{ede-project}.
 @table @code
 @item project-am-makefile
 No children
@@ -2215,9 +2226,11 @@ buffer being in order to provide a smart default target 
type.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-project-placeholder}.
+@item ede-project-placeholder
+@xref{ede-project-placeholder}.
 @table @code
-@item @xref{ede-project}.
+@item ede-project
+@xref{ede-project}.
 @table @code
 @item ede-step-project
 No children
@@ -2577,7 +2590,8 @@ Retrieves the slot @code{menu} from an object of class 
@code{ede-target}
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
 @item ede-proj-target
 @table @asis
@@ -2766,9 +2780,11 @@ sources variable.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
 @item ede-proj-target-makefile
 @table @asis
@@ -2864,11 +2880,14 @@ Use @var{CONFIGURATION} as the current configuration to 
query.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
 @item semantic-ede-proj-target-grammar
 No children
@@ -2918,11 +2937,14 @@ Argument @var{THIS} is the target that should insert 
stuff.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
 @item ede-proj-target-makefile-objectcode
 @table @asis
@@ -2980,13 +3002,17 @@ Argument @var{THIS} is the target to get sources from.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
-@item @xref{ede-proj-target-makefile-objectcode}.
+@item ede-proj-target-makefile-objectcode
+@xref{ede-proj-target-makefile-objectcode}.
 @table @code
 @item ede-proj-target-makefile-archive
 No children
@@ -3023,13 +3049,17 @@ Makefile.am generator, so use it to add this important 
bin program.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
-@item @xref{ede-proj-target-makefile-objectcode}.
+@item ede-proj-target-makefile-objectcode
+@xref{ede-proj-target-makefile-objectcode}.
 @table @code
 @item ede-proj-target-makefile-program
 @table @asis
@@ -3102,15 +3132,20 @@ Insert bin_PROGRAMS variables needed by target 
@var{THIS}.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
-@item @xref{ede-proj-target-makefile-objectcode}.
+@item ede-proj-target-makefile-objectcode
+@xref{ede-proj-target-makefile-objectcode}.
 @table @code
-@item @xref{ede-proj-target-makefile-program}.
+@item ede-proj-target-makefile-program
+@xref{ede-proj-target-makefile-program}.
 @table @code
 @item ede-proj-target-makefile-shared-object
 No children
@@ -3162,11 +3197,14 @@ Makefile.am generator, so use it to add this important 
bin program.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
 @item ede-proj-target-elisp
 @table @asis
@@ -3238,13 +3276,17 @@ is found, such as a @code{-version} variable, or the 
standard header.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
-@item @xref{ede-proj-target-elisp}.
+@item ede-proj-target-elisp
+@xref{ede-proj-target-elisp}.
 @table @code
 @item ede-proj-target-elisp-autoloads
 No children
@@ -3353,11 +3395,14 @@ sources variable.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
 @item ede-proj-target-makefile-miscelaneous
 No children
@@ -3409,11 +3454,14 @@ Return a list of files which @var{THIS} target depends 
on.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
-@item @xref{ede-proj-target-makefile}.
+@item ede-proj-target-makefile
+@xref{ede-proj-target-makefile}.
 @table @code
 @item ede-proj-target-makefile-info
 No children
@@ -3495,9 +3543,11 @@ when working in Automake mode.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{ede-proj-target}.
+@item ede-proj-target
+@xref{ede-proj-target}.
 @table @code
 @item ede-proj-target-scheme
 No children
@@ -3539,7 +3589,8 @@ Tweak the configure file (current buffer) to accommodate 
@var{THIS}.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
 @item project-am-target
 @table @asis
@@ -3577,9 +3628,11 @@ Edit the target associated with this file.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{project-am-target}.
+@item project-am-target
+@xref{project-am-target}.
 @table @code
 @item project-am-objectcode
 @table @asis
@@ -3622,11 +3675,14 @@ There are no default header files.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{project-am-target}.
+@item project-am-target
+@xref{project-am-target}.
 @table @code
-@item @xref{project-am-objectcode}.
+@item project-am-objectcode
+@xref{project-am-objectcode}.
 @table @code
 @item project-am-program
 No children
@@ -3660,9 +3716,11 @@ Additional LD args.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{project-am-target}.
+@item project-am-target
+@xref{project-am-target}.
 @table @code
 @item @w{project-am-header.}
 @table @code
@@ -3693,9 +3751,11 @@ Return the default macro to 'edit' for this object.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{project-am-target}.
+@item project-am-target
+@xref{project-am-target}.
 @table @code
 @item @w{project-am-header.}
 @table @code
@@ -3726,9 +3786,11 @@ Return the default macro to 'edit' for this object.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{project-am-target}.
+@item project-am-target
+@xref{project-am-target}.
 @table @code
 @item project-am-lisp
 No children
@@ -3756,9 +3818,11 @@ Return the default macro to 'edit' for this object.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{project-am-target}.
+@item project-am-target
+@xref{project-am-target}.
 @table @code
 @item project-am-texinfo
 No children
@@ -3808,9 +3872,11 @@ files in the project.
 @table @code
 @item eieio-speedbar-directory-button
 @table @code
-@item @xref{ede-target}.
+@item ede-target
+@xref{ede-target}.
 @table @code
-@item @xref{project-am-target}.
+@item project-am-target
+@xref{project-am-target}.
 @table @code
 @item project-am-man
 No children
@@ -4071,7 +4137,8 @@ Tweak the configure file (current buffer) to accommodate 
@var{THIS}.
 @table @code
 @item eieio-instance-inheritor
 @table @code
-@item @xref{ede-compilation-program}.
+@item ede-compilation-program
+@xref{ede-compilation-program}.
 @table @code
 @item ede-compiler
 @table @asis
@@ -4179,9 +4246,11 @@ Return a string based on @var{THIS} representing a make 
object variable.
 @table @code
 @item eieio-instance-inheritor
 @table @code
-@item @xref{ede-compilation-program}.
+@item ede-compilation-program
+@xref{ede-compilation-program}.
 @table @code
-@item @xref{ede-compiler}.
+@item ede-compiler
+@xref{ede-compiler}.
 @table @code
 @item ede-object-compiler
 No children
@@ -4222,7 +4291,8 @@ Insert variables needed by the compiler @var{THIS}.
 @table @code
 @item eieio-instance-inheritor
 @table @code
-@item @xref{ede-compilation-program}.
+@item ede-compilation-program
+@xref{ede-compilation-program}.
 @table @code
 @item ede-linker
 No children
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index 2fc8e60d400..631d7016acf 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -2832,9 +2832,12 @@ This may be inconvenient in some setups, so Emacs has 
mechanisms for
 changing the locations of all these files.
 
 @table @code
-@item auto-save-file-name-transforms (@pxref{Auto-Saving,,,elisp, GNU Emacs 
Lisp Reference Manual}).
-@item lock-file-name-transforms (@pxref{File Locks,,,elisp, GNU Emacs Lisp 
Reference Manual}).
-@item backup-directory-alist (@pxref{Making Backups,,,elisp, GNU Emacs Lisp 
Reference Manual}).
+@item auto-save-file-name-transforms
+(@pxref{Auto-Saving,,,elisp, GNU Emacs Lisp Reference Manual}).
+@item lock-file-name-transforms
+(@pxref{File Locks,,,elisp, GNU Emacs Lisp Reference Manual}).
+@item backup-directory-alist
+(@pxref{Making Backups,,,elisp, GNU Emacs Lisp Reference Manual}).
 @end table
 
 For instance, to write all these things to
@@ -3156,9 +3159,9 @@ Registry), like this:
 
 If possible, we recommend running Emacs inside @command{fbterm}, when
 in a Linux console.  This brings the Linux console on par with most
-terminal emulators under X.  To do this, install @command{fbterm}, for
-example with the package manager of your GNU/Linux distribution, and
-execute the command
+terminal emulators under X@.  To do this, install @command{fbterm},
+for example with the package manager of your GNU/Linux distribution,
+and execute the command
 
 @example
 $ fbterm
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index 3bfa240cacc..10902eac33f 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -412,16 +412,18 @@ One way to add functionality to ERC is to customize which 
of its many
 modules are loaded.
 
 There is a spiffy customize interface, which may be reached by typing
-@kbd{M-x customize-option @key{RET} erc-modules @key{RET}}.
-When removing a module outside of the Custom ecosystem, you may wish
-to ensure it's disabled by invoking its associated minor-mode toggle
-with a nonpositive prefix argument, for example, @kbd{C-u - M-x
+@kbd{M-x customize-option @key{RET} erc-modules @key{RET}}.  When
+removing a module outside of Customize, you may wish to ensure it's
+disabled by invoking its associated minor-mode toggle with a
+nonpositive prefix argument, for example, @kbd{C-u - M-x
 erc-spelling-mode @key{RET}}.  Additionally, if you plan on loading
 third-party modules that perform atypical setup on activation, you may
 need to arrange for calling @code{erc-update-modules} in your init
 file.  Examples of such setup might include registering an
 @code{erc-before-connect} hook, advising @code{erc-open}, and
-modifying @code{erc-modules} itself.
+modifying @code{erc-modules} itself.  On Emacs 29 and greater, you can
+also run @code{erc-update-modules} indirectly, via @code{(setopt
+erc-modules erc-modules)}.
 
 The following is a list of available modules.
 
@@ -652,41 +654,54 @@ buffers belonging to their connection (when called 
interactively).
 And unlike global toggles, none of these ever mutates
 @code{erc-modules}.
 
-
+@c FIXME add section to Advanced chapter for creating modules, and
+@c move this there.
 @anchor{Module Loading}
-@subheading Module Loading
+@subheading Loading
 @cindex module loading
 
 ERC loads internal modules in alphabetical order and third-party
 modules as they appear in @code{erc-modules}.  When defining your own
 module, take care to ensure ERC can find it.  An easy way to do that
 is by mimicking the example in the doc string for
-@code{define-erc-module}.  For historical reasons, ERC also falls back
-to @code{require}ing features.  For example, if some module
-@code{<mymod>} in @code{erc-modules} lacks a corresponding
-@code{erc-<mymod>-mode} command, ERC will attempt to load the library
-@code{erc-<mymod>} prior to connecting.  If this fails, ERC signals an
-error.  Users wanting to define modules in an init files should
-@code{(provide 'erc-<my-mod>)} somewhere to placate ERC.  Dynamically
-generating modules on the fly is not supported.
-
-Sometimes, packages attempt to autoload a module's definition instead
-of its minor-mode command, which breaks the link between the library
-and the module.  This means that enabling the mode by invoking its
-command toggle isn't enough to load its defining library.  Such
-packages should instead only supply autoload cookies featuring an
-explicit @code{autoload} form for their module's minor-mode command.
-As mentioned above, packages can also usually avoid autoload cookies
-entirely so long as their module's prefixed name matches that of its
-defining library and the latter's provided feature.
-
-Packages have also been seen to specify unnecessary top-level
-@code{eval-after-load} forms, which end up being ineffective in most
-cases.  Another unfortunate practice is mutating @code{erc-modules}
-itself in an autoloaded form.  Doing this tricks Customize into
-displaying the widget for @code{erc-modules} incorrectly, with
-built-in modules moved from the predefined checklist to the
-user-provided free-form area.
+@code{define-erc-module} (also shown below).  For historical reasons,
+ERC falls back to @code{require}ing features.  For example, if some
+module @code{my-module} in @code{erc-modules} lacks a corresponding
+@code{erc-my-module-mode} command, ERC will attempt to load the
+library @code{erc-my-module} prior to connecting.  If this fails, ERC
+signals an error.  Users defining personal modules in an init file
+should @code{(provide 'erc-my-module)} somewhere to placate ERC.
+Dynamically generating modules on the fly is not supported.
+
+Some packages have been known to autoload a module's definition
+instead of its minor-mode command, which severs the link between the
+library and the module.  This means that enabling the mode by invoking
+its command toggle isn't enough to load its defining library.  As
+such, packages should only supply module-related autoload cookies with
+an actual @code{autoload} form for their module's minor-mode command,
+like so:
+
+@lisp
+;;;###autoload(autoload 'erc-my-module-mode "erc-my-module" nil t)
+(define-erc-module my-module nil
+  "My doc string."
+  ((add-hook 'erc-insert-post-hook #'erc-my-module-on-insert-post))
+  ((remove-hook 'erc-insert-post-hook #'erc-my-module-on-insert-post)))
+@end lisp
+
+@noindent
+As implied earlier, packages can usually omit such cookies entirely so
+long as their module's prefixed name matches that of its defining
+library and the library's provided feature.
+
+Finally, packages have also been observed to run
+@code{erc-update-modules} in top-level forms, forcing ERC to take
+special precautions to avoid recursive invocations.  Another
+unfortunate practice is mutating @code{erc-modules} itself upon
+loading @code{erc}, possibly by way of an autoload.  Doing this tricks
+Customize into displaying the widget for @code{erc-modules}
+incorrectly, with built-in modules moved from the predefined checklist
+to the user-provided free-form area.
 
 @c PRE5_4: Document every option of every module in its own subnode
 
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index cc94f610615..e8aa8cdc6a3 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -400,6 +400,14 @@ Return the buffer named @var{name}.  This is equivalent to
 @samp{$(get-buffer-create "@var{name}")} (@pxref{Creating Buffers, , ,
 elisp, The Emacs Lisp Reference Manual}).
 
+@item #<marker @var{position} @var{buffer-or-name}>
+Return a marker at @var{position} in the buffer @var{buffer-or-name}.
+@var{buffer-or-name} can either be a string naming a buffer or an
+actual buffer object.  This is roughly equivalent to creating a new
+marker and calling @samp{$(set-marker marker @var{position}
+@var{buffer-or-name})} (@pxref{Moving Markers, , , elisp, The Emacs
+Lisp Reference Manual}).
+
 @item #<process @var{name}>
 Return the process named @var{name}.  This is equivalent to
 @samp{$(get-process "@var{name}")} (@pxref{Process Information, , ,
@@ -2590,11 +2598,6 @@ If it's a Lisp function, input redirection implies 
@command{xargs} (in a
 way@dots{}).  If input redirection is added, also update the
 @code{file-name-quote-list}, and the delimiter list.
 
-@item Allow @samp{#<@var{word} @var{arg}>} as a generic syntax
-
-With the handling of @emph{word} specified by an
-@code{eshell-special-alist}.
-
 @item In @code{eshell-eval-using-options}, allow a @code{:complete} tag
 
 It would be used to provide completion rules for that command.  Then the
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 8a50f064326..582038d973f 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -3216,7 +3216,7 @@ if address "sender" "sieve-admin@@extundo.com" @{
 @end example
 
 To generate tests for multiple email-addresses use a group parameter
-like @code{(sieve address "sender" ("name@@one.org" else@@two.org"))}.
+like @code{(sieve address "sender" ("name@@one.org" "else@@two.org"))}.
 When generating a sieve script (@pxref{Sieve Commands}) Sieve code
 like the following is generated:
 
@@ -3372,7 +3372,7 @@ You can define different sorting to different groups via
 group by reverse date to see the latest news at the top and an
 @acronym{RSS} group by subject.  In this example, the first group is the
 Debian daily news group @code{gmane.linux.debian.user.news} from
-news.gmane.org.  The @acronym{RSS} group corresponds to the Debian
+news.gmane.io.  The @acronym{RSS} group corresponds to the Debian
 weekly news RSS feed
 @url{https://packages.debian.org/unstable/newpkg_main.en.rdf},
 @xref{RSS}.
@@ -4426,7 +4426,7 @@ A select method can be very long, like:
 
 @lisp
 (nntp "gmane"
-      (nntp-address "news.gmane.org")
+      (nntp-address "news.gmane.io")
       (nntp-end-of-line "\n")
       (nntp-open-connection-function
        nntp-open-via-rlogin-and-telnet)
@@ -7279,7 +7279,7 @@ The server has to support @acronym{NOV} for any of this 
to work.
 @cindex Gmane, @code{gnus-fetch-old-headers}
 This feature can seriously impact performance it ignores all locally
 cached header entries.  Setting it to @code{t} for groups for a server
-that doesn't expire articles (such as news.gmane.org), leads to very
+that doesn't expire articles (such as news.gmane.io), leads to very
 slow summary generation.
 
 @item gnus-fetch-old-ephemeral-headers
@@ -18020,7 +18020,7 @@ Here is an example:
  (nnselect-args
   . [["nnimap+work:mail" 595 100]
      ["nnimap+home:sent" 223 100]
-     ["nntp+news.gmane.org:gmane.emacs.gnus.general" 23666 100]]))
+     ["nntp+news.gmane.io:gmane.emacs.gnus.general" 23666 100]]))
 @end lisp
 
 The function is the identity and the argument is just the list of
@@ -25155,9 +25155,9 @@ groups as spam and reports the to Gmane at group exit:
 @end lisp
 
 Additionally, I use @code{(setq spam-report-gmane-use-article-number nil)}
-because I don't read the groups directly from news.gmane.org, but
+because I don't read the groups directly from news.gmane.io, but
 through my local news server (leafnode).  I.e., the article numbers are
-not the same as on news.gmane.org, thus @code{spam-report.el} has to check
+not the same as on news.gmane.io, thus @code{spam-report.el} has to check
 the @code{X-Report-Spam} header to find the correct number.
 
 @node Spam Back Ends
@@ -25341,7 +25341,7 @@ added to a group's @code{spam-process} parameter, the 
spam-marked
 articles groups will be reported to the Gmane administrators via a
 HTTP request.
 
-Gmane was formerly found at @uref{http://gmane.org}.
+Gmane is at @uref{https://gmane.io}.
 
 @emph{WARNING}
 
@@ -26434,12 +26434,12 @@ lines:
 (setq gnus-refer-article-method
       '(current
         (nnregistry)
-        (nnweb "gmane" (nnweb-type gmane))))
+        (nnweb "google" (nnweb-type google))))
 @end example
 
 The example above instructs Gnus to first look up the article in the
 current group, or, alternatively, using the registry, and finally, if
-all else fails, using Gmane.
+all else fails, using Google.
 
 @node Fancy splitting to parent
 @subsection Fancy splitting to parent
@@ -28808,7 +28808,7 @@ be read correctly in Emacs 22 and below.  If you want 
to use Gnus across
 different Emacs versions, you may set @code{mm-auto-save-coding-system}
 to @code{emacs-mule}.
 @c FIXME: Untested.  (Or did anyone test it?)
-@c Cf. http://thread.gmane.org/gmane.emacs.gnus.general/66251/focus=66344
+@c Cf. http://thread.gmane.org/gmane.emacs.gnus.general/66251/focus=66344 
[dead link]
 
 @item Lisp files are now installed in @file{.../site-lisp/gnus/} by default.
 It defaulted to @file{.../site-lisp/} formerly.  In addition to this,
@@ -29321,13 +29321,13 @@ have names like @samp{gnu.emacs.gnus}.
 You can also have any number of foreign groups active at the same
 time.  These are groups that use non-native non-secondary back ends
 for getting news.  Foreign groups have names like
-@samp{nntp+news.gmane.org:gmane.emacs.gnus.devel}.
+@samp{nntp+news.gmane.io:gmane.emacs.gnus.devel}.
 
 @item secondary
 @cindex secondary
 Secondary back ends are somewhere half-way between being native and
 being foreign, but they mostly act like they are native, but they, too
-have names like @samp{nntp+news.gmane.org:gmane.emacs.gnus.devel}.
+have names like @samp{nntp+news.gmane.io:gmane.emacs.gnus.devel}.
 
 @item article
 @cindex article
diff --git a/doc/misc/octave-mode.texi b/doc/misc/octave-mode.texi
index 0a599f64516..bdeaf31cdc0 100644
--- a/doc/misc/octave-mode.texi
+++ b/doc/misc/octave-mode.texi
@@ -146,9 +146,7 @@ An error is signaled if no block to close is found.
 @findex octave-insert-defun
 Insert a function skeleton, prompting for the function's name, arguments
 and return values which have to be entered without parentheses
-(@code{octave-insert-defun}).
-@noindent
-in one of your Emacs startup files.
+(@code{octave-insert-defun}) in one of your Emacs startup files.
 @end table
 
 The following variables can be used to customize Octave mode.
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 64d47515978..2f2c166cf8c 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -6089,20 +6089,23 @@ wrapping the timer function body as follows:
 to 10.  @value{tramp} does not display all messages; only those with a
 verbosity level less than or equal to @code{tramp-verbose}.
 
+@noindent
 The verbosity levels are
 
-          @w{ 0}  silent (no @value{tramp} messages at all)
-@*@indent @w{ 1}  errors
-@*@indent @w{ 2}  warnings
-@*@indent @w{ 3}  connection to remote hosts (default verbosity)
-@*@indent @w{ 4}  activities
-@*@indent @w{ 5}  internal
-@*@indent @w{ 6}  sent and received strings
-@*@indent @w{ 7}  connection properties
-@*@indent @w{ 8}  file caching
-@*@indent @w{ 9}  test commands
-@*@indent @w{10}  traces (huge)
-@*@indent @w{11}  call traces (maintainer only)
+@itemize @w{}
+@item @w{ 0}  Silent (no @value{tramp} messages at all)
+@item @w{ 1}  Errors
+@item @w{ 2}  Warnings
+@item @w{ 3}  Connection to remote hosts (default verbosity)
+@item @w{ 4}  Activities
+@item @w{ 5}  Internal
+@item @w{ 6}  Sent and received strings
+@item @w{ 7}  Connection properties
+@item @w{ 8}  File caching
+@item @w{ 9}  Test commands
+@item @w{10}  Traces (huge)
+@item @w{11}  Call traces (maintainer only)
+@end itemize
 
 With @code{tramp-verbose} greater than or equal to 4, messages are
 also written to the @value{tramp} debug buffer @file{*debug
diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi
index 55e56f7ce4e..37ed50ab2b1 100644
--- a/doc/misc/use-package.texi
+++ b/doc/misc/use-package.texi
@@ -451,7 +451,7 @@ docstring of @code{system-type} for other valid values.
 @item
 Window system
 
-The example below loads a package only on macOS and X.  See the
+The example below loads a package only on macOS and X@.  See the
 docstring of @code{window-system} for valid values.
 
 @lisp
@@ -940,7 +940,7 @@ Examples:
 Remapping of commands with @code{:bind} and @code{bind-key} works as
 expected, because when the binding is a vector, it is passed straight
 to @code{define-key}.  @xref{Remapping Commands,,, elisp, GNU Emacs
-Lisp Reference Manual}), for more information about command remapping.
+Lisp Reference Manual}, for more information about command remapping.
 For example, the following declaration will rebind
 @code{fill-paragraph} (bound to @kbd{M-q} by default) to
 @code{unfill-toggle}:
diff --git a/doc/misc/wisent.texi b/doc/misc/wisent.texi
index 2d9fedadcc5..e1fee10d954 100644
--- a/doc/misc/wisent.texi
+++ b/doc/misc/wisent.texi
@@ -383,7 +383,8 @@ On the other hand, @var{precedence} explicitly assign the 
precedence
 level of the given terminal to a rule.
 
 @cindex semantic actions
-@item @anchor{action}action
+@anchor{action}
+@item action
 An action is an optional Emacs Lisp function call, like this:
 
 @code{(identity $1)}
diff --git a/etc/AUTHORS b/etc/AUTHORS
index 27d01ed9eb9..5fc54f1909f 100644
--- a/etc/AUTHORS
+++ b/etc/AUTHORS
@@ -280,6 +280,8 @@ Amin Bandali: changed erc.el erc.texi erc-backend.el 
erc-button.el
 
 Amos Bird: changed xfns.c
 
+Amritpal Singh: changed decompress.c
+
 Anand Mitra: changed gnus-sum.el
 
 Anders Holst: wrote hippie-exp.el
@@ -296,9 +298,9 @@ Anders Waldenborg: changed emacsclient.c
 Andrea Corallo: wrote comp-cstr-tests.el comp-cstr.el comp-tests.el
   comp.el
 and changed comp.c pdumper.c lread.c bytecomp.el startup.el configure.ac
-  comp.h loadup.el lisp.h data.c alloc.c emacs.c .gitlab-ci.yml
-  cl-macs.el elisp-mode.el nadvice.el comp-test-funcs.el lisp/Makefile.in
-  subr.el Makefile.in advice.el and 70 other files
+  comp.h loadup.el lisp.h data.c elisp-mode.el alloc.c emacs.c subr.el
+  .gitlab-ci.yml cl-macs.el nadvice.el comp-test-funcs.el
+  lisp/Makefile.in Makefile.in advice.el and 70 other files
 
 André A. Gomes: changed ispell.el
 
@@ -535,6 +537,8 @@ Aubrey Jaffer: changed info.el unexelf.c
 
 August Feng: changed bookmark.el
 
+Augustin Chéneau: changed treesit.el
+
 Augusto Stoffel: co-wrote ansi-osc.el
 and changed progmodes/python.el isearch.el eglot.el comint.el eldoc.el
   project.el README.md font-lock.el man.el misc.texi modes.texi
@@ -578,8 +582,8 @@ Bartosz Duszel: changed allout.el bib-mode.el cc-cmds.el 
hexl.el icon.el
 
 Basil L. Contovounesios: changed simple.el subr.el message.el eww.el
   modes.texi custom.el text.texi bibtex.el gnus-sum.el internals.texi
-  customize.texi display.texi files.texi gnus-group.el gnus-win.el
-  gnus.texi gravatar.el js.el json.el map.el shr.el and 345 other files
+  js.el customize.texi display.texi files.texi gnus-group.el gnus-win.el
+  gnus.texi gravatar.el json.el map.el shr.el and 345 other files
 
 Bastian Beischer: changed semantic/complete.el calc-yank.el include.el
   mru-bookmark.el refs.el senator.el
@@ -702,9 +706,9 @@ Bob Olson: co-wrote cperl-mode.el
 
 Bob Rogers: wrote ietf-drums-date-tests.el ietf-drums-date.el
   ietf-drums-tests.el
-and changed ietf-drums.el vc-dir.el vc-svn.el cperl-mode.el diff.el
-  ewoc.el ffap.el files.el maintaining.texi sql.el thingatpt.el
-  time-date.el vc.el vc1-xtra.texi
+and changed ietf-drums.el vc-dir.el time-date.el vc-svn.el cperl-mode.el
+  diff.el ewoc.el ffap.el files.el maintaining.texi os.texi sql.el
+  thingatpt.el vc.el vc1-xtra.texi
 
 Bob Weiner: changed info.el quail.el dframe.el etags.c rmail.el
   rmailsum.el speedbar.el
@@ -1014,6 +1018,8 @@ Christopher Wellons: changed emacs-lisp/cl-lib.el 
hashcash.el
 
 Christophe Troestler: changed gnus-icalendar.el epg.el newcomment.el
 
+Christoph Göttschkes: changed make-mode.el
+
 Christoph Scholtes: changed README.W32 progmodes/python.el stdint.h
   INSTALL maintaining.texi INSTALL.REPO admin.el bookmark.el
   configure.bat control.texi cua-base.el help-mode.el help.el ibuffer.el
@@ -1158,7 +1164,7 @@ Daniele Nicolodi: changed url-http.el
 
 Daniel Fleischer: changed TUTORIAL browse-url.el startup.el
 
-Daniel Freeman: changed eglot.el eglot.texi
+Daniel Freeman: changed eglot.el js.el eglot.texi
 
 Daniel Gröber: changed rxvt.el
 
@@ -1190,7 +1196,7 @@ Daniel Martín: changed c-ts-mode.el nsterm.m shortdoc.el 
ns-win.el
   simple.el diff-mode-tests.el erc.texi files.el files.texi indent.erts
   msdos-xtra.texi progmodes/python.el search.texi .lldbinit basic.texi
   c-ts-mode-tests.el cmacexp.el compilation.txt compile-tests.el
-  compile.texi configure.ac and 45 other files
+  compile.texi configure.ac and 46 other files
 
 Daniel McClanahan: changed lisp-mode.el
 
@@ -1316,7 +1322,7 @@ David Edmondson: changed message.el erc.el mml2015.el 
process.c
   gnus-cite.el gnus-cloud.el gnus.texi imap.el mm-uu.el mm-view.el
   nnfolder.el nnimap.el nnml.el rcirc.el shr.el
 
-Davide Masserut: changed bindings.el sh-script.el basic.texi
+Davide Masserut: changed bindings.el sh-script.el Makefile.in basic.texi
   dictionary.el eglot.el faces.el go-ts-mode-tests.el go-ts-mode.el
   indent.erts
 
@@ -1420,8 +1426,8 @@ David Ponce: wrote bovine/grammar.el cedet.el comp.el 
java-tags.el
 and co-wrote util-modes.el
 and changed w32menu.c w32term.c close.png close.xpm empty.png empty.xpm
   end-guide.png end-guide.xpm files.el guide.png guide.xpm handle.png
-  handle.xpm keyboard.c leaf.png leaf.xpm no-guide.png no-guide.xpm
-  no-handle.png no-handle.xpm open.png and 22 other files
+  handle.xpm image.el keyboard.c leaf.png leaf.xpm no-guide.png
+  no-guide.xpm no-handle.png no-handle.xpm and 22 other files
 
 David Raynes: changed ns-win.el
 
@@ -1496,7 +1502,7 @@ Detlev Zundel: wrote re-builder.el
 and changed buffer.c
 
 Devon Sean McCullough: changed url-http.el buff-menu.el comint.el
-  ns-win.el
+  iso-transl.el ns-win.el
 
 Dhruva Krishnamurthy: changed emacsclient.c fontset.c image.c sound.c
   w32proc.c
@@ -1660,9 +1666,9 @@ Eli Zaretskii: wrote [bidirectional display in xdisp.c]
   chartab-tests.el coding-tests.el etags-tests.el rxvt.el tty-colors.el
 and co-wrote help-tests.el
 and changed xdisp.c display.texi w32.c msdos.c simple.el w32fns.c
-  files.el fileio.c keyboard.c emacs.c text.texi w32term.c configure.ac
+  files.el fileio.c keyboard.c emacs.c text.texi configure.ac w32term.c
   dispnew.c frames.texi w32proc.c files.texi xfaces.c window.c
-  dispextern.h lisp.h and 1330 other files
+  dispextern.h lisp.h and 1334 other files
 
 Eliza Velasquez: changed server.el
 
@@ -1808,7 +1814,7 @@ Ernesto Alfonso: changed simple.el
 
 E Sabof: changed hi-lock.el image-dired.el
 
-Eshel Yaron: changed eglot.el eww.el
+Eshel Yaron: changed eglot.el emacs.texi eww.el indent.texi
 
 Espen Skoglund: wrote pascal.el
 
@@ -1877,10 +1883,8 @@ and changed minibuf.c esh-var.el minibuf.texi mouse.el 
package.el rect.el
   edebug.el em-dirs.el eshell-tests.el eww.el fileio-tests.el fileio.c
   files.texi gamegrid.el keyboard.c and 8 other files
 
-Felician Nemeth: changed rmc.el
-
 Felicián Németh: changed eglot.el EGLOT-NEWS README.md eglot-tests.el
-  project.el xref.el
+  project.el rmc.el xref.el
 
 Felipe Ochoa: changed faces.el js.el paren.el
 
@@ -2154,12 +2158,10 @@ and changed tar-mode.el
 
 Greg Minshall: changed eldoc.el
 
-Gregoire Jadi: changed proced.el
-
 Grégoire Jadi: changed org.texi configure.ac emacsgtkfixed.c keyboard.c
   rcirc.el xwidget.c xwidget.el Makefile.in bibtex-tests.el bibtex.el
   cl-generic.el dispextern.h dispnew.c emacs.c latin-post.el lisp.h
-  ob-core.el org-id.el org.el print.c reporter.el and 8 other files
+  ob-core.el org-id.el org.el print.c proced.el and 9 other files
 
 Gregorio Gervasio, Jr.: changed gnus-sum.el
 
@@ -2342,7 +2344,8 @@ Igor Kuzmin: wrote cconv.el
 Igor Saprykin: changed ftfont.c
 
 Ihor Radchenko: wrote org-fold-core.el org-fold.el org-persist.el
-and changed ox.el fns.c help-mode.el oc.el org-element.el
+and changed ox.el fns.c emacsclient.desktop help-mode.el oc.el
+  org-element.el
 
 Iku Iwasa: changed auth-source-pass-tests.el auth-source-pass.el
 
@@ -2504,7 +2507,7 @@ James TD Smith: changed org.el org-colview.el org-clock.el
   org-remember.el org-plot.el org-agenda.el org-compat.el org-habit.el
   org.texi
 
-James Thomas: changed quail/indian.el gnus-msg.el ind-util.el
+James Thomas: changed quail/indian.el gnus-msg.el ind-util.el nnmail.el
 
 James Troup: changed gnus-sum.el
 
@@ -2545,10 +2548,8 @@ Jan Seeger: changed ox-publish.el parse-time.el
 
 Jan Stranik: changed ebrowse.c
 
-Jan Synacek: changed emacs-lisp-intro.texi minibuffer.el mwheel.el
-  vc-git.el
-
-Jan Synáček: changed maintaining.texi project.el
+Jan Synáček: changed emacs-lisp-intro.texi maintaining.texi minibuffer.el
+  mwheel.el project.el vc-git.el
 
 Jan Tatarik: wrote gnus-icalendar-tests.el gnus-icalendar.el
 and changed gnus-score.el gnus-logic.el
@@ -2686,8 +2687,8 @@ and changed mml-sec.el gnus-util.el message.texi 
mml-smime.el mml1991.el
 Jens Petersen: wrote find-func.el
 and changed mule-cmds.el pcmpl-rpm.el
 
-Jens Schmidt: changed epa.texi plstore.el auth.texi comint.el gnus.texi
-  isearch.el ldap.el
+Jens Schmidt: changed plstore.el epa.texi auth.texi comint.el
+  elisp-mode.el epa-file.el epg.el gnus.texi isearch.el ldap.el
 
 Jens Toivo Berger Thielemann: changed word-help.el
 
@@ -2766,7 +2767,7 @@ Jim Porter: changed eshell.texi esh-cmd.el 
esh-var-tests.el
   esh-util.el eshell-tests-helpers.el em-pred.el esh-arg.el
   esh-cmd-tests.el tramp.el em-pred-tests.el em-dirs-tests.el server.el
   em-basic.el em-extpipe-tests.el esh-opt-tests.el esh-opt.el
-  and 90 other files
+  and 92 other files
 
 Jim Radford: changed gnus-start.el
 
@@ -2778,12 +2779,13 @@ Jim Wilson: changed alloca.c oldXMenu/Makefile.in
 
 Jin Choi: changed progmodes/python.el
 
-Jindrich Makovicka: changed eval.c fns.c
-
-Jindřich Makovička: changed pgtkfns.c pgtkselect.c pgtkterm.c
+Jindřich Makovička: changed eval.c fns.c pgtkfns.c pgtkselect.c
+  pgtkterm.c
 
 Jirka Kosek: changed mule.el
 
+J M: changed csharp-mode.el
+
 Joachim Nilsson: changed cc-styles.el
 
 Joachim Reiter: changed org-footnote.el
@@ -2920,7 +2922,7 @@ John Mastro: changed auth-source.el ibuffer.el w32heap.c
 
 John Mongan: changed progmodes/f90.el
 
-John Muhl: changed calculator.el
+John Muhl: changed calculator.el sqlite-mode.el
 
 John Paul Wallington: changed ibuffer.el ibuf-ext.el subr.el help-fns.el
   rmail.el files.el thumbs.el bindings.el fns.c xfns.c arc-mode.el
@@ -3044,7 +3046,7 @@ and changed xterm.c xfns.c keyboard.c screen.c dispnew.c 
xdisp.c window.c
 
 Joseph M. Kelsey: changed fileio.c skeleton.el
 
-Joseph Turner: changed package-vc.el
+Joseph Turner: changed package-vc.el subr.el
 
 Josh Elsasser: changed eglot.el README.md configure.ac
 
@@ -3125,8 +3127,8 @@ Juri Linkov: wrote compose.el emoji.el files-x.el 
misearch.el
   repeat-tests.el replace-tests.el tab-bar-tests.el tab-bar.el
   tab-line.el
 and changed isearch.el simple.el info.el replace.el dired.el dired-aux.el
-  progmodes/grep.el minibuffer.el window.el subr.el vc.el mouse.el
-  outline.el diff-mode.el repeat.el image-mode.el files.el menu-bar.el
+  progmodes/grep.el minibuffer.el window.el subr.el vc.el outline.el
+  mouse.el diff-mode.el repeat.el image-mode.el files.el menu-bar.el
   search.texi startup.el progmodes/compile.el and 473 other files
 
 Jussi Lahdenniemi: changed w32fns.c ms-w32.h msdos.texi w32.c w32.h
@@ -3387,8 +3389,6 @@ Kishore Kumar: changed terminal.el
 
 Kiso Katsuyuki: changed tab-line.el
 
-Kjartan Oli Agustsson: changed doc-view.el
-
 Kjartan Óli Ágústsson: changed doc-view.el
 
 Klaus Straubinger: changed url-http.el url-history.el pcmpl-rpm.el
@@ -3666,7 +3666,7 @@ Manuel Giraud: changed vc.el ox-html.el bookmark.el 
image-dired.el
   longlines.el ox-publish.el keyboard.c paragraphs.el simple.el
   basic.texi battery.el bookmark-tests.el cus-start.el dired.texi
   dispextern.h easymenu.el find-dired.el ibuf-ext.el ibuf-macs.el
-  idlwave.el image.c and 11 other files
+  idlwave.el image-mode.el and 12 other files
 
 Manuel Gómez: changed speedbar.el
 
@@ -3935,6 +3935,8 @@ Matthew Mundell: changed calendar.texi diary-lib.el 
files.texi
 
 Matthew Newton: changed imenu.el
 
+Matthew Tromp: changed ielm.el
+
 Matthew White: changed buffer.c bookmark-tests.el bookmark.el
   test-list.bmk
 
@@ -3988,7 +3990,7 @@ Mauro Aranda: changed wid-edit.el cus-edit.el custom.el 
wid-edit-tests.el
   widget.texi perl-mode.el custom-tests.el checkdoc-tests.el checkdoc.el
   cperl-mode-tests.el cus-edit-tests.el cus-theme.el customize.texi
   files.texi gnus.texi octave.el pong.el align.el auth-source.el
-  autorevert.el button.el and 45 other files
+  autorevert.el base.el and 56 other files
 
 Maxime Edouard Robert Froumentin: changed gnus-art.el mml.el
 
@@ -4011,8 +4013,8 @@ and co-wrote tramp-cache.el tramp-sh.el tramp.el
 and changed tramp.texi tramp-adb.el trampver.el trampver.texi dbusbind.c
   files.el ange-ftp.el files.texi file-notify-tests.el dbus.texi
   gitlab-ci.yml autorevert.el tramp-fish.el kqueue.c Dockerfile.emba
-  os.texi tramp-gw.el test/Makefile.in README shell.el files-x.el
-  and 308 other files
+  os.texi tramp-gw.el test/Makefile.in README shell.el files-tests.el
+  and 309 other files
 
 Michael Ben-Gershon: changed acorn.h configure.ac riscix1-1.h riscix1-2.h
   unexec.c
@@ -4453,6 +4455,8 @@ and changed rsz-mini.el emacs-buffer.gdb comint.el 
files.el Makefile
 
 Noah Lavine: changed tramp.el
 
+Noah Peart: changed treesit.el
+
 Noah Swainland: changed calc.el goto-addr.el misc.texi
 
 Noam Postavsky: changed progmodes/python.el lisp-mode.el bytecomp.el
@@ -4795,9 +4799,10 @@ Philipp Stephani: wrote callint-tests.el 
checkdoc-tests.el
   cl-preloaded-tests.el ediff-diff-tests.el eval-tests.el ido-tests.el
   lread-tests.el mouse-tests.el startup-tests.el xt-mouse-tests.el
 and changed emacs-module.c emacs-module-tests.el configure.ac json.c
-  process.c eval.c internals.texi json-tests.el process-tests.el alloc.c
-  emacs-module.h.in emacs.c lread.c nsterm.m pdumper.c bytecomp.el lisp.h
-  seccomp-filter.c callproc.c cl-macs.el gtkutil.c and 188 other files
+  process.c eval.c internals.texi json-tests.el process-tests.el
+  pdumper.c alloc.c emacs-module.h.in emacs.c lread.c nsterm.m
+  bytecomp.el lisp.h seccomp-filter.c callproc.c cl-macs.el gtkutil.c
+  and 188 other files
 
 Phillip Dixon: changed eglot.el
 
@@ -5092,7 +5097,7 @@ and changed configure.ac process.c blocks.awk keymap.el 
font.c
   network-stream-tests.el processes.texi custom.texi emoji-zwj.awk
   ftfont.c gtkutil.c process-tests.el unicode vc-git.el terminal.c
   char-fold.el gnutls.el keymaps.texi network-stream.el nsm.el nsterm.m
-  and 192 other files
+  and 193 other files
 
 Robert Thorpe: changed cus-start.el indent.el rmail.texi
 
@@ -5154,6 +5159,8 @@ Ross Donaldson: changed progmodes/python.el
 
 Ross Patterson: co-wrote org-protocol.el
 
+Ross Timson: changed eglot.el
+
 Roy Hashimoto: changed mm-view.el
 
 Roy Liu: changed ns-win.el
@@ -5324,6 +5331,8 @@ Sebastian Kremer: wrote dired-aux.el dired.el ls-lisp.el
 and co-wrote dired-x.el find-dired.el
 and changed add-log.el
 
+Sebastian Miele: changed strings.texi
+
 Sebastian Reuße: changed find-dired.el
 
 Sebastian Rose: co-wrote org-protocol.el
@@ -5515,10 +5524,10 @@ Stefan Kangas: wrote bookmark-tests.el 
cal-julian-tests.el
   studly-tests.el tabify-tests.el time-tests.el timezone-tests.el
   underline-tests.el uudecode-tests.el wallpaper.el warnings-tests.el
 and co-wrote help-tests.el keymap-tests.el
-and changed image-dired.el package.el efaq.texi cperl-mode.el subr.el
-  checkdoc.el help.el bookmark.el simple.el dired.el files.el dired-x.el
-  gnus.texi keymap.c image-mode.el erc.el ediff-util.el speedbar.el
-  browse-url.el bytecomp-tests.el bytecomp.el and 1657 other files
+and changed image-dired.el efaq.texi package.el cperl-mode.el help.el
+  subr.el checkdoc.el bookmark.el simple.el dired.el files.el gnus.texi
+  dired-x.el keymap.c image-mode.el erc.el ediff-util.el speedbar.el
+  woman.el browse-url.el bytecomp-tests.el and 1678 other files
 
 Stefan Merten: co-wrote rst.el
 
@@ -5571,7 +5580,7 @@ and co-wrote todo-mode.el
 and changed wdired.el todo-mode.texi wdired-tests.el diary-lib.el
   dired.el dired-tests.el doc-view.el files.el info.el minibuffer.el
   outline.el todo-test-1.todo allout.el eww.el find-dired.el frames.texi
-  hl-line.el menu-bar.el mouse.el otodo-mode.el subr.el
+  hl-line.el menu-bar.el mouse.el otodo-mode.el simple.el
   and 63 other files
 
 Stephen C. Gilardi: changed configure.ac
@@ -5781,7 +5790,7 @@ Thamer Mahmoud: changed arabic.el
 Theodore Jump: changed makefile.nt makefile.def w32-win.el w32faces.c
 
 Theodor Thornhill: changed typescript-ts-mode.el java-ts-mode.el
-  c-ts-mode.el eglot.el js.el csharp-mode.el css-mode.el project.el
+  c-ts-mode.el eglot.el csharp-mode.el js.el css-mode.el project.el
   json-ts-mode.el treesit.el c-ts-common.el eglot-tests.el EGLOT-NEWS
   README.md c-ts-mode-tests.el compile-tests.el go-ts-mode.el
   indent-bsd.erts indent.erts maintaining.texi mwheel.el
@@ -5833,6 +5842,8 @@ and changed soap-inspect.el eudc.el eudc-vars.el 
eudc.texi ldap.el
   README authinfo bbdb diary-lib.el display.texi eudc-capf.el
   and 8 other files
 
+Thomas Hilke: changed sqlite-mode.el
+
 Thomas Horsley: changed cxux-crt0.s cxux.h cxux7.h emacs.c nh3000.h
   nh4000.h simple.el sysdep.c xterm.c
 
@@ -6075,8 +6086,8 @@ Ulrich Leodolter: changed w32proc.c
 Ulrich Müller: changed configure.ac calc-units.el
   emacsclient-mail.desktop lib-src/Makefile.in src/Makefile.in version.el
   Makefile.in doctor.el emacs.1 files.el gamegrid.el gud.el server.el
-  ChgPane.c ChgSel.c HELLO INSTALL XMakeAssoc.c authors.el bytecomp.el
-  case-table.el and 44 other files
+  ChgPane.c ChgSel.c HELLO INSTALL XMakeAssoc.c authors.el bindings.el
+  bytecomp.el and 45 other files
 
 Ulrich Neumerkel: changed xterm.c
 
@@ -6151,7 +6162,8 @@ Vincent Bernat: changed gnus-int.el nnimap.el xsettings.c
 
 Vincent Del Vecchio: changed info.el mh-utils.el
 
-Vincenzo Pupillo: changed js.el typescript-ts-mode.el java-ts-mode.el
+Vincenzo Pupillo: changed cmake-ts-mode.el js.el typescript-ts-mode.el
+  java-ts-mode.el
 
 Vince Salvino: changed msdos.texi w32.c w32fns.c
 
diff --git a/etc/CALC-NEWS b/etc/CALC-NEWS
index 8fd5365011f..a466a9db40b 100644
--- a/etc/CALC-NEWS
+++ b/etc/CALC-NEWS
@@ -856,7 +856,7 @@ For changes in Emacs 23.1 and later, see the main Emacs 
NEWS file.
 
 ** Fixed obsolete trail tags gsmp, gneg, ginv to jsmp, jneg, jinv.
 
-** Fixed some errors and made improvements in units table [Ulrich Mueller].
+** Fixed some errors and made improvements in units table [Ulrich Müller].
 
 
 * Version 1.07:
diff --git a/etc/ChangeLog.1 b/etc/ChangeLog.1
index 68c15fc6e69..f7786775e50 100644
--- a/etc/ChangeLog.1
+++ b/etc/ChangeLog.1
@@ -1778,7 +1778,7 @@
 
        * refcards/orgcard.tex: Cleanup.
 
-2010-11-27  Ulrich Mueller  <ulm@gentoo.org>
+2010-11-27  Ulrich Müller  <ulm@gentoo.org>
 
        * HELLO: Add ancient Greek (Bug#7418).
 
@@ -2497,7 +2497,7 @@
 
        * NEWS: New function `locate-user-emacs-file'.
 
-2008-10-18  Ulrich Mueller  <ulm@gentoo.org>
+2008-10-18  Ulrich Müller  <ulm@gentoo.org>
 
        * MACHINES: Add section for SuperH.
 
@@ -2914,7 +2914,7 @@
        emacs48_mac.png, emacs256_mac.png, and emacs512_mac.png,
        respectively.
 
-2007-12-08  Ulrich Mueller  <ulm@gentoo.org>  (tiny change)
+2007-12-08  Ulrich Müller  <ulm@gentoo.org>  (tiny change)
 
        * emacs.desktop (Exec, Icon, Categories): Fix entries.
 
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
index 2e56539f210..f59023eae62 100644
--- a/etc/ERC-NEWS
+++ b/etc/ERC-NEWS
@@ -228,6 +228,12 @@ with a legitimate use for this option likely also 
possesses the
 knowledge to rig up a suitable analog with minimal effort.  That said,
 the road to removal is long.
 
+** The 'track' module always ignores date stamps.
+Users of the stamp module who leave 'erc-insert-timestamp-function'
+set to its default of 'erc-insert-timestamp-left-and-right' will find
+that date stamps no longer affect the mode line, even for IRC commands
+not included in 'erc-track-exclude-types'.
+
 ** Option 'erc-warn-about-blank-lines' is more informative.
 Enabled by default, this option now produces more useful feedback
 whenever ERC rejects prompt input containing whitespace-only lines.
@@ -288,6 +294,29 @@ ERC also provisionally reserves the same depth interval for
 continue to modify non-ERC hooks locally whenever possible, especially
 in new code.
 
+*** A singular entry point for inserting messages.
+Displaying "local" messages, like help text and interactive-command
+feedback, in ERC buffers has never been straightforward.  As such,
+ancient patterns, like the pairing of preformatted "notice" text with
+ERC's oldest insertion function, 'erc-display-line', still appear
+quite frequently in the wild despite having been largely phased out of
+ERC's own code base in 2002.  That this example has endured makes some
+sense because it's probably seen as less cumbersome than fiddling with
+the more powerful and complicated 'erc-display-message'.
+
+The latest twist in this saga comes with this release, in which a
+healthy bit of "pre-insertion" business has taken up residence in
+'erc-display-message'.  While this would seem to put antiquated
+patterns, like the above mentioned 'erc-make-notice' combo, at risk of
+having messages ignored or subject to degraded treatment by built-in
+modules, an adaptive measure has been introduced that recasts
+'erc-display-line' as a thin wrapper around 'erc-display-message'.
+And though nothing of the sort has been done for the lower-level
+'erc-display-line-1' (now an obsolete alias for 'erc-insert-line'),
+some last-ditch fallback code is in place to ensure baseline
+functionality.  As always, if you find these developments disturbing,
+please say so on the tracker.
+
 *** ERC now manages timestamp-related properties a bit differently.
 For starters, the 'cursor-sensor-functions' text property is absent by
 default unless the option 'erc-echo-timestamps' is already enabled on
@@ -325,7 +354,9 @@ leading portion of message bodies as well as special casing 
to act on
 these areas without inflicting collateral damage.  It may also be
 worth noting that as consequence of these changes, the internally
 managed variable 'erc-timestamp-last-inserted-left' no longer records
-the final trailing newline in 'erc-timestamp-format-left'.
+the final trailing newline in 'erc-timestamp-format-left'.  If you
+must, see variable 'erc-stamp-prepend-date-stamps-p' for a temporary
+escape hatch.
 
 *** The role of a module's Custom group is now more clearly defined.
 Associating built-in modules with Custom groups and provided library
@@ -402,6 +433,24 @@ use of 'insert-before-markers' instead of 'insert'.  As 
always, users
 feeling unduly inconvenienced by these changes are encouraged to voice
 their concerns on the bug list.
 
+*** Introducing new ways to detect ERC buffer types.
+The old standby 'erc-default-target' has served ERC well for over two
+decades.  But a lesser known gotcha affecting its use has always
+haunted an unlucky few, that is, the function has always returned
+non-nil in "unjoined" channel buffers (those that the client has
+parted with or been kicked from).  While perhaps not itself a major
+footgun, recessive pitfalls rooted in this subtlety continue to affect
+dependent functions, like 'erc-get-buffer'.
+
+To discourage misuse of 'erc-default-target', ERC 5.6 offers an
+alternative in the function 'erc-target', which is identical to the
+former except for its disregard for "joinedness."  As a related bonus,
+the dependent function 'erc-server-buffer-p' is being rebranded as
+'erc-server-or-unjoined-channel-buffer-p'.  Unfortunately, this
+release lacks a similar solution for detecting "joinedness" directly,
+but users can turn to 'xor'-ing 'erc-default-target' and 'erc-target'
+as a makeshift kludge.
+
 *** Miscellaneous changes
 Two helper macros from GNU ELPA's Compat library are now available to
 third-party modules as 'erc-compat-call' and 'erc-compat-function'.
diff --git a/etc/NEWS b/etc/NEWS
index 129017f7dbe..9c0f28e3fa9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -62,6 +62,19 @@ more details.
 
 ** Emacs now supports Unicode Standard version 15.1.
 
++++
+** The Network Security Manager now warns about 3DES by default.
+This cypher is no longer recommended owing to a major vulnerability
+disclosed in 2016, and its small 112 bit key size.  Emacs now warns
+about its use also when 'network-security-level' is set to 'medium'
+(the default).  See 'network-security-protocol-checks'.
+
+---
+** The Network Security Manager now warns about <2048 bits in DH key exchange.
+Emacs used to warn for Diffie-Hellman key exchanges with prime numbers
+smaller than 1024 bits.  Since more servers now support it, this
+number has been bumped to 2048 bits.
+
 ** Help
 
 *** 'describe-function' shows function inferred type when available.
@@ -135,6 +148,27 @@ window systems other than Nextstep.
 When this minor mode is enabled, buttons representing modifier keys
 are displayed along the tool bar.
 
++++
+** 'd' in the mode line now indicates that the window is dedicated.
+Windows have always been able to be dedicated to a specific buffer;
+see 'window-dedicated-p'.  Now the mode line indicates the dedicated
+status of a window, with 'd' appearing in the mode line if a window is
+dedicated and 'D' if the window is strongly dedicated.  This indicator
+appears before the buffer name, and after the buffer modification and
+remote buffer indicators (usually "---" together).
+
++++
+** New command 'toggle-window-dedicated'.
+This makes it easy to interactively mark a specific window as
+dedicated, so it won't be reused by 'display-buffer'.  This can be
+useful for complicated window setups.  It is bound to 'C-x w d'
+globally.
+
+** cl-print
+*** You can expand the "..." truncation everywhere.
+The code that allowed "..." to be expanded in the *Backtrace* should
+now work anywhere the data is generated by `cl-print`.
+
 ---
 ** New user option 'uniquify-dirname-transform'.
 This can be used to customize how buffer names are uniquified, by
@@ -187,6 +221,11 @@ right-aligned to is controlled by the new user option
 It can be used to add, remove and reorder functions that change
 the appearance of every tab on the tab bar.
 
++++
+** New optional argument for modifying directory local variables
+The commands 'add-dir-local-variable', 'delete-dir-local-variable' and
+'copy-file-locals-to-dir-locals' now take an optional prefix argument,
+to enter the file you want to modify.
 ** Miscellaneous
 
 ---
@@ -194,6 +233,17 @@ the appearance of every tab on the tab bar.
 It can be used to customize the look of the appointment notification
 displayed on the mode line when 'appt-display-mode-line' is non-nil.
 
+** Emacs Server and Client
+
+---
+*** 'server-eval-args-left' can be used to pop and eval subsequent args.
+When '--eval' is passed to emacsclient and Emacs is evaluating each
+argument, this variable is set to those arguments not yet evaluated.
+It can be used to 'pop' arguments and process them by the function
+called in the '--eval' expression, which is useful when those
+arguments contain arbitrary characters that otherwise might require
+elaborate and error-prone escaping (to protect them from the shell).
+
 
 * Editing Changes in Emacs 30.1
 
@@ -412,6 +462,14 @@ appropriate, but still allow piping the output elsewhere 
if desired.
 For more information, see the "(eshell) Built-ins" node in the Eshell
 manual.
 
++++
+*** New special reference type '#<marker POSITION BUFFER>'.
+This special reference type returns a marker at 'POSITION' in
+'BUFFER'.  You can insert it by typing or using the new interactive
+command 'eshell-insert-marker'.  You can also insert markers of any
+type with the new command 'eshell-insert-special-reference'.  See the
+"(eshell) Arguments" node in the Eshell manual for more details.
+
 +++
 *** New splice operator for Eshell dollar expansions.
 Dollar expansions in Eshell now let you splice the elements of the
@@ -486,6 +544,10 @@ When this option is non-nil, remote file names are not 
completed by
 Pcomplete.  Packages, like 'shell-mode', could set this in order to
 suppress remote file name completion at all.
 
+---
+*** Completion for the 'doas' command has been added.
+Command completion for 'doas' in Eshell and Shell mode will now work.
+
 ** Shell Mode
 
 +++
@@ -723,6 +785,13 @@ interactive Python interpreter specified by 
'python-interpreter'.
 *** New ':vc' keyword.
 This keyword enables the user to install packages using 'package-vc'.
 
+** Gnus
+
+*** The 'nnweb-type' option 'gmane' has been removed.
+The gmane.org website is, sadly, down since a number of years with no
+prospect of it coming back.  Therefore, it is no longer valid to set
+the user option 'nnweb-type' to the 'gmane'.
+
 ** Rmail
 
 ---
@@ -812,6 +881,16 @@ value of "perl-code" is useful for trailing POD and for 
AutoSplit
 modules, the value "comment" makes cperl-mode treat trailers as
 comment, like perl-mode does.
 
+*** Commands using the Perl info page are obsolete.
+
+The Perl documentation in info format is no longer distributed with
+Perl or on CPAN since more than 10 years.  Perl documentation can be
+read with 'cperl-perldoc' instead.
+
+*** Highlighting trailing whitespace has been removed.
+The user option 'cperl-invalid-face' is now obsolete, and does
+nothing.  See the user option 'show-trailing-whitespace' instead.
+
 ** Emacs Sessions (Desktop)
 
 +++
@@ -854,14 +933,6 @@ This can help avoid some awkward skip conditions.  For 
example
 '(skip-unless (not noninteractive))' can be changed to the easier
 to read '(skip-when noninteractive)'.
 
-** Checkdoc
-
----
-*** New checkdock warning if not using lexical-binding.
-Checkdoc now warns if the first line of an Emacs Lisp file does not
-end with a "-*- lexical-binding: t -*-" cookie.  Customize the user
-option 'checkdoc-lexical-binding-flag' to nil to disable this warning.
-
 ** URL
 
 +++
@@ -893,6 +964,19 @@ When this is non-nil, the lines of key sequences are 
displayed with
 the most recent line first.  This is can be useful when working with
 macros with many lines, such as from 'kmacro-edit-lossage'.
 
+** Miscellaneous
+
+---
+*** Webjump now assumes URIs are HTTPS instead of HTTP.
+For links in 'webjump-sites' without an explicit URI scheme, it was
+previously assumed that they should be prefixed with "http://";.  Such
+URIs are now prefixed with "https://"; instead.
+
+** Customize
++++
+*** New command customize-dirlocals
+This command pops up a buffer to edit the settings in .dir-locals.el
+
 
 * New Modes and Packages in Emacs 30.1
 
@@ -961,6 +1045,13 @@ the file listing's performance is still optimized.
 
 * Incompatible Lisp Changes in Emacs 30.1
 
+** `buffer-match-p and `match-buffers` take `&rest args`
+They used to take a single `&optional arg` and were documented to use
+an unreliable hack to try and support condition predicates that
+don't accept this optional arg.
+The new semantics makes no such accommodation, but the code still
+supports it (with a warning) for backward compatibility.
+
 ** 'post-gc-hook' runs after updating 'gcs-done' and 'gcs-elapsed'.
 
 ---
@@ -1041,6 +1132,9 @@ Use 'define-minor-mode' and 
'define-globalized-minor-mode' instead.
 ** The obsolete calling convention of 'sit-for' has been removed.
 That convention was: (sit-for SECONDS MILLISEC &optional NODISP)
 
+** The 'millisec' argument of 'sleep-for' has been declared obsolete.
+Use a float value for the first argument instead.
+
 ** 'eshell-process-wait-{seconds,milliseconds}' options are now obsolete.
 Instead, use 'eshell-process-wait-time', which supports floating-point
 values.
@@ -1048,6 +1142,16 @@ values.
 
 * Lisp Changes in Emacs 30.1
 
++++
+** Drag-and-drop functions can now be called once for compound drops.
+It is now possible for drag-and-drop handler functions to respond to
+drops incorporating more than one URL.  Functions capable of this must
+set their 'dnd-multiple-handler' symbol properties to a non-nil value.
+See the Info node "(elisp)Drag and Drop".
+
+Incident to this change, the function 'dnd-handle-one-url' has been
+made obsolete, for it cannot take these new handlers into account.
+
 ** New function 're-disassemble' to see the innards of a regexp.
 If you compiled with '--enable-checking', you can use this to help debug
 either your regexp performance problems or the regexp engine.
@@ -1100,6 +1204,14 @@ instead of "ctags", "ebrowse", "etags", "hexl", 
"emacsclient", and
 "rcs2log", when starting one of these built in programs in a
 subprocess.
 
++++
+** New variable 'case-symbols-as-words' affects case operations for symbols.
+If non-nil, then case operations such as 'upcase-initials' or
+'replace-match' (with nil FIXEDCASE) will treat the entire symbol name
+as a single word.  This is useful for programming languages and styles
+where only the first letter of a symbol's name is ever capitalized.
+The default value of this variable is nil.
+
 +++
 ** 'x-popup-menu' now understands touch screen events.
 When a 'touchscreen-begin' or 'touchscreen-end' event is passed as the
@@ -1169,6 +1281,30 @@ sexp-related motion commands.
 
 ** New or changed byte-compilation warnings
 
+---
+*** Warn about missing 'lexical-binding' directive.
+The compiler now warns if an Elisp file lacks the standard
+'-*- lexical-binding: ... -*-' cookie on the first line.
+This line typically looks something like
+
+    ;;; My little pony mode  -*- lexical-binding: t -*-
+
+It is needed to inform the compiler about which dialect of ELisp
+your code is using: the modern dialect with lexical binding or
+the old dialect with only dynamic binding.
+
+Lexical binding avoids some name conflicts and allows the compiler to
+detect more mistakes and generate more efficient code, so it is
+recommended.  For how to adapt your code to lexical binding, see the
+manual section "(elisp) Converting to Lexical Binding".
+
+If your code cannot be converted to lexical binding, you can insert
+the line
+
+    ;;; -*- lexical-binding: nil -*-
+
+first in the file to declare that it uses the old dialect.
+
 ---
 *** Warn about empty bodies for more special forms and macros.
 The compiler now warns about an empty body argument to 'when',
@@ -1327,6 +1463,16 @@ Since circular alias chains now cannot occur, 
'function-alias-p',
 'indirect-function' and 'indirect-variable' will never signal an error.
 Their 'noerror' arguments have no effect and are therefore obsolete.
 
++++
+** 'treesit-font-lock-rules' now accepts additional global keywords.
+When supplied with ':default-language LANGUAGE', rules after it will
+default to use 'LANGUAGE'.
+
+---
+** New optional argument to 'modify-dir-local-variable'
+A 5th argument, optional, has been added to
+'modify-dir-local-variable'.  It can be used to specify which
+dir-locals file to modify.
 
 * Changes in Emacs 30.1 on Non-Free Operating Systems
 
diff --git a/etc/emacsclient-mail.desktop b/etc/emacsclient-mail.desktop
index 0a2420ddead..4f7f00ebefd 100644
--- a/etc/emacsclient-mail.desktop
+++ b/etc/emacsclient-mail.desktop
@@ -1,10 +1,7 @@
 [Desktop Entry]
 Categories=Network;Email;
 Comment=GNU Emacs is an extensible, customizable text editor - and more
-# We want to pass the following commands to the shell wrapper:
-# u=$(echo "$1" | sed 's/[\"]/\\&/g'); exec emacsclient --alternate-editor= 
--display="$DISPLAY" --eval "(message-mailto \"$u\")"
-# Special chars '"', '$', and '\' must be escaped as '\\"', '\\$', and '\\\\'.
-Exec=sh -c "u=\\$(echo \\"\\$1\\" | sed 's/[\\\\\\"]/\\\\\\\\&/g'); exec 
emacsclient --alternate-editor= --display=\\"\\$DISPLAY\\" --eval 
\\"(message-mailto \\\\\\"\\$u\\\\\\")\\"" sh %u
+Exec=emacsclient --alternate-editor= --eval "(message-mailto (pop 
server-eval-args-left))" %u
 Icon=emacs
 Name=Emacs (Mail, Client)
 MimeType=x-scheme-handler/mailto;
@@ -16,7 +13,7 @@ Actions=new-window;new-instance;
 
 [Desktop Action new-window]
 Name=New Window
-Exec=sh -c "u=\\$(echo \\"\\$1\\" | sed 's/[\\\\\\"]/\\\\\\\\&/g'); exec 
emacsclient --alternate-editor= --create-frame --eval \\"(message-mailto 
\\\\\\"\\$u\\\\\\")\\"" sh %u
+Exec=emacsclient --alternate-editor= --create-frame --eval "(message-mailto 
(pop server-eval-args-left))" %u
 
 [Desktop Action new-instance]
 Name=New Instance
diff --git a/etc/publicsuffix.txt b/etc/publicsuffix.txt
index 456b8aeaf0b..956110851a4 100644
--- a/etc/publicsuffix.txt
+++ b/etc/publicsuffix.txt
@@ -14414,7 +14414,7 @@ alpha.bounty-full.com
 beta.bounty-full.com
 
 // Smallregistry by Promopixel SARL: https://www.smallregistry.net
-// Former AFNIC's SLDs 
+// Former AFNIC's SLDs
 // Submitted by Jérôme Lipowicz <support@promopixel.com>
 aeroport.fr
 avocat.fr
diff --git a/java/org/gnu/emacs/EmacsNative.java 
b/java/org/gnu/emacs/EmacsNative.java
index 7d7e1e5d831..f15927bb3a7 100644
--- a/java/org/gnu/emacs/EmacsNative.java
+++ b/java/org/gnu/emacs/EmacsNative.java
@@ -39,6 +39,9 @@ public final class EmacsNative
   /* Like `dup' in C.  */
   public static native int dup (int fd);
 
+  /* Like `close' in C.  */
+  public static native int close (int fd);
+
   /* Obtain the fingerprint of this build of Emacs.  The fingerprint
      can be used to determine the dump file name.  */
   public static native String getFingerprint ();
diff --git a/java/org/gnu/emacs/EmacsOpenActivity.java 
b/java/org/gnu/emacs/EmacsOpenActivity.java
index 0c0da6acd1f..a5e8be2f238 100644
--- a/java/org/gnu/emacs/EmacsOpenActivity.java
+++ b/java/org/gnu/emacs/EmacsOpenActivity.java
@@ -462,10 +462,30 @@ public final class EmacsOpenActivity extends Activity
            /* Escape the special characters $ and " before enclosing
               the string within the `message-mailto' wrapper.  */
            fileName = uri.toString ();
+
+           /* If fileName is merely mailto: (absent either an email
+              address or content), then the program launching Emacs
+              conceivably provided such an URI to exclude non-email
+              programs from being enumerated within the Share dialog;
+              whereupon Emacs should replace it with any address
+              provided as EXTRA_EMAIL.  */
+
+           if (fileName.equals ("mailto:";) || fileName.equals ("mailto://";))
+             {
+               tem = intent.getCharSequenceExtra (Intent.EXTRA_EMAIL);
+
+               if (tem != null)
+                 fileName = "mailto:"; + tem;
+             }
+
+           /* Subsequently, escape fileName such that it is rendered
+              safe to append to the command line.  */
+
            fileName = (fileName
                        .replace ("\\", "\\\\")
                        .replace ("\"", "\\\"")
                        .replace ("$", "\\$"));
+
            fileName = "(message-mailto \"" + fileName + "\" ";
 
            /* Parse the intent itself to ascertain if any
diff --git a/java/org/gnu/emacs/EmacsSdk11Clipboard.java 
b/java/org/gnu/emacs/EmacsSdk11Clipboard.java
index b8a43496b6d..b068a89831e 100644
--- a/java/org/gnu/emacs/EmacsSdk11Clipboard.java
+++ b/java/org/gnu/emacs/EmacsSdk11Clipboard.java
@@ -245,6 +245,8 @@ public final class EmacsSdk11Clipboard extends 
EmacsClipboard
     if (data == null || data.getItemCount () < 1)
       return null;
 
+    fd = -1;
+
     try
       {
        uri = data.getItemAt (0).getUri ();
@@ -267,12 +269,34 @@ public final class EmacsSdk11Clipboard extends 
EmacsClipboard
        /* Close the original offset.  */
        assetFd.close ();
       }
+    catch (SecurityException e)
+      {
+       /* Guarantee a file descriptor duplicated or detached is
+          ultimately closed if an error arises.  */
+
+       if (fd != -1)
+         EmacsNative.close (fd);
+
+       return null;
+      }
     catch (FileNotFoundException e)
       {
+       /* Guarantee a file descriptor duplicated or detached is
+          ultimately closed if an error arises.  */
+
+       if (fd != -1)
+         EmacsNative.close (fd);
+
        return null;
       }
     catch (IOException e)
       {
+       /* Guarantee a file descriptor duplicated or detached is
+          ultimately closed if an error arises.  */
+
+       if (fd != -1)
+         EmacsNative.close (fd);
+
        return null;
       }
 
diff --git a/java/org/gnu/emacs/EmacsWindow.java 
b/java/org/gnu/emacs/EmacsWindow.java
index 386eaca8c41..d7a37a8d57f 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -152,6 +152,10 @@ public final class EmacsWindow extends EmacsHandleObject
   /* The position of this window relative to the root window.  */
   public int xPosition, yPosition;
 
+  /* The position of the last drag and drop event received; both
+     values are -1 if no drag and drop operation is under way.  */
+  private int dndXPosition, dndYPosition;
+
   public
   EmacsWindow (short handle, final EmacsWindow parent, int x, int y,
               int width, int height, boolean overrideRedirect)
@@ -202,6 +206,9 @@ public final class EmacsWindow extends EmacsHandleObject
            return size () > 10;
          }
        };
+
+    dndXPosition = -1;
+    dndYPosition = -1;
   }
 
   public void
@@ -1605,6 +1612,7 @@ public final class EmacsWindow extends EmacsHandleObject
     String type;
     Uri uri;
     EmacsActivity activity;
+    StringBuilder builder;
 
     x = (int) event.getX ();
     y = (int) event.getY ();
@@ -1616,11 +1624,26 @@ public final class EmacsWindow extends EmacsHandleObject
        return true;
 
       case DragEvent.ACTION_DRAG_LOCATION:
-       /* Send this drag motion event to Emacs.  */
-       EmacsNative.sendDndDrag (handle, x, y);
+       /* Send this drag motion event to Emacs.  Skip this when the
+          integer position hasn't changed, for Android sends events
+          even if the movement from the previous position of the drag
+          is less than 1 pixel on either axis.  */
+
+       if (x != dndXPosition || y != dndYPosition)
+         {
+           EmacsNative.sendDndDrag (handle, x, y);
+           dndXPosition = x;
+           dndYPosition = y;
+         }
+
        return true;
 
       case DragEvent.ACTION_DROP:
+       /* Reset this view's record of the previous drag and drop
+          event's position.  */
+       dndXPosition = -1;
+       dndYPosition = -1;
+
        /* Judge whether this is plain text, or if it's a file URI for
           which permissions must be requested.  */
 
@@ -1659,38 +1682,59 @@ public final class EmacsWindow extends EmacsHandleObject
                EmacsNative.sendDndUri (handle, x, y, type);
                return true;
              }
-           else
-             {
-               /* If the item dropped is a URI, send it to the main
-                  thread.  */
+         }
 
-               uri = data.getItemAt (0).getUri ();
+       /* There's no plain text data within this clipboard item, so
+          each item within should be treated as a content URI
+          designating a file.  */
 
-               /* Attempt to acquire permissions for this URI;
-                  failing which, insert it as text instead.  */
+       /* Collect the URIs into a string with each suffixed
+          by newlines, much as in a text/uri-list.  */
+       builder = new StringBuilder ();
 
-               if (uri != null
-                   && uri.getScheme () != null
-                   && uri.getScheme ().equals ("content")
-                   && (activity = EmacsActivity.lastFocusedActivity) != null)
-                 {
-                   if (activity.requestDragAndDropPermissions (event) == null)
-                     uri = null;
-                 }
-
-               if (uri != null)
-                 EmacsNative.sendDndUri (handle, x, y, uri.toString ());
-               else
-                 {
-                   type = (data.getItemAt (0)
-                           .coerceToText (EmacsService.SERVICE)
-                           .toString ());
-                   EmacsNative.sendDndText (handle, x, y, type);
-                 }
+       for (i = 0; i < itemCount; ++i)
+         {
+           /* If the item dropped is a URI, send it to the
+              main thread.  */
+
+           uri = data.getItemAt (i).getUri ();
+
+           /* Attempt to acquire permissions for this URI;
+              failing which, insert it as text instead.  */
+                   
+           if (uri != null
+               && uri.getScheme () != null
+               && uri.getScheme ().equals ("content")
+               && (activity = EmacsActivity.lastFocusedActivity) != null)
+             {
+               if ((activity.requestDragAndDropPermissions (event) == null))
+                 uri = null;
+             }
 
-               return true;
+           if (uri != null)
+             builder.append (uri.toString ()).append ("\n");
+           else
+             {
+               /* Treat each URI that Emacs cannot secure
+                  permissions for as plain text.  */
+               type = (data.getItemAt (i)
+                       .coerceToText (EmacsService.SERVICE)
+                       .toString ());
+               EmacsNative.sendDndText (handle, x, y, type);
              }
          }
+
+       /* Now send each URI to Emacs.  */
+
+       if (builder.length () > 0)
+         EmacsNative.sendDndUri (handle, x, y, builder.toString ());
+       return true;
+
+      default:
+       /* Reset this view's record of the previous drag and drop
+          event's position.  */
+       dndXPosition = -1;
+       dndYPosition = -1;
       }
 
     return true;
diff --git a/lib-src/ChangeLog.1 b/lib-src/ChangeLog.1
index 136e8917d50..7a540979613 100644
--- a/lib-src/ChangeLog.1
+++ b/lib-src/ChangeLog.1
@@ -1853,7 +1853,7 @@
        * emacsclient.c (main): Remove unused variables.
        (start_daemon_and_retry_set_socket): Use EXIT_FAILURE.
 
-2010-09-25  Ulrich Mueller  <ulm@gentoo.org>
+2010-09-25  Ulrich Müller  <ulm@gentoo.org>
 
        * etags.c (compressors, print_language_names): Support xz compression.
 
@@ -2498,7 +2498,7 @@
        * makefile.w32-in ($(BLD)/sorted-doc.$(O)): Remove spurious backslash.
        Reported by Guillaume Conjat <gconjat.ext@orange-ftgroup.com>.
 
-2008-10-29  Ulrich Mueller  <ulm@gentoo.org>
+2008-10-29  Ulrich Müller  <ulm@gentoo.org>
 
        * emacsclient.c (set_local_socket): Use TMPDIR (default /tmp)
        instead of hardcoded /tmp.
@@ -2539,7 +2539,7 @@
        * Makefile.in (CFLAGS): Drop -universal under NS_IMPL_COCOA.
        (.m.o): Dispense with GNUstep-specific flags.
 
-2008-08-05  Ulrich Mueller  <ulm@gentoo.org>
+2008-08-05  Ulrich Müller  <ulm@gentoo.org>
 
        * pop.c (socket_connection): Add conditionals for
        HAVE_KRB5_ERROR_TEXT and HAVE_KRB5_ERROR_E_TEXT to support
@@ -3003,7 +3003,7 @@
 
        * Makefile.in (etags, ctags): Define EMACS_NAME as "GNU Emacs".
 
-2007-02-20  Ulrich Mueller  <ulm@kph.uni-mainz.de>  (tiny change)
+2007-02-20  Ulrich Müller  <ulm@kph.uni-mainz.de>  (tiny change)
 
        * Makefile.in (EMACS, EMACSOPT): New variables.
        (blessmail): Use `--no-site-file' when compiling.
diff --git a/lisp/ChangeLog.12 b/lisp/ChangeLog.12
index 9bc440626dc..88d3a41461c 100644
--- a/lisp/ChangeLog.12
+++ b/lisp/ChangeLog.12
@@ -6789,8 +6789,8 @@
 2006-09-04  Daiki Ueno  <ueno@unixuser.org>
 
        * pgg-gpg.el (pgg-gpg-process-region): Revert two patches from Satyaki
-       Das.  http://article.gmane.org/gmane.emacs.gnus.general/49947
-       http://article.gmane.org/gmane.emacs.gnus.general/50457
+       Das.  http://article.gmane.org/gmane.emacs.gnus.general/49947 [dead 
link]
+       http://article.gmane.org/gmane.emacs.gnus.general/50457 [dead link]
 
 2006-09-03  Chong Yidong  <cyd@stupidchicken.com>
 
diff --git a/lisp/ChangeLog.13 b/lisp/ChangeLog.13
index 49ff87f464c..ac382e1685d 100644
--- a/lisp/ChangeLog.13
+++ b/lisp/ChangeLog.13
@@ -7753,7 +7753,7 @@
        * textmodes/remember.el (remember-buffer):
        Use define-obsolete-function-alias rather than defalias.
 
-2007-11-03  Ulrich Mueller  <ulm@gentoo.org>  (tiny change)
+2007-11-03  Ulrich Müller  <ulm@gentoo.org>  (tiny change)
 
        * simple.el (bad-packages-alist): Anchor semantic regexp.
 
@@ -12516,7 +12516,7 @@
        * net/tramp-ftp.el (top): Autoload `tramp-set-connection-property'.
        (tramp-ftp-file-name-handler): Set "started" property.
 
-2007-08-24  Ulrich Mueller  <ulm@gentoo.org>  (tiny change)
+2007-08-24  Ulrich Müller  <ulm@gentoo.org>  (tiny change)
 
        * files.el (backup-buffer-copy): Don't wrap delete in
        condition-case, only try to delete if file exists.
diff --git a/lisp/ChangeLog.14 b/lisp/ChangeLog.14
index 129621791c0..efaac2869c8 100644
--- a/lisp/ChangeLog.14
+++ b/lisp/ChangeLog.14
@@ -39,7 +39,7 @@
        * language/korean.el (korean-cp949): New coding system.  Set cp949
        as an alias to it.
 
-2009-06-18  Ulrich Mueller  <ulm@gentoo.org>
+2009-06-18  Ulrich Müller  <ulm@gentoo.org>
 
        * pgg-gpg.el (pgg-gpg-lookup-key-owner): Handle colon listings
        format used by GnuPG 2.0.11.
@@ -459,7 +459,7 @@
 
        * subr.el (assoc-default): Doc fix.
 
-2009-04-29  Ulrich Mueller  <ulm@gentoo.org>
+2009-04-29  Ulrich Müller  <ulm@gentoo.org>
 
        * files.el (hack-local-variables-prop-line)
        (hack-local-variables, dir-locals-read-from-file):
@@ -3281,7 +3281,7 @@
        (ispell-find-aspell-dictionaries): Better error message.  Use correct
        dictionary alist for default.  Better fallback default dictionary.
 
-2009-01-16  Ulrich Mueller  <ulm@kph.uni-mainz.de>
+2009-01-16  Ulrich Müller  <ulm@kph.uni-mainz.de>
 
        * international/quail.el (quail-insert-kbd-layout):
        Delete superfluous handling of 8-bit code.  (Bug#1418)
@@ -3736,7 +3736,7 @@
 
        * simple.el (visual-line-mode-map): Remove M-[ and M-] bindings.
 
-2009-01-04  Ulrich Mueller  <ulm@kph.uni-mainz.de>
+2009-01-04  Ulrich Müller  <ulm@kph.uni-mainz.de>
 
        * progmodes/sh-script.el (sh-ancestor-alist): Doc fix.
 
@@ -4380,7 +4380,7 @@
 2008-12-10  Juanma Barranquero  <lekktu@gmail.com>
 
        * net/tramp.el (top): Don't fail if there is no current message.
-       [Ulrich Mueller sent a patch, which I saw too late.]  (Bug#1514)
+       [Ulrich Müller sent a patch, which I saw too late.]  (Bug#1514)
 
 2008-12-10  Kenichi Handa  <handa@m17n.org>
 
@@ -5317,7 +5317,7 @@
        (math-standard-units): Fix typo in constant's description.
        (math-additional-units): Fix typo in docstring.
 
-2008-11-19  Ulrich Mueller  <ulm@kph.uni-mainz.de>
+2008-11-19  Ulrich Müller  <ulm@kph.uni-mainz.de>
 
        * calc/calc-units.el (math-standard-units): Add eps0,
        permittivity of vacuum.
@@ -6087,7 +6087,7 @@
 
        * progmodes/gud.el (gud-tooltip-mode): Use `tooltip-functions'.
 
-2008-10-29  Ulrich Mueller  <ulm@gentoo.org>
+2008-10-29  Ulrich Müller  <ulm@gentoo.org>
 
        * server.el (server-socket-dir): Use TMPDIR (default /tmp) instead
        of hardcoded /tmp.
@@ -6284,7 +6284,7 @@
 
        * pcmpl-rpm.el (pcomplete/rpm): Make "rpm -qp" use file completion.
 
-2008-10-23  Ulrich Mueller  <ulm@kph.uni-mainz.de>
+2008-10-23  Ulrich Müller  <ulm@kph.uni-mainz.de>
 
        * international/mule-cmds.el (describe-language-environment):
        Indent sample text.
@@ -7198,7 +7198,7 @@
        * play/fortune.el (fortune-program-options): Change to a list.
        (fortune-in-buffer): Use apply.
 
-2008-09-20  Ulrich Mueller  <ulm@kph.uni-mainz.de>
+2008-09-20  Ulrich Müller  <ulm@kph.uni-mainz.de>
 
        * emacs-lisp/authors.el: Change encoding of file to utf-8.
        (authors-coding-system): Likewise.
@@ -15985,7 +15985,7 @@
        (imap-message-copyuid-1): Use it.
        (imap-message-appenduid-1): Likewise.  Based on patch by Nathan
        J. Williams in
-       <http://permalink.gmane.org/gmane.emacs.gnus.general/65855>.
+       <http://permalink.gmane.org/gmane.emacs.gnus.general/65855>. [dead link]
 
 2008-04-02  Alan Mackenzie  <acm@muc.de>
 
diff --git a/lisp/ChangeLog.15 b/lisp/ChangeLog.15
index 6bd61211d47..c6026b8b9a8 100644
--- a/lisp/ChangeLog.15
+++ b/lisp/ChangeLog.15
@@ -3931,7 +3931,7 @@
        * emacs-lisp/autoload.el (autoload-find-destination): The function
        coding-system-eol-type may return non-numeric values.  (Bug#7414)
 
-2010-11-18  Ulrich Mueller  <ulm@gentoo.org>
+2010-11-18  Ulrich Müller  <ulm@gentoo.org>
 
        * server.el (server-force-stop): Ensure the server is stopped 
(Bug#7409).
 
@@ -6386,7 +6386,7 @@
        * eshell/esh-util.el, eshell/esh-var.el:
        Remove leading `*' from docs of faces and defcustoms.
 
-2010-09-25  Ulrich Mueller  <ulm@gentoo.org>
+2010-09-25  Ulrich Müller  <ulm@gentoo.org>
 
        * eshell/em-ls.el (eshell-ls-archive-regexp):
        * eshell/esh-util.el (eshell-tar-regexp):
@@ -14019,7 +14019,7 @@
        * font-lock.el (font-lock-refresh-defaults): New function, which
        can be used to let font-lock react to external changes in
        variables like font-lock-defaults and keywords.
-       See http://thread.gmane.org/gmane.emacs.devel/118777/focus=118802
+       See http://thread.gmane.org/gmane.emacs.devel/118777/focus=118802 [dead 
link]
 
 2009-12-28  Dan Nicolaescu  <dann@ics.uci.edu>
 
@@ -14485,7 +14485,7 @@
        color queries.  Recompute faces after getting the background
        color.
 
-2009-12-07  Ulrich Mueller  <ulm@gentoo.org>
+2009-12-07  Ulrich Müller  <ulm@gentoo.org>
 
        * emacs-lisp/bytecomp.el (byte-compile-insert-header): Put the version
        number comment back on its own line, for easier parsing.
@@ -17532,7 +17532,7 @@
        (flyspell-word-search-backward): Remove nil argument in calls to
        flyspell-get-word, since it is not needed now.
 
-2009-10-17  Ulrich Mueller  <ulm@gentoo.org>
+2009-10-17  Ulrich Müller  <ulm@gentoo.org>
 
        * play/doctor.el (doctor-adverbp): Exclude some nouns.  (Bug#4565)
 
diff --git a/lisp/ChangeLog.16 b/lisp/ChangeLog.16
index f7dcda87466..39649ec8ae0 100644
--- a/lisp/ChangeLog.16
+++ b/lisp/ChangeLog.16
@@ -2573,7 +2573,7 @@
 
        * progmodes/grep.el (rgrep): Escape command line.  Sometimes, it
        is too long for Tramp.  See discussion in
-       <http://thread.gmane.org/gmane.emacs.tramp/8233/focus=8244>.
+       <http://thread.gmane.org/gmane.emacs.tramp/8233/focus=8244>. [dead link]
 
        * progmodes/compile.el (compilation-start): Remove line escape
        template.
@@ -15382,7 +15382,7 @@
        * calendar/calendar.el (calendar-mode):
        Locally set scroll-margin to 0.  (Bug#10379)
 
-2012-01-06  Ulrich Mueller  <ulm@gentoo.org>
+2012-01-06  Ulrich Müller  <ulm@gentoo.org>
 
        * play/doctor.el (doctor-death): Escape "," characters.  (Bug#10370)
 
@@ -17133,7 +17133,7 @@
        (mouse-drag-vertical-line): Call mouse-drag-line.
        * window.el (window-at-side-p, windows-at-side): New functions.
 
-2011-10-21  Ulrich Mueller  <ulm@gentoo.org>
+2011-10-21  Ulrich Müller  <ulm@gentoo.org>
 
        * tar-mode.el (tar-grind-file-mode):
        Fix handling of setuid/setgid, handle sticky bit.  (Bug#9817)
diff --git a/lisp/ChangeLog.17 b/lisp/ChangeLog.17
index 3377da7c54d..19b8e1e28eb 100644
--- a/lisp/ChangeLog.17
+++ b/lisp/ChangeLog.17
@@ -24676,7 +24676,7 @@
        * frame.el (display-monitor-attributes-list): Add NS case.
        (ns-display-monitor-attributes-list): Declare.
 
-2013-05-09  Ulrich Mueller  <ulm@gentoo.org>
+2013-05-09  Ulrich Müller  <ulm@gentoo.org>
 
        * descr-text.el (describe-char): Fix %d/%x typo.  (Bug#14360)
 
diff --git a/lisp/ChangeLog.4 b/lisp/ChangeLog.4
index f0dd1295dd7..702a059ce65 100644
--- a/lisp/ChangeLog.4
+++ b/lisp/ChangeLog.4
@@ -1055,7 +1055,7 @@
        (gud-irixdbx-marker-filter): New function.
        (dbx): Insert case for Irix.
 
-1994-04-27  Ulrich Mueller  (ulm@vsnhd1.cern.ch)
+1994-04-27  Ulrich Müller  (ulm@vsnhd1.cern.ch)
 
        * case-table.el (describe-buffer-case-table): Don't use
        text-char-description.
@@ -4189,7 +4189,7 @@
        * paths.el (rmail-spool-directory): Use dgux, not dgux-unix.
        * lpr.el (lpr-command): Use dgux, not dgux-unix.
 
-1993-12-14  Ulrich Mueller  (ulm@vsnhd1.cern.ch)
+1993-12-14  Ulrich Müller  (ulm@vsnhd1.cern.ch)
 
        * gud.el (gud-format-command): Use gud-last-last-frame if
        gud-last-frame is nil.
@@ -4200,7 +4200,7 @@
 
        * info.el (Info-insert-dir): For generated menu items, add ::.
 
-1993-12-13  Ulrich Mueller  (ulm@vsnhd1.cern.ch)
+1993-12-13  Ulrich Müller  (ulm@vsnhd1.cern.ch)
 
        * gud.el (gud-mipsdbx-massage-args, gud-mipsdbx-marker-filter):
        New functions for dbx support on Mips under Ultrix.
diff --git a/lisp/ChangeLog.5 b/lisp/ChangeLog.5
index 96bda7650e2..a9f1beaaae8 100644
--- a/lisp/ChangeLog.5
+++ b/lisp/ChangeLog.5
@@ -5463,7 +5463,7 @@
        (makefile-font-lock-keywords): Use makefile-tab-face.
        (makefile-font-lock-keywords): Use defvar, not defconst.
 
-1994-10-28  Ulrich Mueller  <ulm@vsnhd1.cern.ch>
+1994-10-28  Ulrich Müller  <ulm@vsnhd1.cern.ch>
 
        * iso-acc.el (iso-accents-mode): Variable renamed from
        iso-accents-minor-mode.
diff --git a/lisp/ChangeLog.6 b/lisp/ChangeLog.6
index 0fc8ffcf591..fcad77bd38f 100644
--- a/lisp/ChangeLog.6
+++ b/lisp/ChangeLog.6
@@ -7197,7 +7197,7 @@
 
        * faces.el (x-font-regexp): Add \\(\\) for substring extraction.
 
-1995-07-27  Ulrich Mueller  <ulm@vsnhd1.cern.ch>
+1995-07-27  Ulrich Müller  <ulm@vsnhd1.cern.ch>
 
        * fortran.el (fortran-break-line): Fixed a bug that sometimes
        deleted first character in statement field of continuation line.
diff --git a/lisp/align.el b/lisp/align.el
index a286addb51f..9fa78525ecb 100644
--- a/lisp/align.el
+++ b/lisp/align.el
@@ -577,7 +577,18 @@ The possible settings for `align-region-separate' are:
                     "="
                     (group (zero-or-more (syntax whitespace)))))
      (group . (1 2))
-     (modes . '(conf-toml-mode toml-ts-mode))))
+     (modes . '(conf-toml-mode toml-ts-mode lua-mode lua-ts-mode)))
+
+    (double-dash-comment
+     (regexp . ,(rx (group (zero-or-more (syntax whitespace)))
+                    "--"
+                    (zero-or-more nonl)))
+     (modes  . '(lua-mode lua-ts-mode))
+     (column . comment-column)
+     (valid  . ,(lambda ()
+                  (save-excursion
+                    (goto-char (match-beginning 1))
+                    (not (bolp)))))))
   "A list describing all of the available alignment rules.
 The format is:
 
diff --git a/lisp/auth-source.el b/lisp/auth-source.el
index 365f6697ec8..583b6e57897 100644
--- a/lisp/auth-source.el
+++ b/lisp/auth-source.el
@@ -387,7 +387,6 @@ soon as a function returns non-nil.")
       (cond
        ((equal extension "plist")
         (auth-source-backend
-         source
          :source source
          :type 'plstore
          :search-function #'auth-source-plstore-search
@@ -395,13 +394,11 @@ soon as a function returns non-nil.")
          :data (plstore-open source)))
        ((member-ignore-case extension '("json"))
         (auth-source-backend
-         source
          :source source
          :type 'json
          :search-function #'auth-source-json-search))
        (t
         (auth-source-backend
-         source
          :source source
          :type 'netrc
          :search-function #'auth-source-netrc-search
@@ -449,7 +446,6 @@ soon as a function returns non-nil.")
         (setq source (symbol-name source)))
 
       (auth-source-backend
-       (format "Mac OS Keychain (%s)" source)
        :source source
        :type keychain-type
        :search-function #'auth-source-macos-keychain-search
@@ -490,7 +486,6 @@ soon as a function returns non-nil.")
 
       (if (featurep 'secrets)
           (auth-source-backend
-           (format "Secrets API (%s)" source)
            :source source
            :type 'secrets
            :search-function #'auth-source-secrets-search
@@ -498,7 +493,6 @@ soon as a function returns non-nil.")
         (auth-source-do-warn
          "auth-source-backend-parse: no Secrets API, ignoring spec: %S" entry)
         (auth-source-backend
-         (format "Ignored Secrets API (%s)" source)
          :source ""
          :type 'ignore))))))
 
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 70e4087e131..418ee265e69 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -298,6 +298,35 @@ Value is used for `mode-line-frame-identification', which 
see."
 ;;;###autoload
 (put 'mode-line-frame-identification 'risky-local-variable t)
 
+(defvar mode-line-window-dedicated-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map [mode-line mouse-1] #'toggle-window-dedicated)
+    (purecopy map)) "\
+Keymap for what is displayed by `mode-line-window-dedicated'.")
+
+(defun mode-line-window-control ()
+  "Compute mode line construct for window dedicated state.
+Value is used for `mode-line-window-dedicated', which see."
+  (cond
+   ((eq (window-dedicated-p) t)
+    (propertize
+     "D"
+     'help-echo "Window strongly dedicated to its buffer\nmouse-1: Toggle"
+     'local-map mode-line-window-dedicated-keymap
+     'mouse-face 'mode-line-highlight))
+   ((window-dedicated-p)
+    (propertize
+     "d"
+     'help-echo "Window dedicated to its buffer\nmouse-1: Toggle"
+     'local-map mode-line-window-dedicated-keymap
+     'mouse-face 'mode-line-highlight))
+   (t "")))
+
+(defvar mode-line-window-dedicated '(:eval (mode-line-window-control))
+  "Mode line construct to describe the current window.")
+;;;###autoload
+(put 'mode-line-window-dedicated 'risky-local-variable t)
+
 (defvar-local mode-line-process nil
   "Mode line construct for displaying info on process status.
 Normally nil in most modes, since there is no process to display.")
@@ -676,8 +705,9 @@ By default, this shows the information specified by 
`global-mode-string'.")
                    'mode-line-mule-info
                    'mode-line-client
                    'mode-line-modified
-                   'mode-line-remote)
-              'display '(min-width (5.0)))
+                   'mode-line-remote
+                   'mode-line-window-dedicated)
+              'display '(min-width (6.0)))
             'mode-line-frame-identification
             'mode-line-buffer-identification
             "   "
diff --git a/lisp/calc/calc-units.el b/lisp/calc/calc-units.el
index 3e8f25966ef..f20e5801a01 100644
--- a/lisp/calc/calc-units.el
+++ b/lisp/calc/calc-units.el
@@ -269,8 +269,8 @@
     ;; and mu0 no longer has the previous exact value of 4 pi 10^(-7) H/m.
     ( eps0    "ech^2 / (2 alpha h c)"       "Permittivity of vacuum" )
     ( ε0      "eps0"                        "Permittivity of vacuum" )
-    ( mu0     "1 / (eps0 c^2)"              "Permeability of vacuum") ;; Exact
-    ( μ0      "mu0"                         "Permeability of vacuum") ;; Exact
+    ( mu0     "1 / (eps0 c^2)"              "Permeability of vacuum")
+    ( μ0      "mu0"                         "Permeability of vacuum")
     ( G       "6.67408*10^(-11) m^3/(kg s^2)"    "Gravitational constant" nil
               "6.67408 10^-11 m^3/(kg s^2) (*)")
     ( Nav     "6.02214076*10^(23) / mol"    "Avogadro's constant" nil
diff --git a/lisp/cedet/semantic/imenu.el b/lisp/cedet/semantic/imenu.el
index a28f050f3a0..7f27561c3d2 100644
--- a/lisp/cedet/semantic/imenu.el
+++ b/lisp/cedet/semantic/imenu.el
@@ -32,6 +32,8 @@
 ;;             (setq imenu-create-index-function 'semantic-create-imenu-index)
 ;;             ))
 
+;;; Code:
+
 (require 'semantic)
 (require 'semantic/format)
 (require 'semantic/db)
@@ -134,7 +136,6 @@ Tags of those classes will be given submenu with children.
 By default, a `type' has interesting children.  In Texinfo, however, a
 `section' has interesting children.")
 
-;;; Code:
 (defun semantic-imenu-tag-overlay (tag)
   "Return the overlay belonging to tag.
 If TAG doesn't have an overlay, and instead as a vector of positions,
@@ -469,9 +470,8 @@ Clears all imenu menus that may be depending on the 
database."
 ;; buffer, there is a much more efficient way of doing this.
 ;; Advise `which-function' so that we optionally use semantic tags
 ;; instead, and get better stuff.
-(require 'advice)
 
-(defvar semantic-which-function 'semantic-default-which-function
+(defvar semantic-which-function #'semantic-default-which-function
   "Function to convert semantic tags into `which-function' text.")
 
 (defcustom semantic-which-function-use-color nil
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 706e08d5657..6442ffeac24 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -512,6 +512,13 @@ WIDGET is the widget to apply the filter entries of MENU 
on."
        (push name result)))
     (nreverse result)))
 
+(defun custom--editable-field-p (widget)
+  "Non-nil if WIDGET is an editable-field widget, or inherits from it."
+  (let ((type (widget-type widget)))
+    (while (and type (not (eq type 'editable-field)))
+      (setq type (widget-type (get type 'widget-type))))
+    type))
+
 ;;; Unlispify.
 
 (defvar custom-prefix-list nil
@@ -5366,11 +5373,6 @@ The following properties have special meanings for this 
widget:
 :hidden-states should be a list of widget states for which the
   widget's initial contents are to be hidden.
 
-:custom-form should be a symbol describing how to display and
-  edit the variable---either `edit' (using edit widgets),
-  `lisp' (as a Lisp sexp), or `mismatch' (should not happen);
-  if nil, use the return value of `custom-variable-default-form'.
-
 :shown-value, if non-nil, should be a list whose `car' is the
   variable value to display in place of the current value.
 
@@ -5383,11 +5385,34 @@ The following properties have special meanings for this 
widget:
   :custom-category 'option
   :custom-state nil
   :custom-form nil
-  :value-create 'custom-icon-value-create
+  :value-create #'custom-icon-value-create
   :hidden-states '(standard)
-  :custom-set 'custom-icon-set
-  :custom-reset-current 'custom-redraw
-  :custom-reset-saved 'custom-variable-reset-saved)
+  :action #'custom-icon-action
+  :custom-set #'custom-icon-set
+  :custom-reset-current #'custom-redraw)
+  ;; Not implemented yet.
+  ;; :custom-reset-saved 'custom-icon-reset-saved)
+
+(defvar custom-icon-extended-menu
+  (let ((map (make-sparse-keymap)))
+    (define-key-after map [custom-icon-set]
+      '(menu-item "Set for Current Session" custom-icon-set
+                  :enable (eq (widget-get custom-actioned-widget :custom-state)
+                              'modified)))
+    (when (or custom-file init-file-user)
+      (define-key-after map [custom-icon-save]
+        '(menu-item "Save for Future Sessions" custom-icon-save
+                    :enable (memq
+                             (widget-get custom-actioned-widget :custom-state)
+                             '(modified set changed)))))
+    (define-key-after map [custom-redraw]
+      '(menu-item "Undo Edits" custom-redraw
+                  :enable (memq
+                           (widget-get custom-actioned-widget :custom-state)
+                           '(modified changed))))
+    map)
+  "A menu for `custom-icon' widgets.
+Used in `custom-icon-action' to show a menu to the user.")
 
 (defun custom-icon-value-create (widget)
   "Here is where you edit the icon's specification."
@@ -5517,6 +5542,24 @@ The following properties have special meanings for this 
widget:
          (custom-add-parent-links widget))
        (custom-add-see-also widget)))))
 
+(defun custom-icon-action (widget &optional event)
+  "Show the menu for `custom-icon' WIDGET.
+Optional EVENT is the location for the menu."
+  (if (eq (widget-get widget :custom-state) 'hidden)
+      (custom-toggle-hide widget)
+    (unless (eq (widget-get widget :custom-state) 'modified)
+      (custom-icon-state-set widget))
+    (custom-redraw-magic widget)
+    (let* ((completion-ignore-case t)
+           (custom-actioned-widget widget)
+           (answer (widget-choose (concat "Operation on "
+                                          (custom-unlispify-tag-name
+                                           (widget-get widget :value)))
+                                  custom-icon-extended-menu
+                                  event)))
+      (when answer
+        (funcall answer widget)))))
+
 (defun custom-toggle-hide-icon (visibility-widget &rest _ignore)
   "Toggle the visibility of a `custom-icon' parent widget.
 By default, this signals an error if the parent has unsaved
@@ -5553,10 +5596,21 @@ changes."
       (user-error "Cannot update hidden icon"))
 
     (setq val (custom--icons-widget-value child))
-    (unless (equal val (icon-complete-spec symbol))
-      (custom-variable-backup-value widget))
+    ;; FIXME: What was the intention here?
+    ;; (unless (equal val (icon-complete-spec symbol))
+    ;;   (custom-variable-backup-value widget))
     (custom-push-theme 'theme-icon symbol 'user 'set val)
-    (custom-redraw-magic widget)))
+    (custom-redraw widget)))
+
+(defun custom-icon-save (widget)
+  "Save value of icon edited by widget WIDGET."
+  (custom-set-icons (cons (widget-value widget)
+                          (list
+                           (custom--icons-widget-value
+                            (car (widget-get widget :children))))))
+  (custom-save-all)
+  (custom-icon-state-set widget)
+  (custom-redraw-magic widget))
 
 ;;;###autoload
 (defun customize-icon (icon)
@@ -5645,6 +5699,288 @@ This stores EXP (without evaluating it) as the saved 
spec for SYMBOL."
           (prin1 value (current-buffer)))
         (insert ")\n")))))
 
+;;; Directory Local Variables.
+;; The following code provides an Easy Customization interface to manage
+;; `.dir-locals.el' files.
+;; The main command is `customize-dirlocals'.  It presents a Custom-like buffer
+;; but with a few tweaks.  Variables are inserted in a repeat widget, and
+;; update its associated widget (the one for editing the value) upon the user
+;; hitting RET or TABbing out of it.
+;; This is unlike the `cus-theme.el' interface for editing themes, that prompts
+;; the user for the variable to then create the appropriate widget.
+(defvar-local custom-dirlocals-widget nil
+  "Widget that holds the dir-locals customizations.")
+
+(defvar-local custom-dirlocals-file-widget nil
+  "Widget that holds the name of the dir-locals file being customized.")
+
+(defvar-keymap custom-dirlocals-map
+  :doc "Keymap used in the \"*Customize Dirlocals*\" buffer."
+  :full t
+  :parent widget-keymap
+  "SPC"     #'scroll-up-command
+  "S-SPC"   #'scroll-down-command
+  "DEL"     #'scroll-down-command
+  "C-x C-s" #'Custom-dirlocals-save
+  "q"       #'Custom-buffer-done
+  "n"       #'widget-forward
+  "p"       #'widget-backward)
+
+(defvar custom-dirlocals-field-map
+  (let ((map (copy-keymap custom-field-keymap)))
+    (define-key map "\C-x\C-s" #'Custom-dirlocals-save)
+    (define-key map "\C-m" #'widget-field-activate)
+    map)
+  "Keymap for the editable fields in the \"*Customize Dirlocals*\" buffer .")
+
+(defvar custom-dirlocals-commands
+  '((" Save Settings " Custom-dirlocals-save t
+     "Save Settings to the dir-locals file." "save" "Save" t)
+    (" Undo Edits " Custom-dirlocals-revert-buffer t
+     "Revert buffer, undoing any editions."
+     "refresh" "Undo" t)
+    (" Help for Customize " Custom-help t "Get help for using Customize."
+     "help" "Help" t)
+    (" Exit " Custom-buffer-done t "Exit Customize." "exit" "Exit" t))
+  "Alist of specifications for Customize menu items, tool bar icons and 
buttons.
+See `custom-commands' for further explanation.")
+
+(easy-menu-define
+  Custom-dirlocals-menu (list custom-dirlocals-map
+                              custom-dirlocals-field-map)
+  "Menu used in dirlocals customization buffers."
+  (nconc (list "Custom"
+               (customize-menu-create 'customize))
+         (mapcar (lambda (arg)
+                   (let ((tag     (nth 0 arg))
+                         (command (nth 1 arg))
+                         (visible (nth 2 arg))
+                         (help    (nth 3 arg))
+                         (active  (nth 6 arg)))
+                     (vector tag command :visible (eval visible)
+                             :active `(eq t ',active)
+                             :help help)))
+                 custom-dirlocals-commands)))
+
+(defvar custom-dirlocals-tool-bar-map nil
+  "Keymap for the toolbar in \"*Customize Dirlocals*\" buffer.")
+
+(define-widget 'custom-dirlocals-key 'menu-choice
+  "Menu to choose between possible keys in a dir-locals file.
+
+Possible values are nil, a symbol (standing for a major mode) or a directory
+name."
+  :tag "Specification"
+  :value nil
+  :help-echo "Select a key for the dir-locals specification."
+  :args '((const :tag "All modes" nil)
+          (symbol :tag "Major mode" fundamental-mode)
+          (directory :tag "Subdirectory")))
+
+(define-widget 'custom-dynamic-cons 'cons
+  "A cons widget that changes its 2nd type based on the 1st type."
+  :value-create #'custom-dynamic-cons-value-create)
+
+(defun custom-dynamic-cons-value-create (widget)
+  "Select an appropriate 2nd type for the cons WIDGET and create WIDGET.
+
+The appropriate types are:
+- A symbol, if the value to represent is a minor-mode.
+- A boolean, if the value to represent is either the unibyte value or the
+  subdirs value.
+- A widget type suitable for editing a variable, in case of specifying a
+  variable's value.
+- A sexp widget, if none of the above happens."
+  (let* ((args (widget-get widget :args))
+         (value (widget-get widget :value))
+         (val (car value)))
+    (cond
+     ((eq val 'mode) (setf (nth 1 args)
+                           '(symbol :keymap custom-dirlocals-field-map
+                                    :tag "Minor mode")))
+     ((eq val 'unibyte) (setf (nth 1 args) '(boolean)))
+     ((eq val 'subdirs) (setf (nth 1 args) '(boolean)))
+     ((custom-variable-p val)
+      (let ((w (widget-convert (custom-variable-type val))))
+        (when (custom--editable-field-p w)
+          (widget-put w :keymap custom-dirlocals-field-map))
+        (setf (nth 1 args) w)))
+     (t (setf (nth 1 args) '(sexp :keymap custom-dirlocals-field-map))))
+    (widget-put (nth 0 args) :keymap custom-dirlocals-field-map)
+    (widget-group-value-create widget)))
+
+(defun custom-dirlocals-maybe-update-cons ()
+  "If focusing out from the first widget in a cons widget, update its value."
+  (when-let ((w (widget-at)))
+    (when (widget-get w :custom-dirlocals-symbol)
+      (widget-value-set (widget-get w :parent)
+                        (cons (widget-value w) ""))
+      (widget-setup))))
+
+(define-widget 'custom-dirlocals 'editable-list
+  "An editable list to edit settings in a dir-locals file."
+  :entry-format "%i %d %v"
+  :insert-button-args '(:help-echo "Insert new specification here.")
+  :append-button-args '(:help-echo "Append new specification here.")
+  :delete-button-args '(:help-echo "Delete this specification.")
+  :args '((group :format "%v"
+                 custom-dirlocals-key
+                 (repeat
+                  :tag "Settings"
+                  :inline t
+                  (custom-dynamic-cons
+                   :tag "Setting"
+                   (symbol :action custom-dirlocals-symbol-action
+                           :custom-dirlocals-symbol t)
+                   ;; Will change according to the option being customized.
+                   (sexp :tag "Value"))))))
+
+(defun custom-dirlocals-symbol-action (widget &optional _event)
+  "Action for the symbol WIDGET.
+
+Sets the value of its parent, a cons widget, in order to create an
+appropriate widget to edit the value of WIDGET.
+
+Moves point into the widget that holds the value."
+  (setq widget (or widget (widget-at)))
+  (widget-value-set (widget-get widget :parent)
+                    (cons (widget-value widget) ""))
+  (widget-setup)
+  (widget-forward 1))
+
+(defun custom-dirlocals-change-file (widget &optional _event)
+  "Switch to a buffer to customize the dir-locals file in WIDGET."
+  (customize-dirlocals (expand-file-name (widget-value widget))))
+
+(defun custom-dirlocals--set-widget-vars ()
+  "Set local variables for the Widget library."
+  (custom--initialize-widget-variables)
+  (add-hook 'widget-forward-hook #'custom-dirlocals-maybe-update-cons nil t))
+
+(defmacro custom-dirlocals-with-buffer (&rest body)
+  "Arrange to execute BODY in a \"*Customize Dirlocals*\" buffer."
+  ;; We don't use `custom-buffer-create' because the settings here
+  ;; don't go into the `custom-file'.
+  `(progn
+     (switch-to-buffer "*Customize Dirlocals*")
+     (kill-all-local-variables)
+     (let ((inhibit-read-only t))
+       (erase-buffer))
+     (remove-overlays)
+     (custom-dirlocals--set-widget-vars)
+     ,@body
+     (setq-local tool-bar-map
+                 (or custom-dirlocals-tool-bar-map
+                     ;; Set up `custom-dirlocals-tool-bar-map'.
+                     (let ((map (make-sparse-keymap)))
+                       (mapc
+                        (lambda (arg)
+                          (tool-bar-local-item-from-menu
+                           (nth 1 arg) (nth 4 arg) map custom-dirlocals-map
+                           :label (nth 5 arg)))
+                        custom-dirlocals-commands)
+                       (setq custom-dirlocals-tool-bar-map map))))
+     (setq-local revert-buffer-function #'Custom-dirlocals-revert-buffer)
+     (use-local-map custom-dirlocals-map)
+     (widget-setup)))
+
+(defun custom-dirlocals-get-options ()
+  "Return all options inside a custom-dirlocals widget."
+  (let* ((groups (widget-get custom-dirlocals-widget :children))
+         (repeats (mapcar (lambda (group)
+                            (nth 1 (widget-get group :children)))
+                          groups)))
+    (mapcan (lambda (repeat)
+              (mapcar (lambda (w)
+                        (nth 1 (widget-get w :children)))
+                      (widget-get repeat :children)))
+            repeats)))
+
+(defun custom-dirlocals-validate ()
+  "Non-nil if all customization options validate.
+
+If at least an option doesn't validate, signals an error and moves point
+to the widget with the invalid value."
+  (dolist (opt (custom-dirlocals-get-options))
+    (when-let ((w (widget-apply opt :validate)))
+      (goto-char (widget-get w :from))
+      (error "%s" (widget-get w :error))))
+  t)
+
+(defun Custom-dirlocals-revert-buffer (&rest _ignored)
+  "Revert the buffer for Directory Local Variables customization."
+  (interactive)
+  (customize-dirlocals (widget-get custom-dirlocals-file-widget :value)))
+
+(defun Custom-dirlocals-save (&rest _ignore)
+  "Save the settings to the dir-locals file being customized."
+  (interactive)
+  (when (custom-dirlocals-validate)
+    (let* ((file (widget-value custom-dirlocals-file-widget))
+           (old (widget-get custom-dirlocals-widget :value))
+           (dirlocals (widget-value custom-dirlocals-widget)))
+      (dolist (spec old)
+        (let ((mode (car spec))
+              (settings (cdr spec)))
+          (dolist (setting settings)
+            (delete-dir-local-variable mode (car setting) file))))
+      (dolist (spec dirlocals)
+        (let ((mode (car spec))
+              (settings (cdr spec)))
+          (dolist (setting (reverse settings))
+            (when (memq (car setting) '(mode eval))
+              (delete-dir-local-variable mode (car setting) file))
+            (add-dir-local-variable mode (car setting) (cdr setting) file)))))
+    ;; Write the dir-locals file and kill its buffer, to come back to
+    ;; our own buffer.
+    (write-file (expand-file-name buffer-file-name) nil)
+    (kill-buffer)))
+
+;;;###autoload
+(defun customize-dirlocals (&optional filename)
+  "Customize Directory Local Variables in the current directory.
+
+With optional argument FILENAME non-nil, customize the `.dir-locals.el' file
+that FILENAME specifies."
+  (interactive)
+  (let* ((file (or filename (expand-file-name ".dir-locals.el")))
+         (dirlocals (when (file-exists-p file)
+                      (with-current-buffer (find-file-noselect file)
+                        (goto-char (point-min))
+                        (prog1
+                            (condition-case _
+                                (read (current-buffer))
+                              (end-of-file nil))
+                          (kill-buffer))))))
+    (custom-dirlocals-with-buffer
+     (widget-insert
+      "This buffer is for customizing the Directory Local Variables in:\n")
+     (setq custom-dirlocals-file-widget
+           (widget-create `(file :action ,#'custom-dirlocals-change-file
+                                 ,file)))
+     (widget-insert
+      (substitute-command-keys
+       "
+To select another file, edit the above field and hit RET.
+
+After you enter a user option name under the symbol field,
+be sure to press \\`RET' or \\`TAB', so that the field that holds the
+value changes to an appropriate field for the option.
+
+Type \\`C-x C-s' when you've finished editing it, to save the
+settings to the file."))
+     (widget-insert "\n\n\n")
+     (widget-create 'push-button :tag " Revert "
+                    :action #'Custom-dirlocals-revert-buffer)
+     (widget-insert " ")
+     (widget-create 'push-button :tag " Save Settings "
+                    :action #'Custom-dirlocals-save)
+     (widget-insert "\n\n")
+     (setq custom-dirlocals-widget
+           (widget-create 'custom-dirlocals :value dirlocals))
+     (setq default-directory (file-name-directory file))
+     (goto-char (point-min)))))
+
 (provide 'cus-edit)
 
 ;;; cus-edit.el ends here
diff --git a/lisp/dired.el b/lisp/dired.el
index cc8c74839b9..231d305210b 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1681,7 +1681,9 @@ see `dired-use-ls-dired' for more details.")
       (cond (dir-wildcard
              (setq switches (concat "-d " switches))
              (let* ((default-directory (car dir-wildcard))
-                    (script (format "ls %s %s" switches (cdr dir-wildcard)))
+                    (script (format "%s %s %s"
+                                    insert-directory-program
+                                    switches (cdr dir-wildcard)))
                     (sh (or (and remotep "/bin/sh")
                             (executable-find shell-file-name)
                             (executable-find "sh")))
diff --git a/lisp/dnd.el b/lisp/dnd.el
index 14581e3d414..936534fa32c 100644
--- a/lisp/dnd.el
+++ b/lisp/dnd.el
@@ -42,23 +42,25 @@
 
 ;;;###autoload
 (defcustom dnd-protocol-alist
-  `((,(purecopy "^file:///")  . dnd-open-local-file)   ; XDND format.
-    (,(purecopy "^file://")   . dnd-open-file)         ; URL with host
-    (,(purecopy "^file:")     . dnd-open-local-file)   ; Old KDE, Motif, Sun
-    (,(purecopy "^\\(https?\\|ftp\\|file\\|nfs\\)://") . dnd-open-file))
-
+  `((,(purecopy "^file:///")    . dnd-open-local-file) ; XDND format.
+    (,(purecopy "^file://[^/]") . dnd-open-file)       ; URL with host
+    (,(purecopy "^file:/[^/]")  . dnd-open-local-file) ; Old KDE, Motif, Sun
+    (,(purecopy "^file:[^/]")   . dnd-open-local-file) ; MS-Windows
+    (,(purecopy "^\\(https?\\|ftp\\|nfs\\)://") . dnd-open-file))
   "The functions to call for different protocols when a drop is made.
-This variable is used by `dnd-handle-one-url' and `dnd-handle-file-name'.
+This variable is used by `dnd-handle-multiple-urls'.
 The list contains of (REGEXP . FUNCTION) pairs.
 The functions shall take two arguments, URL, which is the URL dropped and
 ACTION which is the action to be performed for the drop (move, copy, link,
 private or ask).
+If a function's `dnd-multiple-handler' property is set, it is provided
+a list of each URI dropped instead.
 If no match is found here, and the value of `browse-url-browser-function'
 is a pair of (REGEXP . FUNCTION), those regexps are tried for a match.
 If no match is found, the URL is inserted as text by calling `dnd-insert-text'.
 The function shall return the action done (move, copy, link or private)
 if some action was made, or nil if the URL is ignored."
-  :version "22.1"
+  :version "30.1"
   :type '(repeat (cons (regexp) (function)))
   :group 'dnd)
 
@@ -159,7 +161,10 @@ If no match is found here, `browse-url-handlers' and
 `browse-url-default-handlers' are searched for a match.
 If no match is found, just call `dnd-insert-text'.  WINDOW is
 where the drop happened, ACTION is the action for the drop, URL
-is what has been dropped.  Returns ACTION."
+is what has been dropped.  Returns ACTION.
+
+This function has been obsolete since Emacs 30.1; it has been
+supplanted by `dnd-handle-multiple-urls'."
   (let (ret)
     (or
      (catch 'done
@@ -180,6 +185,91 @@ is what has been dropped.  Returns ACTION."
        (setq ret 'private)))
     ret))
 
+(make-obsolete 'dnd-handle-one-url 'dnd-handle-multiple-urls "30.1")
+
+(defun dnd-handle-multiple-urls (window urls action)
+  "Select a handler for, then open, each element of URLS.
+The argument ACTION is the action which must be taken, much as
+that to `dnd-begin-file-drag'.
+
+Assign and give each URL to one of the \"DND handler\" functions
+listed in the variable `dnd-protocol-alist'.  When multiple
+handlers matching the same subset of URLs exist, give precedence
+to the handler assigned the greatest number of URLs.
+
+If a handler is a symbol with the property
+`dnd-multiple-handler', call it with ACTION and a list of every
+URL it is assigned.  Otherwise, call it once for each URL
+assigned with ACTION and the URL in question.
+
+Subsequently open URLs that don't match any handlers opened with
+any handler selected by `browse-url-select-handler', and failing
+even that, insert them with `dnd-insert-text'.
+
+Return a symbol designating the actions taken by each DND handler
+called.  If all DND handlers called return the same symbol,
+return that symbol; otherwise, or if no DND handlers are called,
+return `private'.
+
+Do not rely on the contents of URLS after calling this function,
+for it will be modified."
+  (let ((list nil) (return-value nil))
+    (with-selected-window window
+      (dolist (handler dnd-protocol-alist)
+        (let ((pattern (car handler))
+              (handler (cdr handler)))
+          (dolist (uri urls)
+            (when (string-match pattern uri)
+              (let ((cell (or (cdr (assq handler list))
+                              (let ((cell (cons handler nil)))
+                                (push cell list)
+                                cell))))
+                (unless (memq uri cell)
+                  (setcdr cell (cons uri (cdr cell)))))))))
+      (setq list (nreverse list))
+      ;; While unassessed handlers still exist...
+      (while list
+        ;; Sort list by the number of URLs assigned to each handler.
+        (setq list (sort list (lambda (first second)
+                                (> (length (cdr first))
+                                   (length (cdr second))))))
+        ;; Call the handler in its car before removing each URL from
+        ;; URLs.
+        (let ((handler (caar list))
+              (entry-urls (cdar list)))
+          (setq list (cdr list))
+          (when entry-urls
+            (if (and (symbolp handler)
+                     (get handler 'dnd-multiple-handler))
+                (progn
+                  (let ((value (funcall handler entry-urls action)))
+                    (if (or (not return-value)
+                            (eq return-value value))
+                        (setq return-value value)
+                      (setq return-value 'private)))
+                  (dolist (url entry-urls)
+                    (setq urls (delq url urls))
+                    ;; And each handler-URL list after this.
+                    (dolist (item list)
+                      (setcdr item (delq url (cdr item))))))
+              (dolist (url entry-urls)
+                (let ((value (funcall handler url action)))
+                  (if (or (not return-value) (eq return-value value))
+                      (setq return-value value)
+                    (setq return-value 'private)))
+                (setq urls (delq url urls))
+                ;; And each handler-URL list after this.
+                (dolist (item list)
+                  (setcdr item (delq url (cdr item)))))))))
+      ;; URLS should now incorporate only those which haven't been
+      ;; assigned their own handlers.
+      (dolist (leftover urls)
+        (setq return-value 'private)
+        (if-let ((handler (browse-url-select-handler leftover
+                                                     'internal)))
+            (funcall handler leftover action)
+          (dnd-insert-text window action leftover)))
+      (or return-value 'private))))
 
 (defun dnd-get-local-file-uri (uri)
   "Return an uri converted to file:/// syntax if uri is a local file.
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 17d99c6c51c..31f513ec91b 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -2201,6 +2201,10 @@ See also `emacs-lisp-byte-compile-and-load'."
               filename buffer-file-name))
       ;; Don't inherit lexical-binding from caller (bug#12938).
       (unless (local-variable-p 'lexical-binding)
+        (let ((byte-compile-current-buffer (current-buffer)))
+          (byte-compile-warn-x
+           (position-symbol 'a (point-min))
+           "file has no `lexical-binding' directive on its first line"))
         (setq-local lexical-binding nil))
       (unless (local-variable-p 'symbol-packages)
         (setq-local symbol-packages nil))
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index 440e133f44b..471a2fbdf48 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -128,14 +128,6 @@
 ;; simple style rules to follow which checkdoc will auto-fix for you.
 ;; `y-or-n-p' and `yes-or-no-p' should also end in "?".
 ;;
-;; Lexical binding:
-;;
-;;   We recommend always using lexical binding in new code, and
-;; converting old code to use it.  Checkdoc warns if you don't have
-;; the recommended string "-*- lexical-binding: t -*-" at the top of
-;; the file.  You can disable this check with the user option
-;; `checkdoc-lexical-binding-flag'.
-;;
 ;; Adding your own checks:
 ;;
 ;;   You can experiment with adding your own checks by setting the
@@ -347,12 +339,6 @@ See Info node `(elisp) Documentation Tips' for background."
   :type 'boolean
   :version "28.1")
 
-(defcustom checkdoc-lexical-binding-flag t
-  "Non-nil means generate warnings if file is not using lexical binding.
-See Info node `(elisp) Converting to Lexical Binding' for more."
-  :type 'boolean
-  :version "30.1")
-
 ;; This is how you can use checkdoc to make mass fixes on the Emacs
 ;; source tree:
 ;;
@@ -2391,31 +2377,6 @@ Code:, and others referenced in the style guide."
              (point-min) (save-excursion (goto-char (point-min))
                                          (line-end-position))))
         nil))
-      (when checkdoc-lexical-binding-flag
-        (setq
-         err
-         ;; Lexical binding cookie.
-         (if (not (save-excursion
-                    (save-restriction
-                      (goto-char (point-min))
-                      (narrow-to-region (point) (pos-eol))
-                      (re-search-forward
-                       (rx "-*-" (* (* nonl) ";")
-                           (* space) "lexical-binding:" (* space) "t" (* space)
-                           (* ";" (* nonl))
-                           "-*-")
-                       nil t))))
-             (let ((pos (save-excursion (goto-char (point-min))
-                                        (goto-char (pos-eol))
-                                        (point))))
-               (if (checkdoc-y-or-n-p "There is no lexical-binding cookie!  
Add one?")
-                   (progn
-                     (goto-char pos)
-                     (insert "  -*- lexical-binding: t -*-"))
-                 (checkdoc-create-error
-                  "The first line should end with \"-*- lexical-binding: t 
-*-\""
-                  pos (1+ pos) t)))
-           nil)))
       (setq
        err
        (or
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 722d561b9f4..a4a241d9c63 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -3092,7 +3092,11 @@ To see the documentation for a defined struct type, use
                                  descs)))
              (t
               (error "Structure option %s unrecognized" opt)))))
-    (unless (or include-name type)
+    (unless (or include-name type
+                ;; Don't create a bogus parent to `cl-structure-object'
+                ;; while compiling the (cl-defstruct cl-structure-object ..)
+                ;; in `cl-preloaded.el'.
+                (eq name cl--struct-default-parent))
       (setq include-name cl--struct-default-parent))
     (when include-name (setq include (cl--struct-get-class include-name)))
     (if print-func
@@ -3331,7 +3335,7 @@ To see the documentation for a defined struct type, use
 ;;; Add cl-struct support to pcase
 
 ;;In use by comp.el
-(defun cl--struct-all-parents (class)
+(defun cl--struct-all-parents (class) ;FIXME: Merge with `cl--class-allparents'
   (when (cl--struct-class-p class)
     (let ((res ())
           (classes (list class)))
diff --git a/lisp/emacs-lisp/cl-preloaded.el b/lisp/emacs-lisp/cl-preloaded.el
index 96e288db7d5..03068639575 100644
--- a/lisp/emacs-lisp/cl-preloaded.el
+++ b/lisp/emacs-lisp/cl-preloaded.el
@@ -52,12 +52,12 @@
 
 (defconst cl--typeof-types
   ;; Hand made from the source code of `type-of'.
-  '((integer number number-or-marker atom)
+  '((integer number integer-or-marker number-or-marker atom)
     (symbol-with-pos symbol atom) (symbol atom) (string array sequence atom)
     (cons list sequence)
     ;; Markers aren't `numberp', yet they are accepted wherever integers are
     ;; accepted, pretty much.
-    (marker number-or-marker atom)
+    (marker integer-or-marker number-or-marker atom)
     (overlay atom) (float number number-or-marker atom)
     (window-configuration atom) (process atom) (window atom)
     ;; FIXME: We'd want to put `function' here, but that's only true
@@ -65,7 +65,7 @@
     (subr atom)
     ;; FIXME: We should probably reverse the order between
     ;; `compiled-function' and `byte-code-function' since arguably
-    ;; `subr' and also "compiled functions" but not "byte code functions",
+    ;; `subr' is also "compiled functions" but not "byte code functions",
     ;; but it would require changing the value returned by `type-of' for
     ;; byte code objects, which risks breaking existing code, which doesn't
     ;; seem worth the trouble.
@@ -333,6 +333,9 @@ supertypes from the most specific to least specific.")
                            (cl--class-parents class)))))
     (nreverse parents)))
 
+(eval-and-compile
+  (cl-assert (null (cl--class-parents (cl--find-class 'cl-structure-object)))))
+
 ;; Make sure functions defined with cl-defsubst can be inlined even in
 ;; packages which do not require CL.  We don't put an autoload cookie
 ;; directly on that function, since those cookies only go to cl-loaddefs.
diff --git a/lisp/emacs-lisp/comp-cstr.el b/lisp/emacs-lisp/comp-cstr.el
index 57ae39520c5..ee0ae10539d 100644
--- a/lisp/emacs-lisp/comp-cstr.el
+++ b/lisp/emacs-lisp/comp-cstr.el
@@ -89,8 +89,10 @@ Integer values are handled in the `range' slot.")
 
 (defun comp--cl-class-hierarchy (x)
   "Given a class name `x' return its hierarchy."
-  `(,@(mapcar #'cl--struct-class-name (cl--struct-all-parents
-                                       (cl--struct-get-class x)))
+  `(,@(cl--class-allparents (cl--struct-get-class x))
+    ;; FIXME: AFAICT, `comp--all-classes' will also find those struct types
+    ;; which use :type and can thus be either `vector' or `cons' (the latter
+    ;; isn't `atom').
     atom
     t))
 
@@ -263,12 +265,13 @@ Return them as multiple value."
 ;;; Type handling.
 
 (defun comp--sym-lessp (x y)
-  "Like `string-lessp' but for strings."
+  "Like `string-lessp' but for symbol names."
   (string-lessp (symbol-name x)
                 (symbol-name y)))
 
-(defun comp--direct-supertype (type)
+(defun comp--direct-supertype (type)    ;FIXME: There can be several!
   "Return the direct supertype of TYPE."
+  (declare (obsolete comp--direct-supertype "30.1"))
   (cl-loop
    named outer
    for i in (comp-cstr-ctxt-typeof-types comp-ctxt)
@@ -276,24 +279,50 @@ Return them as multiple value."
                    when (eq j type)
                      do (cl-return-from outer y))))
 
+(defun comp--direct-supertypes (type)
+  "Return the direct supertypes of TYPE."
+  (let ((supers (comp-supertypes type)))
+    (cl-assert (eq type (car supers)))
+    (cl-loop
+     with notdirect = nil
+     with direct = nil
+     for parent in (cdr supers)
+     unless (memq parent notdirect)
+     do (progn
+          (push parent direct)
+          (setq notdirect (append notdirect (comp-supertypes parent))))
+     finally return direct)))
+
 (defun comp--normalize-typeset0 (typeset)
-  ;; For every type search its supertype. If all the subtypes of that
+  ;; For every type search its supertypes.  If all the subtypes of a
   ;; supertype are presents remove all of them, add the identified
   ;; supertype and restart.
+  ;; FIXME: The intention is to return a 100% equivalent but simpler
+  ;; typeset, but this is only the case when the supertype is abstract
+  ;; and "final/closed" (i.e. can't have new subtypes).
   (when typeset
     (while (eq 'restart
                (cl-loop
                 named main
-                for i in typeset
-                for sup = (comp--direct-supertype i)
+                for sup in (cl-remove-duplicates
+                            (apply #'append
+                                   (mapcar #'comp--direct-supertypes typeset)))
                 for subs = (comp--direct-subtypes sup)
-                when (and sup
-                          (length> subs 1)
-                          (cl-every (lambda (x) (member x typeset)) subs))
-                  do (cl-loop for s in subs
-                              do (setq typeset (cl-delete s typeset))
-                              finally (progn (push sup typeset)
-                                           (cl-return-from main 'restart))))))
+                when (and (length> subs 1) ;;FIXME: Why?
+                          ;; Every subtype of `sup` is a subtype of
+                          ;; some element of `typeset`?
+                          ;; It's tempting to just check (member x typeset),
+                          ;; but think of the typeset (marker number),
+                          ;; where `sup' is `integer-or-marker' and `sub'
+                          ;; is `integer'.
+                          (cl-every (lambda (sub)
+                                      (cl-some (lambda (type)
+                                                 (comp-subtype-p sub type))
+                                               typeset))
+                                    subs))
+                do (progn
+                     (setq typeset (cons sup (cl-set-difference typeset subs)))
+                     (cl-return-from main 'restart)))))
     typeset))
 
 (defun comp-normalize-typeset (typeset)
@@ -302,57 +331,54 @@ Return them as multiple value."
 
 (defun comp--direct-subtypes (type)
   "Return all the direct subtypes of TYPE."
-  ;; TODO memoize.
-  (cl-sort
-   (cl-loop for j in (comp-cstr-ctxt-typeof-types comp-ctxt)
-            for res = (cl-loop for i in j
-                               with last = nil
-                               when (eq i type)
-                                 return last
-                               do (setq last i))
-            when res
-              collect res)
-   #'comp--sym-lessp))
+  ;; TODO: memoize.
+  (let ((subtypes ()))
+    (dolist (j (comp-cstr-ctxt-typeof-types comp-ctxt))
+      (let ((occur (memq type j)))
+        (when occur
+          (while (not (eq j occur))
+            (let ((candidate (pop j)))
+              (when (and (not (memq candidate subtypes))
+                         (memq type (comp--direct-supertypes candidate)))
+                (push candidate subtypes)))))))
+    (cl-sort subtypes #'comp--sym-lessp)))
+
+(defun comp--intersection (list1 list2)
+  "Like `cl-intersection` but preserves the order of one of its args."
+  (if (equal list1 list2) list1
+    (let ((res nil))
+      (while list2
+       (if (memq (car list2) list1)
+           (push (car list2) res))
+       (pop list2))
+      (nreverse res))))
 
 (defun comp-supertypes (type)
-  "Return a list of pairs (supertype . hierarchy-level) for TYPE."
+  "Return the ordered list of supertypes of TYPE."
+  ;; FIXME: We should probably keep the results in
+  ;; `comp-cstr-ctxt-typeof-types' (or maybe even precompute them
+  ;; and maybe turn `comp-cstr-ctxt-typeof-types' into a hash-table).
+  ;; Or maybe we shouldn't keep structs and defclasses in it,
+  ;; and just use `cl--class-allparents' when needed (and refuse to
+  ;; compute their direct subtypes since we can't know them).
   (cl-loop
-   named outer
-   with found = nil
-   for l in (comp-cstr-ctxt-typeof-types comp-ctxt)
-   do (cl-loop
-       for x in l
-       for i from (length l) downto 0
-       when (eq type x)
-         do (setf found t)
-       when found
-         collect `(,x . ,i) into res
-       finally (when found
-                 (cl-return-from outer res)))))
-
-(defun comp-common-supertype-2 (type1 type2)
-  "Return the first common supertype of TYPE1 TYPE2."
-  (when-let ((types (cl-intersection
-                     (comp-supertypes type1)
-                     (comp-supertypes type2)
-                     :key #'car)))
-    (car (cl-reduce (lambda (x y)
-                      (if (> (cdr x) (cdr y)) x y))
-                    types))))
-
-(defun comp-common-supertype (&rest types)
-  "Return the first common supertype of TYPES."
-  (or (gethash types (comp-cstr-ctxt-common-supertype-mem comp-ctxt))
-      (puthash types
-               (cl-reduce #'comp-common-supertype-2 types)
-               (comp-cstr-ctxt-common-supertype-mem comp-ctxt))))
+   named loop
+   with above
+   for lane in (comp-cstr-ctxt-typeof-types comp-ctxt)
+   do (let ((x (memq type lane)))
+        (cond
+         ((null x) nil)
+         ((eq x lane) (cl-return-from loop x)) ;A base type: easy case.
+         (t (setq above
+                  (if above (comp--intersection x above) x)))))
+   finally return above))
 
 (defsubst comp-subtype-p (type1 type2)
   "Return t if TYPE1 is a subtype of TYPE2 or nil otherwise."
   (let ((types (cons type1 type2)))
     (or (gethash types (comp-cstr-ctxt-subtype-p-mem comp-ctxt))
         (puthash types
-                 (eq (comp-common-supertype-2 type1 type2) type2)
+                 (memq type2 (comp-supertypes type1))
                  (comp-cstr-ctxt-subtype-p-mem comp-ctxt)))))
 
 (defun comp-union-typesets (&rest typesets)
@@ -360,16 +386,18 @@ Return them as multiple value."
   (or (gethash typesets (comp-cstr-ctxt-union-typesets-mem comp-ctxt))
       (puthash typesets
                (cl-loop
-                with types = (apply #'append typesets)
+                ;; List of (TYPE . SUPERTYPES)", ordered from
+                ;; "most general" to "least general"
+                with typess = (sort (mapcar #'comp-supertypes
+                                            (apply #'append typesets))
+                                    (lambda (l1 l2)
+                                      (<= (length l1) (length l2))))
                 with res = '()
-                for lane in (comp-cstr-ctxt-typeof-types comp-ctxt)
-                do (cl-loop
-                    with last = nil
-                    for x in lane
-                    when (memq x types)
-                      do (setf last x)
-                    finally (when last
-                              (push last res)))
+                for types in typess
+                ;; Don't keep this type if it's a subtype of one of
+                ;; the other types.
+                unless (comp--intersection types res)
+                do (push (car types) res)
                 finally return (comp-normalize-typeset res))
                (comp-cstr-ctxt-union-typesets-mem comp-ctxt))))
 
@@ -863,7 +891,7 @@ Non memoized version of `comp-cstr-intersection-no-mem'."
                            (comp-subtype-p neg-type pos-type))
                    do (cl-loop
                        with found
-                       for (type . _) in (comp-supertypes neg-type)
+                       for type in (comp-supertypes neg-type)
                        when found
                          collect type into res
                        when (eq type pos-type)
diff --git a/lisp/emacs-lisp/comp.el b/lisp/emacs-lisp/comp.el
index 181e5ca96a1..bdc59703de9 100644
--- a/lisp/emacs-lisp/comp.el
+++ b/lisp/emacs-lisp/comp.el
@@ -4180,7 +4180,7 @@ the deferred compilation mechanism."
         (comp-log "\n\n" 1)
         (unwind-protect
             (progn
-              (condition-case err
+              (condition-case-unless-debug err
                   (cl-loop
                    with report = nil
                    for t0 = (current-time)
@@ -4199,7 +4199,8 @@ the deferred compilation mechanism."
                      (comp-log (format "Done compiling %s" data) 0)
                      (cl-loop for (pass . time) in (reverse report)
                               do (comp-log (format "Pass %s took: %fs."
-                                                   pass time) 0))))
+                                                   pass time)
+                                           0))))
                 (native-compiler-skip)
                 (t
                  (let ((err-val (cdr err)))
diff --git a/lisp/emacs-lisp/icons.el b/lisp/emacs-lisp/icons.el
index cb08c1a6b81..9a6d26243c7 100644
--- a/lisp/emacs-lisp/icons.el
+++ b/lisp/emacs-lisp/icons.el
@@ -181,9 +181,9 @@ present if the icon is represented by an image."
         (let ((parent-keywords (icon-spec-keywords elem))
               (current-keywords (icon-spec-keywords current)))
           (while parent-keywords
-            (unless (plist-get (car parent-keywords) current-keywords)
-              (nconc current (take 2 parent-keywords))
-              (setq parent-keywords (cddr parent-keywords))))))))
+            (unless (plist-get current-keywords (car parent-keywords))
+              (nconc current (take 2 parent-keywords)))
+            (setq parent-keywords (cddr parent-keywords)))))))
   merged)
 
 (cl-defmethod icons--create ((_type (eql 'image)) icon keywords)
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index cd80df2c41d..ce5467f3c5c 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -292,14 +292,13 @@ HOW is a symbol to select an entry in 
`advice--how-alist'."
                               (equal function (cdr (assq 'name props))))
                           (list (advice--remove-function rest function)))))))
 
-(defvar advice--buffer-local-function-sample nil
-  "Keeps an example of the special \"run the default value\" functions.
-These functions play the same role as t in buffer-local hooks, and to recognize
-them, we keep a sample here against which to compare.  Each instance is
-different, but `function-equal' will hopefully ignore those differences.")
+(oclosure-define (advice--forward
+                  (:predicate advice--forward-p))
+  "Redirect to the global value of a var.
+These functions act like the t special value in buffer-local hooks.")
 
 (defun advice--set-buffer-local (var val)
-  (if (function-equal val advice--buffer-local-function-sample)
+  (if (advice--forward-p val)
       (kill-local-variable var)
     (set (make-local-variable var) val)))
 
@@ -308,11 +307,10 @@ different, but `function-equal' will hopefully ignore 
those differences.")
   "Buffer-local value of VAR, presumed to contain a function."
   (declare (gv-setter advice--set-buffer-local))
   (if (local-variable-p var) (symbol-value var)
-    (setq advice--buffer-local-function-sample
-          ;; This function acts like the t special value in buffer-local hooks.
-          ;; FIXME: Provide an `advice-bottom' function that's like
-          ;; `advice-cd*r' but also follows through this proxy.
-          (lambda (&rest args) (apply (default-value var) args)))))
+    ;; FIXME: Provide an `advice-bottom' function that's like
+    ;; `advice--cd*r' but also follows through this proxy.
+    (oclosure-lambda (advice--forward) (&rest args)
+      (apply (default-value var) args))))
 
 (eval-and-compile
   (defun advice--normalize-place (place)
diff --git a/lisp/emacs-lisp/smie.el b/lisp/emacs-lisp/smie.el
index 19a0c22027a..2bc7674b8bf 100644
--- a/lisp/emacs-lisp/smie.el
+++ b/lisp/emacs-lisp/smie.el
@@ -56,8 +56,8 @@
 ;; which includes a kind of tutorial to get started with SMIE:
 ;;
 ;;     SMIE: Weakness is Power!  Auto-indentation with incomplete information
-;;     Stefan Monnier, <Programming> Journal 2020, volume 5, issue 1.
-;;     doi: 10.22152/programming-journal.org/2021/5/1
+;;     Stefan Monnier, <Programming> Journal 2021, volume 5, issue 1.
+;;     doi: https://doi.org/10.22152/programming-journal.org/2021/5/1
 
 ;; A good background to understand the development (especially the parts
 ;; building the 2D precedence tables and then computing the precedence levels
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
index 3d34fc97d00..4b5edaa77d2 100644
--- a/lisp/erc/erc-backend.el
+++ b/lisp/erc/erc-backend.el
@@ -1103,7 +1103,7 @@ Change value of property `erc-prompt' from t to `hidden'."
             (erc--register-connection)
           ;; assume event is 'failed
           (erc-with-all-buffers-of-server cproc nil
-                                          (setq erc-server-connected nil))
+            (setq erc-server-connected nil))
           (when erc-server-ping-handler
             (progn (cancel-timer erc-server-ping-handler)
                    (setq erc-server-ping-handler nil)))
@@ -1111,6 +1111,8 @@ Change value of property `erc-prompt' from t to `hidden'."
                               (erc-current-nick) (system-name) "")
           (dolist (buf (erc-buffer-filter (lambda () (boundp 
'erc-channel-users)) cproc))
             (with-current-buffer buf
+              (when (erc--target-channel-p erc--target)
+                (setf (erc--target-channel-joined-p erc--target) nil))
               (setq erc-channel-users (make-hash-table :test 'equal))))
           ;; Hide the prompt
           (erc--hide-prompt cproc)
@@ -1611,7 +1613,9 @@ Would expand to:
 
 \(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)"
   (declare (debug (&define [&name "erc-response-handler@"
-                                  (symbolp &rest symbolp)]
+                                  ;; No `def-edebug-elem-spec' in 27.
+                                  ([&or integerp symbolp]
+                                   &rest [&or integerp symbolp])]
                            &optional sexp sexp def-body))
            (indent defun))
   (if (numberp name) (setq name (intern (format "%03i" name))))
@@ -1729,6 +1733,7 @@ add things to `%s' instead."
                         (with-suppressed-warnings
                             ((obsolete erc-add-default-channel))
                           (erc-add-default-channel chnl))
+                        (setf (erc--target-channel-joined-p erc--target) t)
                         (erc-server-send (format "MODE %s" chnl)))
                       (erc-with-buffer (chnl proc)
                         (erc-channel-begin-receiving-names))
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el
index 8d896e663b5..930e8032f6d 100644
--- a/lisp/erc/erc-common.el
+++ b/lisp/erc/erc-common.el
@@ -81,16 +81,13 @@
   (string "" :type string :documentation "Received name of target.")
   (symbol nil :type symbol :documentation "Case-mapped name as symbol."))
 
-;; At some point, it may make sense to add a query type with an
-;; account field, which may help support reassociation across
-;; reconnects and nick changes (likely requires v3 extensions).
-;;
-;; These channel variants should probably take on a `joined' field to
-;; track "joinedness", which `erc-server-JOIN', `erc-server-PART',
-;; etc. should toggle.  Functions like `erc--current-buffer-joined-p'
-;; may find it useful.
+;; At some point, it may make sense to add a separate query type,
+;; possibly with an account field to help reassociation across
+;; reconnects and nick changes.
+
+(cl-defstruct (erc--target-channel (:include erc--target))
+  (joined-p nil :type boolean :documentation "Whether channel is joined."))
 
-(cl-defstruct (erc--target-channel (:include erc--target)))
 (cl-defstruct (erc--target-channel-local (:include erc--target-channel)))
 
 ;; Beginning in 5.5/29.1, the `tags' field may take on one of two
@@ -427,6 +424,13 @@ nil."
                             ,@forms))
                         ,process)))
 
+(defvar-local erc--target nil
+  "A permanent `erc--target' struct instance in channel and query buffers.")
+
+(define-inline erc-target ()
+  "Return target of current buffer, if any, as a string."
+  (inline-quote (and erc--target (erc--target-string erc--target))))
+
 (defun erc-log-aux (string)
   "Do the debug logging of STRING."
   (let ((cb (current-buffer))
diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el
index 0048956e075..e8f3f624ff1 100644
--- a/lisp/erc/erc-fill.el
+++ b/lisp/erc/erc-fill.el
@@ -145,10 +145,6 @@ Its value should be larger than that of the variable
   :package-version '(ERC . "5.6") ; FIXME sync on release
   :type '(choice (const nil) number))
 
-(defvar erc-fill--spaced-commands '(PRIVMSG NOTICE)
-  "Types of messages to add space between on graphical displays.
-Only considered when `erc-fill-line-spacing' is non-nil.")
-
 (defvar-local erc-fill--function nil
   "Internal copy of `erc-fill-function'.
 Takes precedence over the latter when non-nil.")
@@ -175,11 +171,11 @@ You can put this on `erc-insert-modify-hook' and/or 
`erc-send-modify-hook'."
           (when-let* ((erc-fill-line-spacing)
                       (p (point-min)))
             (widen)
-            (when (or (erc--check-msg-prop 'erc-cmd erc-fill--spaced-commands)
-                      (and-let* ((cmd (save-excursion
-                                        (forward-line -1)
-                                        (get-text-property (point) 'erc-cmd))))
-                        (memq cmd erc-fill--spaced-commands)))
+            (when (or (erc--check-msg-prop 'erc-msg 'msg)
+                      (and-let* ((m (save-excursion
+                                      (forward-line -1)
+                                      (erc--get-inserted-msg-prop 'erc-msg))))
+                        (eq 'msg m)))
               (put-text-property (1- p) p
                                  'line-spacing erc-fill-line-spacing))))))))
 
@@ -463,6 +459,7 @@ is not recommended."
    (kill-local-variable 'erc-fill--wrap-value)
    (kill-local-variable 'erc-fill--function)
    (kill-local-variable 'erc-fill--wrap-visual-keys)
+   (kill-local-variable 'erc-fill--wrap-last-msg)
    (remove-hook 'erc-button--prev-next-predicate-functions
                 #'erc-fill--wrap-merged-button-p t))
   'local)
@@ -479,13 +476,17 @@ variable can be converted to a public one if needed by 
third
 parties.")
 
 (defvar-local erc-fill--wrap-last-msg nil)
-(defvar-local erc-fill--wrap-max-lull (* 24 60 60))
+(defvar erc-fill--wrap-max-lull (* 24 60 60))
 
 (defun erc-fill--wrap-continued-message-p ()
   "Return non-nil when the current speaker hasn't changed.
 That is, indicate whether the text just inserted is from the same
 sender as that of the previous \"PRIVMSG\"."
-  (prog1 (and-let*
+  (and
+   (not (erc--check-msg-prop 'erc-ephemeral))
+   (progn ; preserve blame for now, unprogn on next major change
+     (prog1
+         (and-let*
              ((m (or erc-fill--wrap-last-msg
                      (setq erc-fill--wrap-last-msg (point-min-marker))
                      nil))
@@ -493,8 +494,9 @@ sender as that of the previous \"PRIVMSG\"."
               (props (save-restriction
                        (widen)
                        (and-let*
-                           (((eq 'PRIVMSG (get-text-property m 'erc-cmd)))
-                            ((not (eq (get-text-property m 'erc-msg) 'ACTION)))
+                           (((eq 'msg (get-text-property m 'erc-msg)))
+                            ((not (eq (get-text-property m 'erc-ctcp)
+                                      'ACTION)))
                             ((not (invisible-p m)))
                             (spr (next-single-property-change m 'erc-speaker)))
                          (cons (get-text-property m 'erc-ts)
@@ -509,7 +511,7 @@ sender as that of the previous \"PRIVMSG\"."
               ((not (erc--check-msg-prop 'erc-ctcp 'ACTION)))
               (nick (get-text-property speaker 'erc-speaker))
               ((erc-nick-equal-p props nick))))
-    (set-marker erc-fill--wrap-last-msg (point-min))))
+       (set-marker erc-fill--wrap-last-msg (point-min))))))
 
 (defun erc-fill--wrap-measure (beg end)
   "Return display spec width for inserted region between BEG and END.
@@ -539,7 +541,8 @@ See `erc-fill-wrap-mode' for details."
     (goto-char (point-min))
     (let ((len (or (and erc-fill--wrap-length-function
                         (funcall erc-fill--wrap-length-function))
-                   (and-let* ((msg-prop (erc--check-msg-prop 'erc-msg)))
+                   (and-let* ((msg-prop (erc--check-msg-prop 'erc-msg))
+                              ((not (eq msg-prop 'unknown))))
                      (when-let ((e (erc--get-speaker-bounds))
                                 (b (pop e))
                                 ((or erc-fill--wrap-action-dedent-p
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 9d70c644429..4cc81dd9378 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -119,28 +119,20 @@ may be nil, is the number of lines between `window-start' 
and
   "Commands to skip instead of force-scroll on `post-command-hook'.")
 
 (defun erc--scrolltobottom-on-post-command ()
-  "Restore window start or scroll to prompt and recenter.
-When `erc--scrolltobottom-window-info' is non-nil and its first
-item is associated with the selected window, restore start of
-window so long as prompt hasn't moved.  Expect buffer to be
-unnarrowed."
+  "Scroll selected window unless `this-command' is exempted."
   (when (eq (selected-window) (get-buffer-window))
     (unless (memq this-command erc--scrolltobottom-post-ignore-commands)
-      (erc--scrolltobottom-confirm))
-    (setq erc--scrolltobottom-window-info nil)))
+      (setq erc--scrolltobottom-window-info nil)
+      (erc--scrolltobottom-confirm))))
 
 ;; It may be desirable to also restore the relative line position of
 ;; window point after changing dimensions.  Perhaps stashing the
 ;; previous ratio of window line to body height and later recentering
 ;; proportionally would achieve this.
-(defun erc--scrolltobottom-at-prompt-minibuffer-active ()
+(defun erc--scrolltobottom-on-win-conf-change ()
   "Scroll window to bottom when at prompt and using the minibuffer."
-  ;; This is redundant or ineffective in the selected window if at
-  ;; prompt or if only one window exists.
-  (unless (or (input-pending-p)
-              (and (minibuffer-window-active-p (minibuffer-window))
-                   (eq (old-selected-window) (minibuffer-window))))
-    (erc--scrolltobottom-confirm)))
+  (setq erc--scrolltobottom-window-info nil)
+  (erc--scrolltobottom-confirm))
 
 (defun erc--scrolltobottom-all (&rest _)
   "Maybe put prompt on last line in all windows displaying current buffer.
@@ -176,17 +168,20 @@ function used `window-scroll-functions', which was 
replaced by
       (if erc-scrolltobottom-all
           (progn
             (setq-local read-minibuffer-restore-windows nil)
+            (when (zerop scroll-conservatively)
+              (setq-local scroll-step 1))
             (unless (eq erc-scrolltobottom-all 'relaxed)
               (add-hook 'window-configuration-change-hook
-                        #'erc--scrolltobottom-at-prompt-minibuffer-active 50 t)
+                        #'erc--scrolltobottom-on-win-conf-change 50 t)
               (add-hook 'post-command-hook
                         #'erc--scrolltobottom-on-post-command 50 t)))
         (add-hook 'post-command-hook #'erc-scroll-to-bottom nil t))
     (remove-hook 'post-command-hook #'erc-scroll-to-bottom t)
     (remove-hook 'post-command-hook #'erc--scrolltobottom-on-post-command t)
     (remove-hook 'window-configuration-change-hook
-                 #'erc--scrolltobottom-at-prompt-minibuffer-active t)
+                 #'erc--scrolltobottom-on-win-conf-change t)
     (kill-local-variable 'read-minibuffer-restore-windows)
+    (kill-local-variable 'scroll-step)
     (kill-local-variable 'erc--scrolltobottom-window-info)))
 
 (defun erc--scrolltobottom-on-pre-insert (_)
diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el
index 472cc1388a4..79fece5779e 100644
--- a/lisp/erc/erc-log.el
+++ b/lisp/erc/erc-log.el
@@ -276,11 +276,11 @@ The current buffer is given by BUFFER."
 
 (defun erc-log-all-but-server-buffers (buffer)
   "Return t if logging should be enabled in BUFFER.
-Returns nil if `erc-server-buffer-p' returns t."
+Return nil if BUFFER is a server buffer."
   (save-excursion
     (save-window-excursion
       (set-buffer buffer)
-      (not (erc-server-buffer-p)))))
+      (not (erc--server-buffer-p)))))
 
 (defun erc-save-query-buffers (process)
   "Save all buffers of the given PROCESS."
diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el
index 186717579d7..8644e61106f 100644
--- a/lisp/erc/erc-match.el
+++ b/lisp/erc/erc-match.el
@@ -491,7 +491,9 @@ Use this defun with `erc-insert-modify-hook'."
          (message (buffer-substring message-beg (point-max))))
     (when (and vector
               (not (and erc-match-exclude-server-buffer
-                        (erc-server-buffer-p))))
+                         ;; FIXME replace with `erc--server-buffer-p'
+                         ;; or explain why that's unwise.
+                         (erc-server-or-unjoined-channel-buffer-p))))
       (mapc
        (lambda (match-type)
         (goto-char (point-min))
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index d73d715db2c..dd047243a3c 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -53,7 +53,6 @@
 (defvar erc-server-process)
 (defvar erc-session-server)
 
-(declare-function erc--default-target "erc" nil)
 (declare-function erc--get-isupport-entry "erc-backend" (key &optional single))
 (declare-function erc-buffer-filter "erc" (predicate &optional proc))
 (declare-function erc-current-nick "erc" nil)
@@ -991,12 +990,11 @@ object."
                                       (erc-networks--id-qualifying-len nid))
   (erc-networks--rename-server-buffer (or proc erc-server-process) parsed)
   (erc-networks--shrink-ids-and-buffer-names-any)
-  (erc-with-all-buffers-of-server
-      erc-server-process #'erc--default-target
-      (when-let* ((new-name (erc-networks--reconcile-buffer-names erc--target
-                                                                  nid))
-                  ((not (equal (buffer-name) new-name))))
-        (rename-buffer new-name 'unique))))
+  (erc-with-all-buffers-of-server erc-server-process #'erc-target
+    (when-let
+        ((new-name (erc-networks--reconcile-buffer-names erc--target nid))
+         ((not (equal (buffer-name) new-name))))
+      (rename-buffer new-name 'unique))))
 
 (cl-defgeneric erc-networks--id-ensure-comparable (self other)
   "Take measures to ensure two net identities are in comparable states.")
diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el
index 55be8976ada..cf7ffbb40d7 100644
--- a/lisp/erc/erc-notify.el
+++ b/lisp/erc/erc-notify.el
@@ -218,7 +218,9 @@ with args, toggle notify status of people."
            ;; from your notify list.
            (dolist (buf (erc-buffer-list))
              (with-current-buffer buf
-               (if (erc-server-buffer-p)
+                ;; FIXME replace with `erc--server-buffer-p' or
+                ;; explain why that's unwise.
+                (if (erc-server-or-unjoined-channel-buffer-p)
                    (setq erc-last-ison (delete (car args) erc-last-ison))))))
        (setq erc-notify-list (cons (erc-string-no-properties (car args))
                                    erc-notify-list)))
diff --git a/lisp/erc/erc-speedbar.el b/lisp/erc/erc-speedbar.el
index 625d59530b0..bb5fad6f52f 100644
--- a/lisp/erc/erc-speedbar.el
+++ b/lisp/erc/erc-speedbar.el
@@ -135,7 +135,7 @@ This will add a speedbar major display mode."
   (erase-buffer)
   (let (serverp chanp queryp)
     (with-current-buffer buffer
-      (setq serverp (erc-server-buffer-p))
+      (setq serverp (erc--server-buffer-p))
       (setq chanp (erc-channel-p (erc-default-target)))
       (setq queryp (erc-query-buffer-p)))
     (cond (serverp
diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el
index 394643c03cb..b3812470a4d 100644
--- a/lisp/erc/erc-stamp.el
+++ b/lisp/erc/erc-stamp.el
@@ -219,7 +219,9 @@ This becomes the message's `erc-ts' text property."
   (erc-compat--current-lisp-time))
 
 (cl-defmethod erc-stamp--current-time :around ()
-  (or erc-stamp--current-time (cl-call-next-method)))
+  (or erc-stamp--current-time
+      (and erc--msg-props (gethash 'erc-ts erc--msg-props))
+      (cl-call-next-method)))
 
 (defvar erc-stamp--skip nil
   "Non-nil means inhibit `erc-add-timestamp' completely.")
@@ -241,7 +243,8 @@ or `erc-send-modify-hook'."
            (erc-stamp--invisible-property
             ;; FIXME on major version bump, make this `erc-' prefixed.
             (if invisible `(timestamp ,@(ensure-list invisible)) 'timestamp))
-           (skipp (and erc-stamp--skip-when-invisible invisible))
+           (skipp (or (and erc-stamp--skip-when-invisible invisible)
+                      (erc--check-msg-prop 'erc-ephemeral)))
            (erc-stamp--current-time ct))
       (when erc--msg-props
         (puthash 'erc-ts ct erc--msg-props))
@@ -490,8 +493,11 @@ and `erc-stamp--margin-left-p', before activating the 
mode."
     (put-text-property erc-insert-marker (1- erc-input-marker)
                        'display `((margin left-margin) ,prompt))))
 
-(cl-defmethod erc-insert-timestamp-left (string)
+(defun erc-insert-timestamp-left (string)
   "Insert timestamps at the beginning of the line."
+  (erc--insert-timestamp-left string))
+
+(cl-defmethod erc--insert-timestamp-left (string)
   (goto-char (point-min))
   (let* ((ignore-p (and erc-timestamp-only-if-changed-flag
                        (string-equal string erc-timestamp-last-inserted)))
@@ -502,13 +508,12 @@ and `erc-stamp--margin-left-p', before activating the 
mode."
     (erc-put-text-property 0 len 'invisible erc-stamp--invisible-property s)
     (insert s)))
 
-(cl-defmethod erc-insert-timestamp-left
+(cl-defmethod erc--insert-timestamp-left
   (string &context (erc-stamp--display-margin-mode (eql t)))
   (unless (and erc-timestamp-only-if-changed-flag
                (string-equal string erc-timestamp-last-inserted))
     (goto-char (point-min))
-    (insert-before-markers-and-inherit
-     (setq erc-timestamp-last-inserted string))
+    (insert-and-inherit (setq erc-timestamp-last-inserted string))
     (dolist (p erc-stamp--inherited-props)
       (when-let ((v (get-text-property (point) p)))
         (put-text-property (point-min) (point) p v)))
@@ -634,7 +639,8 @@ printed just after each line's text (no alignment)."
 (defun erc-stamp--propertize-left-date-stamp ()
   (add-text-properties (point-min) (1- (point-max))
                        '(field erc-timestamp erc-stamp-type date-left))
-  (erc--hide-message 'timestamp))
+  (erc--hide-message 'timestamp)
+  (run-hooks 'erc-stamp--insert-date-hook))
 
 ;; A kludge to pass state from insert hook to nested insert hook.
 (defvar erc-stamp--current-datestamp-left nil)
@@ -661,19 +667,18 @@ printed just after each line's text (no alignment)."
   (cl-assert string)
   (let ((erc-stamp--skip t)
         (erc--msg-props (map-into `((erc-msg . datestamp)
-                                    (erc-ts . ,erc-stamp--current-time))
+                                    (erc-ts . ,(erc-stamp--current-time)))
                                   'hash-table))
-        (erc-send-modify-hook `(,@erc-send-modify-hook
-                                erc-stamp--propertize-left-date-stamp
-                                ,@erc-stamp--insert-date-hook))
         (erc-insert-modify-hook `(,@erc-insert-modify-hook
-                                  erc-stamp--propertize-left-date-stamp
-                                  ,@erc-stamp--insert-date-hook)))
+                                  erc-stamp--propertize-left-date-stamp))
+        ;; Don't run hooks that aren't expecting a narrowed buffer.
+        (erc-insert-pre-hook nil)
+        (erc-insert-done-hook nil))
     (erc-display-message nil nil (current-buffer) string)
     (setq erc-timestamp-last-inserted-left string)))
 
 (defun erc-stamp--lr-date-on-pre-modify (_)
-  (when-let ((ct (or erc-stamp--current-time (erc-stamp--current-time)))
+  (when-let ((ct (erc-stamp--current-time))
              (rendered (erc-stamp--format-date-stamp ct))
              ((not (string-equal rendered erc-timestamp-last-inserted-left)))
              (erc-stamp--current-datestamp-left rendered)
@@ -685,6 +690,16 @@ printed just after each line's text (no alignment)."
       (let (erc-timestamp-format erc-away-timestamp-format)
         (erc-add-timestamp)))))
 
+(defvar erc-stamp-prepend-date-stamps-p nil
+  "When non-nil, date stamps are not independent messages.
+Users should think twice about enabling this escape hatch.  It
+will likely degraded the user experience by causing post-5.5
+features, like `fill-wrap', dynamic invisibility, etc., to
+malfunction.  Basic support for the default configuration may
+expire earlier than normally expected.")
+(make-obsolete-variable 'erc-stamp-prepend-date-stamps-p
+                        "unsupported legacy behavior" "30.1")
+
 (defun erc-insert-timestamp-left-and-right (string)
   "Insert a stamp on either side when it changes.
 When the deprecated option `erc-timestamp-format-right' is nil,
@@ -699,20 +714,29 @@ requirements related to `erc-legacy-invisible-bounds-p'.
 Additionally, ensure every date stamp is identifiable as such so
 that internal modules can easily distinguish between other
 left-sided stamps and date stamps inserted by this function."
-  (unless erc-stamp--date-format-end
+  (unless (or erc-stamp--date-format-end erc-stamp-prepend-date-stamps-p)
     (add-hook 'erc-insert-pre-hook #'erc-stamp--lr-date-on-pre-modify -95 t)
     (add-hook 'erc-send-pre-functions #'erc-stamp--lr-date-on-pre-modify -95 t)
-    (let ((erc--insert-marker (point-min-marker)))
+    (let ((erc--insert-marker (point-min-marker))
+          (end-marker (point-max-marker)))
       (set-marker-insertion-type erc--insert-marker t)
       (erc-stamp--lr-date-on-pre-modify nil)
-      (narrow-to-region erc--insert-marker (point-max))
+      (narrow-to-region erc--insert-marker end-marker)
+      (set-marker end-marker nil)
       (set-marker erc--insert-marker nil)))
-  (let* ((ct (or erc-stamp--current-time (erc-stamp--current-time)))
+  (let* ((ct (erc-stamp--current-time))
          (ts-right (with-suppressed-warnings
                        ((obsolete erc-timestamp-format-right))
                      (if erc-timestamp-format-right
                          (erc-format-timestamp ct erc-timestamp-format-right)
                        string))))
+    ;; Maybe insert legacy date stamp.
+    (when-let ((erc-stamp-prepend-date-stamps-p)
+               (ts-left (erc-format-timestamp ct erc-timestamp-format-left))
+               ((not (string= ts-left erc-timestamp-last-inserted-left))))
+      (goto-char (point-min))
+      (erc-put-text-property 0 (length ts-left) 'field 'erc-timestamp ts-left)
+      (insert (setq erc-timestamp-last-inserted-left ts-left)))
     ;; insert right timestamp
     (let ((erc-timestamp-only-if-changed-flag t)
          (erc-timestamp-last-inserted erc-timestamp-last-inserted-right))
diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el
index 64e59a90047..a36b781e04d 100644
--- a/lisp/erc/erc-track.el
+++ b/lisp/erc/erc-track.el
@@ -785,6 +785,9 @@ that face with highest priority in NEW-FACES is also a 
member of
               choice))
         choice))))
 
+(defvar erc-track--skipped-msgs '(datestamp)
+  "Values of `erc-msg' text prop to ignore.")
+
 (defun erc-track-modified-channels ()
   "Hook function for `erc-insert-post-hook'.
 Check if the current buffer should be added to the mode line as a
@@ -795,11 +798,16 @@ the current buffer is in `erc-mode'."
     (if (and (not (erc-buffer-visible (current-buffer)))
             (not (member this-channel erc-track-exclude))
             (not (and erc-track-exclude-server-buffer
-                      (erc-server-buffer-p)))
-            (not (erc-message-type-member
-                  (or (erc-find-parsed-property)
-                      (point-min))
-                  erc-track-exclude-types)))
+                       ;; FIXME either use `erc--server-buffer-p' or
+                       ;; explain why that's unwise.
+                       (erc-server-or-unjoined-channel-buffer-p)))
+             (not (let ((parsed (erc-find-parsed-property)))
+                    (or (erc-message-type-member (or parsed (point-min))
+                                                 erc-track-exclude-types)
+                        ;; Skip certain non-server-sent messages.
+                        (and (not parsed)
+                             (erc--check-msg-prop 'erc-msg
+                                                  erc-track--skipped-msgs))))))
        ;; If the active buffer is not visible (not shown in a
        ;; window), and not to be excluded, determine the kinds of
        ;; faces used in the current message, and unless the user
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 5bf6496e926..0471ee0bbb8 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -136,8 +136,62 @@ concerning buffers."
   :group 'erc)
 
 (defvar erc-message-parsed) ; only known to this file
-(defvar erc--msg-props nil)
-(defvar erc--msg-prop-overrides nil)
+
+(defvar erc--msg-props nil
+  "Hash table containing metadata properties for current message.
+Provided by the insertion functions `erc-display-message' and
+`erc-display-msg' while running their modification hooks.
+Initialized when null for each visitation round from function
+parameters and environmental factors, as well as the alist
+`erc--msg-prop-overrides'.  Keys are symbols.  Values are opaque
+objects, unless otherwise specified.  Items present after running
+`erc-insert-post-hook' or `erc-send-post-hook' become text
+properties added to the first character of an inserted message.
+A given message therefore spans the interval extending from one
+set of such properties to the newline before the next (or
+`erc-insert-marker').  As of ERC 5.6, this forms the basis for
+visiting and editing inserted messages.  Modules should align
+their markers accordingly.  The following properties have meaning
+as of ERC 5.6:
+
+ - `erc-msg': a symbol, guaranteed present; values include:
+
+   - `msg', signifying a `PRIVMSG' or an incoming `NOTICE'
+   - `self', a fallback used by `erc-display-msg' for callers
+     that don't specify an `erc-msg'
+   - `unknown', a similar fallback for `erc-display-message'
+   - a catalog key, such as `s401' or `finished'
+   - an `erc-display-message' TYPE parameter, like `notice'
+
+ - `erc-cmd': a message's associated IRC command, as read by
+   `erc--get-eq-comparable-cmd'; currently either a symbol, like
+   `PRIVMSG', or a number, like 5, which represents the numeric
+   \"005\"; absent on \"local\" messages, such as simple warnings
+   and help text, and on outgoing messages unless echoed back by
+   the server (assuming future support)
+
+ - `erc-ctcp': a CTCP command, like `ACTION'
+
+ - `erc-ts': a timestamp, possibly provided by the server; as of
+   5.6, a ticks/hertz pair on Emacs 29 and above, and a \"list\"
+   type otherwise; managed by the `stamp' module
+
+ - `erc-ephemeral': a symbol prefixed by or matching a module
+   name; indicates to other modules and members of modification
+   hooks that the current message should not affect stateful
+   operations, such as recording a channel's most recent speaker
+
+This is an internal API, and the selection of related helper
+utilities is fluid and provisional.  As of ERC 5.6, see the
+functions `erc--check-msg-prop' and `erc--get-inserted-msg-prop'.")
+
+(defvar erc--msg-prop-overrides nil
+  "Alist of \"message properties\" for populating `erc--msg-props'.
+These override any defaults normally shown to modification hooks
+by `erc-display-msg' and `erc-display-message'.  Modules should
+accommodate existing overrides when applicable.  Items toward the
+front shadow any that follow.  Ignored when `erc--msg-props' is
+already non-nil.")
 
 ;; Forward declarations
 (defvar tabbar--local-hlf)
@@ -534,6 +588,8 @@ See also: `erc-remove-server-user' and
 
 Removes all users in the current channel.  This is called by
 `erc-server-PART' and `erc-server-QUIT'."
+  (when (erc--target-channel-p erc--target)
+    (setf (erc--target-channel-joined-p erc--target) nil))
   (when (and erc-server-connected
              (erc-server-process-alive)
              (hash-table-p erc-channel-users))
@@ -1391,16 +1447,6 @@ buffer during local-module setup and `erc-mode-hook' 
activation.")
              #'make-erc--target)
            :string string :symbol (intern (erc-downcase string))))
 
-(defvar-local erc--target nil
-  "Info about a buffer's target, if any.")
-
-;; Temporary internal getter to ease transition to `erc--target'
-;; everywhere.  Will be replaced by updated `erc-default-target'.
-(defun erc--default-target ()
-  "Return target string or nil."
-  (when erc--target
-    (erc--target-string erc--target)))
-
 (defun erc-once-with-server-event (event f)
   "Run function F the next time EVENT occurs in the `current-buffer'.
 
@@ -1417,7 +1463,7 @@ Please be sure to use this function in server-buffers.  In
 channel-buffers it may not work at all, as it uses the LOCAL
 argument of `add-hook' and `remove-hook' to ensure multiserver
 capabilities."
-  (unless (erc-server-buffer-p)
+  (unless (erc--server-buffer-p)
     (error
      "You should only run `erc-once-with-server-event' in a server buffer"))
   (let ((fun (make-symbol "fun"))
@@ -1474,26 +1520,37 @@ the process buffer."
   (and (processp erc-server-process)
        (buffer-live-p (process-buffer erc-server-process))))
 
-(defun erc-server-buffer-p (&optional buffer)
+(define-obsolete-function-alias
+  'erc-server-buffer-p 'erc-server-or-unjoined-channel-buffer-p "30.1")
+(defun erc-server-or-unjoined-channel-buffer-p (&optional buffer)
   "Return non-nil if argument BUFFER is an ERC server buffer.
-
-If BUFFER is nil, the current buffer is used."
+If BUFFER is nil, use the current buffer.  For historical
+reasons, also return non-nil for channel buffers the client has
+parted or from which it's been kicked."
   (with-current-buffer (or buffer (current-buffer))
     (and (eq major-mode 'erc-mode)
          (null (erc-default-target)))))
 
+(defun erc--server-buffer-p (&optional buffer)
+  "Return non-nil if BUFFER is an ERC server buffer.
+Without BUFFER, use the current buffer."
+  (if buffer
+      (with-current-buffer buffer
+        (and (eq major-mode 'erc-mode) (null erc--target)))
+    (and (eq major-mode 'erc-mode) (null erc--target))))
+
 (defun erc-open-server-buffer-p (&optional buffer)
   "Return non-nil if BUFFER is an ERC server buffer with an open IRC process.
 
 If BUFFER is nil, the current buffer is used."
-  (and (erc-server-buffer-p buffer)
+  (and (erc--server-buffer-p buffer)
        (erc-server-process-alive buffer)))
 
 (defun erc-query-buffer-p (&optional buffer)
   "Return non-nil if BUFFER is an ERC query buffer.
 If BUFFER is nil, the current buffer is used."
   (with-current-buffer (or buffer (current-buffer))
-    (let ((target (erc-default-target)))
+    (let ((target (erc-target)))
       (and (eq major-mode 'erc-mode)
            target
            (not (memq (aref target 0) '(?# ?& ?+ ?!)))))))
@@ -1858,7 +1915,10 @@ All strings are compared according to IRC protocol case 
rules, see
 
 (defun erc-get-buffer (target &optional proc)
   "Return the buffer matching TARGET in the process PROC.
-If PROC is not supplied, all processes are searched."
+Without PROC, search all ERC buffers.  For historical reasons,
+skip buffers for channels the client has \"PART\"ed or from which
+it's been \"KICK\"ed.  Expect users to use a different function
+for finding targets independent of \"JOIN\"edness."
   (let ((downcased-target (erc-downcase target)))
     (catch 'buffer
       (erc-buffer-filter
@@ -2047,6 +2107,7 @@ removed from the list will be disabled."
                    (when (symbol-value f)
                      (message "Disabling `erc-%s'" module)
                      (funcall f 0))
+                   ;; Disable local module in all ERC buffers.
                    (unless (or (custom-variable-p f)
                                (not (fboundp 'erc-buffer-filter)))
                      (erc-buffer-filter (lambda ()
@@ -2055,8 +2116,8 @@ removed from the list will be disabled."
                                           (kill-local-variable f)))))))))
          ;; Calling `set-default-toplevel-value' complicates testing.
          (set sym (erc--sort-modules val))
-         ;; this test is for the case where erc hasn't been loaded yet
-         ;; FIXME explain how this ^ can occur or remove comment.
+         ;; Don't initialize modules on load, even though the rare
+         ;; third-party module may need it.
          (when (fboundp 'erc-update-modules)
            (unless erc--inside-mode-toggle-p
              (erc-update-modules))))
@@ -2129,12 +2190,17 @@ Except ignore all local modules, which were introduced 
in ERC 5.5."
 (defun erc--warn-about-aberrant-modules ()
   (when (and erc--aberrant-modules (not erc--target))
     (erc-button--display-error-notice-with-keys-and-warn
-     "The following modules exhibited strange loading behavior: "
+     "The following modules likely engage in unfavorable loading practices: "
      (mapconcat (lambda (s) (format "`%s'" s)) erc--aberrant-modules ", ")
      ". Please contact ERC with \\[erc-bug] if you believe this to be untrue."
      " See Info:\"(erc) Module Loading\" for more.")
     (setq erc--aberrant-modules nil)))
 
+(defvar erc--requiring-module-mode-p nil
+  "Non-nil while doing (require \\='erc-mymod) for `mymod' in `erc-modules'.
+Used for inhibiting potentially recursive `erc-update-modules'
+invocations by third-party packages.")
+
 (defun erc--find-mode (sym)
   (setq sym (erc--normalize-module-symbol sym))
   (if-let ((mode (intern-soft (concat "erc-" (symbol-name sym) "-mode")))
@@ -2144,10 +2210,16 @@ Except ignore all local modules, which were introduced 
in ERC 5.5."
                 (symbol-file mode)
                 (ignore (cl-pushnew sym erc--aberrant-modules)))))
       mode
-    (and (require (or (get sym 'erc--feature)
-                      (intern (concat "erc-" (symbol-name sym))))
-                  nil 'noerror)
-         (setq mode (intern-soft (concat "erc-" (symbol-name sym) "-mode")))
+    (and (or (and erc--requiring-module-mode-p
+                  ;; Also likely non-nil: (eq sym (car features))
+                  (cl-pushnew sym erc--aberrant-modules))
+             (let ((erc--requiring-module-mode-p t))
+               (require (or (get sym 'erc--feature)
+                            (intern (concat "erc-" (symbol-name sym))))
+                        nil 'noerror))
+             (memq sym erc--aberrant-modules))
+         (or mode (setq mode (intern-soft (concat "erc-" (symbol-name sym)
+                                                  "-mode"))))
          (fboundp mode)
          mode)))
 
@@ -2466,10 +2538,12 @@ in here get called with three parameters, SERVER, PORT 
and NICK."
   :type '(repeat function))
 
 (defcustom erc-after-connect nil
-  "Functions called after connecting to a server.
-This functions in this variable gets executed when an end of MOTD
-has been received.  All functions in here get called with the
-parameters SERVER and NICK."
+  "Abnormal hook run upon establishing a logical IRC connection.
+Runs on MOTD's end when `erc-server-connected' becomes non-nil.
+ERC calls members with `erc-server-announced-name', falling back
+to the 376/422 message's \"sender\", as well as the current nick,
+as given by the 376/422 message's \"target\" parameter, which is
+typically the same as that reported by `erc-current-nick'."
   :group 'erc-hooks
   :type '(repeat function))
 
@@ -2878,9 +2952,9 @@ If ARG is non-nil, show the *erc-protocol* buffer."
   "Send CTCP ACTION information described by STR to TGT."
   (erc-send-ctcp-message tgt (format "ACTION %s" str) force)
   ;; Allow hooks that act on inserted PRIVMSG and NOTICES to process us.
-  (let ((erc--msg-prop-overrides '((erc-msg . msg)
-                                   (erc-cmd . PRIVMSG)
-                                   (erc-ctcp . ACTION)))
+  (let ((erc--msg-prop-overrides `((erc-msg . msg)
+                                   (erc-ctcp . ACTION)
+                                   ,@erc--msg-prop-overrides))
         (nick (erc-current-nick)))
     (setq nick (propertize nick 'erc-speaker nick))
     (erc-display-message nil '(t action input) (current-buffer)
@@ -2960,7 +3034,7 @@ POINT, search from POINT instead of `point'."
                           (and-let*
                               ((p (previous-single-property-change point
                                                                    'erc-msg)))
-                            (if (= p (1- point)) point (1- p)))))))
+                            (if (= p (1- point)) p (1- p)))))))
           ,@(and (member only '(nil 'end))
                  '((e (1- (next-single-property-change
                            (if at-start-p (1+ point) point)
@@ -2985,8 +3059,12 @@ Expect callers to know that this doesn't wrap BODY in
        ,@body)))
 
 (defun erc--traverse-inserted (beg end fn)
-  "Visit messages between BEG and END and run FN in narrowed buffer."
-  (setq end (min end (marker-position erc-insert-marker)))
+  "Visit messages between BEG and END and run FN in narrowed buffer.
+If END is a marker, possibly update its position."
+  (unless (markerp end)
+    (setq end (set-marker (make-marker) (or end erc-insert-marker))))
+  (unless (eq end erc-insert-marker)
+    (set-marker end (min erc-insert-marker end)))
   (save-excursion
     (goto-char beg)
     (let ((b (if (get-text-property (point) 'erc-msg)
@@ -2998,18 +3076,33 @@ Expect callers to know that this doesn't wrap BODY in
         (save-restriction
           (narrow-to-region b e)
           (funcall fn))
-        (setq b e)))))
+        (setq b e))))
+  (unless (eq end erc-insert-marker)
+    (set-marker end nil)))
 
 (defvar erc--insert-marker nil
   "Internal override for `erc-insert-marker'.")
 
-(defun erc-display-line-1 (string buffer)
-  "Display STRING in `erc-mode' BUFFER.
-Auxiliary function used in `erc-display-line'.  The line gets filtered to
-interpret the control characters.  Then, `erc-insert-pre-hook' gets called.
-If `erc-insert-this' is still t, STRING gets inserted into the buffer.
-Afterwards, `erc-insert-modify' and `erc-insert-post-hook' get called.
-If STRING is nil, the function does nothing."
+(define-obsolete-function-alias 'erc-display-line-1 'erc-insert-line "30.1")
+(defun erc-insert-line (string buffer)
+  "Insert STRING in an `erc-mode' BUFFER.
+When STRING is nil, do nothing.  Otherwise, start off by running
+`erc-insert-pre-hook' in BUFFER with `erc-insert-this' bound to
+t.  If the latter remains non-nil afterward, insert STRING into
+BUFFER, ensuring a trailing newline.  After that, narrow BUFFER
+around STRING, along with its final line ending, and run
+`erc-insert-modify' and `erc-insert-post-hook', respectively.  In
+all cases, run `erc-insert-done-hook' unnarrowed before exiting,
+and update positions in `buffer-undo-list'.
+
+In general, expect to be called from a higher-level insertion
+function, like `erc-display-message', especially when modules
+should consider STRING as a candidate for formatting with
+enhancements like indentation, fontification, timestamping, etc.
+Otherwise, when called directly, allow built-in modules to ignore
+STRING, which may make it appear incongruous in situ (unless
+preformatted or anticipated by third-party members of the various
+modification hooks)."
   (when string
     (with-current-buffer (or buffer (process-buffer erc-server-process))
       (let ((insert-position (marker-position erc-insert-marker)))
@@ -3021,7 +3114,7 @@ If STRING is nil, the function does nothing."
             (when (erc-string-invisible-p string)
               (erc-put-text-properties 0 (length string)
                                        '(invisible intangible) string)))
-          (erc-log (concat "erc-display-line: " string
+          (erc-log (concat "erc-display-message: " string
                            (format "(%S)" string) " in buffer "
                            (format "%s" buffer)))
           (setq erc-insert-this t)
@@ -3091,39 +3184,45 @@ If STRING is nil, the function does nothing."
   "Check if NICK is a valid IRC nickname."
   (string-match (concat "\\`" erc-valid-nick-regexp "\\'") nick))
 
-(defun erc-display-line (string &optional buffer)
-  "Display STRING in the ERC BUFFER.
-All screen output must be done through this function.  If BUFFER is nil
-or omitted, the default ERC buffer for the `erc-session-server' is used.
-The BUFFER can be an actual buffer, a list of buffers, `all' or `active'.
-If BUFFER = `all', the string is displayed in all the ERC buffers for the
-current session.  `active' means the current active buffer
-\(`erc-active-buffer').  If the buffer can't be resolved, the current
-buffer is used.  `erc-display-line-1' is used to display STRING.
-
-If STRING is nil, the function does nothing."
-  (let (new-bufs)
+(defun erc--route-insertion (string buffer)
+  "Insert STRING in BUFFER.
+See `erc-display-message' for acceptable BUFFER types."
+  (let (seen msg-props)
     (dolist (buf (cond
                   ((bufferp buffer) (list buffer))
-                  ((listp buffer) buffer)
+                  ((consp buffer)
+                   (setq msg-props erc--msg-props)
+                   buffer)
                   ((processp buffer) (list (process-buffer buffer)))
                   ((eq 'all buffer)
                    ;; Hmm, or all of the same session server?
                    (erc-buffer-list nil erc-server-process))
-                  ((and (eq 'active buffer) (erc-active-buffer))
-                   (list (erc-active-buffer)))
+                  ((and-let* (((eq 'active buffer))
+                              (b (erc-active-buffer)))
+                        (list b)))
                   ((erc-server-buffer-live-p)
                    (list (process-buffer erc-server-process)))
                   (t (list (current-buffer)))))
       (when (buffer-live-p buf)
-        (erc-display-line-1 string buf)
-        (push buf new-bufs)))
-    (when (null new-bufs)
-      (erc-display-line-1 string (if (erc-server-buffer-live-p)
-                                     (process-buffer erc-server-process)
-                                   (current-buffer))))))
-
-(defvar erc--compose-text-properties nil
+        (when msg-props
+          (setq erc--msg-props (copy-hash-table msg-props)))
+        (erc-insert-line string buf)
+        (setq seen t)))
+    (unless (or seen (null buffer))
+      (erc--route-insertion string nil))))
+
+(defun erc-display-line (string &optional buffer)
+  "Insert STRING in BUFFER as a plain \"local\" message.
+Take pains to ensure modification hooks see messages created by
+the old pattern (erc-display-line (erc-make-notice) my-buffer) as
+being equivalent to a `erc-display-message' TYPE of `notice'."
+  (let ((erc--msg-prop-overrides erc--msg-prop-overrides))
+    (when (eq 'erc-notice-face (get-text-property 0 'font-lock-face string))
+      (unless (assq 'erc-msg erc--msg-prop-overrides)
+        (push '(erc-msg . notice) erc--msg-prop-overrides)))
+    (erc-display-message nil nil buffer string)))
+
+(defvar erc--merge-text-properties-p nil
   "Non-nil when `erc-put-text-property' defers to `erc--merge-prop'.")
 
 ;; To save space, we could maintain a map of all readable property
@@ -3201,6 +3300,27 @@ don't bother including the preceding newline."
           (cl-incf beg))
         (erc--merge-prop (1- beg) (1- end) 'invisible value)))))
 
+(defun erc--delete-inserted-message (beg-or-point &optional end)
+  "Remove message between BEG and END.
+Expect BEG and END to match bounds as returned by the macro
+`erc--get-inserted-msg-bounds'.  Ensure all markers residing at
+the start of the deleted message end up at the beginning of the
+subsequent message."
+  (let ((beg beg-or-point))
+    (save-restriction
+      (widen)
+      (unless end
+        (setq end (erc--get-inserted-msg-bounds nil beg-or-point)
+              beg (pop end)))
+      (with-silent-modifications
+        (if erc-legacy-invisible-bounds-p
+            (delete-region beg (1+ end))
+          (save-excursion
+            (goto-char beg)
+            (insert-before-markers
+             (substring (delete-and-extract-region (1- (point)) (1+ end))
+                        -1))))))))
+
 (defvar erc--ranked-properties '(erc-msg erc-ts erc-cmd))
 
 (defun erc--order-text-properties-from-hash (table)
@@ -3432,14 +3552,24 @@ returns non-nil."
 Insert MSG or text derived from MSG into an ERC buffer, possibly
 after applying formatting by way of either a `format-spec' known
 to a message-catalog entry or a TYPE known to a specialized
-string handler.  Additionally, derive internal metadata, faces,
-and other text properties from the various overloaded parameters,
-such as PARSED, when it's an `erc-response' object, and MSG, when
-it's a key (symbol) for a \"message catalog\" entry.  Expect
-ARGS, when applicable, to be `format-spec' args known to such an
-entry, and TYPE, when non-nil, to be a symbol handled by
+string handler.  Additionally, derive metadata, faces, and other
+text properties from the various overloaded parameters, such as
+PARSED, when it's an `erc-response' object, and MSG, when it's a
+key (symbol) for a \"message catalog\" entry.  Expect ARGS, when
+applicable, to be `format-spec' args known to such an entry, and
+TYPE, when non-nil, to be a symbol handled by
 `erc-display-message-highlight' (necessarily accompanied by a
-string MSG).
+string MSG).  Expect BUFFER to be among the sort accepted by the
+function `erc-display-line'.
+
+Expect BUFFER to be a live `erc-mode' buffer, a list of such
+buffers, or the symbols `all' or `active'.  If `all', insert
+STRING in all buffers for the current session.  If `active',
+defer to the function `erc-active-buffer', which may return the
+session's server buffer if the previously active buffer has been
+killed.  If BUFFER is nil or a network process, pretend it's set
+to the appropriate server buffer.  Otherwise, use the current
+buffer.
 
 When TYPE is a list of symbols, call handlers from left to right
 without influencing how they behave when encountering existing
@@ -3451,29 +3581,36 @@ expect a TYPE of (t notice error) to result in 
`font-lock-face'
 being (erc-error-face erc-notice-face) throughout MSG when
 `erc-notice-highlight-type' is left at its default, `all'.
 
-As of ERC 5.6, assume user code will use this function instead of
-`erc-display-line' when it's important that insert hooks treat
-MSG in a manner befitting messages received from a server.  That
-is, expect to process most nontrivial informational messages, for
-which PARSED is typically nil, when the caller desires
-buttonizing and other effects."
+As of ERC 5.6, assume third-party code will use this function
+instead of lower-level ones, like `erc-insert-line', when needing
+ERC to process arbitrary informative messages as if they'd been
+sent from a server.  That is, guarantee \"local\" messages, for
+which PARSED is typically nil, will be subject to buttonizing,
+filling, and other effects."
   (let ((string (if (symbolp msg)
                     (apply #'erc-format-message msg args)
                   msg))
         (erc--msg-props
          (or erc--msg-props
-             (let* ((table (make-hash-table :size 5))
-                    (cmd (and parsed (erc--get-eq-comparable-cmd
-                                      (erc-response.command parsed))))
-                    (m (cond ((and msg (symbolp msg)) msg)
-                             ((and cmd (memq cmd '(PRIVMSG NOTICE)) 'msg))
-                             (t 'unknown))))
-               (puthash 'erc-msg m table)
+             (let ((table (make-hash-table :size 5))
+                   (cmd (and parsed (erc--get-eq-comparable-cmd
+                                     (erc-response.command parsed)))))
+               (puthash 'erc-msg
+                        (cond ((and msg (symbolp msg)) msg)
+                              ((and cmd (memq cmd '(PRIVMSG NOTICE)) 'msg))
+                              (type (pcase type
+                                      ((pred symbolp) type)
+                                      ((pred listp)
+                                       (intern (mapconcat #'prin1-to-string
+                                                          type "-")))
+                                      (_ 'unknown)))
+                              (t 'unknown))
+                        table)
                (when cmd
                  (puthash 'erc-cmd cmd table))
-               (and erc--msg-prop-overrides
-                    (pcase-dolist (`(,k . ,v) erc--msg-prop-overrides)
-                      (puthash k v table)))
+               (and-let* ((ovs erc--msg-prop-overrides))
+                 (pcase-dolist (`(,k . ,v) (reverse ovs))
+                   (puthash k v table)))
                table)))
         (erc-message-parsed parsed))
     (setq string
@@ -3481,7 +3618,7 @@ buttonizing and other effects."
            ((null type)
             string)
            ((listp type)
-            (let ((erc--compose-text-properties
+            (let ((erc--merge-text-properties-p
                    (and (eq (car type) t) (setq type (cdr type)))))
               (dolist (type type)
                 (setq string (erc-display-message-highlight type string))))
@@ -3490,13 +3627,13 @@ buttonizing and other effects."
             (erc-display-message-highlight type string))))
 
     (if (not (erc-response-p parsed))
-        (erc-display-line string buffer)
+        (erc--route-insertion string buffer)
       (unless (erc-hide-current-message-p parsed)
         (erc-put-text-property 0 (length string) 'erc-parsed parsed string)
        (when (erc-response.tags parsed)
          (erc-put-text-property 0 (length string) 'tags (erc-response.tags 
parsed)
                                 string))
-       (erc-display-line string buffer)))))
+        (erc--route-insertion string buffer)))))
 
 (defun erc-message-type-member (position list)
   "Return non-nil if the erc-parsed text-property at POSITION is in LIST.
@@ -4584,10 +4721,7 @@ the message given by REASON."
     ;; kill them
     (run-at-time
      4 nil
-     (lambda ()
-       (dolist (buffer (erc-buffer-list (lambda (buf)
-                                          (not (erc-server-buffer-p buf)))))
-         (kill-buffer buffer)))))
+     #'erc-buffer-do (lambda () (when erc--target (kill-buffer)))))
   t)
 
 (defalias 'erc-cmd-GQ #'erc-cmd-GQUIT)
@@ -5690,9 +5824,7 @@ See also: `erc-echo-notice-in-user-buffers',
         (erc-load-script f)))))
 
 (defun erc-connection-established (proc parsed)
-  "Run just after connection.
-
-Set user modes and run `erc-after-connect' hook."
+  "Set user mode and run `erc-after-connect' hook in server buffer."
   (with-current-buffer (process-buffer proc)
     (unless erc-server-connected ; only once per session
       (let ((server (or erc-server-announced-name
@@ -5711,14 +5843,11 @@ Set user modes and run `erc-after-connect' hook."
         (erc-update-mode-line)
         (erc-set-initial-user-mode nick buffer)
         (erc-server-setup-periodical-ping buffer)
-        (run-hook-with-args 'erc-after-connect server nick))))
-
-  (when erc-unhide-query-prompt
-    (erc-with-all-buffers-of-server proc
-      nil ; FIXME use `erc--target' after bug#48598
-      (when (and (erc-default-target)
-                 (not (erc-channel-p (car erc-default-recipients))))
-        (erc--unhide-prompt)))))
+        (when erc-unhide-query-prompt
+          (erc-with-all-buffers-of-server erc-server-process nil
+            (when (and erc--target (not (erc--target-channel-p erc--target)))
+              (erc--unhide-prompt))))
+        (run-hook-with-args 'erc-after-connect server nick)))))
 
 (defun erc-set-initial-user-mode (nick buffer)
   "If `erc-user-mode' is non-nil for NICK, set the user modes.
@@ -5755,7 +5884,8 @@ See also `erc-display-message'."
           (let* ((type (upcase (car (split-string (car queries)))))
                  (hook (intern-soft (concat "erc-ctcp-query-" type "-hook")))
                  (erc--msg-prop-overrides `((erc-msg . msg)
-                                            (erc-ctcp . ,(intern type)))))
+                                            (erc-ctcp . ,(intern type))
+                                            ,@erc--msg-prop-overrides)))
             (if (and hook (boundp hook))
                 (if (string-equal type "ACTION")
                     (run-hook-with-args-until-success
@@ -6481,7 +6611,7 @@ OBJECT is modified without being copied first.
 
 You can redefine or `defadvice' this function in order to add
 EmacsSpeak support."
-  (if erc--compose-text-properties
+  (if erc--merge-text-properties-p
       (erc--merge-prop start end property value object)
     (put-text-property start end property value object)))
 
@@ -6760,8 +6890,8 @@ ERC prints them as a single message joined by newlines.")
             (when-let (((not (erc--input-split-abortp state)))
                        (inhibit-read-only t)
                        (old-buf (current-buffer)))
-              (let ((erc--msg-prop-overrides '((erc-cmd . PRIVMSG)
-                                               (erc-msg . msg))))
+              (let ((erc--msg-prop-overrides `((erc-msg . msg)
+                                               ,@erc--msg-prop-overrides)))
                 (erc-set-active-buffer (current-buffer))
                 ;; Kill the input and the prompt
                 (delete-region erc-input-marker (erc-end-of-input-line))
@@ -6903,15 +7033,18 @@ Return non-nil only if we actually send anything."
           t)))))
 
 (defun erc-display-msg (line)
-  "Display LINE as a message of the user to the current target at point."
+  "Insert LINE into current buffer and run \"send\" hooks.
+Expect LINE to originate from input submitted interactively at
+the prompt, such as outgoing chat messages or echoed slash
+commands."
   (when erc-insert-this
     (save-excursion
       (erc--assert-input-bounds)
       (let ((insert-position (marker-position (goto-char erc-insert-marker)))
-            (erc--msg-props (or erc--msg-props
-                                (map-into (cons '(erc-msg . self)
-                                                erc--msg-prop-overrides)
-                                          'hash-table)))
+            (erc--msg-props (or erc--msg-props ; prefer `self' to `unknown'
+                                (let ((ovs erc--msg-prop-overrides))
+                                  (map-into `((erc-msg . self) ,@(reverse ovs))
+                                            'hash-table))))
             beg)
         (insert (erc-format-my-nick))
         (setq beg (point))
@@ -7006,28 +7139,16 @@ See also `erc-downcase'."
 ;; default target handling
 
 (defun erc--current-buffer-joined-p ()
-  "Return whether the current target buffer is joined."
-  ;; This may be a reliable means of detecting subscription status,
-  ;; but it's also roundabout and awkward.  Perhaps it's worth
-  ;; discussing adding a joined slot to `erc--target' for this.
+  "Return non-nil if the current buffer is a channel and is joined."
   (cl-assert erc--target)
   (and (erc--target-channel-p erc--target)
-       (erc-get-channel-user (erc-current-nick)) t))
-
-;; While `erc-default-target' happens to return nil in channel buffers
-;; you've parted or from which you've been kicked, using it to detect
-;; whether a channel is currently joined may become unreliable in the
-;; future.  For now, third-party code can use
-;;
-;;   (erc-get-channel-user (erc-current-nick))
-;;
-;; A predicate may be provided eventually.  For retrieving a target's
-;; name regardless of subscription or connection status, new library
-;; code should use `erc--default-target'.  Third-party code should
-;; continue to use `erc-default-target'.
+       (erc--target-channel-joined-p erc--target)
+       t))
 
 (defun erc-default-target ()
-  "Return the current default target (as a character string) or nil if none."
+  "Return the current channel or query target, if any.
+For historical reasons, return nil in channel buffers if not
+currently joined."
   (let ((tgt (car erc-default-recipients)))
     (cond
      ((not tgt) nil)
@@ -7589,15 +7710,14 @@ If it doesn't exist, create it."
   (unless (file-attributes dir) (make-directory dir))
   (or (file-accessible-directory-p dir) (error "Cannot access %s" dir)))
 
+;; FIXME make function obsolete or alias to something less confusing.
 (defun erc-kill-query-buffers (process)
-  "Kill all buffers of PROCESS.
-Does nothing if PROCESS is not a process object."
+  "Kill all target buffers of PROCESS, including channel buffers.
+Do nothing if PROCESS is not a process object."
   ;; here, we only want to match the channel buffers, to avoid
   ;; "selecting killed buffers" b0rkage.
   (when (processp process)
-    (erc-with-all-buffers-of-server process
-      (lambda ()
-       (not (erc-server-buffer-p)))
+    (erc-with-all-buffers-of-server process (lambda () erc--target)
       (kill-buffer (current-buffer)))))
 
 (defun erc-nick-at-point ()
@@ -8255,6 +8375,7 @@ See also `kill-buffer'."
   :group 'erc-hooks
   :type 'hook)
 
+;; FIXME alias and deprecate current *-function suffixed name.
 (defun erc-kill-buffer-function ()
   "Function to call when an ERC buffer is killed.
 This function should be on `kill-buffer-hook'.
@@ -8268,7 +8389,7 @@ or `erc-kill-buffer-hook' if any other buffer."
     (cond
      ((eq (erc-server-buffer) (current-buffer))
       (run-hooks 'erc-kill-server-hook))
-     ((erc-channel-p (or (erc-default-target) (buffer-name)))
+     ((erc--target-channel-p erc--target)
       (run-hooks 'erc-kill-channel-hook))
      (t
       (run-hooks 'erc-kill-buffer-hook)))))
diff --git a/lisp/eshell/em-cmpl.el b/lisp/eshell/em-cmpl.el
index 61f1237b907..0255da88dbd 100644
--- a/lisp/eshell/em-cmpl.el
+++ b/lisp/eshell/em-cmpl.el
@@ -377,7 +377,8 @@ to writing a completion function."
                 (throw 'pcompleted (elisp-completion-at-point)))
                (t
                 (eshell--pcomplete-insert-tab)))))
-    (when (get-text-property (1- end) 'comment)
+    (when (and (< begin end)
+               (get-text-property (1- end) 'comment))
       (eshell--pcomplete-insert-tab))
     (let ((pos (1- end)))
       (while (>= pos begin)
diff --git a/lisp/eshell/em-extpipe.el b/lisp/eshell/em-extpipe.el
index 5c9a0a85934..0d5c217f5f0 100644
--- a/lisp/eshell/em-extpipe.el
+++ b/lisp/eshell/em-extpipe.el
@@ -118,86 +118,87 @@ as though it were Eshell syntax."
   ;; other members of `eshell-parse-argument-hook'.  We must avoid
   ;; misinterpreting a quoted `*|', `*<' or `*>' as indicating an
   ;; external pipeline, hence the structure of the loop in `findbeg1'.
-  (cl-flet
-      ((findbeg1 (pat &optional go (bound (point-max)))
-         (let* ((start (point))
-                (result
-                 (catch 'found
-                   (while (> bound (point))
-                     (let* ((found
-                             (save-excursion
-                               (re-search-forward
-                                "\\(?:#?'\\|\"\\|\\\\\\)" bound t)))
-                            (next (or (and found (match-beginning 0))
-                                      bound)))
-                       (if (re-search-forward pat next t)
-                           (throw 'found (match-beginning 1))
-                         (goto-char next)
-                         (while (eshell-extpipe--or-with-catch
-                                 (eshell-parse-lisp-argument)
-                                 (eshell-parse-backslash)
-                                 (eshell-parse-double-quote)
-                                 (eshell-parse-literal-quote)))
-                         ;; Guard against an infinite loop if none of
-                         ;; the parsers moved us forward.
-                         (unless (or (> (point) next) (eobp))
-                           (forward-char 1))))))))
-           (goto-char (if (and result go) (match-end 0) start))
-           result)))
-    (unless (or eshell-current-argument eshell-current-quoted)
-      (let ((beg (point)) end
-            (next-marked (findbeg1 "\\(?:\\=\\|\\s-\\)\\(\\*[|<>]\\)"))
-            (next-unmarked
-             (or (findbeg1 "\\(?:\\=\\|[^*]\\|\\S-\\*\\)\\(|\\)")
-                 (point-max))))
-        (when (and next-marked (> next-unmarked next-marked)
-                   (or (> next-marked (point))
-                       (looking-back "\\`\\|\\s-" nil)))
-          ;; Skip to the final segment of the external pipeline.
-          (while (findbeg1 "\\(?:\\=\\|\\s-\\)\\(\\*|\\)" t))
-          ;; Find output redirections.
-          (while (findbeg1
-                  "\\([0-9]?>+&?[0-9]?\\s-*\\S-\\)" t next-unmarked)
-            ;; Is the output redirection Eshell-specific?  We have our
-            ;; own logic, rather than calling `eshell-parse-argument',
-            ;; to avoid specifying here all the possible cars of
-            ;; parsed special references -- `get-buffer-create' etc.
-            (forward-char -1)
-            (let ((this-end
-                   (save-match-data
-                     (cond ((looking-at "#<")
-                            (forward-char 1)
-                            (1+ (eshell-find-delimiter ?\< ?\>)))
-                           ((and (looking-at "/\\S-+")
-                                 (assoc (match-string 0)
-                                        eshell-virtual-targets))
-                            (match-end 0))))))
-              (cond ((and this-end end)
-                     (goto-char this-end))
-                    (this-end
-                     (goto-char this-end)
-                     (setq end (match-beginning 0)))
-                    (t
-                     (setq end nil)))))
-          ;; We've moved past all Eshell-specific output redirections
-          ;; we could find.  If there is only whitespace left, then
-          ;; `end' is right before redirections we should exclude;
-          ;; otherwise, we must include everything.
-          (unless (and end (skip-syntax-forward "\s" next-unmarked)
-                       (= next-unmarked (point)))
-            (setq end next-unmarked))
-          (let ((cmd (string-trim
-                      (buffer-substring-no-properties beg end))))
-            (goto-char end)
-            ;; We must now drop the asterisks, unless quoted/escaped.
-            (with-temp-buffer
-              (insert cmd)
-              (goto-char (point-min))
-              (cl-loop
-               for next = (findbeg1 "\\(?:\\=\\|\\s-\\)\\(\\*[|<>]\\)" t)
-               while next do (forward-char -2) (delete-char 1))
-              (eshell-finish-arg
-               `(eshell-external-pipeline ,(buffer-string))))))))))
+  (unless eshell-current-argument-plain
+    (cl-flet
+        ((findbeg1 (pat &optional go (bound (point-max)))
+           (let* ((start (point))
+                  (result
+                   (catch 'found
+                     (while (> bound (point))
+                       (let* ((found
+                               (save-excursion
+                                 (re-search-forward
+                                  "\\(?:#?'\\|\"\\|\\\\\\)" bound t)))
+                              (next (or (and found (match-beginning 0))
+                                        bound)))
+                         (if (re-search-forward pat next t)
+                             (throw 'found (match-beginning 1))
+                           (goto-char next)
+                           (while (eshell-extpipe--or-with-catch
+                                   (eshell-parse-lisp-argument)
+                                   (eshell-parse-backslash)
+                                   (eshell-parse-double-quote)
+                                   (eshell-parse-literal-quote)))
+                           ;; Guard against an infinite loop if none of
+                           ;; the parsers moved us forward.
+                           (unless (or (> (point) next) (eobp))
+                             (forward-char 1))))))))
+             (goto-char (if (and result go) (match-end 0) start))
+             result)))
+      (unless (or eshell-current-argument eshell-current-quoted)
+        (let ((beg (point)) end
+              (next-marked (findbeg1 "\\(?:\\=\\|\\s-\\)\\(\\*[|<>]\\)"))
+              (next-unmarked
+               (or (findbeg1 "\\(?:\\=\\|[^*]\\|\\S-\\*\\)\\(|\\)")
+                   (point-max))))
+          (when (and next-marked (> next-unmarked next-marked)
+                     (or (> next-marked (point))
+                         (looking-back "\\`\\|\\s-" nil)))
+            ;; Skip to the final segment of the external pipeline.
+            (while (findbeg1 "\\(?:\\=\\|\\s-\\)\\(\\*|\\)" t))
+            ;; Find output redirections.
+            (while (findbeg1
+                    "\\([0-9]?>+&?[0-9]?\\s-*\\S-\\)" t next-unmarked)
+              ;; Is the output redirection Eshell-specific?  We have our
+              ;; own logic, rather than calling `eshell-parse-argument',
+              ;; to avoid specifying here all the possible cars of
+              ;; parsed special references -- `get-buffer-create' etc.
+              (forward-char -1)
+              (let ((this-end
+                     (save-match-data
+                       (cond ((looking-at "#<")
+                              (forward-char 1)
+                              (1+ (eshell-find-delimiter ?\< ?\>)))
+                             ((and (looking-at "/\\S-+")
+                                   (assoc (match-string 0)
+                                          eshell-virtual-targets))
+                              (match-end 0))))))
+                (cond ((and this-end end)
+                       (goto-char this-end))
+                      (this-end
+                       (goto-char this-end)
+                       (setq end (match-beginning 0)))
+                      (t
+                       (setq end nil)))))
+            ;; We've moved past all Eshell-specific output redirections
+            ;; we could find.  If there is only whitespace left, then
+            ;; `end' is right before redirections we should exclude;
+            ;; otherwise, we must include everything.
+            (unless (and end (skip-syntax-forward "\s" next-unmarked)
+                         (= next-unmarked (point)))
+              (setq end next-unmarked))
+            (let ((cmd (string-trim
+                        (buffer-substring-no-properties beg end))))
+              (goto-char end)
+              ;; We must now drop the asterisks, unless quoted/escaped.
+              (with-temp-buffer
+                (insert cmd)
+                (goto-char (point-min))
+                (cl-loop
+                 for next = (findbeg1 "\\(?:\\=\\|\\s-\\)\\(\\*[|<>]\\)" t)
+                 while next do (forward-char -2) (delete-char 1))
+                (eshell-finish-arg
+                 `(eshell-external-pipeline ,(buffer-string)))))))))))
 
 (defun eshell-rewrite-external-pipeline (terms)
   "Rewrite an external pipeline in TERMS as parsed by
diff --git a/lisp/eshell/em-smart.el b/lisp/eshell/em-smart.el
index 4c39a991ec6..fc283547519 100644
--- a/lisp/eshell/em-smart.el
+++ b/lisp/eshell/em-smart.el
@@ -95,7 +95,7 @@ it to get a real sense of how it works."
   (list
    (lambda ()
      (remove-hook 'window-configuration-change-hook
-                  'eshell-refresh-windows)))
+                  'eshell-smart-scroll)))
   "A hook that gets run when `eshell-smart' is unloaded."
   :type 'hook
   :group 'eshell-smart)
@@ -159,9 +159,7 @@ The options are `begin', `after' or `end'."
 
 ;;; Internal Variables:
 
-(defvar eshell-smart-displayed nil)
 (defvar eshell-smart-command-done nil)
-(defvar eshell-currently-handling-window nil)
 
 ;;; Functions:
 
@@ -174,10 +172,9 @@ The options are `begin', `after' or `end'."
     (setq-local eshell-scroll-to-bottom-on-input nil)
     (setq-local eshell-scroll-show-maximum-output t)
 
-    (add-hook 'window-scroll-functions 'eshell-smart-scroll-window nil t)
-    (add-hook 'window-configuration-change-hook 'eshell-refresh-windows)
+    (add-hook 'window-configuration-change-hook 'eshell-smart-scroll nil t)
 
-    (add-hook 'eshell-output-filter-functions 'eshell-refresh-windows t t)
+    (add-hook 'eshell-output-filter-functions 'eshell-smart-scroll-windows 90 
t)
 
     (add-hook 'after-change-functions 'eshell-disable-after-change nil t)
 
@@ -193,28 +190,15 @@ The options are `begin', `after' or `end'."
       (add-hook 'eshell-post-command-hook
                'eshell-smart-maybe-jump-to-end nil t))))
 
-;; This is called by window-scroll-functions with two arguments.
-(defun eshell-smart-scroll-window (wind _start)
-  "Scroll the given Eshell window WIND accordingly."
-  (unless eshell-currently-handling-window
-    (let ((eshell-currently-handling-window t))
-      (with-selected-window wind
-       (eshell-smart-redisplay)))))
-
-(defun eshell-refresh-windows (&optional frame)
-  "Refresh all visible Eshell buffers."
-  (let (affected)
-    (walk-windows
-     (lambda (wind)
-       (with-current-buffer (window-buffer wind)
-         (if eshell-mode
-             (let (window-scroll-functions) ;;FIXME: Why?
-               (eshell-smart-scroll-window wind (window-start))
-               (setq affected t)))))
-     0 frame)
-    (if affected
-       (let (window-scroll-functions) ;;FIXME: Why?
-          (redisplay)))))
+(defun eshell-smart-scroll-windows ()
+  "Scroll all eshell windows to display as much output as possible, smartly."
+  (walk-windows
+   (lambda (wind)
+     (with-current-buffer (window-buffer wind)
+       (if eshell-mode
+           (with-selected-window wind
+             (eshell-smart-scroll)))))
+   0 t))
 
 (defun eshell-smart-display-setup ()
   "Set the point to somewhere in the beginning of the last command."
@@ -231,8 +215,7 @@ The options are `begin', `after' or `end'."
    (t
     (error "Invalid value for `eshell-where-to-jump'")))
   (setq eshell-smart-command-done nil)
-  (add-hook 'pre-command-hook 'eshell-smart-display-move nil t)
-  (eshell-refresh-windows))
+  (add-hook 'pre-command-hook 'eshell-smart-display-move nil t))
 
 ;; Called from after-change-functions with 3 arguments.
 (defun eshell-disable-after-change (_b _e _l)
@@ -254,28 +237,22 @@ and the end of the buffer are still visible."
     (goto-char (point-max))
     (remove-hook 'pre-command-hook 'eshell-smart-display-move t)))
 
-(defun eshell-smart-redisplay ()
-  "Display as much output as possible, smartly."
-  (if (eobp)
+(defun eshell-smart-scroll ()
+  "Scroll WINDOW to display as much output as possible, smartly."
+  (let ((top-point (point)))
+    (and (memq 'eshell-smart-display-move pre-command-hook)
+         (>= (point) eshell-last-input-start)
+         (< (point) eshell-last-input-end)
+         (set-window-start (selected-window)
+                           (pos-bol) t))
+    (when (pos-visible-in-window-p (point-max) (selected-window))
       (save-excursion
-       (recenter -1)
-       ;; trigger the redisplay now, so that we catch any attempted
-       ;; point motion; this is to cover for a redisplay bug
-        (redisplay))
-    (let ((top-point (point)))
-      (and (memq 'eshell-smart-display-move pre-command-hook)
-          (>= (point) eshell-last-input-start)
-          (< (point) eshell-last-input-end)
-          (set-window-start (selected-window)
-                            (line-beginning-position) t))
-      (if (pos-visible-in-window-p (point-max))
-         (save-excursion
-           (goto-char (point-max))
-           (recenter -1)
-           (unless (pos-visible-in-window-p top-point)
-             (goto-char top-point)
-             (set-window-start (selected-window)
-                               (line-beginning-position) t)))))))
+        (goto-char (point-max))
+        (recenter -1)
+        (unless (pos-visible-in-window-p top-point (selected-window))
+          (goto-char top-point)
+          (set-window-start (selected-window)
+                            (pos-bol) t))))))
 
 (defun eshell-smart-goto-end ()
   "Like `end-of-buffer', but do not push a mark."
@@ -323,7 +300,7 @@ and the end of the buffer are still visible."
        (remove-hook 'pre-command-hook 'eshell-smart-display-move t))))
 
 (defun em-smart-unload-hook ()
-  (remove-hook 'window-configuration-change-hook #'eshell-refresh-windows))
+  (remove-hook 'window-configuration-change-hook #'eshell-smart-scroll))
 
 (provide 'em-smart)
 
diff --git a/lisp/eshell/esh-arg.el b/lisp/eshell/esh-arg.el
index e7b5eef11db..2bdfdff8a3a 100644
--- a/lisp/eshell/esh-arg.el
+++ b/lisp/eshell/esh-arg.el
@@ -49,6 +49,8 @@ yield the values intended."
 (defvar eshell-arg-listified nil)
 (defvar eshell-nested-argument nil)
 (defvar eshell-current-quoted nil)
+(defvar eshell-current-argument-plain nil
+  "If non-nil, the current argument is \"plain\", and not part of a command.")
 (defvar eshell-inside-quote-regexp nil)
 (defvar eshell-outside-quote-regexp nil)
 
@@ -163,6 +165,43 @@ treated as a literal character."
   :type 'hook
   :group 'eshell-arg)
 
+(defvar eshell-special-ref-alist
+  '(("buffer"
+     (creation-function   eshell-get-buffer)
+     (insertion-function  eshell-insert-buffer-name)
+     (completion-function eshell-complete-buffer-ref))
+    ("marker"
+     (creation-function   eshell-get-marker)
+     (insertion-function  eshell-insert-marker)
+     (completion-function eshell-complete-marker-ref)))
+  "Alist of special reference types for Eshell.
+Each entry is a list of the form (TYPE (KEY VALUE)...).  TYPE is
+the name of the special reference type, and each KEY/VALUE pair
+represents a parameter for the type.  Eshell defines the
+following KEYs:
+
+* `creation-function'
+  A function taking any number of arguments that returns the Lisp
+  object for this special ref type.
+
+* `insertion-function'
+  An interactive function that returns the special reference in
+  string form.  This string should look like \"#<TYPE ARG...>\";
+  Eshell will pass the ARGs to `creation-function'.
+
+* `completion-function'
+  A function using Pcomplete to perform completion on any
+  arguments necessary for creating this special reference type.")
+
+(defcustom eshell-special-ref-default "buffer"
+  "The default type for special references when the type keyword is omitted.
+This should be a key in `eshell-special-ref-alist' (which see).
+Eshell will expand special refs like \"#<ARG...>\" into
+\"#<`eshell-special-ref-default' ARG...>\"."
+  :version "30.1"
+  :type 'string
+  :group 'eshell-arg)
+
 (defvar-keymap eshell-arg-mode-map
   "C-c M-b" #'eshell-insert-buffer-name)
 
@@ -184,11 +223,6 @@ treated as a literal character."
     (add-hook 'pcomplete-try-first-hook
               #'eshell-complete-special-reference nil t)))
 
-(defun eshell-insert-buffer-name (buffer-name)
-  "Insert BUFFER-NAME into the current buffer at point."
-  (interactive "BName of buffer: ")
-  (insert-and-inherit "#<buffer " buffer-name ">"))
-
 (defsubst eshell-escape-arg (string)
   "Return STRING with the `escaped' property on it."
   (if (stringp string)
@@ -505,42 +539,6 @@ leaves point where it was."
         (goto-char bound)
         (apply #'concat (nreverse strings))))))
 
-(defun eshell-parse-special-reference ()
-  "Parse a special syntax reference, of the form `#<args>'.
-
-args           := `type' `whitespace' `arbitrary-args' | `arbitrary-args'
-type           := \"buffer\" or \"process\"
-arbitrary-args := any string of characters.
-
-If the form has no `type', the syntax is parsed as if `type' were
-\"buffer\"."
-  (when (and (not eshell-current-argument)
-             (not eshell-current-quoted)
-             (looking-at (rx "#<" (? (group (or "buffer" "process"))
-                                     space))))
-    (let ((here (point)))
-      (goto-char (match-end 0)) ;; Go to the end of the match.
-      (let ((buffer-p (if (match-beginning 1)
-                          (equal (match-string 1) "buffer")
-                        t)) ; With no type keyword, assume we want a buffer.
-            (end (eshell-find-delimiter ?\< ?\>)))
-        (when (not end)
-          (when (match-beginning 1)
-            (goto-char (match-beginning 1)))
-          (throw 'eshell-incomplete "#<"))
-        (if (eshell-arg-delimiter (1+ end))
-            (prog1
-                (list (if buffer-p #'get-buffer-create #'get-process)
-                      ;; FIXME: We should probably parse this as a
-                      ;; real Eshell argument so that we get the
-                      ;; benefits of quoting, variable-expansion, etc.
-                      (string-trim-right
-                       (replace-regexp-in-string
-                        (rx "\\" (group anychar)) "\\1"
-                        (buffer-substring-no-properties (point) end))))
-              (goto-char (1+ end)))
-          (ignore (goto-char here)))))))
-
 (defun eshell-parse-delimiter ()
   "Parse an argument delimiter, which is essentially a command operator."
   ;; this `eshell-operator' keyword gets parsed out by
@@ -591,41 +589,158 @@ If no argument requested a splice, return nil."
     (when splicep
       grouped-args)))
 
-;;;_* Special ref completion
+;;; Special references
+
+(defsubst eshell--special-ref-function (type function)
+  "Get the specified FUNCTION for a particular special ref TYPE.
+If TYPE is nil, get the FUNCTION for the `eshell-special-ref-default'."
+  (cadr (assq function (assoc (or type eshell-special-ref-default)
+                              eshell-special-ref-alist))))
+
+(defun eshell-parse-special-reference ()
+  "Parse a special syntax reference, of the form `#<args>'.
+
+args           := `type' `whitespace' `arbitrary-args' | `arbitrary-args'
+type           := one of the keys in `eshell-special-ref-alist'
+arbitrary-args := any number of Eshell arguments
+
+If the form has no `type', the syntax is parsed as if `type' were
+`eshell-special-ref-default'."
+  (let ((here (point))
+        (special-ref-types (mapcar #'car eshell-special-ref-alist)))
+    (when (and (not eshell-current-argument)
+               (not eshell-current-quoted)
+               (looking-at (rx-to-string
+                            `(seq "#<" (? (group (or ,@special-ref-types))
+                                          (+ space)))
+                            t)))
+      (goto-char (match-end 0))         ; Go to the end of the match.
+      (let ((end (eshell-find-delimiter ?\< ?\>))
+            (creation-fun (eshell--special-ref-function
+                           (match-string 1) 'creation-function)))
+        (unless end
+          (when (match-beginning 1)
+            (goto-char (match-beginning 1)))
+          (throw 'eshell-incomplete "#<"))
+        (if (eshell-arg-delimiter (1+ end))
+            (prog1
+                (cons creation-fun
+                      (let ((eshell-current-argument-plain t))
+                        (eshell-parse-arguments (point) end)))
+              (goto-char (1+ end)))
+          (ignore (goto-char here)))))))
+
+(defun eshell-insert-special-reference (type &rest args)
+  "Insert a special reference of the specified TYPE.
+ARGS is a list of arguments to pass to the insertion function for
+TYPE (see `eshell-special-ref-alist')."
+  (interactive
+   (let* ((type (completing-read
+                 (format-prompt "Type" eshell-special-ref-default)
+                 (mapcar #'car eshell-special-ref-alist)
+                 nil 'require-match nil nil eshell-special-ref-default))
+          (insertion-fun (eshell--special-ref-function
+                          type 'insertion-function)))
+     (list :interactive (call-interactively insertion-fun))))
+  (if (eq type :interactive)
+      (car args)
+    (apply (eshell--special-ref-function type 'insertion-function) args)))
 
 (defun eshell-complete-special-reference ()
   "If there is a special reference, complete it."
-  (let ((arg (pcomplete-actual-arg)))
-    (when (string-match
-           (rx string-start
-               "#<" (? (group (or "buffer" "process")) space)
-               (group (* anychar))
-               string-end)
-           arg)
-      (let ((all-results (if (equal (match-string 1 arg) "process")
-                             (mapcar #'process-name (process-list))
-                           (mapcar #'buffer-name (buffer-list))))
-            (saw-type (match-beginning 1)))
-        (unless saw-type
-          ;; Include the special reference types as completion options.
-          (setq all-results (append '("buffer" "process") all-results)))
-        (setq pcomplete-stub (replace-regexp-in-string
-                              (rx "\\" (group anychar)) "\\1"
-                              (substring arg (match-beginning 2))))
-        ;; When finished with completion, add a trailing ">" (unless
-        ;; we just completed the initial "buffer" or "process"
-        ;; keyword).
-        (add-function
-         :before (var pcomplete-exit-function)
-         (lambda (value status)
-           (when (and (eq status 'finished)
-                      (or saw-type
-                          (not (member value '("buffer" "process")))))
-             (if (looking-at ">")
-                 (goto-char (match-end 0))
-               (insert ">")))))
-        (throw 'pcomplete-completions
-               (all-completions pcomplete-stub all-results))))))
+  (when (string-prefix-p "#<" (pcomplete-actual-arg))
+    (let ((special-ref-types (mapcar #'car eshell-special-ref-alist))
+          num-args explicit-type)
+      ;; When finished with completion, add a trailing ">" when
+      ;; appropriate.
+      (add-function
+       :around (var pcomplete-exit-function)
+       (lambda (oldfun value status)
+         (when (eq status 'finished)
+           ;; Don't count the special reference type (e.g. "buffer").
+           (when (or explicit-type
+                     (and (= num-args 1)
+                          (member value special-ref-types)))
+             (setq num-args (1- num-args)))
+           (let ((creation-fun (eshell--special-ref-function
+                                explicit-type 'creation-function)))
+             ;; Check if we already have the maximum number of
+             ;; arguments for this special ref type.  If so, finish
+             ;; the ref with ">".  Otherwise, insert a space and set
+             ;; the completion status to `sole'.
+             (if (eq (cdr (func-arity creation-fun)) num-args)
+                 (if (looking-at ">")
+                     (goto-char (match-end 0))
+                   (insert ">"))
+               (pcomplete-default-exit-function value status)
+               (setq status 'sole))
+             (funcall oldfun value status)))))
+      ;; Parse the arguments to this special reference and call the
+      ;; appropriate completion function.
+      (save-excursion
+        (eshell-with-temp-command (cons (+ 2 (pcomplete-begin)) (point))
+          (goto-char (point-max))
+          (let (pcomplete-args pcomplete-last pcomplete-index pcomplete-begins)
+            (when (let ((eshell-current-argument-plain t))
+                    (pcomplete-parse-arguments
+                     pcomplete-expand-before-complete))
+              (setq num-args (length pcomplete-args))
+              (if (= pcomplete-index pcomplete-last)
+                  ;; Call the default special ref completion function,
+                  ;; and also add the known special ref types as
+                  ;; possible completions.
+                  (throw 'pcomplete-completions
+                         (nconc
+                          (mapcar #'car eshell-special-ref-alist)
+                          (catch 'pcomplete-completions
+                            (funcall (eshell--special-ref-function
+                                      nil 'completion-function)))))
+                ;; Get the special ref type and call its completion
+                ;; function.
+                (let ((first (pcomplete-arg 'first)))
+                  (when (member first special-ref-types)
+                    ;; "Complete" the ref type (which we already
+                    ;; completed above).
+                    (pcomplete-here)
+                    (setq explicit-type first)))
+                (funcall (eshell--special-ref-function
+                          explicit-type 'completion-function))))))))))
+
+(defun eshell-get-buffer (buffer-or-name)
+  "Return the buffer specified by BUFFER-OR-NAME, creating a new one if needed.
+This is equivalent to `get-buffer-create', but only accepts a
+single argument."
+  (get-buffer-create buffer-or-name))
+
+(defun eshell-insert-buffer-name (buffer-name)
+  "Insert BUFFER-NAME into the current buffer at point."
+  (interactive "BName of buffer: ")
+  (insert-and-inherit "#<buffer " (eshell-quote-argument buffer-name) ">"))
+
+(defun eshell-complete-buffer-ref ()
+  "Perform completion for buffer references."
+  (pcomplete-here (mapcar #'buffer-name (buffer-list))))
+
+(defun eshell-get-marker (position buffer-or-name)
+  "Return the marker for character number POSITION in BUFFER-OR-NAME.
+BUFFER-OR-NAME can be a buffer or a string.  If a string and a
+live buffer with that name exists, use that buffer.  If no such
+buffer exists, create a new buffer with that name and use it."
+  (let ((marker (make-marker)))
+    (set-marker marker (string-to-number position)
+                (get-buffer-create buffer-or-name))))
+
+(defun eshell-insert-marker (position buffer-name)
+  "Insert a marker into the current buffer at point.
+This marker will point to POSITION in BUFFER-NAME."
+  (interactive "nPosition: \nBName of buffer: ")
+  (insert-and-inherit "#<marker " (number-to-string position) " "
+                      (eshell-quote-argument buffer-name) ">"))
+
+(defun eshell-complete-marker-ref ()
+  "Perform completion for marker references."
+  (pcomplete-here)
+  (pcomplete-here (mapcar #'buffer-name (buffer-list))))
 
 (provide 'esh-arg)
 ;;; esh-arg.el ends here
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 990d2ca1122..ecd947774ee 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -393,49 +393,6 @@ for a given process."
 
 ;; Command parsing
 
-(defsubst eshell--region-p (object)
-  "Return non-nil if OBJECT is a pair of numbers or markers."
-  (and (consp object)
-       (number-or-marker-p (car object))
-       (number-or-marker-p (cdr object))))
-
-(defmacro eshell-with-temp-command (command &rest body)
-  "Temporarily insert COMMAND into the buffer and execute the forms in BODY.
-
-COMMAND can be a string to insert, a cons cell (START . END)
-specifying a region in the current buffer, or (:file . FILENAME)
-to temporarily insert the contents of FILENAME.
-
-Before executing BODY, narrow the buffer to the text for COMMAND
-and and set point to the beginning of the narrowed region.
-
-The value returned is the last form in BODY."
-  (declare (indent 1))
-  (let ((command-sym (make-symbol "command"))
-        (begin-sym (make-symbol "begin"))
-        (end-sym (make-symbol "end")))
-    `(let ((,command-sym ,command))
-       (if (eshell--region-p ,command-sym)
-           (save-restriction
-             (narrow-to-region (car ,command-sym) (cdr ,command-sym))
-             (goto-char (car ,command-sym))
-             ,@body)
-         ;; Since parsing relies partly on buffer-local state
-         ;; (e.g. that of `eshell-parse-argument-hook'), we need to
-         ;; perform the parsing in the Eshell buffer.
-         (let ((,begin-sym (point)) ,end-sym)
-           (with-silent-modifications
-             (if (stringp ,command-sym)
-                 (insert ,command-sym)
-               (forward-char (cadr (insert-file-contents (cdr ,command-sym)))))
-             (setq ,end-sym (point))
-             (unwind-protect
-                 (save-restriction
-                   (narrow-to-region ,begin-sym ,end-sym)
-                   (goto-char ,begin-sym)
-                   ,@body)
-               (delete-region ,begin-sym ,end-sym))))))))
-
 (defun eshell-parse-command (command &optional args toplevel)
   "Parse the COMMAND, adding ARGS if given.
 COMMAND can be a string, a cons cell (START . END) demarcating a
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el
index d0f1e04e925..c29b96dd711 100644
--- a/lisp/eshell/esh-io.el
+++ b/lisp/eshell/esh-io.el
@@ -196,7 +196,8 @@ describing the mode, e.g. for using with 
`eshell-get-target'.")
 
 (defun eshell-parse-redirection ()
   "Parse an output redirection, such as `2>' or `>&'."
-  (when (not eshell-current-quoted)
+  (unless (or eshell-current-quoted
+              eshell-current-argument-plain)
     (cond
      ;; Copying a handle (e.g. `2>&1').
      ((looking-at (rx (? (group digit))
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index 3c946c22bdc..6561561440e 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -23,6 +23,7 @@
 
 ;;; Code:
 
+(require 'esh-arg)
 (require 'esh-io)
 (require 'esh-util)
 
@@ -158,6 +159,14 @@ PROC and STATUS to functions on the latter."
 (defun eshell-proc-initialize ()    ;Called from `eshell-mode' via intern-soft!
   "Initialize the process handling code."
   (make-local-variable 'eshell-process-list)
+  (setq-local eshell-special-ref-alist
+              (cons
+               `("process"
+                 (creation-function   get-process)
+                 (insertion-function  eshell-insert-process)
+                 (completion-function eshell-complete-process-ref))
+               eshell-special-ref-alist))
+
   (eshell-proc-mode))
 
 (define-obsolete-function-alias 'eshell-reset-after-proc
@@ -227,23 +236,6 @@ and signal names."
 
 (put 'eshell/kill 'eshell-no-numeric-conversions t)
 
-(defun eshell-read-process-name (prompt)
-  "Read the name of a process from the minibuffer, using completion.
-The prompt will be set to PROMPT."
-  (completing-read prompt
-                  (mapcar
-                    (lambda (proc)
-                      (cons (process-name proc) t))
-                   (process-list))
-                   nil t))
-
-(defun eshell-insert-process (process)
-  "Insert the name of PROCESS into the current buffer at point."
-  (interactive
-   (list (get-process
-         (eshell-read-process-name "Name of process: "))))
-  (insert-and-inherit "#<process " (process-name process) ">"))
-
 (defsubst eshell-record-process-object (object)
   "Record OBJECT as now running."
   (when (and eshell-subjob-messages
@@ -695,5 +687,30 @@ everything."
 ;    ;; `eshell-resume-eval'.
 ;    (eshell--reset-after-signal "continue\n")))
 
+;;; Special references
+
+(defun eshell-read-process-name (prompt)
+  "Read the name of a process from the minibuffer, using completion.
+The prompt will be set to PROMPT."
+  (completing-read prompt
+                  (mapcar
+                    (lambda (proc)
+                      (cons (process-name proc) t))
+                   (process-list))
+                   nil t))
+
+(defun eshell-insert-process (process)
+  "Insert the name of PROCESS into the current buffer at point."
+  (interactive
+   (list (get-process
+         (eshell-read-process-name "Name of process: "))))
+  (insert-and-inherit "#<process "
+                      (eshell-quote-argument (process-name process))
+                      ">"))
+
+(defun eshell-complete-process-ref ()
+  "Perform completion for process references."
+  (pcomplete-here (mapcar #'process-name (process-list))))
+
 (provide 'esh-proc)
 ;;; esh-proc.el ends here
diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el
index ca2f775318a..b22c286c635 100644
--- a/lisp/eshell/esh-util.el
+++ b/lisp/eshell/esh-util.el
@@ -242,6 +242,49 @@ current buffer."
    string)
   string)
 
+(defsubst eshell--region-p (object)
+  "Return non-nil if OBJECT is a pair of numbers or markers."
+  (and (consp object)
+       (number-or-marker-p (car object))
+       (number-or-marker-p (cdr object))))
+
+(defmacro eshell-with-temp-command (command &rest body)
+  "Temporarily insert COMMAND into the buffer and execute the forms in BODY.
+
+COMMAND can be a string to insert, a cons cell (START . END)
+specifying a region in the current buffer, or (:file . FILENAME)
+to temporarily insert the contents of FILENAME.
+
+Before executing BODY, narrow the buffer to the text for COMMAND
+and and set point to the beginning of the narrowed region.
+
+The value returned is the last form in BODY."
+  (declare (indent 1))
+  (let ((command-sym (make-symbol "command"))
+        (begin-sym (make-symbol "begin"))
+        (end-sym (make-symbol "end")))
+    `(let ((,command-sym ,command))
+       (if (eshell--region-p ,command-sym)
+           (save-restriction
+             (narrow-to-region (car ,command-sym) (cdr ,command-sym))
+             (goto-char (car ,command-sym))
+             ,@body)
+         ;; Since parsing relies partly on buffer-local state
+         ;; (e.g. that of `eshell-parse-argument-hook'), we need to
+         ;; perform the parsing in the Eshell buffer.
+         (let ((,begin-sym (point)) ,end-sym)
+           (with-silent-modifications
+             (if (stringp ,command-sym)
+                 (insert ,command-sym)
+               (forward-char (cadr (insert-file-contents (cdr ,command-sym)))))
+             (setq ,end-sym (point))
+             (unwind-protect
+                 (save-restriction
+                   (narrow-to-region ,begin-sym ,end-sym)
+                   (goto-char ,begin-sym)
+                   ,@body)
+               (delete-region ,begin-sym ,end-sym))))))))
+
 (defun eshell-find-delimiter
   (open close &optional bound reverse-p backslash-p)
   "From point, find the CLOSE delimiter corresponding to OPEN.
diff --git a/lisp/ffap.el b/lisp/ffap.el
index 6f477dd790b..530e3da182e 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -554,7 +554,7 @@ Looks at `ffap-ftp-default-user', returns \"\" for 
\"localhost\"."
     (concat "gopher://"; mach "/"))
    ;; www.ncsa.uiuc.edu
    ((and (string-match "\\`w\\(ww\\|eb\\)[-.]" mach))
-    (concat "http://"; mach "/"))
+    (concat "https://"; mach "/"))
    ;; More cases?
    (ffap-ftp-regexp (ffap-host-to-filename mach))
    ))
@@ -730,6 +730,7 @@ This uses `ffap-file-exists-string', which may try adding 
suffixes from
 (defvar ffap-alist
   '(
     ("" . ffap-completable)            ; completion, slow on some systems
+    ("" . ffap-in-project)             ; maybe in the root of the project
     ("\\.info\\'" . ffap-info)         ; gzip.info
     ("\\`info/" . ffap-info-2)         ; info/emacs
     ("\\`[-[:lower:]]+\\'" . ffap-info-3) ; (emacs)Top [only in the 
parentheses]
@@ -793,6 +794,11 @@ to extract substrings.")
         (cmp (file-name-completion (file-name-nondirectory name) dir)))
     (and cmp (concat dir cmp))))
 
+(declare-function project-root "project" (project))
+(defun ffap-in-project (name)
+  (when-let (project (project-current))
+    (file-name-concat (project-root project) name)))
+
 (defun ffap-home (name) (ffap-locate-file name t '("~")))
 
 (defun ffap-info (name)
diff --git a/lisp/files-x.el b/lisp/files-x.el
index 3ba7632d253..a8d525ec5ff 100644
--- a/lisp/files-x.el
+++ b/lisp/files-x.el
@@ -31,6 +31,8 @@
 ;;; Code:
 
 (eval-when-compile (require 'subr-x)) ; for string-trim-right
+(declare-function dosified-file-name "dos-fns" (file-name))
+(declare-function project-root "project" (project))
 
 
 ;;; Commands to add/delete file-local/directory-local variables.
@@ -410,7 +412,7 @@ then this function adds it."
 
 (defvar auto-insert) ; from autoinsert.el
 
-(defun modify-dir-local-variable (mode variable value op)
+(defun modify-dir-local-variable (mode variable value op &optional file)
   "Modify directory-local VARIABLE in .dir-locals.el depending on operation OP.
 
 If OP is `add-or-replace' then delete all existing settings of
@@ -422,28 +424,37 @@ If .dir-locals.el was not found and OP is not `delete' 
then create
 this file in the current directory.
 
 If OP is `delete' then delete all existing settings of VARIABLE
-from the MODE alist ignoring the input argument VALUE."
+from the MODE alist ignoring the input argument VALUE.
+
+Optional argument FILE, when non-nil, specifies what file to modify.  It
+should be an expanded filename."
   (catch 'exit
     (unless enable-local-variables
       (throw 'exit (message "Directory-local variables are disabled")))
-    (let* ((dir-or-cache (and (buffer-file-name)
-                              (not (file-remote-p (buffer-file-name)))
-                              (dir-locals-find-file (buffer-file-name))))
-           (variables-file
-            ;; If there are several .dir-locals, the user probably
-            ;; wants to edit the last one (the highest priority).
-            (cond ((stringp dir-or-cache)
-                   (car (last (dir-locals--all-files dir-or-cache))))
-                  ((consp dir-or-cache)        ; result from cache
-                   ;; If cache element has an mtime, assume it came
-                   ;; from a file.  Otherwise, assume it was set
-                   ;; directly.
-                   (if (nth 2 dir-or-cache)
-                       (car (last (dir-locals--all-files (car dir-or-cache))))
-                     (cadr dir-or-cache)))
-                  ;; Try to make a proper file-name.
-                  (t (expand-file-name dir-locals-file))))
-           variables)
+    (let ((variables-file
+           (if (stringp file)
+               file
+             (let ((dir-or-cache
+                    (and (buffer-file-name)
+                         (not (file-remote-p (buffer-file-name)))
+                         (dir-locals-find-file (buffer-file-name)))))
+               ;; If there are several .dir-locals, the user probably
+               ;; wants to edit the last one (the highest priority).
+               (cond
+                ((stringp dir-or-cache)
+                 (car (last (dir-locals--all-files dir-or-cache))))
+                ((consp dir-or-cache)  ; result from cache
+                 ;; If cache element has an mtime, assume it came
+                 ;; from a file.  Otherwise, assume it was set
+                 ;; directly.
+                 (if (nth 2 dir-or-cache)
+                     (car (last (dir-locals--all-files (car dir-or-cache))))
+                   (cadr dir-or-cache)))
+                ;; Try to make a proper file-name.
+                (t (expand-file-name (if (eq system-type 'ms-dos)
+                                         (dosified-file-name dir-locals-file)
+                                       dir-locals-file)))))))
+          variables)
       ;; I can't be bothered to handle this case right now.
       ;; Dir locals were set directly from a class.  You need to
       ;; directly modify the class in dir-locals-class-alist.
@@ -527,33 +538,75 @@ from the MODE alist ignoring the input argument VALUE."
                                      (cdr mode-variables) "\n"))))
            variables "\n")))
 
+(defun read-dir-locals-file ()
+  "Read a dir-locals filename using completion.
+Intended to be used in the `interactive' spec of `add-dir-local-variable',
+`delete-dir-local-variable' and `copy-file-locals-to-dir-locals'.
+
+Returns the filename, expanded."
+  (let* ((pri dir-locals-file)
+         (sec (replace-regexp-in-string ".el$" "-2.el" dir-locals-file))
+         (dir (or (locate-dominating-file default-directory pri)
+                  (locate-dominating-file default-directory sec))))
+    (expand-file-name
+     (read-file-name
+      "File: "
+      (cond (dir)
+            ((when-let ((proj (and (featurep 'project) (project-current))))
+               (project-root proj))))
+      nil
+      (lambda (fname)
+        (member (file-name-nondirectory fname) (list pri sec)))
+      dir-locals-file))))
+
 ;;;###autoload
-(defun add-dir-local-variable (mode variable value)
-  "Add directory-local VARIABLE with its VALUE and MODE to .dir-locals.el."
+(defun add-dir-local-variable (mode variable value &optional file)
+  "Add directory-local VARIABLE with its VALUE and MODE to .dir-locals.el.
+
+With a prefix argument, prompt for the file to modify.
+
+When called from Lisp, FILE may be the expanded name of the dir-locals file
+where to add VARIABLE."
   (interactive
    (let (variable)
      (list
       (read-file-local-variable-mode)
       (setq variable (read-file-local-variable "Add directory-local variable"))
-      (read-file-local-variable-value variable))))
-  (modify-dir-local-variable mode variable value 'add-or-replace))
+      (read-file-local-variable-value variable)
+      (when current-prefix-arg
+        (read-dir-locals-file)))))
+  (modify-dir-local-variable mode variable value 'add-or-replace file))
 
 ;;;###autoload
-(defun delete-dir-local-variable (mode variable)
-  "Delete all MODE settings of file-local VARIABLE from .dir-locals.el."
+(defun delete-dir-local-variable (mode variable &optional file)
+  "Delete all MODE settings of dir-local VARIABLE from .dir-locals.el.
+
+With a prefix argument, prompt for the file to modify.
+
+When called from Lisp, FILE may be the expanded name of the dir-locals file
+from where to delete VARIABLE."
   (interactive
    (list
     (read-file-local-variable-mode)
-    (read-file-local-variable "Delete directory-local variable")))
-  (modify-dir-local-variable mode variable nil 'delete))
+    (read-file-local-variable "Delete directory-local variable")
+    (when current-prefix-arg
+      (read-dir-locals-file))))
+  (modify-dir-local-variable mode variable nil 'delete file))
 
 ;;;###autoload
-(defun copy-file-locals-to-dir-locals ()
-  "Copy file-local variables to .dir-locals.el."
-  (interactive)
+(defun copy-file-locals-to-dir-locals (&optional file)
+  "Copy file-local variables to .dir-locals.el.
+
+With a prefix argument, prompt for the file to modify.
+
+When called from Lisp, FILE may be the expanded name of the dir-locals file
+where to copy the file-local variables."
+  (interactive
+   (list (when current-prefix-arg
+           (read-dir-locals-file))))
   (dolist (elt file-local-variables-alist)
     (unless (assq (car elt) dir-local-variables-alist)
-      (add-dir-local-variable major-mode (car elt) (cdr elt)))))
+      (add-dir-local-variable major-mode (car elt) (cdr elt) file))))
 
 ;;;###autoload
 (defun copy-dir-locals-to-file-locals ()
@@ -647,7 +700,8 @@ Return a reordered plist."
   "Return the connection profiles list for CRITERIA.
 CRITERIA is a plist identifying a connection and the application
 using this connection, see `connection-local-criteria-alist'."
-  (let (profiles)
+  (let ((criteria (connection-local-normalize-criteria criteria))
+        profiles)
     (dolist (crit-alist connection-local-criteria-alist)
       (let ((crit criteria)
             (match t))
diff --git a/lisp/files.el b/lisp/files.el
index 488e94e0a22..29f66e27989 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -1135,9 +1135,11 @@ the function needs to examine, starting with FILE."
     (while (not (or root
                     (null file)
                     (string-match locate-dominating-stop-dir-regexp file)))
-      (setq try (if (stringp name)
-                    (and (file-directory-p file)
-                         (file-exists-p (expand-file-name name file)))
+      (setq file (if (file-directory-p file)
+                     file
+                   (file-name-directory file))
+            try (if (stringp name)
+                    (file-exists-p (expand-file-name name file))
                   (funcall name file)))
       (cond (try (setq root file))
             ((equal file (setq file (file-name-directory
@@ -5936,9 +5938,10 @@ Before and after saving the buffer, this function runs
                          t))
        ;; If file not writable, see if we can make it writable
        ;; temporarily while we write it (its original modes will be
-       ;; restored in 'basic-save-buffer').  But no need to do so if
-       ;; we have just backed it up (setmodes is set) because that
-       ;; says we're superseding.
+       ;; restored in 'basic-save-buffer' or, in case of an error, in
+       ;; the `unwind-protect' below).  But no need to do so if we
+       ;; have just backed it up (setmodes is set) because that says
+       ;; we're superseding.
        (cond ((and tempsetmodes (not setmodes))
               ;; Change the mode back, after writing.
               (setq setmodes
@@ -5948,7 +5951,12 @@ Before and after saving the buffer, this function runs
                             (file-extended-attributes buffer-file-name))
                           buffer-file-name))
               ;; If set-file-extended-attributes fails to make the
-              ;; file writable, fall back on set-file-modes.
+              ;; file writable, fall back on set-file-modes.  Calling
+              ;; set-file-extended-attributes here may or may not be
+              ;; actually necessary.  However, since its exact
+              ;; behavior is highly port-specific, since calling it
+              ;; does not do any harm, and since the call has a long
+              ;; history, we decided to leave it in (bug#66546).
               (with-demoted-errors "Error setting attributes: %s"
                 (set-file-extended-attributes buffer-file-name
                                               (nth 1 setmodes)))
@@ -5965,12 +5973,22 @@ Before and after saving the buffer, this function runs
                               buffer-file-name nil t buffer-file-truename)
                 (when save-silently (message nil))
                (setq success t))
-           ;; If we get an error writing the new file, and we made
-           ;; the backup by renaming, undo the backing-up.
-           (and setmodes (not success)
-                (progn
-                  (rename-file (nth 2 setmodes) buffer-file-name t)
-                  (setq buffer-backed-up nil)))))))
+            (cond
+             ;; If we get an error writing the file, and there is no
+             ;; backup file, then we (most likely) made that file
+             ;; writable above.  Attempt to undo the write-access.
+             ((and setmodes (not success)
+                   (equal (nth 2 setmodes) buffer-file-name))
+             (with-demoted-errors "Error setting file modes: %S"
+               (set-file-modes buffer-file-name (car setmodes)))
+             (with-demoted-errors "Error setting attributes: %s"
+               (set-file-extended-attributes buffer-file-name
+                                             (nth 1 setmodes))))
+            ;; If we get an error writing the new file, and we made
+            ;; the backup by renaming, undo the backing-up.
+            ((and setmodes (not success))
+             (rename-file (nth 2 setmodes) buffer-file-name t)
+             (setq buffer-backed-up nil)))))))
     setmodes))
 
 (declare-function diff-no-select "diff"
diff --git a/lisp/gnus/ChangeLog.3 b/lisp/gnus/ChangeLog.3
index d0b195e5f13..0fc5c093371 100644
--- a/lisp/gnus/ChangeLog.3
+++ b/lisp/gnus/ChangeLog.3
@@ -578,7 +578,7 @@
 
        * gnus-start.el (gnus-dribble-read-file): Don't stop the auto-saving of
        the dribble buffer even when it is shrunk a lot.
-       <http://thread.gmane.org/gmane.emacs.gnus.user/16923>
+       <http://thread.gmane.org/gmane.emacs.gnus.user/16923> [dead link]
 
 2014-06-26  Glenn Morris  <rgm@gnu.org>
 
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 6f201f9c3df..bd9a49eb6a5 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -1622,7 +1622,8 @@ predicate.  See Info node `(gnus)Customizing Articles'."
   "The protocol used for encrypt articles.
 It is a string, such as \"PGP\".  If nil, ask user."
   :version "22.1"
-  :type 'string
+  :type '(choice (const :tag "Ask me" nil)
+                 string)
   :group 'mime-security)
 
 (defcustom gnus-use-idna t
@@ -7560,10 +7561,11 @@ must return `mid', `mail', `invalid' or `ask'."
   :version "22.1"
   :group 'gnus-article-buttons
   :type '(choice (function-item :tag "Heuristic function"
-                               gnus-button-mid-or-mail-heuristic)
-                (const ask)
-                (const mid)
-                (const mail)))
+                                gnus-button-mid-or-mail-heuristic)
+                 (const :tag "Query me" ask)
+                 (const :tag "Assume it's a message ID" mid)
+                 (const :tag "Assume it's a mail address" mail)
+                 function))
 
 (defcustom gnus-button-mid-or-mail-heuristic-alist
   '((-10.0 . ".+\\$.+@")
diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el
index 1a926619e14..aee122aa557 100644
--- a/lisp/gnus/gnus-bookmark.el
+++ b/lisp/gnus/gnus-bookmark.el
@@ -61,12 +61,12 @@
 ;; (define-key global-map "\C-crl" 'gnus-bookmark-bmenu-list)
 
 ;; FIXME: Add keybindings, see
-;; http://thread.gmane.org/gmane.emacs.gnus.general/63101/focus=63379
-;; http://thread.gmane.org/v9fxx9fkm4.fsf@marauder.physik.uni-ulm.de
+;; http://thread.gmane.org/gmane.emacs.gnus.general/63101/focus=63379 [dead 
link]
+;; http://thread.gmane.org/v9fxx9fkm4.fsf@marauder.physik.uni-ulm.de [dead 
link]
 
 ;; FIXME: Check if `gnus-bookmark.el' should use
 ;; `bookmark-make-record-function'.
-;; Cf. http://article.gmane.org/gmane.emacs.gnus.general/66076
+;; Cf. http://article.gmane.org/gmane.emacs.gnus.general/66076 [dead link]
 
 (defgroup gnus-bookmark nil
   "Setting, annotation and jumping to Gnus bookmarks."
@@ -112,7 +112,7 @@ You can toggle whether details are shown with 
\\<gnus-bookmark-bmenu-mode-map>\\
 
 (defcustom gnus-bookmark-bookmark-inline-details '(author)
   "Details to be shown with `gnus-bookmark-bmenu-toggle-infos'.
-The default value is \(subject)."
+The default value is (author)."
   :type '(list :tag "Gnus bookmark details"
               (set :inline t
                    (const :tag "Author" author)
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 8c1d7e3c86a..01e6a8f317f 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -286,10 +286,10 @@ If you want to modify the group buffer, you can use this 
hook."
   :type 'hook)
 
 (defcustom gnus-useful-groups
-  '(("(ding) mailing list mirrored at gmane.org"
+  '(("(ding) mailing list mirrored at gmane.io"
      "gmane.emacs.gnus.general"
      (nntp "Gmane"
-          (nntp-address "news.gmane.org")))
+           (nntp-address "news.gmane.io")))
     ("Gnus bug archive"
      "gnus.gnus-bug"
      (nntp "news.gnus.org"
@@ -1436,14 +1436,8 @@ if it is a string, only list groups matching REGEXP."
 
 ;; Moving through the Group buffer (in topic mode) e.g. with C-n doesn't
 ;; update the state (enabled/disabled) of the icon `gnus-group-describe-group'
-;; automatically.  After `C-l' the state is correct.  See the following report
-;; on emacs-devel
-;; <http://thread.gmane.org/v9acdmrcse.fsf@marauder.physik.uni-ulm.de>:
-;; From: Reiner Steib
-;; Subject: tool bar icons not updated according to :active condition
-;; Newsgroups: gmane.emacs.devel
-;; Date: Mon, 23 Jan 2006 19:59:13 +0100
-;; Message-ID: <v9acdmrcse.fsf@marauder.physik.uni-ulm.de>
+;; automatically.  After `C-l' the state is correct.
+;; See: https://lists.gnu.org/r/emacs-devel/2006-01/msg00853.html
 
 ;; Using `redraw-frame' (see `gnus-tool-bar-update') in Emacs might
 ;; be confusing, so maybe we shouldn't call it by default.
@@ -2336,7 +2330,7 @@ Valid input formats include:
     (cond
      ;; URLs providing `group', `start' and `range':
      ((string-match
-       ;; http://thread.gmane.org/gmane.emacs.devel/86326/focus=86525
+       ;; http://thread.gmane.org/gmane.emacs.devel/86326/focus=86525 [dead 
link]
        
"^http://thread\\.gmane\\.org/\\([^/]+\\)/\\([0-9]+\\)/focus=\\([0-9]+\\)$"
        url)
       (setq group (match-string 1 url)
@@ -2347,7 +2341,7 @@ Valid input formats include:
                     start -1)))
      ;; URLs providing `group' and `start':
      ((or (string-match
-          ;; http://article.gmane.org/gmane.comp.gnu.make.bugs/3584
+           ;; http://article.gmane.org/gmane.comp.gnu.make.bugs/3584 [dead 
link]
           
"^http://\\(?:thread\\|article\\|permalink\\)\\.gmane\\.org/\\([^/]+\\)/\\([0-9]+\\)"
           url)
          (string-match
@@ -2355,7 +2349,7 @@ Valid input formats include:
           "^\\(?:nntp\\|news\\)://news\\.gmane\\.org/\\([^/]+\\)/\\([0-9]+\\)"
           url)
          (string-match
-          ;; 
http://news.gmane.org/group/gmane.emacs.gnus.general/thread=65099/force_load=t
+           ;; 
http://news.gmane.org/group/gmane.emacs.gnus.general/thread=65099/force_load=t 
[dead link]
           "^http://news\\.gmane\\.org/group/\\([^/]+\\)/thread=\\([0-9]+\\)"
           url))
       (setq group (match-string 1 url)
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index f576d4e6147..1639c062471 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -122,7 +122,7 @@ The server has to support NOV for any of this to work.
 
 This feature can seriously impact performance it ignores all
 locally cached header entries.  Setting it to t for groups for a
-server that doesn't expire articles (such as news.gmane.org),
+server that doesn't expire articles (such as news.gmane.io),
 leads to very slow summary generation."
   :group 'gnus-thread
   :type '(choice (const :tag "off" nil)
@@ -322,7 +322,8 @@ This can either be a regular expression or list of regular 
expressions
 that will be removed from subject strings if fuzzy subject
 simplification is selected."
   :group 'gnus-thread
-  :type '(repeat regexp))
+  :type '(choice regexp
+                 (repeat regexp)))
 
 (defcustom gnus-show-threads t
   "If non-nil, display threads in summary mode."
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 0071c02c081..0f5d253bc96 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -1145,7 +1145,8 @@ Note that these functions use `mail-citation-hook' if 
that is non-nil."
 This can also be a list of functions.  Each function can find the
 citation between (point) and (mark t).  And each function should leave
 point and mark around the citation text as modified."
-  :type 'function
+  :type '(choice function
+                 (repeat function))
   :link '(custom-manual "(message)Insertion Variables")
   :group 'message-insertion)
 
@@ -1406,8 +1407,9 @@ This can also be a list of values."
   :group 'message
   :link '(custom-manual "(message)Mail Aliases")
   :type '(choice (const :tag "Use Mailabbrev" abbrev)
-                (const :tag "Use ecomplete" ecomplete)
-                (const :tag "No expansion" nil)))
+                 (const :tag "Use ecomplete" ecomplete)
+                 (set (const :tag "Use Mailabbrev" abbrev)
+                      (const :tag "Use ecomplete" ecomplete))))
 
 (defcustom message-self-insert-commands '(self-insert-command)
   "List of `self-insert-command's used to trigger ecomplete.
@@ -1451,8 +1453,9 @@ If a function email is passed as the argument."
   :group 'message
   :link '(custom-manual "(message)Wide Reply")
   :type '(choice (const :tag "Yourself" nil)
-                regexp
-                (repeat :tag "Regexp List" regexp)))
+                 regexp
+                 (repeat :tag "Regexp List" regexp)
+                 function))
 
 (defsubst message-dont-reply-to-names ()
   (if (functionp message-dont-reply-to-names)
diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el
index 6025ca7e72a..24cd5eb83d3 100644
--- a/lisp/gnus/mml.el
+++ b/lisp/gnus/mml.el
@@ -1369,9 +1369,9 @@ If not set, `default-directory' will be used."
 ;;; Attachment functions.
 
 (defcustom mml-dnd-protocol-alist
-  '(("^file:///" . mml-dnd-attach-file)
-    ("^file://"  . dnd-open-file)
-    ("^file:"    . mml-dnd-attach-file))
+  '(("^file:///" . mml-dnd-attach-file) ; GNOME, KDE, and suchlike.
+    ("^file:/[^/]" . mml-dnd-attach-file) ; Motif, other systems.
+    ("^file:[^/]" . mml-dnd-attach-file)) ; MS-Windows.
   "The functions to call when a drop in `mml-mode' is made.
 See `dnd-protocol-alist' for more information.  When nil, behave
 as in other buffers."
@@ -1460,29 +1460,36 @@ will be computed and used."
                 (file-name-nondirectory file)))
       (goto-char at-end))))
 
-(defun mml-dnd-attach-file (uri _action)
-  "Attach a drag and drop file.
-
-Ask for type, description or disposition according to
-`mml-dnd-attach-options'."
-  (let ((file (dnd-get-local-file-name uri t)))
-    (when (and file (file-regular-p file))
-      (let ((mml-dnd-attach-options mml-dnd-attach-options)
-           type description disposition)
-       (setq mml-dnd-attach-options
-             (when (and (eq mml-dnd-attach-options t)
-                        (not
-                         (y-or-n-p
-                          "Use default type, disposition and description? ")))
-               '(type description disposition)))
-       (when (or (memq 'type mml-dnd-attach-options)
-                 (memq 'disposition mml-dnd-attach-options))
-         (setq type (mml-minibuffer-read-type file)))
-       (when (memq 'description mml-dnd-attach-options)
-         (setq description (mml-minibuffer-read-description)))
-       (when (memq 'disposition mml-dnd-attach-options)
-         (setq disposition (mml-minibuffer-read-disposition type nil file)))
-       (mml-attach-file file type description disposition)))))
+(defun mml-dnd-attach-file (uris _action)
+  "Attach a drag and drop URIS, a list of local file URIs.
+
+Query whether to use the types, dispositions and descriptions
+default for each URL, subject to `mml-dnd-attach-options'.
+
+Return the action `private', communicating to the drop source
+that the file has been attached."
+  (let (file (mml-dnd-attach-options mml-dnd-attach-options))
+    (setq mml-dnd-attach-options
+         (when (and (eq mml-dnd-attach-options t)
+                    (not
+                     (y-or-n-p
+                      "Use default type, disposition and description? ")))
+           '(type description disposition)))
+    (dolist (uri uris)
+      (setq file (dnd-get-local-file-name uri t))
+      (when (and file (file-regular-p file))
+        (let (type description disposition)
+         (when (or (memq 'type mml-dnd-attach-options)
+                   (memq 'disposition mml-dnd-attach-options))
+           (setq type (mml-minibuffer-read-type file)))
+         (when (memq 'description mml-dnd-attach-options)
+           (setq description (mml-minibuffer-read-description)))
+         (when (memq 'disposition mml-dnd-attach-options)
+           (setq disposition (mml-minibuffer-read-disposition type nil file)))
+         (mml-attach-file file type description disposition)))))
+  'private)
+
+(put 'mml-dnd-attach-file 'dnd-multiple-handler t)
 
 (defun mml-attach-buffer (buffer &optional type description disposition 
filename)
   "Attach a buffer to the outgoing MIME message.
diff --git a/lisp/gnus/mml2015.el b/lisp/gnus/mml2015.el
index 21bb46b8fa7..df3dd434b0a 100644
--- a/lisp/gnus/mml2015.el
+++ b/lisp/gnus/mml2015.el
@@ -148,8 +148,8 @@ If set, it overrides the setting of 
`mml2015-sign-with-sender'."
   ;;
   ;; This function doesn't handle NotDashEscaped correctly.  EasyPG handles it
   ;; correctly.
-  ;; http://thread.gmane.org/gmane.emacs.gnus.general/66062/focus=66082
-  ;; http://thread.gmane.org/gmane.emacs.gnus.general/65087/focus=65109
+  ;; http://thread.gmane.org/gmane.emacs.gnus.general/66062/focus=66082 [dead 
link]
+  ;; http://thread.gmane.org/gmane.emacs.gnus.general/65087/focus=65109 [dead 
link]
   (goto-char (point-min))
   (forward-line)
   ;; We need to be careful not to strip beyond the armor headers.
diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el
index cdba6e663bf..5dc5bf1fd75 100644
--- a/lisp/gnus/nnheader.el
+++ b/lisp/gnus/nnheader.el
@@ -85,7 +85,7 @@ Integer values will in effect be rounded up to the nearest 
multiple of
 
 (defvar nnheader-read-timeout
   (if (memq system-type '(windows-nt cygwin))
-      ;; http://thread.gmane.org/v9655t3pjo.fsf@marauder.physik.uni-ulm.de
+      ;; http://thread.gmane.org/v9655t3pjo.fsf@marauder.physik.uni-ulm.de 
[dead link]
       ;;
       ;; IIRC, values lower than 1.0 didn't/don't work on Windows/DOS.
       ;;
diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el
index c5f2cb672d7..06a0bc7e799 100644
--- a/lisp/gnus/nnrss.el
+++ b/lisp/gnus/nnrss.el
@@ -629,7 +629,7 @@ which RSS 2.0 allows."
               (assoc 'href
                      (nnrss-discover-feed
                       (read-string
-                       (format "URL to search for %s: " group) "http://";)))))
+                        (format "URL to search for %s: " group) "https://";)))))
        (let ((pair (assoc-string group nnrss-server-data)))
          (if pair
              (setcdr (cdr pair) (list url))
diff --git a/lisp/gnus/nnweb.el b/lisp/gnus/nnweb.el
index d3bf138edeb..f175379f53d 100644
--- a/lisp/gnus/nnweb.el
+++ b/lisp/gnus/nnweb.el
@@ -42,37 +42,30 @@
 
 (defvoo nnweb-type 'google
   "What search engine type is being used.
-Valid types include `google', `dejanews', and `gmane'.")
+Valid types include `google' and `dejanews'.")
 
 (defvar nnweb-type-definition
   '((google
-     (id . "http://www.google.com/groups?as_umsgid=%s&hl=en&dmode=source";)
-     (result . "http://groups.google.com/group/%s/msg/%s?dmode=source";)
+     (id . "https://www.google.com/groups?as_umsgid=%s&hl=en&dmode=source";)
+     (result . "https://groups.google.com/group/%s/msg/%s?dmode=source";)
      (article . nnweb-google-wash-article)
      (reference . identity)
      (map . nnweb-google-create-mapping)
      (search . nnweb-google-search)
-     (address . "http://groups.google.com/groups";)
-     (base    . "http://groups.google.com";)
+     (address . "https://groups.google.com/groups";)
+     (base    . "https://groups.google.com";)
      (identifier . nnweb-google-identity))
+    ;; FIXME: Make obsolete?
     (dejanews ;; alias of google
-     (id . "http://www.google.com/groups?as_umsgid=%s&hl=en&dmode=source";)
-     (result . "http://groups.google.com/group/%s/msg/%s?dmode=source";)
+     (id . "https://www.google.com/groups?as_umsgid=%s&hl=en&dmode=source";)
+     (result . "https://groups.google.com/group/%s/msg/%s?dmode=source";)
      (article . nnweb-google-wash-article)
      (reference . identity)
      (map . nnweb-google-create-mapping)
      (search . nnweb-google-search)
-     (address . "http://groups.google.com/groups";)
-     (base    . "http://groups.google.com";)
-     (identifier . nnweb-google-identity))
-    (gmane
-     (article . nnweb-gmane-wash-article)
-     (id . "http://gmane.org/view.php?group=%s";)
-     (reference . identity)
-     (map . nnweb-gmane-create-mapping)
-     (search . nnweb-gmane-search)
-     (address . "http://search.gmane.org/nov.php";)
-     (identifier . nnweb-gmane-identity)))
+     (address . "https://groups.google.com/groups";)
+     (base    . "https://groups.google.com";)
+     (identifier . nnweb-google-identity)))
   "Type-definition alist.")
 
 (defvoo nnweb-search nil
@@ -254,6 +247,8 @@ Valid types include `google', `dejanews', and `gmane'.")
 
 (defun nnweb-definition (type &optional noerror)
   "Return the definition of TYPE."
+  (when (eq nnweb-type 'gmane)
+    (user-error "`gmane' is no longer a valid value for `nnweb-type'"))
   (let ((def (cdr (assq type (assq nnweb-type nnweb-type-definition)))))
     (when (and (not def)
               (not noerror))
@@ -277,6 +272,8 @@ Valid types include `google', `dejanews', and `gmane'.")
   (unless (gnus-buffer-live-p nnweb-buffer)
     (setq nnweb-buffer
          (save-current-buffer
+            (when (eq nnweb-type 'gmane)
+              (user-error "`gmane' is no longer a valid value for 
`nnweb-type'"))
             (nnheader-set-temp-buffer
              (format " *nnweb %s %s %s*"
                      nnweb-type nnweb-search server))
@@ -437,10 +434,11 @@ Valid types include `google', `dejanews', and `gmane'.")
     url))
 
 ;;;
-;;; gmane.org
+;;; gmane.org -- now obsolete as the gmane.org web interface is gone
 ;;;
 (defun nnweb-gmane-create-mapping ()
   "Perform the search and create a number-to-url alist."
+  (declare (obsolete nil "30.1"))
   (with-current-buffer nnweb-buffer
     (let ((case-fold-search t)
          (active (or (cadr (assoc nnweb-group nnweb-group-alist))
@@ -484,6 +482,7 @@ Valid types include `google', `dejanews', and `gmane'.")
            (sort (nconc nnweb-articles map) #'car-less-than-car)))))
 
 (defun nnweb-gmane-wash-article ()
+  (declare (obsolete nil "30.1"))
   (let ((case-fold-search t))
     (goto-char (point-min))
     (when (search-forward "<!--X-Head-of-Message-->" nil t)
@@ -495,6 +494,7 @@ Valid types include `google', `dejanews', and `gmane'.")
       (mm-url-remove-markup))))
 
 (defun nnweb-gmane-search (search)
+  (declare (obsolete nil "30.1"))
   (mm-url-insert
    (concat
     (nnweb-definition 'address)
@@ -511,6 +511,7 @@ Valid types include `google', `dejanews', and `gmane'.")
 
 (defun nnweb-gmane-identity (url)
   "Return a unique identifier based on URL."
+  (declare (obsolete nil "30.1"))
   (if (string-match "group=\\(.+\\)" url)
       (match-string 1 url)
     url))
diff --git a/lisp/gnus/spam-report.el b/lisp/gnus/spam-report.el
index 7e0392797f9..8435d2d0124 100644
--- a/lisp/gnus/spam-report.el
+++ b/lisp/gnus/spam-report.el
@@ -49,7 +49,7 @@ instead."
   "Whether the article number (faster!) or the header should be used.
 
 You must set this to nil if you don't read Gmane groups directly
-from news.gmane.org, e.g. when using local newsserver such as
+from news.gmane.io, e.g. when using local newsserver such as
 leafnode."
   :type 'boolean)
 
@@ -64,7 +64,7 @@ The function must accept the arguments `host' and `report'."
                 spam-report-url-ping-mm-url)
          (const :tag "Store request URLs in `spam-report-requests-file'"
                 spam-report-url-to-file)
-         (function :tag "User defined function" nil)))
+         (function :tag "User defined function")))
 
 (defcustom spam-report-requests-file
   (nnheader-concat gnus-directory "spam/" "spam-report-requests.url")
@@ -149,6 +149,8 @@ submitted at once.  Internal variable.")
   (when (and gnus-newsgroup-name
             (or (null spam-report-gmane-regex)
                 (string-match spam-report-gmane-regex gnus-newsgroup-name)))
+    ;; FIXME: These addresses are down.  There is also no
+    ;;        unspam.gmane.io or spam.gmane.io.
     (let ((rpt-host (if unspam "unspam.gmane.org" "spam.gmane.org")))
       (gnus-message 6 "Reporting article %d to %s..." article rpt-host)
       (cond
diff --git a/lisp/ido.el b/lisp/ido.el
index bbb3264f4f7..2daf3bae717 100644
--- a/lisp/ido.el
+++ b/lisp/ido.el
@@ -2326,7 +2326,7 @@ If cursor is not at the end of the user input, move to 
end of input."
                          (if (eq ido-use-filename-at-point 'guess)
                              (ffap-guesser)
                            (ffap-string-at-point))))
-              (not (string-match "\\`http:/" fn)))
+               (not (string-match (rx bos "http" (? "s") ":/") fn)))
           (let ((absolute-fn (expand-file-name fn)))
             (cond
              ((file-directory-p absolute-fn)
diff --git a/lisp/info-look.el b/lisp/info-look.el
index da45e30cd36..eeb758e5b85 100644
--- a/lisp/info-look.el
+++ b/lisp/info-look.el
@@ -1,7 +1,6 @@
 ;;; info-look.el --- major-mode-sensitive Info index lookup facility -*- 
lexical-binding: t -*-
-;; An older version of this was known as libc.el.
 
-;; Copyright (C) 1995-1999, 2001-2023 Free Software Foundation, Inc.
+;; Copyright (C) 1995-2023 Free Software Foundation, Inc.
 
 ;; Author: Ralph Schleicher <rs@ralph-schleicher.de>
 ;; Keywords: help languages
@@ -28,11 +27,9 @@
 
 ;; Some additional sources of (Tex)info files for non-GNU packages:
 ;;
-;; Scheme: <URL:http://groups.csail.mit.edu/mac/ftpdir/scm/r5rs.info.tar.gz>
-;; LaTeX:
-;;  
<URL:http://ctan.tug.org/tex-archive/info/latex2e-help-texinfo/latex2e.texi>
+;; Scheme: https://groups.csail.mit.edu/mac/ftpdir/scm/r5rs.info.tar.gz
+;; LaTeX: https://mirrors.ctan.org/info/latex2e-help-texinfo/latex2e.texi
 ;;  (or CTAN mirrors)
-;; Perl: <URL:http://ftp.cpan.org/pub/CPAN/doc/manual/texinfo/> (or CPAN 
mirrors)
 
 ;; Traditionally, makeinfo quoted `like this', but version 5 and later
 ;; quotes 'like this' or ‘like this’.  Doc specs with patterns
diff --git a/lisp/language/hanja-util.el b/lisp/language/hanja-util.el
index be0364b1c23..b5ef9230d27 100644
--- a/lisp/language/hanja-util.el
+++ b/lisp/language/hanja-util.el
@@ -6479,11 +6479,7 @@ character.  This variable is initialized by 
`hanja-init-load'.")
     map)
   "Keymap for Hanja (Korean Hanja Converter).")
 
-(defun hanja-filter (condp lst)
-  "Construct a list from the elements of LST for which CONDP returns true."
-  (delq
-   nil
-   (mapcar (lambda (x) (and (funcall condp x) x)) lst)))
+(define-obsolete-function-alias 'hanja-filter #'seq-filter "30.1")
 
 (defun hanja-list-prev-group ()
   "Select the previous group of hangul->hanja conversions."
@@ -6570,12 +6566,12 @@ The value is a hanja character that is selected 
interactively."
            0 0
            ;; Filter characters that can not be decoded.
            ;; Maybe it can not represent characters in current terminal coding.
-           (hanja-filter (lambda (x) (car x))
-                         (mapcar (lambda (c)
-                                   (if (listp c)
-                                       (cons (car c) (cdr c))
-                                     (list c)))
-                                 (aref hanja-table char)))))
+           (seq-filter #'car
+                       (mapcar (lambda (c)
+                                 (if (listp c)
+                                     (cons (car c) (cdr c))
+                                   (list c)))
+                               (aref hanja-table char)))))
     (unwind-protect
        (when (aref hanja-conversions 2)
          (catch 'exit-input-loop
diff --git a/lisp/loadup.el b/lisp/loadup.el
index b468cab276c..14152632da6 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -496,23 +496,23 @@ lost after dumping")))
 ;; At this point, we're ready to resume undo recording for scratch.
 (buffer-enable-undo "*scratch*")
 
-(defvar comp-subr-arities-h)
-(when (featurep 'native-compile)
-  ;; Save the arity for all primitives so the compiler can always
-  ;; retrive it even in case of redefinition.
-  (mapatoms (lambda (f)
-              (when (subr-primitive-p (symbol-function f))
-                (puthash f (func-arity f) comp-subr-arities-h))))
-  ;; Fix the compilation unit filename to have it working when
-  ;; installed or if the source directory got moved.  This is set to be
-  ;; a pair in the form of:
-  ;;     (rel-filename-from-install-bin . rel-filename-from-local-bin).
-  (let ((bin-dest-dir (cadr (member "--bin-dest" command-line-args)))
-        (eln-dest-dir (cadr (member "--eln-dest" command-line-args))))
-    (when (and bin-dest-dir eln-dest-dir)
-      (setq eln-dest-dir
-            (concat eln-dest-dir "native-lisp/" comp-native-version-dir "/"))
-      (maphash (lambda (_ cu)
+(defvar load--bin-dest-dir nil
+  "Store the original value passed by \"--bin-dest\" during dump.
+Internal use only.")
+(defvar load--eln-dest-dir nil
+  "Store the original value passed by \"--eln-dest\" during dump.
+Internal use only.")
+
+(defun load--fixup-all-elns ()
+  "Fix all compilation unit filename.
+This to have it working when installed or if Emacs source
+directory got moved.  This is set to be a pair in the form of:
+\(rel-filename-from-install-bin . rel-filename-from-local-bin)."
+  (when (and load--bin-dest-dir load--eln-dest-dir)
+    (setq eln-dest-dir
+          (concat load--eln-dest-dir "native-lisp/" comp-native-version-dir 
"/"))
+    (maphash (lambda (_ cu)
+               (when (stringp (native-comp-unit-file cu))
                  (let* ((file (native-comp-unit-file cu))
                         (preloaded (equal (substring (file-name-directory file)
                                                      -10 -1)
@@ -529,10 +529,20 @@ lost after dumping")))
                                           (file-name-nondirectory
                                            file)
                                           eln-dest-dir-eff)
-                                         bin-dest-dir)
+                                         load--bin-dest-dir)
                      ;; Relative filename from the built uninstalled binary.
-                     (file-relative-name file invocation-directory)))))
-              comp-loaded-comp-units-h)))
+                     (file-relative-name file invocation-directory))))))
+            comp-loaded-comp-units-h)))
+
+(defvar comp-subr-arities-h)
+(when (featurep 'native-compile)
+  ;; Save the arity for all primitives so the compiler can always
+  ;; retrive it even in case of redefinition.
+  (mapatoms (lambda (f)
+              (when (subr-primitive-p (symbol-function f))
+                (puthash f (func-arity f) comp-subr-arities-h))))
+  (setq load--bin-dest-dir (cadr (member "--bin-dest" command-line-args)))
+  (setq load--eln-dest-dir (cadr (member "--eln-dest" command-line-args)))
   ;; Set up the mechanism to allow inhibiting native-comp via
   ;; file-local variables.
   (defvar comp--no-native-compile (make-hash-table :test #'equal)))
diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el
index 6c498d8df71..b493f7d86dd 100644
--- a/lisp/mh-e/mh-mime.el
+++ b/lisp/mh-e/mh-mime.el
@@ -1355,6 +1355,7 @@ See also \\[mh-mh-to-mime]."
     ("ftp")             ; RFC2046 File Transfer Protocol
     ("gopher")          ; RFC1738 The Gopher Protocol
     ("http")            ; RFC1738 Hypertext Transfer Protocol
+    ("https")           ; RFC2818 HTTP Over TLS
     ("local-file")      ; RFC2046 Local file access
     ("mail-server")     ; RFC2046 mail-server Electronic mail address
     ("mailto")          ; RFC1738 Electronic mail address
diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el
index 11bfeb1b339..dfb2243988d 100644
--- a/lisp/net/browse-url.el
+++ b/lisp/net/browse-url.el
@@ -244,7 +244,7 @@ be used instead."
      (concat
       "\\(?:"
       ;; Match paired parentheses, e.g. in Wikipedia URLs:
-      ;; http://thread.gmane.org/47B4E3B2.3050402@gmail.com
+      ;; http://thread.gmane.org/47B4E3B2.3050402@gmail.com [dead link]
       "[" chars punct "]+" "(" "[" chars punct "]+" ")"
       "\\(?:" "[" chars punct "]+" "[" chars "]" "\\)?"
       "\\|"
@@ -680,7 +680,9 @@ For example, when point is on an URL fragment like
 Note that if you set this to \"https\", websites that do not yet
 support HTTPS may not load correctly in your web browser.  Such
 websites are increasingly rare, but they do still exist."
-  :type 'string
+  :type '(choice (const :tag "HTTP" "http")
+                 (const :tag "HTTPS" "https")
+                 (string :tag "Something else" "https"))
   :version "29.1")
 
 (defun browse-url-url-at-point ()
@@ -1305,7 +1307,7 @@ Default to the URL around or before point."
   (let* ((scheme (save-match-data
                    (if (string-match "\\(.+\\):/" url)
                        (match-string 1 url)
-                     "http")))
+                     browse-url-default-scheme)))
          (mime (concat "application/x-vnd.Be.URL." scheme)))
     (haiku-roster-launch mime (vector url))))
 
diff --git a/lisp/net/newst-backend.el b/lisp/net/newst-backend.el
index 055a38a76e3..726134874ff 100644
--- a/lisp/net/newst-backend.el
+++ b/lisp/net/newst-backend.el
@@ -618,13 +618,13 @@ If URL is nil it is searched at point."
                    (end-of-line)
                    (and
                     (re-search-backward
-                     "http://";
+                     (rx "http" (? "s") "://")
                      (if (> (point) (+ (point-min) 100))
                          (- (point) 100)
                        (point-min))
                      t)
                     (re-search-forward
-                     "http://[-a-zA-Z0-9&/_.]*";
+                     (rx "http" (? "s") "://" (zero-or-more (any 
"-a-zA-Z0-9&/_.")))
                      (if (< (point) (- (point-max) 200))
                          (+ (point) 200)
                        (point-max))
diff --git a/lisp/net/newst-reader.el b/lisp/net/newst-reader.el
index 9ec0b395675..3c79304d8dd 100644
--- a/lisp/net/newst-reader.el
+++ b/lisp/net/newst-reader.el
@@ -237,7 +237,8 @@ for formatting."
     (cond ((listp contents)
            (mapc (lambda (i)
                    (if (and (stringp i)
-                            (string-match "^http://.*"; i))
+                            (string-match
+                             (rx bol "http" (? "s") "://" (* nonl)) i))
                        (let ((pos (point)))
                          (insert i " ") ; avoid self-reference from the
                                         ; nt-link thing
@@ -248,7 +249,7 @@ for formatting."
                                 'help-echo
                                 (format "mouse-2: visit (%s)" i)
                                 'keymap keymap)))
-                         (insert (format "%s" i))))
+                     (insert (format "%s" i))))
                  contents))
           (t
            (insert (format "%s" contents))))
diff --git a/lisp/net/nsm.el b/lisp/net/nsm.el
index 7cbeb48f5be..274cca7123a 100644
--- a/lisp/net/nsm.el
+++ b/lisp/net/nsm.el
@@ -149,10 +149,11 @@ unencrypted."
     (dhe-prime-kx           medium)
     (sha1-sig               medium)
     (ecdsa-cbc-cipher       medium)
+    ;; Deprecated by NIST from 2016/2023 (see also CVE-2016-2183).
+    (3des-cipher            medium)
     ;; Towards TLS 1.3
     (dhe-kx                 high)
     (rsa-kx                 high)
-    (3des-cipher            high)
     (cbc-cipher             high))
   "This variable specifies what TLS connection checks to perform.
 It's an alist where the key is the name of the check, and the
@@ -169,13 +170,13 @@ otherwise.
 
 See also: `nsm-check-tls-connection', `nsm-save-host-names',
 `nsm-settings-file'"
-  :version "27.1"
   :type '(repeat (list (symbol :tag "Check function")
                        (choice :tag "Level"
                                :value medium
                                (const :tag "Low" low)
                                (const :tag "Medium" medium)
-                               (const :tag "High" high)))))
+                               (const :tag "High" high))))
+  :version "30.1")
 
 (defun nsm-save-fingerprint-maybe (host port status &rest _)
   "Save the certificate's fingerprint.
@@ -386,12 +387,11 @@ between the user and the server, to downgrade vulnerable 
TLS
 connections to insecure 512-bit export grade cryptography.
 
 The Logjam paper suggests using 1024-bit prime on the client to
-mitigate some effects of this attack, and upgrade to 2048-bit as
-soon as server configurations allow.  According to SSLLabs' SSL
-Pulse tracker, only about 75% of server support 2048-bit key
-exchange in June 2018[2].  To provide a balance between
-compatibility and security, this function only checks for a
-minimum key strength of 1024-bit.
+mitigate some effects of this attack, and upgrading to 2048-bit
+as soon as server configurations allow.  According to SSLLabs'
+SSL Pulse tracker the overwhelming majority of servers support
+2048-bit key exchange in October 2023[2].  This function
+therefore checks for a minimum key strength of 2048 bits.
 
 See also: `nsm-protocol-check--dhe-kx'
 
@@ -403,10 +403,10 @@ Diffie-Hellman Fails in Practice\", `https://weakdh.org/'
 `https://www.ssllabs.com/ssl-pulse/'"
   (let ((prime-bits (plist-get status :diffie-hellman-prime-bits)))
     (if (and (string-match "^\\bDHE\\b" (plist-get status :key-exchange))
-             (< prime-bits 1024))
+             (< prime-bits 2048))
         (format-message
          "Diffie-Hellman key strength (%s bits) too weak (%s bits)"
-         prime-bits 1024))))
+         prime-bits 2048))))
 
 (defun nsm-protocol-check--dhe-kx (_host _port status &optional _settings)
   "Check for existence of DH key exchange based on integer factorization.
@@ -484,7 +484,7 @@ because of MAC-then-encrypt.  This construction is 
vulnerable to
 padding oracle attacks[1].
 
 Since GnuTLS 3.4.0, the TLS encrypt-then-MAC extension[2] has
-been enabled by default[3]. If encrypt-then-MAC is negotiated,
+been enabled by default[3].  If encrypt-then-MAC is negotiated,
 this check has no effect.
 
 Reference:
diff --git a/lisp/net/rcirc.el b/lisp/net/rcirc.el
index 7cc7adc45c7..ecfeb9f8f84 100644
--- a/lisp/net/rcirc.el
+++ b/lisp/net/rcirc.el
@@ -2974,20 +2974,13 @@ keywords when no KEYWORD is given."
     browse-url-button-regexp)
   "Regexp matching URLs.  Set to nil to disable URL features in rcirc.")
 
-;; cf cl-remove-if-not
-(defun rcirc-condition-filter (condp lst)
-  "Remove all items not satisfying condition CONDP in list LST.
-CONDP is a function that takes a list element as argument and returns
-non-nil if that element should be included.  Returns a new list."
-  (delq nil (mapcar (lambda (x) (and (funcall condp x) x)) lst)))
-
 (defun rcirc-browse-url (&optional arg)
   "Prompt for URL to browse based on URLs in buffer before point.
 
 If ARG is given, opens the URL in a new browser window."
   (interactive "P")
   (let* ((point (point))
-         (filtered (rcirc-condition-filter
+         (filtered (seq-filter
                     (lambda (x) (>= point (cdr x)))
                     rcirc-urls))
          (completions (mapcar (lambda (x) (car x)) filtered))
@@ -4008,6 +4001,8 @@ PROCESS is the process object for the current connection."
 (define-obsolete-function-alias 'rcirc-format-strike-trough
   'rcirc-format-strike-through "30.1")
 
+(define-obsolete-function-alias 'rcirc-condition-filter #'seq-filter "30.1")
+
 (provide 'rcirc)
 
 ;;; rcirc.el ends here
diff --git a/lisp/net/sieve-manage.el b/lisp/net/sieve-manage.el
index 5bee4f4c4ad..81f50e74987 100644
--- a/lisp/net/sieve-manage.el
+++ b/lisp/net/sieve-manage.el
@@ -511,7 +511,7 @@ If NAME is nil, return the full server list of 
capabilities."
     (while (not pos)
       (setq pos (search-forward-regexp pattern nil t))
       (goto-char (point-min))
-      (sleep-for 0 50))
+      (sleep-for 0.05))
     pos))
 
 (defun sieve-manage-drop-next-answer ()
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index ba6dbdf0c39..49acf8395c5 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -31,8 +31,7 @@
 
 ;;; Code:
 
-(eval-when-compile (require 'cl-lib))
-(require 'cl-seq)
+(require 'cl-lib)
 (require 'tramp)
 
 ;; `dired-*' declarations can be removed, starting with Emacs 29.1.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 7cc9b0c14a2..9cc319bef67 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -6231,20 +6231,20 @@ Set connection properties 
\"{uid,gid,groups}-{integer,string}\"."
       (goto-char (point-min))
       ;; Read uid.
       (when (search-forward-regexp
-            (rx "uid=" (group (+ digit)) "(" (group (+ (any "_" word))) ")")
+            (rx "uid=" (group (+ digit)) "(" (group (+ (any "_-" alnum))) ")")
             nil 'noerror)
        (setq uid-integer (string-to-number (match-string 1))
              uid-string (match-string 2)))
       ;; Read gid.
       (when (search-forward-regexp
-            (rx "gid=" (group (+ digit)) "(" (group (+ (any "_" word))) ")")
+            (rx "gid=" (group (+ digit)) "(" (group (+ (any "_-" alnum))) ")")
             nil 'noerror)
        (setq gid-integer (string-to-number (match-string 1))
              gid-string (match-string 2)))
       ;; Read groups.
       (when (search-forward-regexp (rx "groups=") nil 'noerror)
        (while (looking-at
-               (rx (group (+ digit)) "(" (group (+ (any "_" word))) ")"))
+               (rx (group (+ digit)) "(" (group (+ (any "_-" alnum))) ")"))
          (setq groups-integer (cons (string-to-number (match-string 1))
                                     groups-integer)
                groups-string (cons (match-string 2) groups-string))
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index 4d56cf367e3..aefe14e845e 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -105,7 +105,7 @@
          ("2.3.5.26.3" . "26.3")
          ("2.4.3.27.1" . "27.1") ("2.4.5.27.2" . "27.2")
          ("2.5.2.28.1" . "28.1") ("2.5.3.28.2" . "28.2") ("2.5.4" . "28.3")
-         ("2.6.0.29.1" . "29.1")))
+         ("2.6.0.29.1" . "29.1") ("2.6.2.29.2" . "29.2")))
 
 (add-hook 'tramp-unload-hook
          (lambda ()
diff --git a/lisp/net/webjump.el b/lisp/net/webjump.el
index fe7c3679876..77f00578a48 100644
--- a/lisp/net/webjump.el
+++ b/lisp/net/webjump.el
@@ -1,6 +1,6 @@
 ;;; webjump.el --- programmable Web hotlist  -*- lexical-binding: t; -*-
 
-;; Copyright (C) 1996-1997, 2001-2023 Free Software Foundation, Inc.
+;; Copyright (C) 1996-2023 Free Software Foundation, Inc.
 
 ;; Author:     Neil W. Van Dyke <nwv@acm.org>
 ;; Maintainer: emacs-devel@gnu.org
@@ -123,7 +123,7 @@ external browser like IceCat."
     ;; Misc. general interest.
     ("National Weather Service" . webjump-to-iwin)
     ("Usenet FAQs" .
-     "www.faqs.org/faqs/")
+     "http://www.faqs.org/faqs/";)
     ("RTFM Usenet FAQs by Group" .
      "ftp://rtfm.mit.edu/pub/usenet-by-group/";)
     ("RTFM Usenet FAQs by Hierarchy" .
@@ -132,7 +132,7 @@ external browser like IceCat."
 
     ;; Computer social issues, privacy, professionalism.
     ("Association for Computing Machinery" . "www.acm.org")
-    ("Computer Professionals for Social Responsibility" . "www.cpsr.org")
+    ("Computer Professionals for Social Responsibility" . 
"http://www.cpsr.org";)
     ("Electronic Frontier Foundation" . "www.eff.org")
     ("IEEE Computer Society" . "www.computer.org")
     ("Risks Digest" . webjump-to-risks)
@@ -194,7 +194,7 @@ If the symbol of a function is given, then the function 
will be called with the
 Web site name (the one you specified in the CAR of the alist cell) as a
 parameter.  This might come in handy for various kludges.
 
-For convenience, if the `http://', `ftp://', or `file://' prefix is missing
+For convenience, if the `https://', `ftp://', or `file://' prefix is missing
 from a URL, WebJump will make a guess at what you wanted and prepend it before
 submitting the URL."
   :type '(alist :key-type (string :tag "Name")
@@ -262,33 +262,22 @@ Please submit bug reports and other feedback to the 
author, Neil W. Van Dyke
                (completing-read "WebJump to site: " webjump-sites nil t)
                webjump-sites t))
         (name (car item))
-        (expr (cdr item)))
-    (if webjump-use-internal-browser
-        (browse-url-with-browser-kind
-         'internal (webjump-url-fix
-                    (cond ((not expr) "")
-                          ((stringp expr) expr)
-                          ((vectorp expr) (webjump-builtin expr name))
-                          ((listp expr) (eval expr t))
-                          ((symbolp expr)
-                           (if (fboundp expr)
-                               (funcall expr name)
-                             (error "WebJump URL function \"%s\" undefined"
-                                    expr)))
-                          (t (error "WebJump URL expression for \"%s\" invalid"
-                                    name)))))
-      (browse-url (webjump-url-fix
-                   (cond ((not expr) "")
-                         ((stringp expr) expr)
-                         ((vectorp expr) (webjump-builtin expr name))
-                         ((listp expr) (eval expr t))
-                         ((symbolp expr)
-                          (if (fboundp expr)
-                              (funcall expr name)
-                            (error "WebJump URL function \"%s\" undefined"
-                                   expr)))
-                         (t (error "WebJump URL expression for \"%s\" invalid"
-                                   name))))))))
+         (expr (cdr item))
+         (fun (if webjump-use-internal-browser
+                  (apply-partially #'browse-url-with-browser-kind 'internal)
+                #'browse-url)))
+    (funcall fun (webjump-url-fix
+                  (cond ((not expr) "")
+                        ((stringp expr) expr)
+                        ((vectorp expr) (webjump-builtin expr name))
+                        ((listp expr) (eval expr t))
+                        ((symbolp expr)
+                         (if (fboundp expr)
+                             (funcall expr name)
+                           (error "WebJump URL function \"%s\" undefined"
+                                  expr)))
+                        (t (error "WebJump URL expression for \"%s\" invalid"
+                                  name)))))))
 
 (defun webjump-builtin (expr name)
   (if (< (length expr) 1)
@@ -380,9 +369,11 @@ Please submit bug reports and other feedback to the 
author, Neil W. Van Dyke
       ((string-match "^[a-zA-Z]+:" url) url)
       ((string-match "^/" url) (concat "file://" url))
       ((string-match "^\\([^\\./]+\\)" url)
+       ;; FIXME: ftp.gnu.org and many others now prefer HTTPS instead
+       ;;        of FTP.  Does this heuristic make sense these days?
        (concat (if (string= (downcase (match-string 1 url)) "ftp")
                   "ftp"
-                "http")
+                 "https")
               "://"
               url))
       (t url)))))
diff --git a/lisp/obsolete/terminal.el b/lisp/obsolete/terminal.el
index 4e23fc3c710..31c1ebead14 100644
--- a/lisp/obsolete/terminal.el
+++ b/lisp/obsolete/terminal.el
@@ -1154,7 +1154,7 @@ subprocess started."
 
 
 (defun te-parse-program-and-args (s)
-  (cond ((string-match "\\`\\([-a-zA-Z0-9+=_.@/:]+[ \t]*\\)+\\'" s)
+  (cond ((string-match "\\`[-a-zA-Z0-9+=_.@/:][-a-zA-Z0-9+=_.@/: \t]*\\'" s)
         (let ((l ()) (p 0))
           (while p
             (setq l (cons (if (string-match
diff --git a/lisp/org/ob-lua.el b/lisp/org/ob-lua.el
index 81521d9e0a5..7eaf5e00b13 100644
--- a/lisp/org/ob-lua.el
+++ b/lisp/org/ob-lua.el
@@ -326,7 +326,7 @@ last statement in BODY, as elisp."
 If RESULT-TYPE equals `output' then return standard output as a
 string.  If RESULT-TYPE equals `value' then return the value of the
 last statement in BODY, as elisp."
-  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0 5)))
+  (let* ((send-wait (lambda () (comint-send-input nil t) (sleep-for 0.005)))
         (dump-last-value
          (lambda
            (tmp-file pp)
diff --git a/lisp/org/ob-python.el b/lisp/org/ob-python.el
index 6c05d1c8b2a..48a906a1934 100644
--- a/lisp/org/ob-python.el
+++ b/lisp/org/ob-python.el
@@ -235,7 +235,7 @@ then create.  Return the initialized session."
           ;; multiple prompts during initialization.
           (with-current-buffer py-buffer
             (while (not org-babel-python--initialized)
-              (sleep-for 0 10)))
+              (sleep-for 0.01)))
         (org-babel-comint-wait-for-output py-buffer))
       (setq org-babel-python-buffers
            (cons (cons session py-buffer)
@@ -403,7 +403,7 @@ last statement in BODY, as elisp."
                      (body (org-babel-python-format-session-value
                             tmp-src-file tmp-results-file result-params)))
                 (org-babel-python--send-string session body)
-                (sleep-for 0 10)
+                 (sleep-for 0.01)
                 (org-babel-eval-read-file tmp-results-file)))))))
     (org-babel-result-cond result-params
       results
diff --git a/lisp/org/org.el b/lisp/org/org.el
index 8b02721a859..49f62d0f43b 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -11346,7 +11346,7 @@ See also `org-scan-tags'."
   (let ((match0 match)
        (re (concat
             "^&?\\([-+:]\\)?\\({[^}]+}\\|LEVEL\\([<=>]\\{1,2\\}\\)"
-            "\\([0-9]+\\)\\|\\(\\(?:[[:alnum:]_]+\\(?:\\\\-\\)*\\)+\\)"
+            "\\([0-9]+\\)\\|\\([[:alnum:]_]\\(?:[[:alnum:]_]\\|\\\\-\\)*\\)"
             "\\([<>=]\\{1,2\\}\\)"
             "\\({[^}]+}\\|\"[^\"]*\"\\|-?[.0-9]+\\(?:[eE][-+]?[0-9]+\\)?\\)"
             "\\|" org-tag-re "\\)"))
diff --git a/lisp/pcmpl-unix.el b/lisp/pcmpl-unix.el
index e6b67256a4c..7af5f2bce74 100644
--- a/lisp/pcmpl-unix.el
+++ b/lisp/pcmpl-unix.el
@@ -685,6 +685,14 @@ Includes files as well as host names followed by a colon."
   (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
               pcomplete-default-completion-function)))
 
+;;;###autoload
+(defun pcomplete/doas ()
+  "Completion for the `doas' command."
+  (pcomplete-opt "C(pcomplete-entries)Lnsu(pcmpl-unix-user-names)")
+  (funcall pcomplete-command-completion-function)
+  (funcall (or (pcomplete-find-completion-function (pcomplete-arg 1))
+               pcomplete-default-completion-function)))
+
 (provide 'pcmpl-unix)
 
 ;;; pcmpl-unix.el ends here
diff --git a/lisp/pgtk-dnd.el b/lisp/pgtk-dnd.el
index f2998fd1e67..48edaa2472a 100644
--- a/lisp/pgtk-dnd.el
+++ b/lisp/pgtk-dnd.el
@@ -238,10 +238,9 @@ WINDOW is the window where the drop happened.
 STRING is the uri-list as a string.  The URIs are separated by \\r\\n."
   (let ((uri-list (split-string string "[\0\r\n]" t))
        retval)
-    (dolist (bf uri-list)
-      ;; If one URL is handled, treat as if the whole drop succeeded.
-      (let ((did-action (dnd-handle-one-url window action bf)))
-       (when did-action (setq retval did-action))))
+    (let ((did-action (dnd-handle-multiple-urls window uri-list
+                                                action)))
+      (when did-action (setq retval did-action)))
     retval))
 
 (defun pgtk-dnd-handle-file-name (window action string)
@@ -252,17 +251,22 @@ STRING is the file names as a string, separated by nulls."
        (coding (or file-name-coding-system
                    default-file-name-coding-system))
        retval)
-    (dolist (bf uri-list)
-      ;; If one URL is handled, treat as if the whole drop succeeded.
-      (if coding (setq bf (encode-coding-string bf coding)))
-      (let* ((file-uri (concat "file://"
-                              (mapconcat 'url-hexify-string
-                                         (split-string bf "/") "/")))
-            (did-action (dnd-handle-one-url window action file-uri)))
-       (when did-action (setq retval did-action))))
+    (let ((did-action
+           (dnd-handle-multiple-urls
+            window (mapcar
+                    (lambda (item)
+                      (when coding
+                        (setq item (encode-coding-string item
+                                                         coding)))
+                      (concat "file://"
+                              (mapconcat 'url-hexify-string
+                                         (split-string item "/")
+                                         "/")))
+                    uri-list)
+            action)))
+      (when did-action (setq retval did-action)))
     retval))
 
-
 (defun pgtk-dnd-choose-type (types &optional known-types)
   "Choose which type we want to receive for the drop.
 TYPES are the types the source of the drop offers, a vector of type names
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 8dea599ed98..227a6af2a6b 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -257,7 +257,7 @@ control).  See \"cc-mode.el\" for more info."
 
   ;; Set up text conversion, for Emacs >= 30.0
   (when (boundp 'post-text-conversion-hook)
-    (add-hook 'post-text-conversion-hook #'c-post-text-conversion))
+    (add-hook 'post-text-conversion-hook #'c-post-text-conversion nil t))
 
   (unless new-style-init
     (c-init-language-vars-for 'c-mode)))
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index d525b069407..1a2ad15f5b2 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -379,6 +379,8 @@ Font for POD headers."
   :type 'face
   :version "21.1"
   :group 'cperl-faces)
+(make-obsolete-variable 'cperl-invalid-face
+                        'show-trailing-whitespace "30.1")
 
 (defcustom cperl-pod-here-fontify t
   "Not-nil after evaluation means to highlight POD and here-docs sections."
@@ -433,6 +435,11 @@ after reload."
 Older version of this page was called `perl5', newer `perl'."
   :type 'string
   :group 'cperl-help-system)
+(make-obsolete-variable 'cperl-info-page
+                        (concat "The Perl info page is no longer maintained. "
+                                "Consider installing the perl-doc package from 
"
+                                "GNU ELPA to access Perl documentation.")
+                        "30.1")
 
 (defcustom cperl-use-syntax-table-text-property t
   "Non-nil means CPerl sets up and uses `syntax-table' text property."
@@ -473,12 +480,6 @@ If nil, the value of `cperl-indent-level' will be used."
   :group 'cperl)
 (make-obsolete-variable 'cperl-under-as-char 'superword-mode "24.4")
 
-(defcustom cperl-extra-perl-args ""
-  "Extra arguments to use when starting Perl.
-Currently used with `cperl-check-syntax' only."
-  :type 'string
-  :group 'cperl)
-
 (defcustom cperl-message-electric-keyword t
   "Non-nil means that the `cperl-electric-keyword' prints a help message."
   :type 'boolean
@@ -631,22 +632,14 @@ imenu entries."
 ;;; Short extra-docs.
 
 (defvar cperl-tips 'please-ignore-this-line
-  "Note that to enable Compile choices in the menu you need to install
-mode-compile.el.
-
-If your Emacs does not default to `cperl-mode' on Perl files, and you
+  "If your Emacs does not default to `cperl-mode' on Perl files, and you
 want it to: put the following into your .emacs file:
 
   (add-to-list \\='major-mode-remap-alist \\='(perl-mode . cperl-mode))
 
-Get perl5-info from
-  $CPAN/doc/manual/info/perl5-old/perl5-info.tar.gz
-Also, one can generate a newer documentation running `pod2texi' converter
-  $CPAN/doc/manual/info/perl5/pod2texi-0.1.tar.gz
-
-If you use imenu-go, run imenu on perl5-info buffer (you can do it
-from Perl menu).  If many files are related, generate TAGS files from
-Tools/Tags submenu in Perl menu.
+To read Perl documentation in info format you can convert POD to
+texinfo with the converter `pod2texi' from the texinfo project:
+  https://www.gnu.org/software/texinfo/manual/pod2texi.html
 
 If some class structure is too complicated, use Tools/Hierarchy-view
 from Perl menu, or hierarchic view of imenu.  The second one uses the
@@ -713,45 +706,41 @@ voice);
                 3) Separate list of packages/classes;
                 4) Hierarchical view of methods in (sub)packages;
                 5) and functions (by the full name - with package);
-        e) Has an interface to INFO docs for Perl; The interface is
-                very flexible, including shrink-wrapping of
-                documentation buffer/frame;
-        f) Has a builtin list of one-line explanations for perl constructs.
-        g) Can show these explanations if you stay long enough at the
+        e) Has a builtin list of one-line explanations for perl constructs.
+        f) Can show these explanations if you stay long enough at the
                 corresponding place (or on demand);
-        h) Has an enhanced fontification (using 3 or 4 additional faces
+        g) Has an enhanced fontification (using 3 or 4 additional faces
                 comparing to font-lock - basically, different
                 namespaces in Perl have different colors);
-        i) Can construct TAGS basing on its knowledge of Perl syntax,
+        h) Can construct TAGS basing on its knowledge of Perl syntax,
                 the standard menu has 6 different way to generate
                 TAGS (if \"by directory\", .xs files - with C-language
                 bindings - are included in the scan);
-        j) Can build a hierarchical view of classes (via imenu) basing
+        i) Can build a hierarchical view of classes (via imenu) basing
                 on generated TAGS file;
-        k) Has electric parentheses, electric newlines, uses Abbrev
+        j) Has electric parentheses, electric newlines, uses Abbrev
                 for electric logical constructs
                         while () {}
                 with different styles of expansion (context sensitive
                 to be not so bothering).  Electric parentheses behave
                 \"as they should\" in a presence of a visible region.
-        l) Changes msb.el \"on the fly\" to insert a group \"Perl files\";
-        m) Can convert from
+        k) Changes msb.el \"on the fly\" to insert a group \"Perl files\";
+        l) Can convert from
                if (A) { B }
           to
                B if A;
 
-        n) Highlights (by user-choice) either 3-delimiters constructs
+        m) Highlights (by user-choice) either 3-delimiters constructs
           (such as tr/a/b/), or regular expressions and `y/tr';
-       o) Highlights trailing whitespace;
-       p) Is able to manipulate Perl Regular Expressions to ease
+        o) Is able to manipulate Perl Regular Expressions to ease
           conversion to a more readable form.
-        q) Can ispell POD sections and HERE-DOCs.
-       r) Understands comments and character classes inside regular
+        p) Can ispell POD sections and HERE-DOCs.
+        q) Understands comments and character classes inside regular
           expressions; can find matching () and [] in a regular expression.
-       s) Allows indentation of //x-style regular expressions;
-       t) Highlights different symbols in regular expressions according
+        r) Allows indentation of //x-style regular expressions;
+        s) Highlights different symbols in regular expressions according
           to their function; much less problems with backslashitis;
-       u) Allows you to locate regular expressions which contain
+        t) Allows you to locate regular expressions which contain
           interpolated parts.
 
 5) The indentation engine was very smart, but most of tricks may be
@@ -840,7 +829,6 @@ B) Speed of editing operations.
   `font-lock-type-face'                Overridable keywords
   `font-lock-variable-name-face' Variable declarations, indirect array and
                                hash names, POD headers/item names
-  `cperl-invalid-face'         Trailing whitespace
 
 Note that in several situations the highlighting tries to inform about
 possible confusion, such as different colors for function names in
@@ -987,12 +975,12 @@ Unless KEEP, removes the old indentation."
     (define-key map "\177" 'cperl-electric-backspace)
     (define-key map "\t" 'cperl-indent-command)
     ;; don't clobber the backspace binding:
-    (define-key map [(control ?c) (control ?h) ?F] 'cperl-info-on-command)
+    (define-key map [(control ?c) (control ?h) ?F] 'cperl-perldoc)
     (if (cperl-val 'cperl-clobber-lisp-bindings)
         (progn
          (define-key map [(control ?h) ?f]
            ;;(concat (char-to-string help-char) "f") ; does not work
-           'cperl-info-on-command)
+           'cperl-perldoc)
          (define-key map [(control ?h) ?v]
            ;;(concat (char-to-string help-char) "v") ; does not work
            'cperl-get-help)
@@ -1003,7 +991,7 @@ Unless KEEP, removes the old indentation."
            ;;(concat (char-to-string help-char) "v") ; does not work
            (key-binding "\C-hv")))
       (define-key map [(control ?c) (control ?h) ?f]
-        'cperl-info-on-current-command)
+        'cperl-perldoc)
       (define-key map [(control ?c) (control ?h) ?v]
        ;;(concat (char-to-string help-char) "v") ; does not work
        'cperl-get-help))
@@ -1056,17 +1044,10 @@ Unless KEEP, removes the old indentation."
     ["Comment region" cperl-comment-region (use-region-p)]
     ["Uncomment region" cperl-uncomment-region (use-region-p)]
     "----"
-    ["Run" mode-compile (fboundp 'mode-compile)]
-    ["Kill" mode-compile-kill (and (fboundp 'mode-compile-kill)
-                                   (get-buffer "*compilation*"))]
-    ["Next error" next-error (get-buffer "*compilation*")]
-    ["Check syntax" cperl-check-syntax (fboundp 'mode-compile)]
-    "----"
     ["Debugger" cperl-db t]
     "----"
     ("Tools"
      ["Imenu" imenu]
-     ["Imenu on Perl Info" cperl-imenu-on-info (featurep 'imenu)]
      "----"
      ["Ispell PODs" cperl-pod-spell
       ;; Better not to update syntaxification here:
@@ -1125,8 +1106,6 @@ Unless KEEP, removes the old indentation."
       ;; This is from imenu-go.el.  I can't find it on any ELPA
       ;; archive, so I'm not sure if it's still in use or not.
       (fboundp 'imenu-go-find-at-position)]
-     ["Help on function" cperl-info-on-command t]
-     ["Help on function at point" cperl-info-on-current-command t]
      ["Help on symbol at point" cperl-get-help t]
      ["Perldoc" cperl-perldoc t]
      ["Perldoc on word at point" cperl-perldoc-at-point t]
@@ -1731,16 +1710,8 @@ by setting them to `null'.  Note that one may undo the 
extra
 whitespace inserted by semis and braces in `auto-newline'-mode by
 consequent \\[cperl-electric-backspace].
 
-If your site has perl5 documentation in info format, you can use commands
-\\[cperl-info-on-current-command] and \\[cperl-info-on-command] to access it.
-These keys run commands `cperl-info-on-current-command' and
-`cperl-info-on-command', which one is which is controlled by variable
-`cperl-info-on-command-no-prompt' and `cperl-clobber-lisp-bindings'
-\(in turn affected by `cperl-hairy').
-
-Even if you have no info-format documentation, short one-liner-style
-help is available on \\[cperl-get-help], and one can run perldoc or
-man via menu.
+Short one-liner-style help is available on \\[cperl-get-help],
+and one can run perldoc or man via menu.
 
 It is possible to show this help automatically after some idle time.
 This is regulated by variable `cperl-lazy-help-time'.  Default with
@@ -1832,8 +1803,8 @@ or as help on variables `cperl-tips', `cperl-problems',
        (cperl-val 'cperl-info-on-command-no-prompt))
       (progn
        ;; don't clobber the backspace binding:
-       (define-key cperl-mode-map "\C-hf" 'cperl-info-on-current-command)
-       (define-key cperl-mode-map "\C-c\C-hf" 'cperl-info-on-command)))
+       (define-key cperl-mode-map "\C-hf" 'cperl-perldoc)
+       (define-key cperl-mode-map "\C-c\C-hf" 'cperl-perldoc)))
   (setq local-abbrev-table cperl-mode-abbrev-table)
   (if (cperl-val 'cperl-electric-keywords)
       (abbrev-mode 1))
@@ -5887,9 +5858,6 @@ functions (which they are not).  Inherits from 
`default'.")
          (setq
           t-font-lock-keywords
           (list
-            ;; -------- trailing spaces -> use invalid-face as a warning
-            ;; (matcher subexp facespec)
-           `("[ \t]+$" 0 ',cperl-invalid-face t)
             ;; -------- function definition _and_ declaration
             ;; (matcher (subexp facespec))
             ;; facespec is evaluated depending on whether the
@@ -6561,13 +6529,6 @@ side-effect of memorizing only.  Examples in 
`cperl-style-examples'."
            cperl-old-style (cdr cperl-old-style))
       (set (car setting) (cdr setting)))))
 
-(defvar perl-dbg-flags)
-(defun cperl-check-syntax ()
-  (interactive)
-  (require 'mode-compile)
-  (let ((perl-dbg-flags (concat cperl-extra-perl-args " -wc")))
-    (eval '(mode-compile))))           ; Avoid a warning
-
 (declare-function Info-find-node "info"
                  (filename nodename &optional no-going-back strict-case
                             noerror))
@@ -6611,10 +6572,7 @@ side-effect of memorizing only.  Examples in 
`cperl-style-examples'."
                       'find-tag-default))))))
 
 (defun cperl-info-on-command (command)
-  "Show documentation for Perl command COMMAND in other window.
-If perl-info buffer is shown in some frame, uses this frame.
-Customized by setting variables `cperl-shrink-wrap-info-frame',
-`cperl-max-help-size'."
+  (declare (obsolete cperl-perldoc "30.1"))
   (interactive
    (let* ((default (cperl-word-at-point))
          (read (read-string
@@ -6690,25 +6648,26 @@ Customized by setting variables 
`cperl-shrink-wrap-info-frame',
     (select-window iniwin)))
 
 (defun cperl-info-on-current-command ()
-  "Show documentation for Perl command at point in other window."
+  (declare (obsolete cperl-perldoc "30.1"))
   (interactive)
   (cperl-info-on-command (cperl-word-at-point)))
 
 (defun cperl-imenu-info-imenu-search ()
+  (declare (obsolete nil "30.1"))
   (if (looking-at "^-X[ \t\n]") nil
     (re-search-backward
      "^\n\\([-a-zA-Z_]+\\)[ \t\n]")
     (forward-line 1)))
 
 (defun cperl-imenu-info-imenu-name ()
+  (declare (obsolete nil "30.1"))
   (buffer-substring
    (match-beginning 1) (match-end 1)))
 
 (declare-function imenu-choose-buffer-index "imenu" (&optional prompt alist))
 
 (defun cperl-imenu-on-info ()
-  "Show imenu for Perl Info Buffer.
-Opens Perl Info buffer if needed."
+  (declare (obsolete nil "30.1"))
   (interactive)
   (require 'imenu)
   (let* ((buffer (current-buffer))
@@ -7369,9 +7328,6 @@ One may build such TAGS files from CPerl mode menu."
                            (nreverse list2))
                      list1)))))
 
-(defvar imenu-max-items nil
-  "Max items in an imenu list.  Defined in imenu.el.")
-
 (defun cperl-menu-to-keymap (menu)
   (let (list)
     (cons 'keymap
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 7d83bcdd7ac..eba66503bf7 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -467,7 +467,9 @@ ACTION is the default value for commands not in the alist."
   "If non-nil, show progress of long running LSP server work.
 If set to `messages', use *Messages* buffer, else use Eglot's
 mode line indicator."
-  :type 'boolean
+  :type '(choice (const :tag "Don't show progress" nil)
+                 (const :tag "Show progress in *Messages*" messages)
+                 (const :tag "Show progress in Eglot's mode line indicator" t))
   :version "1.10")
 
 (defcustom eglot-ignored-server-capabilities (list)
diff --git a/lisp/progmodes/elixir-ts-mode.el b/lisp/progmodes/elixir-ts-mode.el
index 2ddce3de105..05edb4159a1 100644
--- a/lisp/progmodes/elixir-ts-mode.el
+++ b/lisp/progmodes/elixir-ts-mode.el
@@ -469,12 +469,11 @@
    :override t
    `((sigil
       (sigil_name) @elixir-ts-font-sigil-name-face
-      (:match "^[sSwWpPUD]$" @elixir-ts-font-sigil-name-face))
+      (:match "^[^HF]$" @elixir-ts-font-sigil-name-face))
      @font-lock-string-face
      (sigil
-      "~" @font-lock-string-face
-      (sigil_name) @elixir-ts-font-sigil-name-face
-      (:match "^[rR]$" @elixir-ts-font-sigil-name-face))
+      (sigil_name) @font-lock-regexp-face
+      (:match "^[rR]$" @font-lock-regexp-face))
      @font-lock-regexp-face
      (sigil
       "~" @font-lock-string-face
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index b27e6527f81..fb000517655 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -4,7 +4,7 @@
 
 ;; Author: Pavel Kobyakov <pk_at_work@yahoo.com>
 ;; Maintainer: João Távora <joaotavora@gmail.com>
-;; Version: 1.3.6
+;; Version: 1.3.7
 ;; Keywords: c languages tools
 ;; Package-Requires: ((emacs "26.1") (eldoc "1.14.0") (project "0.7.1"))
 
@@ -809,6 +809,7 @@ Return nil or the overlay created."
                         (flymake--diag-orig-end e))
                   (flymake--delete-overlay eov)))
     (setq ov (make-overlay beg end))
+    (setf (flymake--diag-overlay diagnostic) ov)
     (when (= (overlay-start ov) (overlay-end ov))
       ;; Some backends report diagnostics with invalid bounds.  Don't
       ;; bother.
@@ -863,7 +864,6 @@ Return nil or the overlay created."
     (overlay-put ov 'evaporate t)
     (overlay-put ov 'flymake-overlay t)
     (overlay-put ov 'flymake-diagnostic diagnostic)
-    (setf (flymake--diag-overlay diagnostic) ov)
     ;; Handle `flymake-show-diagnostics-at-end-of-line'
     ;;
     (when flymake-show-diagnostics-at-end-of-line
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index bc0070d2630..3afdc59a67e 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -1960,19 +1960,23 @@ static char *magick[] = {
   :group 'gdb)
 
 
-(defvar gdb-python-guile-commands-regexp
-  "python\\|python-interactive\\|pi\\|guile\\|guile-repl\\|gr"
-  "Regexp that matches Python and Guile commands supported by GDB.")
-
 (defvar gdb-control-commands-regexp
-  (concat
-   "^\\("
-   "comm\\(a\\(n\\(ds?\\)?\\)?\\)?\\|if\\|while"
-   "\\|def\\(i\\(ne?\\)?\\)?\\|doc\\(u\\(m\\(e\\(nt?\\)?\\)?\\)?\\)?\\|"
-   gdb-python-guile-commands-regexp
-   "\\|while-stepping\\|stepp\\(i\\(ng?\\)?\\)?\\|ws\\|actions"
-   "\\|expl\\(o\\(re?\\)?\\)?"
-   "\\)\\([[:blank:]]+\\([^[:blank:]]*\\)\\)*$")
+  (rx bol
+      (or
+       (or "comm" "comma" "comman" "command" "commands"
+           "if" "while"
+           "def" "defi" "defin" "define"
+           "doc" "docu" "docum" "docume" "documen" "document"
+           "while-stepping"
+           "stepp" "steppi" "steppin" "stepping"
+           "ws" "actions"
+           "expl" "explo" "explor" "explore")
+       (group         ; group 1: Python and Guile commands
+        (or "python" "python-interactive" "pi" "guile" "guile-repl" "gr")))
+      (? (+ blank)
+         (group       ; group 2: command arguments
+          (* nonl)))
+      eol)
   "Regexp matching GDB commands that enter a recursive reading loop.
 As long as GDB is in the recursive reading loop, it does not expect
 commands to be prefixed by \"-interpreter-exec console\".")
@@ -2032,15 +2036,13 @@ commands to be prefixed by \"-interpreter-exec 
console\".")
       (setq gdb-continuation nil)))
   ;; Python and Guile commands that have an argument don't enter the
   ;; recursive reading loop.
-  (let* ((control-command-p (string-match gdb-control-commands-regexp string))
-         (command-arg (and control-command-p (match-string 3 string)))
-         (python-or-guile-p (string-match gdb-python-guile-commands-regexp
-                                          string)))
-    (if (and control-command-p
-             (or (not python-or-guile-p)
-                 (null command-arg)
-                 (zerop (length command-arg))))
-        (setq gdb-control-level (1+ gdb-control-level)))))
+  (when (string-match gdb-control-commands-regexp string)
+    (let ((python-or-guile-p (match-beginning 1))
+          (command-arg (match-string 2 string)))
+      (when (or (not python-or-guile-p)
+                (null command-arg)
+                (zerop (length command-arg)))
+        (setq gdb-control-level (1+ gdb-control-level))))))
 
 (defun gdb-mi-quote (string)
   "Return STRING quoted properly as an MI argument.
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 805e7a1b7a4..70af736372e 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -40,7 +40,6 @@
 ;;; Code:
 
 (require 'comint)
-(require 'cl-macs)
 
 (defvar gdb-active-process)
 (defvar gdb-define-alist)
@@ -3863,30 +3862,78 @@ so they have been disabled."))
 (defvar gud-lldb-history nil)
 
 (defcustom gud-gud-lldb-command-name "lldb"
-  "Default command to run an executable under LLDB."
-  :type 'string)
-
-(cl-defun gud-lldb-stop (&key file line column)
-  (setq gud-last-frame (list file line column)))
+  "Default command to invoke LLDB in order to debug a program with it."
+  :type 'string
+  :version "30.1")
 
 (defun gud-lldb-marker-filter (string)
   "Deduce interesting stuff from process output STRING."
-  (cond
-   ;; gud-info: (function-name args...)
-   ((string-match (rx line-start (0+ blank) "gud-info:" (0+ blank)
-                      (group "(" (1+ (not ")")) ")"))
-                  string)
-    (let ((form (string-replace "///" "\"" (match-string 1 string))))
-      (eval (car (read-from-string form)))))
-   ;; Process 72874 exited with status = 9 (0x00000009) killed.
-   ;; Doesn't seem to be changeable as of LLDB 17.0.2.
-    ((string-match (rx "Process " (1+ digit) " exited with status")
-                   string)
-     (setq gud-last-last-frame nil)
-     (setq gud-overlay-arrow-position nil)))
+
+  ;; Pick information from our own frame info line "!gud LINE:COL:FILE"
+  ;; because the file name in the standard LLDB frame-format doesn't have
+  ;; a directory.
+  (setq string
+        (replace-regexp-in-string
+         (rx bol "!gud "
+             (group (+ digit)) ":"            ; 1: line
+             (group (* digit)) ":"            ; 2: column
+             (group (+ (not (in "\n\r"))))    ; 3: file
+             (* "\r") "\n")
+         (lambda (m)
+           (let ((line (string-to-number (match-string 1 m)))
+                 (col (string-to-number (match-string 2 m)))
+                 (file  (match-string 3 m)))
+             (setq gud-last-frame (list file line col)))
+           ;; Remove the line so that the user won't see it.
+           "")
+         string t t))
+
+  (when (string-match (rx "Process " (1+ digit) " exited with status")
+                      string)
+    ;; Process 72874 exited with status = 9 (0x00000009) killed.
+    ;; Doesn't seem to be changeable as of LLDB 17.0.2.
+    (setq gud-last-last-frame nil)
+    (setq gud-overlay-arrow-position nil))
+
+  ;; LLDB sometimes emits certain ECMA-48 sequences even if TERM is "dumb":
+  ;; CHA (Character Horizontal Absolute) and ED (Erase in Display),
+  ;; seemingly to undo previous output on the same line.
+  ;; Filter out these sequences here while carrying out their edits.
+  (let ((bol (pos-bol)))
+    (when (> (point) bol)
+      ;; Move the current line to the string, so that control sequences
+      ;; can delete parts of it.
+      (setq string (concat (buffer-substring-no-properties bol (point))
+                           string))
+      (let ((inhibit-read-only t))
+        (delete-region bol (point)))))
+  (let ((ofs 0))
+    (while (string-match (rx (group (* (not (in "\e\n"))))  ; preceding chars
+                             "\e["                          ; CSI
+                             (? (group (+ digit)))          ; argument
+                             (group (in "GJ")))             ; CHA or ED
+                         string ofs)
+      (let* ((start (match-beginning 1))
+             (prefix-end (match-end 1))
+             (op (aref string (match-beginning 3)))
+             (end (match-end 0))
+             (keep-end
+              (if (eq op ?G)
+                  ;; Move to absolute column (CHA)
+                  (min prefix-end
+                       (+ start
+                          (if (match-beginning 2)
+                              (1- (string-to-number (match-string 2 string)))
+                            0)))
+                ;; Erase in display (ED): no further action.
+                prefix-end)))
+        ;; Delete the control sequence and possibly part of the preceding 
chars.
+        (setq string (concat (substring string 0 keep-end)
+                             (substring string end)))
+        (setq ofs start))))
   string)
 
-;; According to SBCommanInterpreter.cpp, the return value of
+;; According to SBCommandInterpreter.cpp, the return value of
 ;; HandleCompletions is as follows:
 ;;
 ;; Index 1 to the end contain all the completions.
@@ -3906,27 +3953,35 @@ so they have been disabled."))
 
 (defcustom gud-lldb-max-completions 20
   "Maximum number of completions to request from LLDB."
-  :type 'integer)
+  :type 'integer
+  :version "30.1")
 
-(defvar gud-lldb-def-python-completion-function
-  "
+(defconst gud--lldb-python-init-string
+  "\
+deb = lldb.debugger
+inst = deb.GetInstanceName()
+ff = deb.GetInternalVariableValue('frame-format', inst).GetStringAtIndex(0)
+ff = ff[:-1] + '!gud 
${line.number}:${line.column}:${line.file.fullpath}\\\\n\"'
+_ = deb.SetInternalVariable('frame-format', ff, inst)
 def gud_complete(s, max):
     interpreter = lldb.debugger.GetCommandInterpreter()
     string_list = lldb.SBStringList()
     interpreter.HandleCompletion(s, len(s), len(s), max, string_list)
-    print('gud-completions: (')
+    print('gud-completions: ##(')
     # Specifying a max count doesn't seem to work in LLDB 17.
     max = min(max, string_list.GetSize())
     for i in range(max):
         print(f'\"{string_list.GetStringAtIndex(i)}\" ')
-    print(')')
+    print(')##')
 "
-  "LLDB Python function for completion.")
+  "Python code sent to LLDB for gud-specific initialisation.")
 
 (defun gud-lldb-fetch-completions (context command)
   "Return the data to complete the LLDB command before point.
 This is what the Python function we installed at initialzation
-time returns, as a Lisp list."
+time returns, as a Lisp list.
+Maximum number of completions requested from LLDB is controlled
+by `gud-lldb-max-completions', which see."
   (let* ((process (get-buffer-process gud-comint-buffer))
          (to-complete (concat context command))
          (output-buffer (get-buffer-create "*lldb-completions*")))
@@ -3940,12 +3995,12 @@ time returns, as a Lisp list."
     ;; Wait for output
     (unwind-protect
         (while (not comint-redirect-completed)
-          (accept-process-output process))
+          (accept-process-output process 2))
       (comint-redirect-cleanup))
     ;; Process the completion output.
     (with-current-buffer output-buffer
       (goto-char (point-min))
-      (when (search-forward "gud-completions:" nil t)
+      (when (search-forward "gud-completions: ##" nil t)
         (read (current-buffer))))))
 
 (defun gud-lldb-completions (context command)
@@ -3970,15 +4025,6 @@ time returns, as a Lisp list."
           (completion-table-dynamic
            (apply-partially #'gud-lldb-completions context)))))
 
-(defvar gud-lldb-frame-format
-  (concat "gud-info: (gud-lldb-stop "
-          ;; Quote the filename this way to avoid quoting issues in
-          ;; the interplay between Emacs and LLDB.  The quotes are
-          ;; corrected in the process filter.
-          ":file ///${line.file.fullpath}/// "
-          ":line ${line.number} "
-          ":column ${line.column})\\n"))
-
 (defun gud-lldb-send-python (python)
   (gud-basic-call "script --language python --")
   (mapc #'gud-basic-call (split-string python "\n"))
@@ -3986,30 +4032,32 @@ time returns, as a Lisp list."
 
 (defun gud-lldb-initialize ()
   "Initialize the LLDB process as needed for this debug session."
-  (gud-lldb-send-python gud-lldb-def-python-completion-function)
+  (gud-lldb-send-python gud--lldb-python-init-string)
   (gud-basic-call "settings set stop-line-count-before 0")
-  (gud-basic-call "settings set stop-line-count-after 0")
-  (gud-basic-call (format "settings set frame-format \"%s\""
-                          gud-lldb-frame-format))
-  (gud-basic-call "script --language python -- print('Gud initialized')")
-  (gud-basic-call "script --language python -- print('Gud initialized.')"))
+  (gud-basic-call "settings set stop-line-count-after 0"))
 
 ;;;###autoload
 (defun lldb (command-line)
-  "Run lldb passing it COMMAND-LINE as arguments.
-If COMMAND-LINE names a program FILE to debug, lldb will run in
+  "Run LLDB passing it COMMAND-LINE as arguments.
+If COMMAND-LINE names a program FILE to debug, LLDB will run in
 a buffer named *gud-FILE*, and the directory containing FILE
 becomes the initial working directory and source-file directory
-for your debugger.  If you don't want `default-directory' to
+for the debug session.  If you don't want `default-directory' to
 change to the directory of FILE, specify FILE without leading
 directories, in which case FILE should reside either in the
 directory of the buffer from which this command is invoked, or
 it can be found by searching PATH.
 
-If COMMAND-LINE requests that lldb attaches to a process PID, lldb
+If COMMAND-LINE requests that LLDB attaches to a process PID, LLDB
 will run in *gud-PID*, otherwise it will run in *gud*; in these
 cases the initial working directory is the `default-directory' of
-the buffer in which this command was invoked."
+the buffer in which this command was invoked.
+
+Please note that completion framework that complete while you
+type, like Corfu, do not work well with this mode.  You should
+consider to turn them off in this mode.
+
+This command runs functions from `lldb-mode-hook'. "
   (interactive (list (gud-query-cmdline 'lldb)))
 
   (when (and gud-comint-buffer
diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el
index e50e1226b43..37c501ae4e2 100644
--- a/lisp/progmodes/idlw-shell.el
+++ b/lisp/progmodes/idlw-shell.el
@@ -1454,9 +1454,7 @@ and then calls `idlwave-shell-send-command' for any 
pending commands."
                         (concat idlwave-shell-accumulation string)))
                    (setq idlwave-shell-accumulation
                          (substring string
-                                    (progn (string-match "\\(.*[\n\r]+\\)*"
-                                                         string)
-                                           (match-end 0)))))
+                                    (string-match "[^\n\r]*\\'" string))))
                (setq idlwave-shell-accumulation
                      (concat idlwave-shell-accumulation string)))
 
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 9ca6bee8454..6fd714940b6 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3854,7 +3854,7 @@ See `treesit-thing-settings' for more information.")
     "pair"
     "jsx")
   "Nodes that designate sexps in JavaScript.
-See `treesit-sexp-type-regexp' for more information.")
+See `treesit-thing-settings' for more information.")
 
 ;;;###autoload
 (define-derived-mode js-ts-mode js-base-mode "JavaScript"
diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el
index 030a3585158..2193779b759 100644
--- a/lisp/progmodes/lua-ts-mode.el
+++ b/lisp/progmodes/lua-ts-mode.el
@@ -38,7 +38,12 @@
   (require 'cl-lib)
   (require 'rx))
 
+(declare-function treesit-induce-sparse-tree "treesit.c")
 (declare-function treesit-node-child-by-field-name "treesit.c")
+(declare-function treesit-node-child-count "treesit.c")
+(declare-function treesit-node-first-child-for-pos "treesit.c")
+(declare-function treesit-node-parent "treesit.c")
+(declare-function treesit-node-start "treesit.c")
 (declare-function treesit-node-type "treesit.c")
 (declare-function treesit-parser-create "treesit.c")
 (declare-function treesit-search-subtree "treesit.c")
@@ -48,6 +53,15 @@
   :prefix "lua-ts-"
   :group 'languages)
 
+(defcustom lua-ts-mode-hook nil
+  "Hook run after entering `lua-ts-mode'."
+  :type 'hook
+  :options '(flymake-mode
+             hs-minor-mode
+             outline-minor-mode)
+  :group 'lua-ts
+  :version "30.1")
+
 (defcustom lua-ts-indent-offset 4
   "Number of spaces for each indentation step in `lua-ts-mode'."
   :type 'natnum
@@ -57,7 +71,7 @@
 
 (defcustom lua-ts-luacheck-program "luacheck"
   "Location of the Luacheck program."
-  :type '(choice (const nil) string)
+  :type '(choice (const :tag "None" nil) string)
   :group 'lua-ts
   :version "30.1")
 
@@ -70,7 +84,7 @@
 
 (defcustom lua-ts-inferior-program "lua"
   "Program to run in the inferior Lua process."
-  :type '(choice (const nil) string)
+  :type '(choice (const :tag "None" nil) string)
   :group 'lua-ts
   :version "30.1")
 
@@ -82,13 +96,28 @@
 
 (defcustom lua-ts-inferior-startfile nil
   "File to load into the inferior Lua process at startup."
-  :type '(choice (const nil) (file :must-match t))
+  :type '(choice (const :tag "None" nil) (file :must-match t))
+  :group 'lua-ts
+  :version "30.1")
+
+(defcustom lua-ts-inferior-prompt ">"
+  "Prompt used by the inferior Lua process."
+  :type 'string
+  :safe 'stringp
+  :group 'lua-ts
+  :version "30.1")
+
+(defcustom lua-ts-inferior-prompt-continue ">>"
+  "Continuation prompt used by the inferior Lua process."
+  :type 'string
+  :safe 'stringp
   :group 'lua-ts
   :version "30.1")
 
-(defcustom lua-ts-inferior-prompt-regexp "^>>?[[:blank:]]"
-  "Regular expression matching the prompt of the inferior Lua process."
-  :type 'regexp
+(defcustom lua-ts-inferior-history nil
+  "File used to save command history of the inferior Lua process."
+  :type '(choice (const :tag "None" nil) file)
+  :safe 'string-or-null-p
   :group 'lua-ts
   :version "30.1")
 
@@ -103,6 +132,12 @@
     "close" "flush" "lines" "read" "seek" "setvbuf" "write")
   "Lua built-in functions for tree-sitter font-locking.")
 
+(defvar lua-ts--keywords
+  '("and" "do" "else" "elseif" "end" "for" "function"
+    "goto" "if" "in" "local" "not" "or" "repeat"
+    "return" "then" "until" "while")
+  "Lua keywords for tree-sitter font-locking and navigation.")
+
 (defvar lua-ts--font-lock-settings
   (treesit-font-lock-rules
    :language 'lua
@@ -167,13 +202,11 @@
 
    :language 'lua
    :feature 'keyword
-   '((break_statement) @font-lock-keyword-face
+   `((break_statement) @font-lock-keyword-face
      (true) @font-lock-constant-face
      (false) @font-lock-constant-face
      (nil) @font-lock-constant-face
-     ["and" "do" "else" "elseif" "end" "for" "function"
-      "goto" "if" "in" "local" "not" "or" "repeat"
-      "return" "then" "until" "while"]
+     ,(vconcat lua-ts--keywords)
      @font-lock-keyword-face)
 
    :language 'lua
@@ -235,27 +268,145 @@
 
 (defvar lua-ts--simple-indent-rules
   `((lua
+     ((or (node-is "comment")
+          (parent-is "comment_content")
+          (parent-is "string_content")
+          (node-is "]]"))
+      no-indent 0)
+     ((and (n-p-gp "field" "table_constructor" "arguments")
+           lua-ts--multi-arg-function-call-matcher)
+      parent lua-ts-indent-offset)
+     ((and (n-p-gp "}" "table_constructor" "arguments")
+           lua-ts--multi-arg-function-call-matcher)
+      parent 0)
+     ((or (node-is "do")
+          (node-is "then")
+          (node-is "elseif_statement")
+          (node-is "else_statement")
+          (node-is "until")
+          (node-is ")")
+          (node-is "}"))
+      standalone-parent 0)
+     ((or (and (parent-is "arguments") lua-ts--first-child-matcher)
+          (and (parent-is "parameters") lua-ts--first-child-matcher)
+          (and (parent-is "table_constructor") lua-ts--first-child-matcher))
+      standalone-parent lua-ts-indent-offset)
+     ((or (parent-is "arguments")
+          (parent-is "parameters")
+          (parent-is "table_constructor"))
+      (nth-sibling 1) 0)
+     ((and (n-p-gp "block" "function_definition" "parenthesized_expression")
+           lua-ts--nested-function-block-matcher
+           lua-ts--nested-function-block-include-matcher)
+      parent lua-ts-indent-offset)
+     ((and (n-p-gp "block" "function_definition" "arguments")
+           lua-ts--nested-function-argument-matcher)
+      parent lua-ts-indent-offset)
+     ((match "function_definition" "parenthesized_expression")
+      standalone-parent lua-ts-indent-offset)
+     ((node-is "block") standalone-parent lua-ts-indent-offset)
+     ((parent-is "block") parent 0)
+     ((and (node-is "end") lua-ts--end-line-matcher)
+      standalone-parent lua-ts--end-indent-offset)
+     ((match "end" "function_declaration") parent 0)
+     ((and (n-p-gp "end" "function_definition" "parenthesized_expression")
+           lua-ts--nested-function-end-argument-matcher)
+      parent 0)
+     ((and (n-p-gp "end" "function_definition" "parenthesized_expression")
+           lua-ts--nested-function-block-matcher
+           lua-ts--nested-function-end-matcher
+           lua-ts--nested-function-last-function-matcher)
+      parent 0)
+     ((n-p-gp "end" "function_definition" "arguments") parent 0)
+     ((or (match "end" "function_definition")
+          (node-is "end"))
+      standalone-parent 0)
+     ((or (parent-is "function_declaration")
+          (parent-is "function_definition")
+          (parent-is "do_statement")
+          (parent-is "for_statement")
+          (parent-is "repeat_statement")
+          (parent-is "while_statement")
+          (parent-is "if_statement")
+          (parent-is "else_statement")
+          (parent-is "elseif_statement"))
+      standalone-parent lua-ts-indent-offset)
      ((parent-is "chunk") column-0 0)
-     ((node-is "comment_end") column-0 0)
-     ((parent-is "block") parent-bol 0)
-     ((node-is "}") parent-bol 0)
-     ((node-is ")") parent-bol 0)
-     ((node-is "else_statement") parent-bol 0)
-     ((node-is "elseif_statement") parent-bol 0)
-     ((node-is "end") parent-bol 0)
-     ((node-is "until") parent-bol 0)
-     ((parent-is "for_statement") parent-bol lua-ts-indent-offset)
-     ((parent-is "function_declaration") parent-bol lua-ts-indent-offset)
-     ((parent-is "function_definition") parent-bol lua-ts-indent-offset)
-     ((parent-is "if_statement") parent-bol lua-ts-indent-offset)
-     ((parent-is "else_statement") parent-bol lua-ts-indent-offset)
-     ((parent-is "repeat_statement") parent-bol lua-ts-indent-offset)
-     ((parent-is "while_statement") parent-bol lua-ts-indent-offset)
-     ((parent-is "table_constructor") parent-bol lua-ts-indent-offset)
-     ((parent-is "arguments") parent-bol lua-ts-indent-offset)
-     ((parent-is "parameters") parent-bol lua-ts-indent-offset)
      ((parent-is "ERROR") no-indent 0))))
 
+(defun lua-ts--end-line-matcher (&rest _)
+  "Matches if there is more than one `end' on the current line."
+  (> (lua-ts--end-count) 1))
+
+(defun lua-ts--end-indent-offset (&rest _)
+  "Calculate indent offset based on `end' count."
+  (- (* (1- (lua-ts--end-count)) lua-ts-indent-offset)))
+
+(defun lua-ts--end-count ()
+  "Count the number of `end's on the current line."
+  (count-matches "end" (line-beginning-position) (line-end-position)))
+
+(defun lua-ts--first-child-matcher (node &rest _)
+  "Matches if NODE is the first among its siblings."
+  (= (treesit-node-index node) 1))
+
+(defun lua-ts--function-definition-p (node)
+  "Return t if NODE is a function_definition."
+  (equal "function_definition" (treesit-node-type node)))
+
+(defun lua-ts--g-g-g-parent (node)
+  "Return the great-great-grand-parent of NODE."
+  (let* ((parent (treesit-node-parent node))
+         (g-parent (treesit-node-parent parent))
+         (g-g-parent (treesit-node-parent g-parent)))
+    (treesit-node-parent g-g-parent)))
+
+(defun lua-ts--multi-arg-function-call-matcher (_n parent &rest _)
+  "Matches if PARENT has multiple arguments."
+  (> (treesit-node-child-count (treesit-node-parent parent)) 3))
+
+(defun lua-ts--nested-function-argument-matcher (node &rest _)
+  "Matches if NODE is in a nested function argument."
+  (save-excursion
+    (goto-char (treesit-node-start node))
+    (treesit-beginning-of-defun)
+    (backward-char 2)
+    (not (looking-at ")("))))
+
+(defun lua-ts--nested-function-block-matcher (node &rest _)
+  "Matches if NODE is in a nested function block."
+  (let* ((g-g-g-parent (lua-ts--g-g-g-parent node))
+         (g-g-g-type (treesit-node-type g-g-g-parent)))
+    (not (equal g-g-g-type "chunk"))))
+
+(defun lua-ts--nested-function-block-include-matcher (node _p bol &rest _)
+  "Matches if NODE's child at BOL is not another block."
+  (let* ((child (treesit-node-first-child-for-pos node bol))
+         (child-type (treesit-node-type child))
+         (g-g-g-type (treesit-node-type (lua-ts--g-g-g-parent node))))
+    (or (equal child-type "assignment_statement")
+        (and (equal child-type "return_statement")
+             (or (equal g-g-g-type "arguments")
+                 (and (equal g-g-g-type "expression_list")
+                      (not (treesit-search-subtree child 
"function_call"))))))))
+
+(defun lua-ts--nested-function-end-matcher (node &rest _)
+  "Matches if NODE is the `end' of a nested function."
+  (save-excursion
+    (goto-char (treesit-node-start node))
+    (treesit-beginning-of-defun)
+    (looking-at "function[[:space:]]*")))
+
+(defun lua-ts--nested-function-end-argument-matcher (node &rest _)
+  "Matches if great-great-grandparent of NODE is arguments."
+  (equal "arguments" (treesit-node-type (lua-ts--g-g-g-parent node))))
+
+(defun lua-ts--nested-function-last-function-matcher (_n parent &rest _)
+  "Matches if PARENT is the last nested function."
+  (let ((sparse-tree
+         (treesit-induce-sparse-tree parent #'lua-ts--function-definition-p)))
+    (= 1 (length (cadr sparse-tree)))))
+
 (defvar lua-ts--syntax-table
   (let ((table (make-syntax-table)))
     (modify-syntax-entry ?+  "."    table)
@@ -292,6 +443,33 @@ Return nil if there is no name or if NODE is not a defun 
node."
        (and (treesit-search-subtree node "function_definition" nil nil 1)
             (treesit-node-text child t))))))
 
+(defun lua-ts--named-function-p (node)
+  "Matches if NODE is a named function."
+  (let ((type (treesit-node-type node)))
+    (or (equal "function_declaration" type)
+        (and (equal "field" type)
+             (equal "function_definition"
+                    (treesit-node-type
+                     (treesit-node-child-by-field-name
+                      node "value")))
+             (treesit-node-child-by-field-name node "name")))))
+
+(defun lua-ts--require-name-function (node)
+  "Return name of NODE to use for requires in imenu."
+  (when-let* (((lua-ts--require-p node))
+              (parent (treesit-node-parent node))
+              (parent-type (treesit-node-type parent)))
+    (if (equal "expression_list" parent-type)
+        (let* ((g-parent (treesit-node-parent parent))
+               (name (treesit-node-child-by-field-name g-parent "name")))
+          (treesit-node-text name t))
+      (treesit-node-text (treesit-search-subtree node "string_content") t))))
+
+(defun lua-ts--require-p (node)
+  "Matches if NODE is a require statement."
+  (let ((name (treesit-node-child-by-field-name node "name")))
+    (equal "require" (treesit-node-text name t))))
+
 (defvar-local lua-ts--flymake-process nil)
 
 (defun lua-ts-flymake-luacheck (report-fn &rest _args)
@@ -352,26 +530,126 @@ Calls REPORT-FN directly."
 (defun lua-ts-inferior-lua ()
   "Run a Lua interpreter in an inferior process."
   (interactive)
-  (let* ((buffer lua-ts-inferior-buffer)
-         (name (string-replace "*" "" buffer))
-         (program lua-ts-inferior-program)
-         (prompt-regexp lua-ts-inferior-prompt-regexp)
-         (switches lua-ts-inferior-options)
-         (startfile lua-ts-inferior-startfile))
-    (unless (comint-check-proc buffer)
-      (set-buffer (apply (function make-comint) name program startfile 
switches))
+  (unless (comint-check-proc lua-ts-inferior-buffer)
+    (apply #'make-comint-in-buffer
+           (string-replace "*" "" lua-ts-inferior-buffer)
+           lua-ts-inferior-buffer
+           lua-ts-inferior-program
+           lua-ts-inferior-startfile
+           lua-ts-inferior-options)
+    (when lua-ts-inferior-history
+        (set-process-sentinel (get-buffer-process lua-ts-inferior-buffer)
+                              'lua-ts-inferior--write-history))
+    (with-current-buffer lua-ts-inferior-buffer
       (setq-local comint-input-ignoredups t
+                  comint-input-ring-file-name lua-ts-inferior-history
+                  comint-use-prompt-regexp t
                   comint-prompt-read-only t
-                  comint-prompt-regexp prompt-regexp
-                  comint-use-prompt-regexp t))
-    (select-window (display-buffer buffer '((display-buffer-reuse-window
-                                             display-buffer-pop-up-frame)
-                                            (reusable-frames . t))))))
+                  comint-prompt-regexp (rx-to-string `(: bol
+                                                         
,lua-ts-inferior-prompt
+                                                         (1+ space))))
+      (comint-read-input-ring t)
+      (add-hook 'comint-preoutput-filter-functions
+                (lambda (string)
+                  (if (or (not (equal (buffer-name) lua-ts-inferior-buffer))
+                          (equal string
+                                 (concat lua-ts-inferior-prompt-continue " ")))
+                      string
+                    (concat
+                     ;; Filter out the extra prompt characters that
+                     ;; accumulate in the output when sending regions
+                     ;; to the inferior process.
+                     (replace-regexp-in-string (rx-to-string
+                                                `(: bol
+                                                    (* ,lua-ts-inferior-prompt
+                                                       (? 
,lua-ts-inferior-prompt)
+                                                       (1+ space))
+                                                    (group (* nonl))))
+                                               "\\1" string)
+                     ;; Re-add the prompt for the next line.
+                     lua-ts-inferior-prompt " "))))))
+  (select-window (display-buffer lua-ts-inferior-buffer
+                                 '((display-buffer-reuse-window
+                                    display-buffer-pop-up-frame)
+                                   (reusable-frames . t))))
+  (get-buffer-process (current-buffer)))
+
+(defun lua-ts-send-buffer ()
+  "Send current buffer to the inferior Lua process."
+  (interactive)
+  (lua-ts-send-region (point-min) (point-max)))
+
+(defun lua-ts-send-file (file)
+  "Send contents of FILE to the inferior Lua process."
+  (interactive "f")
+  (with-temp-buffer
+    (insert-file-contents-literally file)
+    (lua-ts-send-region (point-min) (point-max))))
+
+(defun lua-ts-send-region (beg end)
+  "Send region between BEG and END to the inferior Lua process."
+  (interactive "r")
+  (let ((string (buffer-substring-no-properties beg end))
+        (proc-buffer (lua-ts-inferior-lua)))
+    (comint-send-string proc-buffer "print()") ; Prevent output from
+    (comint-send-string proc-buffer "\n")      ; appearing at prompt.
+    (comint-send-string proc-buffer string)
+    (comint-send-string proc-buffer "\n")))
+
+(defun lua-ts-show-process-buffer ()
+  "Show the inferior Lua process buffer."
+  (interactive)
+  (display-buffer lua-ts-inferior-buffer))
+
+(defun lua-ts-hide-process-buffer ()
+  "Hide the inferior Lua process buffer."
+  (interactive)
+  (delete-windows-on lua-ts-inferior-buffer))
+
+(defun lua-ts-kill-process ()
+  "Kill the inferior Lua process."
+  (interactive)
+  (with-current-buffer lua-ts-inferior-buffer
+    (kill-buffer-and-window)))
+
+(defun lua-ts-inferior--write-history (process _)
+  "Write history file for inferior Lua PROCESS."
+  ;; Depending on how the process is killed the buffer may not be
+  ;; around anymore; e.g. `kill-buffer'.
+  (when-let* ((buffer (process-buffer process))
+              ((buffer-live-p (process-buffer process))))
+    (with-current-buffer buffer (comint-write-input-ring))))
+
+(defvar lua-ts-mode-map
+  (let ((map (make-sparse-keymap "Lua")))
+    (define-key map "\C-c\C-n" 'lua-ts-inferior-lua)
+    (define-key map "\C-c\C-c" 'lua-ts-send-buffer)
+    (define-key map "\C-c\C-l" 'lua-ts-send-file)
+    (define-key map "\C-c\C-r" 'lua-ts-send-region)
+    map)
+  "Keymap for `lua-ts-mode' buffers.")
+
+(easy-menu-define lua-ts-mode-menu lua-ts-mode-map
+  "Menu bar entry for `lua-ts-mode'."
+  `("Lua"
+    ["Evaluate Buffer" lua-ts-send-buffer]
+    ["Evaluate File" lua-ts-send-file]
+    ["Evaluate Region" lua-ts-send-region]
+    "--"
+    ["Start Process" lua-ts-inferior-lua]
+    ["Show Process Buffer" lua-ts-show-process-buffer]
+    ["Hide Process Buffer" lua-ts-hide-process-buffer]
+    ["Kill Process" lua-ts-kill-process]
+    "--"
+    ["Customize" (lambda () (interactive) (customize-group "lua-ts"))]))
 
 ;;;###autoload
 (define-derived-mode lua-ts-mode prog-mode "Lua"
-  "Major mode for editing Lua files, powered by tree-sitter."
+  "Major mode for editing Lua files, powered by tree-sitter.
+
+\\{lua-ts-mode-map}"
   :syntax-table lua-ts--syntax-table
+  (use-local-map lua-ts-mode-map)
 
   (when (treesit-ready-p 'lua)
     (treesit-parser-create 'lua)
@@ -404,31 +682,52 @@ Calls REPORT-FN directly."
                 (rx (or "function_declaration" "function_definition")))
     (setq-local treesit-thing-settings
                 `((lua
-                   (sentence ,(rx (or "do_statement"
-                                      "field"
-                                      "for_statement"
-                                      "function_call"
-                                      "if_statement"
-                                      "repeat_statement"
-                                      "return_statement"
-                                      "variable_declaration"
-                                      "while_statement")))
-                   (sexp ,(rx (or "arguments"
-                                  "block"
-                                  "parameters"
-                                  "string"
-                                  "table_constructor")))
+                   (function ,(rx (or "function_declaration"
+                                      "function_definition")))
+                   (keyword ,(regexp-opt lua-ts--keywords
+                                         'symbols))
+                   (loop-statement ,(rx (or "do_statement"
+                                            "for_statement"
+                                            "repeat_statement"
+                                            "while_statement")))
+                   (sentence (or function
+                                 loop-statement
+                                 ,(rx (or "assignment_statement"
+                                          "comment"
+                                          "field"
+                                          "function_call"
+                                          "if_statement"
+                                          "return_statement"
+                                          "variable_declaration"))))
+                   (sexp (or function
+                             keyword
+                             loop-statement
+                             ,(rx (or "arguments"
+                                      "break_statement"
+                                      "expression_list"
+                                      "false"
+                                      "identifier"
+                                      "nil"
+                                      "number"
+                                      "parameters"
+                                      "parenthesized_expression"
+                                      "string"
+                                      "table_constructor"
+                                      "true"
+                                      "vararg_expression"))))
                    (text "comment"))))
 
     ;; Imenu.
     (setq-local treesit-simple-imenu-settings
-                `(("Variable" ,(rx bos "variable_declaration" eos) nil nil)
-                  ("Function" ,(rx bos
-                                   (or "function_declaration"
-                                       "function_definition"
-                                       "field")
-                                   eos)
-                   nil nil)))
+                `(("Requires"
+                   "\\`function_call\\'"
+                   lua-ts--require-p
+                   lua-ts--require-name-function)
+                  ("Variables" "\\`variable_declaration\\'" nil nil)
+                  (nil
+                   "\\`\\(?:f\\(?:ield\\|unction_declaration\\)\\)\\'"
+                   lua-ts--named-function-p
+                   nil)))
 
     ;; Which-function.
     (setq-local which-func-functions (treesit-defun-at-point))
@@ -443,6 +742,9 @@ Calls REPORT-FN directly."
                                            "function"))
                                   symbol-end)))))
 
+    ;; Align.
+    (setq-local align-indent-before-aligning t)
+
     (treesit-major-mode-setup))
 
   (add-hook 'flymake-diagnostic-functions #'lua-ts-flymake-luacheck nil 
'local))
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index f45490ef6c3..6fd59ed3f93 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -768,7 +768,7 @@ Key bindings:
   (setq-local comint-prompt-read-only inferior-octave-prompt-read-only)
   (add-hook 'comint-input-filter-functions
             'inferior-octave-directory-tracker nil t)
-  ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572
+  ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572 [dead link]
   (add-hook 'window-configuration-change-hook
             'inferior-octave-track-window-width-change nil t)
   (setq-local compilation-error-regexp-alist 
inferior-octave-error-regexp-alist)
@@ -1007,7 +1007,7 @@ directory and makes this the current buffer's default 
directory."
 (defvar inferior-octave-last-column-width nil)
 
 (defun inferior-octave-track-window-width-change ()
-  ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572
+  ;; http://thread.gmane.org/gmane.comp.gnu.octave.general/48572 [dead link]
   (let ((width (max inferior-octave-minimal-columns (window-width))))
     (unless (eq inferior-octave-last-column-width width)
       (setq-local inferior-octave-last-column-width width)
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index b9ecb770e60..bb44cfefa54 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -647,6 +647,7 @@ See `project-vc-extra-root-markers' for the marker value 
format.")
             (include-untracked (project--value-in-dir
                                 'project-vc-include-untracked
                                 dir))
+            (submodules (project--git-submodules))
             files)
        (setq args (append args
                           '("-c" "--exclude-standard")
@@ -678,23 +679,25 @@ See `project-vc-extra-root-markers' for the marker value 
format.")
                                         i)))
                                    extra-ignores)))))
        (setq files
-             (mapcar
-              (lambda (file) (concat default-directory file))
-              (split-string
-               (apply #'vc-git--run-command-string nil "ls-files" args)
-               "\0" t)))
+             (delq nil
+                   (mapcar
+                    (lambda (file)
+                      (unless (member file submodules)
+                        (concat default-directory file)))
+                    (split-string
+                     (apply #'vc-git--run-command-string nil "ls-files" args)
+                     "\0" t))))
        (when (project--vc-merge-submodules-p default-directory)
          ;; Unfortunately, 'ls-files --recurse-submodules' conflicts with '-o'.
-         (let* ((submodules (project--git-submodules))
-                (sub-files
-                 (mapcar
-                  (lambda (module)
-                    (when (file-directory-p module)
-                      (project--vc-list-files
-                       (concat default-directory module)
-                       backend
-                       extra-ignores)))
-                  submodules)))
+         (let ((sub-files
+                (mapcar
+                 (lambda (module)
+                   (when (file-directory-p module)
+                     (project--vc-list-files
+                      (concat default-directory module)
+                      backend
+                      extra-ignores)))
+                 submodules)))
            (setq files
                  (apply #'nconc files sub-files))))
        ;; 'git ls-files' returns duplicate entries for merge conflicts.
@@ -880,6 +883,17 @@ DIRS must contain directory names."
         (call-interactively cmd)
       (user-error "%s is undefined" (key-description key)))))
 
+(defun project--other-place-prefix (place &optional extra-keymap)
+  (cl-assert (member place '(window frame tab)))
+  (prefix-command-preserve-state)
+  (let ((inhibit-message t)) (funcall (intern (format "other-%s-prefix" 
place))))
+  (message "Display next project command buffer in a new %s..." place)
+  ;; Should return exitfun from set-transient-map
+  (set-transient-map (if extra-keymap
+                         (make-composed-keymap project-prefix-map
+                                               extra-keymap)
+                       project-prefix-map)))
+
 ;;;###autoload
 (defun project-other-window-command ()
   "Run project command, displaying resultant buffer in another window.
@@ -889,9 +903,11 @@ The following commands are available:
 \\{project-prefix-map}
 \\{project-other-window-map}"
   (interactive)
-  (project--other-place-command '((display-buffer-pop-up-window)
-                                  (inhibit-same-window . t))
-                                project-other-window-map))
+  (if (< emacs-major-version 30)
+      (project--other-place-command '((display-buffer-pop-up-window)
+                                      (inhibit-same-window . t))
+                                    project-other-window-map)
+    (project--other-place-prefix 'window project-other-window-map)))
 
 ;;;###autoload (define-key ctl-x-4-map "p" #'project-other-window-command)
 
@@ -904,8 +920,10 @@ The following commands are available:
 \\{project-prefix-map}
 \\{project-other-frame-map}"
   (interactive)
-  (project--other-place-command '((display-buffer-pop-up-frame))
-                                project-other-frame-map))
+  (if (< emacs-major-version 30)
+      (project--other-place-command '((display-buffer-pop-up-frame))
+                                    project-other-frame-map)
+    (project--other-place-prefix 'frame project-other-frame-map)))
 
 ;;;###autoload (define-key ctl-x-5-map "p" #'project-other-frame-command)
 
@@ -917,7 +935,9 @@ The following commands are available:
 
 \\{project-prefix-map}"
   (interactive)
-  (project--other-place-command '((display-buffer-in-new-tab))))
+  (if (< emacs-major-version 30)
+      (project--other-place-command '((display-buffer-in-new-tab)))
+    (project--other-place-prefix 'tab)))
 
 ;;;###autoload
 (when (bound-and-true-p tab-prefix-map)
@@ -1309,8 +1329,7 @@ command \\[fileloop-continue]."
   (interactive "sSearch (regexp): ")
   (fileloop-initialize-search
    regexp
-   ;; XXX: See the comment in project-query-replace-regexp.
-   (cl-delete-if-not #'file-regular-p (project-files (project-current t)))
+   (project-files (project-current t))
    'default)
   (fileloop-continue))
 
@@ -1331,10 +1350,7 @@ If you exit the `query-replace', you can later continue 
the
        (list from to))))
   (fileloop-initialize-replace
    from to
-   ;; XXX: Filter out Git submodules, which are not regular files.
-   ;; `project-files' can return those, which is arguably suboptimal,
-   ;; but removing them eagerly has performance cost.
-   (cl-delete-if-not #'file-regular-p (project-files (project-current t)))
+   (project-files (project-current t))
    'default)
   (fileloop-continue))
 
@@ -1924,6 +1940,15 @@ Otherwise, use the face `help-key-binding' in the 
prompt."
   :version "30.1")
 
 (defun project--keymap-prompt ()
+  "Return a prompt for the project switching using the prefix map."
+  (let (keys)
+    (map-keymap
+     (lambda (evt _)
+       (when (characterp evt) (push evt keys)))
+     project-prefix-map)
+    (mapconcat (lambda (key) (help-key-description (string key) nil)) keys " 
")))
+
+(defun project--menu-prompt ()
   "Return a prompt for the project switching dispatch menu."
   (mapconcat
    (pcase-lambda (`(,cmd ,label ,key))
@@ -1962,20 +1987,30 @@ Otherwise, use the face `help-key-binding' in the 
prompt."
               (when-let ((cmd (nth 0 row))
                          (keychar (nth 2 row)))
                 (define-key temp-map (vector keychar) cmd)))))
-         command)
+         command
+         choice)
     (while (not command)
       (let* ((overriding-local-map commands-map)
-             (choice (read-key-sequence (project--keymap-prompt))))
+             (prompt (if project-switch-use-entire-map
+                         (project--keymap-prompt)
+                       (project--menu-prompt))))
+        (when choice
+          (setq prompt (concat prompt
+                               (format " %s: %s"
+                                       (propertize "Unrecognized input"
+                                                   'face 'warning)
+                                       (help-key-description choice nil)))))
+        (setq choice (read-key-sequence (concat "Choose: " prompt)))
         (when (setq command (lookup-key commands-map choice))
+          (when (numberp command) (setq command nil))
           (unless (or project-switch-use-entire-map
                       (assq command commands-menu))
-            ;; TODO: Add some hint to the prompt, like "key not
-            ;; recognized" or something.
             (setq command nil)))
         (let ((global-command (lookup-key (current-global-map) choice)))
           (when (memq global-command
                       '(keyboard-quit keyboard-escape-quit))
             (call-interactively global-command)))))
+    (message nil)
     command))
 
 ;;;###autoload
diff --git a/lisp/progmodes/typescript-ts-mode.el 
b/lisp/progmodes/typescript-ts-mode.el
index 01a021c64fc..b976145dbf3 100644
--- a/lisp/progmodes/typescript-ts-mode.el
+++ b/lisp/progmodes/typescript-ts-mode.el
@@ -166,7 +166,7 @@ Argument LANGUAGE is either `typescript' or `tsx'."
   ;; but then raises an error if the wrong node type is used. So it is
   ;; important to check with the new node type (member_expression)
   (condition-case nil
-      (progn (treesit-query-capture language '(jsx_opening_element 
(member_expression) @capture))
+      (progn (treesit-query-capture language '((jsx_opening_element 
(member_expression) @capture)))
             '((jsx_opening_element
                [(member_expression (identifier)) (identifier)]
                @typescript-ts-jsx-tag-face)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 8d0a10c0918..b55fae3374a 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -11769,8 +11769,8 @@ reflected in a subsequent paste operation."
                (setq comment (substring type (match-beginning 2)))
                (setq type (substring type 0 (match-beginning 1))))
              ;; strip of trailing group-comment
-             (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
-             (setq type (substring type 0 (match-end 1)))
+              (when (string-match "\\S-\\s-*\\'" type)
+               (setq type (substring type 0 (1+ (match-beginning 0)))))
              ;; parse initialization expression
              (setq init nil)
              (when (vhdl-parse-string ":=[ \t\n\r\f]*" t)
@@ -11844,8 +11844,8 @@ reflected in a subsequent paste operation."
                (setq comment (substring type (match-beginning 2)))
                (setq type (substring type 0 (match-beginning 1))))
              ;; strip of trailing group-comment
-             (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
-             (setq type (substring type 0 (match-end 1)))
+              (when (string-match "\\S-\\s-*\\'" type)
+               (setq type (substring type 0 (1+ (match-beginning 0)))))
              (vhdl-forward-syntactic-ws)
              (setq end-of-list (vhdl-parse-string ")" t))
              (vhdl-parse-string "\\s-*;\\s-*")
@@ -12580,8 +12580,8 @@ reflected in a subsequent paste operation."
              (setq comment (substring type (match-beginning 2)))
              (setq type (substring type 0 (match-beginning 1))))
            ;; strip off trailing group-comment
-           (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" type)
-           (setq type (substring type 0 (match-end 1)))
+            (when (string-match "\\S-\\s-*\\'" type)
+             (setq type (substring type 0 (1+ (match-beginning 0)))))
            ;; parse initialization expression
            (setq init nil)
            (when (vhdl-parse-string ":=[ \t\n\r\f]*" t)
@@ -12621,8 +12621,9 @@ reflected in a subsequent paste operation."
                (setq return-comment (substring return-type (match-beginning 
2)))
                (setq return-type (substring return-type 0 (match-beginning 
1))))
              ;; strip of trailing group-comment
-             (string-match "\\(\\(\\s-*\\S-+\\)+\\)\\s-*" return-type)
-             (setq return-type (substring return-type 0 (match-end 1)))
+              (when (string-match "\\S-\\s-*\\'" return-type)
+               (setq return-type
+                      (substring return-type 0 (1+ (match-beginning 0)))))
              ;; parse return comment
              (unless return-comment
                (setq return-comment (and (vhdl-parse-string 
"--\\s-*\\([^\n]*\\)" t)
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 09d0250515f..0e04bab6ea4 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -208,21 +208,28 @@ non-nil.")
 (add-hook 'after-change-major-mode-hook #'which-func-ff-hook t)
 
 (defun which-func-try-to-enable ()
-  (unless (or (not which-function-mode)
-              (local-variable-p 'which-func-mode))
-    (setq which-func-mode (or (eq which-func-modes t)
-                              (member major-mode which-func-modes)))
-    (setq which-func--use-mode-line
-          (member which-func-display '(mode mode-and-header)))
-    (setq which-func--use-header-line
-          (member which-func-display '(header mode-and-header)))
-    (when (and which-func-mode which-func--use-header-line)
+  (when which-function-mode
+    (unless (local-variable-p 'which-func-mode)
+      (setq which-func-mode (or (eq which-func-modes t)
+                                (member major-mode which-func-modes)))
+      (setq which-func--use-mode-line
+            (member which-func-display '(mode mode-and-header)))
+      (setq which-func--use-header-line
+            (member which-func-display '(header mode-and-header))))
+    ;; We might need to re-add which-func-format to the header line,
+    ;; if which-function-mode was toggled off and on.
+    (when (and which-func-mode which-func--use-header-line
+               (listp header-line-format))
       (add-to-list 'header-line-format '("" which-func-format " ")))))
 
-(defun which-func--disable ()
-  (when (and which-func-mode which-func--use-header-line)
+(defun which-func--header-line-remove ()
+  (when (and which-func-mode which-func--use-header-line
+             (listp header-line-format))
     (setq header-line-format
-          (delete '("" which-func-format " ") header-line-format)))
+          (delete '("" which-func-format " ") header-line-format))))
+
+(defun which-func--disable ()
+  (which-func--header-line-remove)
   (setq which-func-mode nil))
 
 (defun which-func-ff-hook ()
@@ -288,9 +295,11 @@ in certain major modes."
   (when which-function-mode
     ;;Turn it on.
     (setq which-func-update-timer
-          (run-with-idle-timer idle-update-delay t #'which-func-update))
-    (dolist (buf (buffer-list))
-      (with-current-buffer buf (which-func-try-to-enable)))))
+          (run-with-idle-timer idle-update-delay t #'which-func-update)))
+  (dolist (buf (buffer-list))
+    (with-current-buffer buf
+      (which-func--header-line-remove)
+      (which-func-ff-hook))))
 
 (defvar which-function-imenu-failed nil
   "Locally t in a buffer if `imenu--make-index-alist' found nothing there.")
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index fd788ec8f32..81618428bf3 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -281,9 +281,10 @@ current project's main and external roots."
          (xref-references-in-directory identifier dir)
        (message "Searching %s... done" dir)))
    (let ((pr (project-current t)))
-     (cons
-      (xref--project-root pr)
-      (project-external-roots pr)))))
+     (project-combine-directories
+      (cons
+       (xref--project-root pr)
+       (project-external-roots pr))))))
 
 (cl-defgeneric xref-backend-apropos (backend pattern)
   "Find all symbols that match PATTERN string.
diff --git a/lisp/select.el b/lisp/select.el
index 09c678867d0..f62f7b07239 100644
--- a/lisp/select.el
+++ b/lisp/select.el
@@ -49,27 +49,28 @@ the current system default encoding on 9x/Me, `utf-16le-dos'
 \(Unicode) on NT/W2K/XP, and `iso-latin-1-dos' on MS-DOS.
 
 For X Windows:
-When sending text via selection and clipboard, if the target
-data-type matches this coding system according to the table
-below, it is used for encoding the text.  Otherwise (including
-the case that this variable is nil), a proper coding system is
-selected as below:
-
-data-type      coding system
----------      -------------
-UTF8_STRING    utf-8
-COMPOUND_TEXT  compound-text-with-extensions
-STRING         iso-latin-1
-C_STRING       raw-text-unix
-
-When receiving text, if this coding system is non-nil, it is used
-for decoding regardless of the data-type.  If this is nil, a
-proper coding system is used according to the data-type as above.
 
-See also the documentation of the variable `x-select-request-type' how
-to control which data-type to request for receiving text.
+This coding system replaces that of the default coding system
+selection text is encoded by in reaction to a request for the
+polymorphic `TEXT' selection target when its base coding system
+is compatible with `compound-text' and the text being encoded
+cannot be rendered Latin-1 without loss of information.
+
+It also replaces the coding system by which calls to
+`gui-get-selection' decode selection requests for text data
+types, which are enumerated below beside their respective coding
+systems otherwise used.
+
+DATA TYPE                      CODING SYSTEM
+--------------------------     -------------
+UTF8_STRING                    utf-8
+text/plain\\;charset=utf-8     utf-8
+COMPOUND_TEXT                  compound-text-with-extensions
+STRING                         iso-latin-1
+C_STRING                       raw-text-unix
 
-The default value is nil."
+See also the documentation of the variable `x-select-request-type' how
+to control which data-type to request for receiving text."
   :type 'coding-system
   :group 'mule
   ;; Default was compound-text-with-extensions in 22.x (pre-unicode).
diff --git a/lisp/server.el b/lisp/server.el
index ce68e9aebc9..a2671165bfc 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1199,6 +1199,7 @@ The following commands are accepted by the client:
                parent-id  ; Window ID for XEmbed
                dontkill   ; t if client should not be killed.
                commands
+               evalexprs
                dir
                use-current-frame
                frame-parameters  ;parameters for newly created frame
@@ -1332,8 +1333,7 @@ The following commands are accepted by the client:
                  (let ((expr (pop args-left)))
                    (if coding-system
                        (setq expr (decode-coding-string expr coding-system)))
-                   (push (lambda () (server-eval-and-print expr proc))
-                         commands)
+                   (push expr evalexprs)
                    (setq filepos nil)))
 
                 ;; -env NAME=VALUE:  An environment variable.
@@ -1358,7 +1358,7 @@ The following commands are accepted by the client:
            ;; arguments, use an existing frame.
            (and nowait
                 (not (eq tty-name 'window-system))
-                (or files commands)
+                (or files commands evalexprs)
                 (setq use-current-frame t))
 
            (setq frame
@@ -1407,7 +1407,7 @@ The following commands are accepted by the client:
                  (let ((default-directory
                          (if (and dir (file-directory-p dir))
                              dir default-directory)))
-                   (server-execute proc files nowait commands
+                   (server-execute proc files nowait commands evalexprs
                                    dontkill frame tty-name)))))
 
             (when (or frame files)
@@ -1417,22 +1417,35 @@ The following commands are accepted by the client:
     ;; condition-case
     (t (server-return-error proc err))))
 
-(defun server-execute (proc files nowait commands dontkill frame tty-name)
+(defvar server-eval-args-left nil
+  "List of eval args not yet processed.
+
+Adding or removing strings from this variable while the Emacs
+server is processing a series of eval requests will affect what
+Emacs evaluates.
+
+See also `argv' for a similar variable which works for
+invocations of \"emacs\".")
+
+(defun server-execute (proc files nowait commands evalexprs dontkill frame 
tty-name)
   ;; This is run from timers and process-filters, i.e. "asynchronously".
   ;; But w.r.t the user, this is not really asynchronous since the timer
   ;; is run after 0s and the process-filter is run in response to the
   ;; user running `emacsclient'.  So it is OK to override the
-  ;; inhibit-quit flag, which is good since `commands' (as well as
+  ;; inhibit-quit flag, which is good since `evalexprs' (as well as
   ;; find-file-noselect via the major-mode) can run arbitrary code,
   ;; including code that needs to wait.
   (with-local-quit
     (condition-case err
         (let ((buffers (server-visit-files files proc nowait)))
           (mapc 'funcall (nreverse commands))
+          (let ((server-eval-args-left (nreverse evalexprs)))
+            (while server-eval-args-left
+              (server-eval-and-print (pop server-eval-args-left) proc)))
          ;; If we were told only to open a new client, obey
          ;; `initial-buffer-choice' if it specifies a file
           ;; or a function.
-          (unless (or files commands)
+          (unless (or files commands evalexprs)
             (let ((buf
                    (cond ((stringp initial-buffer-choice)
                          (find-file-noselect initial-buffer-choice))
diff --git a/lisp/so-long.el b/lisp/so-long.el
index b93b047ce55..b7cfce31173 100644
--- a/lisp/so-long.el
+++ b/lisp/so-long.el
@@ -310,7 +310,7 @@
 ;; possibly also `so-long-max-lines' and `so-long-skip-leading-comments' (these
 ;; latter two are not used by default starting from Emacs 28.1).  E.g.:
 ;;
-;;   (add-hook 'js-mode-hook 'my-js-mode-hook)
+;;   (add-hook 'js-mode-hook #'my-js-mode-hook)
 ;;
 ;;   (defun my-js-mode-hook ()
 ;;     "Custom `js-mode' behaviors."
@@ -324,7 +324,7 @@
 ;; set `bidi-inhibit-bpa' in XML files, on the basis that XML files with long
 ;; lines are less likely to trigger BPA-related performance problems:
 ;;
-;;   (add-hook 'nxml-mode-hook 'my-nxml-mode-hook)
+;;   (add-hook 'nxml-mode-hook #'my-nxml-mode-hook)
 ;;
 ;;   (defun my-nxml-mode-hook ()
 ;;     "Custom `nxml-mode' behaviors."
@@ -366,7 +366,7 @@
 ;; variable.  Refer to M-: (info "(emacs) Specifying File Variables") RET
 ;;
 ;; `so-long-minor-mode' can also be called directly if desired.  e.g.:
-;; (add-hook 'FOO-mode-hook 'so-long-minor-mode)
+;; (add-hook 'FOO-mode-hook #'so-long-minor-mode)
 ;;
 ;; In Emacs 26.1 or later (see "Caveats" below) you also have the option of
 ;; using file-local and directory-local variables to determine how `so-long'
@@ -1320,8 +1320,8 @@ This minor mode is a standard `so-long-action' option."
           (so-long--ensure-enabled)
           (setq so-long--active t
                 so-long-detected-p t
-                so-long-function 'turn-on-so-long-minor-mode
-                so-long-revert-function 'turn-off-so-long-minor-mode)
+                so-long-function #'turn-on-so-long-minor-mode
+                so-long-revert-function #'turn-off-so-long-minor-mode)
           (so-long-remember-all :reset)
           (unless (derived-mode-p 'so-long-mode)
             (setq so-long-mode-line-info (so-long-mode-line-info))))
@@ -1345,7 +1345,7 @@ This minor mode is a standard `so-long-action' option."
 
 (defvar so-long-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "C-c C-c") 'so-long-revert)
+    (define-key map (kbd "C-c C-c") #'so-long-revert)
     ;; Define the major mode menu.  We have an awkward issue whereby
     ;; [menu-bar so-long] is already defined in the global map and is
     ;; :visible so-long-detected-p, but we also want this to be
@@ -1396,12 +1396,12 @@ configure the behavior."
     (so-long--ensure-enabled)
     (setq so-long--active t
           so-long-detected-p t
-          so-long-function 'so-long-mode
-          so-long-revert-function 'so-long-mode-revert))
+          so-long-function #'so-long-mode
+          so-long-revert-function #'so-long-mode-revert))
   ;; Use `after-change-major-mode-hook' to disable minor modes and override
   ;; variables.  Append, to act after any globalized modes have acted.
   (add-hook 'after-change-major-mode-hook
-            'so-long-after-change-major-mode :append :local)
+            #'so-long-after-change-major-mode :append :local)
   ;; Override variables.  This is the first of two instances where we do this
   ;; (the other being `so-long-after-change-major-mode').  It is desirable to
   ;; set variables here in order to cover cases where the setting of a variable
@@ -1591,8 +1591,8 @@ because we do not want to downgrade the major mode in 
that scenario."
     (when (and (symbolp (so-long-function))
                (provided-mode-derived-p (so-long-function) 'so-long-mode))
       ;; Downgrade from `so-long-mode' to the `so-long-minor-mode' behavior.
-      (setq so-long-function 'turn-on-so-long-minor-mode
-            so-long-revert-function 'turn-off-so-long-minor-mode))))
+      (setq so-long-function #'turn-on-so-long-minor-mode
+            so-long-revert-function #'turn-off-so-long-minor-mode))))
 
 (defun so-long-inhibit (&optional _mode)
   "Prevent `global-so-long-mode' from having any effect.
@@ -1897,7 +1897,6 @@ Use \\[so-long-commentary] for more information.
 Use \\[so-long-customize] to open the customization group `so-long' to
 configure the behavior."
   :global t
-  :group 'so-long
   (if global-so-long-mode
       ;; Enable
       (progn
@@ -2030,7 +2029,7 @@ If it appears in `%s', you should remove it."
   ;; Update to version 1.0 from earlier versions:
   (when (version< so-long-version "1.0")
     (remove-hook 'change-major-mode-hook 'so-long-change-major-mode)
-    (eval-and-compile (require 'advice)) ;; Both macros and functions.
+    (require 'advice) ;; It should already be loaded, but just in case.
     (declare-function ad-find-advice "advice")
     (declare-function ad-remove-advice "advice")
     (declare-function ad-activate "advice")
diff --git a/lisp/speedbar.el b/lisp/speedbar.el
index 67d4e8c4df1..51c5962cb66 100644
--- a/lisp/speedbar.el
+++ b/lisp/speedbar.el
@@ -631,7 +631,7 @@ function `speedbar-extension-list-to-regex'.")
   (append '(".[ch]\\(\\+\\+\\|pp\\|c\\|h\\|xx\\)?" ".tex\\(i\\(nfo\\)?\\)?"
            ".el" ".emacs" ".l" ".lsp" ".p" ".java" ".js" 
".f\\(90\\|77\\|or\\)?")
          (if speedbar-use-imenu-flag
-             '(".ad[abs]" ".p[lm]" ".tcl" ".m" ".scm" ".pm" ".py" ".g"
+             '(".ad[abs]" ".p[lm]" ".tcl" ".m" ".scm" ".pm" ".py" ".g" ".lua"
                ;; html is not supported by default, but an imenu tags package
                ;; is available.  Also, html files are nice to be able to see.
                ".s?html"
diff --git a/lisp/sqlite-mode.el b/lisp/sqlite-mode.el
index 38e9f84b842..120967a725f 100644
--- a/lisp/sqlite-mode.el
+++ b/lisp/sqlite-mode.el
@@ -33,6 +33,7 @@
 (declare-function sqlite-finalize "sqlite.c")
 (declare-function sqlite-select "sqlite.c")
 (declare-function sqlite-open "sqlite.c")
+(declare-function sqlite-close "sqlite.c")
 
 (defvar-keymap sqlite-mode-map
   "g" #'sqlite-mode-list-tables
diff --git a/lisp/startup.el b/lisp/startup.el
index 6329e3ea8d0..37843eab176 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -120,7 +120,10 @@ the remaining command-line args are in the variable 
`command-line-args-left'.")
     "List of command-line args not yet processed.
 This is a convenience alias, so that one can write (pop argv)
 inside of --eval command line arguments in order to access
-following arguments."))
+following arguments.
+
+See also `server-eval-args-left' for a similar variable which
+works for invocations of \"emacsclient --eval\"."))
 (internal-make-var-non-special 'argv)
 
 (defvar command-line-args-left nil
diff --git a/lisp/subr.el b/lisp/subr.el
index 58274987d71..d4173b4daba 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1959,6 +1959,7 @@ be a list of the form returned by `event-start' and 
`event-end'."
 (set-advertised-calling-convention 'redirect-frame-focus '(frame focus-frame) 
"24.3")
 (set-advertised-calling-convention 'libxml-parse-xml-region '(&optional start 
end base-url) "27.1")
 (set-advertised-calling-convention 'libxml-parse-html-region '(&optional start 
end base-url) "27.1")
+(set-advertised-calling-convention 'sleep-for '(seconds) "30.1")
 (set-advertised-calling-convention 'time-convert '(time form) "29.1")
 
 ;;;; Obsolescence declarations for variables, and aliases.
@@ -2681,17 +2682,15 @@ The variable list SPEC is the same as in `if-let*'."
   "Non-nil if MODE is derived from one of MODES.
 Uses the `derived-mode-parent' property of the symbol to trace backwards.
 If you just want to check `major-mode', use `derived-mode-p'."
-  ;; If MODE is an alias, then look up the real mode function first.
   (declare (side-effect-free t))
-  (when-let ((alias (symbol-function mode)))
-    (when (symbolp alias)
-      (setq mode alias)))
   (while
       (and
        (not (memq mode modes))
-       (let* ((parent (get mode 'derived-mode-parent))
-              (parentfn (symbol-function parent)))
-         (setq mode (if (and parentfn (symbolp parentfn)) parentfn parent)))))
+       (let* ((parent (get mode 'derived-mode-parent)))
+        (setq mode (or parent
+                       ;; If MODE is an alias, then follow the alias.
+                       (let ((alias (symbol-function mode)))
+                         (and (symbolp alias) alias)))))))
   mode)
 
 (defun derived-mode-p (&rest modes)
@@ -7277,13 +7276,15 @@ lines."
             (setq start (length string)))))
       (nreverse lines))))
 
-(defun buffer-match-p (condition buffer-or-name &optional arg)
+(defvar buffer-match-p--past-warnings nil)
+
+(defun buffer-match-p (condition buffer-or-name &rest args)
   "Return non-nil if BUFFER-OR-NAME matches CONDITION.
 CONDITION is either:
 - the symbol t, to always match,
 - the symbol nil, which never matches,
 - a regular expression, to match a buffer name,
-- a predicate function that takes BUFFER-OR-NAME and ARG as
+- a predicate function that takes BUFFER-OR-NAME plus ARGS as
   arguments, and returns non-nil if the buffer matches,
 - a cons-cell, where the car describes how to interpret the cdr.
   The car can be one of the following:
@@ -7308,9 +7309,18 @@ CONDITION is either:
                       ((pred stringp)
                        (string-match-p condition (buffer-name buffer)))
                       ((pred functionp)
-                       (if (eq 1 (cdr (func-arity condition)))
-                           (funcall condition buffer-or-name)
-                         (funcall condition buffer-or-name arg)))
+                       (if (cdr args)
+                           ;; New in Emacs>29.1. no need for compatibility 
hack.
+                           (apply condition buffer-or-name args)
+                         (condition-case-unless-debug err
+                             (apply condition buffer-or-name args)
+                           (wrong-number-of-arguments
+                            (unless (member condition
+                                            buffer-match-p--past-warnings)
+                              (message "%s" (error-message-string err))
+                              (push condition buffer-match-p--past-warnings))
+                            (apply condition buffer-or-name
+                                   (if args nil '(nil)))))))
                       (`(major-mode . ,mode)
                        (eq
                         (buffer-local-value 'major-mode buffer)
@@ -7332,17 +7342,17 @@ CONDITION is either:
                 (throw 'match t)))))))
     (funcall match (list condition))))
 
-(defun match-buffers (condition &optional buffers arg)
+(defun match-buffers (condition &optional buffers &rest args)
   "Return a list of buffers that match CONDITION, or nil if none match.
 See `buffer-match-p' for various supported CONDITIONs.
 By default all buffers are checked, but the optional
 argument BUFFERS can restrict that: its value should be
 an explicit list of buffers to check.
-Optional argument ARG is passed to `buffer-match-p', for
+Optional arguments ARGS are passed to `buffer-match-p', for
 predicate conditions in CONDITION."
   (let (bufs)
     (dolist (buf (or buffers (buffer-list)))
-      (when (buffer-match-p condition (get-buffer buf) arg)
+      (when (apply #'buffer-match-p condition (get-buffer buf) args)
         (push buf bufs)))
     bufs))
 
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index d2815c03ebf..e21367255a0 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -1227,7 +1227,9 @@ tab bar might wrap to the second line when it shouldn't.")
                    ((< prev-width width)
                     (let* ((space (apply #'propertize " "
                                          (text-properties-at 0 name)))
-                           (ins-pos (- len (if close-p 1 0)))
+                           (ins-pos (- len (if close-p
+                                               (length tab-bar-close-button)
+                                             0)))
                            (prev-name name))
                       (while continue
                         (setq name (concat (substring name 0 ins-pos)
diff --git a/lisp/term/android-win.el b/lisp/term/android-win.el
index f3f5c227df0..960dfdcb4a6 100644
--- a/lisp/term/android-win.el
+++ b/lisp/term/android-win.el
@@ -272,6 +272,7 @@ content:// URIs into the special file names which represent 
them."
           ((eq (car message) 'uri)
            (let ((uri-list (split-string (cdr message)
                                          "[\0\r\n]" t))
+                 (new-uri-list nil)
                  (dnd-unescape-file-uris t))
              (dolist (uri uri-list)
                (ignore-errors
@@ -286,7 +287,10 @@ content:// URIs into the special file names which 
represent them."
                            ;; subject to URI decoding, for it must be
                            ;; transformed back into a content URI.
                            dnd-unescape-file-uris nil))))
-               (dnd-handle-one-url (posn-window posn) 'copy uri)))))))
+               (push uri new-uri-list))
+             (dnd-handle-multiple-urls (posn-window posn)
+                                       new-uri-list
+                                       'copy))))))
 
 (define-key special-event-map [drag-n-drop] 'android-handle-dnd-event)
 
diff --git a/lisp/term/haiku-win.el b/lisp/term/haiku-win.el
index 50c9cb5b9d4..f53cf7939b9 100644
--- a/lisp/term/haiku-win.el
+++ b/lisp/term/haiku-win.el
@@ -369,14 +369,15 @@ or a pair of markers) and turns it into a file system 
reference."
          ((posn-area (event-start event)))
          ((assoc "refs" string)
           (with-selected-window window
-            (dolist (filename (cddr (assoc "refs" string)))
-              (dnd-handle-one-url window action
-                                  (concat "file:" filename)))))
+            (dnd-handle-multiple-urls
+             window (mapcar
+                     (lambda (name) (concat "file:" name))
+                     (cddr (assoc "refs" string)))
+             action)))
          ((assoc "text/uri-list" string)
           (dolist (text (cddr (assoc "text/uri-list" string)))
             (let ((uri-list (split-string text "[\0\r\n]" t)))
-              (dolist (bf uri-list)
-                (dnd-handle-one-url window action bf)))))
+              (dnd-handle-multiple-urls window uri-list action))))
          ((assoc "text/plain" string)
           (with-selected-window window
             (dolist (text (cddr (assoc "text/plain" string)))
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 7525b9321ca..e40a0ce3e96 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -520,11 +520,12 @@ string dropped into the current buffer."
       (goto-char (posn-point (event-start event)))
       (cond ((or (memq 'ns-drag-operation-generic operations)
                  (memq 'ns-drag-operation-copy operations))
-             ;; Perform the default/copy action.
-             (dolist (data objects)
-               (dnd-handle-one-url window 'private (if (eq type 'file)
-                                                       (concat "file:" data)
-                                                     data))))
+             (let ((urls (if (eq type 'file) (mapcar
+                                              (lambda (file)
+                                                (concat "file:" file))
+                                              objects)
+                           objects)))
+               (dnd-handle-multiple-urls window urls 'private)))
             (t
              ;; Insert the text as is.
              (dnd-insert-text window 'private string))))))
diff --git a/lisp/term/pgtk-win.el b/lisp/term/pgtk-win.el
index f2552d3b057..ef854a28278 100644
--- a/lisp/term/pgtk-win.el
+++ b/lisp/term/pgtk-win.el
@@ -48,45 +48,6 @@
 
 (declare-function pgtk-use-im-context "pgtkim.c")
 
-(defun pgtk-drag-n-drop (event &optional new-frame force-text)
-  "Edit the files listed in the drag-n-drop EVENT.
-Switch to a buffer editing the last file dropped."
-  (interactive "e")
-  (let* ((window (posn-window (event-start event)))
-         (arg (car (cdr (cdr event))))
-         (type (car arg))
-         (data (car (cdr arg)))
-         (url-or-string (cond ((eq type 'file)
-                               (concat "file:" data))
-                              (t data))))
-    (set-frame-selected-window nil window)
-    (when new-frame
-      (select-frame (make-frame)))
-    (raise-frame)
-    (setq window (selected-window))
-    (if force-text
-        (dnd-insert-text window 'private data)
-      (dnd-handle-one-url window 'private url-or-string))))
-
-(defun pgtk-drag-n-drop-other-frame (event)
-  "Edit the files listed in the drag-n-drop EVENT, in other frames.
-May create new frames, or reuse existing ones.  The frame editing
-the last file dropped is selected."
-  (interactive "e")
-  (pgtk-drag-n-drop event t))
-
-(defun pgtk-drag-n-drop-as-text (event)
-  "Drop the data in EVENT as text."
-  (interactive "e")
-  (pgtk-drag-n-drop event nil t))
-
-(defun pgtk-drag-n-drop-as-text-other-frame (event)
-  "Drop the data in EVENT as text in a new frame."
-  (interactive "e")
-  (pgtk-drag-n-drop event t t))
-
-(global-set-key [drag-n-drop] 'pgtk-drag-n-drop)
-
 (defun pgtk-suspend-error ()
   "Don't allow suspending if any of the frames are PGTK frames."
   (if (memq 'pgtk (mapcar 'window-system (frame-list)))
@@ -392,7 +353,6 @@ Users should not call this function; see `device-class' 
instead."
 
 (defvaralias 'x-gtk-use-system-tooltips 'use-system-tooltips)
 
-
 (define-key special-event-map [drag-n-drop] 
#'pgtk-dnd-handle-drag-n-drop-event)
 (add-hook 'after-make-frame-functions #'pgtk-dnd-init-frame)
 
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index c9e25f4f83d..4f1fd475392 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -117,12 +117,14 @@
                      (split-string (encode-coding-string f coding)
                                    "/")
                      "/")))
-               (dnd-handle-one-url window 'private
-                                   (concat
-                                    (if (eq system-type 'cygwin)
-                                        "file://"
-                                      "file:")
-                                    file-name)))
+  ;; FIXME: is the W32 build capable only of receiving a single file
+  ;; from each drop?
+  (dnd-handle-multiple-urls window (list (concat
+                                         (if (eq system-type 'cygwin)
+                                             "file://"
+                                           "file:")
+                                         file-name))
+                            'private))
 
 (defun w32-drag-n-drop (event &optional new-frame)
   "Edit the files listed in the drag-n-drop EVENT.
diff --git a/lisp/term/xterm.el b/lisp/term/xterm.el
index 295ef2b3f4c..5ed4e46e0a5 100644
--- a/lisp/term/xterm.el
+++ b/lisp/term/xterm.el
@@ -725,7 +725,7 @@ Return the pasted text as a string."
         ;; `tty-set-up-initial-frame-faces' only once, but that
         ;; caused the light background faces to be computed
         ;; incorrectly.  See:
-        ;; http://permalink.gmane.org/gmane.emacs.devel/119627
+        ;; https://lists.gnu.org/r/emacs-devel/2010-01/msg00439.html
         (when recompute-faces
           (tty-set-up-initial-frame-faces))))))
 
diff --git a/lisp/textmodes/dns-mode.el b/lisp/textmodes/dns-mode.el
index 1b5f0c1d94b..bc3fa8d8e3a 100644
--- a/lisp/textmodes/dns-mode.el
+++ b/lisp/textmodes/dns-mode.el
@@ -132,6 +132,7 @@ manually with \\[dns-mode-soa-increment-serial]."
     (modify-syntax-entry ?\; "<   " table)
     (modify-syntax-entry ?\n ">   " table)
     (modify-syntax-entry ?\" "\""   table)
+    (modify-syntax-entry ?\\ "\\"   table)
     table)
   "Syntax table in use in DNS master file buffers.")
 
diff --git a/lisp/textmodes/fill.el b/lisp/textmodes/fill.el
index 2fde2ff6c4d..4d6c73bfdd6 100644
--- a/lisp/textmodes/fill.el
+++ b/lisp/textmodes/fill.el
@@ -103,7 +103,7 @@ reinserts the fill prefix in each resulting line."
   ;; Added `%' for TeX comments.
   ;; RMS: deleted the code to match `1.' and `(1)'.
   ;; Update mail-mode's paragraph-separate if you change this.
-  (purecopy "[ \t]*\\([-–!|#%;>*·•‣⁃◦]+[ \t]*\\)*")
+  (purecopy "[-–!|#%;>*·•‣⁃◦ \t]*")
   "Regexp to match text at start of line that constitutes indentation.
 If Adaptive Fill mode is enabled, a prefix matching this pattern
 on the first and second lines of a paragraph is used as the
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index 72acb0b749f..5d4f4df9131 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -565,9 +565,9 @@ looks like an email address, \"ftp://\"; if it starts with
         ;; If it looks like ftp.example.com. treat it as ftp.
         (if (string-match "\\`ftp\\." str)
             (setq str (concat "ftp://"; str)))
-        ;; If it looks like www.example.com. treat it as http.
+         ;; If it looks like www.example.com. treat it as https.
         (if (string-match "\\`www\\." str)
-            (setq str (concat "http://"; str)))
+             (setq str (concat "https://"; str)))
         ;; Otherwise, it just isn't a URI.
         (setq str nil)))
       str)))
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el
index 2621aebf037..ea1e27a263b 100644
--- a/lisp/touch-screen.el
+++ b/lisp/touch-screen.el
@@ -58,25 +58,30 @@ This is always cleared upon any significant state change.")
 If non-nil, the touch screen key event translation machinery
 is being called from `read-sequence' or some similar function.")
 
+(defgroup touch-screen nil
+  "Interact with Emacs from touch screen devices."
+  :group 'mouse
+  :version "30.0")
+
 (defcustom touch-screen-display-keyboard nil
   "If non-nil, always display the on screen keyboard.
 A buffer local value means to always display the on screen
 keyboard when the buffer is selected."
   :type 'boolean
-  :group 'mouse
+  :group 'touch-screen
   :version "30.1")
 
 (defcustom touch-screen-delay 0.7
   "Delay in seconds before Emacs considers a touch to be a long-press."
   :type 'number
-  :group 'mouse
+  :group 'touch-screen
   :version "30.1")
 
 (defcustom touch-screen-precision-scroll nil
   "Whether or not to use precision scrolling for touch screens.
 See `pixel-scroll-precision-mode' for more details."
   :type 'boolean
-  :group 'mouse
+  :group 'touch-screen
   :version "30.1")
 
 (defcustom touch-screen-word-select nil
@@ -84,7 +89,7 @@ See `pixel-scroll-precision-mode' for more details."
 If non-nil, long-press events (see `touch-screen-delay') followed
 by dragging will try to select entire words."
   :type 'boolean
-  :group 'mouse
+  :group 'touch-screen
   :version "30.1")
 
 (defcustom touch-screen-extend-selection nil
@@ -93,7 +98,7 @@ When enabled, tapping on the character containing the point or
 mark will resume dragging where it left off while the region is
 active."
   :type 'boolean
-  :group 'mouse
+  :group 'touch-screen
   :version "30.1")
 
 (defcustom touch-screen-preview-select nil
@@ -102,7 +107,15 @@ When enabled, a preview of the visible line within the 
window
 will be displayed in the echo area while dragging combined with
 an indication of the position of point within that line."
   :type 'boolean
-  :group 'mouse
+  :group 'touch-screen
+  :version "30.1")
+
+(defcustom touch-screen-enable-hscroll t
+  "If non-nil, hscroll can be changed from the touch screen.
+When enabled, tapping on a window and dragging your finger left
+or right will scroll that window horizontally."
+  :type 'boolean
+  :group 'touch-screen
   :version "30.1")
 
 (defvar-local touch-screen-word-select-bounds nil
@@ -229,7 +242,12 @@ horizontal scrolling according to the movement in DX."
                             (>= (- accumulator) column-width))
                        (progn
                          (setq accumulator (+ accumulator column-width))
-                         (scroll-right 1)
+                         ;; Maintain both hscroll counters even when
+                         ;; it's disabled to prevent unintentional or
+                         ;; patently horizontal gestures from
+                         ;; scrolling the window vertically.
+                         (when touch-screen-enable-hscroll
+                           (scroll-right 1))
                          (setq lines-hscrolled (1+ lines-hscrolled))
                          (when (not (zerop accumulator))
                            ;; If there is still an outstanding amount
@@ -238,7 +256,8 @@ horizontal scrolling according to the movement in DX."
                      (when (and (> accumulator 0)
                                 (>= accumulator column-width))
                        (setq accumulator (- accumulator column-width))
-                       (scroll-left 1)
+                       (when touch-screen-enable-hscroll
+                         (scroll-left 1))
                        (setq lines-hscrolled (1+ lines-hscrolled))
                        (when (not (zerop accumulator))
                          ;; If there is still an outstanding amount to
diff --git a/lisp/treesit.el b/lisp/treesit.el
index c73ac9912d6..3555396390d 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -32,9 +32,8 @@
 
 ;;; Code:
 
-(eval-when-compile (require 'cl-lib))
 (eval-when-compile (require 'subr-x)) ; For `string-join'.
-(require 'cl-seq)
+(require 'cl-lib)
 (require 'font-lock)
 (require 'seq)
 
@@ -893,6 +892,8 @@ Other keywords include:
              `append'   Append the new face to existing ones.
              `prepend'  Prepend the new face to existing ones.
              `keep'     Fill-in regions without an existing face.
+  :default-language  LANGUAGE  Every QUERY after this keyword
+                               will use LANGUAGE by default.
 
 Capture names in QUERY should be face names like
 `font-lock-keyword-face'.  The captured node will be fontified
@@ -922,12 +923,22 @@ name, it is ignored."
           ;; that following queries will apply to.
           current-language current-override
           current-feature
+          ;; DEFAULT-LANGUAGE will be chosen when current-language is
+          ;; not set.
+          default-language
           ;; The list this function returns.
           (result nil))
       (while query-specs
         (let ((token (pop query-specs)))
           (pcase token
             ;; (1) Process keywords.
+            (:default-language
+             (let ((lang (pop query-specs)))
+               (when (or (not (symbolp lang)) (null lang))
+                 (signal 'treesit-font-lock-error
+                         `("Value of :default-language should be a symbol"
+                           ,lang)))
+               (setq default-language lang)))
             (:language
              (let ((lang (pop query-specs)))
                (when (or (not (symbolp lang)) (null lang))
@@ -955,23 +966,24 @@ name, it is ignored."
                (setq current-feature var)))
             ;; (2) Process query.
             ((pred treesit-query-p)
-             (when (null current-language)
-               (signal 'treesit-font-lock-error
-                       `("Language unspecified, use :language keyword to 
specify a language for this query" ,token)))
-             (when (null current-feature)
-               (signal 'treesit-font-lock-error
-                       `("Feature unspecified, use :feature keyword to specify 
the feature name for this query" ,token)))
-             (if (treesit-compiled-query-p token)
-                 (push `(,current-language token) result)
-               (push `(,(treesit-query-compile current-language token)
-                       t
-                       ,current-feature
-                       ,current-override)
-                     result))
-             ;; Clears any configurations set for this query.
-             (setq current-language nil
-                   current-override nil
-                   current-feature nil))
+             (let ((lang (or default-language current-language)))
+               (when (null lang)
+                 (signal 'treesit-font-lock-error
+                         `("Language unspecified, use :language keyword or 
:default-language to specify a language for this query" ,token)))
+               (when (null current-feature)
+                 (signal 'treesit-font-lock-error
+                         `("Feature unspecified, use :feature keyword to 
specify the feature name for this query" ,token)))
+               (if (treesit-compiled-query-p token)
+                   (push `(,lang token) result)
+                 (push `(,(treesit-query-compile lang token)
+                         t
+                         ,current-feature
+                         ,current-override)
+                       result))
+               ;; Clears any configurations set for this query.
+               (setq current-language nil
+                     current-override nil
+                     current-feature nil)))
             (_ (signal 'treesit-font-lock-error
                        `("Unexpected value" ,token))))))
       (nreverse result))))
@@ -1413,8 +1425,10 @@ See `treesit-simple-indent-presets'.")
 
                     (goto-char bol)
                     (setq this-line-has-prefix
-                          (and (looking-at adaptive-fill-regexp)
-                               (match-string 1)))
+                          (and (looking-at-p adaptive-fill-regexp)
+                               (not (string-match-p
+                                     (rx bos (* whitespace) eos)
+                                     (match-string 0)))))
 
                     (forward-line -1)
                     (and (>= (point) comment-start-bol)
@@ -1422,7 +1436,7 @@ See `treesit-simple-indent-presets'.")
                          (looking-at adaptive-fill-regexp)
                          ;; If previous line is an empty line, don't
                          ;; indent.
-                         (not (looking-at (rx (* whitespace) eol)))
+                         (not (looking-at-p (rx (* whitespace) eol)))
                          ;; Return the anchor.  If the indenting line
                          ;; has a prefix and the previous line also
                          ;; has a prefix, indent to the beginning of
@@ -2132,7 +2146,7 @@ If LANGUAGE is nil, return the first definition for THING 
in
                                     (copy-tree (cdr entry)))
                                   treesit-thing-settings)))))
 
-(defalias 'treesit-thing-defined-p 'treesit-thing-definition
+(defalias 'treesit-thing-defined-p #'treesit-thing-definition
   "Return non-nil if THING is defined.")
 
 (defun treesit-beginning-of-thing (thing &optional arg tactic)
@@ -3198,13 +3212,13 @@ window."
               (treesit--explorer-tree-mode)))
           (display-buffer treesit--explorer-buffer
                           (cons nil '((inhibit-same-window . t))))
+          (setq-local treesit--explorer-last-node nil)
           (treesit--explorer-refresh)
           ;; Set up variables and hooks.
           (add-hook 'post-command-hook
                     #'treesit--explorer-post-command 0 t)
           (add-hook 'kill-buffer-hook
                     #'treesit--explorer-kill-explorer-buffer 0 t)
-          (setq-local treesit--explorer-last-node nil)
           ;; Tell `desktop-save' to not save explorer buffers.
           (when (boundp 'desktop-modes-not-to-save)
             (unless (memq 'treesit--explorer-tree-mode
@@ -3342,7 +3356,7 @@ nil, the grammar is installed to the standard location, 
the
                           " ")))
               ;; If success, Save the recipe for the current session.
               (setf (alist-get lang treesit-language-source-alist)
-                    recipe))))
+                    (cdr recipe)))))
       (error
        (display-warning
         'treesit
diff --git a/lisp/url/url-vars.el b/lisp/url/url-vars.el
index ef4b8b2841b..630de7f4e43 100644
--- a/lisp/url/url-vars.el
+++ b/lisp/url/url-vars.el
@@ -146,7 +146,7 @@ variable."
                           (const :tag "Emacs version" :value emacs)
                           (const :tag "Last location" :value lastloc)
                           (const :tag "Browser identification" :value agent)
-                          (const :tag "No cookies" :value cookie)))
+                           (const :tag "No cookies" :value cookies)))
   :group 'url)
 
 (defcustom url-lastloc-privacy-level 'domain-match
diff --git a/lisp/vc/log-view.el b/lisp/vc/log-view.el
index e6eb6a5b973..af24fcfd398 100644
--- a/lisp/vc/log-view.el
+++ b/lisp/vc/log-view.el
@@ -163,14 +163,14 @@
      :help "Go to the previous count'th log message"]
     ["Next File"  log-view-file-next
      :help "Go to the next count'th file"
-     :active (derived-mode-p vc-cvs-log-view-mode
-                             vc-rcs-log-view-mode
-                             vc-sccs-log-view-mode)]
+     :active (derived-mode-p 'vc-cvs-log-view-mode
+                             'vc-rcs-log-view-mode
+                             'vc-sccs-log-view-mode)]
     ["Previous File"  log-view-file-prev
      :help "Go to the previous count'th file"
-     :active (derived-mode-p vc-cvs-log-view-mode
-                             vc-rcs-log-view-mode
-                             vc-sccs-log-view-mode)]))
+     :active (derived-mode-p 'vc-cvs-log-view-mode
+                             'vc-rcs-log-view-mode
+                             'vc-sccs-log-view-mode)]))
 
 (defvar log-view-mode-hook nil
   "Hook run at the end of `log-view-mode'.")
diff --git a/lisp/window.el b/lisp/window.el
index 2f9b46ebb0a..06d5cfc0077 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7468,6 +7468,64 @@ Return WINDOW if BUFFER and WINDOW are live."
 The actual non-nil value of this variable will be copied to the
 `window-dedicated-p' flag.")
 
+(defcustom toggle-window-dedicated-flag 'interactive
+  "What dedicated flag should `toggle-window-dedicated' use by default.
+
+If `toggle-window-dedicated' does not receive a flag argument,
+the value of this variable is used and passed to
+`set-window-dedicated-p'.  Setting this to t will make
+`toggle-window-dedicated' use strong dedication by default.  Any
+other non-nil value will result in the same kind of non-strong
+dedication."
+  :type '(choice (const :tag "Strongly dedicated" t)
+                 (const :tag "Dedicated" interactive))
+  :version "30.0"
+  :group 'windows)
+
+(defun toggle-window-dedicated (&optional window flag interactive)
+  "Toggle whether WINDOW is dedicated to its current buffer.
+
+WINDOW must be a live window and defaults to the selected one.
+If FLAG is t (interactively, the prefix argument), make the window
+\"strongly\" dedicated to its buffer.  FLAG defaults to a non-nil,
+non-t value, and is passed to `set-window-dedicated-p', which see.
+If INTERACTIVE is non-nil, print a message describing the dedication
+status of WINDOW, after toggling it.  Interactively, this argument is
+always non-nil.
+
+When a window is dedicated to its buffer, `display-buffer' will avoid
+displaying another buffer in it, if possible.  When a window is
+strongly dedicated to its buffer, changing the buffer shown in the
+window will usually signal an error.
+
+You can control the default of FLAG with
+`toggle-window-dedicated-flag'.  Consequently, if you set that
+variable to t, strong dedication will be used by default and
+\\[universal-argument] will make the window weakly dedicated.
+
+See the info node `(elisp)Dedicated Windows' for more details."
+  (interactive "i\nP\np")
+  (setq window (window-normalize-window window))
+  (setq flag (cond
+              ((consp flag)
+               (if (eq toggle-window-dedicated-flag t)
+                   'interactive
+                 t))
+              ((null flag) toggle-window-dedicated-flag)
+              (t flag)))
+  (if (window-dedicated-p window)
+      (set-window-dedicated-p window nil)
+    (set-window-dedicated-p window flag))
+  (when interactive
+    (message "Window is %s dedicated to buffer %s"
+             (let ((status (window-dedicated-p window)))
+               (cond
+                ((null status) "no longer")
+                ((eq status t) "now strongly")
+                (t "now")))
+             (current-buffer))
+    (force-mode-line-update)))
+
 (defconst display-buffer--action-function-custom-type
   '(choice :tag "Function"
           (const :tag "--" ignore) ; default for insertion
@@ -7535,10 +7593,8 @@ where:
   arguments: a buffer to display and an alist of the same form as
   ALIST.  See `display-buffer' for details.
 
-`display-buffer' scans this alist until it either finds a
-matching regular expression or the function specified by a
-condition returns non-nil.  In any of these cases, it adds the
-associated action to the list of actions it will try."
+`display-buffer' scans this alist until the CONDITION is satisfied
+and adds the associated ACTION to the list of actions it will try."
   :type `(alist :key-type
                (choice :tag "Condition"
                        regexp
@@ -10750,6 +10806,7 @@ Used in `repeat-mode'."
   "2" #'split-root-window-below
   "3" #'split-root-window-right
   "s" #'window-toggle-side-windows
+  "d" #'toggle-window-dedicated
   "^ f" #'tear-off-window
   "^ t" #'tab-window-detach
   "-" #'fit-window-to-buffer
diff --git a/lisp/x-dnd.el b/lisp/x-dnd.el
index b87fc97f8fd..cf7f61b39a7 100644
--- a/lisp/x-dnd.el
+++ b/lisp/x-dnd.el
@@ -369,10 +369,9 @@ WINDOW is the window where the drop happened.
 STRING is the uri-list as a string.  The URIs are separated by \\r\\n."
   (let ((uri-list (split-string string "[\0\r\n]" t))
        retval)
-    (dolist (bf uri-list)
-      ;; If one URL is handled, treat as if the whole drop succeeded.
-      (let ((did-action (dnd-handle-one-url window action bf)))
-       (when did-action (setq retval did-action))))
+    (let ((did-action (dnd-handle-multiple-urls window uri-list
+                                                action)))
+      (when did-action (setq retval did-action)))
     retval))
 
 (defun x-dnd-handle-file-name (window action string)
@@ -383,17 +382,23 @@ STRING is the file names as a string, separated by nulls."
        (coding (or file-name-coding-system
                    default-file-name-coding-system))
        retval)
-    (dolist (bf uri-list)
-      ;; If one URL is handled, treat as if the whole drop succeeded.
-      (if coding (setq bf (encode-coding-string bf coding)))
-      (let* ((file-uri (concat "file://"
-                              (mapconcat 'url-hexify-string
-                                         (split-string bf "/") "/")))
-            (did-action (dnd-handle-one-url window action file-uri)))
-       (when did-action (setq retval did-action))))
+    (let ((did-action
+           (dnd-handle-multiple-urls
+            window
+            (mapcar
+             (lambda (item)
+               (when coding
+                 (setq item (encode-coding-string item
+                                                  coding)))
+               (concat "file://"
+                       (mapconcat 'url-hexify-string
+                                  (split-string item "/")
+                                  "/")))
+             uri-list)
+            action)))
+      (when did-action (setq retval did-action)))
     retval))
 
-
 (defun x-dnd-choose-type (types &optional known-types)
   "Choose which type we want to receive for the drop.
 TYPES are the types the source of the drop offers, a vector of type names
diff --git a/nextstep/ChangeLog.1 b/nextstep/ChangeLog.1
index 26def2266fe..cd6bfbfbbbe 100644
--- a/nextstep/ChangeLog.1
+++ b/nextstep/ChangeLog.1
@@ -6,7 +6,7 @@
 
        * Makefile.in (links): New phony target to create a fake
        installation pointing back to the source tree to run GUI Emacs
-       in-place (http://article.gmane.org/gmane.emacs.devel:178330).
+       in-place (http://article.gmane.org/gmane.emacs.devel:178330). [dead 
link]
 
 2014-11-22  Glenn Morris  <rgm@gnu.org>
 
diff --git a/oldXMenu/ChangeLog.1 b/oldXMenu/ChangeLog.1
index 2de6071a33c..0e0d0ea4ce5 100644
--- a/oldXMenu/ChangeLog.1
+++ b/oldXMenu/ChangeLog.1
@@ -240,7 +240,7 @@
 
        * Relicense all FSF files to GPLv3 or later.
 
-2007-06-04  Ulrich Mueller  <ulm@gentoo.org>  (tiny change)
+2007-06-04  Ulrich Müller  <ulm@gentoo.org>  (tiny change)
 
        * ChgPane.c, ChgSel.c: Quiet --with-x-toolkit=no
        compilation warnings: #include <config.h>.
@@ -249,7 +249,7 @@
 
        * Version 22.1 released.
 
-2007-05-30  Ulrich Mueller  <ulm@gentoo.org>  (tiny change)
+2007-05-30  Ulrich Müller  <ulm@gentoo.org>  (tiny change)
 
        * XMakeAssoc.c (XMakeAssoc): Use malloc rather than xmalloc.
 
diff --git a/src/ChangeLog.11 b/src/ChangeLog.11
index bfd4fef4e80..b1e476e56fd 100644
--- a/src/ChangeLog.11
+++ b/src/ChangeLog.11
@@ -12876,7 +12876,7 @@
 
        * editfns.c (Ftranspose_regions): Doc fix (Bug#3248).
 
-2009-05-10  Ulrich Mueller  <ulm@gentoo.org>
+2009-05-10  Ulrich Müller  <ulm@gentoo.org>
 
        * s/gnu-linux.h: Make GCPROs and UNGCPRO no-ops also on SuperH.
 
@@ -12978,7 +12978,7 @@
        * process.c (create_process): Clean up merger residues of
        2008-07-17 change.
 
-2009-04-29  Ulrich Mueller  <ulm@gentoo.org>
+2009-04-29  Ulrich Müller  <ulm@gentoo.org>
 
        * lread.c (Vread_circle): New variable.
        (read1): Disable recursive read if Vread_circle is nil.
@@ -14860,7 +14860,7 @@
 
        * process.c (Fsystem_process_attributes, syms_of_process):
        Fix typo in name of Ssystem_process_attributes.
-       Reported by Ulrich Mueller <ulm@kph.uni-mainz.de>.
+       Reported by Ulrich Müller <ulm@kph.uni-mainz.de>.
 
 2008-12-11  Juanma Barranquero  <lekktu@gmail.com>
 
@@ -15356,7 +15356,7 @@
        * keyboard.c (command_loop_1): Handle NORECORD in call of
        Fselect_frame (currently ifdefd).
 
-2008-11-02  Ulrich Mueller  <ulm@kph.uni-mainz.de>
+2008-11-02  Ulrich Müller  <ulm@kph.uni-mainz.de>
 
        * emacs.c (USAGE2): Untabify.
 
@@ -15626,7 +15626,7 @@
        (Fset_window_buffer): Respect any non-nil dedicated value for
        window.  Rename "buffer" argument to "buffer_or_name".
 
-2008-10-18  Ulrich Mueller  <ulm@gentoo.org>
+2008-10-18  Ulrich Müller  <ulm@gentoo.org>
 
        * m/sh3.h: New file, machine description for SuperH.
 
@@ -23405,7 +23405,7 @@
        * Makefile.in (lisp): Add ${lispsource}language/tai-viet.el.
        (shortlisp): Add ../lisp/language/tai-viet.el.
 
-2008-02-01  Ulrich Mueller  <ulm@gentoo.org>
+2008-02-01  Ulrich Müller  <ulm@gentoo.org>
 
        * Makefile.in (${lispsource}international/charprop.el): Depend on
        temacs${EXEEXT}.
diff --git a/src/ChangeLog.4 b/src/ChangeLog.4
index 0c47d979ecc..8d4b3594eaf 100644
--- a/src/ChangeLog.4
+++ b/src/ChangeLog.4
@@ -3490,7 +3490,7 @@
 
        * Makefile.in.in (temacs): Delete redundant use of LDFLAGS.
 
-1994-01-02  Ulrich Mueller  (ulm@vsnhd1.cern.ch)
+1994-01-02  Ulrich Müller  (ulm@vsnhd1.cern.ch)
 
        * sysdep.c (get_system_name): If the official name of the host is
        not a fully qualified domain name, then try to find one in the
diff --git a/src/android.c b/src/android.c
index 9f0e966a602..79f16568fd4 100644
--- a/src/android.c
+++ b/src/android.c
@@ -1260,6 +1260,14 @@ NATIVE_NAME (dup) (JNIEnv *env, jobject object, jint fd)
   return dup (fd);
 }
 
+JNIEXPORT jint JNICALL
+NATIVE_NAME (close) (JNIEnv *env, jobject object, jint fd)
+{
+  JNI_STACK_ALIGNMENT_PROLOGUE;
+
+  return close (fd);
+}
+
 JNIEXPORT jstring JNICALL
 NATIVE_NAME (getFingerprint) (JNIEnv *env, jobject object)
 {
@@ -1531,7 +1539,7 @@ android_init_emacs_service (void)
     = (*android_java_env)->GetMethodID (android_java_env,      \
                                        service_class.class,    \
                                        name, signature);       \
-  assert (service_class.c_name);
+  eassert (service_class.c_name);
 
   FIND_METHOD (fill_rectangle, "fillRectangle",
               "(Lorg/gnu/emacs/EmacsDrawable;"
@@ -1647,7 +1655,7 @@ android_init_emacs_pixmap (void)
     = (*android_java_env)->GetMethodID (android_java_env,      \
                                        pixmap_class.class,     \
                                        name, signature);       \
-  assert (pixmap_class.c_name);
+  eassert (pixmap_class.c_name);
 
   FIND_METHOD (constructor_mutable, "<init>", "(SIII)V");
 
@@ -1678,7 +1686,7 @@ android_init_graphics_point (void)
     = (*android_java_env)->GetMethodID (android_java_env,      \
                                        point_class.class,      \
                                        name, signature);       \
-  assert (point_class.c_name);
+  eassert (point_class.c_name);
 
   FIND_METHOD (constructor, "<init>", "(II)V");
 #undef FIND_METHOD
@@ -1708,7 +1716,7 @@ android_init_emacs_drawable (void)
     = (*android_java_env)->GetMethodID (android_java_env,      \
                                        drawable_class.class,   \
                                        name, signature);       \
-  assert (drawable_class.c_name);
+  eassert (drawable_class.c_name);
 
   FIND_METHOD (get_bitmap, "getBitmap", "()Landroid/graphics/Bitmap;");
 #undef FIND_METHOD
@@ -1738,7 +1746,7 @@ android_init_emacs_window (void)
     = (*android_java_env)->GetMethodID (android_java_env,      \
                                        window_class.class,     \
                                        name, signature);       \
-  assert (window_class.c_name);
+  eassert (window_class.c_name);
 
   FIND_METHOD (swap_buffers, "swapBuffers", "()V");
   FIND_METHOD (toggle_on_screen_keyboard,
@@ -1798,7 +1806,7 @@ android_init_emacs_cursor (void)
     = (*android_java_env)->GetMethodID (android_java_env,      \
                                        cursor_class.class,     \
                                        name, signature);       \
-  assert (cursor_class.c_name);
+  eassert (cursor_class.c_name);
 
   FIND_METHOD (constructor, "<init>", "(SI)V");
 #undef FIND_METHOD
@@ -2695,12 +2703,12 @@ android_destroy_handle (android_handle handle)
       class
        = (*android_java_env)->FindClass (android_java_env,
                                          "org/gnu/emacs/EmacsHandleObject");
-      assert (class != NULL);
+      eassert (class != NULL);
 
       method
        = (*android_java_env)->GetMethodID (android_java_env, class,
                                            "destroyHandle", "()V");
-      assert (method != NULL);
+      eassert (method != NULL);
 
       old = class;
       class
@@ -2843,13 +2851,13 @@ android_create_window (android_window parent, int x, 
int y,
     {
       class = (*android_java_env)->FindClass (android_java_env,
                                              "org/gnu/emacs/EmacsWindow");
-      assert (class != NULL);
+      eassert (class != NULL);
 
       constructor
        = (*android_java_env)->GetMethodID (android_java_env, class, "<init>",
                                            "(SLorg/gnu/emacs/EmacsWindow;"
                                            "IIIIZ)V");
-      assert (constructor != NULL);
+      eassert (constructor != NULL);
 
       old = class;
       class = (*android_java_env)->NewGlobalRef (android_java_env, class);
@@ -2925,12 +2933,12 @@ android_init_android_rect_class (void)
   android_rect_class
     = (*android_java_env)->FindClass (android_java_env,
                                      "android/graphics/Rect");
-  assert (android_rect_class);
+  eassert (android_rect_class);
 
   android_rect_constructor
     = (*android_java_env)->GetMethodID (android_java_env, android_rect_class,
                                        "<init>", "(IIII)V");
-  assert (emacs_gc_constructor);
+  eassert (emacs_gc_constructor);
 
   old = android_rect_class;
   android_rect_class
@@ -2952,19 +2960,19 @@ android_init_emacs_gc_class (void)
   emacs_gc_class
     = (*android_java_env)->FindClass (android_java_env,
                                      "org/gnu/emacs/EmacsGC");
-  assert (emacs_gc_class);
+  eassert (emacs_gc_class);
 
   emacs_gc_constructor
     = (*android_java_env)->GetMethodID (android_java_env,
                                        emacs_gc_class,
                                        "<init>", "(S)V");
-  assert (emacs_gc_constructor);
+  eassert (emacs_gc_constructor);
 
   emacs_gc_mark_dirty
     = (*android_java_env)->GetMethodID (android_java_env,
                                        emacs_gc_class,
                                        "markDirty", "(Z)V");
-  assert (emacs_gc_mark_dirty);
+  eassert (emacs_gc_mark_dirty);
 
   old = emacs_gc_class;
   emacs_gc_class
@@ -6667,7 +6675,7 @@ android_begin_query (void)
   if (old == 1)
     {
       /* Answer the query that is currently being made.  */
-      assert (android_query_function != NULL);
+      eassert (android_query_function != NULL);
       android_answer_query ();
     }
 
diff --git a/src/androidselect.c b/src/androidselect.c
index 3f025351093..f7988db0520 100644
--- a/src/androidselect.c
+++ b/src/androidselect.c
@@ -90,7 +90,7 @@ android_init_emacs_clipboard (void)
     = (*android_java_env)->GetMethodID (android_java_env,      \
                                        clipboard_class.class,  \
                                        name, signature);       \
-  assert (clipboard_class.c_name);
+  eassert (clipboard_class.c_name);
 
   FIND_METHOD (set_clipboard, "setClipboard", "([B)V");
   FIND_METHOD (owns_clipboard, "ownsClipboard", "()I");
@@ -107,7 +107,7 @@ android_init_emacs_clipboard (void)
                                              "makeClipboard",
                                              "()Lorg/gnu/emacs/"
                                              "EmacsClipboard;");
-  assert (clipboard_class.make_clipboard);
+  eassert (clipboard_class.make_clipboard);
 
 #undef FIND_METHOD
 }
@@ -511,7 +511,7 @@ android_init_emacs_desktop_notification (void)
     = (*android_java_env)->GetMethodID (android_java_env,              \
                                        notification_class.class,       \
                                        name, signature);               \
-  assert (notification_class.c_name);
+  eassert (notification_class.c_name);
 
   FIND_METHOD (init, "<init>", "(Ljava/lang/String;"
               "Ljava/lang/String;Ljava/lang/String;"
diff --git a/src/androidterm.c b/src/androidterm.c
index 9d6517cce2b..4a479daf452 100644
--- a/src/androidterm.c
+++ b/src/androidterm.c
@@ -21,7 +21,6 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <stdio.h>
 #include <math.h>
 #include <stdlib.h>
-#include <assert.h>
 #include <semaphore.h>
 
 #include "lisp.h"
@@ -1142,7 +1141,7 @@ handle_one_android_event (struct android_display_info 
*dpyinfo,
              Lisp_Object window
                = window_from_coordinates (f, event->xmotion.x,
                                           event->xmotion.y, 0,
-                                          false, false);
+                                          false, false, false);
 
              /* A window will be autoselected only when it is not
                 selected now and the last mouse movement event was
@@ -1291,7 +1290,7 @@ handle_one_android_event (struct android_display_info 
*dpyinfo,
              int x = event->xbutton.x;
              int y = event->xbutton.y;
 
-             window = window_from_coordinates (f, x, y, 0, true, true);
+             window = window_from_coordinates (f, x, y, 0, true, true, true);
              tab_bar_p = EQ (window, f->tab_bar_window);
 
              if (tab_bar_p)
@@ -1313,7 +1312,7 @@ handle_one_android_event (struct android_display_info 
*dpyinfo,
              int x = event->xbutton.x;
              int y = event->xbutton.y;
 
-             window = window_from_coordinates (f, x, y, 0, true, true);
+             window = window_from_coordinates (f, x, y, 0, true, true, true);
              tool_bar_p = (EQ (window, f->tool_bar_window)
                            && ((event->xbutton.type
                                 != ANDROID_BUTTON_RELEASE)
@@ -1409,7 +1408,7 @@ handle_one_android_event (struct android_display_info 
*dpyinfo,
          int y = event->touch.y;
 
          window = window_from_coordinates (any, x, y, 0, true,
-                                           true);
+                                           true, true);
 
          /* If this touch has started in the tool bar, do not
             send it to Lisp.  Instead, simulate a tool bar
@@ -1606,7 +1605,7 @@ handle_one_android_event (struct android_display_info 
*dpyinfo,
          /* Figure out how much to scale the deltas by.  */
          window = window_from_coordinates (any, event->wheel.x,
                                            event->wheel.y, NULL,
-                                           false, false);
+                                           false, false, false);
 
          if (WINDOWP (window))
            scroll_height = XWINDOW (window)->pixel_height;
@@ -5602,15 +5601,15 @@ NATIVE_NAME (getExtractedText) (JNIEnv *env, jobject 
ignored_object,
       class
        = (*env)->FindClass (env, ("android/view/inputmethod"
                                   "/ExtractedTextRequest"));
-      assert (class);
+      eassert (class);
 
       request_class.hint_max_chars
        = (*env)->GetFieldID (env, class, "hintMaxChars", "I");
-      assert (request_class.hint_max_chars);
+      eassert (request_class.hint_max_chars);
 
       request_class.token
        = (*env)->GetFieldID (env, class, "token", "I");
-      assert (request_class.token);
+      eassert (request_class.token);
 
       request_class.initialized = true;
     }
@@ -5620,12 +5619,12 @@ NATIVE_NAME (getExtractedText) (JNIEnv *env, jobject 
ignored_object,
       text_class.class
        = (*env)->FindClass (env, ("android/view/inputmethod"
                                   "/ExtractedText"));
-      assert (text_class.class);
+      eassert (text_class.class);
 
       class
        = text_class.class
        = (*env)->NewGlobalRef (env, text_class.class);
-      assert (text_class.class);
+      eassert (text_class.class);
 
       text_class.flags
        = (*env)->GetFieldID (env, class, "flags", "I");
@@ -5924,7 +5923,7 @@ android_get_surrounding_text_internal (JNIEnv *env, 
jshort window,
          return NULL;
        }
 #else /* __ANDROID_API__ >= 31 */
-      assert (class);
+      eassert (class);
 #endif /* __ANDROID_API__ < 31 */
 
       class = (*env)->NewGlobalRef (env, class);
@@ -5936,7 +5935,7 @@ android_get_surrounding_text_internal (JNIEnv *env, 
jshort window,
       /* Now look for its constructor.  */
       constructor = (*env)->GetMethodID (env, class, "<init>",
                                         "(Ljava/lang/CharSequence;III)V");
-      assert (constructor);
+      eassert (constructor);
     }
 
   context.before_length = before_length;
@@ -6032,7 +6031,7 @@ NATIVE_NAME (takeSnapshot) (JNIEnv *env, jobject object, 
jshort window)
          return NULL;
        }
 #else /* __ANDROID_API__ >= 33 */
-      assert (class);
+      eassert (class);
 #endif /* __ANDROID_API__ < 33 */
 
       class = (*env)->NewGlobalRef (env, class);
@@ -6044,7 +6043,7 @@ NATIVE_NAME (takeSnapshot) (JNIEnv *env, jobject object, 
jshort window)
       constructor = (*env)->GetMethodID (env, class, "<init>",
                                         "(Landroid/view/inputmethod"
                                         "/SurroundingText;III)V");
-      assert (constructor);
+      eassert (constructor);
     }
 
   /* Try to create a TextSnapshot object.  */
diff --git a/src/androidvfs.c b/src/androidvfs.c
index f89a82cfcc6..51558d2a375 100644
--- a/src/androidvfs.c
+++ b/src/androidvfs.c
@@ -403,6 +403,16 @@ android_init_fd_class (JNIEnv *env)
 
 
 
+/* Account for SAF file names two times as large as PATH_MAX; larger
+   values are prohibitively slow, but smaller values can't face up to
+   some long file names within several nested layers of directories.
+
+   Buffers holding components or other similar file name constitutents
+   which don't represent SAF files must continue to use PATH_MAX, for
+   that is the restriction imposed by the Unix file system.  */
+
+#define EMACS_PATH_MAX (PATH_MAX * 2)
+
 /* Delete redundant instances of `.' and `..' from NAME in-place.
    NAME must be *LENGTH long, excluding a mandatory trailing NULL
    byte.
@@ -4990,7 +5000,7 @@ android_saf_tree_rename (struct android_vnode *src,
 {
   char *last, *dst_last;
   struct android_saf_tree_vnode *vp, *vdst;
-  char path[PATH_MAX], path1[PATH_MAX];
+  char path[EMACS_PATH_MAX], path1[EMACS_PATH_MAX];
   char *fill, *dst_id;
   int rc;
 
@@ -5076,8 +5086,8 @@ android_saf_tree_rename (struct android_vnode *src,
       /* The names of the source and destination directories will have
         to be copied to path.  */
 
-      if (last - vp->name >= PATH_MAX
-         || dst_last - vdst->name >= PATH_MAX)
+      if (last - vp->name >= EMACS_PATH_MAX
+         || dst_last - vdst->name >= EMACS_PATH_MAX)
        {
          errno = ENAMETOOLONG;
          return -1;
@@ -5191,7 +5201,7 @@ android_saf_tree_rename (struct android_vnode *src,
      directory is required, as it provides the directory whose entries
      will be modified.  */
 
-  if (last - vp->name >= PATH_MAX)
+  if (last - vp->name >= EMACS_PATH_MAX)
     {
       errno = ENAMETOOLONG;
       return -1;
@@ -5480,7 +5490,7 @@ android_saf_tree_opendir (struct android_vnode *vnode)
   struct android_saf_tree_vdir *dir;
   char *fill, *end;
   jobject cursor;
-  char component[PATH_MAX];
+  char component[EMACS_PATH_MAX];
 
   vp = (struct android_saf_tree_vnode *) vnode;
 
@@ -5510,7 +5520,7 @@ android_saf_tree_opendir (struct android_vnode *vnode)
   if (!end)
     emacs_abort ();
 
-  if (end - fill >= PATH_MAX)
+  if (end - fill >= EMACS_PATH_MAX)
     {
       errno = ENAMETOOLONG;
       xfree (dir);
@@ -6455,7 +6465,7 @@ android_root_name (struct android_vnode *vnode, char 
*name,
    least N bytes.
 
    NAME may be either an absolute file name or a name relative to the
-   current working directory.  It must not be longer than PATH_MAX
+   current working directory.  It must not be longer than EMACS_PATH_MAX
    bytes.
 
    Value is NULL upon failure with errno set accordingly, or the
@@ -6464,14 +6474,14 @@ android_root_name (struct android_vnode *vnode, char 
*name,
 static struct android_vnode *
 android_name_file (const char *name)
 {
-  char buffer[PATH_MAX + 1], *head;
+  char buffer[EMACS_PATH_MAX + 1], *head;
   const char *end;
   size_t len;
   int nslash, c;
   struct android_vnode *vp;
 
   len = strlen (name);
-  if (len > PATH_MAX)
+  if (len > EMACS_PATH_MAX)
     {
       errno = ENAMETOOLONG;
       return NULL;
@@ -6557,12 +6567,12 @@ android_vfs_init (JNIEnv *env, jobject manager)
 
   /* Initialize some required classes.  */
   java_string_class = (*env)->FindClass (env, "java/lang/String");
-  assert (java_string_class);
+  eassert (java_string_class);
 
   old = java_string_class;
   java_string_class = (jclass) (*env)->NewGlobalRef (env,
                                                     java_string_class);
-  assert (java_string_class);
+  eassert (java_string_class);
   (*env)->DeleteLocalRef (env, old);
 
   /* And initialize those used on Android 5.0 and later.  */
@@ -7009,7 +7019,7 @@ int
 android_fstatat (int dirfd, const char *restrict pathname,
                 struct stat *restrict statbuf, int flags)
 {
-  char buffer[PATH_MAX + 1];
+  char buffer[EMACS_PATH_MAX + 1];
   struct android_vnode *vp;
   int rc;
 
@@ -7023,7 +7033,7 @@ android_fstatat (int dirfd, const char *restrict pathname,
   /* Now establish whether DIRFD is a file descriptor corresponding to
      an open VFS directory stream.  */
 
-  if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1))
+  if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1))
     {
       pathname = buffer;
       goto vfs;
@@ -7049,7 +7059,7 @@ int
 android_faccessat (int dirfd, const char *restrict pathname,
                   int mode, int flags)
 {
-  char buffer[PATH_MAX + 1];
+  char buffer[EMACS_PATH_MAX + 1];
   struct android_vnode *vp;
   int rc;
 
@@ -7063,7 +7073,7 @@ android_faccessat (int dirfd, const char *restrict 
pathname,
   /* Now establish whether DIRFD is a file descriptor corresponding to
      an open VFS directory stream.  */
 
-  if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1))
+  if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1))
     {
       pathname = buffer;
       goto vfs;
@@ -7089,7 +7099,7 @@ int
 android_fchmodat (int dirfd, const char *pathname, mode_t mode,
                  int flags)
 {
-  char buffer[PATH_MAX + 1];
+  char buffer[EMACS_PATH_MAX + 1];
   struct android_vnode *vp;
   int rc;
 
@@ -7099,7 +7109,7 @@ android_fchmodat (int dirfd, const char *pathname, mode_t 
mode,
   /* Now establish whether DIRFD is a file descriptor corresponding to
      an open VFS directory stream.  */
 
-  if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1))
+  if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1))
     {
       pathname = buffer;
       goto vfs;
@@ -7125,7 +7135,7 @@ ssize_t
 android_readlinkat (int dirfd, const char *restrict pathname,
                    char *restrict buf, size_t bufsiz)
 {
-  char buffer[PATH_MAX + 1];
+  char buffer[EMACS_PATH_MAX + 1];
   struct android_vnode *vp;
   ssize_t rc;
 
@@ -7135,7 +7145,7 @@ android_readlinkat (int dirfd, const char *restrict 
pathname,
   /* Now establish whether DIRFD is a file descriptor corresponding to
      an open VFS directory stream.  */
 
-  if (!android_fstatat_1 (dirfd, pathname, buffer, PATH_MAX + 1))
+  if (!android_fstatat_1 (dirfd, pathname, buffer, EMACS_PATH_MAX + 1))
     {
       pathname = buffer;
       goto vfs;
diff --git a/src/casefiddle.c b/src/casefiddle.c
index d567a5e353a..3afb131c50e 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -92,6 +92,12 @@ prepare_casing_context (struct casing_context *ctx,
     SETUP_BUFFER_SYNTAX_TABLE ();      /* For syntax_prefix_flag_p.  */
 }
 
+static bool
+case_ch_is_word (enum syntaxcode syntax)
+{
+  return syntax == Sword || (case_symbols_as_words && syntax == Ssymbol);
+}
+
 struct casing_str_buf
 {
   unsigned char data[max (6, MAX_MULTIBYTE_LENGTH)];
@@ -115,7 +121,7 @@ case_character_impl (struct casing_str_buf *buf,
 
   /* Update inword state */
   bool was_inword = ctx->inword;
-  ctx->inword = SYNTAX (ch) == Sword &&
+  ctx->inword = case_ch_is_word (SYNTAX (ch)) &&
     (!ctx->inbuffer || was_inword || !syntax_prefix_flag_p (ch));
 
   /* Normalize flag so its one of CASE_UP, CASE_DOWN or CASE_CAPITALIZE.  */
@@ -222,7 +228,7 @@ case_character (struct casing_str_buf *buf, struct 
casing_context *ctx,
      has a word syntax (i.e. current character is end of word), use final
      sigma.  */
   if (was_inword && ch == GREEK_CAPITAL_LETTER_SIGMA && changed
-      && (!next || SYNTAX (STRING_CHAR (next)) != Sword))
+      && (!next || !case_ch_is_word (SYNTAX (STRING_CHAR (next)))))
     {
       buf->len_bytes = CHAR_STRING (GREEK_SMALL_LETTER_FINAL_SIGMA, buf->data);
       buf->len_chars = 1;
@@ -720,6 +726,21 @@ Called with one argument METHOD which can be:
   3rd argument.  */);
   Vregion_extract_function = Qnil; /* simple.el sets this.  */
 
+  DEFVAR_BOOL ("case-symbols-as-words", case_symbols_as_words,
+    doc: /* If non-nil, case functions treat symbol syntax as part of words.
+
+Functions such as `upcase-initials' and `replace-match' check or modify
+the case pattern of sequences of characters.  Normally, these operate on
+sequences of characters whose syntax is word constituent.  If this
+variable is non-nil, then they operate on sequences of characters whose
+syntax is either word constituent or symbol constituent.
+
+This is useful for programming languages and styles where only the first
+letter of a symbol's name is ever capitalized.*/);
+  case_symbols_as_words = 0;
+  DEFSYM (Qcase_symbols_as_words, "case-symbols-as-words");
+  Fmake_variable_buffer_local (Qcase_symbols_as_words);
+
   defsubr (&Supcase);
   defsubr (&Sdowncase);
   defsubr (&Scapitalize);
diff --git a/src/dispnew.c b/src/dispnew.c
index d6a27ac29ec..e4037494775 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -6206,9 +6206,9 @@ bitch_at_user (void)
 DEFUN ("sleep-for", Fsleep_for, Ssleep_for, 1, 2, 0,
        doc: /* Pause, without updating display, for SECONDS seconds.
 SECONDS may be a floating-point value, meaning that you can wait for a
-fraction of a second.  Optional second arg MILLISECONDS specifies an
-additional wait period, in milliseconds; this is for backwards compatibility.
-\(Not all operating systems support waiting for a fraction of a second.)  */)
+fraction of a second.
+An optional second arg MILLISECONDS can be provided but is deprecated:
+it specifies an additional wait period, in milliseconds.  */)
   (Lisp_Object seconds, Lisp_Object milliseconds)
 {
   double duration = extract_float (seconds);
diff --git a/src/eval.c b/src/eval.c
index 68a30631fb0..859cc162562 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2395,9 +2395,13 @@ static Lisp_Object list_of_t;  /* Never-modified 
constant containing (t).  */
 
 DEFUN ("eval", Feval, Seval, 1, 2, 0,
        doc: /* Evaluate FORM and return its value.
-If LEXICAL is t, evaluate using lexical scoping.
-LEXICAL can also be an actual lexical environment, in the form of an
-alist mapping symbols to their value.  */)
+If LEXICAL is `t', evaluate using lexical binding by default.
+This is the recommended value.
+
+If absent or `nil', use dynamic scoping only.
+
+LEXICAL can also represent an actual lexical environment; see the Info
+node `(elisp)Eval' for details.  */)
   (Lisp_Object form, Lisp_Object lexical)
 {
   specpdl_ref count = SPECPDL_INDEX ();
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index 3fc90385af3..33ad5889043 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -1059,6 +1059,8 @@ public:
        msg->FindInt64 ("when", &rq.time);
 
        rq.modifiers = 0;
+       rq.keysym = 0;
+
        uint32_t mods = modifiers ();
 
        if (mods & B_SHIFT_KEY)
@@ -1073,10 +1075,39 @@ public:
        if (mods & B_OPTION_KEY)
          rq.modifiers |= HAIKU_MODIFIER_SUPER;
 
-       ret = keysym_from_raw_char (raw, key, &rq.keysym);
+       /* mods & B_SHIFT_KEY should be inverted if keycode is
+          situated in the numeric keypad and Num Lock is set, for
+          this transformation is not effected on key events
+          themselves.  */
+
+       if (mods & B_NUM_LOCK)
+         {
+           switch (key)
+             {
+             case 0x37:
+             case 0x38:
+             case 0x39:
+             case 0x48:
+             case 0x49:
+             case 0x4a:
+             case 0x58:
+             case 0x59:
+             case 0x5a:
+             case 0x64:
+             case 0x65:
+               mods ^= B_SHIFT_KEY;
+
+               /* If shift is set at this juncture, map these keys to
+                  the digits they represent.  Because raw is not
+                  affected by Num Lock, keysym_from_raw_char will map
+                  this to the keysym yielded by this key in the
+                  absence of any modifiers.  */
+               if (mods & B_SHIFT_KEY)
+                 goto map_keysym;
+             }
+         }
 
-       if (!ret)
-         rq.keysym = 0;
+       ret = keysym_from_raw_char (raw, key, &rq.keysym);
 
        if (ret < 0)
          return;
@@ -1087,6 +1118,7 @@ public:
          {
            if (mods & B_SHIFT_KEY)
              {
+         map_keysym:
                if (mods & B_CAPS_LOCK)
                  map_caps_shift (key, &rq.multibyte_char);
                else
diff --git a/src/haikuterm.c b/src/haikuterm.c
index b1a016b49a9..bcb5055ea42 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -3472,7 +3472,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
                if (!NILP (Vmouse_autoselect_window))
                  {
                    static Lisp_Object last_mouse_window;
-                   Lisp_Object window = window_from_coordinates (f, b->x, 
b->y, 0, 0, 0);
+                   Lisp_Object window = window_from_coordinates (f, b->x, 
b->y, 0, 0, 0, 0);
 
                    if (WINDOWP (window)
                        && !EQ (window, last_mouse_window)
@@ -3555,7 +3555,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
                int x = b->x;
                int y = b->y;
 
-               window = window_from_coordinates (f, x, y, 0, true, true);
+               window = window_from_coordinates (f, x, y, 0, true, true, true);
                tab_bar_p = EQ (window, f->tab_bar_window);
 
                if (tab_bar_p)
@@ -3573,7 +3573,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
                int x = b->x;
                int y = b->y;
 
-               window = window_from_coordinates (f, x, y, 0, true, true);
+               window = window_from_coordinates (f, x, y, 0, true, true, true);
                tool_bar_p = (EQ (window, f->tool_bar_window)
                              && (type != BUTTON_UP
                                  || f->last_tool_bar_item != -1));
@@ -3834,7 +3834,7 @@ haiku_read_socket (struct terminal *terminal, struct 
input_event *hold_quit)
 
            BView_get_mouse (FRAME_HAIKU_VIEW (f), &x, &y);
 
-           wheel_window = window_from_coordinates (f, x, y, 0, false, false);
+           wheel_window = window_from_coordinates (f, x, y, 0, false, false, 
false);
 
            if (NILP (wheel_window))
              {
diff --git a/src/indent.c b/src/indent.c
index eda85f2e94d..7d34d3638d9 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2031,7 +2031,7 @@ vmotion (ptrdiff_t from, ptrdiff_t from_byte,
 }
 
 /* Return the width taken by line-number display in window W.  */
-static void
+void
 line_number_display_width (struct window *w, int *width, int *pixel_width)
 {
   if (NILP (Vdisplay_line_numbers))
@@ -2101,7 +2101,7 @@ numbers on display.  */)
 {
   int width, pixel_width;
   struct window *w = XWINDOW (selected_window);
-  line_number_display_width (XWINDOW (selected_window), &width, &pixel_width);
+  line_number_display_width (w, &width, &pixel_width);
   if (EQ (pixelwise, Qcolumns))
     {
       struct frame *f = XFRAME (w->frame);
diff --git a/src/keyboard.c b/src/keyboard.c
index 76dec637cb1..c00f48d7836 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5531,6 +5531,10 @@ static Lisp_Object button_down_location;
    the down mouse event.  */
 static Lisp_Object frame_relative_event_pos;
 
+/* The line-number display width, in columns, at the time of most
+   recent down mouse event.  */
+static int down_mouse_line_number_width;
+
 /* Information about the most recent up-going button event:  Which
    button, what location, and what time.  */
 
@@ -5558,7 +5562,7 @@ make_lispy_position (struct frame *f, Lisp_Object x, 
Lisp_Object y,
   int xret = 0, yret = 0;
   /* The window or frame under frame pixel coordinates (x,y)  */
   Lisp_Object window_or_frame = f
-    ? window_from_coordinates (f, mx, my, &part, true, true)
+    ? window_from_coordinates (f, mx, my, &part, true, true, true)
     : Qnil;
 #ifdef HAVE_WINDOW_SYSTEM
   bool tool_bar_p = false;
@@ -5927,6 +5931,57 @@ coords_in_tab_bar_window (struct frame *f, int x, int y)
 
 #endif /* HAVE_WINDOW_SYSTEM */
 
+static void
+save_line_number_display_width (struct input_event *event)
+{
+  struct window *w;
+  int pixel_width;
+
+  if (WINDOWP (event->frame_or_window))
+    w = XWINDOW (event->frame_or_window);
+  else if (FRAMEP (event->frame_or_window))
+    w = XWINDOW (XFRAME (event->frame_or_window)->selected_window);
+  else
+    w = XWINDOW (selected_window);
+  line_number_display_width (w, &down_mouse_line_number_width, &pixel_width);
+}
+
+/* Return non-zero if the change of position from START_POS to END_POS
+   is likely to be the effect of horizontal scrolling due to a change
+   in line-number width produced by redisplay between two mouse
+   events, like mouse-down followed by mouse-up, at those positions.
+   This is used to decide whether to converts mouse-down followed by
+   mouse-up event into a mouse-drag event.  */
+static bool
+line_number_mode_hscroll (Lisp_Object start_pos, Lisp_Object end_pos)
+{
+  if (!EQ (Fcar (start_pos), Fcar (end_pos)) /* different window */
+      || list_length (start_pos) < 7        /* no COL/ROW info */
+      || list_length (end_pos) < 7)
+    return false;
+
+  Lisp_Object start_col_row = Fnth (make_fixnum (6), start_pos);
+  Lisp_Object end_col_row = Fnth (make_fixnum (6), end_pos);
+  Lisp_Object window = Fcar (end_pos);
+  int col_width, pixel_width;
+  Lisp_Object start_col, end_col;
+  struct window *w;
+  if (!WINDOW_VALID_P (window))
+    {
+      if (WINDOW_LIVE_P (window))
+       window = XFRAME (window)->selected_window;
+      else
+       window = selected_window;
+    }
+  w = XWINDOW (window);
+  line_number_display_width (w, &col_width, &pixel_width);
+  start_col = Fcar (start_col_row);
+  end_col = Fcar (end_col_row);
+  return EQ (start_col, end_col)
+        && down_mouse_line_number_width >= 0
+        && col_width != down_mouse_line_number_width;
+}
+
 /* Given a struct input_event, build the lisp event which represents
    it.  If EVENT is 0, build a mouse movement event from the mouse
    movement buffer, which should have a movement event in it.
@@ -6329,6 +6384,8 @@ make_lispy_event (struct input_event *event)
            *start_pos_ptr = Fcopy_alist (position);
            frame_relative_event_pos = Fcons (event->x, event->y);
            ignore_mouse_drag_p = false;
+           /* Squirrel away the line-number width, if any.  */
+           save_line_number_display_width (event);
          }
 
        /* Now we're releasing a button - check the coordinates to
@@ -6374,12 +6431,18 @@ make_lispy_event (struct input_event *event)
                          it's probably OK to ignore it as well.  */
                       && (EQ (Fcar (Fcdr (start_pos)),
                               Fcar (Fcdr (position))) /* Same buffer pos */
+                          /* Redisplay hscrolled text between down- and
+                              up-events due to display-line-numbers-mode.  */
+                          || line_number_mode_hscroll (start_pos, position)
                           || !EQ (Fcar (start_pos),
                                   Fcar (position))))) /* Different window */
+
                  {
                    /* Mouse has moved enough.  */
                    button_down_time = 0;
                    click_or_drag_modifier = drag_modifier;
+                   /* Reset the value for future clicks.  */
+                   down_mouse_line_number_width = -1;
                  }
                else if (((!EQ (Fcar (start_pos), Fcar (position)))
                          || (!EQ (Fcar (Fcdr (start_pos)),
diff --git a/src/lisp.h b/src/lisp.h
index 8318e7ae8b4..54dd12bf291 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4989,6 +4989,7 @@ extern void keys_of_keyboard (void);
 
 /* Defined in indent.c.  */
 extern ptrdiff_t current_column (void);
+extern void line_number_display_width (struct window *, int *, int *);
 extern void invalidate_current_column (void);
 extern bool indented_beyond_p (ptrdiff_t, ptrdiff_t, EMACS_INT);
 extern void syms_of_indent (void);
diff --git a/src/msdos.c b/src/msdos.c
index 1b7f2d4ae21..5dd7c1573c4 100644
--- a/src/msdos.c
+++ b/src/msdos.c
@@ -2662,7 +2662,7 @@ dos_rawgetc (void)
              static Lisp_Object last_mouse_window;
 
              mouse_window = window_from_coordinates
-               (SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0, 0);
+               (SELECTED_FRAME (), mouse_last_x, mouse_last_y, 0, 0, 0, 0);
              /* A window will be selected only when it is not
                 selected now, and the last mouse movement event was
                 not in it.  A minibuffer window will be selected iff
diff --git a/src/nsterm.m b/src/nsterm.m
index 11535f071eb..46a5e8870e8 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -7412,7 +7412,7 @@ ns_in_echo_area (void)
          int x = lrint (p.x);
          int y = lrint (p.y);
 
-         window = window_from_coordinates (emacsframe, x, y, 0, true, true);
+         window = window_from_coordinates (emacsframe, x, y, 0, true, true, 
true);
          tab_bar_p = EQ (window, emacsframe->tab_bar_window);
 
          if (tab_bar_p)
@@ -7518,7 +7518,7 @@ ns_in_echo_area (void)
       NSTRACE_MSG ("mouse_autoselect_window");
       static Lisp_Object last_mouse_window;
       Lisp_Object window
-       = window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0, 0);
+       = window_from_coordinates (emacsframe, pt.x, pt.y, 0, 0, 0, 0);
 
       if (WINDOWP (window)
           && !EQ (window, last_mouse_window)
diff --git a/src/pdumper.c b/src/pdumper.c
index 8dd834bddd1..733cc1d8a73 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2860,8 +2860,10 @@ dump_buffer (struct dump_context *ctx, const struct 
buffer *in_buffer)
   DUMP_FIELD_COPY (out, buffer, long_line_optimizations_p);
 
   if (!itree_empty_p (buffer->overlays))
-    /* We haven't implemented the code to dump overlays.  */
-    emacs_abort ();
+    {
+      /* We haven't implemented the code to dump overlays.  */
+      error ("dumping overlays is not yet implemented");
+    }
   else
     out->overlays = NULL;
 
@@ -2954,7 +2956,7 @@ dump_native_comp_unit (struct dump_context *ctx,
                       struct Lisp_Native_Comp_Unit *comp_u)
 {
   if (!CONSP (comp_u->file))
-    error ("Trying to dump non fixed-up eln file");
+    error ("trying to dump non fixed-up eln file");
 
   /* Have function documentation always lazy loaded to optimize load-time.  */
   comp_u->data_fdoc_v = Qnil;
@@ -4089,6 +4091,10 @@ types.  */)
   if (!NILP (XCDR (Fall_threads ())))
     error ("No other Lisp threads can be running when this function is 
called");
 
+#ifdef HAVE_NATIVE_COMP
+  CALLN (Ffuncall, intern_c_string ("load--fixup-all-elns"));
+#endif
+
   check_pure_size ();
 
   /* Clear out any detritus in memory.  */
@@ -5349,11 +5355,11 @@ dump_do_dump_relocation (const uintptr_t dump_base,
          dump_ptr (dump_base, reloc_offset);
        comp_u->lambda_gc_guard_h = CALLN (Fmake_hash_table, QCtest, Qeq);
        if (STRINGP (comp_u->file))
-         error ("Trying to load incoherent dumped eln file %s",
+         error ("trying to load incoherent dumped eln file %s",
                 SSDATA (comp_u->file));
 
        if (!CONSP (comp_u->file))
-         error ("Incoherent compilation unit for dump was dumped");
+         error ("incoherent compilation unit for dump was dumped");
 
        /* emacs_execdir is always unibyte, but the file names in
           comp_u->file could be multibyte, so we need to encode
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index a7c687d811d..461c9d6d899 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -5894,7 +5894,7 @@ motion_notify_event (GtkWidget *widget, GdkEvent *event,
        {
          static Lisp_Object last_mouse_window;
          Lisp_Object window = window_from_coordinates
-           (f, event->motion.x, event->motion.y, 0, false, false);
+           (f, event->motion.x, event->motion.y, 0, false, false, false);
 
          /* A window will be autoselected only when it is not
             selected now and the last mouse movement event was
@@ -6047,7 +6047,7 @@ button_event (GtkWidget *widget, GdkEvent *event,
          int x = event->button.x;
          int y = event->button.y;
 
-         window = window_from_coordinates (f, x, y, 0, true, true);
+         window = window_from_coordinates (f, x, y, 0, true, true, true);
          tab_bar_p = EQ (window, f->tab_bar_window);
 
          if (tab_bar_p)
diff --git a/src/print.c b/src/print.c
index 103ca64c1cf..b3708e588f6 100644
--- a/src/print.c
+++ b/src/print.c
@@ -2019,7 +2019,7 @@ print_vectorlike (Lisp_Object obj, Lisp_Object 
printcharfun, bool escapeflag,
       {
        struct Lisp_Native_Comp_Unit *cu = XNATIVE_COMP_UNIT (obj);
        print_c_string ("#<native compilation unit: ", printcharfun);
-       print_string (cu->file, printcharfun);
+       print_object (cu->file, printcharfun, escapeflag);
        printchar (' ', printcharfun);
        print_object (cu->optimize_qualities, printcharfun, escapeflag);
        printchar ('>', printcharfun);
diff --git a/src/profiler.c b/src/profiler.c
index 6217071ef9c..b494ad783dc 100644
--- a/src/profiler.c
+++ b/src/profiler.c
@@ -55,6 +55,8 @@ struct profiler_log {
   EMACS_INT discarded; /* Samples evicted during table overflow.  */
 };
 
+static Lisp_Object export_log (struct profiler_log *);
+
 static struct profiler_log
 make_log (void)
 {
@@ -213,6 +215,23 @@ record_backtrace (struct profiler_log *plog, EMACS_INT 
count)
 
 /* Sampling profiler.  */
 
+/* Signal handler for sampling profiler.  */
+
+static void
+add_sample (struct profiler_log *plog, EMACS_INT count)
+{
+  if (EQ (backtrace_top_function (), QAutomatic_GC)) /* bug#60237 */
+    /* Special case the time-count inside GC because the hash-table
+       code is not prepared to be used while the GC is running.
+       More specifically it uses ASIZE at many places where it does
+       not expect the ARRAY_MARK_FLAG to be set.  We could try and
+       harden the hash-table code, but it doesn't seem worth the
+       effort.  */
+    plog->gc_count = saturated_add (plog->gc_count, count);
+  else
+    record_backtrace (plog, count);
+}
+
 #ifdef PROFILER_CPU_SUPPORT
 
 /* The profiler timer and whether it was properly initialized, if
@@ -235,30 +254,9 @@ static enum profiler_cpu_running
 /* Hash-table log of CPU profiler.  */
 static struct profiler_log cpu;
 
-/* Hash-table log of Memory profiler.  */
-static struct profiler_log memory;
-
 /* The current sampling interval in nanoseconds.  */
 static EMACS_INT current_sampling_interval;
 
-/* Signal handler for sampling profiler.  */
-
-static void
-add_sample (struct profiler_log *plog, EMACS_INT count)
-{
-  if (EQ (backtrace_top_function (), QAutomatic_GC)) /* bug#60237 */
-    /* Special case the time-count inside GC because the hash-table
-       code is not prepared to be used while the GC is running.
-       More specifically it uses ASIZE at many places where it does
-       not expect the ARRAY_MARK_FLAG to be set.  We could try and
-       harden the hash-table code, but it doesn't seem worth the
-       effort.  */
-    plog->gc_count = saturated_add (plog->gc_count, count);
-  else
-    record_backtrace (plog, count);
-}
-
-
 static void
 handle_profiler_signal (int signal)
 {
@@ -421,6 +419,19 @@ DEFUN ("profiler-cpu-running-p",
   return profiler_cpu_running ? Qt : Qnil;
 }
 
+DEFUN ("profiler-cpu-log", Fprofiler_cpu_log, Sprofiler_cpu_log,
+       0, 0, 0,
+       doc: /* Return the current cpu profiler log.
+The log is a hash-table mapping backtraces to counters which represent
+the amount of time spent at those points.  Every backtrace is a vector
+of functions, where the last few elements may be nil.
+Before returning, a new log is allocated for future samples.  */)
+  (void)
+{
+  return (export_log (&cpu));
+}
+#endif /* PROFILER_CPU_SUPPORT */
+
 static Lisp_Object
 export_log (struct profiler_log *log)
 {
@@ -433,29 +444,21 @@ export_log (struct profiler_log *log)
     Fputhash (CALLN (Fvector, QDiscarded_Samples, Qnil),
              make_fixnum (log->discarded),
              result);
+#ifdef PROFILER_CPU_SUPPORT
   /* Here we're making the log visible to Elisp, so it's not safe any
      more for our use afterwards since we can't rely on its special
      pre-allocated keys anymore.  So we have to allocate a new one.  */
   if (profiler_cpu_running)
     *log = make_log ();
+#endif /* PROFILER_CPU_SUPPORT */
   return result;
 }
-
-DEFUN ("profiler-cpu-log", Fprofiler_cpu_log, Sprofiler_cpu_log,
-       0, 0, 0,
-       doc: /* Return the current cpu profiler log.
-The log is a hash-table mapping backtraces to counters which represent
-the amount of time spent at those points.  Every backtrace is a vector
-of functions, where the last few elements may be nil.
-Before returning, a new log is allocated for future samples.  */)
-  (void)
-{
-  return (export_log (&cpu));
-}
-#endif /* PROFILER_CPU_SUPPORT */
 
 /* Memory profiler.  */
 
+/* Hash-table log of Memory profiler.  */
+static struct profiler_log memory;
+
 /* True if memory profiler is running.  */
 bool profiler_memory_running;
 
diff --git a/src/search.c b/src/search.c
index e9b29bb7179..692d8488049 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2365,7 +2365,7 @@ text has only capital letters and has at least one 
multiletter word,
 convert NEWTEXT to all caps.  Otherwise if all words are capitalized
 in the replaced text, capitalize each word in NEWTEXT.  Note that
 what exactly is a word is determined by the syntax tables in effect
-in the current buffer.
+in the current buffer, and the variable `case-symbols-as-words'.
 
 If optional third arg LITERAL is non-nil, insert NEWTEXT literally.
 Otherwise treat `\\' as special:
@@ -2479,7 +2479,8 @@ since only regular expressions have distinguished 
subexpressions.  */)
              /* Cannot be all caps if any original char is lower case */
 
              some_lowercase = 1;
-             if (SYNTAX (prevc) != Sword)
+             if (SYNTAX (prevc) != Sword
+                 && !(case_symbols_as_words && SYNTAX (prevc) == Ssymbol))
                some_nonuppercase_initial = 1;
              else
                some_multiletter_word = 1;
@@ -2487,7 +2488,8 @@ since only regular expressions have distinguished 
subexpressions.  */)
          else if (uppercasep (c))
            {
              some_uppercase = 1;
-             if (SYNTAX (prevc) != Sword)
+             if (SYNTAX (prevc) != Sword
+                 && !(case_symbols_as_words && SYNTAX (prevc) == Ssymbol))
                ;
              else
                some_multiletter_word = 1;
@@ -2496,7 +2498,8 @@ since only regular expressions have distinguished 
subexpressions.  */)
            {
              /* If the initial is a caseless word constituent,
                 treat that like a lowercase initial.  */
-             if (SYNTAX (prevc) != Sword)
+             if (SYNTAX (prevc) != Sword
+                 && !(case_symbols_as_words && SYNTAX (prevc) == Ssymbol))
                some_nonuppercase_initial = 1;
            }
 
diff --git a/src/sfnt.c b/src/sfnt.c
index 0648e12150c..7559055e8c2 100644
--- a/src/sfnt.c
+++ b/src/sfnt.c
@@ -12297,18 +12297,47 @@ sfnt_interpret_compound_glyph (struct sfnt_glyph 
*glyph,
 
 /* Unicode Variation Sequence (UVS) support.
 
-   Unicode defines a mechanism by which a two-codepoint sequence
-   consisting of a ``base character'' and ``variation selector'' is
-   able to produce a glyph that is a variant of the glyph that would
-   conventionally have been mapped to the ``base character''.
-
-   TrueType describes variation selector sequences through a type of
-   character mapping table that is given the format 14.  The character
-   mapping table consists of an array of variation selectors, each of
-   which have a corresponding ``default UVS table'', which describes
-   ranges of ``base characters'' having no special variant glyphs, and
-   a ``non-default UVS table'', which is a map of ``base characters''
-   to their corresponding variant glyphs.  */
+   Unicode defines a mechanism by which two-codepoint sequences
+   comprising a ``base character'' and ``variation selector'' combine
+   to produce a glyph besides that which is mapped to the ``base
+   character'' itself.
+
+   TrueType stores variation selector sequences inside a special type
+   of character mapping table that is given the format 14.  The
+   character mapping table consists of an array of variation
+   selectors, each of which is assigned a ``default UVS table''
+   recording ranges of ``base characters'' absent special variant
+   glyphs, and a ``non-default UVS table'', linking ``base
+   characters'' to their respective variant glyphs.
+
+   Unicode variation selectors occupy the range formed between 0xfe00
+   and 0xfe0f, along with that from 0xe0100 to 0xe01ef, within the
+   Unicode codespace.  When a variation selector is encountered as
+   text is being examined for display with a particular font, that
+   font's character mapping table is indexed by it, yielding a default
+   and non-default UVS table.  If the base character (which is
+   directly behind the variation selector) is subsequently located
+   within the default UVS table, then the glyph represented by this
+   union of base character and variation selector is that designated
+   by the base character within any UCS-4 or BMP character mapping
+   table in the font.  Since this glyph is at variance with that
+   derived from the base character only when the character set of the
+   character mapping table otherwise consulted is not UCS-4 or BMP,
+   the distinction between those two glyphs is largely notional.
+   Should the nondefault UVS table hold the base character, then the
+   glyph is conversely that enumerated in said table, whose indexing
+   is facilitated by sfnt_variation_glyph_for_char.  And if the base
+   character isn't present within either table or the tables for the
+   variation selector are absent in the first place, then the two
+   codepoints constituting the sequence are immiscible and therefore
+   the sequence cannot apply to the font.
+
+   The approach taken by Emacs character composition routines is
+   diametric to the approach illustrated above: in place of searching
+   for variation glyphs each time a variation selector character is
+   encountered, these routines ascertain which glyphs are linked to
+   each base character that they have adjudged subject to variation in
+   advance.  See sfntfont_get_variation_glyphs.  */
 
 /* Read a default UVS table from the font file FD, at the specified
    OFFSET.  Value is the default UVS table upon success, else
@@ -12688,6 +12717,26 @@ sfnt_compare_uvs_mapping (const void *k, const void *v)
   return 1;
 }
 
+/* Compare *(sfnt_char *) K to the Unicode value range V.  */
+
+static int
+sfnt_compare_unicode_value_range (const void *k, const void *v)
+{
+  const sfnt_char *key;
+  const struct sfnt_unicode_value_range *value;
+
+  key = k;
+  value = v;
+
+  if (*key < value->start_unicode_value)
+    return -1;
+  else if ((*key - value->start_unicode_value
+           <= value->additional_count))
+    return 0;
+
+  return 1;
+}
+
 /* Return the ID of a variation glyph for the character C in the
    nondefault UVS mapping table UVS.
 
@@ -12707,6 +12756,21 @@ sfnt_variation_glyph_for_char (struct 
sfnt_nondefault_uvs_table *uvs,
   return mapping ? mapping->base_character_value : 0;
 }
 
+/* Return whether the character C is present in the default UVS
+   mapping table UVS.  */
+
+TEST_STATIC bool
+sfnt_is_character_default (struct sfnt_default_uvs_table *uvs,
+                          sfnt_char c)
+{
+  /* UVS->ranges comprises ranges of characters sorted in increasing
+     order; these ranges cannot overlap.  */
+
+  return (bsearch (&c, uvs->ranges, uvs->num_unicode_value_ranges,
+                  sizeof *uvs->ranges,
+                  sfnt_compare_unicode_value_range) != NULL);
+}
+
 
 
 #if defined HAVE_MMAP && !defined TEST
@@ -12843,9 +12907,13 @@ sfnt_read_table (int fd, struct sfnt_offset_subtable 
*subtable,
 
 /* Glyph variations.  Instead of defining separate fonts for each
    combination of weight, width and slant (bold, condensed, italic,
-   etc), some fonts specify a list of ``variation axes'', each of
-   which determines one delta to apply to each point in every
-   glyph.
+   etc), some fonts specify a list of ``variation axes'', which are
+   options that accept values consisting of numbers on scales
+   governing deltas applied to select points in their glyphs.
+
+   Particular styles within the font are then supplied as sets of
+   values on these scales to which their respective axes are set,
+   termed ``instances''.
 
    This optional information is specified in the `fvar' (font
    variation), `gvar' (glyph variation) and `cvar' (CVT variation)
@@ -14048,7 +14116,7 @@ sfnt_compute_tuple_scale (struct sfnt_blend *blend, 
bool intermediate_p,
       if (intermediate_p)
        {
          start = intermediate_start[i] * 4;
-         end = intermediate_start[i] * 4;
+         end = intermediate_end[i] * 4;
        }
 
       /* Ignore tuples that can be skipped.  */
@@ -14601,7 +14669,7 @@ sfnt_vary_simple_glyph (struct sfnt_blend *blend, 
sfnt_glyph id,
     coords = alloca (gvar->axis_count * sizeof *coords * 3);
 
   intermediate_start = coords + gvar->axis_count;
-  intermediate_end = coords + gvar->axis_count;
+  intermediate_end = intermediate_start + gvar->axis_count;
 
   /* Allocate arrays of booleans and fwords to keep track of which
      points have been touched.  */
@@ -14973,7 +15041,7 @@ sfnt_vary_compound_glyph (struct sfnt_blend *blend, 
sfnt_glyph id,
     coords = alloca (gvar->axis_count * sizeof *coords * 3);
 
   intermediate_start = coords + gvar->axis_count;
-  intermediate_end = coords + gvar->axis_count;
+  intermediate_end = intermediate_start + gvar->axis_count;
 
   while (ntuples--)
     {
@@ -19158,10 +19226,11 @@ static void
 sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 *format14)
 {
   struct sfnt_uvs_context *context;
-  size_t i, j;
+  size_t i, j, k;
   sfnt_glyph glyph;
   sfnt_char c;
   struct sfnt_nondefault_uvs_table *uvs;
+  struct sfnt_default_uvs_table *default_uvs;
 
   context = sfnt_create_uvs_context (format14, fd);
 
@@ -19176,6 +19245,27 @@ sfnt_test_uvs (int fd, struct sfnt_cmap_format_14 
*format14)
 
       for (i = 0; i < context->num_records; ++i)
        {
+         if (context->records[i].default_uvs)
+           {
+             default_uvs = context->records[i].default_uvs;
+
+             for (j = 0; j < default_uvs->num_unicode_value_ranges; ++j)
+               {
+                 fprintf (stderr, "   Default UVS: %u, %u\n",
+                          default_uvs->ranges[j].start_unicode_value,
+                          default_uvs->ranges[j].additional_count);
+
+                 c = default_uvs->ranges[j].start_unicode_value;
+                 k = 0;
+
+                 for (; k <= default_uvs->ranges[j].additional_count; ++k)
+                   {
+                     if (!sfnt_is_character_default (default_uvs, c + k))
+                       abort ();
+                   }
+               }
+           }
+
          if (!context->records[i].nondefault_uvs)
            continue;
 
diff --git a/src/sfnt.h b/src/sfnt.h
index 6602d240051..41c1f6f74e8 100644
--- a/src/sfnt.h
+++ b/src/sfnt.h
@@ -1526,6 +1526,12 @@ extern sfnt_glyph sfnt_variation_glyph_for_char 
(PROTOTYPE);
 
 #undef PROTOTYPE
 
+#define PROTOTYPE struct sfnt_default_uvs_table *, sfnt_char
+
+extern bool sfnt_is_character_default (PROTOTYPE);
+
+#undef PROTOTYPE
+
 
 
 #ifdef HAVE_MMAP
diff --git a/src/sfntfont.c b/src/sfntfont.c
index 2c58de31a16..35b37396ccd 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -3720,9 +3720,10 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
                               unsigned variations[256])
 {
   struct sfnt_font_info *info;
-  size_t i;
+  size_t i, index;
   int n;
   struct sfnt_mapped_variation_selector_record *record;
+  sfnt_glyph default_glyph;
 
   info = (struct sfnt_font_info *) font;
   n = 0;
@@ -3743,12 +3744,37 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
         && info->uvs->records[i].selector < 0xfe00)
     ++i;
 
+  /* Get the glyph represented by C, used when C is present within a
+     default value table.  */
+
+  default_glyph = sfntfont_lookup_glyph (info, c);
+
   /* Fill in selectors 0 to 15.  */
 
   while (i < info->uvs->num_records
         && info->uvs->records[i].selector <= 0xfe0f)
     {
       record = &info->uvs->records[i];
+      index = info->uvs->records[i].selector - 0xfe00 + 16;
+
+      /* Handle invalid unsorted tables.  */
+
+      if (record->selector < 0xfe00)
+       return 0;
+
+      /* If there are default mappings in this record, ascertain if
+        this glyph matches one of them.  */
+
+      if (record->default_uvs
+         && sfnt_is_character_default (record->default_uvs, c))
+       {
+         variations[index] = default_glyph;
+
+         if (default_glyph)
+           ++n;
+
+         goto next_selector;
+       }
 
       /* If record has no non-default mappings, continue on to the
         next selector.  */
@@ -3756,18 +3782,13 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
       if (!record->nondefault_uvs)
        goto next_selector;
 
-      /* Handle invalid unsorted tables.  */
-
-      if (record->selector < 0xfe00)
-       return 0;
-
       /* Find the glyph ID associated with C and put it in
         VARIATIONS.  */
 
-      variations[info->uvs->records[i].selector - 0xfe00]
+      variations[index]
        = sfnt_variation_glyph_for_char (record->nondefault_uvs, c);
 
-      if (variations[info->uvs->records[i].selector - 0xfe00])
+      if (variations[index])
        ++n;
 
     next_selector:
@@ -3787,6 +3808,26 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
         && info->uvs->records[i].selector <= 0xe01ef)
     {
       record = &info->uvs->records[i];
+      index = info->uvs->records[i].selector - 0xe0100 + 16;
+
+      /* Handle invalid unsorted tables.  */
+
+      if (record->selector < 0xe0100)
+       return 0;
+
+      /* If there are default mappings in this record, ascertain if
+        this glyph matches one of them.  */
+
+      if (record->default_uvs
+         && sfnt_is_character_default (record->default_uvs, c))
+       {
+         variations[index] = default_glyph;
+
+         if (default_glyph)
+           ++n;
+
+         goto next_selector_1;
+       }
 
       /* If record has no non-default mappings, continue on to the
         next selector.  */
@@ -3794,18 +3835,13 @@ sfntfont_get_variation_glyphs (struct font *font, int c,
       if (!record->nondefault_uvs)
        goto next_selector_1;
 
-      /* Handle invalid unsorted tables.  */
-
-      if (record->selector < 0xe0100)
-       return 0;
-
       /* Find the glyph ID associated with C and put it in
         VARIATIONS.  */
 
-      variations[info->uvs->records[i].selector - 0xe0100 + 16]
+      variations[index]
        = sfnt_variation_glyph_for_char (record->nondefault_uvs, c);
 
-      if (variations[info->uvs->records[i].selector - 0xe0100 + 16])
+      if (variations[index])
        ++n;
 
     next_selector_1:
@@ -3841,7 +3877,7 @@ sfntfont_detect_sigbus (void *addr)
   return false;
 }
 
-#endif
+#endif /* HAVE_MMAP */
 
 
 
diff --git a/src/w32.c b/src/w32.c
index c75beb630e5..81201509e2d 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -9387,7 +9387,7 @@ sys_write (int fd, const void * buffer, unsigned int 
count)
         break them into smaller chunks.  See the Comments section of
         the MSDN documentation of WriteFile for details behind the
         choice of the value of CHUNK below.  See also the thread
-        http://thread.gmane.org/gmane.comp.version-control.git/145294
+        http://thread.gmane.org/gmane.comp.version-control.git/145294 [dead 
link]
         in the git mailing list.  */
       const unsigned char *p = buffer;
       const bool is_pipe = (fd < MAXDESC
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 29717954cfd..630a9f4e5fb 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -496,7 +496,7 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
            if (!NILP (Vmouse_autoselect_window))
              {
                Lisp_Object mouse_window = window_from_coordinates (f, mx, my,
-                                                                   0, 0, 0);
+                                                                   0, 0, 0, 0);
                /* A window will be selected only when it is not
                   selected now, and the last mouse movement event was
                   not in it.  A minibuffer window will be selected iff
diff --git a/src/w32term.c b/src/w32term.c
index a5f17a18213..301d8f4ef12 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3376,7 +3376,7 @@ w32_construct_mouse_wheel (struct input_event *result, 
W32Msg *msg,
       if (w32_wheel_scroll_lines == UINT_MAX)
        {
          Lisp_Object window = window_from_coordinates (f, p.x, p.y, NULL,
-                                                       false, false);
+                                                       false, false, false);
          if (!WINDOWP (window))
            {
              result->kind = NO_EVENT;
@@ -5335,7 +5335,7 @@ w32_read_socket (struct terminal *terminal,
                {
                  static Lisp_Object last_mouse_window;
                  Lisp_Object window = window_from_coordinates
-                   (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0, 
0);
+                   (f, LOWORD (msg.msg.lParam), HIWORD (msg.msg.lParam), 0, 0, 
0, 0);
 
                  /* Window will be selected only when it is not
                     selected now and last mouse movement event was
@@ -5407,7 +5407,7 @@ w32_read_socket (struct terminal *terminal,
                    int x = XFIXNAT (inev.x);
                    int y = XFIXNAT (inev.y);
 
-                    window = window_from_coordinates (f, x, y, 0, 1, 1);
+                    window = window_from_coordinates (f, x, y, 0, 1, 1, 1);
 
                     if (EQ (window, f->tab_bar_window))
                       {
@@ -5435,7 +5435,7 @@ w32_read_socket (struct terminal *terminal,
                    int x = XFIXNAT (inev.x);
                    int y = XFIXNAT (inev.y);
 
-                    window = window_from_coordinates (f, x, y, 0, 1, 1);
+                    window = window_from_coordinates (f, x, y, 0, 1, 1, 1);
 
                     if (EQ (window, f->tool_bar_window)
                        /* Make sure the tool bar was previously
diff --git a/src/window.c b/src/window.c
index 968b982c135..e802ffb3fe2 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1680,7 +1680,8 @@ check_window_containing (struct window *w, void 
*user_data)
 
 Lisp_Object
 window_from_coordinates (struct frame *f, int x, int y,
-                        enum window_part *part, bool tab_bar_p, bool 
tool_bar_p)
+                        enum window_part *part, bool menu_bar_p,
+                        bool tab_bar_p, bool tool_bar_p)
 {
   Lisp_Object window;
   struct check_window_data cw;
@@ -1693,6 +1694,21 @@ window_from_coordinates (struct frame *f, int x, int y,
   cw.window = &window, cw.x = x, cw.y = y; cw.part = part;
   foreach_window (f, check_window_containing, &cw);
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_MENU_BAR)
+  /* If not found above, see if it's in the menu bar window, if a menu
+     bar exists.  */
+  if (NILP (window)
+      && menu_bar_p
+      && WINDOWP (f->menu_bar_window)
+      && WINDOW_TOTAL_LINES (XWINDOW (f->menu_bar_window)) > 0
+      && (coordinates_in_window (XWINDOW (f->menu_bar_window), x, y)
+         != ON_NOTHING))
+    {
+      *part = ON_TEXT;
+      window = f->menu_bar_window;
+    }
+#endif
+
 #if defined (HAVE_WINDOW_SYSTEM)
   /* If not found above, see if it's in the tab bar window, if a tab
      bar exists.  */
@@ -1746,7 +1762,7 @@ function returns nil.  */)
                                   + FRAME_INTERNAL_BORDER_WIDTH (f)),
                                  (FRAME_PIXEL_Y_FROM_CANON_Y (f, y)
                                   + FRAME_INTERNAL_BORDER_WIDTH (f)),
-                                 0, false, false);
+                                 0, false, false, false);
 }
 
 ptrdiff_t
diff --git a/src/window.h b/src/window.h
index 413293420fd..9ef8434af18 100644
--- a/src/window.h
+++ b/src/window.h
@@ -1111,7 +1111,7 @@ extern Lisp_Object minibuf_selected_window;
 
 extern Lisp_Object make_window (void);
 extern Lisp_Object window_from_coordinates (struct frame *, int, int,
-                                            enum window_part *, bool, bool);
+                                            enum window_part *, bool, bool, 
bool);
 extern void resize_frame_windows (struct frame *, int, bool);
 extern void restore_window_configuration (Lisp_Object);
 extern void delete_all_child_windows (Lisp_Object);
diff --git a/src/xdisp.c b/src/xdisp.c
index 300308e2f17..56711c190b9 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2778,7 +2778,7 @@ remember_mouse_glyph (struct frame *f, int gx, int gy, 
NativeRectangle *rect)
       goto virtual_glyph;
     }
   else if (!f->glyphs_initialized_p
-          || (window = window_from_coordinates (f, gx, gy, &part, false, 
false),
+          || (window = window_from_coordinates (f, gx, gy, &part, false, 
false, false),
               NILP (window)))
     {
       width = FRAME_SMALLEST_CHAR_WIDTH (f);
@@ -35439,7 +35439,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
     return;
 
   /* Which window is that in?  */
-  window = window_from_coordinates (f, x, y, &part, true, true);
+  window = window_from_coordinates (f, x, y, &part, true, true, true);
 
   /* If displaying active text in another window, clear that.  */
   if (! EQ (window, hlinfo->mouse_face_window)
@@ -35538,6 +35538,16 @@ note_mouse_highlight (struct frame *f, int x, int y)
   w = XWINDOW (window);
   frame_to_window_pixel_xy (w, &x, &y);
 
+#if defined (HAVE_WINDOW_SYSTEM) && ! defined (HAVE_EXT_MENU_BAR)
+  /* Handle menu-bar window differently since it doesn't display a
+     buffer.  */
+  if (EQ (window, f->menu_bar_window))
+    {
+      cursor = FRAME_OUTPUT_DATA (f)->nontext_cursor;
+      goto set_cursor;
+    }
+#endif
+
 #if defined (HAVE_WINDOW_SYSTEM)
   /* Handle tab-bar window differently since it doesn't display a
      buffer.  */
diff --git a/src/xterm.c b/src/xterm.c
index 517bdf57aab..d01c4da0564 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -11820,7 +11820,9 @@ x_frame_highlight (struct frame *f)
   x_stop_ignoring_errors (dpyinfo);
   unblock_input ();
   gui_update_cursor (f, true);
-  x_set_frame_alpha (f);
+
+  if (!FRAME_X_OUTPUT (f)->alpha_identical_p)
+    x_set_frame_alpha (f);
 }
 
 static void
@@ -11844,7 +11846,15 @@ x_frame_unhighlight (struct frame *f)
   unblock_input ();
 
   gui_update_cursor (f, true);
-  x_set_frame_alpha (f);
+
+  /* Eschew modifying the frame alpha when the alpha values for
+     focused and background frames are identical; otherwise, this will
+     upset the order in which changes to the alpha property
+     immediately subsequent to a focus change are propagated into a
+     frame's alpha property.  (bug#66398) */
+
+  if (!FRAME_X_OUTPUT (f)->alpha_identical_p)
+    x_set_frame_alpha (f);
 }
 
 /* The focus has changed.  Update the frames as necessary to reflect
@@ -21161,7 +21171,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                  }
 
                Lisp_Object window = window_from_coordinates
-                 (f, xmotion.x, xmotion.y, 0, false, false);
+                 (f, xmotion.x, xmotion.y, 0, false, false, false);
 
                /* A window will be autoselected only when it is not
                   selected now and the last mouse movement event was
@@ -21892,7 +21902,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 int x = event->xbutton.x;
                 int y = event->xbutton.y;
 
-                window = window_from_coordinates (f, x, y, 0, true, true);
+                window = window_from_coordinates (f, x, y, 0, true, true, 
true);
                 tab_bar_p = EQ (window, f->tab_bar_window);
 
                 if (tab_bar_p)
@@ -21913,7 +21923,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 int x = event->xbutton.x;
                 int y = event->xbutton.y;
 
-                window = window_from_coordinates (f, x, y, 0, true, true);
+                window = window_from_coordinates (f, x, y, 0, true, true, 
true);
                 tool_bar_p = (EQ (window, f->tool_bar_window)
                              && (event->xbutton.type != ButtonRelease
                                  || f->last_tool_bar_item != -1));
@@ -22646,7 +22656,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                            continue;
 
                          window = window_from_coordinates (f, real_x, real_y, 
NULL,
-                                                           false, false);
+                                                           false, false, 
false);
 
                          if (WINDOWP (window))
                            scroll_height = XWINDOW (window)->pixel_height;
@@ -23089,7 +23099,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                          || !NILP (focus_follows_mouse)))
                    {
                      static Lisp_Object last_mouse_window;
-                     Lisp_Object window = window_from_coordinates (f, ev.x, 
ev.y, 0, false, false);
+                     Lisp_Object window = window_from_coordinates (f, ev.x, 
ev.y, 0, false, false,
+                                                                   false);
 
                      /* A window will be autoselected only when it is not
                         selected now and the last mouse movement event was
@@ -23667,7 +23678,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                      int x = bv.x;
                      int y = bv.y;
 
-                     window = window_from_coordinates (f, x, y, 0, true, true);
+                     window = window_from_coordinates (f, x, y, 0, true, true, 
true);
                      tab_bar_p = EQ (window, f->tab_bar_window);
 
                      if (tab_bar_p)
@@ -23688,7 +23699,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                      int x = bv.x;
                      int y = bv.y;
 
-                     window = window_from_coordinates (f, x, y, 0, true, true);
+                     window = window_from_coordinates (f, x, y, 0, true, true, 
true);
                      /* Ignore button release events if the mouse
                         wasn't previously pressed on the tool bar.
                         We do this because otherwise selecting some
@@ -24694,7 +24705,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                  int x = xev->event_x;
                  int y = xev->event_y;
 
-                 window = window_from_coordinates (f, x, y, 0, true, true);
+                 window = window_from_coordinates (f, x, y, 0, true, true, 
true);
                  /* Ignore button release events if the mouse
                     wasn't previously pressed on the tool bar.
                     We do this because otherwise selecting some
diff --git a/test/lisp/align-resources/lua-ts-mode.erts 
b/test/lisp/align-resources/lua-ts-mode.erts
new file mode 100644
index 00000000000..b0473ad6cdf
--- /dev/null
+++ b/test/lisp/align-resources/lua-ts-mode.erts
@@ -0,0 +1,67 @@
+Name: align assignments
+
+=-=
+local first=1
+local s <const> =2
+local last=3
+=-=
+local first     = 1
+local s <const> = 2
+local last      = 3
+=-=-=
+
+Name: align fields
+
+=-=
+local Table={
+first=1,
+second=2,
+last=3,
+}
+=-=
+local Table = {
+    first   = 1,
+    second  = 2,
+    last    = 3,
+}
+=-=-=
+
+Name: align comments
+
+=-=
+local first-- 1
+local second -- 2
+local last      -- 3
+=-=
+local first         -- 1
+local second        -- 2
+local last          -- 3
+=-=-=
+
+Name: align assignments and comments
+
+=-=
+local first=1-- one
+local second=2 -- two
+local last=3    -- three
+=-=
+local first  = 1    -- one
+local second = 2    -- two
+local last   = 3    -- three
+=-=-=
+
+Name: align fields and comments
+
+=-=
+local T={
+first=1,--one
+second=2, --two
+last=3,         --three
+}
+=-=
+local T    = {
+    first  = 1,     --one
+    second = 2,     --two
+    last   = 3,     --three
+}
+=-=-=
diff --git a/test/lisp/align-tests.el b/test/lisp/align-tests.el
index a4d9303827f..f8dd7dcfb9b 100644
--- a/test/lisp/align-tests.el
+++ b/test/lisp/align-tests.el
@@ -49,6 +49,15 @@
   (ert-test-erts-file (ert-resource-file "latex-mode.erts")
                       (test-align-transform-fun #'latex-mode)))
 
+(autoload 'treesit-ready-p "treesit")
+
+(ert-deftest align-lua ()
+  (skip-unless (treesit-ready-p 'lua))
+  (let ((comment-column 20)
+        (indent-tabs-mode nil))
+    (ert-test-erts-file (ert-resource-file "lua-ts-mode.erts")
+                        (test-align-transform-fun #'lua-ts-mode))))
+
 (ert-deftest align-python ()
   (ert-test-erts-file (ert-resource-file "python-mode.erts")
                       (test-align-transform-fun #'python-mode)))
diff --git a/test/lisp/dnd-tests.el b/test/lisp/dnd-tests.el
index 9f97d739cec..7a7f54ba0bb 100644
--- a/test/lisp/dnd-tests.el
+++ b/test/lisp/dnd-tests.el
@@ -33,6 +33,7 @@
 (require 'tramp)
 (require 'select)
 (require 'ert-x)
+(require 'browse-url)
 
 (defvar dnd-tests-selection-table nil
   "Alist of selection names to their values.")
@@ -437,5 +438,162 @@ This function only tries to handle strings."
       (ignore-errors
         (delete-file normal-temp-file)))))
 
+
+
+(defvar dnd-tests-list-1 '("file:///usr/openwin/include/pixrect/pr_impl.h"
+                           "file:///usr/openwin/include/pixrect/pr_io.h")
+  "Sample data for tests concerning the treatment of drag-and-drop URLs.")
+
+(defvar dnd-tests-list-2 '("file:///usr/openwin/include/pixrect/pr_impl.h"
+                           "file://remote/usr/openwin/include/pixrect/pr_io.h")
+  "Sample data for tests concerning the treatment of drag-and-drop URLs.")
+
+(defvar dnd-tests-list-3 (append dnd-tests-list-2 '("http://example.com";))
+  "Sample data for tests concerning the treatment of drag-and-drop URLs.")
+
+(defvar dnd-tests-list-4 (append dnd-tests-list-3 '("scheme1://foo.bar"
+                                                    "scheme2://foo.bar"))
+  "Sample data for tests concerning the treatment of drag-and-drop URLs.")
+
+(defun dnd-tests-local-file-function (urls _action)
+  "Signal an error if URLS doesn't match `dnd-tests-list-1'.
+ACTION is ignored.  Return the symbol `copy' otherwise."
+  (should (equal urls dnd-tests-list-1))
+  'copy)
+
+(put 'dnd-tests-local-file-function 'dnd-multiple-handler t)
+
+(defun dnd-tests-remote-file-function (urls _action)
+  "Signal an error if URLS doesn't match `dnd-tests-list-2'.
+ACTION is ignored.  Return the symbol `copy' otherwise."
+  (should (equal urls dnd-tests-list-2))
+  'copy)
+
+(put 'dnd-tests-remote-file-function 'dnd-multiple-handler t)
+
+(defun dnd-tests-http-scheme-function (url _action)
+  "Signal an error if URLS doesn't match `dnd-tests-list-3''s third element.
+ACTION is ignored.  Return the symbol `private' otherwise."
+  (should (equal url (car (last dnd-tests-list-3))))
+  'private)
+
+(defun dnd-tests-browse-url-handler (url &rest _ignored)
+  "Verify URL is `dnd-tests-list-4''s fourth element."
+  (should (equal url (nth 3 dnd-tests-list-4))))
+
+(put 'dnd-tests-browse-url-handler 'browse-url-browser-kind 'internal)
+
+(ert-deftest dnd-tests-receive-multiple-urls ()
+  (let ((dnd-protocol-alist '(("^file:///" . dnd-tests-local-file-function)
+                              ("^file:" . error)
+                              ("^unrelated-scheme:" . error)))
+        (browse-url-handlers nil))
+    ;; Check that the order of the alist is respected when the
+    ;; precedences of two handlers are equal.
+    (should (equal (dnd-handle-multiple-urls (selected-window)
+                                             (copy-sequence
+                                              dnd-tests-list-1)
+                                             'copy)
+                   'copy))
+    ;; Check that sorting handlers by precedence functions correctly.
+    (setq dnd-protocol-alist '(("^file:///" . error)
+                               ("^file:" . dnd-tests-remote-file-function)
+                               ("^unrelated-scheme:" . error)))
+    (should (equal (dnd-handle-multiple-urls (selected-window)
+                                             (copy-sequence
+                                              dnd-tests-list-2)
+                                             'copy)
+                   'copy))
+    ;; Check that multiple handlers can be called at once, and actions
+    ;; are properly "downgraded" to private when multiple handlers
+    ;; return inconsistent values.
+    (setq dnd-protocol-alist '(("^file:" . dnd-tests-remote-file-function)
+                               ("^file:///" . error)
+                               ("^http://"; . dnd-tests-http-scheme-function)))
+    (should (equal (dnd-handle-multiple-urls (selected-window)
+                                             (copy-sequence
+                                              dnd-tests-list-3)
+                                             'copy)
+                   'private))
+    ;; Now verify that the function's documented fallback behavior
+    ;; functions correctly.  Set browse-url-handlers to an association
+    ;; list incorporating a test function, then guarantee that is
+    ;; called.
+    (setq browse-url-handlers '(("^scheme1://" . 
dnd-tests-browse-url-handler)))
+    ;; Furthermore, guarantee the fifth argument of the test data is
+    ;; inserted, for no apposite handler exists.
+    (save-window-excursion
+      (set-window-buffer nil (get-buffer-create " *dnd-tests*"))
+      (set-buffer (get-buffer-create " *dnd-tests*"))
+      (erase-buffer)
+      (should (equal (dnd-handle-multiple-urls (selected-window)
+                                               (copy-sequence
+                                                dnd-tests-list-4)
+                                               'copy)
+                     'private))
+      (should (equal (buffer-string) (nth 4 dnd-tests-list-4))))
+    ;; Check that a handler enumerated twice in the handler list
+    ;; receives URIs assigned to it only once.
+    (let* ((received-p nil)
+           (lambda (lambda (uri _action)
+                     (should (equal uri "scheme1://test"))
+                     (should (null received-p))
+                     (setq received-p 'copy))))
+      (setq dnd-protocol-alist (list (cons "scheme1://" lambda)
+                                     (cons "scheme1://" lambda)))
+      (should (equal (dnd-handle-multiple-urls (selected-window)
+                                               (list "scheme1://test")
+                                               'copy)
+                     'copy)))))
+
+(ert-deftest dnd-tests-default-file-name-handlers ()
+  (let* ((local-files-opened nil)
+         (remote-files-opened nil)
+         (function-1 (lambda (file _uri)
+                       (push file local-files-opened)
+                       'copy))
+         (function-2 (lambda (file _uri)
+                       (push file remote-files-opened)
+                       'copy)))
+    (unwind-protect
+        (progn
+          (advice-add #'dnd-open-local-file :override
+                      function-1)
+          (advice-add #'dnd-open-file :override
+                      function-2)
+          ;; Guarantee that file names are properly categorized as either
+          ;; local or remote by the default dnd-protocol-alist.
+          (dnd-handle-multiple-urls
+           (selected-window)
+           (list
+            ;; These are run-of-the-mill local file URIs.
+            "file:///usr/include/sys/acct.h"
+            "file:///usr/include/sys/acctctl.h"
+            ;; These URIs incorporate a host; they should match
+            ;; function-2 but never function-1.
+            "file://remotehost/usr/src/emacs/configure.ac"
+            "file://remotehost/usr/src/emacs/configure"
+            ;; These URIs are generated by drag-and-drop event
+            ;; handlers from local file names alone; they are not
+            ;; echt URIs in and of themselves, but a product of our
+            ;; drag and drop code.
+            "file:/etc/vfstab"
+            "file:/etc/dfs/sharetab"
+            ;; These URIs are generated under MS-Windows.
+            "file:c:/path/to/file/name"
+            "file:d:/path/to/file/name")
+           'copy)
+          (should (equal (sort local-files-opened #'string<)
+                         '("file:///usr/include/sys/acct.h"
+                           "file:///usr/include/sys/acctctl.h"
+                           "file:/etc/dfs/sharetab"
+                           "file:/etc/vfstab"
+                           "file:c:/path/to/file/name"
+                           "file:d:/path/to/file/name")))
+          (should (equal (sort remote-files-opened #'string<)
+                         '("file://remotehost/usr/src/emacs/configure"
+                           "file://remotehost/usr/src/emacs/configure.ac"))))
+      (advice-remove #'dnd-open-local-file function-2))))
+
 (provide 'dnd-tests)
 ;;; dnd-tests.el ends here
diff --git a/test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el 
b/test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el
index 00ad1947507..1de5cf66b66 100644
--- a/test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el
+++ b/test/lisp/emacs-lisp/bytecomp-resources/no-byte-compile.el
@@ -1 +1 @@
-;; -*- no-byte-compile: t; -*-
+;; -*- no-byte-compile: t; lexical-binding: t; -*-
diff --git a/test/lisp/emacs-lisp/bytecomp-tests.el 
b/test/lisp/emacs-lisp/bytecomp-tests.el
index e644417c3d4..4aa555f1e92 100644
--- a/test/lisp/emacs-lisp/bytecomp-tests.el
+++ b/test/lisp/emacs-lisp/bytecomp-tests.el
@@ -1302,6 +1302,30 @@ byte-compiled.  Run with dynamic binding."
        (let ((elc (concat ,file-name-var ".elc")))
          (if (file-exists-p elc) (delete-file elc))))))
 
+(defun bytecomp-tests--log-from-compilation (source)
+  "Compile the string SOURCE and return the compilation log output."
+  (let ((text-quoting-style 'grave)
+        (byte-compile-log-buffer (generate-new-buffer " *Compile-Log*")))
+    (with-current-buffer byte-compile-log-buffer
+      (let ((inhibit-read-only t)) (erase-buffer)))
+    (bytecomp-tests--with-temp-file el-file
+      (write-region source nil el-file)
+      (byte-compile-file el-file))
+    (with-current-buffer byte-compile-log-buffer
+      (buffer-string))))
+
+(ert-deftest bytecomp-tests--lexical-binding-cookie ()
+  (cl-flet ((cookie-warning (source)
+              (string-search
+               "file has no `lexical-binding' directive on its first line"
+               (bytecomp-tests--log-from-compilation source))))
+    (let ((some-code "(defun my-fun () 12)\n"))
+      (should-not (cookie-warning
+                   (concat ";;; -*-lexical-binding:t-*-\n" some-code)))
+      (should-not (cookie-warning
+                   (concat ";;; -*-lexical-binding:nil-*-\n" some-code)))
+      (should (cookie-warning some-code)))))
+
 (ert-deftest bytecomp-tests--unescaped-char-literals ()
   "Check that byte compiling warns about unescaped character
 literals (Bug#20852)."
@@ -1310,7 +1334,9 @@ literals (Bug#20852)."
         (byte-compile-debug t)
         (text-quoting-style 'grave))
     (bytecomp-tests--with-temp-file source
-      (write-region "(list ?) ?( ?; ?\" ?[ ?])" nil source)
+      (write-region (concat ";;; -*-lexical-binding:t-*-\n"
+                            "(list ?) ?( ?; ?\" ?[ ?])")
+                    nil source)
       (bytecomp-tests--with-temp-file destination
         (let* ((byte-compile-dest-file-function (lambda (_) destination))
                (err (should-error (byte-compile-file source))))
@@ -1322,7 +1348,9 @@ literals (Bug#20852)."
                                     "`?\\]' expected!")))))))
     ;; But don't warn in subsequent compilations (Bug#36068).
     (bytecomp-tests--with-temp-file source
-      (write-region "(list 1 2 3)" nil source)
+      (write-region (concat ";;; -*-lexical-binding:t-*-\n"
+                            "(list 1 2 3)")
+                    nil source)
       (bytecomp-tests--with-temp-file destination
         (let ((byte-compile-dest-file-function (lambda (_) destination)))
           (should (byte-compile-file source)))))))
@@ -1330,6 +1358,7 @@ literals (Bug#20852)."
 (ert-deftest bytecomp-tests-function-put ()
   "Check `function-put' operates during compilation."
   (bytecomp-tests--with-temp-file source
+    (insert  ";;; -*-lexical-binding:t-*-\n")
     (dolist (form '((function-put 'bytecomp-tests--foo 'foo 1)
                     (function-put 'bytecomp-tests--foo 'bar 2)
                     (defmacro bytecomp-tests--foobar ()
@@ -1636,7 +1665,8 @@ writable (Bug#44631)."
            (byte-compile-error-on-warn t))
       (unwind-protect
           (progn
-            (write-region "" nil input-file nil nil nil 'excl)
+            (write-region ";;; -*-lexical-binding:t-*-\n"
+                          nil input-file nil nil nil 'excl)
             (write-region "" nil output-file nil nil nil 'excl)
             (set-file-modes input-file #o400)
             (set-file-modes output-file #o200)
@@ -1700,7 +1730,8 @@ mountpoint (Bug#44631)."
     (let* ((default-directory directory)
            (byte-compile-dest-file-function (lambda (_) "test.elc"))
            (byte-compile-error-on-warn t))
-      (write-region "" nil "test.el" nil nil nil 'excl)
+      (write-region  ";;; -*-lexical-binding:t-*-\n"
+                     nil "test.el" nil nil nil 'excl)
       (should (byte-compile-file "test.el"))
       (should (file-regular-p "test.elc"))
       (should (cl-plusp (file-attribute-size
diff --git a/test/lisp/emacs-lisp/comp-cstr-tests.el 
b/test/lisp/emacs-lisp/comp-cstr-tests.el
index d2f552af6fa..cbedce0c47d 100644
--- a/test/lisp/emacs-lisp/comp-cstr-tests.el
+++ b/test/lisp/emacs-lisp/comp-cstr-tests.el
@@ -42,14 +42,14 @@
                       ',expected-type-spec))))
 
   (defconst comp-cstr-typespec-tests-alist
-    `(;; 1
+    '(;; 1
       (symbol . symbol)
       ;; 2
       ((or string array) . array)
       ;; 3
       ((or symbol number) . (or number symbol))
       ;; 4
-      ((or cons atom) . (or atom cons)) ;; SBCL return T
+      ((or cons atom) . t) ;; SBCL return T
       ;; 5
       ((or integer number) . number)
       ;; 6
@@ -219,14 +219,18 @@
       ;; 88
       ((and (or (member a b c)) (not (or (member a b)))) . (member c))
       ;; 89
-      ((or cons symbol) . list)
+      ((or cons symbol) . (or list symbol)) ;; FIXME: Why `list'?
       ;; 90
       ((or string char-table bool-vector vector) . array)
       ;; 91
       ((or string char-table bool-vector vector number) . (or array number))
       ;; 92
       ((or string char-table bool-vector vector cons symbol number) .
-       (or number sequence)))
+       (or number sequence symbol))
+      ;; 93?
+      ;; FIXME: I get `cons' rather than `list'?
+      ;;((or null cons) . list)
+      )
     "Alist type specifier -> expected type specifier."))
 
 (defmacro comp-cstr-synthesize-tests ()
diff --git a/test/lisp/erc/erc-fill-tests.el b/test/lisp/erc/erc-fill-tests.el
index f6c4c268017..92424d1e556 100644
--- a/test/lisp/erc/erc-fill-tests.el
+++ b/test/lisp/erc/erc-fill-tests.el
@@ -33,7 +33,6 @@
   (declare (indent 1))
   (let* ((msg (erc-format-privmessage speaker
                                       (apply #'concat msg-parts) nil t))
-         ;; (erc--msg-prop-overrides '((erc-msg . msg) (erc-cmd . PRIVMSG)))
          (parsed (make-erc-response :unparsed msg :sender speaker
                                     :command "PRIVMSG"
                                     :command-args (list "#chan" msg)
@@ -129,10 +128,10 @@
       (should (equal (get-text-property (1- (pos-eol)) 'wrap-prefix)
                      '(space :width erc-fill--wrap-value))))))
 
-;; Set this variable to t to generate new snapshots after carefully
+;; Use this variable to generate new snapshots after carefully
 ;; reviewing the output of *each* snapshot (not just first and last).
 ;; Obviously, only run one test at a time.
-(defvar erc-fill-tests--save-p nil)
+(defvar erc-fill-tests--save-p (getenv "ERC_TESTS_FILL_SAVE"))
 
 ;; On graphical displays, echo .graphic >> .git/info/exclude
 (defvar erc-fill-tests--graphic-dir "fill/snapshots/.graphic")
@@ -162,8 +161,12 @@
         (insert (setq got (read repr))))
       (erc-mode))
     (if erc-fill-tests--save-p
-        (with-temp-file expect-file
-          (insert repr))
+        (let (inhibit-message)
+          (with-temp-file expect-file
+            (insert repr))
+          ;; Limit writing snapshots to one test at a time.
+          (setq erc-fill-tests--save-p nil)
+          (message "erc-fill-tests--compare: wrote %S" expect-file))
       (if (file-exists-p expect-file)
           ;; Ensure string-valued properties, like timestamps, aren't
           ;; recursive (signals `max-lisp-eval-depth' exceeded).
@@ -203,36 +206,39 @@
   (unless (>= emacs-major-version 29)
     (ert-skip "Emacs version too low, missing `buffer-text-pixel-size'"))
 
-  (erc-fill-tests--wrap-populate
-
-   (lambda ()
-     (should (= erc-fill--wrap-value 27))
-     (erc-fill-tests--wrap-check-prefixes "*** " "<alice> " "<bob> ")
-     (erc-fill-tests--compare "monospace-01-start")
-
-     (ert-info ("Shift right by one (plus)")
-       ;; Args are all `erc-fill-wrap-nudge' +1 because interactive "p"
-       (ert-with-message-capture messages
-         ;; M-x erc-fill-wrap-nudge RET =
-         (ert-simulate-command '(erc-fill-wrap-nudge 2))
-         (should (string-match (rx "for further adjustment") messages)))
-       (should (= erc-fill--wrap-value 29))
-       (erc-fill-tests--wrap-check-prefixes "*** " "<alice> " "<bob> ")
-       (erc-fill-tests--compare "monospace-02-right"))
-
-     (ert-info ("Shift left by five")
-       ;; "M-x erc-fill-wrap-nudge RET -----"
-       (ert-simulate-command '(erc-fill-wrap-nudge -4))
-       (should (= erc-fill--wrap-value 25))
-       (erc-fill-tests--wrap-check-prefixes "*** " "<alice> " "<bob> ")
-       (erc-fill-tests--compare "monospace-03-left"))
+  (let ((erc-prompt (lambda () "ABC>")))
+    (erc-fill-tests--wrap-populate
 
-     (ert-info ("Reset")
-       ;; M-x erc-fill-wrap-nudge RET 0
-       (ert-simulate-command '(erc-fill-wrap-nudge 0))
+     (lambda ()
        (should (= erc-fill--wrap-value 27))
        (erc-fill-tests--wrap-check-prefixes "*** " "<alice> " "<bob> ")
-       (erc-fill-tests--compare "monospace-04-reset")))))
+       (erc-fill-tests--compare "monospace-01-start")
+
+       (ert-info ("Shift right by one (plus)")
+         ;; Args are all `erc-fill-wrap-nudge' +1 because interactive "p"
+         (ert-with-message-capture messages
+           ;; M-x erc-fill-wrap-nudge RET =
+           (ert-simulate-command '(erc-fill-wrap-nudge 2))
+           (should (string-match (rx "for further adjustment") messages)))
+         (should (= erc-fill--wrap-value 29))
+         (erc-fill-tests--wrap-check-prefixes "*** " "<alice> " "<bob> ")
+         (erc-fill-tests--compare "monospace-02-right"))
+
+       (ert-info ("Shift left by five")
+         ;; "M-x erc-fill-wrap-nudge RET -----"
+         (ert-simulate-command '(erc-fill-wrap-nudge -4))
+         (should (= erc-fill--wrap-value 25))
+         (erc-fill-tests--wrap-check-prefixes "*** " "<alice> " "<bob> ")
+         (erc-fill-tests--compare "monospace-03-left"))
+
+       (ert-info ("Reset")
+         ;; M-x erc-fill-wrap-nudge RET 0
+         (ert-simulate-command '(erc-fill-wrap-nudge 0))
+         (should (= erc-fill--wrap-value 27))
+         (erc-fill-tests--wrap-check-prefixes "*** " "<alice> " "<bob> ")
+         (erc-fill-tests--compare "monospace-04-reset"))
+
+       (erc--assert-input-bounds)))))
 
 (defun erc-fill-tests--simulate-refill ()
   ;; Simulate `erc-fill-wrap-refill-buffer' synchronously and without
@@ -294,16 +300,20 @@
      ;; Set this here so that the first few messages are from 1970
      (let ((erc-fill-tests--time-vals (lambda () 1680332400)))
        (erc-fill-tests--insert-privmsg "bob" "zero.")
+       (erc-fill-tests--insert-privmsg "bob" "0.5")
 
        (erc-process-ctcp-query
         erc-server-process
         (make-erc-response
-         :unparsed ":bob!~u@fake PRIVMSG #chan :\1ACTION one\1"
-         :sender "bob!~u@fake" :command "PRIVMSG"
-         :command-args '("#chan" "\1ACTION one\1") :contents "\1ACTION one\1")
+         :unparsed ":bob!~u@fake PRIVMSG #chan :\1ACTION one.\1"
+         :sender "bob!~u@fake"
+         :command "PRIVMSG"
+         :command-args '("#chan" "\1ACTION one.\1")
+         :contents "\1ACTION one.\1")
         "bob" "~u" "fake")
 
        (erc-fill-tests--insert-privmsg "bob" "two.")
+       (erc-fill-tests--insert-privmsg "bob" "2.5")
 
        ;; Compat switch to opt out of overhanging speaker.
        (let (erc-fill--wrap-action-dedent-p)
diff --git a/test/lisp/erc/erc-networks-tests.el 
b/test/lisp/erc/erc-networks-tests.el
index e95d99c128f..d0f1dddf6b3 100644
--- a/test/lisp/erc/erc-networks-tests.el
+++ b/test/lisp/erc/erc-networks-tests.el
@@ -623,11 +623,6 @@
                                :symbol 'foonet/dummy
                                :parts [foonet "dummy"]
                                :len 2)
-             ;; `erc-kill-buffer-function' uses legacy target detection
-             ;; but falls back on buffer name, so no need for:
-             ;;
-             ;;   erc-default-recipients '("#a")
-             ;;
              erc--target (erc--target-from-string "#a")
              erc-server-process (with-temp-buffer
                                   (erc-networks-tests--create-dead-proc)))
@@ -1206,7 +1201,7 @@
           calls)
       (erc-mode)
 
-      (cl-letf (((symbol-function 'erc-display-line)
+      (cl-letf (((symbol-function 'erc--route-insertion)
                  (lambda (&rest r) (push r calls))))
 
         (ert-info ("Signals when `erc-server-announced-name' unset")
diff --git a/test/lisp/erc/erc-scenarios-base-reuse-buffers.el 
b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
index 71027a0c138..af483bb1a52 100644
--- a/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
+++ b/test/lisp/erc/erc-scenarios-base-reuse-buffers.el
@@ -124,6 +124,7 @@ Adapted from scenario clash-of-chans/uniquify described in 
Bug#48598:
         (erc-d-t-search-for 1 "shake my sword")
         (erc-cmd-PART "#chan")
         (funcall expect 3 "You have left channel #chan")
+        (should-not (erc-get-channel-user (erc-current-nick)))
         (erc-cmd-JOIN "#chan")))
 
     (ert-info ("Part #chan@barnet")
@@ -139,6 +140,7 @@ Adapted from scenario clash-of-chans/uniquify described in 
Bug#48598:
       (get-buffer "#chan/127.0.0.1<3>"))
 
     (ert-info ("Activity continues in new, <n>-suffixed #chan@foonet buffer")
+      ;; The first /JOIN did not cause the same buffer to be reused.
       (with-current-buffer "#chan/127.0.0.1"
         (should-not (erc-get-channel-user (erc-current-nick))))
       (with-current-buffer "#chan/127.0.0.1<3>"
diff --git a/test/lisp/erc/erc-scenarios-display-message.el 
b/test/lisp/erc/erc-scenarios-display-message.el
new file mode 100644
index 00000000000..51bdf305ad5
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-display-message.el
@@ -0,0 +1,64 @@
+;;; erc-scenarios-display-message.el --- erc-display-message -*- 
lexical-binding: t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert-x)
+(eval-and-compile
+  (let ((load-path (cons (ert-resource-directory) load-path)))
+    (require 'erc-scenarios-common)))
+
+(ert-deftest erc-scenarios-display-message--multibuf ()
+  :tags '(:expensive-test)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/display-message")
+       (dumb-server (erc-d-run "localhost" t 'multibuf))
+       (port (process-contact dumb-server :service))
+       (erc-server-flood-penalty 0.1)
+       (erc-modules (cons 'fill-wrap erc-modules))
+       (erc-autojoin-channels-alist '((foonet "#chan")))
+       (expect (erc-d-t-make-expecter)))
+
+    (ert-info ("Connect to foonet")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :full-name "tester")
+        (funcall expect 10 "debug mode")))
+
+    (ert-info ("User dummy is a member of #chan")
+      (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+        (funcall expect 10 "dummy")))
+
+    (ert-info ("Dummy's QUIT notice in query contains metadata props")
+      (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "dummy"))
+        (funcall expect 10 "<dummy> hi")
+        (funcall expect 10 "*** dummy (~u@rdjcgiwfuwqmc.irc) has quit")
+        (should (eq 'QUIT (get-text-property (match-beginning 0) 'erc-msg)))))
+
+    (ert-info ("Dummy's QUIT notice in #chan contains metadata props")
+      (with-current-buffer (erc-d-t-wait-for 5 (get-buffer "#chan"))
+        (funcall expect 10 "*** dummy (~u@rdjcgiwfuwqmc.irc) has quit")
+        (should (eq 'QUIT (get-text-property (match-beginning 0) 'erc-msg)))))
+
+    (erc-cmd-QUIT "")))
+
+(eval-when-compile (require 'erc-join))
+
+;;; erc-scenarios-display-message.el ends here
diff --git a/test/lisp/erc/erc-scenarios-log.el 
b/test/lisp/erc/erc-scenarios-log.el
index f7e7d61c92e..cd28ea54b2e 100644
--- a/test/lisp/erc/erc-scenarios-log.el
+++ b/test/lisp/erc/erc-scenarios-log.el
@@ -149,7 +149,7 @@
     (when noninteractive (delete-directory tempdir :recursive))))
 
 (ert-deftest erc-scenarios-log--truncate ()
-  :tags '(:expensive-test)
+  :tags '(:expensive-test :unstable)
   (erc-scenarios-common-with-cleanup
       ((erc-scenarios-common-dialog "base/assoc/bouncer-history")
        (dumb-server (erc-d-run "localhost" t 'foonet))
diff --git a/test/lisp/erc/erc-scenarios-stamp.el 
b/test/lisp/erc/erc-scenarios-stamp.el
new file mode 100644
index 00000000000..b98300d04be
--- /dev/null
+++ b/test/lisp/erc/erc-scenarios-stamp.el
@@ -0,0 +1,116 @@
+;;; erc-scenarios-stamp.el --- Misc `erc-stamp' scenarios -*- lexical-binding: 
t -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert-x)
+(eval-and-compile
+  (let ((load-path (cons (ert-resource-directory) load-path)))
+    (require 'erc-scenarios-common)))
+
+(require 'erc-stamp)
+
+(defvar erc-scenarios-stamp--user-marker nil)
+
+(defun erc-scenarios-stamp--on-post-modify ()
+  (when-let (((erc--check-msg-prop 'erc-cmd 4)))
+    (set-marker erc-scenarios-stamp--user-marker (point-max))
+    (ert-info ("User marker correctly placed at `erc-insert-marker'")
+      (should (= ?\n (char-before erc-scenarios-stamp--user-marker)))
+      (should (= erc-scenarios-stamp--user-marker erc-insert-marker))
+      (save-excursion
+        (goto-char erc-scenarios-stamp--user-marker)
+        ;; The raw message ends in " Iabefhkloqv".  However,
+        ;; `erc-server-004' only prints up to the 5th parameter.
+        (should (looking-back "CEIMRUabefhiklmnoqstuv\n"))))))
+
+(ert-deftest erc-scenarios-stamp--left/display-margin-mode ()
+
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "base/reconnect")
+       (dumb-server (erc-d-run "localhost" t 'unexpected-disconnect))
+       (port (process-contact dumb-server :service))
+       (erc-scenarios-stamp--user-marker (make-marker))
+       (erc-stamp--current-time 704591940)
+       (erc-stamp--tz t)
+       (erc-server-flood-penalty 0.1)
+       (erc-insert-timestamp-function #'erc-insert-timestamp-left)
+       (erc-modules (cons 'fill-wrap erc-modules))
+       (erc-timestamp-only-if-changed-flag nil)
+       (expect (erc-d-t-make-expecter)))
+
+    (ert-info ("Connect")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :full-name "tester"
+                                :nick "tester")
+
+        (add-hook 'erc-insert-post-hook #'erc-scenarios-stamp--on-post-modify
+                  nil t)
+        (funcall expect 5 "This server is in debug mode")
+
+        (ert-info ("Stamps appear in left margin and are invisible")
+          (should (eq 'erc-timestamp (field-at-pos (pos-bol))))
+          (should (= (pos-bol) (field-beginning (pos-bol))))
+          (should (eq 'msg (get-text-property (pos-bol) 'erc-msg)))
+          (should (eq 'NOTICE (get-text-property (pos-bol) 'erc-cmd)))
+          (should (= ?- (char-after (field-end (pos-bol)))))
+          (should (equal (get-text-property (1+ (field-end (pos-bol)))
+                                            'erc-speaker)
+                         "irc.foonet.org"))
+          (should (pcase (get-text-property (pos-bol) 'display)
+                    (`((margin left-margin) ,s)
+                     (eq 'timestamp (get-text-property 0 'invisible s))))))
+
+        ;; We set a third-party marker at the end of 004's message (on
+        ;; then "\n"), post-insertion.
+        (ert-info ("User markers untouched by subsequent message left stamp")
+          (save-excursion
+            (goto-char erc-scenarios-stamp--user-marker)
+            (should (looking-back "CEIMRUabefhiklmnoqstuv\n"))
+            (should (looking-at (rx "[")))))))))
+
+(ert-deftest erc-scenarios-stamp--legacy-date-stamps ()
+  (with-suppressed-warnings ((obsolete erc-stamp-prepend-date-stamps-p))
+    (erc-scenarios-common-with-cleanup
+        ((erc-scenarios-common-dialog "base/reconnect")
+         (erc-stamp-prepend-date-stamps-p t)
+         (dumb-server (erc-d-run "localhost" t 'unexpected-disconnect))
+         (port (process-contact dumb-server :service))
+         (erc-server-flood-penalty 0.1)
+         (expect (erc-d-t-make-expecter)))
+
+      (ert-info ("Connect")
+        (with-current-buffer (erc :server "127.0.0.1"
+                                  :port port
+                                  :full-name "tester"
+                                  :nick "tester")
+          (funcall expect 5 "Opening connection")
+          (goto-char (1- (match-beginning 0)))
+          (should (eq 'erc-timestamp (field-at-pos (point))))
+          (should (eq 'unknown (erc--get-inserted-msg-prop 'erc-msg)))
+          ;; Force redraw of date stamp.
+          (setq erc-timestamp-last-inserted-left nil)
+
+          (funcall expect 5 "This server is in debug mode")
+          (while (and (zerop (forward-line -1))
+                      (not (eq 'erc-timestamp (field-at-pos (point))))))
+          (should (erc--get-inserted-msg-prop 'erc-cmd)))))))
+
+;;; erc-scenarios-stamp.el ends here
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 4f4662f5075..1af087e7e31 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -69,26 +69,25 @@
     (with-current-buffer (get-buffer-create "#foo")
       (erc-mode)
       (setq erc-server-process proc-exnet)
-      (setq erc-default-recipients '("#foo")))
+      (setq erc--target (erc--target-from-string "#foo")))
 
     (with-current-buffer (get-buffer-create "#spam")
       (erc-mode)
       (setq erc-server-process proc-onet)
-      (setq erc-default-recipients '("#spam")))
+      (setq erc--target (erc--target-from-string "#spam")))
 
     (with-current-buffer (get-buffer-create "#bar")
       (erc-mode)
       (setq erc-server-process proc-onet)
-      (setq erc-default-recipients '("#bar")))
+      (setq erc--target (erc--target-from-string "#bar")))
 
     (with-current-buffer (get-buffer-create "#baz")
       (erc-mode)
       (setq erc-server-process proc-exnet)
-      (setq erc-default-recipients '("#baz")))
+      (setq erc--target (erc--target-from-string "#baz")))
 
     (should (eq (get-buffer-process "ExampleNet") proc-exnet))
-    (erc-with-all-buffers-of-server (get-buffer-process "ExampleNet")
-      nil
+    (erc-with-all-buffers-of-server (get-buffer-process "ExampleNet") nil
       (kill-buffer))
 
     (should-not (get-buffer "ExampleNet"))
@@ -102,8 +101,7 @@
            (calls 0)
            (get-test (lambda () (cl-incf calls) test)))
 
-      (erc-with-all-buffers-of-server proc-onet
-        (funcall get-test)
+      (erc-with-all-buffers-of-server proc-onet (funcall get-test)
         (kill-buffer))
 
       (should (= calls 1)))
@@ -812,7 +810,7 @@
 
 (ert-deftest erc--target-from-string ()
   (should (equal (erc--target-from-string "#chan")
-                 #s(erc--target-channel "#chan" \#chan)))
+                 #s(erc--target-channel "#chan" \#chan nil)))
 
   (should (equal (erc--target-from-string "Bob")
                  #s(erc--target "Bob" bob)))
@@ -820,7 +818,7 @@
   (let ((erc--isupport-params (make-hash-table)))
     (puthash 'CHANTYPES  '("&#") erc--isupport-params)
     (should (equal (erc--target-from-string "&Bitlbee")
-                   #s(erc--target-channel-local "&Bitlbee" &bitlbee)))))
+                   #s(erc--target-channel-local "&Bitlbee" &bitlbee nil)))))
 
 (ert-deftest erc--modify-local-map ()
   (when (and (bound-and-true-p erc-irccontrols-mode)
@@ -1434,6 +1432,80 @@
 
           (should-not calls))))))
 
+(ert-deftest erc--delete-inserted-message ()
+  (erc-mode)
+  (erc--initialize-markers (point) nil)
+  ;; Put unique invisible properties on the line endings.
+  (erc-display-message nil 'notice nil "one")
+  (put-text-property (1- erc-insert-marker) erc-insert-marker 'invisible 'a)
+  (let ((erc--msg-prop-overrides '((erc-msg . datestamp) (erc-ts . 0))))
+    (erc-display-message nil nil nil
+                         (propertize "\n[date]" 'field 'erc-timestamp)))
+  (put-text-property (1- erc-insert-marker) erc-insert-marker 'invisible 'b)
+  (erc-display-message nil 'notice nil "two")
+
+  (ert-info ("Date stamp deleted cleanly")
+    (goto-char 11)
+    (should (looking-at (rx "\n[date]")))
+    (should (eq 'datestamp (get-text-property (point) 'erc-msg)))
+    (should (eq (point) (field-beginning (1+ (point)))))
+
+    (erc--delete-inserted-message (point))
+
+    ;; Preceding line ending clobbered, replaced by trailing.
+    (should (looking-back (rx "*** one\n")))
+    (should (looking-at (rx "*** two")))
+    (should (eq 'b (get-text-property (1- (point)) 'invisible))))
+
+  (ert-info ("Markers at pos-bol preserved")
+    (erc-display-message nil 'notice nil "three")
+    (should (looking-at (rx "*** two")))
+
+    (let ((m (point-marker))
+          (n (point-marker))
+          (p (point)))
+      (set-marker-insertion-type m t)
+      (goto-char (point-max))
+      (erc--delete-inserted-message p)
+      (should (= (marker-position n) p))
+      (should (= (marker-position m) p))
+      (goto-char p)
+      (set-marker m nil)
+      (set-marker n nil)
+      (should (looking-back (rx "*** one\n")))
+      (should (looking-at (rx "*** three")))))
+
+  (ert-info ("Compat")
+    (erc-display-message nil 'notice nil "four")
+    (should (looking-at (rx "*** three\n")))
+    (with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p))
+      (let ((erc-legacy-invisible-bounds-p t))
+        (erc--delete-inserted-message (point))))
+    (should (looking-at (rx "*** four\n"))))
+
+  (ert-info ("Deleting most recent message preserves markers")
+    (let ((m (point-marker))
+          (n (point-marker))
+          (p (point)))
+      (should (equal "*** four\n" (buffer-substring p erc-insert-marker)))
+      (set-marker-insertion-type m t)
+      (goto-char (point-max))
+      (erc--delete-inserted-message p)
+      (should (= (marker-position m) p))
+      (should (= (marker-position n) p))
+      (goto-char p)
+      (should (looking-back (rx "*** one\n")))
+      (should (looking-at erc-prompt))
+      (erc--assert-input-bounds)
+
+      ;; However, `m' is now forever "trapped" at `erc-insert-marker'.
+      (erc-display-message nil 'notice nil "two")
+      (should (= m erc-insert-marker))
+      (goto-char n)
+      (should (looking-at (rx "*** two\n")))
+      (set-marker m nil)
+      (set-marker n nil))))
+
 (ert-deftest erc--order-text-properties-from-hash ()
   (let ((table (map-into '((a . 1)
                            (erc-ts . 0)
@@ -1846,6 +1918,7 @@
         (erc-mode)
         (setq erc-server-process (buffer-local-value 'erc-server-process
                                                      (get-buffer "ExampleNet"))
+              erc--target (erc--target-from-string "#chan")
               erc-default-recipients '("#chan")
               erc-channel-users (make-hash-table :test 'equal)
               erc-network 'ExampleNet)
@@ -1938,6 +2011,69 @@
                2 5 (erc-speaker "Bob" font-lock-face erc-nick-default-face)
                5 12 (font-lock-face erc-default-face))))))
 
+(ert-deftest erc--route-insertion ()
+  (erc-tests--send-prep)
+  (erc-tests--set-fake-server-process "sleep" "1")
+  (setq erc-networks--id (erc-networks--id-create 'foonet))
+
+  (let* ((erc-modules) ; for `erc--open-target'
+         (server-buffer (current-buffer))
+         (spam-buffer (save-excursion (erc--open-target "#spam")))
+         (chan-buffer (save-excursion (erc--open-target "#chan")))
+         calls)
+    (cl-letf (((symbol-function 'erc-insert-line)
+               (lambda (&rest r) (push (cons 'line-1 r) calls))))
+
+      (with-current-buffer chan-buffer
+
+        (ert-info ("Null `buffer' routes to live server-buffer")
+          (erc--route-insertion "null" nil)
+          (should (equal (pop calls) `(line-1 "null" ,server-buffer)))
+          (should-not calls))
+
+        (ert-info ("Cons `buffer' routes to live members")
+          ;; Copies a let-bound `erc--msg-props' before mutating.
+          (let* ((table (map-into '(erc-msg msg) 'hash-table))
+                 (erc--msg-props table))
+            (erc--route-insertion "cons" (list server-buffer spam-buffer))
+            (should-not (eq table erc--msg-props)))
+          (should (equal (pop calls) `(line-1 "cons" ,spam-buffer)))
+          (should (equal (pop calls) `(line-1 "cons" ,server-buffer)))
+          (should-not calls))
+
+        (ert-info ("Variant `all' inserts in all session buffers")
+          (erc--route-insertion "all" 'all)
+          (should (equal (pop calls) `(line-1 "all" ,chan-buffer)))
+          (should (equal (pop calls) `(line-1 "all" ,spam-buffer)))
+          (should (equal (pop calls) `(line-1 "all" ,server-buffer)))
+          (should-not calls))
+
+        (ert-info ("Variant `active' routes to active buffer if alive")
+          (should (eq chan-buffer (erc-with-server-buffer erc-active-buffer)))
+          (erc-set-active-buffer spam-buffer)
+          (erc--route-insertion "act" 'active)
+          (should (equal (pop calls) `(line-1 "act" ,spam-buffer)))
+          (should (eq (erc-active-buffer) spam-buffer))
+          (should-not calls))
+
+        (ert-info ("Variant `active' falls back to current buffer")
+          (should (eq spam-buffer (erc-active-buffer)))
+          (kill-buffer "#spam")
+          (erc--route-insertion "nact" 'active)
+          (should (equal (pop calls) `(line-1 "nact" ,server-buffer)))
+          (should (eq (erc-with-server-buffer erc-active-buffer)
+                      server-buffer))
+          (should-not calls))
+
+        (ert-info ("Dead single buffer defaults to live server-buffer")
+          (should-not (get-buffer "#spam"))
+          (erc--route-insertion "dead" 'spam-buffer)
+          (should (equal (pop calls) `(line-1 "dead" ,server-buffer)))
+          (should-not calls))))
+
+    (should-not (buffer-live-p spam-buffer))
+    (kill-buffer chan-buffer)))
+
 (defvar erc-tests--ipv6-examples
   '("1:2:3:4:5:6:7:8"
     "::ffff:10.0.0.1" "::ffff:1.2.3.4" "::ffff:0.0.0.0"
@@ -2512,6 +2648,7 @@
   (let* ((calls nil)
          (custom-modes nil)
          (on-load nil)
+         (text-quoting-style 'grave)
 
          (get-calls (lambda () (prog1 (nreverse calls) (setq calls nil))))
 
@@ -2554,8 +2691,8 @@
               (obarray (obarray-make))
               (err (should-error (erc--update-modules erc-modules))))
          (should (equal (cadr err) "`foo' is not a known ERC module"))
-         (should (equal (funcall get-calls)
-                        `((req . ,(intern-soft "erc-foo")))))))
+         (should (equal (mapcar #'prin1-to-string (funcall get-calls))
+                        '("(req . erc-foo)")))))
 
      ;; Module's mode command exists but lacks an associated file.
      (ert-info ("Bad autoload flagged as suspect")
@@ -2564,10 +2701,8 @@
               (obarray (obarray-make))
               (erc-modules (list (intern "foo"))))
 
-         ;; Create a mode activation command.
+         ;; Create a mode-activation command and make mode-var global.
          (funcall mk-cmd "foo")
-
-         ;; Make the mode var global.
          (funcall mk-global "foo")
 
          ;; No local modules to return.
@@ -2576,7 +2711,7 @@
                         '("foo")))
          ;; ERC requires the library via prefixed module name.
          (should (equal (mapcar #'prin1-to-string (funcall get-calls))
-                        `("(req . erc-foo)" "(erc-foo-mode . 1)"))))))))
+                        '("(req . erc-foo)" "(erc-foo-mode . 1)"))))))))
 
 ;; A local module (here, `lo2') lacks a mode toggle, so ERC tries to
 ;; load its defining library, first via the symbol property
diff --git a/test/lisp/erc/resources/base/display-message/multibuf.eld 
b/test/lisp/erc/resources/base/display-message/multibuf.eld
new file mode 100644
index 00000000000..e49a654cd06
--- /dev/null
+++ b/test/lisp/erc/resources/base/display-message/multibuf.eld
@@ -0,0 +1,45 @@
+;; -*- mode: lisp-data; -*-
+((nick 10 "NICK tester"))
+((user 10 "USER user 0 * :tester")
+ (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
+ (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running 
version ergo-v2.11.1")
+ (0.01 ":irc.foonet.org 003 tester :This server was created Sat, 14 Oct 2023 
16:08:20 UTC")
+ (0.02 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios 
CEIMRUabefhiklmnoqstuv Iabefhkloqv")
+ (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii 
CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# 
CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by 
this server")
+ (0.01 ":irc.foonet.org 005 tester KICKLEN=390 MAXLIST=beI:60 MAXTARGETS=4 
MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ 
TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100
 TOPICLEN=390 UTF8ONLY WHOX :are supported by this server")
+ (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by 
this server")
+ (0.00 ":irc.foonet.org 251 tester :There are 0 users and 5 invisible on 1 
server(s)")
+ (0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
+ (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
+ (0.00 ":irc.foonet.org 254 tester 2 :channels formed")
+ (0.00 ":irc.foonet.org 255 tester :I have 5 clients and 0 servers")
+ (0.00 ":irc.foonet.org 265 tester 5 5 :Current local users 5, max 5")
+ (0.02 ":irc.foonet.org 266 tester 5 5 :Current global users 5, max 5")
+ (0.01 ":irc.foonet.org 422 tester :MOTD File is missing")
+ (0.00 ":irc.foonet.org 221 tester +i")
+ (0.01 ":irc.foonet.org NOTICE tester :This server is in debug mode and is 
logging all user I/O. If you do not wish for everything you send to be readable 
by the server owner(s), please disconnect."))
+
+((mode 10 "MODE tester +i")
+ (0.00 ":irc.foonet.org 221 tester +i"))
+
+((join 10 "JOIN #chan")
+ (0.03 ":tester!~u@rdjcgiwfuwqmc.irc JOIN #chan")
+ (0.03 ":irc.foonet.org 353 tester = #chan :@fsbot bob alice dummy tester")
+ (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list")
+ (0.00 ":bob!~u@uee7kge7ua5sy.irc PRIVMSG #chan :tester, welcome!")
+ (0.01 ":alice!~u@uee7kge7ua5sy.irc PRIVMSG #chan :tester, welcome!"))
+
+((mode 10 "MODE #chan")
+ (0.01 ":bob!~u@uee7kge7ua5sy.irc PRIVMSG #chan :alice: Persuade this rude 
wretch willingly to die.")
+ (0.01 ":irc.foonet.org 324 tester #chan +Cnt")
+ (0.01 ":irc.foonet.org 329 tester #chan 1697299707")
+ (0.03 ":alice!~u@uee7kge7ua5sy.irc PRIVMSG #chan :bob: It might be yours or 
hers, for aught I know.")
+ (0.07 ":bob!~u@uee7kge7ua5sy.irc PRIVMSG #chan :Would all themselves laugh 
mortal.")
+ (0.04 ":dummy!~u@rdjcgiwfuwqmc.irc PRIVMSG tester :hi")
+ (0.06 ":bob!~u@uee7kge7ua5sy.irc PRIVMSG #chan :alice: It hath pleased the 
devil drunkenness to give place to the devil wrath; one unperfectness shows me 
another, to make me frankly despise myself.")
+ (0.05 ":dummy!~u@rdjcgiwfuwqmc.irc QUIT :Quit: \2ERC\2 5.6-git (IRC client 
for GNU Emacs 30.0.50)")
+ (0.08 ":alice!~u@uee7kge7ua5sy.irc PRIVMSG #chan :You speak of him when he 
was less furnished than now he is with that which makes him both without and 
within."))
+
+((quit 10 "QUIT :\2ERC\2")
+ (0.04 ":tester!~u@rdjcgiwfuwqmc.irc QUIT :Quit: \2ERC\2 5.x (IRC client for 
GNU Emacs)")
+ (0.02 "ERROR :Quit: \2ERC\2 5.x (IRC client for GNU Emacs)"))
diff --git a/test/lisp/erc/resources/base/renick/queries/solo.eld 
b/test/lisp/erc/resources/base/renick/queries/solo.eld
index 12fa7d264e9..fa4c075adac 100644
--- a/test/lisp/erc/resources/base/renick/queries/solo.eld
+++ b/test/lisp/erc/resources/base/renick/queries/solo.eld
@@ -30,7 +30,7 @@
  (0 ":irc.foonet.org NOTICE tester :[09:56:57] This server is in debug mode 
and is logging all user I/O. If you do not wish for everything you send to be 
readable by the server owner(s), please disconnect.")
  (0 ":irc.foonet.org 305 tester :You are no longer marked as being away"))
 
-((mode 1 "MODE #foo")
+((mode 10 "MODE #foo")
  (0 ":irc.foonet.org 324 tester #foo +nt")
  (0 ":irc.foonet.org 329 tester #foo 1622454985")
  (0.1 ":alice!~u@gq7yjr7gsu7nn.irc PRIVMSG #foo :bob: Farewell, pretty lady: 
you must hold the credit of your father.")
diff --git a/test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld 
b/test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld
index efc2506fd6f..d106a45cf66 100644
--- a/test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld
+++ b/test/lisp/erc/resources/base/reuse-buffers/channel/barnet.eld
@@ -56,7 +56,7 @@
  (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :tester, welcome!")
  (0 ":joe!~u@wvys46tx8tpmk.irc PRIVMSG #chan :tester, welcome!"))
 
-((mode 1 "MODE #chan")
+((mode 10 "MODE #chan")
  (0 ":irc.barnet.org 324 tester #chan +nt")
  (0 ":irc.barnet.org 329 tester #chan 1620205534")
  (0.1 ":mike!~u@wvys46tx8tpmk.irc PRIVMSG #chan :joe: Chi non te vede, non te 
pretia.")
diff --git a/test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld 
b/test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld
index a11cfac2e73..603afa2fc3e 100644
--- a/test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld
+++ b/test/lisp/erc/resources/base/reuse-buffers/channel/foonet.eld
@@ -52,7 +52,7 @@
  (0.1 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :tester, welcome!")
  (0 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :tester, welcome!"))
 
-((mode 1 "MODE #chan")
+((mode 10 "MODE #chan")
  (0 ":irc.foonet.org 324 tester #chan +nt")
  (0 ":irc.foonet.org 329 tester #chan 1620205534")
  (0.1 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: Thou desirest me to 
stop in my tale against the hair.")
diff --git a/test/lisp/erc/resources/erc-d/erc-d-t.el 
b/test/lisp/erc/resources/erc-d/erc-d-t.el
index cf869fb3c70..7126165fd91 100644
--- a/test/lisp/erc/resources/erc-d/erc-d-t.el
+++ b/test/lisp/erc/resources/erc-d/erc-d-t.el
@@ -157,6 +157,7 @@ ON-SUCCESS, is nonexistent.  To reset, specify a FROM 
argument."
   (let (positions)
     (lambda (timeout text &optional reset-from)
       (let* ((pos (cdr (assq (current-buffer) positions)))
+             (erc-d-t--wait-message-prefix (and (< timeout 0) "Sustaining: "))
              (cb (lambda ()
                    (unless pos
                      (push (cons (current-buffer) (setq pos (make-marker)))
diff --git a/test/lisp/erc/resources/erc-scenarios-common.el 
b/test/lisp/erc/resources/erc-scenarios-common.el
index 5354b300b47..9e134e6932f 100644
--- a/test/lisp/erc/resources/erc-scenarios-common.el
+++ b/test/lisp/erc/resources/erc-scenarios-common.el
@@ -574,7 +574,7 @@ buffer-naming collisions involving bouncers in ERC."
                                 :password "changeme"
                                 :full-name "tester")
         (erc-scenarios-common-assert-initial-buf-name nil port)
-        (erc-d-t-wait-for 3 (eq (erc-network) 'foonet))
+        (erc-d-t-wait-for 6 (eq (erc-network) 'foonet))
         (erc-d-t-wait-for 3 (string= (buffer-name) "foonet"))
         (funcall expect 5 "foonet")))
 
@@ -713,7 +713,7 @@ Bug#48598: 28.0.50; buffer-naming collisions involving 
bouncers in ERC."
         (erc-d-t-wait-for 3 (eq erc-server-process erc-server-process-foo))
         (funcall expect 3 "<bob>")
         (erc-d-t-absent-for 0.1 "<joe>")
-        (funcall expect 10 "not given me")))
+        (funcall expect 20 "not given me")))
 
     (ert-info ("All #chan@barnet output received")
       (with-current-buffer chan-buf-bar
diff --git a/test/lisp/erc/resources/fill/snapshots/merge-01-start.eld 
b/test/lisp/erc/resources/fill/snapshots/merge-01-start.eld
index 238d8cc73c2..8a6f2289f5d 100644
--- a/test/lisp/erc/resources/fill/snapshots/merge-01-start.eld
+++ b/test/lisp/erc/resources/fill/snapshots/merge-01-start.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr  1 
2023]\n<bob> zero.[07:00]\n<alic [...]
\ No newline at end of file
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr  1 
2023]\n<bob> zero.[07:00]\n<alic [...]
diff --git a/test/lisp/erc/resources/fill/snapshots/merge-02-right.eld 
b/test/lisp/erc/resources/fill/snapshots/merge-02-right.eld
index d1ce9198e69..3eb4be4919b 100644
--- a/test/lisp/erc/resources/fill/snapshots/merge-02-right.eld
+++ b/test/lisp/erc/resources/fill/snapshots/merge-02-right.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr  1 
2023]\n<bob> zero.[07:00]\n<alic [...]
\ No newline at end of file
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr  1 
2023]\n<bob> zero.[07:00]\n<alic [...]
diff --git a/test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld 
b/test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld
index d70184724ba..f966daeed1f 100644
--- a/test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld
+++ b/test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr  1 
2023]\n<bob> zero.[07:00]\n* bob [...]
\ No newline at end of file
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr  1 
2023]\n<bob> zero.[07:00]\n<bob> [...]
\ No newline at end of file
diff --git a/test/lisp/erc/resources/fill/snapshots/monospace-01-start.eld 
b/test/lisp/erc/resources/fill/snapshots/monospace-01-start.eld
index def97738ce6..84a1e34670c 100644
--- a/test/lisp/erc/resources/fill/snapshots/monospace-01-start.eld
+++ b/test/lisp/erc/resources/fill/snapshots/monospace-01-start.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
\ No newline at end of file
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
diff --git a/test/lisp/erc/resources/fill/snapshots/monospace-02-right.eld 
b/test/lisp/erc/resources/fill/snapshots/monospace-02-right.eld
index be3e2b33cfd..83394f2f639 100644
--- a/test/lisp/erc/resources/fill/snapshots/monospace-02-right.eld
+++ b/test/lisp/erc/resources/fill/snapshots/monospace-02-right.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
\ No newline at end of file
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
diff --git a/test/lisp/erc/resources/fill/snapshots/monospace-03-left.eld 
b/test/lisp/erc/resources/fill/snapshots/monospace-03-left.eld
index 098257d0b49..1605628b29f 100644
--- a/test/lisp/erc/resources/fill/snapshots/monospace-03-left.eld
+++ b/test/lisp/erc/resources/fill/snapshots/monospace-03-left.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
\ No newline at end of file
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
diff --git a/test/lisp/erc/resources/fill/snapshots/monospace-04-reset.eld 
b/test/lisp/erc/resources/fill/snapshots/monospace-04-reset.eld
index def97738ce6..84a1e34670c 100644
--- a/test/lisp/erc/resources/fill/snapshots/monospace-04-reset.eld
+++ b/test/lisp/erc/resources/fill/snapshots/monospace-04-reset.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
\ No newline at end of file
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg 
datestamp erc-ts 0 field erc-ti [...]
diff --git a/test/lisp/erc/resources/fill/snapshots/spacing-01-mono.eld 
b/test/lisp/erc/resources/fill/snapshots/spacing-01-mono.eld
index 360b3dafafd..7a7e01de49d 100644
--- a/test/lisp/erc/resources/fill/snapshots/spacing-01-mono.eld
+++ b/test/lisp/erc/resources/fill/snapshots/spacing-01-mono.eld
@@ -1 +1 @@
-#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n<bob> This 
buffer is for text.\n*** one two th [...]
+#("\n\n\n[Thu Jan  1 1970]\n*** This server is in debug mode and is logging 
all user I/O. If you do not wish for everything you send to be readable by the 
server owner(s), please disconnect.[00:00]\n<alice> bob: come, you are a 
tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause 
to complain of? Come me to what was done to her.\n<bob> alice: Either your 
unparagoned mistress is dead, or she's outprized by a trifle.\n<bob> This 
buffer is for text.\n*** one two th [...]
diff --git a/test/lisp/erc/resources/fill/snapshots/stamps-left-01.eld 
b/test/lisp/erc/resources/fill/snapshots/stamps-left-01.eld
index cd3537d3c94..bb248ffb28e 100644
--- a/test/lisp/erc/resources/fill/snapshots/stamps-left-01.eld
+++ b/test/lisp/erc/resources/fill/snapshots/stamps-left-01.eld
@@ -1 +1 @@
-#("\n\n[00:00]*** This server is in debug mode and is logging all user I/O. If 
you do not wish for everything you send to be readable by the server owner(s), 
please disconnect.\n[00:00]<alice> bob: come, you are a tedious fool: to the 
purpose. What was done to Elbow's wife, that he hath cause to complain of? Come 
me to what was done to her.\n[00:00]<bob> alice: Either your unparagoned 
mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg unknown 
erc-ts 0 display #3=(#5=(margi [...]
\ No newline at end of file
+#("\n\n[00:00]*** This server is in debug mode and is logging all user I/O. If 
you do not wish for everything you send to be readable by the server owner(s), 
please disconnect.\n[00:00]<alice> bob: come, you are a tedious fool: to the 
purpose. What was done to Elbow's wife, that he hath cause to complain of? Come 
me to what was done to her.\n[00:00]<bob> alice: Either your unparagoned 
mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg notice erc-ts 
0 display #3=(#5=(margin [...]
diff --git a/test/lisp/erc/resources/join/network-id/foonet.eld 
b/test/lisp/erc/resources/join/network-id/foonet.eld
index 7d63f5f0c6c..74a107f8144 100644
--- a/test/lisp/erc/resources/join/network-id/foonet.eld
+++ b/test/lisp/erc/resources/join/network-id/foonet.eld
@@ -1,8 +1,8 @@
 ;; -*- mode: lisp-data; -*-
 ((pass 10 "PASS :foonet:changeme"))
-((nick 1 "NICK tester"))
+((nick 10 "NICK tester"))
 
-((user 1 "USER user 0 * :tester")
+((user 10 "USER user 0 * :tester")
  (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
  (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version 
oragono-2.6.0-7481bf0385b95b16")
  (0 ":irc.foonet.org 003 tester :This server was created Mon, 10 May 2021 
00:58:22 UTC")
diff --git a/test/lisp/eshell/em-cmpl-tests.el 
b/test/lisp/eshell/em-cmpl-tests.el
index 29a41625d5e..dd3c338ac54 100644
--- a/test/lisp/eshell/em-cmpl-tests.el
+++ b/test/lisp/eshell/em-cmpl-tests.el
@@ -243,14 +243,17 @@ See <lisp/eshell/esh-cmd.el>."
                   "echo $(eshell/echo"))))
 
 (ert-deftest em-cmpl-test/special-ref-completion/type ()
-  "Test completion of the start of special references like \"#<buffer\".
+  "Test completion of the start of special reference types like \"#<buffer\".
 See <lisp/eshell/esh-arg.el>."
   (with-temp-eshell
    (should (equal (eshell-insert-and-complete "echo hi > #<buf")
                   "echo hi > #<buffer ")))
   (with-temp-eshell
    (should (equal (eshell-insert-and-complete "echo hi > #<proc")
-                  "echo hi > #<process "))))
+                  "echo hi > #<process ")))
+  (with-temp-eshell
+   (should (equal (eshell-insert-and-complete "echo hi > #<mark")
+                  "echo hi > #<marker "))))
 
 (ert-deftest em-cmpl-test/special-ref-completion/implicit-buffer ()
   "Test completion of special references like \"#<buf>\".
@@ -282,6 +285,31 @@ See <lisp/eshell/esh-arg.el>."
                       (format "echo hi > #<buffer %s> "
                               (string-replace " " "\\ " bufname))))))))
 
+(ert-deftest em-cmpl-test/special-ref-completion/marker ()
+  "Test completion of special references like \"#<marker 1 buf>\".
+See <lisp/eshell/esh-arg.el>."
+  (let (bufname)
+    (with-temp-buffer
+      (setq bufname (rename-buffer "my-buffer" t))
+      ;; Complete the buffer name in various forms.
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 my-buf")
+                      (format "echo hi > #<marker 1 %s> " bufname))))
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 #<my-buf")
+                      (format "echo hi > #<marker 1 #<%s>> " bufname))))
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 #<buffer my-buf")
+                      (format "echo hi > #<marker 1 #<buffer %s>> " bufname))))
+      ;; Partially-complete the "buffer" type name.
+      (with-temp-eshell
+       (should (equal (eshell-insert-and-complete
+                       "echo hi > #<marker 1 #<buf")
+                      "echo hi > #<marker 1 #<buffer "))))))
+
 (ert-deftest em-cmpl-test/variable-ref-completion ()
   "Test completion of variable references like \"$var\".
 See <lisp/eshell/esh-var.el>."
diff --git a/test/lisp/eshell/em-extpipe-tests.el 
b/test/lisp/eshell/em-extpipe-tests.el
index bdffcd9b320..6984ec2de59 100644
--- a/test/lisp/eshell/em-extpipe-tests.el
+++ b/test/lisp/eshell/em-extpipe-tests.el
@@ -55,7 +55,9 @@
                              "temp\\([^>]\\|\\'\\)" temp
                              (string-replace
                               "#<buffer temp>"
-                              (concat "#<buffer " (buffer-name temp-buffer) 
">")
+                              (format "#<buffer %s>"
+                                      (eshell-quote-argument
+                                       (buffer-name temp-buffer)))
                               input))))
                        ,@body)
                    (when (buffer-name temp-buffer)
@@ -110,7 +112,7 @@
    '(progn
       (ignore
        (eshell-set-output-handle 1 'overwrite
-                                (get-buffer-create "temp")))
+                                (eshell-get-buffer "temp")))
       (eshell-named-command "sh"
                            (list "-c" "echo \"bar\" | rev"))))
   (with-substitute-for-temp
@@ -133,7 +135,7 @@
    '(progn
       (ignore
        (eshell-set-output-handle 1 'overwrite
-                                (get-buffer-create "quux")))
+                                (eshell-get-buffer "quux")))
       (ignore
        (eshell-set-output-handle 1 'append
                                 (get-process "other")))
diff --git a/test/lisp/eshell/esh-arg-tests.el 
b/test/lisp/eshell/esh-arg-tests.el
index c883db3907f..1eb8e08b883 100644
--- a/test/lisp/eshell/esh-arg-tests.el
+++ b/test/lisp/eshell/esh-arg-tests.el
@@ -118,7 +118,68 @@ treated literally, as a backslash and a newline."
      (format "echo #<buffer %s>" (buffer-name))
      (current-buffer))))
 
-(ert-deftest esh-arg-test/special-reference/special ()
+(ert-deftest esh-arg-test/special-reference/marker ()
+  "Test that \"#<marker N buf>\" refers to a marker in the buffer \"buf\"."
+  (with-temp-buffer
+    (rename-buffer "my-buffer" t)
+    (insert "hello")
+    (let ((marker (make-marker)))
+      (set-marker marker 1 (current-buffer))
+      (eshell-command-result-equal
+       (format "echo #<marker 1 %s>" (buffer-name))
+       marker))))
+
+(ert-deftest esh-arg-test/special-reference/quoted ()
+  "Test that '#<buffer \"foo bar\">' refers to the buffer \"foo bar\"."
+  (with-temp-buffer
+    (rename-buffer "foo bar" t)
+    (eshell-command-result-equal
+     (format "echo #<buffer \"%s\">" (buffer-name))
+     (current-buffer))
+    (eshell-command-result-equal
+     (format "echo #<buffer '%s'>" (buffer-name))
+     (current-buffer))))
+
+(ert-deftest esh-arg-test/special-reference/nested ()
+  "Test that nested special references work correctly."
+  (with-temp-buffer
+    (rename-buffer "my-buffer" t)
+    (insert "hello")
+    (let ((marker (make-marker)))
+      (set-marker marker 1 (current-buffer))
+      (eshell-command-result-equal
+       (format "echo #<marker 1 #<%s>>" (buffer-name))
+       marker)
+      (eshell-command-result-equal
+       (format "echo #<marker 1 #<buffer %s>>" (buffer-name))
+       marker))))
+
+(ert-deftest esh-arg-test/special-reference/var-expansion ()
+  "Test that variable expansion inside special references works."
+  (with-temp-buffer
+    (rename-buffer "my-buffer" t)
+    (let ((eshell-test-value (buffer-name)))
+      (eshell-command-result-equal
+       "echo #<buffer $eshell-test-value>"
+       (current-buffer))
+      (eshell-command-result-equal
+       "echo #<buffer \"$eshell-test-value\">"
+       (current-buffer)))))
+
+(ert-deftest esh-arg-test/special-reference/lisp-form ()
+  "Test that Lisp forms inside special references work."
+  (with-temp-eshell
+   (let ((marker (make-marker))
+         eshell-test-value)
+     (set-marker marker 1 (current-buffer))
+     (eshell-insert-command
+      "setq eshell-test-value #<marker 1 (current-buffer)>")
+     (should (equal eshell-test-value marker))
+     (eshell-insert-command
+      "setq eshell-test-value #<marker 1 #<buffer (buffer-name)>>")
+     (should (equal eshell-test-value marker)))))
+
+(ert-deftest esh-arg-test/special-reference/special-characters ()
   "Test that \"#<...>\" works correctly when escaping special characters."
   (with-temp-buffer
     (rename-buffer "<my buffer>" t)
diff --git a/test/lisp/gnus/gnus-group-tests.el 
b/test/lisp/gnus/gnus-group-tests.el
index e12f42711ea..3f5cbefc6ea 100644
--- a/test/lisp/gnus/gnus-group-tests.el
+++ b/test/lisp/gnus/gnus-group-tests.el
@@ -38,7 +38,7 @@
      ;; This is a very aggressive shortening of the left hand side.
      ("nnimap+email@banana.salesman.example.com:234" . "email@banana:234")
      ("nntp+some.where.edu:soc.motss" . "some:s.motss")
-     ("nntp+news.gmane.org:gmane.emacs.gnus.general" . "news:g.e.g.general";)
+     ("nntp+news.gmane.io:gmane.emacs.gnus.general" . "news:g.e.g.general";)
      ("nntp+news.gnus.org:gmane.text.docbook.apps" . "news:g.t.d.apps";)
 
      ;; nnimap groups.
diff --git a/test/lisp/net/webjump-tests.el b/test/lisp/net/webjump-tests.el
index 42fa346a869..ffdebf2bb6f 100644
--- a/test/lisp/net/webjump-tests.el
+++ b/test/lisp/net/webjump-tests.el
@@ -58,7 +58,7 @@
 (ert-deftest webjump-tests-url-fix ()
   (should (equal (webjump-url-fix nil) ""))
   (should (equal (webjump-url-fix "/tmp/") "file:///tmp/"))
-  (should (equal (webjump-url-fix "gnu.org") "http://gnu.org/";))
+  (should (equal (webjump-url-fix "gnu.org") "https://gnu.org/";))
   (should (equal (webjump-url-fix "ftp.x.org") "ftp://ftp.x.org/";))
   (should (equal (webjump-url-fix "https://gnu.org";)
                  "https://gnu.org/";)))
diff --git a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts 
b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts
index 040225c8580..9797467bbe5 100644
--- a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts
+++ b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts
@@ -5,148 +5,675 @@ Code:
     (lua-ts-mode)
     (indent-region (point-min) (point-max)))
 
-Name: Basic Indent
+Name: Chunk Indent
 
 =-=
-      print(
-0,
-      1
-)
+ print(1)
+       print(2)
+=-=
+print(1)
+print(2)
+=-=-=
 
-local function f(o)
-   if o.x > o.y then
- return o.x
-elseif o.y > o.z then
-           return o.y
-      else
-return o.z
-            end
+Name: Function Indent
+
+=-=
+function f1(n)
+print(n)
+return n + 1
 end
 
-f({
- x = 1,
-  y = 2,
-   z = 3,
-})
+local function f2(n)
+print(n)
+return n * 2
+end
 
-;(function()
-return false
-)()
+local f3 = function(n)
+print(n)
+return n / 3
+end
+
+function f4(...)
+local f = function (...)
+if ok
+then print(1)
+else print(0)
+end
+end
+return f
+end
+
+function f5(...)
+local f = function (...)
+if ok
+then
+print(1)
+else
+print(0)
+end
+end
+return f
+end
+
+function f6(...)
+local f = function (...)
+if ok then
+print(1)
+else
+print(0)
+end
+end
+return f
+end
+
+;(function ()
+ return true
+ end)()
 =-=
-print(
-  0,
-  1
-)
+function f1(n)
+  print(n)
+  return n + 1
+end
 
-local function f(o)
-  if o.x > o.y then
-    return o.x
-  elseif o.y > o.z then
-    return o.y
-  else
-    return o.z
+local function f2(n)
+  print(n)
+  return n * 2
+end
+
+local f3 = function(n)
+  print(n)
+  return n / 3
+end
+
+function f4(...)
+  local f = function (...)
+    if ok
+    then print(1)
+    else print(0)
+    end
   end
+  return f
 end
 
-f({
-  x = 1,
-  y = 2,
-  z = 3,
-})
+function f5(...)
+  local f = function (...)
+    if ok
+    then
+      print(1)
+    else
+      print(0)
+    end
+  end
+  return f
+end
+
+function f6(...)
+  local f = function (...)
+    if ok then
+      print(1)
+    else
+      print(0)
+    end
+  end
+  return f
+end
 
-;(function()
-  return false
-)()
+;(function ()
+  return true
+end)()
 =-=-=
 
-Name: Argument Indent
+Name: Conditional Indent
 
 =-=
-function h(
-string,
-number,
-options)
-print(string, number, options)
+if true then
+print(true)
+return 1
+elseif false then
+print(false)
+return -1
+else
+print(nil)
+return 0
 end
 
-local p = h(
-"sring",
-        1000,
-      {
-cost = 2,
-length = 8,
-       parallelism = 4,
-})
+if true
+ then
+ print(true)
+ return 1
+ elseif false
+ then
+ print(false)
+ return -1
+ else
+ print(nil)
+ return 0
+end
+
+if true
+ then return 1
+ elseif false
+ then return -1
+ else return 0
+end
 =-=
-function h(
-  string,
-  number,
-  options)
-  print(string, number, options)
+if true then
+  print(true)
+  return 1
+elseif false then
+  print(false)
+  return -1
+else
+  print(nil)
+  return 0
 end
 
-local p = h(
-  "sring",
-  1000,
-  {
-    cost = 2,
-    length = 8,
-    parallelism = 4,
-  })
+if true
+then
+  print(true)
+  return 1
+elseif false
+then
+  print(false)
+  return -1
+else
+  print(nil)
+  return 0
+end
+
+if true
+then return 1
+elseif false
+then return -1
+else return 0
+end
 =-=-=
 
-Name: Continuation Indent
+Name: Loop Indent
 
 =-=
+for k,v in pairs({}) do
+ print(k)
+ print(v)
+end
+
+for i=1,10
+ do print(i)
+end
+
+while n < 10 do
+ n = n + 1
+ print(n)
+end
+
+while n < 10
+ do
+ n = n + 1
+ print(n)
+end
+
+for i=0,9 do
+repeat n = n+1
+ until n > 99
+end
+
+repeat
+z = z * 2
+print(z)
+until z > 12
+
+ for i,x in ipairs(t) do
+ while i < 9
+ do
+ local n = t[x]
+ repeat n = n + 1
+ until n > #t
+ while n < 99
+ do
+ print(n)
+ end
+ end
+ print(t[i])
+ end
+
+do
+local a = b
+print(a + 1)
+end
+=-=
+for k,v in pairs({}) do
+  print(k)
+  print(v)
+end
+
+for i=1,10
+do print(i)
+end
+
+while n < 10 do
+  n = n + 1
+  print(n)
+end
+
+while n < 10
+do
+  n = n + 1
+  print(n)
+end
+
+for i=0,9 do
+  repeat n = n+1
+  until n > 99
+end
+
+repeat
+  z = z * 2
+  print(z)
+until z > 12
+
+for i,x in ipairs(t) do
+  while i < 9
+  do
+    local n = t[x]
+    repeat n = n + 1
+    until n > #t
+    while n < 99
+    do
+      print(n)
+    end
+  end
+  print(t[i])
+end
+
+do
+  local a = b
+  print(a + 1)
+end
+=-=-=
+
+Name: Bracket Indent
+
+=-=
+fn(
+  )
+
+tb={
+   }
+=-=
+fn(
+)
+
+tb={
+}
+=-=-=
+
+Name: Multi-line String Indent
+
+=-=
+local s = [[
+      Multi-line
+    string content
+    ]]
+
 function f()
   local str = [[
   multi-line
        string
     ]]
---[[
-multi-line
-comment
-    ]]
 return true
 end
 =-=
+local s = [[
+      Multi-line
+    string content
+    ]]
+
 function f()
   local str = [[
   multi-line
        string
     ]]
-  --[[
+  return true
+end
+=-=-=
+
+Name: Multi-line Comment Indent
+
+=-=
+--[[
+      Multi-line
+    comment content
+ ]]
+
+function f()
+--[[
+multi-line
+   comment
+    ]]
+  return true
+end
+=-=
+--[[
+      Multi-line
+    comment content
+ ]]
+
+function f()
+--[[
 multi-line
-comment
+   comment
     ]]
   return true
 end
 =-=-=
 
-Name: Loop Indent
+Name: Argument Indent
+
+=-=
+ h(
+ "string",
+ 1000
+ )
+
+local p = h(
+"string",
+        1000
+)
+
+fn(1,
+2,
+     3)
+
+fn( 1, 2,
+3, 4 )
+
+f({
+x = 1,
+y = 2,
+z = 3,
+})
+
+f({ x = 1,
+y = 2,
+z = 3, })
+
+Test({
+a=1
+})
+
+Test({
+a = 1,
+b = 2,
+},
+nil)
+=-=
+h(
+  "string",
+  1000
+)
+
+local p = h(
+  "string",
+  1000
+)
+
+fn(1,
+   2,
+   3)
+
+fn( 1, 2,
+    3, 4 )
+
+f({
+  x = 1,
+  y = 2,
+  z = 3,
+})
+
+f({ x = 1,
+    y = 2,
+    z = 3, })
+
+Test({
+  a=1
+})
+
+Test({
+       a = 1,
+       b = 2,
+     },
+     nil)
+=-=-=
+
+Name: Parameter Indent
 
 =-=
-for k, v in pairs({}) do
-        print(k, v)
+function f1(
+a,
+b
+)
+print(a,b)
 end
 
-while n < 10 do
-n = n + 1
+local function f2(a,
+                b)
+print(a,b)
 end
 
-repeat
-z = z * 2
- until z > 12
+local f3 = function( a, b,
+                c, d )
+print(a,b,c,d)
+end
 =-=
-for k, v in pairs({}) do
-  print(k, v)
+function f1(
+  a,
+  b
+)
+  print(a,b)
 end
 
-while n < 10 do
-  n = n + 1
+local function f2(a,
+                  b)
+  print(a,b)
 end
 
-repeat
-  z = z * 2
-until z > 12
+local f3 = function( a, b,
+                     c, d )
+  print(a,b,c,d)
+end
+=-=-=
+
+Name: Table Indent
+
+=-=
+local Other = {
+    First={up={Step=true,Jump=true},
+        down={Step=true,Jump=true},
+        left={Step=true,Jump=true},
+        right={Step=true,Jump=true}},
+    Second={up={Step=true,Jump=true},
+        down={Step=true,Jump=true},
+        left={Step=true,Jump=true},
+        right={Step=true,Jump=true}},
+    Third={up={Goto=true},
+        down={Goto=true},
+        left={Goto=true},
+        right={Goto=true}}
+}
+
+local Other = {
+a = 1,
+ b = 2,
+  c = 3,
+}
+=-=
+local Other = {
+  First={up={Step=true,Jump=true},
+         down={Step=true,Jump=true},
+         left={Step=true,Jump=true},
+         right={Step=true,Jump=true}},
+  Second={up={Step=true,Jump=true},
+          down={Step=true,Jump=true},
+          left={Step=true,Jump=true},
+          right={Step=true,Jump=true}},
+  Third={up={Goto=true},
+         down={Goto=true},
+         left={Goto=true},
+         right={Goto=true}}
+}
+
+local Other = {
+  a = 1,
+  b = 2,
+  c = 3,
+}
+=-=-=
+
+Code:
+  (lambda ()
+    (setq indent-tabs-mode nil)
+    (setq lua-ts-indent-offset 4)
+    (lua-ts-mode)
+    (indent-region (point-min) (point-max)))
+
+Name: End Indent
+
+=-=
+function f(x)
+    for y=1,x.y do
+        for x=1,x.z do
+            if x.y and x.z then
+                if y <= x then
+                    y = y + 1
+   end end end end
+    return {x,y} or {math.random(),math.random()}
+ end
+
+for y=1,x.y do
+    for x=1,x.z do
+        if x.y and x.z then
+            if y <= x then
+                y = y + 1
+           end
+ end end end
+=-=
+function f(x)
+    for y=1,x.y do
+        for x=1,x.z do
+            if x.y and x.z then
+                if y <= x then
+                    y = y + 1
+    end end end end
+    return {x,y} or {math.random(),math.random()}
+end
+
+for y=1,x.y do
+    for x=1,x.z do
+        if x.y and x.z then
+            if y <= x then
+                y = y + 1
+            end
+end end end
+=-=-=
+
+Name: Nested Function Indent
+
+=-=
+function a(...)
+    return (function (x)
+                return x
+            end)(foo(...))
+end
+
+function b(n)
+    local x = 1
+    return function (i)
+        return function (...)
+            return (function (n, ...)
+                return function (f, ...)
+                    return (function (...)
+                        if ... and x < 9 then
+                            x = x + 1
+                            return ...
+                    end end)(n(f, ...))
+                end, ...
+            end)(i(...))
+end end end
+
+function c(f)
+    local f1 = function (...)
+        if nil ~= ... then
+            return f(...)
+        end
+    end
+    return function (i)
+        return function (...)
+            local fn = function (n, ...)
+                local x = function (f, ...)
+                    return f1(n(f, ...))
+                end
+                return x
+            end
+            return fn(i(...))
+        end
+    end
+end
+
+function d(f)
+    local f1 = function (c, f, ...)
+        if ... then
+            if f(...) then
+                return ...
+            else
+                return c(f, ...)
+    end end end
+    return function (i)
+        return function (...)
+            return (function (n, ...)
+                local function j (f, ...)
+                    return f1(j, f, n(f, ...))
+                end
+                return j, ...
+            end)(i(...))
+end end end
+
+function e (n, t)
+    return function (i)
+        return function (...)
+            return (
+                function (n, ...)
+                    local x, y, z = 0, {}
+                    return (function (f, ...)
+                        return (function (i, ...) return i(i, ...) end)(
+                            function (i, ...)
+                                return f(function (x, ...)
+                                             return i(i, ...)(x, ...)
+                                         end, ...)
+                            end)
+                    end)(function (j)
+                        return function(f, ...)
+                            return (function (c, f, ...)
+                                if ... then
+                                    if n+1 == x then
+                                        local y1, x1 = y, x
+                                        y, x = {}, 0
+                                        return (function (...)
+                                                    z = ...
+                                                    return ...
+                                                end)(t(y1-1, x1-1, ...))
+                                    else
+                                        x = x - 1
+                                        return c(f,
+                                                 (function (...)
+                                                      z = ...
+                                                      return ...
+                                                  end)(t(y, x, ...)))
+                                    end
+                                elseif x ~= 0 then
+                                    x = 0
+                                    return z, y
+                            end end)(j, f, n(f, ...))
+                    end end), ...
+                end)(i(...))
+end end end
 =-=-=
diff --git a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts 
b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts
index 770aa23b18d..11e86f12926 100644
--- a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts
+++ b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts
@@ -147,7 +147,7 @@ end|
 print(1)
 =-=-=
 
-Name: forward-sentence moves over for statements
+Name: forward-sentence moves over do statements
 
 =-=
 |do
@@ -417,34 +417,6 @@ Code:
 
 Point-Char: |
 
-Name: forward-sexp moves over blocks
-
-=-=
-local function Test()
-  |local t = {
-    a = 1,
-  }
-
-  if true then
-    print(1)
-  else
-    print(0)
-  end
-end
-=-=
-local function Test()
-  local t = {
-    a = 1,
-  }
-
-  if true then
-    print(1)
-  else
-    print(0)
-  end|
-end
-=-=-=
-
 Name: forward-sexp moves over arguments
 
 =-=
@@ -481,41 +453,91 @@ local t = { 1,
   3 }|
 =-=-=
 
-Code:
-  (lambda ()
-    (lua-ts-mode)
-    (backward-sexp 1))
+Name: forward-sexp moves over parenthesized expressions
 
-Point-Char: |
+=-=
+|(function (x) return x + 1 end)(41)
+=-=
+(function (x) return x + 1 end)|(41)
+=-=-=
 
-Name: backward-sexp moves over blocks
+Name: forward-sexp moves over function declarations
 
 =-=
-local function Test()
-  local t = {
-    a = 1,
-  }
+|function foo (x)
+    if false then
+        print "foo"
+    elseif true then
+        print "bar"
+    end
+end
+=-=
+function foo (x)
+    if false then
+        print "foo"
+    elseif true then
+        print "bar"
+    end
+end|
+=-=-=
 
-  if true then
-    print(1)
-  else
-    print(0)
-  end|
+Name: forward-sexp moves over do statements
+
+=-=
+|do
+  print(a + 1)
 end
 =-=
-local function Test()
-  |local t = {
-    a = 1,
-  }
+do
+  print(a + 1)
+end|
+=-=-=
 
-  if true then
-    print(1)
-  else
-    print(0)
-  end
+Name: forward-sexp moves over for statements
+
+=-=
+|for k,v in pairs({}) do
+  print(k, v)
+end
+=-=
+for k,v in pairs({}) do
+  print(k, v)
+end|
+=-=-=
+
+Name: forward-sexp moves over repeat statements
+
+=-=
+|repeat
+  n = n + 1
+until n > 10
+=-=
+repeat
+  n = n + 1
+until n > 10|
+=-=-=
+
+Name: forward-sexp moves over while statements
+
+=-=
+|while n < 99
+do
+  n = n+1
 end
+=-=
+while n < 99
+do
+  n = n+1
+end|
 =-=-=
 
+Code:
+  (lambda ()
+    (lua-ts-mode)
+    (backward-sexp 1))
+
+Point-Char: |
+
 Name: backward-sexp moves over arguments
 
 =-=
@@ -551,3 +573,31 @@ local t = |{ 1,
   2,
   3 }
 =-=-=
+
+Name: backward-sexp moves over parenthesized expressions
+
+=-=
+(function (x) return x + 1 end)|(41)
+=-=
+|(function (x) return x + 1 end)(41)
+=-=-=
+
+Name: backward-sexp moves over function declarations
+
+=-=
+function foo (x)
+    if false then
+        print "foo"
+    elseif true then
+        print "bar"
+    end
+end|
+=-=
+|function foo (x)
+    if false then
+        print "foo"
+    elseif true then
+        print "bar"
+    end
+end
+=-=-=
diff --git a/test/lisp/progmodes/which-func-tests.el 
b/test/lisp/progmodes/which-func-tests.el
new file mode 100644
index 00000000000..73709f1c5e5
--- /dev/null
+++ b/test/lisp/progmodes/which-func-tests.el
@@ -0,0 +1,58 @@
+;;; which-func-tests.el --- tests for which-func     -*- lexical-binding: t; 
-*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; Author: Spencer Baugh <sbaugh@catern.com>
+
+;; This file is part of GNU Emacs.
+
+;; This program 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.
+
+;; This program 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 'which-func)
+
+(ert-deftest which-func-tests-toggle ()
+  (let ((which-func-display 'mode-and-header) buf-code buf-not)
+    (setq buf-code (find-file-noselect "which-func-tests.el"))
+    (setq buf-not (get-buffer-create "fundamental"))
+    (with-current-buffer buf-code
+      (should-not which-func-mode) (should-not header-line-format))
+    (with-current-buffer buf-not
+      (should-not which-func-mode) (should-not header-line-format))
+    (which-function-mode 1)
+    (with-current-buffer buf-code
+      (should which-func-mode) (should header-line-format))
+    (with-current-buffer buf-not
+      (should-not which-func-mode) (should-not header-line-format))
+    (which-function-mode -1)
+    ;; which-func-mode stays set even when which-function-mode is off.
+    (with-current-buffer buf-code
+      (should which-func-mode) (should-not header-line-format))
+    (with-current-buffer buf-not
+      (should-not which-func-mode) (should-not header-line-format))
+    (kill-buffer buf-code)
+    (kill-buffer buf-not)
+    (which-function-mode 1)
+    (setq buf-code (find-file-noselect "which-func-tests.el"))
+    (setq buf-not (get-buffer-create "fundamental"))
+    (with-current-buffer buf-code
+      (should which-func-mode) (should header-line-format))
+    (with-current-buffer buf-not
+      (should-not which-func-mode) (should-not header-line-format))))
+
+(provide 'which-func-tests)
+;;; which-func-tests.el ends here
diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el
index 0d409cead26..db327056533 100644
--- a/test/lisp/subr-tests.el
+++ b/test/lisp/subr-tests.el
@@ -348,15 +348,17 @@
 (defalias 'subr-tests--parent-mode
   (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
 
+(define-derived-mode subr-tests--derived-mode-1 prog-mode "test")
+(define-derived-mode subr-tests--derived-mode-2 subr-tests--parent-mode "test")
 (ert-deftest provided-mode-derived-p ()
   ;; base case: `derived-mode' directly derives `prog-mode'
-  (should (progn
-            (define-derived-mode derived-mode prog-mode "test")
-            (provided-mode-derived-p 'derived-mode 'prog-mode)))
-  ;; edge case: `derived-mode' derives an alias of `prog-mode'
-  (should (progn
-            (define-derived-mode derived-mode subr-tests--parent-mode "test")
-            (provided-mode-derived-p 'derived-mode 'prog-mode))))
+  (should (provided-mode-derived-p 'subr-tests--derived-mode-1 'prog-mode))
+  ;; Edge cases: aliases along the derivation.
+  (should (provided-mode-derived-p 'subr-tests--parent-mode
+                                   'subr-tests--parent-mode))
+  (should (provided-mode-derived-p 'subr-tests--derived-mode-2
+                                   'subr-tests--parent-mode))
+  (should (provided-mode-derived-p 'subr-tests--derived-mode-2 'prog-mode)))
 
 (ert-deftest number-sequence-test ()
   (should (= (length
diff --git a/test/src/casefiddle-tests.el b/test/src/casefiddle-tests.el
index e7f4348b0c6..12984d898b9 100644
--- a/test/src/casefiddle-tests.el
+++ b/test/src/casefiddle-tests.el
@@ -294,4 +294,16 @@
     ;;(should (string-equal (capitalize "indIá") "İndıa"))
     ))
 
+(defun casefiddle-tests--check-syms (init with-words with-symbols)
+  (let ((case-symbols-as-words nil))
+    (should (string-equal (upcase-initials init) with-words)))
+  (let ((case-symbols-as-words t))
+    (should (string-equal (upcase-initials init) with-symbols))))
+
+(ert-deftest casefiddle-case-symbols-as-words ()
+  (casefiddle-tests--check-syms "Aa_bb Cc_dd" "Aa_Bb Cc_Dd" "Aa_bb Cc_dd")
+  (casefiddle-tests--check-syms "Aa_bb cc_DD" "Aa_Bb Cc_DD" "Aa_bb Cc_DD")
+  (casefiddle-tests--check-syms "aa_bb cc_dd" "Aa_Bb Cc_Dd" "Aa_bb Cc_dd")
+  (casefiddle-tests--check-syms "Aa_Bb Cc_Dd" "Aa_Bb Cc_Dd" "Aa_Bb Cc_Dd"))
+
 ;;; casefiddle-tests.el ends here
diff --git a/test/src/filelock-tests.el b/test/src/filelock-tests.el
index f4376b2a5b0..f4ae7192796 100644
--- a/test/src/filelock-tests.el
+++ b/test/src/filelock-tests.el
@@ -26,7 +26,7 @@
 
 ;;; Code:
 
-(require 'cl-macs)
+(require 'cl-lib)
 (require 'ert)
 (require 'ert-x)
 (require 'seq)



reply via email to

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