emacs-diffs
[Top][All Lists]
Advanced

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

feature/pgtk c31d3da 1/2: Merge branch 'master' of git.sv.gnu.org:/srv/g


From: Yuuki Harano
Subject: feature/pgtk c31d3da 1/2: Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Date: Sat, 13 Nov 2021 02:45:09 -0500 (EST)

branch: feature/pgtk
commit c31d3dacf7f153589b6e7a5f5204937c64e7fd24
Merge: c3377ae b4c6ab8
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Yuuki Harano <masm+github@masm11.me>

    Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
---
 ChangeLog.3                                        |  10 +-
 admin/emake                                        |   6 +-
 admin/gitmerge.el                                  |  10 +-
 admin/nt/dist-build/build-dep-zips.py              |  42 ++-
 admin/update_autogen                               |   4 +-
 configure.ac                                       |  17 +
 doc/emacs/files.texi                               |   4 +-
 doc/emacs/misc.texi                                |  31 ++
 doc/lispintro/emacs-lisp-intro.texi                |   2 +-
 doc/lispref/display.texi                           |  24 +-
 doc/lispref/nonascii.texi                          |  26 +-
 doc/misc/ChangeLog.1                               |   2 +-
 doc/misc/efaq-w32.texi                             |   2 +-
 doc/misc/flymake.texi                              |   4 +-
 doc/misc/org.org                                   |   2 +-
 doc/misc/tramp.texi                                |  12 +-
 doc/misc/trampver.texi                             |   4 +-
 etc/NEWS                                           | 212 +++++------
 etc/NEWS.28                                        |  32 +-
 etc/PROBLEMS                                       |  20 +-
 lisp/ChangeLog.12                                  |   2 +-
 lisp/calc/calc-store.el                            |  15 +-
 lisp/cedet/ChangeLog.1                             |   2 +-
 lisp/emacs-lisp/autoload.el                        |   2 +
 lisp/emacs-lisp/checkdoc.el                        |   1 +
 lisp/emacs-lisp/crm.el                             |  47 ++-
 lisp/emacs-lisp/package.el                         |   1 +
 lisp/emacs-lisp/subr-x.el                          |  12 +-
 lisp/env.el                                        |   2 +-
 lisp/erc/erc-services.el                           |   2 +-
 lisp/erc/erc.el                                    |  12 +-
 lisp/files.el                                      |   2 +-
 lisp/gnus/gnus-art.el                              |   2 +-
 lisp/gnus/gnus-sum.el                              |   5 -
 lisp/icomplete.el                                  |  18 +-
 lisp/image-dired.el                                | 213 ++++++-----
 lisp/image.el                                      |  94 +++--
 lisp/info.el                                       |  47 ++-
 lisp/ldefs-boot.el                                 | 270 ++++++++++----
 lisp/ls-lisp.el                                    |   2 +-
 lisp/mh-e/ChangeLog.1                              |   4 +-
 lisp/net/shr.el                                    |  17 +-
 lisp/net/tramp-adb.el                              |  34 +-
 lisp/net/tramp-archive.el                          |   5 +-
 lisp/net/tramp-compat.el                           | 177 ++-------
 lisp/net/tramp-crypt.el                            |  10 +-
 lisp/net/tramp-ftp.el                              |   9 +-
 lisp/net/tramp-fuse.el                             |   8 +-
 lisp/net/tramp-gvfs.el                             |  44 +--
 lisp/net/tramp-integration.el                      |  23 +-
 lisp/net/tramp-rclone.el                           |  20 +-
 lisp/net/tramp-sh.el                               |  48 ++-
 lisp/net/tramp-smb.el                              |  50 ++-
 lisp/net/tramp-sshfs.el                            |  12 +-
 lisp/net/tramp-sudoedit.el                         |  24 +-
 lisp/net/tramp.el                                  | 213 +++++------
 lisp/net/trampver.el                               |  10 +-
 lisp/progmodes/cc-styles.el                        |  12 +-
 lisp/progmodes/flymake.el                          |   4 +-
 lisp/progmodes/xref.el                             |   2 +-
 lisp/saveplace.el                                  |  17 +-
 lisp/select.el                                     |  24 +-
 lisp/server.el                                     | 121 ++++--
 lisp/startup.el                                    |  10 +-
 lisp/subr.el                                       |   2 +-
 lisp/vc/vc-git.el                                  |   5 +-
 lisp/window.el                                     |   2 +-
 lisp/xdg.el                                        |   4 +-
 lisp/xwidget.el                                    |  99 ++++-
 src/ChangeLog.11                                   |   4 +-
 src/atimer.c                                       |   7 +
 src/callproc.c                                     | 191 +++++++++-
 src/coding.c                                       |   9 +-
 src/emacsgtkfixed.c                                |  89 -----
 src/fileio.c                                       |   9 +-
 src/ftfont.c                                       |   2 -
 src/lread.c                                        |  21 +-
 src/term.c                                         |  10 +-
 src/w32.c                                          |  12 +-
 src/w32font.c                                      |  33 +-
 src/xfaces.c                                       |  46 ---
 src/xwidget.c                                      | 303 +++++++++++----
 src/xwidget.h                                      |   7 +
 .../files-resources/insert-directory/test_dir/bar  |   0
 .../files-resources/insert-directory/test_dir/foo  |   0
 .../insert-directory/test_dir_other/bar            |   0
 .../insert-directory/test_dir_other/foo            |   0
 test/lisp/files-tests.el                           |  98 ++++-
 test/lisp/info-tests.el                            |  39 ++
 test/lisp/mh-e/mh-utils-tests.el                   |   2 +-
 test/lisp/net/tramp-archive-tests.el               |  86 ++---
 test/lisp/net/tramp-tests.el                       | 409 +++++++++------------
 test/lisp/so-long-tests/so-long-tests.el           |   4 +-
 93 files changed, 2083 insertions(+), 1525 deletions(-)

diff --git a/ChangeLog.3 b/ChangeLog.3
index 9ec19e9..ad65969 100644
--- a/ChangeLog.3
+++ b/ChangeLog.3
@@ -48398,10 +48398,10 @@
        Impl. json-pretty-print with replace-region-contents + minimization
 
        * lisp/json.el (json-pretty-print): Use the new
-         replace-region-contents.  Add prefix arg for minimzation.
-       (json-pretty-print-buffer): Add prefix arg for minimzation.
-       (json-pretty-print-buffer-ordered): Add prefix arg for minimzation.
-       (json-pretty-print-ordered): Add prefix arg for minimzation.
+         replace-region-contents.  Add prefix arg for minimization.
+       (json-pretty-print-buffer): Add prefix arg for minimization.
+       (json-pretty-print-buffer-ordered): Add prefix arg for minimization.
+       (json-pretty-print-ordered): Add prefix arg for minimization.
 
 2019-02-08  Tassilo Horn  <tsdh@gnu.org>
 
@@ -122196,7 +122196,7 @@
 
 2012-08-15  Tom Tromey  <tromey@redhat.com>
 
-       This parameterizes the GC a bit to make it thread-ready.
+       This parametrizes the GC a bit to make it thread-ready.
 
        The basic idea is that whenever a thread "exits lisp" -- that is,
        releases the global lock in favor of another thread -- it must save
diff --git a/admin/emake b/admin/emake
index 8c37c16..2ff5532 100755
--- a/admin/emake
+++ b/admin/emake
@@ -13,7 +13,7 @@ cores=1
 
 # Determine the number of cores.
 if [ -f /proc/cpuinfo ]; then
-    cores=$(($(egrep "^physical id|^cpu cores" /proc/cpuinfo |\
+    cores=$(($(grep -E "^physical id|^cpu cores" /proc/cpuinfo |\
        awk '{ print $4; }' |\
        sed '$!N;s/\n/ /' |\
        uniq |\
@@ -30,7 +30,7 @@ s#^Configured for # Configured for #
 s#^./temacs.*#  \\& #
 s#^make.*Error#  \\& #
 ' | \
-egrep --line-buffered -v "^make|\
+grep -E --line-buffered -v "^make|\
 ^Loading|\
 SCRAPE|\
 INFO.*Scraping.*[.] ?\$|\
@@ -93,4 +93,4 @@ done
 # changed since last time.
 make -j$cores check-maybe 2>&1 | \
     sed -n '/contained unexpected results/,$p' | \
-    egrep --line-buffered -v "^make"
+    grep -E --line-buffered -v "^make"
diff --git a/admin/gitmerge.el b/admin/gitmerge.el
index adb13fc..67fca87 100644
--- a/admin/gitmerge.el
+++ b/admin/gitmerge.el
@@ -37,10 +37,10 @@
 ;;   up-to-date).
 ;; - Mark commits you'd like to skip, meaning to only merge their
 ;;   metadata (merge strategy 'ours').
-;; - Hit 'm' to start merging. Skipped commits will be merged separately.
+;; - Hit 'm' to start merging.  Skipped commits will be merged separately.
 ;; - If conflicts cannot be resolved automatically, you'll have to do
-;;   it manually. In that case, resolve the conflicts and restart
-;;   gitmerge, which will automatically resume. It will add resolved
+;;   it manually.  In that case, resolve the conflicts and restart
+;;   gitmerge, which will automatically resume.  It will add resolved
 ;;   files, commit the pending merge and continue merging the rest.
 ;; - Inspect master branch, and if everything looks OK, push.
 
@@ -129,7 +129,7 @@ If nil, the function `gitmerge-default-branch' guesses.")
     (string-to-number (match-string 1))))
 
 (defun gitmerge-default-branch ()
-  "Default for branch that should be merged; eg \"origin/emacs-26\"."
+  "Default for branch that should be merged; e.g. \"origin/emacs-28\"."
   (or gitmerge-default-branch
       (format "origin/emacs-%s" (1- (gitmerge-emacs-version)))))
 
@@ -472,7 +472,7 @@ Throw an user-error if we cannot resolve automatically."
       (if (not (zerop
                (call-process "git" nil t nil
                              "diff" "--name-only" "--diff-filter=U")))
-         (error "Error listing unmerged files. Resolve manually.")
+          (error "Error listing unmerged files.  Resolve manually.")
        (goto-char (point-min))
        (while (not (eobp))
          (push (buffer-substring (point) (line-end-position)) files)
diff --git a/admin/nt/dist-build/build-dep-zips.py 
b/admin/nt/dist-build/build-dep-zips.py
index 19168e7..6bed191 100755
--- a/admin/nt/dist-build/build-dep-zips.py
+++ b/admin/nt/dist-build/build-dep-zips.py
@@ -20,6 +20,8 @@ import argparse
 import os
 import shutil
 import re
+import functools
+import operator
 
 from subprocess import check_output
 
@@ -112,7 +114,7 @@ def ntldd_munge(out):
 ## Packages to fiddle with
 ## Source for gcc-libs is part of gcc
 SKIP_SRC_PKGS=["mingw-w64-gcc-libs"]
-SKIP_DEP_PKGS=["mingw-w64-glib2"]
+SKIP_DEP_PKGS=frozenset(["mingw-w64-x86_64-glib2"])
 MUNGE_SRC_PKGS={"mingw-w64-libwinpthread-git":"mingw-w64-winpthreads-git"}
 MUNGE_DEP_PKGS={
     "mingw-w64-x86_64-libwinpthread":"mingw-w64-x86_64-libwinpthread-git",
@@ -124,16 +126,14 @@ ARCH_PKGS=[]
 SRC_REPO="https://sourceforge.net/projects/msys2/files/REPOS/MINGW/Sources";
 
 
-def immediate_deps(pkg):
-    package_info = check_output(["pacman", "-Si", 
pkg]).decode("utf-8").split("\n")
+def immediate_deps(pkgs):
+    package_info = check_output(["pacman", "-Si"] + 
pkgs).decode("utf-8").splitlines()
 
-    ## Extract the "Depends On" line
-    depends_on = [x for x in package_info if x.startswith("Depends On")][0]
-    ## Remove "Depends On" prefix
-    dependencies = depends_on.split(":")[1]
-
-    ## Split into dependencies
-    dependencies = dependencies.strip().split(" ")
+    ## Extract the packages listed for "Depends On:" lines.
+    dependencies = [line.split(":")[1].split() for line in package_info
+                    if line.startswith("Depends On")]
+    ## Flatten dependency lists from multiple packages into one list.
+    dependencies = functools.reduce(operator.iconcat, dependencies, [])
 
     ## Remove > signs TODO can we get any other punctuation here?
     dependencies = [d.split(">")[0] for d in dependencies if d]
@@ -149,16 +149,18 @@ def extract_deps():
     print( "Extracting deps" )
 
     # Get a list of all dependencies needed for packages mentioned above.
-    pkgs = PKG_REQ[:]
-    n = 0
-    while n < len(pkgs):
-        subdeps = immediate_deps(pkgs[n])
-        for p in subdeps:
-            if not (p in pkgs or p in SKIP_DEP_PKGS):
-                pkgs.append(p)
-        n = n + 1
+    pkgs = set(PKG_REQ)
+    newdeps = pkgs
+    print("adding...")
+    while True:
+        subdeps = frozenset(immediate_deps(list(newdeps)))
+        newdeps = subdeps - SKIP_DEP_PKGS - pkgs
+        if not newdeps:
+            break
+        print('\n'.join(newdeps))
+        pkgs |= newdeps
 
-    return sorted(pkgs)
+    return list(pkgs)
 
 
 def download_source(tarball):
@@ -255,7 +257,7 @@ DRY_RUN=args.d
 
 if( args.l ):
     print("List of dependencies")
-    print( extract_deps() )
+    print( deps )
     exit(0)
 
 if args.s:
diff --git a/admin/update_autogen b/admin/update_autogen
index 11c4313..a54c5ac 100755
--- a/admin/update_autogen
+++ b/admin/update_autogen
@@ -248,7 +248,7 @@ info_dir ()
     rm -f $outfile
     cp $basefile $outfile
 
-    local topic file dircat dirent
+    local topic file dircat
 
     ## FIXME inefficient looping.
     for topic in "Texinfo documentation system" "Emacs" "GNU Emacs Lisp" \
@@ -292,8 +292,6 @@ EOF
 
 [ "$autogendir" ] && {
 
-    oldpwd=$PWD
-
     cp $genfiles $autogendir/
 
     cd $autogendir || die "cd error for $autogendir"
diff --git a/configure.ac b/configure.ac
index a19d752..3748bbc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4841,6 +4841,23 @@ dnl AC_CHECK_FUNCS_ONCE wouldn’t be right for snprintf, 
which needs
 dnl the current CFLAGS etc.
 AC_CHECK_FUNCS(snprintf)
 
+dnl posix_spawn.  The chdir and setsid functionality is relatively
+dnl recent, so we check for it specifically.
+AC_CHECK_HEADERS([spawn.h])
+AC_SUBST([HAVE_SPAWN_H])
+AC_CHECK_FUNCS([posix_spawn \
+                posix_spawn_file_actions_addchdir \
+                posix_spawn_file_actions_addchdir_np \
+                posix_spawnattr_setflags])
+AC_SUBST([HAVE_POSIX_SPAWN])
+AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR])
+AC_SUBST([HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP])
+AC_SUBST([HAVE_POSIX_SPAWNATTR_SETFLAGS])
+AC_CHECK_DECLS([POSIX_SPAWN_SETSID], [], [], [[
+               #include <spawn.h>
+               ]])
+AC_SUBST([HAVE_DECL_POSIX_SPAWN_SETSID])
+
 dnl Check for glib.  This differs from other library checks in that
 dnl Emacs need not link to glib unless some other library is already
 dnl linking to glib.  Although glib provides no facilities that Emacs
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi
index 3e07883..b7016b0 100644
--- a/doc/emacs/files.texi
+++ b/doc/emacs/files.texi
@@ -1476,8 +1476,8 @@ characters that don't match.  Then the command exits.
   If point in the two windows is followed by non-matching text when
 the command starts, @kbd{M-x compare-windows} tries heuristically to
 advance up to matching text in the two windows, and then exits.  So if
-you use @kbd{M-x compare-windows} repeatedly, each time it either
-skips one matching range or finds the start of another.
+you use @kbd{M-x compare-windows} repeatedly (@pxref{Repeating}), each
+time it either skips one matching range or finds the start of another.
 
 @vindex compare-ignore-case
 @vindex compare-ignore-whitespace
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 4b3c2ea..3d423d7 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -1703,6 +1703,11 @@ options.  @xref{Initial Options}.  When Emacs is started 
this way, it
 calls @code{server-start} after initialization and does not open an
 initial frame.  It then waits for edit requests from clients.
 
+@item
+Run the command @code{emacsclient} with the @samp{--alternate-editor=""}
+command-line option.  This starts an Emacs daemon only if no Emacs daemon
+is already running.
+
 @cindex systemd unit file
 @item
 If your operating system uses @command{systemd} to manage startup,
@@ -1769,6 +1774,32 @@ you can give each daemon its own server name like this:
   emacs --daemon=foo
 @end example
 
+@findex server-stop-automatically
+  The Emacs server can optionally be stopped automatically when
+certain conditions are met.  To do this, call the function
+@code{server-stop-automatically} in your init file (@pxref{Init
+File}), with one of the following arguments:
+
+@itemize
+@item
+With the argument @code{empty}, the server is stopped when it has no
+clients, no unsaved file-visiting buffers and no running processes
+anymore.
+
+@item
+With the argument @code{delete-frame}, when the last client frame is
+being closed, you are asked whether each unsaved file-visiting buffer
+must be saved and each unfinished process can be stopped, and if so,
+the server is stopped.
+
+@item
+With the argument @code{kill-terminal}, when the last client frame is
+being closed with @kbd{C-x C-c} (@code{save-buffers-kill-terminal}),
+you are asked whether each unsaved file-visiting buffer must be saved
+and each unfinished process can be stopped, and if so, the server is
+stopped.
+@end itemize
+
 @findex server-eval-at
   If you have defined a server by a unique server name, it is possible
 to connect to the server from another Emacs instance and evaluate Lisp
diff --git a/doc/lispintro/emacs-lisp-intro.texi 
b/doc/lispintro/emacs-lisp-intro.texi
index f5f79a5..6ddc3bf 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -5818,7 +5818,7 @@ written like this:
 @subsection The @code{let} Expression in @code{insert-buffer}
 
 After ensuring that the variable @code{buffer} refers to a buffer itself
-and not just to the name of a buffer, the @code{insert-buffer function}
+and not just to the name of a buffer, the @code{insert-buffer} function
 continues with a @code{let} expression.  This specifies three local
 variables, @code{start}, @code{end}, and @code{newmark} and binds them
 to the initial value @code{nil}.  These variables are used inside the
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index b6bd14f..a8a7837 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -6804,6 +6804,12 @@ pixels, and @var{title}, a string, specifies its title.  
@var{related}
 is used internally by the WebKit widget, and specifies another WebKit
 widget that the newly created widget should share settings and
 subprocesses with.
+
+The xwidget that is returned will be killed alongside its buffer
+(@pxref{Killing Buffers}).  Once it is killed, the xwidget may
+continue to exist as a Lisp object and act as a @code{display}
+property until all references to it are gone, but most actions that
+can be performed on live xwidgets will no longer be available.
 @end defun
 
 @defun xwidgetp object
@@ -6811,6 +6817,11 @@ This function returns @code{t} if @var{object} is an 
xwidget,
 @code{nil} otherwise.
 @end defun
 
+@defun xwidget-live-p object
+This function returns @code{t} if @var{object} is an xwidget that
+hasn't been killed, and @code{nil} otherwise.
+@end defun
+
 @defun xwidget-plist xwidget
 This function returns the property list of @var{xwidget}.
 @end defun
@@ -6821,7 +6832,8 @@ property list given by @var{plist}.
 @end defun
 
 @defun xwidget-buffer xwidget
-This function returns the buffer of @var{xwidget}.
+This function returns the buffer of @var{xwidget}.  If @var{xwidget}
+has been killed, it returns @code{nil}.
 @end defun
 
 @defun set-xwidget-buffer xwidget buffer
@@ -6943,6 +6955,16 @@ Finish a search operation started with 
@code{xwidget-webkit-search} in
 signals an error.
 @end defun
 
+@defun xwidget-webkit-load-html xwidget text &optional base-uri
+Load @var{text}, a string, into @var{xwidget}, which should be a
+WebKit xwidget.  Any HTML markup in @var{text} will be processed
+by @var{xwidget} while rendering the text.
+
+Optional argument @var{base-uri}, which should be a string, specifies
+the absolute location of the web resources referenced by @var{text},
+to be used for resolving relative links in @var{text}.
+@end defun
+
 @node Buttons
 @section Buttons
 @cindex buttons in buffers
diff --git a/doc/lispref/nonascii.texi b/doc/lispref/nonascii.texi
index 6980920..24117b50 100644
--- a/doc/lispref/nonascii.texi
+++ b/doc/lispref/nonascii.texi
@@ -1048,9 +1048,9 @@ Alternativnyj, and KOI8.
   Every coding system specifies a particular set of character code
 conversions, but the coding system @code{undecided} is special: it
 leaves the choice unspecified, to be chosen heuristically for each
-file, based on the file's data.  The coding system @code{prefer-utf-8}
-is like @code{undecided}, but it prefers to choose @code{utf-8} when
-possible.
+file or string, based on the file's or string's data, when they are
+decoded or encoded.  The coding system @code{prefer-utf-8} is like
+@code{undecided}, but it prefers to choose @code{utf-8} when possible.
 
   In general, a coding system doesn't guarantee roundtrip identity:
 decoding a byte sequence using a coding system, then encoding the
@@ -1921,9 +1921,24 @@ length of the decoded text.  If that buffer is a unibyte 
buffer
 the decoded text (@pxref{Text Representations}) is inserted into the
 buffer as individual bytes.
 
+@cindex @code{charset}, text property on buffer text
 This command puts a @code{charset} text property on the decoded text.
 The value of the property states the character set used to decode the
 original text.
+
+@cindex undecided coding-system, when decoding
+This command detects the encoding of the text if necessary.  If
+@var{coding-system} is @code{undecided}, the command detects the
+encoding of the text based on the byte sequences it finds in the text,
+and also detects the type of end-of-line convention used by the text
+(@pxref{Lisp and Coding Systems, eol type}).  If @var{coding-system}
+is @code{undecided-@var{eol-type}}, where @var{eol-type} is
+@code{unix}, @code{dos}, or @code{mac}, then the command detects only
+the encoding of the text.  Any @var{coding-system} that doesn't
+specify @var{eol-type}, as in @code{utf-8}, causes the command to
+detect the end-of-line convention; specify the encoding completely, as
+in @code{utf-8-unix}, if the EOL convention used by the text is known
+in advance, to prevent any automatic detection.
 @end deffn
 
 @defun decode-coding-string string coding-system &optional nocopy buffer
@@ -1936,13 +1951,16 @@ trivial.  To make explicit decoding useful, the 
contents of
 values, but a multibyte string is also acceptable (assuming it
 contains 8-bit bytes in their multibyte form).
 
+This function detects the encoding of the string if needed, like
+@code{decode-coding-region} does.
+
 If optional argument @var{buffer} specifies a buffer, the decoded text
 is inserted in that buffer after point (point does not move).  In this
 case, the return value is the length of the decoded text.  If that
 buffer is a unibyte buffer, the internal representation of the decoded
 text is inserted into it as individual bytes.
 
-@cindex @code{charset}, text property
+@cindex @code{charset}, text property on strings
 This function puts a @code{charset} text property on the decoded text.
 The value of the property states the character set used to decode the
 original text:
diff --git a/doc/misc/ChangeLog.1 b/doc/misc/ChangeLog.1
index c050e5d..be2a7ca 100644
--- a/doc/misc/ChangeLog.1
+++ b/doc/misc/ChangeLog.1
@@ -5965,7 +5965,7 @@
        names when publishing to the source directory.
        (Clean view): Document `org-indent-mode'.
        (Clocking work time): Add documentation for the
-       new :timetamp option when creating a clock report.
+       new :timestamp option when creating a clock report.
        (Paragraphs): Fix many typos.
        (Plain lists): Remove duplicate explanation about the
        `C-c *' command.
diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi
index ba1077d..a5b5251 100644
--- a/doc/misc/efaq-w32.texi
+++ b/doc/misc/efaq-w32.texi
@@ -628,7 +628,7 @@ REGEDIT4
 @node Swap Caps 98
 @subsubsection Windows 95/98/ME
 
-Microsoft has a tool called keyremap that is part of their Kernel Toys add ons
+Microsoft has a tool called keyremap that is part of their Kernel Toys add-ons
 for Windows 95.  The tool has also been confirmed to work on Windows 98.
 
 @node Make Emacs like a Windows app
diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi
index 309bed7..f741ee5 100644
--- a/doc/misc/flymake.texi
+++ b/doc/misc/flymake.texi
@@ -218,7 +218,7 @@ can use the variables @code{flymake-mode-line-format} and
 
 @cindex disabled backends
 @cindex backends, disabled
-As Flymake supports multiple simutaneously active external backends,
+As Flymake supports multiple simultaneously active external backends,
 is becomes useful to monitor their status.  For example, some backends
 may take longer than others to respond or complete, and some may
 decide to @emph{disable} themselves if they are not suitable for the
@@ -343,7 +343,7 @@ The following sections discuss each approach in detail.
 To customize the appearance of error types, the user must set
 properties on the symbols associated with each diagnostic type.
 
-The three standard diagnostic keyowrd symbols -- @code{:error},
+The three standard diagnostic keyword symbols -- @code{:error},
 @code{:warning} and @code{:note} -- have pre-configured appearances.
 However a backend may define more (@pxref{Backend functions}).
 
diff --git a/doc/misc/org.org b/doc/misc/org.org
index 17fd2dc..df2724d 100644
--- a/doc/misc/org.org
+++ b/doc/misc/org.org
@@ -16556,7 +16556,7 @@ identifying a reference in the bibliography.
 - Each key starts with the character =@=.
 
 - Each key can be qualified by a /prefix/ (e.g.\nbsp{}"see ") and/or
-  a /suffix/ (e.g.\nbsp{}"p.\nbsp{}123"), giving informations useful or 
necessary
+  a /suffix/ (e.g.\nbsp{}"p.\nbsp{}123"), giving information useful or 
necessary
   fo the comprehension of the citation but not included in the
   reference.
 
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index a17a8d6..819670a 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -2238,8 +2238,7 @@ preserves the path value, which can be used to update
 shell supports the login argument @samp{-l}.
 @end defopt
 
-Starting with @w{Emacs 26}, @code{tramp-remote-path} can be set per
-host via connection-local
+@code{tramp-remote-path} can also be set per host via connection-local
 @ifinfo
 variables, @xref{Connection Variables, , , emacs}.
 @end ifinfo
@@ -3533,9 +3532,8 @@ ensures the correct name of the remote shell program.
 When @code{explicit-shell-file-name} is equal to @code{nil}, calling
 @code{shell} interactively will prompt for a shell name.
 
-Starting with @w{Emacs 26}, you could use connection-local variables
-for setting different values of @code{explicit-shell-file-name} for
-different remote hosts.
+You could use connection-local variables for setting different values
+of @code{explicit-shell-file-name} for different remote hosts.
 @ifinfo
 @xref{Connection Variables, , , emacs}.
 @end ifinfo
@@ -4347,8 +4345,8 @@ Where is the latest @value{tramp}?
 @item
 Which systems does it work on?
 
-The package works successfully on @w{Emacs 25}, @w{Emacs 26}, @w{Emacs
-27}, and @w{Emacs 28}.
+The package works successfully on @w{Emacs 26}, @w{Emacs 27}, @w{Emacs
+28}, and @w{Emacs 29}.
 
 While Unix and Unix-like systems are the primary remote targets,
 @value{tramp} has equal success connecting to other platforms, such as
diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi
index b11ee39..89c4780 100644
--- a/doc/misc/trampver.texi
+++ b/doc/misc/trampver.texi
@@ -8,10 +8,10 @@
 @c In the Tramp GIT, the version numbers are auto-frobbed from
 @c tramp.el, and the bug report address is auto-frobbed from
 @c configure.ac.
-@set trampver 2.5.2-pre
+@set trampver 2.6.0-pre
 @set trampurl https://www.gnu.org/software/tramp/
 @set tramp-bug-report-address tramp-devel@@gnu.org
-@set emacsver 25.1
+@set emacsver 26.1
 
 @c Other flags from configuration.
 @set instprefix /usr/local
diff --git a/etc/NEWS b/etc/NEWS
index 3cad099..c362e56 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -46,6 +46,14 @@ time.
 
 * Changes in Emacs 29.1
 
+** Terminal Emacs
+
+---
+*** Emacs will now use 24-bit colors on terminals that support "Tc" capability.
+This is in addition to previously-supported ways of discovering 24-bit
+color support: either via the "RGB" or "setf24" capabilities, or if
+the 'COLORTERM' environment variable is set to the value "truecolor".
+
 ** Emoji
 
 +++
@@ -88,7 +96,7 @@ Jumping to source from "*Help*" buffer moves the point when 
the source
 buffer is already open.  Now, the old point is pushed to mark ring.
 
 +++
-*** New key bindings in *Help* buffers: 'n' and 'p'.
+*** New key bindings in "*Help*" buffers: 'n' and 'p'.
 These will take you (respectively) to the next and previous "page".
 
 ---
@@ -99,7 +107,7 @@ These will take you (respectively) to the next and previous 
"page".
 +++
 *** New user option 'outline-minor-mode-use-buttons'.
 If non-nil, Outline Minor Mode will use buttons to hide/show outlines
-in addition to the ellipsis.
+in addition to the ellipsis.  Default nil.
 
 ---
 *** New user option 'outline-minor-mode-buttons'.
@@ -115,8 +123,12 @@ Image specifiers can now use ':type webp'.
 
 +++
 *** 'display-buffer' now can set up the body size of the chosen window.
-For example, an alist entry as '(window-width . (body-columns . 40))'
-will make the body of the chosen window 40 columns wide.
+For example, a 'display-buffer-alist' entry of
+
+    '(window-width . (body-columns . 40))'
+
+will make the body of the chosen window 40 columns wide.  For the
+height use 'window-height' in combination with 'body-lines'.
 
 ** Better detection of text suspiciously reordered on display.
 The function 'bidi-find-overridden-directionality' has been extended
@@ -126,8 +138,6 @@ LRI).  The new command 'highlight-confusing-reorderings' 
finds and
 highlights segments of buffer text whose reordering for display is
 suspicious and could be malicious.
 
-
-
 ** Emacs server and client changes
 
 +++
@@ -135,6 +145,12 @@ suspicious and could be malicious.
 With this command-line option, Emacs reuses an existing graphical client
 frame if one exists; otherwise it creates a new frame.
 
++++
+*** 'server-stop-automatically' can be used to automatically stop the server.
+The Emacs server will be automatically stopped when certain conditions
+are met.  The conditions are given by the argument, which can be
+'empty', 'delete-frame' or 'kill-terminal'.
+
 * Editing Changes in Emacs 29.1
 
 ---
@@ -170,7 +186,7 @@ effectively dragged.
 
 ---
 ** New user option 'yank-menu-max-items'.
-Customize this option to limit the amount of entries in the menu
+Customize this option to limit the number of entries in the menu
 "Edit->Paste from Kill Menu".  The default is 60.
 
 ** show-paren-mode
@@ -179,7 +195,7 @@ Customize this option to limit the amount of entries in the 
menu
 *** New user option 'show-paren-context-when-offscreen'.
 When non-nil, if the point is in a closing delimiter and the opening
 delimiter is offscreen, shows some context around the opening
-delimiter in the echo area.
+delimiter in the echo area.  Default nil.
 
 ** Comint
 
@@ -192,14 +208,21 @@ change the terminal used on a remote host.
 
 * Changes in Specialized Modes and Packages in Emacs 29.1
 
+** Info
+
+---
+*** New command 'Info-goto-node-web' and key binding 'G'.
+This will take you to the gnu.org web server's version of the current
+info node.  This command only works for the Emacs and Emacs Lisp manuals.
+
 ** vc
 
 ---
 *** 'C-x v v' on an unregistered file will now use the most specific backend.
-Previously, if you had an SVN-covered ~/ directory, and a Git-covered
-directory in ~/foo/bar, using 'C-x v v' on a new, unregistered file
-~/foo/bar/zot would register it in the SVN repository in ~/ instead of
-in the Git repository in ~/foo/bar.  This makes this command
+Previously, if you had an SVN-covered "~/" directory, and a Git-covered
+directory in "~/foo/bar", using 'C-x v v' on a new, unregistered file
+"~/foo/bar/zot" would register it in the SVN repository in "~/" instead of
+in the Git repository in "~/foo/bar".  This makes this command
 consistent with 'vc-responsible-backend'.
 
 ** Message
@@ -211,8 +234,10 @@ If non-nil, 'C-c C-a' will put attached files at the end 
of the message.
 ---
 *** Message Mode now supports image yanking.
 
+** HTML Mode
+
 ---
-*** HTML Mode now supports text/html and image/* yanking.
+*** HTML Mode now supports "text/html" and "image/*" yanking.
 
 ** Texinfo Mode
 
@@ -232,14 +257,14 @@ doesn't work on other systems.  Also see etc/PROBLEMS.
 +++
 *** New user option 'eww-url-transformers'.
 These are used to alter an URL before using it.  By default it removes
-the common utm_ trackers from URLs.
+the common "utm_" trackers from URLs.
 
 ** Gnus
 
 +++
 *** New user option 'gnus-treat-emojize-symbols'.
 If non-nil, symbols that have an emoji representation will be
-displayed as emojis.
+displayed as emojis.  Default nil.
 
 +++
 *** New command 'gnus-article-emojize-symbols'.
@@ -249,74 +274,7 @@ representation as emojis.
 ** EIEIO
 
 +++
-*** New command 'C-x t C-r' to open file read-only in the other tab.
-
-+++
-*** The tab bar now supports more mouse commands.
-Clicking 'mouse-2' closes the tab, 'mouse-3' displays the context menu
-with items that operate on the clicked tab.  Dragging the tab with
-'mouse-1' moves it to another position on the tab bar.  Mouse wheel
-scrolling switches to the previous/next tab, and holding the Shift key
-during scrolling moves the tab to the left/right.
-
-+++
-*** Frame-specific appearance of the tab bar when 'tab-bar-show' is a number.
-When 'tab-bar-show' is a number, the tab bar on different frames can
-be shown or hidden independently, as determined by the number of tabs
-on each frame compared to the numerical value of 'tab-bar-show'.
-
-+++
-*** New command 'toggle-frame-tab-bar'.
-It can be used to enable/disable the tab bar on the currently selected
-frame regardless of the values of 'tab-bar-mode' and 'tab-bar-show'.
-This allows enabling/disabling the tab bar independently on different
-frames.
-
-+++
-*** New user option 'tab-bar-format' defines a list of tab bar items.
-When it contains 'tab-bar-format-global' (possibly appended after
-'tab-bar-format-align-right'), then after enabling 'display-time-mode'
-(or any other mode that uses 'global-mode-string') it displays time
-aligned to the right on the tab bar instead of on the mode line.
-When 'tab-bar-format-tabs' is replaced with 'tab-bar-format-tabs-groups',
-the tab bar displays tab groups.
-
-+++
-*** New optional key binding for 'tab-last'.
-If you customize the user option 'tab-bar-select-tab-modifiers' to
-allow selecting tabs using their index numbers, the '<MODIFIER>-9' key
-is bound to 'tab-last', and switches to the last tab.  Here <MODIFIER>
-is any of the modifiers in the list that is the value of
-'tab-bar-select-tab-modifiers'.  You can also use positive indices,
-which count from the last tab: 1 is the last tab, 2 the one before
-that, etc.
-
----
-*** New command 'tab-duplicate' bound to 'C-x t n'.
-
----
-*** 'C-x t N' creates a new tab at the specified absolute position.
-The position is provided as prefix arg, and specifies an index that
-starts at 1.  Negative values count from the end of the tab bar.
-
----
-*** 'C-x t M' moves the current tab to the specified absolute position.
-The position is provided as prefix arg, whose interpretation is as in
-'C-x t N'.
-
----
-*** 'C-x t G' assigns a tab to a named group of tabs.
-'tab-close-group' closes all tabs that belong to the selected group.
-The user option 'tab-bar-new-tab-group' defines the default group of
-new tabs.  After customizing 'tab-bar-tab-post-change-group-functions'
-to 'tab-bar-move-tab-to-group', changing the group of a tab will also
-move it closer to other tabs in the same group.
-
----
-*** New user option 'tab-bar-tab-name-format-function'.
-
----
-*** New user option 'tab-line-tab-name-format-function'.
+*** 'slot-value' can now be used to read slots of 'cl-defstruct' objects.
 
 ** align
 
@@ -340,10 +298,10 @@ default, no automatic renaming is performed.
 ** Help
 
 *** New user option 'help-link-key-to-documentation'.
-When this option is non-nil, key bindings displayed in the "*Help*"
-buffer will be linked to the documentation for the command they are
-bound to.  This does not affect listings of key bindings and
-functions (such as 'C-h b').
+When this option is non-nil (which is the default), key bindings
+displayed in the "*Help*" buffer will be linked to the documentation
+for the command they are bound to.  This does not affect listings of
+key bindings and functions (such as 'C-h b').
 
 ** info-look
 
@@ -415,7 +373,7 @@ The keybinding for 'image-transform-fit-to-width' is now 's 
i'.
 This works like 'image-transform-fit-to-window'.
 
 *** New user option 'image-auto-resize-max-scale-percent'.
-The new 'fit-window' options will never scale an image more than this
+The new 'fit-window' option will never scale an image more than this
 much (in percent).  It is nil by default.
 
 ** Image-Dired
@@ -445,13 +403,13 @@ external "exiftool" command to be available.  The user 
options
 ---
 *** New command for the thumbnail buffer.
 The new command 'image-dired-unmark-all-marks' has been added.  It is
-bound to "U" in the thumbnail buffer.
+bound to 'U' in the thumbnail buffer.
 
 ---
 *** Support Thumbnail Managing Standard v0.9.0 (Dec 2020).
 This standard allows sharing generated thumbnails across different
 programs.  Version 0.9.0 adds two larger thumbnail sizes: 512x512 and
-1024x1024 pixels.  See the user option `image-dired-thumbnail-storage'
+1024x1024 pixels.  See the user option 'image-dired-thumbnail-storage'
 to use it; it is not enabled by default.
 
 ---
@@ -466,6 +424,15 @@ used for images that are flagged for deletion in the Dired 
buffer
 associated with Image-Dired.
 
 ---
+*** The 'image-dired-slideshow-start' command has been revamped.
+It no longer inconveniently prompts for a number of images and a
+delay: it runs indefinitely, but stops automatically on any command.
+You can set the delay with a prefix argument, or a negative prefix
+argument to prompt anyways.  Customize the user option
+'image-dired-slideshow-delay' to change the default, which is 5
+seconds.  It is bound to 'S' in the thumbnail and display buffer.
+
+---
 *** Support for bookmark.el.
 The command 'bookmark-set' (bound to 'C-x r m') is now supported in
 the thumbnail view, and will create a bookmark that opens the current
@@ -494,7 +461,6 @@ If non-nil (which is the default), hitting 'RET' or 
'mouse-1' on
 the directory components at the directory displayed at the start of
 the buffer will take you to that directory.
 
-
 ** Exif
 
 *** New function 'exif-field'.
@@ -504,13 +470,14 @@ This is a convenience function to extract the field data 
from
 ** Xwidgets
 
 ---
-*** New user option 'xwidget-webkit-buffer-name-prefix'.
-This allows the user to change the webkit buffer names.
+*** New user option 'xwidget-webkit-buffer-name-format'.
+Using this option you can control how the xwidget-webkit buffers are
+named.
 
 +++
 *** New minor mode 'xwidget-webkit-edit-mode'.
 When this mode is enabled, self-inserting characters and other common
-web browser shotcut keys are redefined to send themselves to the
+web browser shortcut keys are redefined to send themselves to the
 WebKit widget.
 
 +++
@@ -545,11 +512,11 @@ Emacs buffers, like indentation and the like.  The new 
ert function
 ** Fonts
 
 ---
-*** Emacs now supports `medium' fonts.
-Emacs previously didn't distinguish between the `regular'/`normal'
-weight and the `medium' weight, but it now also supports the (heavier)
-`medium' weight.  However, this means that if you previously specified
-a weight of `normal' and the font doesn't have this weight, Emacs
+*** Emacs now supports 'medium' fonts.
+Emacs previously didn't distinguish between the 'regular'/'normal'
+weight and the 'medium' weight, but it now also supports the (heavier)
+'medium' weight.  However, this means that if you previously specified
+a weight of 'normal' and the font doesn't have this weight, Emacs
 won't find the font spec.  In these cases, replacing ":weight 'normal"
 with ":weight 'medium" should fix the issue.
 
@@ -572,6 +539,12 @@ to multibyte first.  (This goes for the other 
case-changing functions,
 too.)
 
 ---
+** Functions in 'tramp-foreign-file-name-handler-alist' have changed.
+Functions to determine which Tramp file name handler to use are now
+passed a file name in dissected form (via 'tramp-dissect-file-name')
+instead of in string form.
+
+---
 ** 'def' indentation changes.
 In 'emacs-lisp-mode', forms with a symbol with a name that start with
 "def" have been automatically indented as if they were 'defun'-like
@@ -613,60 +586,60 @@ Use 'exif-parse-file' and 'exif-field' instead.
 * Lisp Changes in Emacs 29.1
 
 +++
-*** New function 'file-name-split'.
+** New function 'file-name-split'.
 This returns a list of all the components of a file name.
 
 +++
-*** New macro 'with-undo-amalgamate'
-It records a particular sequence of operations as a single undo step
+** New macro 'with-undo-amalgamate'.
+It records a particular sequence of operations as a single undo step.
 
 +++
-*** New command 'yank-media'.
+** New command 'yank-media'.
 This command supports yanking non-plain-text media like images and
 HTML from other applications into Emacs.  It is only supported in
 modes that have registered support for it, and only on capable
 platforms.
 
 +++
-*** New command 'yank-media-types'.
+** New command 'yank-media-types'.
 This command lets you examine all data in the current selection and
 the clipboard, and insert it into the buffer.
 
 +++
-*** New text property 'inhibit-isearch'.
+** New text property 'inhibit-isearch'.
 If set, 'isearch' will skip these areas, which can be useful (for
 instance) when covering huge amounts of data (that has no meaningful
 searchable data, like image data) with a 'display' text property.
 
 +++
-*** 'insert-image' now takes an INHIBIT-ISEARCH optional parameter.
-It marks the image with the 'inhibit-isearch' text parameter, which
+** 'insert-image' now takes an INHIBIT-ISEARCH optional parameter.
+It marks the image with the 'inhibit-isearch' text property, which
 inhibits 'isearch' matching the STRING parameter.
 
 ---
-*** New user option 'pp-use-max-width'.
+** New user option 'pp-use-max-width'.
 If non-nil, 'pp' will attempt to limit the line length when formatting
 long lists and vectors.
 
 ---
-*** New function 'pp-emacs-lisp-code'.
+** New function 'pp-emacs-lisp-code'.
 'pp' formats general Lisp sexps.  This function does much the same,
 but applies formatting rules appropriate for Emacs Lisp code.
 
 +++
-*** New function 'file-has-changed-p'.
+** New function 'file-has-changed-p'.
 This convenience function is useful when writing code that parses
 files at run-time, and allows Lisp programs to re-parse files only
 when they have changed.
 
 ---
-*** New function 'font-has-char-p'.
+** New function 'font-has-char-p'.
 This can be used to check whether a specific font has a glyph for a
 character.
 
 ** XDG support
 
-*** New function 'xdg-state-home' returns $XDG_STATE_HOME.
+*** New function 'xdg-state-home' returns 'XDG_STATE_HOME' environment 
variable.
 This new location, introduced in the XDG Base Directory Specification
 version 0.8 (8th May 2021), "contains state data that should persist
 between (application) restarts, but that is not important or portable
@@ -680,7 +653,7 @@ the body takes longer to execute than the specified timeout.
 ---
 ** New function 'funcall-with-delayed-message'.
 This function is like 'funcall', but will output the specified message
-is the function take longer to execute that the specified timeout.
+if the function takes longer to execute than the specified timeout.
 
 ** Locale
 
@@ -697,7 +670,7 @@ executing code.
 
 +++
 *** A column can now be set to an image descriptor.
-The `tabulated-list-entries' variable now supports using an image
+The 'tabulated-list-entries' variable now supports using an image
 descriptor, which means to insert an image in that column instead of
 text.  See the documentation string of that variable for details.
 
@@ -769,7 +742,7 @@ separate glyphs.  This takes into account combining 
characters and
 grapheme clusters.
 
 ---
-** 'lookup-key' is more allowing when searching for extended menu items.
+** 'lookup-key' is more permissive when searching for extended menu items.
 In Emacs 28.1, the behavior of 'lookup-key' was changed: when looking
 for a menu item '[menu-bar Foo-Bar]', first try to find an exact
 match, then look for the lowercased '[menu-bar foo-bar]'.
@@ -780,9 +753,9 @@ an exact match, then the lowercased '[menu-bar foo\ bar]' 
and finally
 '[menu-bar foo-bar]'.  This further improves backwards-compatibility
 when converting menus to use 'easy-menu-define'.
 
-+++
 ** xwidgets
 
++++
 *** The function 'make-xwidget' now accepts an optional RELATED argument.
 This argument is used as another widget for the newly created WebKit
 widget to share settings and subprocesses with.  It must be another
@@ -797,6 +770,13 @@ what the widget will actually receive.
 On GTK+, only key and function key events are implemented.
 
 +++
+*** New function 'xwidget-webkit-load-html'.
+This function is used to load HTML text into WebKit xwidgets
+directly, in contrast to creating a temporary file to hold the
+markup, and passing the URI of the file as an argument to
+'xwidget-webkit-goto-uri'.
+
++++
 *** New functions for performing searches on WebKit xwidgets.
 Some new functions, such as 'xwidget-webkit-search', have been added
 for performing searches on WebKit xwidgets.
diff --git a/etc/NEWS.28 b/etc/NEWS.28
index a7b4dc6..8e38c36 100644
--- a/etc/NEWS.28
+++ b/etc/NEWS.28
@@ -486,6 +486,7 @@ command 'other-tab-prefix'.
 +++
 *** New command 'C-x t C-r' to open file read-only in the other tab.
 
++++
 *** The tab bar now supports more mouse commands.
 Clicking 'mouse-2' closes the tab, 'mouse-3' displays the context menu
 with items that operate on the clicked tab.  Dragging the tab with
@@ -506,7 +507,7 @@ frame regardless of the values of 'tab-bar-mode' and 
'tab-bar-show'.
 This allows enabling/disabling the tab bar independently on different
 frames.
 
----
++++
 *** New user option 'tab-bar-format' defines a list of tab bar items.
 When it contains 'tab-bar-format-global' (possibly appended after
 'tab-bar-format-align-right'), then after enabling 'display-time-mode'
@@ -515,14 +516,14 @@ aligned to the right on the tab bar instead of on the 
mode line.
 When 'tab-bar-format-tabs' is replaced with 'tab-bar-format-tabs-groups',
 the tab bar displays tab groups.
 
----
++++
 *** New optional key binding for 'tab-last'.
 If you customize the user option 'tab-bar-select-tab-modifiers' to
 allow selecting tabs using their index numbers, the '<MODIFIER>-9' key
 is bound to 'tab-last', and switches to the last tab.  Here <MODIFIER>
 is any of the modifiers in the list that is the value of
-'tab-bar-select-tab-modifiers'.  You can also use negative indices,
-which count from the last tab: -1 is the last tab, -2 the one before
+'tab-bar-select-tab-modifiers'.  You can also use positive indices,
+which count from the last tab: 1 is the last tab, 2 the one before
 that, etc.
 
 ---
@@ -1398,7 +1399,6 @@ keys, add the following to your init file:
 Using it instead of 'read-char-choice' allows using 'C-x o'
 to switch to the help window displayed after typing 'C-h'.
 
-
 +++
 ** Emacs 28.1 comes with Org v9.5.
 See the file ORG-NEWS for user-visible changes in Org.
@@ -1532,16 +1532,6 @@ When the bookmark.el library is loaded, a customize 
choice is added
 to 'tab-bar-new-tab-choice' for new tabs to show the bookmark list.
 
 ---
-*** The 'list-bookmarks' menu is now based on 'tabulated-list-mode'.
-The interactive bookmark list will now benefit from features in
-'tabulated-list-mode' like sorting columns or changing column width.
-
-Support for the optional "inline" header line, allowing for a header
-without using 'header-line-format', has been dropped.  Consequently,
-the variables 'bookmark-bmenu-use-header-line' and
-'bookmark-bmenu-inline-header-height' are now declared obsolete.
-
----
 *** New user option 'bookmark-set-fringe-mark'.
 If non-nil, setting a bookmark will set a fringe mark on the current
 line, and jumping to a bookmark will also set this mark.
@@ -1554,6 +1544,16 @@ that have been marked for deletion.  However, if this 
new option is
 non-nil then Emacs will require confirmation with 'yes-or-no-p' before
 deleting.
 
+---
+*** The 'list-bookmarks' menu is now based on 'tabulated-list-mode'.
+The interactive bookmark list will now benefit from features in
+'tabulated-list-mode' like sorting columns or changing column width.
+
+Support for the optional "inline" header line, allowing for a
+header without using 'header-line-format', has been dropped.
+The variables 'bookmark-bmenu-use-header-line' and
+'bookmark-bmenu-inline-header-height' are now obsolete.
+
 ** Recentf
 
 ---
@@ -1854,7 +1854,7 @@ The command 'next-error-no-select' is now bound to 'n' and
 'previous-error-no-select' is bound to 'p'.
 
 ---
-*** The new command 'recenter-current-error'.
+*** New command 'recenter-current-error'.
 It is bound to 'l' in Occur or compilation buffers, and recenters the
 current displayed occurrence/error.
 
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index d8d4cf7..f506881 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -1087,6 +1087,24 @@ The solution is to remove the corresponding lines from 
the appropriate
 'fonts.alias' file, then run 'mkfontdir' in that directory, and then run
 'xset fp rehash'.
 
+** fcitx input methods don't work with xwidgets.
+
+fcitx-based input methods might not work when xwidgets are displayed,
+such as inside an xwidget-webkit buffer.  This manifests as the pre-edit
+window of the input method disappearing, and the Emacs frame losing
+input focus as soon as you try to type anything.  You can work around
+this problem by switching to IBus, or by using a native Emacs input
+method and disabling XIM altogether.  For example, you can add the
+following line:
+
+  Emacs.useXIM: false
+
+In your ~/.Xresources file, then run
+
+  $ xrdb ~/.Xresources
+
+And restart Emacs.
+
 * X runtime problems
 
 ** X keyboard problems
@@ -2749,7 +2767,7 @@ its path available to Emacs.  Errors such as:
     Error: Internal native compiler error failed to compile
 
 indicate Emacs can't find the library in running time.  One can set
-the "LIBRARY_PATH" environment variable in the early initalization
+the "LIBRARY_PATH" environment variable in the early initialization
 file; for example:
 
 (setenv "LIBRARY_PATH"
diff --git a/lisp/ChangeLog.12 b/lisp/ChangeLog.12
index 5d42457..d841a75 100644
--- a/lisp/ChangeLog.12
+++ b/lisp/ChangeLog.12
@@ -182,7 +182,7 @@
 
 2007-04-19  Glenn Morris  <rgm@gnu.org>
 
-       * calendar/todo-mode.el: Fix typo: "threshhold" -> "threshold".
+       * calendar/todo-mode.el: Fix typo for "threshold".
 
 2007-04-18  Glenn Morris  <rgm@gnu.org>
 
diff --git a/lisp/calc/calc-store.el b/lisp/calc/calc-store.el
index b396855..de2f18f 100644
--- a/lisp/calc/calc-store.el
+++ b/lisp/calc/calc-store.el
@@ -188,12 +188,15 @@
   (let* ((calc-store-opers store-opers)
          (var (concat
               "var-"
-              (let ((minibuffer-completion-table
-                     (mapcar (lambda (x) (substring x 4))
-                             (all-completions "var-" obarray)))
-                    (minibuffer-completion-predicate
-                     (lambda (x) (boundp (intern (concat "var-" x)))))
-                    (minibuffer-completion-confirm t))
+              (minibuffer-with-setup-hook
+                  (lambda ()
+                    (setq-local minibuffer-completion-table
+                                (mapcar (lambda (x) (substring x 4))
+                                        (all-completions "var-" obarray)))
+                    (setq-local minibuffer-completion-predicate
+                                (lambda (x)
+                                  (boundp (intern (concat "var-" x)))))
+                    (setq-local minibuffer-completion-confirm t))
                 (read-from-minibuffer
                  prompt nil calc-var-name-map nil
                  'calc-read-var-name-history)))))
diff --git a/lisp/cedet/ChangeLog.1 b/lisp/cedet/ChangeLog.1
index fb3dcd2..0fe5573 100644
--- a/lisp/cedet/ChangeLog.1
+++ b/lisp/cedet/ChangeLog.1
@@ -1705,7 +1705,7 @@
 
 2012-07-29  Paul Eggert  <eggert@cs.ucla.edu>
 
-       inaccessable -> inaccessible spelling fix (Bug#10052)
+       "inaccessible" spelling fix (Bug#10052)
        * semantic/wisent/comp.el (wisent-inaccessible-symbols):
        Rename from wisent-inaccessable-symbols, fixing a misspelling.
        Caller changed.
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el
index aaacba2..148fb70 100644
--- a/lisp/emacs-lisp/autoload.el
+++ b/lisp/emacs-lisp/autoload.el
@@ -393,6 +393,8 @@ FILE's name."
     (concat ";;; " basename
             " --- automatically extracted " (or type "autoloads")
             "  -*- lexical-binding: t -*-\n"
+            (when (equal basename "loaddefs.el")
+              ";; This file will be copied to ldefs-boot.el and checked in 
periodically.\n")
            ";;\n"
            ";;; Code:\n\n"
            (if lp
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index 7bb82c2..ab2f34c 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -1116,6 +1116,7 @@ space at the end of each line."
           ";;; lisp/trampver.el.  Generated from trampver.el.in by 
configure."))
   "Regexp that when it matches tells `checkdoc-dired' to skip a file.")
 
+;;;###autoload
 (defun checkdoc-dired (files)
   "In Dired, run `checkdoc' on marked files.
 Skip anything that doesn't have the Emacs Lisp library file
diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el
index d24ea35..59cbc0e 100644
--- a/lisp/emacs-lisp/crm.el
+++ b/lisp/emacs-lisp/crm.el
@@ -244,30 +244,29 @@ contents of the minibuffer are \"alice,bob,eve\" and 
point is between
 
 This function returns a list of the strings that were read,
 with empty strings removed."
-  (unwind-protect
-      (progn
-       (add-hook 'choose-completion-string-functions
-                 'crm--choose-completion-string)
-       (let* ((minibuffer-completion-table #'crm--collection-fn)
-              (minibuffer-completion-predicate predicate)
-              ;; see completing_read in src/minibuf.c
-              (minibuffer-completion-confirm
-               (unless (eq require-match t) require-match))
-              (crm-completion-table table)
-              (map (if require-match
-                       crm-local-must-match-map
-                     crm-local-completion-map))
-              ;; If the user enters empty input, `read-from-minibuffer'
-              ;; returns the empty string, not DEF.
-              (input (read-from-minibuffer
-                      prompt initial-input map
-                      nil hist def inherit-input-method)))
-         (when (and def (string-equal input ""))
-           (setq input (if (consp def) (car def) def)))
-          ;; Remove empty strings in the list of read strings.
-         (split-string input crm-separator t)))
-    (remove-hook 'choose-completion-string-functions
-                'crm--choose-completion-string)))
+  (let* ((map (if require-match
+                  crm-local-must-match-map
+                crm-local-completion-map))
+         input)
+    (minibuffer-with-setup-hook
+        (lambda ()
+          (add-hook 'choose-completion-string-functions
+                    'crm--choose-completion-string nil 'local)
+          (setq-local minibuffer-completion-table #'crm--collection-fn)
+          (setq-local minibuffer-completion-predicate predicate)
+          ;; see completing_read in src/minibuf.c
+          (setq-local minibuffer-completion-confirm
+                      (unless (eq require-match t) require-match))
+          (setq-local crm-completion-table table))
+      (setq input (read-from-minibuffer
+                   prompt initial-input map
+                   nil hist def inherit-input-method)))
+    ;; If the user enters empty input, `read-from-minibuffer'
+    ;; returns the empty string, not DEF.
+    (when (and def (string-equal input ""))
+      (setq input (if (consp def) (car def) def)))
+    ;; Remove empty strings in the list of read strings.
+    (split-string input crm-separator t)))
 
 ;; testing and debugging
 ;; (defun crm-init-test-environ ()
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 27eaa48..08dfe50 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2202,6 +2202,7 @@ directory."
           (dired-mode))
       (insert-file-contents-literally file)
       (set-visited-file-name file)
+      (set-buffer-modified-p nil)
       (when (string-match "\\.tar\\'" file) (tar-mode)))
     (package-install-from-buffer)))
 
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index e3caf88..f336799 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -416,14 +416,14 @@ and return the value found in PLACE instead."
 
 ;;;###autoload
 (defun ensure-empty-lines (&optional lines)
-  "Ensure that there's LINES number of empty lines before point.
-If LINES is nil or missing, a this ensures that there's a single
-empty line before point.
+  "Ensure that there are LINES number of empty lines before point.
+If LINES is nil or omitted, ensure that there is a single empty
+line before point.
 
-Interactively, this command uses the numerical prefix for LINES.
+If called interactively, LINES is given by the prefix argument.
 
-If there's already more empty lines before point than LINES, the
-number of blank lines will be reduced.
+If there are more than LINES empty lines before point, the number
+of empty lines is reduced to LINES.
 
 If point is not at the beginning of a line, a newline character
 is inserted before adjusting the number of empty lines."
diff --git a/lisp/env.el b/lisp/env.el
index 2f7cd9d..fc48059 100644
--- a/lisp/env.el
+++ b/lisp/env.el
@@ -220,7 +220,7 @@ in the environment list of the selected frame."
 
 ;;;###autoload
 (defmacro with-environment-variables (variables &rest body)
-  "Set VARIABLES in the environent and execute BODY.
+  "Set VARIABLES in the environment and execute BODY.
 VARIABLES is a list of variable settings of the form (VAR VALUE),
 where VAR is the name of the variable (a string) and VALUE
 is its value (also a string).
diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el
index adb3f52..5e4cef5 100644
--- a/lisp/erc/erc-services.el
+++ b/lisp/erc/erc-services.el
@@ -492,7 +492,7 @@ Returns t if the message could be sent, nil otherwise."
 Identification will either use NICK or the current nick if not
 provided, and some password obtained through
 `erc-nickserv-get-password' (which see).  If no password can be
-found, an error is reported trough `erc-error'.
+found, an error is reported through `erc-error'.
 
 Interactively, the user will be prompted for NICK, an empty
 string meaning to default to the current nick.
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 3028568..abb1f64 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -3606,11 +3606,13 @@ other people should be displayed."
 
 (defun erc-cmd-QUERY (&optional user)
   "Open a query with USER.
-The type of query window/frame/etc will depend on the value of
-`erc-query-display'.
-
-If USER is omitted, close the current query buffer if one exists
-- except this is broken now ;-)"
+How the query is displayed (in a new window, frame, etc.) depends
+on the value of `erc-query-display'."
+  ;; FIXME: The doc string used to say at the end:
+  ;; "If USER is omitted, close the current query buffer if one exists
+  ;; - except this is broken now ;-)"
+  ;; Does it make sense to have that functionality?  What's wrong with
+  ;; `kill-buffer'?  If it makes sense, re-add it.  -- SK @ 2021-11-11
   (interactive
    (list (read-string "Start a query with: ")))
   (let ((session-buffer (erc-server-buffer))
diff --git a/lisp/files.el b/lisp/files.el
index c694df3..3490d04 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -5069,7 +5069,7 @@ On most systems, this will be true:
         (setq filename (and dir (directory-file-name dir)))
         ;; If there's nothing left to peel off, we're at the root and
         ;; we can stop.
-        (when (equal dir filename)
+        (when (and dir (equal dir filename))
           (push "" components)
           (setq filename nil))))
     components))
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index 89b4a63..78ce89d 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -4579,7 +4579,6 @@ commands:
        (let ((summary gnus-summary-buffer))
          (with-current-buffer name
             (setq-local gnus-article-edit-mode nil)
-           (gnus-article-stop-animations)
            (when gnus-article-mime-handles
              (mm-destroy-parts gnus-article-mime-handles)
              (setq gnus-article-mime-handles nil))
@@ -4605,6 +4604,7 @@ commands:
          (current-buffer))))))
 
 (defun gnus-article-stop-animations ()
+  (declare (obsolete nil "29.1"))
   (cancel-function-timers 'image-animate-timeout))
 
 (defun gnus-stop-downloads ()
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 3beeace..f066612 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -7206,7 +7206,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
     (gnus-dribble-save)))
 
 (declare-function gnus-cache-write-active "gnus-cache" (&optional force))
-(declare-function gnus-article-stop-animations "gnus-art" ())
 
 (defun gnus-summary-exit (&optional temporary leave-hidden)
   "Exit reading current newsgroup, and then return to group selection mode.
@@ -7270,7 +7269,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
                (not (string= group (gnus-group-group-name))))
       (gnus-group-next-unread-group 1))
     (setq group-point (point))
-    (gnus-article-stop-animations)
     (unless leave-hidden
       (gnus-configure-windows 'group 'force))
     (if temporary
@@ -7330,7 +7328,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (run-hooks 'gnus-summary-prepare-exit-hook)
       (when (gnus-buffer-live-p gnus-article-buffer)
        (with-current-buffer gnus-article-buffer
-         (gnus-article-stop-animations)
          (gnus-stop-downloads)
          (mm-destroy-parts gnus-article-mime-handles)
          ;; Set it to nil for safety reason.
@@ -7362,7 +7359,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
        (gnus-group-update-group group nil t))
       (when (gnus-group-goto-group group)
        (gnus-group-next-unread-group 1))
-      (gnus-article-stop-animations)
       (when quit-config
        (gnus-handle-ephemeral-exit quit-config)))))
 
@@ -9908,7 +9904,6 @@ article.  Normally, the keystroke is 
`\\[universal-argument] \\[gnus-summary-sho
       ;; Destroy any MIME parts.
       (when (gnus-buffer-live-p gnus-article-buffer)
        (with-current-buffer gnus-article-buffer
-         (gnus-article-stop-animations)
          (gnus-stop-downloads)
          (mm-destroy-parts gnus-article-mime-handles)
          ;; Set it to nil for safety reason.
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index a61c9d6..f909a3b 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -380,13 +380,17 @@ if that doesn't produce a completion match."
 (defun icomplete-fido-backward-updir ()
   "Delete char before or go up directory, like `ido-mode'."
   (interactive)
-  (if (and (eq (char-before) ?/)
-           (eq (icomplete--category) 'file))
-      (save-excursion
-        (goto-char (1- (point)))
-        (when (search-backward "/" (point-min) t)
-          (delete-region (1+ (point)) (point-max))))
-    (call-interactively 'backward-delete-char)))
+  (cond ((and (eq (char-before) ?/)
+              (eq (icomplete--category) 'file))
+         (when (string-equal (icomplete--field-string) "~/")
+           (delete-region (icomplete--field-beg) (icomplete--field-end))
+           (insert (expand-file-name "~/"))
+           (goto-char (line-end-position)))
+         (save-excursion
+           (goto-char (1- (point)))
+           (when (search-backward "/" (point-min) t)
+             (delete-region (1+ (point)) (point-max)))))
+        (t (call-interactively 'backward-delete-char))))
 
 (defvar icomplete-fido-mode-map
   (let ((map (make-sparse-keymap)))
diff --git a/lisp/image-dired.el b/lisp/image-dired.el
index a2c37f0..852ef0f 100644
--- a/lisp/image-dired.el
+++ b/lisp/image-dired.el
@@ -1527,67 +1527,68 @@ You probably want to use this together with
 (defvar image-dired-thumbnail-mode-line-up-map
   (let ((map (make-sparse-keymap)))
     ;; map it to "g" so that the user can press it more quickly
-    (define-key map "g" 'image-dired-line-up-dynamic)
+    (define-key map "g" #'image-dired-line-up-dynamic)
     ;; "f" for "fixed" number of thumbs per row
-    (define-key map "f" 'image-dired-line-up)
+    (define-key map "f" #'image-dired-line-up)
     ;; "i" for "interactive"
-    (define-key map "i" 'image-dired-line-up-interactive)
+    (define-key map "i" #'image-dired-line-up-interactive)
     map)
   "Keymap for line-up commands in `image-dired-thumbnail-mode'.")
 
 (defvar image-dired-thumbnail-mode-tag-map
   (let ((map (make-sparse-keymap)))
     ;; map it to "t" so that the user can press it more quickly
-    (define-key map "t" 'image-dired-tag-thumbnail)
+    (define-key map "t" #'image-dired-tag-thumbnail)
     ;; "r" for "remove"
-    (define-key map "r" 'image-dired-tag-thumbnail-remove)
+    (define-key map "r" #'image-dired-tag-thumbnail-remove)
     map)
   "Keymap for tag commands in `image-dired-thumbnail-mode'.")
 
 (defvar image-dired-thumbnail-mode-map
   (let ((map (make-sparse-keymap)))
-    (define-key map [right] 'image-dired-forward-image)
-    (define-key map [left] 'image-dired-backward-image)
-    (define-key map [up] 'image-dired-previous-line)
-    (define-key map [down] 'image-dired-next-line)
-    (define-key map "\C-f" 'image-dired-forward-image)
-    (define-key map "\C-b" 'image-dired-backward-image)
-    (define-key map "\C-p" 'image-dired-previous-line)
-    (define-key map "\C-n" 'image-dired-next-line)
+    (define-key map [right] #'image-dired-forward-image)
+    (define-key map [left] #'image-dired-backward-image)
+    (define-key map [up] #'image-dired-previous-line)
+    (define-key map [down] #'image-dired-next-line)
+    (define-key map "\C-f" #'image-dired-forward-image)
+    (define-key map "\C-b" #'image-dired-backward-image)
+    (define-key map "\C-p" #'image-dired-previous-line)
+    (define-key map "\C-n" #'image-dired-next-line)
 
     (define-key map "<" #'image-dired-beginning-of-buffer)
     (define-key map ">" #'image-dired-end-of-buffer)
     (define-key map (kbd "M-<") #'image-dired-beginning-of-buffer)
     (define-key map (kbd "M->") #'image-dired-end-of-buffer)
 
-    (define-key map "d" 'image-dired-flag-thumb-original-file)
-    (define-key map [delete] 'image-dired-flag-thumb-original-file)
-    (define-key map "m" 'image-dired-mark-thumb-original-file)
-    (define-key map "u" 'image-dired-unmark-thumb-original-file)
-    (define-key map "U" 'image-dired-unmark-all-marks)
-    (define-key map "." 'image-dired-track-original-file)
-    (define-key map [tab] 'image-dired-jump-original-dired-buffer)
+    (define-key map "d" #'image-dired-flag-thumb-original-file)
+    (define-key map [delete] #'image-dired-flag-thumb-original-file)
+    (define-key map "m" #'image-dired-mark-thumb-original-file)
+    (define-key map "u" #'image-dired-unmark-thumb-original-file)
+    (define-key map "U" #'image-dired-unmark-all-marks)
+    (define-key map "." #'image-dired-track-original-file)
+    (define-key map [tab] #'image-dired-jump-original-dired-buffer)
 
     ;; add line-up map
     (define-key map "g" image-dired-thumbnail-mode-line-up-map)
     ;; add tag map
     (define-key map "t" image-dired-thumbnail-mode-tag-map)
 
-    (define-key map "\C-m" 'image-dired-display-thumbnail-original-image)
-    (define-key map [C-return] 'image-dired-thumbnail-display-external)
+    (define-key map "\C-m" #'image-dired-display-thumbnail-original-image)
+    (define-key map [C-return] #'image-dired-thumbnail-display-external)
 
-    (define-key map "L" 'image-dired-rotate-original-left)
-    (define-key map "R" 'image-dired-rotate-original-right)
+    (define-key map "L" #'image-dired-rotate-original-left)
+    (define-key map "R" #'image-dired-rotate-original-right)
 
-    (define-key map "D" 'image-dired-thumbnail-set-image-description)
-    (define-key map "\C-d" 'image-dired-delete-char)
-    (define-key map " " 'image-dired-display-next-thumbnail-original)
-    (define-key map (kbd "DEL") 
'image-dired-display-previous-thumbnail-original)
-    (define-key map "c" 'image-dired-comment-thumbnail)
+    (define-key map "D" #'image-dired-thumbnail-set-image-description)
+    (define-key map "S" #'image-dired-slideshow-start)
+    (define-key map "\C-d" #'image-dired-delete-char)
+    (define-key map " " #'image-dired-display-next-thumbnail-original)
+    (define-key map (kbd "DEL") 
#'image-dired-display-previous-thumbnail-original)
+    (define-key map "c" #'image-dired-comment-thumbnail)
 
     ;; Mouse
-    (define-key map [mouse-2] 'image-dired-mouse-display-image)
-    (define-key map [mouse-1] 'image-dired-mouse-select-thumbnail)
+    (define-key map [mouse-2] #'image-dired-mouse-display-image)
+    (define-key map [mouse-1] #'image-dired-mouse-select-thumbnail)
     (define-key map [mouse-3] #'image-dired-mouse-select-thumbnail)
     (define-key map [down-mouse-1] #'image-dired-mouse-select-thumbnail)
     (define-key map [down-mouse-2] #'image-dired-mouse-select-thumbnail)
@@ -1602,8 +1603,8 @@ You probably want to use this together with
     ;; C-down-mouse-1 to `image-dired-mouse-toggle-mark', I get a message
     ;; about C-mouse-1 not being defined afterwards. Annoying, but I
     ;; probably do not completely understand mouse events.
-    (define-key map [C-down-mouse-1] 'undefined)
-    (define-key map [C-mouse-1] 'image-dired-mouse-toggle-mark)
+    (define-key map [C-down-mouse-1] #'undefined)
+    (define-key map [C-mouse-1] #'image-dired-mouse-toggle-mark)
     map)
   "Keymap for `image-dired-thumbnail-mode'.")
 
@@ -1612,37 +1613,36 @@ You probably want to use this together with
   '("Image-Dired"
     ["Display image" image-dired-display-thumbnail-original-image]
     ["Display in external viewer" image-dired-thumbnail-display-external]
+    ["Jump to Dired buffer" image-dired-jump-original-dired-buffer]
     "---"
-    ["Mark original" image-dired-mark-thumb-original-file]
-    ["Unmark original" image-dired-unmark-thumb-original-file]
-    ["Flag original for deletion" image-dired-flag-thumb-original-file]
-    "---"
-    ["Track original" image-dired-track-original-file]
-    ["Jump to dired buffer" image-dired-jump-original-dired-buffer]
-    ["Toggle movement tracking on/off" image-dired-toggle-movement-tracking
-     :style toggle
-     :selected image-dired-track-movement]
+    ["Mark image" image-dired-mark-thumb-original-file]
+    ["Unmark image" image-dired-unmark-thumb-original-file]
+    ["Unmark all images" image-dired-unmark-all-marks]
+    ["Flag for deletion" image-dired-flag-thumb-original-file]
+    ["Delete marked images" image-dired-delete-marked]
     "---"
     ["Rotate original right" image-dired-rotate-original-right]
     ["Rotate original left" image-dired-rotate-original-left]
     "---"
-    ["Line up thumbnails" image-dired-line-up]
-    ["Dynamic line up" image-dired-line-up-dynamic]
-    ["Refresh thumb" image-dired-refresh-thumb]
-    "---"
     ["Comment thumbnail" image-dired-comment-thumbnail]
     ["Tag current or marked thumbnails" image-dired-tag-thumbnail]
-    "---"
     ["Remove tag from current or marked thumbnails"
      image-dired-tag-thumbnail-remove]
-    ["Unmark all marks" image-dired-unmark-all-marks]
-    ["Delete marked images" image-dired-delete-marked]
-    ["Delete thumbnail from buffer" image-dired-delete-char]
+    ["Start slideshow" image-dired-slideshow-start]
     "---"
+    ("View Options"
+     ["Toggle movement tracking" image-dired-toggle-movement-tracking
+      :style toggle
+      :selected image-dired-track-movement]
+     "---"
+     ["Line up thumbnails" image-dired-line-up]
+     ["Dynamic line up" image-dired-line-up-dynamic]
+     ["Refresh thumb" image-dired-refresh-thumb])
     ["Quit" quit-window]))
 
 (defvar image-dired-display-image-mode-map
   (let ((map (make-sparse-keymap)))
+    (define-key map "S" #'image-dired-slideshow-start)
     ;; Disable keybindings from `image-mode-map' that doesn't make sense here.
     (define-key map "o" nil) ; image-save
     (define-key map "n" nil) ; image-next-file
@@ -1660,6 +1660,7 @@ You probably want to use this together with
   special-mode "image-dired-thumbnail"
   "Browse and manipulate thumbnail images using Dired.
 Use `image-dired-minor-mode' to get a nice setup."
+  :interactive nil
   (buffer-disable-undo)
   (add-hook 'file-name-at-point-functions 'image-dired-file-name-at-point nil 
t)
   (setq-local window-resize-pixelwise t)
@@ -1682,23 +1683,23 @@ Resized or in full-size."
     ;; (set-keymap-parent map dired-mode-map)
     ;; Hijack previous and next line movement. Let C-p and C-b be
     ;; though...
-    (define-key map "p" 'image-dired-dired-previous-line)
-    (define-key map "n" 'image-dired-dired-next-line)
-    (define-key map [up] 'image-dired-dired-previous-line)
-    (define-key map [down] 'image-dired-dired-next-line)
-
-    (define-key map (kbd "C-S-n") 'image-dired-next-line-and-display)
-    (define-key map (kbd "C-S-p") 'image-dired-previous-line-and-display)
-    (define-key map (kbd "C-S-m") 'image-dired-mark-and-display-next)
-
-    (define-key map "\C-td" 'image-dired-display-thumbs)
-    (define-key map [tab] 'image-dired-jump-thumbnail-buffer)
-    (define-key map "\C-ti" 'image-dired-dired-display-image)
-    (define-key map "\C-tx" 'image-dired-dired-display-external)
-    (define-key map "\C-ta" 'image-dired-display-thumbs-append)
-    (define-key map "\C-t." 'image-dired-display-thumb)
-    (define-key map "\C-tc" 'image-dired-dired-comment-files)
-    (define-key map "\C-tf" 'image-dired-mark-tagged-files)
+    (define-key map "p" #'image-dired-dired-previous-line)
+    (define-key map "n" #'image-dired-dired-next-line)
+    (define-key map [up] #'image-dired-dired-previous-line)
+    (define-key map [down] #'image-dired-dired-next-line)
+
+    (define-key map (kbd "C-S-n") #'image-dired-next-line-and-display)
+    (define-key map (kbd "C-S-p") #'image-dired-previous-line-and-display)
+    (define-key map (kbd "C-S-m") #'image-dired-mark-and-display-next)
+
+    (define-key map "\C-td" #'image-dired-display-thumbs)
+    (define-key map [tab] #'image-dired-jump-thumbnail-buffer)
+    (define-key map "\C-ti" #'image-dired-dired-display-image)
+    (define-key map "\C-tx" #'image-dired-dired-display-external)
+    (define-key map "\C-ta" #'image-dired-display-thumbs-append)
+    (define-key map "\C-t." #'image-dired-display-thumb)
+    (define-key map "\C-tc" #'image-dired-dired-comment-files)
+    (define-key map "\C-tf" #'image-dired-mark-tagged-files)
     map)
   "Keymap for `image-dired-minor-mode'.")
 
@@ -1758,44 +1759,60 @@ With prefix argument ARG, create thumbnails even if 
they already exist
         (image-dired-create-thumb curr-file thumb-name)))))
 
 
-;;; Slideshow.
+;;; Slideshow
 
-(defvar image-dired-slideshow-timer nil
-  "Slideshow timer.")
+(defcustom image-dired-slideshow-delay 5.0
+  "Seconds to wait before showing the next image in a slideshow.
+This is used by `image-dired-slideshow-start'."
+  :type 'float
+  :version "29.1")
 
-(defvar image-dired-slideshow-count 0
-  "Keeping track on number of images in slideshow.")
+(define-obsolete-variable-alias 'image-dired-slideshow-timer
+  'image-dired--slideshow-timer "29.1")
+(defvar image-dired--slideshow-timer nil
+  "Slideshow timer.")
 
-(defvar image-dired-slideshow-times 0
-  "Number of pictures to display in slideshow.")
+(defvar image-dired--slideshow-initial nil)
 
 (defun image-dired-slideshow-step ()
-  "Step to next file, if `image-dired-slideshow-times' has not been reached."
-  (if (< image-dired-slideshow-count image-dired-slideshow-times)
-      (progn
-        (message "%s" (1+ image-dired-slideshow-count))
-        (setq image-dired-slideshow-count (1+ image-dired-slideshow-count))
-        (image-dired-next-line-and-display))
+  "Step to next image in a slideshow."
+  (if-let ((buf (get-buffer image-dired-thumbnail-buffer)))
+      (with-current-buffer buf
+        (image-dired-display-next-thumbnail-original))
     (image-dired-slideshow-stop)))
 
-(defun image-dired-slideshow-start ()
-  "Start slideshow.
-Ask user for number of images to show and the delay in between."
-  (interactive)
-  (setq image-dired-slideshow-count 0)
-  (setq image-dired-slideshow-times (string-to-number (read-string "How many: 
")))
-  (let ((repeat (string-to-number
-                 (read-string
-                  "Delay, in seconds. Decimals are accepted : " "1"))))
-    (setq image-dired-slideshow-timer
+(defun image-dired-slideshow-start (&optional arg)
+  "Start a slideshow.
+Wait `image-dired-slideshow-delay' seconds before showing the
+next image.
+
+With prefix argument ARG, wait that many seconds before going to
+the next image.
+
+With a negative prefix argument, prompt user for the delay."
+  (interactive "P" image-dired-thumbnail-mode image-dired-display-image-mode)
+  (let ((delay (if (> arg 0)
+                   arg
+                 (string-to-number
+                  (read-string
+                   (let ((delay (number-to-string 
image-dired-slideshow-delay)))
+                     (format-prompt "Delay, in seconds. Decimals are accepted" 
delay) delay))))))
+    (setq image-dired--slideshow-timer
           (run-with-timer
-           0 repeat
-           'image-dired-slideshow-step))))
+           0 delay
+           'image-dired-slideshow-step))
+    (add-hook 'post-command-hook 'image-dired-slideshow-stop)
+    (setq image-dired--slideshow-initial t)
+    (message "Running slideshow; use any command to stop")))
 
 (defun image-dired-slideshow-stop ()
   "Cancel slideshow."
-  (interactive)
-  (cancel-timer image-dired-slideshow-timer))
+  ;; Make sure we don't immediately stop after
+  ;; `image-dired-slideshow-start'.
+  (unless image-dired--slideshow-initial
+    (remove-hook 'post-command-hook 'image-dired-slideshow-stop)
+    (cancel-timer image-dired--slideshow-timer))
+  (setq image-dired--slideshow-initial nil))
 
 
 ;;; Thumbnail mode (cont. 3)
@@ -2978,6 +2995,14 @@ Dired."
                   (cons (list tag file) (cdr image-dired-tag-file-list))))
       (setq image-dired-tag-file-list (list (list tag file))))))
 
+(defvar image-dired-slideshow-count 0
+  "Keeping track on number of images in slideshow.")
+(make-obsolete-variable 'image-dired-slideshow-count "no longer used." "29.1")
+
+(defvar image-dired-slideshow-times 0
+  "Number of pictures to display in slideshow.")
+(make-obsolete-variable 'image-dired-slideshow-times "no longer used." "29.1")
+
 (define-obsolete-function-alias 'image-dired-create-display-image-buffer
   #'ignore "29.1")
 (define-obsolete-function-alias 'image-dired-create-gallery-lists
diff --git a/lisp/image.el b/lisp/image.el
index a149caa..edbf6c5 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -836,15 +836,18 @@ in which case you might want to use 
`image-default-frame-delay'."
 
 (make-obsolete 'image-animated-p 'image-multi-frame-p "24.4")
 
-;; "Destructively"?
-(defun image-animate (image &optional index limit)
+(defun image-animate (image &optional index limit position)
   "Start animating IMAGE.
 Animation occurs by destructively altering the IMAGE spec list.
 
 With optional INDEX, begin animating from that animation frame.
 LIMIT specifies how long to animate the image.  If omitted or
 nil, play the animation until the end.  If t, loop forever.  If a
-number, play until that number of seconds has elapsed."
+number, play until that number of seconds has elapsed.
+
+If POSITION (which should be buffer position where the image is
+displayed), stop the animation if the image is no longer
+displayed."
   (let ((animation (image-multi-frame-p image))
        timer)
     (when animation
@@ -852,6 +855,9 @@ number, play until that number of seconds has elapsed."
          (cancel-timer timer))
       (plist-put (cdr image) :animate-buffer (current-buffer))
       (plist-put (cdr image) :animate-tardiness 0)
+      (when position
+        (plist-put (cdr image) :animate-position
+                   (set-marker (make-marker) position (current-buffer))))
       ;; Stash the data about the animation here so that we don't
       ;; trigger image recomputation unnecessarily later.
       (plist-put (cdr image) :animate-multi-frame-data animation)
@@ -925,40 +931,54 @@ for the animation speed.  A negative value means to 
animate in reverse."
   (plist-put (cdr image) :animate-tardiness
              (+ (* (plist-get (cdr image) :animate-tardiness) 0.9)
                 (float-time (time-since target-time))))
-  (when (and (buffer-live-p (plist-get (cdr image) :animate-buffer))
-             ;; Cumulatively delayed two seconds more than expected.
-             (or (< (plist-get (cdr image) :animate-tardiness) 2)
-                (progn
-                  (message "Stopping animation; animation possibly too big")
-                  nil)))
-    (image-show-frame image n t)
-    (let* ((speed (image-animate-get-speed image))
-          (time (current-time))
-          (time-to-load-image (time-since time))
-          (stated-delay-time
-            (/ (or (cdr (plist-get (cdr image) :animate-multi-frame-data))
-                  image-default-frame-delay)
-              (float (abs speed))))
-          ;; Subtract off the time we took to load the image from the
-          ;; stated delay time.
-          (delay (max (float-time (time-subtract stated-delay-time
-                                                 time-to-load-image))
-                      image-minimum-frame-delay))
-          done)
-      (setq n (if (< speed 0)
-                 (1- n)
-               (1+ n)))
-      (if limit
-         (cond ((>= n count) (setq n 0))
-               ((< n 0) (setq n (1- count))))
-       (and (or (>= n count) (< n 0)) (setq done t)))
-      (setq time-elapsed (+ delay time-elapsed))
-      (if (numberp limit)
-         (setq done (>= time-elapsed limit)))
-      (unless done
-       (run-with-timer delay nil #'image-animate-timeout
-                       image n count time-elapsed limit
-                        (+ (float-time) delay))))))
+  (let ((buffer (plist-get (cdr image) :animate-buffer))
+        (position (plist-get (cdr image) :animate-position)))
+    (when (and (buffer-live-p buffer)
+               ;; If we have a :animate-position setting, the caller
+               ;; has requested that the animation be stopped if the
+               ;; image is no longer displayed in the buffer.
+               (or (null position)
+                   (with-current-buffer buffer
+                     (let ((disp (get-text-property position 'display)))
+                       (and (consp disp)
+                            (eq (car disp) 'image)
+                            ;; We can't check `eq'-ness of the image
+                            ;; itself, since that may change.
+                            (eq position
+                                (plist-get (cdr disp) :animate-position))))))
+               ;; Cumulatively delayed two seconds more than expected.
+               (or (< (plist-get (cdr image) :animate-tardiness) 2)
+                  (progn
+                    (message "Stopping animation; animation possibly too big")
+                    nil)))
+      (image-show-frame image n t)
+      (let* ((speed (image-animate-get-speed image))
+            (time (current-time))
+            (time-to-load-image (time-since time))
+            (stated-delay-time
+              (/ (or (cdr (plist-get (cdr image) :animate-multi-frame-data))
+                    image-default-frame-delay)
+                (float (abs speed))))
+            ;; Subtract off the time we took to load the image from the
+            ;; stated delay time.
+            (delay (max (float-time (time-subtract stated-delay-time
+                                                   time-to-load-image))
+                        image-minimum-frame-delay))
+            done)
+        (setq n (if (< speed 0)
+                   (1- n)
+                 (1+ n)))
+        (if limit
+           (cond ((>= n count) (setq n 0))
+                 ((< n 0) (setq n (1- count))))
+         (and (or (>= n count) (< n 0)) (setq done t)))
+        (setq time-elapsed (+ delay time-elapsed))
+        (if (numberp limit)
+           (setq done (>= time-elapsed limit)))
+        (unless done
+         (run-with-timer delay nil #'image-animate-timeout
+                         image n count time-elapsed limit
+                          (+ (float-time) delay)))))))
 
 
 (defvar imagemagick-types-inhibit)
diff --git a/lisp/info.el b/lisp/info.el
index 41889d6..cd4c867 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -1792,7 +1792,46 @@ of NODENAME; if none is found it then tries a 
case-insensitive match
       (if trim (setq nodename (substring nodename 0 trim))))
     (if transient-mark-mode (deactivate-mark))
     (Info-find-node (if (equal filename "") nil filename)
-                   (if (equal nodename "") "Top" nodename) nil strict-case)))
+                    (if (equal nodename "") "Top" nodename) nil strict-case)))
+
+(defun Info-goto-node-web (node)
+  "Use `browse-url' to go to the gnu.org web server's version of NODE.
+By default, go to the current Info node."
+  (interactive (list (Info-read-node-name
+                      "Go to node (default current page): " Info-current-node))
+               Info-mode)
+  (browse-url-button-open-url
+   (Info-url-for-node (format "(%s)%s" (file-name-sans-extension
+                                        (file-name-nondirectory
+                                         Info-current-file))
+                              node))))
+
+(defun Info-url-for-node (node)
+  "Return a URL for NODE, a node in the GNU Emacs or Elisp manual.
+NODE should be a string on the form \"(manual)Node\".  Only emacs
+and elisp manuals are supported."
+  (unless (string-match "\\`(\\(.+\\))\\(.+\\)\\'" node)
+    (error "Invalid node name %s" node))
+  (let ((manual (match-string 1 node))
+        (node (match-string 2 node)))
+    (unless (member manual '("emacs" "elisp"))
+      (error "Only emacs/elisp manuals are supported"))
+    ;; Encode a bunch of characters the way that makeinfo does.
+    (setq node
+          (mapconcat (lambda (ch)
+                       (if (or (< ch 32)        ; ^@^A-^Z^[^\^]^^^-
+                               (<= 33 ch 47)    ; !"#$%&'()*+,-./
+                               (<= 58 ch 64)    ; :;<=>?@
+                               (<= 91 ch 96)    ; [\]_`
+                               (<= 123 ch 127)) ; {|}~ DEL
+                           (format "_00%x" ch)
+                         (char-to-string ch)))
+                     node
+                     ""))
+    (concat "https://www.gnu.org/software/emacs/manual/html_node/";
+            manual "/"
+            (url-hexify-string (string-replace " " "-" node))
+            ".html")))
 
 (defvar Info-read-node-completion-table)
 
@@ -1877,7 +1916,7 @@ See `completing-read' for a description of arguments and 
usage."
        code Info-read-node-completion-table string predicate))))
 
 ;; Arrange to highlight the proper letters in the completion list buffer.
-(defun Info-read-node-name (prompt)
+(defun Info-read-node-name (prompt &optional default)
   "Read an Info node name with completion, prompting with PROMPT.
 A node name can have the form \"NODENAME\", referring to a node
 in the current Info file, or \"(FILENAME)NODENAME\", referring to
@@ -1885,7 +1924,8 @@ a node in FILENAME.  \"(FILENAME)\" is a short format to 
go to
 the Top node in FILENAME."
   (let* ((completion-ignore-case t)
         (Info-read-node-completion-table (Info-build-node-completions))
-        (nodename (completing-read prompt #'Info-read-node-name-1 nil t)))
+         (nodename (completing-read prompt #'Info-read-node-name-1 nil t nil
+                                    'Info-minibuf-history default)))
     (if (equal nodename "")
        (Info-read-node-name prompt)
       nodename)))
@@ -4046,6 +4086,7 @@ If FORK is non-nil, it is passed to `Info-goto-node'."
     (define-key map "e" 'end-of-buffer)
     (define-key map "f" 'Info-follow-reference)
     (define-key map "g" 'Info-goto-node)
+    (define-key map "G" 'Info-goto-node-web)
     (define-key map "h" 'Info-help)
     ;; This is for compatibility with standalone info (>~ version 5.2).
     ;; Though for some time, standalone info had H and h reversed.
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index 4b9505a..2eae134 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -10512,6 +10512,40 @@ Emerge two RCS revisions of a file, with another 
revision as ancestor.
 
 ;;;***
 
+;;;### (autoloads nil "emoji" "international/emoji.el" (0 0 0 0))
+;;; Generated autoloads from international/emoji.el
+
+(autoload 'emoji-insert "emoji" "\
+Choose and insert an emoji glyph.
+If TEXT (interactively, the prefix), use a textual search instead
+of a visual interface.
+
+\(fn &optional TEXT)" t nil)
+
+(autoload 'emoji-recent "emoji" "\
+Choose and insert a recently used emoji glyph." t nil)
+
+(autoload 'emoji-search "emoji" "\
+Choose and insert an emoji glyph by searching for an emoji name." t nil)
+
+(autoload 'emoji-list "emoji" "\
+List emojis and insert the one that's selected.
+The character will be inserted into the buffer that was selected
+when the command was issued." t nil)
+
+(autoload 'emoji-describe "emoji" "\
+Say what the name of the composed grapheme cluster GLYPH is.
+If it's not known, this function returns nil.
+
+Interactively, it will message what the name of the emoji (or
+character) under point is.
+
+\(fn GLYPH &optional INTERACTIVE)" t nil)
+
+(register-definition-prefixes "emoji" '("emoji-"))
+
+;;;***
+
 ;;;### (autoloads nil "enriched" "textmodes/enriched.el" (0 0 0 0))
 ;;; Generated autoloads from textmodes/enriched.el
 
@@ -11997,14 +12031,14 @@ Fetch URL and render the page.
 If the input doesn't look like an URL or a domain name, the
 word(s) will be searched for via `eww-search-prefix'.
 
-If called with a prefix ARG, use a new buffer instead of reusing
-the default EWW buffer.
+If NEW-BUFFER is non-nil (interactively, the prefix arg), use a
+new buffer instead of reusing the default EWW buffer.
 
 If BUFFER, the data to be rendered is in that buffer.  In that
 case, this function doesn't actually fetch URL.  BUFFER will be
 killed after rendering.
 
-\(fn URL &optional ARG BUFFER)" t nil)
+\(fn URL &optional NEW-BUFFER BUFFER)" t nil)
  (defalias 'browse-web 'eww)
 
 (autoload 'eww-open-file "eww" "\
@@ -18302,7 +18336,11 @@ specifying the X and Y positions and WIDTH and HEIGHT 
of image area
 to insert.  A float value 0.0 - 1.0 means relative to the width or
 height of the image; integer values are taken as pixel values.
 
-\(fn IMAGE &optional STRING AREA SLICE)" nil nil)
+Normally `isearch' is able to search for STRING in the buffer
+even if it's hidden behind a displayed image.  If INHIBIT-ISEARCH
+is non-nil, this is inhibited.
+
+\(fn IMAGE &optional STRING AREA SLICE INHIBIT-ISEARCH)" nil nil)
 
 (autoload 'insert-sliced-image "image" "\
 Insert IMAGE into current buffer at point.
@@ -18487,7 +18525,7 @@ Jump to thumbnail buffer." t nil)
 (autoload 'image-dired-minor-mode "image-dired" "\
 Setup easy-to-use keybindings for the commands to be used in Dired mode.
 Note that n, p and <down> and <up> will be hijacked and bound to
-`image-dired-dired-x-line'.
+`image-dired-dired-next-line' and `image-dired-dired-previous-line'.
 
 This is a minor mode.  If called interactively, toggle the
 `Image-Dired minor mode' mode.  If the prefix argument is positive,
@@ -20982,6 +21020,12 @@ current header, calls `mail-complete-function' and 
passes prefix ARG if any.
 ;;;### (autoloads nil "mailcap" "net/mailcap.el" (0 0 0 0))
 ;;; Generated autoloads from net/mailcap.el
 
+(autoload 'mailcap-mime-type-to-extension "mailcap" "\
+Return a file name extension based on a mime type.
+For instance, `image/png' will result in `png'.
+
+\(fn MIME-TYPE)" nil nil)
+
 (register-definition-prefixes "mailcap" '("mailcap-"))
 
 ;;;***
@@ -22274,6 +22318,8 @@ specifies how the attachment is intended to be 
displayed.  It can
 be either \"inline\" (displayed automatically within the message
 body) or \"attachment\" (separate from the body).
 
+Also see the `mml-attach-file-at-the-end' variable.
+
 If given a prefix interactively, no prompting will be done for
 the TYPE, DESCRIPTION or DISPOSITION values.  Instead defaults
 will be computed and used.
@@ -25930,10 +25976,26 @@ Prettify the current buffer with printed 
representation of a Lisp object." t nil
 Output the pretty-printed representation of OBJECT, any Lisp object.
 Quoting characters are printed as needed to make output that `read'
 can handle, whenever this is possible.
+
+This function does not apply special formatting rules for Emacs
+Lisp code.  See `pp-emacs-lisp-code' instead.
+
+By default, this function won't limit the line length of lists
+and vectors.  Bind `pp-use-max-width' to a non-nil value to do so.
+
 Output stream is STREAM, or value of `standard-output' (which see).
 
 \(fn OBJECT &optional STREAM)" nil nil)
 
+(autoload 'pp-display-expression "pp" "\
+Prettify and display EXPRESSION in an appropriate way, depending on length.
+If LISP, format with `pp-emacs-lisp-code'; use `pp' otherwise.
+
+If a temporary buffer is needed for representation, it will be named
+after OUT-BUFFER-NAME.
+
+\(fn EXPRESSION OUT-BUFFER-NAME &optional LISP)" nil nil)
+
 (autoload 'pp-eval-expression "pp" "\
 Evaluate EXPRESSION and pretty-print its value.
 Also add the value to the front of the list in the variable `values'.
@@ -25959,6 +26021,12 @@ Ignores leading comment characters.
 
 \(fn ARG)" t nil)
 
+(autoload 'pp-emacs-lisp-code "pp" "\
+Insert SEXP into the current buffer, formatted as Emacs Lisp code.
+Use the `pp-max-width' variable to control the desired line length.
+
+\(fn SEXP)" nil nil)
+
 (register-definition-prefixes "pp" '("pp-"))
 
 ;;;***
@@ -32419,14 +32487,14 @@ If OMIT-NULLS, empty lines will be removed from the 
results.
 \(fn STRING &optional OMIT-NULLS)" nil nil)
 
 (autoload 'ensure-empty-lines "subr-x" "\
-Ensure that there's LINES number of empty lines before point.
-If LINES is nil or missing, a this ensures that there's a single
-empty line before point.
+Ensure that there are LINES number of empty lines before point.
+If LINES is nil or omitted, ensure that there is a single empty
+line before point.
 
-Interactively, this command uses the numerical prefix for LINES.
+If called interactively, LINES is given by the prefix argument.
 
-If there's already more empty lines before point than LINES, the
-number of blank lines will be reduced.
+If there are more than LINES empty lines before point, the number
+of empty lines is reduced to LINES.
 
 If point is not at the beginning of a line, a newline character
 is inserted before adjusting the number of empty lines.
@@ -36539,6 +36607,10 @@ For old-style locking-based version control systems, 
like RCS:
   If every file is locked by you and unchanged, unlock them.
   If every file is locked by someone else, offer to steal the lock.
 
+When using this command to register a new file (or files), it
+will automatically deduce which VC repository to register it
+with, using the most specific one.
+
 \(fn VERBOSE)" t nil)
 
 (autoload 'vc-register "vc" "\
@@ -39345,7 +39417,7 @@ If LIMIT is non-nil, then do not consider characters 
beyond LIMIT.
 
 (autoload 'xref-find-backend "xref" nil nil nil)
 
-(defalias 'xref-pop-marker-stack #'xref-go-back)
+(define-obsolete-function-alias 'xref-pop-marker-stack #'xref-go-back "29.1")
 
 (autoload 'xref-go-back "xref" "\
 Go back to the previous position in xref history.
@@ -39525,6 +39597,33 @@ Interactively, URL defaults to the string looking like 
a url around point.
 
 ;;;***
 
+;;;### (autoloads nil "yank-media" "yank-media.el" (0 0 0 0))
+;;; Generated autoloads from yank-media.el
+
+(autoload 'yank-media "yank-media" "\
+Yank media (images, HTML and the like) from the clipboard.
+This command depends on the current major mode having support for
+accepting the media type.  The mode has to register itself using
+the `yank-media-handler' mechanism.
+
+Also see `yank-media-types' for a command that lets you explore
+all the different selection types." t nil)
+
+(autoload 'yank-media-handler "yank-media" "\
+Register HANDLER for dealing with `yank-media' actions for TYPES.
+TYPES should be a MIME media type symbol, a regexp, or a list
+that can contain both symbols and regexps.
+
+HANDLER is a function that will be called with two arguments: The
+MIME type (a symbol on the form `image/png') and the selection
+data (a string).
+
+\(fn TYPES HANDLER)" nil nil)
+
+(register-definition-prefixes "yank-media" '("yank-media-"))
+
+;;;***
+
 ;;;### (autoloads nil "yenc" "mail/yenc.el" (0 0 0 0))
 ;;; Generated autoloads from mail/yenc.el
 
@@ -39558,57 +39657,59 @@ Zone out, completely." t nil)
 ;;;***
 
 ;;;### (autoloads nil nil ("abbrev.el" "bindings.el" "buff-menu.el"
-;;;;;;  "button.el" "calc/calc-aent.el" "calc/calc-embed.el" 
"calc/calc-misc.el"
-;;;;;;  "calc/calc-yank.el" "calendar/cal-loaddefs.el" 
"calendar/diary-loaddefs.el"
-;;;;;;  "calendar/hol-loaddefs.el" "case-table.el" "cedet/ede/base.el"
-;;;;;;  "cedet/ede/config.el" "cedet/ede/cpp-root.el" "cedet/ede/custom.el"
-;;;;;;  "cedet/ede/dired.el" "cedet/ede/emacs.el" "cedet/ede/files.el"
-;;;;;;  "cedet/ede/generic.el" "cedet/ede/linux.el" "cedet/ede/locate.el"
-;;;;;;  "cedet/ede/make.el" "cedet/ede/shell.el" "cedet/ede/speedbar.el"
-;;;;;;  "cedet/ede/system.el" "cedet/ede/util.el" "cedet/semantic/analyze.el"
-;;;;;;  "cedet/semantic/analyze/complete.el" "cedet/semantic/analyze/refs.el"
-;;;;;;  "cedet/semantic/bovine.el" "cedet/semantic/bovine/c-by.el"
-;;;;;;  "cedet/semantic/bovine/c.el" "cedet/semantic/bovine/el.el"
-;;;;;;  "cedet/semantic/bovine/gcc.el" "cedet/semantic/bovine/make-by.el"
-;;;;;;  "cedet/semantic/bovine/make.el" "cedet/semantic/bovine/scm-by.el"
-;;;;;;  "cedet/semantic/bovine/scm.el" "cedet/semantic/complete.el"
-;;;;;;  "cedet/semantic/ctxt.el" "cedet/semantic/db-file.el" 
"cedet/semantic/db-find.el"
-;;;;;;  "cedet/semantic/db-global.el" "cedet/semantic/db-mode.el"
-;;;;;;  "cedet/semantic/db-typecache.el" "cedet/semantic/db.el" 
"cedet/semantic/debug.el"
-;;;;;;  "cedet/semantic/decorate/include.el" "cedet/semantic/decorate/mode.el"
-;;;;;;  "cedet/semantic/dep.el" "cedet/semantic/doc.el" 
"cedet/semantic/edit.el"
-;;;;;;  "cedet/semantic/find.el" "cedet/semantic/format.el" 
"cedet/semantic/grammar-wy.el"
+;;;;;;  "button.el" "calc/calc-aent.el" "calc/calc-embed.el" 
"calc/calc-loaddefs.el"
+;;;;;;  "calc/calc-misc.el" "calc/calc-yank.el" "calendar/cal-loaddefs.el"
+;;;;;;  "calendar/diary-loaddefs.el" "calendar/hol-loaddefs.el" "case-table.el"
+;;;;;;  "cedet/ede/cpp-root.el" "cedet/ede/custom.el" "cedet/ede/dired.el"
+;;;;;;  "cedet/ede/emacs.el" "cedet/ede/files.el" "cedet/ede/generic.el"
+;;;;;;  "cedet/ede/linux.el" "cedet/ede/loaddefs.el" "cedet/ede/locate.el"
+;;;;;;  "cedet/ede/make.el" "cedet/ede/speedbar.el" "cedet/ede/system.el"
+;;;;;;  "cedet/ede/util.el" "cedet/semantic/analyze.el" 
"cedet/semantic/analyze/complete.el"
+;;;;;;  "cedet/semantic/analyze/refs.el" "cedet/semantic/bovine.el"
+;;;;;;  "cedet/semantic/bovine/c-by.el" "cedet/semantic/bovine/c.el"
+;;;;;;  "cedet/semantic/bovine/el.el" "cedet/semantic/bovine/gcc.el"
+;;;;;;  "cedet/semantic/bovine/make-by.el" "cedet/semantic/bovine/make.el"
+;;;;;;  "cedet/semantic/bovine/scm-by.el" "cedet/semantic/bovine/scm.el"
+;;;;;;  "cedet/semantic/complete.el" "cedet/semantic/ctxt.el" 
"cedet/semantic/db-file.el"
+;;;;;;  "cedet/semantic/db-find.el" "cedet/semantic/db-global.el"
+;;;;;;  "cedet/semantic/db-mode.el" "cedet/semantic/db-typecache.el"
+;;;;;;  "cedet/semantic/db.el" "cedet/semantic/debug.el" 
"cedet/semantic/decorate/include.el"
+;;;;;;  "cedet/semantic/decorate/mode.el" "cedet/semantic/dep.el"
+;;;;;;  "cedet/semantic/doc.el" "cedet/semantic/edit.el" 
"cedet/semantic/find.el"
+;;;;;;  "cedet/semantic/format.el" "cedet/semantic/grammar-wy.el"
 ;;;;;;  "cedet/semantic/grm-wy-boot.el" "cedet/semantic/html.el"
 ;;;;;;  "cedet/semantic/ia-sb.el" "cedet/semantic/ia.el" 
"cedet/semantic/idle.el"
 ;;;;;;  "cedet/semantic/imenu.el" "cedet/semantic/lex-spp.el" 
"cedet/semantic/lex.el"
-;;;;;;  "cedet/semantic/mru-bookmark.el" "cedet/semantic/scope.el"
-;;;;;;  "cedet/semantic/senator.el" "cedet/semantic/sort.el" 
"cedet/semantic/symref.el"
-;;;;;;  "cedet/semantic/symref/cscope.el" "cedet/semantic/symref/global.el"
-;;;;;;  "cedet/semantic/symref/grep.el" "cedet/semantic/symref/idutils.el"
-;;;;;;  "cedet/semantic/symref/list.el" "cedet/semantic/tag-file.el"
-;;;;;;  "cedet/semantic/tag-ls.el" "cedet/semantic/tag-write.el"
+;;;;;;  "cedet/semantic/loaddefs.el" "cedet/semantic/mru-bookmark.el"
+;;;;;;  "cedet/semantic/scope.el" "cedet/semantic/senator.el" 
"cedet/semantic/sort.el"
+;;;;;;  "cedet/semantic/symref.el" "cedet/semantic/symref/cscope.el"
+;;;;;;  "cedet/semantic/symref/global.el" "cedet/semantic/symref/grep.el"
+;;;;;;  "cedet/semantic/symref/idutils.el" "cedet/semantic/symref/list.el"
+;;;;;;  "cedet/semantic/tag-file.el" "cedet/semantic/tag-ls.el" 
"cedet/semantic/tag-write.el"
 ;;;;;;  "cedet/semantic/tag.el" "cedet/semantic/texi.el" 
"cedet/semantic/util-modes.el"
 ;;;;;;  "cedet/semantic/wisent/java-tags.el" 
"cedet/semantic/wisent/javascript.el"
 ;;;;;;  "cedet/semantic/wisent/javat-wy.el" "cedet/semantic/wisent/js-wy.el"
 ;;;;;;  "cedet/semantic/wisent/python-wy.el" "cedet/semantic/wisent/python.el"
 ;;;;;;  "cedet/srecode/compile.el" "cedet/srecode/cpp.el" 
"cedet/srecode/document.el"
 ;;;;;;  "cedet/srecode/el.el" "cedet/srecode/expandproto.el" 
"cedet/srecode/getset.el"
-;;;;;;  "cedet/srecode/insert.el" "cedet/srecode/java.el" 
"cedet/srecode/map.el"
-;;;;;;  "cedet/srecode/mode.el" "cedet/srecode/srt-wy.el" 
"cedet/srecode/srt.el"
-;;;;;;  "cedet/srecode/template.el" "cedet/srecode/texi.el" "composite.el"
-;;;;;;  "cus-face.el" "cus-start.el" "custom.el" "dired-aux.el" "dired-x.el"
+;;;;;;  "cedet/srecode/insert.el" "cedet/srecode/java.el" 
"cedet/srecode/loaddefs.el"
+;;;;;;  "cedet/srecode/map.el" "cedet/srecode/mode.el" 
"cedet/srecode/srt-wy.el"
+;;;;;;  "cedet/srecode/srt.el" "cedet/srecode/template.el" 
"cedet/srecode/texi.el"
+;;;;;;  "composite.el" "cus-face.el" "cus-load.el" "cus-start.el"
+;;;;;;  "custom.el" "dired-aux.el" "dired-loaddefs.el" "dired-x.el"
 ;;;;;;  "electric.el" "emacs-lisp/backquote.el" "emacs-lisp/byte-run.el"
-;;;;;;  "emacs-lisp/cl-extra.el" "emacs-lisp/cl-macs.el" 
"emacs-lisp/cl-preloaded.el"
-;;;;;;  "emacs-lisp/cl-seq.el" "emacs-lisp/easymenu.el" 
"emacs-lisp/eieio-compat.el"
-;;;;;;  "emacs-lisp/eieio-custom.el" "emacs-lisp/eieio-opt.el" 
"emacs-lisp/float-sup.el"
-;;;;;;  "emacs-lisp/lisp-mode.el" "emacs-lisp/lisp.el" "emacs-lisp/macroexp.el"
-;;;;;;  "emacs-lisp/map-ynp.el" "emacs-lisp/nadvice.el" 
"emacs-lisp/shorthands.el"
-;;;;;;  "emacs-lisp/syntax.el" "emacs-lisp/timer.el" "env.el" "epa-hook.el"
-;;;;;;  "erc/erc-autoaway.el" "erc/erc-button.el" "erc/erc-capab.el"
-;;;;;;  "erc/erc-compat.el" "erc/erc-dcc.el" "erc/erc-desktop-notifications.el"
+;;;;;;  "emacs-lisp/cl-extra.el" "emacs-lisp/cl-loaddefs.el" 
"emacs-lisp/cl-macs.el"
+;;;;;;  "emacs-lisp/cl-preloaded.el" "emacs-lisp/cl-seq.el" 
"emacs-lisp/easymenu.el"
+;;;;;;  "emacs-lisp/eieio-compat.el" "emacs-lisp/eieio-custom.el"
+;;;;;;  "emacs-lisp/eieio-loaddefs.el" "emacs-lisp/eieio-opt.el"
+;;;;;;  "emacs-lisp/float-sup.el" "emacs-lisp/lisp-mode.el" 
"emacs-lisp/lisp.el"
+;;;;;;  "emacs-lisp/macroexp.el" "emacs-lisp/map-ynp.el" 
"emacs-lisp/nadvice.el"
+;;;;;;  "emacs-lisp/shorthands.el" "emacs-lisp/syntax.el" "emacs-lisp/timer.el"
+;;;;;;  "env.el" "epa-hook.el" "erc/erc-autoaway.el" "erc/erc-button.el"
+;;;;;;  "erc/erc-capab.el" "erc/erc-compat.el" "erc/erc-dcc.el" 
"erc/erc-desktop-notifications.el"
 ;;;;;;  "erc/erc-ezbounce.el" "erc/erc-fill.el" "erc/erc-identd.el"
-;;;;;;  "erc/erc-imenu.el" "erc/erc-join.el" "erc/erc-list.el" "erc/erc-log.el"
-;;;;;;  "erc/erc-match.el" "erc/erc-menu.el" "erc/erc-netsplit.el"
+;;;;;;  "erc/erc-imenu.el" "erc/erc-join.el" "erc/erc-list.el" 
"erc/erc-loaddefs.el"
+;;;;;;  "erc/erc-log.el" "erc/erc-match.el" "erc/erc-menu.el" 
"erc/erc-netsplit.el"
 ;;;;;;  "erc/erc-notify.el" "erc/erc-page.el" "erc/erc-pcomplete.el"
 ;;;;;;  "erc/erc-replace.el" "erc/erc-ring.el" "erc/erc-services.el"
 ;;;;;;  "erc/erc-sound.el" "erc/erc-speedbar.el" "erc/erc-spelling.el"
@@ -39619,13 +39720,25 @@ Zone out, completely." t nil)
 ;;;;;;  "eshell/em-ls.el" "eshell/em-pred.el" "eshell/em-prompt.el"
 ;;;;;;  "eshell/em-rebind.el" "eshell/em-script.el" "eshell/em-smart.el"
 ;;;;;;  "eshell/em-term.el" "eshell/em-tramp.el" "eshell/em-unix.el"
-;;;;;;  "eshell/em-xtra.el" "faces.el" "files.el" "font-core.el"
-;;;;;;  "font-lock.el" "format.el" "frame.el" "help.el" "hfy-cmap.el"
-;;;;;;  "ibuf-ext.el" "indent.el" "international/characters.el" 
"international/charscript.el"
-;;;;;;  "international/cp51932.el" "international/emoji-zwj.el" 
"international/eucjp-ms.el"
+;;;;;;  "eshell/em-xtra.el" "eshell/esh-groups.el" "faces.el" "files.el"
+;;;;;;  "finder-inf.el" "font-core.el" "font-lock.el" "format.el"
+;;;;;;  "frame.el" "help.el" "hfy-cmap.el" "htmlfontify-loaddefs.el"
+;;;;;;  "ibuf-ext.el" "ibuffer-loaddefs.el" "indent.el" 
"international/characters.el"
+;;;;;;  "international/charprop.el" "international/charscript.el"
+;;;;;;  "international/cp51932.el" "international/emoji-labels.el"
+;;;;;;  "international/emoji-zwj.el" "international/eucjp-ms.el"
 ;;;;;;  "international/iso-transl.el" "international/mule-cmds.el"
-;;;;;;  "international/mule-conf.el" "international/mule.el" "isearch.el"
-;;;;;;  "jit-lock.el" "jka-cmpr-hook.el" "language/burmese.el" 
"language/cham.el"
+;;;;;;  "international/mule-conf.el" "international/mule.el" 
"international/uni-bidi.el"
+;;;;;;  "international/uni-brackets.el" "international/uni-category.el"
+;;;;;;  "international/uni-combining.el" "international/uni-comment.el"
+;;;;;;  "international/uni-decimal.el" "international/uni-decomposition.el"
+;;;;;;  "international/uni-digit.el" "international/uni-lowercase.el"
+;;;;;;  "international/uni-mirrored.el" "international/uni-name.el"
+;;;;;;  "international/uni-numeric.el" "international/uni-old-name.el"
+;;;;;;  "international/uni-special-lowercase.el" 
"international/uni-special-titlecase.el"
+;;;;;;  "international/uni-special-uppercase.el" 
"international/uni-titlecase.el"
+;;;;;;  "international/uni-uppercase.el" "isearch.el" "jit-lock.el"
+;;;;;;  "jka-cmpr-hook.el" "language/burmese.el" "language/cham.el"
 ;;;;;;  "language/chinese.el" "language/cyrillic.el" "language/czech.el"
 ;;;;;;  "language/english.el" "language/ethiopic.el" "language/european.el"
 ;;;;;;  "language/georgian.el" "language/greek.el" "language/hebrew.el"
@@ -39652,30 +39765,33 @@ Zone out, completely." t nil)
 ;;;;;;  "leim/quail/sgml-input.el" "leim/quail/slovak.el" 
"leim/quail/symbol-ksc.el"
 ;;;;;;  "leim/quail/tamil-dvorak.el" "leim/quail/tsang-b5.el" 
"leim/quail/tsang-cns.el"
 ;;;;;;  "leim/quail/vntelex.el" "leim/quail/vnvni.el" "leim/quail/welsh.el"
-;;;;;;  "loadup.el" "mail/blessmail.el" "mail/rmailedit.el" "mail/rmailkwd.el"
-;;;;;;  "mail/rmailmm.el" "mail/rmailmsc.el" "mail/rmailsort.el"
-;;;;;;  "mail/rmailsum.el" "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el"
-;;;;;;  "mh-e/mh-loaddefs.el" "minibuffer.el" "mouse.el" 
"net/tramp-loaddefs.el"
-;;;;;;  "newcomment.el" "obarray.el" "org/ob-core.el" "org/ob-lob.el"
-;;;;;;  "org/ob-matlab.el" "org/ob-tangle.el" "org/ob.el" "org/ol-bbdb.el"
-;;;;;;  "org/ol-irc.el" "org/ol.el" "org/org-archive.el" "org/org-attach.el"
-;;;;;;  "org/org-clock.el" "org/org-colview.el" "org/org-compat.el"
-;;;;;;  "org/org-datetree.el" "org/org-duration.el" "org/org-element.el"
-;;;;;;  "org/org-feed.el" "org/org-footnote.el" "org/org-goto.el"
-;;;;;;  "org/org-id.el" "org/org-indent.el" "org/org-install.el"
-;;;;;;  "org/org-keys.el" "org/org-lint.el" "org/org-list.el" "org/org-macs.el"
+;;;;;;  "loadup.el" "mail/blessmail.el" "mail/rmail-loaddefs.el"
+;;;;;;  "mail/rmailedit.el" "mail/rmailkwd.el" "mail/rmailmm.el"
+;;;;;;  "mail/rmailmsc.el" "mail/rmailsort.el" "mail/rmailsum.el"
+;;;;;;  "mail/undigest.el" "menu-bar.el" "mh-e/mh-gnus.el" 
"mh-e/mh-loaddefs.el"
+;;;;;;  "minibuffer.el" "mouse.el" "net/tramp-loaddefs.el" "newcomment.el"
+;;;;;;  "obarray.el" "org/ob-core.el" "org/ob-lob.el" "org/ob-matlab.el"
+;;;;;;  "org/ob-tangle.el" "org/ob.el" "org/ol-bbdb.el" "org/ol-irc.el"
+;;;;;;  "org/ol.el" "org/org-archive.el" "org/org-attach.el" "org/org-clock.el"
+;;;;;;  "org/org-colview.el" "org/org-compat.el" "org/org-datetree.el"
+;;;;;;  "org/org-duration.el" "org/org-element.el" "org/org-feed.el"
+;;;;;;  "org/org-footnote.el" "org/org-goto.el" "org/org-id.el" 
"org/org-indent.el"
+;;;;;;  "org/org-install.el" "org/org-keys.el" "org/org-lint.el"
+;;;;;;  "org/org-list.el" "org/org-loaddefs.el" "org/org-macs.el"
 ;;;;;;  "org/org-mobile.el" "org/org-num.el" "org/org-plot.el" 
"org/org-refile.el"
 ;;;;;;  "org/org-table.el" "org/org-timer.el" "org/ox-ascii.el" 
"org/ox-beamer.el"
 ;;;;;;  "org/ox-html.el" "org/ox-icalendar.el" "org/ox-latex.el"
 ;;;;;;  "org/ox-md.el" "org/ox-odt.el" "org/ox-org.el" "org/ox-publish.el"
 ;;;;;;  "org/ox-texinfo.el" "org/ox.el" "paren.el" "progmodes/elisp-mode.el"
-;;;;;;  "progmodes/prog-mode.el" "ps-mule.el" "register.el" "replace.el"
-;;;;;;  "rfn-eshadow.el" "select.el" "simple.el" "startup.el" "subdirs.el"
-;;;;;;  "subr.el" "tab-bar.el" "textmodes/fill.el" "textmodes/makeinfo.el"
-;;;;;;  "textmodes/page.el" "textmodes/paragraphs.el" "textmodes/reftex-auc.el"
-;;;;;;  "textmodes/reftex-cite.el" "textmodes/reftex-dcr.el" 
"textmodes/reftex-global.el"
-;;;;;;  "textmodes/reftex-index.el" "textmodes/reftex-parse.el" 
"textmodes/reftex-ref.el"
-;;;;;;  "textmodes/reftex-sel.el" "textmodes/reftex-toc.el" 
"textmodes/texnfo-upd.el"
+;;;;;;  "progmodes/prog-mode.el" "ps-mule.el" "ps-print-loaddefs.el"
+;;;;;;  "register.el" "replace.el" "rfn-eshadow.el" "select.el" "simple.el"
+;;;;;;  "startup.el" "subdirs.el" "subr.el" "tab-bar.el" "textmodes/fill.el"
+;;;;;;  "textmodes/makeinfo.el" "textmodes/page.el" "textmodes/paragraphs.el"
+;;;;;;  "textmodes/reftex-auc.el" "textmodes/reftex-cite.el" 
"textmodes/reftex-dcr.el"
+;;;;;;  "textmodes/reftex-global.el" "textmodes/reftex-index.el"
+;;;;;;  "textmodes/reftex-loaddefs.el" "textmodes/reftex-parse.el"
+;;;;;;  "textmodes/reftex-ref.el" "textmodes/reftex-sel.el" 
"textmodes/reftex-toc.el"
+;;;;;;  "textmodes/texinfo-loaddefs.el" "textmodes/texnfo-upd.el"
 ;;;;;;  "textmodes/text-mode.el" "uniquify.el" "vc/ediff-hook.el"
 ;;;;;;  "vc/vc-hooks.el" "version.el" "widget.el" "window.el") (0
 ;;;;;;  0 0 0))
diff --git a/lisp/ls-lisp.el b/lisp/ls-lisp.el
index 82153ff..eea8089 100644
--- a/lisp/ls-lisp.el
+++ b/lisp/ls-lisp.el
@@ -343,7 +343,7 @@ are also supported; unsupported long options are silently 
ignored."
          (goto-char (point-min))
          ;; First find the line to put it on.
          (when (re-search-forward "^total" nil t)
-           (let ((available (get-free-disk-space ".")))
+           (let ((available (get-free-disk-space orig-file)))
              (when available
                ;; Replace "total" with "total used", to avoid confusion.
                (replace-match "total used in directory")
diff --git a/lisp/mh-e/ChangeLog.1 b/lisp/mh-e/ChangeLog.1
index b0fdd02..e87bb34 100644
--- a/lisp/mh-e/ChangeLog.1
+++ b/lisp/mh-e/ChangeLog.1
@@ -10471,7 +10471,7 @@
        mh-header-subject-font-lock instead of regexp for subject headers,
        which may go multiple lines.
        (mh-header-subject-font-lock): New function.
-       Fix typos (hightlight -> highlight).
+       Fix typos ("highlight").
 
 2001-12-04  Eric Ding  <ericding@alum.mit.edu>
 
@@ -10881,7 +10881,7 @@
        loop in emacs20 font-locking.
        (mh-header-field-font-lock): Preventive fix with similar change.
 
-       * mh-comp.el (mh-reply-show-message-p): Typo.  diplayed -> displayed.
+       * mh-comp.el (mh-reply-show-message-p): Fix typo for "displayed".
        * MH-E-NEWS: Same.
 
        * mh-e.el (mh-folder-tool-bar-map): Bug fix.  I had
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 71c18ff..fd74693 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -1137,7 +1137,7 @@ the mouse click event."
 
 ;; Behind display-graphic-p test.
 (declare-function image-size "image.c" (spec &optional pixels frame))
-(declare-function image-animate "image" (image &optional index limit))
+(declare-function image-animate "image" (image &optional index limit position))
 
 (defun shr-put-image (spec alt &optional flags)
   "Insert image SPEC with a string ALT.  Return image.
@@ -1174,13 +1174,14 @@ element is the data blob and the second element is the 
content-type."
          (when (and (> (current-column) 0)
                     (> (car (image-size image t)) 400))
            (insert "\n"))
-         (if (eq size 'original)
-             (insert-sliced-image image (or alt "*") nil 20 1)
-           (insert-image image (or alt "*")))
-         (put-text-property start (point) 'image-size size)
-         (when (and shr-image-animate
-                     (cdr (image-multi-frame-p image)))
-            (image-animate image nil 60)))
+          (let ((image-pos (point)))
+           (if (eq size 'original)
+               (insert-sliced-image image (or alt "*") nil 20 1)
+             (insert-image image (or alt "*")))
+           (put-text-property start (point) 'image-size size)
+           (when (and shr-image-animate
+                       (cdr (image-multi-frame-p image)))
+              (image-animate image nil 60 image-pos))))
        image)
     (insert (or alt ""))))
 
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 362a258..374e5db 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -119,6 +119,7 @@ It is used for TCP/IP devices."
     (directory-files . tramp-handle-directory-files)
     (directory-files-and-attributes
      . tramp-adb-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . ignore)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . tramp-adb-handle-exec-path)
@@ -191,11 +192,10 @@ It is used for TCP/IP devices."
 ;; It must be a `defsubst' in order to push the whole code into
 ;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
 ;;;###tramp-autoload
-(defsubst tramp-adb-file-name-p (filename)
-  "Check if it's a FILENAME for ADB."
-  (and (tramp-tramp-file-p filename)
-       (string= (tramp-file-name-method (tramp-dissect-file-name filename))
-               tramp-adb-method)))
+(defsubst tramp-adb-file-name-p (vec-or-filename)
+  "Check if it's a VEC-OR-FILENAME for ADB."
+  (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+    (string= (tramp-file-name-method vec) tramp-adb-method)))
 
 ;;;###tramp-autoload
 (defun tramp-adb-file-name-handler (operation &rest args)
@@ -306,7 +306,7 @@ arguments to pass to the OPERATION."
   (directory &optional full match nosort id-format count)
   "Like `directory-files-and-attributes' for Tramp files."
   (unless (file-exists-p directory)
-    (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+    (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
   (when (file-directory-p directory)
     (with-parsed-tramp-file-name (expand-file-name directory) nil
       (copy-tree
@@ -499,7 +499,7 @@ Emacs dired can't find files."
   "Like `file-local-copy' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (unless (file-exists-p (file-truename filename))
-      (tramp-compat-file-missing v filename))
+      (tramp-error v 'file-missing filename))
     (let ((tmpfile (tramp-compat-make-temp-file filename)))
       (with-tramp-progress-reporter
          v 3 (format "Fetching %s to tmp file %s" filename tmpfile)
@@ -591,8 +591,7 @@ Emacs dired can't find files."
       ;; Set file modification time.
       (when (or (eq visit t) (stringp visit))
        (set-visited-file-modtime
-        (or (tramp-compat-file-attribute-modification-time
-             (file-attributes filename))
+        (or (file-attribute-modification-time (file-attributes filename))
             (current-time))))
 
       ;; Unlock file.
@@ -660,7 +659,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
          (jka-compr-inhibit t))
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
-         (tramp-compat-file-missing v filename))
+         (tramp-error v 'file-missing filename))
        (when (and (not ok-if-already-exists) (file-exists-p newname))
          (tramp-error v 'file-already-exists newname))
        (when (and (file-directory-p newname)
@@ -720,8 +719,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
     (when keep-date
       (tramp-compat-set-file-times
        newname
-       (tramp-compat-file-attribute-modification-time
-       (file-attributes filename))
+       (file-attribute-modification-time (file-attributes filename))
        (unless ok-if-already-exists 'nofollow)))))
 
 (defun tramp-adb-handle-rename-file
@@ -742,7 +740,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
          (jka-compr-inhibit t))
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
-         (tramp-compat-file-missing v filename))
+         (tramp-error v 'file-missing filename))
        (when (and (not ok-if-already-exists) (file-exists-p newname))
          (tramp-error v 'file-already-exists newname))
        (when (and (file-directory-p newname)
@@ -1349,22 +1347,18 @@ connection if a previous connection has died for some 
reason."
            ;; Mark it as connected.
            (tramp-set-connection-property p "connected" t)))))))
 
-;;; Default connection-local variables for Tramp:
-;; `connection-local-set-profile-variables' and
-;; `connection-local-set-profiles' exists since Emacs 26.1.
+;;; Default connection-local variables for Tramp.
 (defconst tramp-adb-connection-local-default-shell-variables
   '((shell-file-name . "/system/bin/sh")
     (shell-command-switch . "-c"))
   "Default connection-local shell variables for remote adb connections.")
 
-(tramp-compat-funcall
- 'connection-local-set-profile-variables
+(connection-local-set-profile-variables
  'tramp-adb-connection-local-default-shell-profile
  tramp-adb-connection-local-default-shell-variables)
 
 (with-eval-after-load 'shell
-  (tramp-compat-funcall
-   'connection-local-set-profiles
+  (connection-local-set-profiles
    `(:application tramp :protocol ,tramp-adb-method)
    'tramp-adb-connection-local-default-shell-profile))
 
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 8bf2515..578f9fc 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -223,6 +223,7 @@ It must be supported by libarchive(3).")
     (directory-files . tramp-handle-directory-files)
     (directory-files-and-attributes
      . tramp-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . tramp-archive-handle-not-implemented)
     (dired-uncache . tramp-archive-handle-dired-uncache)
     (exec-path . ignore)
@@ -618,7 +619,7 @@ offered."
 (defun tramp-archive-handle-file-system-info (filename)
   "Like `file-system-info' for file archives."
   (with-parsed-tramp-archive-file-name filename nil
-    (list (tramp-compat-file-attribute-size (file-attributes archive)) 0 0)))
+    (list (file-attribute-size (file-attributes archive)) 0 0)))
 
 (defun tramp-archive-handle-file-truename (filename)
   "Like `file-truename' for file archives."
@@ -658,7 +659,7 @@ offered."
   ;; mounted directory, it is returned as it.  Not what we want.
   (with-parsed-tramp-archive-file-name default-directory nil
     (let ((default-directory (file-name-directory archive)))
-      (tramp-compat-temporary-file-directory-function))))
+      (temporary-file-directory))))
 
 (defun tramp-archive-handle-not-implemented (operation &rest args)
   "Generic handler for operations not implemented for file archives."
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index 213ab58..627ff1e 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -23,17 +23,12 @@
 
 ;;; Commentary:
 
-;; Tramp's main Emacs version for development is Emacs 28.  This
-;; package provides compatibility functions for Emacs 25, Emacs 26 and
-;; Emacs 27.
+;; Tramp's main Emacs version for development is Emacs 29.  This
+;; package provides compatibility functions for Emacs 26, Emacs 27 and
+;; Emacs 28.
 
 ;;; Code:
 
-;; In Emacs 25, `tramp-unload-file-name-handlers' is not autoloaded.
-;; So we declare it here in order to avoid recursive load.  This will
-;; be overwritten in tramp.el.
-(defun tramp-unload-file-name-handlers () ".")
-
 (require 'auth-source)
 (require 'format-spec)
 (require 'ls-lisp)  ;; Due to `tramp-handle-insert-directory'.
@@ -42,8 +37,6 @@
 (require 'subr-x)
 
 (declare-function tramp-error "tramp")
-;; `temporary-file-directory' as function is introduced with Emacs 26.1.
-(declare-function tramp-handle-temporary-file-directory "tramp")
 (declare-function tramp-tramp-file-p "tramp")
 (defvar tramp-temp-name-prefix)
 
@@ -83,133 +76,19 @@ Add the extension of F, if existing."
     tramp-temp-name-prefix tramp-compat-temporary-file-directory)
    dir-flag (file-name-extension f t)))
 
-;; `temporary-file-directory' as function is introduced with Emacs 26.1.
-(defalias 'tramp-compat-temporary-file-directory-function
-  (if (fboundp 'temporary-file-directory)
-      #'temporary-file-directory
-    #'tramp-handle-temporary-file-directory))
-
-;; `file-attribute-*' are introduced in Emacs 26.1.
-
-(defalias 'tramp-compat-file-attribute-type
-  (if (fboundp 'file-attribute-type)
-      #'file-attribute-type
-    (lambda (attributes)
-      "The type field in ATTRIBUTES returned by `file-attributes'.
-The value is either t for directory, string (name linked to) for
-symbolic link, or nil."
-      (nth 0 attributes))))
-
-(defalias 'tramp-compat-file-attribute-link-number
-  (if (fboundp 'file-attribute-link-number)
-      #'file-attribute-link-number
-    (lambda (attributes)
-      "Return the number of links in ATTRIBUTES returned by `file-attributes'."
-      (nth 1 attributes))))
-
-(defalias 'tramp-compat-file-attribute-user-id
-  (if (fboundp 'file-attribute-user-id)
-      #'file-attribute-user-id
-    (lambda (attributes)
-      "The UID field in ATTRIBUTES returned by `file-attributes'.
-This is either a string or a number.  If a string value cannot be
-looked up, a numeric value, either an integer or a float, is
-returned."
-      (nth 2 attributes))))
-
-(defalias 'tramp-compat-file-attribute-group-id
-  (if (fboundp 'file-attribute-group-id)
-      #'file-attribute-group-id
-    (lambda (attributes)
-      "The GID field in ATTRIBUTES returned by `file-attributes'.
-This is either a string or a number.  If a string value cannot be
-looked up, a numeric value, either an integer or a float, is
-returned."
-      (nth 3 attributes))))
-
-(defalias 'tramp-compat-file-attribute-access-time
-  (if (fboundp 'file-attribute-access-time)
-      #'file-attribute-access-time
-    (lambda (attributes)
-      "The last access time in ATTRIBUTES returned by `file-attributes'.
-This a Lisp timestamp in the style of `current-time'."
-      (nth 4 attributes))))
-
-(defalias 'tramp-compat-file-attribute-modification-time
-  (if (fboundp 'file-attribute-modification-time)
-      #'file-attribute-modification-time
-    (lambda (attributes)
-      "The modification time in ATTRIBUTES returned by `file-attributes'.
-This is the time of the last change to the file's contents, and
-is a Lisp timestamp in the style of `current-time'."
-      (nth 5 attributes))))
-
-(defalias 'tramp-compat-file-attribute-status-change-time
-  (if (fboundp 'file-attribute-status-change-time)
-      #'file-attribute-status-change-time
-    (lambda (attributes)
-      "The status modification time in ATTRIBUTES returned by 
`file-attributes'.
-This is the time of last change to the file's attributes: owner
-and group, access mode bits, etc., and is a Lisp timestamp in the
-style of `current-time'."
-      (nth 6 attributes))))
-
-(defalias 'tramp-compat-file-attribute-size
-  (if (fboundp 'file-attribute-size)
-      #'file-attribute-size
-    (lambda (attributes)
-      "The size (in bytes) in ATTRIBUTES returned by `file-attributes'.
-If the size is too large for a fixnum, this is a bignum in Emacs 27
-and later, and is a float in Emacs 26 and earlier."
-      (nth 7 attributes))))
-
-(defalias 'tramp-compat-file-attribute-modes
-  (if (fboundp 'file-attribute-modes)
-      #'file-attribute-modes
-    (lambda (attributes)
-      "The file modes in ATTRIBUTES returned by `file-attributes'.
-This is a string of ten letters or dashes as in ls -l."
-      (nth 8 attributes))))
-
-;; `file-missing' is introduced in Emacs 26.1.
-(defconst tramp-file-missing
-  (if (get 'file-missing 'error-conditions) 'file-missing 'file-error)
-  "The error symbol for the `file-missing' error.")
-
-(defsubst tramp-compat-file-missing (vec file)
-  "Emit the `file-missing' error."
-  (if (get 'file-missing 'error-conditions)
-      (tramp-error vec tramp-file-missing file)
-    (tramp-error vec tramp-file-missing "No such file or directory: %s" file)))
-
-;; `file-local-name', `file-name-quoted-p', `file-name-quote' and
-;; `file-name-unquote' are introduced in Emacs 26.1.
-(defalias 'tramp-compat-file-local-name
-  (if (fboundp 'file-local-name)
-      #'file-local-name
-    (lambda (name)
-      "Return the local name component of NAME.
-It returns a file name which can be used directly as argument of
-`process-file', `start-file-process', or `shell-command'."
-      (or (file-remote-p name 'localname) name))))
-
 ;; `file-name-quoted-p', `file-name-quote' and `file-name-unquote' got
 ;; a second argument in Emacs 27.1.
 (defalias 'tramp-compat-file-name-quoted-p
-  (if (and
-       (fboundp 'file-name-quoted-p)
-       (equal (tramp-compat-funcall 'func-arity #'file-name-quoted-p) '(1 . 
2)))
+  (if (equal (func-arity #'file-name-quoted-p) '(1 . 2))
       #'file-name-quoted-p
     (lambda (name &optional top)
       "Whether NAME is quoted with prefix \"/:\".
 If NAME is a remote file name and TOP is nil, check the local part of NAME."
       (let ((file-name-handler-alist (unless top file-name-handler-alist)))
-       (string-prefix-p "/:" (tramp-compat-file-local-name name))))))
+       (string-prefix-p "/:" (file-local-name name))))))
 
 (defalias 'tramp-compat-file-name-quote
-  (if (and
-       (fboundp 'file-name-quote)
-       (equal (tramp-compat-funcall 'func-arity #'file-name-quote) '(1 . 2)))
+  (if (equal (func-arity #'file-name-quote) '(1 . 2))
       #'file-name-quote
     (lambda (name &optional top)
       "Add the quotation prefix \"/:\" to file NAME.
@@ -217,20 +96,17 @@ If NAME is a remote file name and TOP is nil, the local 
part of NAME is quoted."
       (let ((file-name-handler-alist (unless top file-name-handler-alist)))
        (if (tramp-compat-file-name-quoted-p name top)
             name
-         (concat
-          (file-remote-p name) "/:" (tramp-compat-file-local-name name)))))))
+         (concat (file-remote-p name) "/:" (file-local-name name)))))))
 
 (defalias 'tramp-compat-file-name-unquote
-  (if (and
-       (fboundp 'file-name-unquote)
-       (equal (tramp-compat-funcall 'func-arity #'file-name-unquote) '(1 . 2)))
+  (if (equal (func-arity #'file-name-unquote) '(1 . 2))
       #'file-name-unquote
     (lambda (name &optional top)
       "Remove quotation prefix \"/:\" from file NAME.
 If NAME is a remote file name and TOP is nil, the local part of
 NAME is unquoted."
       (let* ((file-name-handler-alist (unless top file-name-handler-alist))
-             (localname (tramp-compat-file-local-name name)))
+             (localname (file-local-name name)))
        (when (tramp-compat-file-name-quoted-p localname top)
          (setq
           localname (if (= (length localname) 2) "/" (substring localname 2))))
@@ -288,8 +164,7 @@ A nil value for either argument stands for the current 
time."
 
 ;; `progress-reporter-update' got argument SUFFIX in Emacs 27.1.
 (defalias 'tramp-compat-progress-reporter-update
-  (if (equal (tramp-compat-funcall 'func-arity #'progress-reporter-update)
-            '(1 . 3))
+  (if (equal (func-arity #'progress-reporter-update) '(1 . 3))
       #'progress-reporter-update
     (lambda (reporter &optional value _suffix)
       (progress-reporter-update reporter value))))
@@ -306,19 +181,19 @@ CONDITION can also be a list of error conditions."
 ;; `file-modes', `set-file-modes' and `set-file-times' got argument
 ;; FLAG in Emacs 28.1.
 (defalias 'tramp-compat-file-modes
-  (if (equal (tramp-compat-funcall 'func-arity #'file-modes) '(1 . 2))
+  (if (equal (func-arity #'file-modes) '(1 . 2))
       #'file-modes
     (lambda (filename &optional _flag)
       (file-modes filename))))
 
 (defalias 'tramp-compat-set-file-modes
-  (if (equal (tramp-compat-funcall 'func-arity #'set-file-modes) '(2 . 3))
+  (if (equal (func-arity #'set-file-modes) '(2 . 3))
       #'set-file-modes
     (lambda (filename mode &optional _flag)
       (set-file-modes filename mode))))
 
 (defalias 'tramp-compat-set-file-times
-  (if (equal (tramp-compat-funcall 'func-arity #'set-file-times) '(1 . 3))
+  (if (equal (func-arity #'set-file-times) '(1 . 3))
       #'set-file-times
     (lambda (filename &optional timestamp _flag)
       (set-file-times filename timestamp))))
@@ -326,14 +201,13 @@ CONDITION can also be a list of error conditions."
 ;; `directory-files' and `directory-files-and-attributes' got argument
 ;; COUNT in Emacs 28.1.
 (defalias 'tramp-compat-directory-files
-  (if (equal (tramp-compat-funcall 'func-arity #'directory-files) '(1 . 5))
+  (if (equal (func-arity #'directory-files) '(1 . 5))
       #'directory-files
     (lambda (directory &optional full match nosort _count)
       (directory-files directory full match nosort))))
 
 (defalias 'tramp-compat-directory-files-and-attributes
-  (if (equal (tramp-compat-funcall 'func-arity 
#'directory-files-and-attributes)
-            '(1 . 6))
+  (if (equal (func-arity #'directory-files-and-attributes) '(1 . 6))
       #'directory-files-and-attributes
     (lambda (directory &optional full match nosort id-format _count)
       (directory-files-and-attributes directory full match nosort id-format))))
@@ -386,14 +260,17 @@ CONDITION can also be a list of error conditions."
   (if (fboundp 'file-name-concat)
       #'file-name-concat
     (lambda (directory &rest components)
-      (unless (null directory)
-       (let ((components (delq nil components))
-             file-name-handler-alist)
-         (if (null components)
-             directory
-           (tramp-compat-file-name-concat
-            (concat (file-name-as-directory directory) (car components))
-            (cdr components))))))))
+      (let ((components (cl-remove-if (lambda (el)
+                                        (or (null el) (equal "" el)))
+                                      components))
+           file-name-handler-alist)
+        (if (null components)
+           directory
+          (apply #'tramp-compat-file-name-concat
+                (concat (unless (or (equal "" directory) (null directory))
+                           (file-name-as-directory directory))
+                         (car components))
+                (cdr components)))))))
 
 (dolist (elt (all-completions "tramp-compat-" obarray 'functionp))
   (put (intern elt) 'tramp-suppress-trace t))
@@ -407,8 +284,6 @@ CONDITION can also be a list of error conditions."
 
 ;;; TODO:
 ;;
-;; * `func-arity' exists since Emacs 26.1.
-;;
 ;; * Starting with Emacs 27.1, there's no need to escape open
 ;;   parentheses with a backslash in docstrings anymore.
 ;;
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index 269560b..f431f97 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -169,6 +169,7 @@ If NAME doesn't belong to a crypted remote directory, retun 
nil."
     (directory-files . tramp-crypt-handle-directory-files)
     (directory-files-and-attributes
      . tramp-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . ignore)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . ignore)
@@ -293,8 +294,9 @@ arguments to pass to the OPERATION."
 
 (defun tramp-crypt-config-file-name (vec)
   "Return the encfs config file name for VEC."
-  (locate-user-emacs-file
-   (concat "tramp-" (tramp-file-name-host vec) tramp-crypt-encfs-config)))
+  (expand-file-name
+   (locate-user-emacs-file
+    (concat "tramp-" (tramp-file-name-host vec) tramp-crypt-encfs-config))))
 
 (defun tramp-crypt-maybe-open-connection (vec)
   "Maybe open a connection VEC.
@@ -595,7 +597,7 @@ absolute file names."
 
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
-         (tramp-compat-file-missing v filename))
+         (tramp-error v 'file-missing filename))
        (when (and (not ok-if-already-exists) (file-exists-p newname))
          (tramp-error v 'file-already-exists newname))
        (when (and (file-directory-p newname)
@@ -697,7 +699,7 @@ absolute file names."
     (directory &optional full match nosort count)
   "Like `directory-files' for Tramp files."
   (unless (file-exists-p directory)
-    (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+    (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
   (when (file-directory-p directory)
     (setq directory (file-name-as-directory (expand-file-name directory)))
     (let* (tramp-crypt-enabled
diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el
index 11ccdc8..f78c08e 100644
--- a/lisp/net/tramp-ftp.el
+++ b/lisp/net/tramp-ftp.el
@@ -175,11 +175,10 @@ pass to the OPERATION."
 ;; It must be a `defsubst' in order to push the whole code into
 ;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
 ;;;###tramp-autoload
-(defsubst tramp-ftp-file-name-p (filename)
-  "Check if it's a FILENAME that should be forwarded to Ange-FTP."
-  (and (tramp-tramp-file-p filename)
-       (string= (tramp-file-name-method (tramp-dissect-file-name filename))
-               tramp-ftp-method)))
+(defsubst tramp-ftp-file-name-p (vec-or-filename)
+  "Check if it's a VEC-OR-FILENAME that should be forwarded to Ange-FTP."
+  (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+    (string= (tramp-file-name-method vec) tramp-ftp-method)))
 
 ;;;###tramp-autoload
 (tramp--with-startup
diff --git a/lisp/net/tramp-fuse.el b/lisp/net/tramp-fuse.el
index c359082..cb270be 100644
--- a/lisp/net/tramp-fuse.el
+++ b/lisp/net/tramp-fuse.el
@@ -48,7 +48,7 @@
     (directory &optional full match nosort count)
   "Like `directory-files' for Tramp files."
   (unless (file-exists-p directory)
-    (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+    (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
   (when (file-directory-p directory)
     (setq directory (file-name-as-directory (expand-file-name directory)))
     (with-parsed-tramp-file-name directory nil
@@ -107,12 +107,6 @@
               (unless (string-match-p elt item) (throw 'match nil)))
             (setq result (cons (concat item "/") result))))))))))
 
-(defun tramp-fuse-handle-file-readable-p (filename)
-  "Like `file-readable-p' for Tramp files."
-  (with-parsed-tramp-file-name (expand-file-name filename) nil
-    (with-tramp-file-property v localname "file-readable-p"
-      (file-readable-p (tramp-fuse-local-file-name filename)))))
-
 ;; This function isn't used.
 (defun tramp-fuse-handle-insert-directory
     (filename switches &optional wildcard full-directory-p)
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index cab912b..11de71a 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -122,10 +122,7 @@
         (autoload 'zeroconf-init "zeroconf")
         (tramp-compat-funcall 'dbus-get-unique-name :system)
         (tramp-compat-funcall 'dbus-get-unique-name :session)
-        (or ;; Until Emacs 25, `process-attributes' could crash Emacs
-            ;; for some processes.  Better we don't check.
-            (<= emacs-major-version 25)
-            (tramp-process-running-p "gvfs-fuse-daemon")
+        (or (tramp-process-running-p "gvfs-fuse-daemon")
             (tramp-process-running-p "gvfsd-fuse"))))
   "Non-nil when GVFS is available.")
 
@@ -471,8 +468,7 @@ It has been changed in GVFS 1.14.")
 ;;   </method>
 ;; </interface>
 
-;; The basic structure for GNOME Online Accounts.  We use a list :type,
-;; in order to be compatible with Emacs 25.
+;; The basic structure for GNOME Online Accounts.
 (cl-defstruct (tramp-goa-account (:type list) :named) method user host port)
 
 ;;;###tramp-autoload
@@ -672,8 +668,7 @@ It has been changed in GVFS 1.14.")
 ;;       STRING                    key (always-call-mount, is-removable, ...)
 ;;       VARIANT           value (boolean?)
 
-;; The basic structure for media devices.  We use a list :type, in
-;; order to be compatible with Emacs 25.
+;; The basic structure for media devices.
 (cl-defstruct (tramp-media-device (:type list) :named) method host port)
 
 ;; "gvfs-<command>" utilities have been deprecated in GVFS 1.31.1.  We
@@ -761,6 +756,7 @@ It has been changed in GVFS 1.14.")
     (directory-files . tramp-handle-directory-files)
     (directory-files-and-attributes
      . tramp-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . ignore)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . ignore)
@@ -834,12 +830,11 @@ Operations not mentioned here will be handled by the 
default Emacs primitives.")
 ;; It must be a `defsubst' in order to push the whole code into
 ;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
 ;;;###tramp-autoload
-(defsubst tramp-gvfs-file-name-p (filename)
-  "Check if it's a FILENAME handled by the GVFS daemon."
-  (and (tramp-tramp-file-p filename)
-       (let ((method
-             (tramp-file-name-method (tramp-dissect-file-name filename))))
-        (and (stringp method) (member method tramp-gvfs-methods)))))
+(defsubst tramp-gvfs-file-name-p (vec-or-filename)
+  "Check if it's a VEC-OR-FILENAME handled by the GVFS daemon."
+  (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+    (let ((method (tramp-file-name-method vec)))
+      (and (stringp method) (member method tramp-gvfs-methods)))))
 
 ;;;###tramp-autoload
 (defun tramp-gvfs-file-name-handler (operation &rest args)
@@ -1002,7 +997,7 @@ file names."
 
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
-         (tramp-compat-file-missing v filename))
+         (tramp-error v 'file-missing filename))
        (when (and (not ok-if-already-exists) (file-exists-p newname))
          (tramp-error v 'file-already-exists newname))
        (when (and (file-directory-p newname)
@@ -1102,8 +1097,7 @@ file names."
   (tramp-skeleton-delete-directory directory recursive trash
     (if (and recursive (not (file-symlink-p directory)))
        (mapc (lambda (file)
-               (if (eq t (tramp-compat-file-attribute-type
-                          (file-attributes file)))
+               (if (eq t (file-attribute-type (file-attributes file)))
                    (delete-directory file recursive)
                  (delete-file file)))
              (directory-files
@@ -1614,9 +1608,8 @@ ID-FORMAT valid values are `string' and `integer'."
                (tramp-get-connection-property
                 (tramp-get-process vec) "share"
                 (tramp-get-connection-property vec "default-location" nil))))
-      (tramp-compat-file-attribute-user-id
-       (file-attributes
-       (tramp-make-tramp-file-name vec localname) id-format)))))
+      (file-attribute-user-id
+       (file-attributes (tramp-make-tramp-file-name vec localname) 
id-format)))))
 
 (defun tramp-gvfs-handle-get-remote-gid (vec id-format)
   "The gid of the remote connection VEC, in ID-FORMAT.
@@ -1625,9 +1618,8 @@ ID-FORMAT valid values are `string' and `integer'."
              (tramp-get-connection-property
               (tramp-get-process vec) "share"
               (tramp-get-connection-property vec "default-location" nil))))
-    (tramp-compat-file-attribute-group-id
-     (file-attributes
-      (tramp-make-tramp-file-name vec localname) id-format))))
+    (file-attribute-group-id
+     (file-attributes (tramp-make-tramp-file-name vec localname) id-format))))
 
 (defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid)
   "Like `tramp-set-file-uid-gid' for Tramp files."
@@ -1865,9 +1857,9 @@ Their full names are \"org.gtk.vfs.MountTracker.mounted\" 
and
                    host (tramp-file-name-host v)
                    port (tramp-file-name-port v)))))
        (when (member method tramp-gvfs-methods)
-          (let ((v (make-tramp-file-name
-                   :method method :user user :domain domain
-                   :host host :port port)))
+         (let ((v (make-tramp-file-name
+                   :method method :user user :domain domain
+                   :host host :port port)))
            (tramp-message
             v 6 "%s %s"
             signal-name (tramp-gvfs-stringify-dbus-message mount-info))
diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el
index 17264193..238abd3 100644
--- a/lisp/net/tramp-integration.el
+++ b/lisp/net/tramp-integration.el
@@ -85,13 +85,6 @@ special handling of `substitute-in-file-name'."
   "An overlay covering the shadowed part of the filename."
   (format "[^%s/~]*\\(/\\|~\\)" tramp-postfix-host-format))
 
-;; Package rfn-eshadow is preloaded in Emacs, but for some reason,
-;; it only did (defvar rfn-eshadow-overlay) without giving it a global
-;; value, so it was only declared as dynamically-scoped within the
-;; rfn-eshadow.el file.  This is now fixed in Emacs>26.1 but we still need
-;; this defvar here for older releases.
-(defvar rfn-eshadow-overlay)
-
 (defun tramp-rfn-eshadow-update-overlay ()
   "Update `rfn-eshadow-overlay' to cover shadowed part of minibuffer input.
 This is intended to be used as a minibuffer `post-command-hook' for
@@ -281,22 +274,18 @@ NAME must be equal to `tramp-current-connection'."
              (remove-hook 'compilation-start-hook
                           #'tramp-compile-disable-ssh-controlmaster-options))))
 
-;;; Default connection-local variables for Tramp:
-;; `connection-local-set-profile-variables' and
-;; `connection-local-set-profiles' exists since Emacs 26.1.
+;;; Default connection-local variables for Tramp.
 
 (defconst tramp-connection-local-default-system-variables
   '((path-separator . ":")
     (null-device . "/dev/null"))
   "Default connection-local system variables for remote connections.")
 
-(tramp-compat-funcall
- 'connection-local-set-profile-variables
+(connection-local-set-profile-variables
  'tramp-connection-local-default-system-profile
  tramp-connection-local-default-system-variables)
 
-(tramp-compat-funcall
- 'connection-local-set-profiles
+(connection-local-set-profiles
  '(:application tramp)
  'tramp-connection-local-default-system-profile)
 
@@ -305,14 +294,12 @@ NAME must be equal to `tramp-current-connection'."
     (shell-command-switch . "-c"))
   "Default connection-local shell variables for remote connections.")
 
-(tramp-compat-funcall
- 'connection-local-set-profile-variables
+(connection-local-set-profile-variables
  'tramp-connection-local-default-shell-profile
  tramp-connection-local-default-shell-variables)
 
 (with-eval-after-load 'shell
-  (tramp-compat-funcall
-   'connection-local-set-profiles
+  (connection-local-set-profiles
    '(:application tramp)
    'tramp-connection-local-default-shell-profile))
 
diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el
index 812e06f..c997215 100644
--- a/lisp/net/tramp-rclone.el
+++ b/lisp/net/tramp-rclone.el
@@ -83,6 +83,7 @@
     (directory-files . tramp-fuse-handle-directory-files)
     (directory-files-and-attributes
      . tramp-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . ignore)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . ignore)
@@ -110,7 +111,7 @@
     (file-notify-rm-watch . ignore)
     (file-notify-valid-p . ignore)
     (file-ownership-preserved-p . ignore)
-    (file-readable-p . tramp-fuse-handle-file-readable-p)
+    (file-readable-p . tramp-rclone-handle-file-readable-p)
     (file-regular-p . tramp-handle-file-regular-p)
     (file-remote-p . tramp-handle-file-remote-p)
     (file-selinux-context . tramp-handle-file-selinux-context)
@@ -156,11 +157,10 @@ Operations not mentioned here will be handled by the 
default Emacs primitives.")
 ;; It must be a `defsubst' in order to push the whole code into
 ;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
 ;;;###tramp-autoload
-(defsubst tramp-rclone-file-name-p (filename)
-  "Check if it's a FILENAME for rclone."
-  (and (tramp-tramp-file-p filename)
-       (string= (tramp-file-name-method (tramp-dissect-file-name filename))
-               tramp-rclone-method)))
+(defsubst tramp-rclone-file-name-p (vec-or-filename)
+  "Check if it's a VEC-OR-FILENAME for rclone."
+  (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+    (string= (tramp-file-name-method vec) tramp-rclone-method)))
 
 ;;;###tramp-autoload
 (defun tramp-rclone-file-name-handler (operation &rest args)
@@ -223,7 +223,7 @@ file names."
 
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
-         (tramp-compat-file-missing v filename))
+         (tramp-error v 'file-missing filename))
        (when (and (not ok-if-already-exists) (file-exists-p newname))
          (tramp-error v 'file-already-exists newname))
        (when (and (file-directory-p newname)
@@ -280,6 +280,12 @@ file names."
      (list filename newname ok-if-already-exists keep-date
           preserve-uid-gid preserve-extended-attributes))))
 
+(defun tramp-rclone-handle-file-readable-p (filename)
+  "Like `file-readable-p' for Tramp files."
+  (with-parsed-tramp-file-name (expand-file-name filename) nil
+    (with-tramp-file-property v localname "file-readable-p"
+      (file-readable-p (tramp-fuse-local-file-name filename)))))
+
 (defun tramp-rclone-handle-file-system-info (filename)
   "Like `file-system-info' for Tramp files."
   (ignore-errors
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index b20e5f8..533ddcf 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -952,6 +952,7 @@ Format specifiers \"%s\" are replaced before the script is 
used.")
     (directory-files . tramp-handle-directory-files)
     (directory-files-and-attributes
      . tramp-sh-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . tramp-sh-handle-dired-compress-file)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . tramp-sh-handle-exec-path)
@@ -1334,7 +1335,7 @@ component is used as the target of the symlink."
       (with-parsed-tramp-file-name f nil
        (let* ((remote-file-name-inhibit-cache t)
               (attr (file-attributes f))
-              (modtime (or (tramp-compat-file-attribute-modification-time attr)
+              (modtime (or (file-attribute-modification-time attr)
                            tramp-time-doesnt-exist)))
          (setq coding-system-used last-coding-system-used)
          (if (not (tramp-compat-time-equal-p modtime tramp-time-dont-know))
@@ -1372,7 +1373,7 @@ of."
        (with-parsed-tramp-file-name f nil
          (let* ((remote-file-name-inhibit-cache t)
                 (attr (file-attributes f))
-                (modtime (tramp-compat-file-attribute-modification-time attr))
+                (modtime (file-attribute-modification-time attr))
                 (mt (visited-file-modtime)))
 
            (cond
@@ -1620,14 +1621,14 @@ ID-FORMAT valid values are `string' and `integer'."
        ;; information would be lost by an (attempted) delete and create.
        (or (null attributes)
            (and
-            (= (tramp-compat-file-attribute-user-id attributes)
+            (= (file-attribute-user-id attributes)
                (tramp-get-remote-uid v 'integer))
             (or (not group)
                 ;; On BSD-derived systems files always inherit the
                  ;; parent directory's group, so skip the group-gid
                  ;; test.
                  (tramp-check-remote-uname v "BSD\\|DragonFly\\|Darwin")
-                (= (tramp-compat-file-attribute-group-id attributes)
+                (= (file-attribute-group-id attributes)
                    (tramp-get-remote-gid v 'integer)))))))))
 
 ;; Directory listings.
@@ -1637,8 +1638,7 @@ ID-FORMAT valid values are `string' and `integer'."
   "Like `directory-files-and-attributes' for Tramp files."
   (unless id-format (setq id-format 'integer))
   (unless (file-exists-p directory)
-    (tramp-compat-file-missing
-     (tramp-dissect-file-name directory) directory))
+    (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
   (when (file-directory-p directory)
     (setq directory (expand-file-name directory))
     (let* ((temp
@@ -1858,7 +1858,7 @@ ID-FORMAT valid values are `string' and `integer'."
        target)
     (with-parsed-tramp-file-name (if t1 dirname newname) nil
       (unless (file-exists-p dirname)
-       (tramp-compat-file-missing v dirname))
+       (tramp-error v 'file-missing dirname))
 
       ;; `copy-directory-create-symlink' exists since Emacs 28.1.
       (if (and (bound-and-true-p copy-directory-create-symlink)
@@ -1952,7 +1952,7 @@ file names."
 
     (let ((t1 (tramp-tramp-file-p filename))
          (t2 (tramp-tramp-file-p newname))
-         (length (tramp-compat-file-attribute-size
+         (length (file-attribute-size
                   (file-attributes (file-truename filename))))
          (attributes (and preserve-extended-attributes
                           (file-extended-attributes filename)))
@@ -1960,7 +1960,7 @@ file names."
 
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
-         (tramp-compat-file-missing v filename))
+         (tramp-error v 'file-missing filename))
        (when (and (not ok-if-already-exists) (file-exists-p newname))
          (tramp-error v 'file-already-exists newname))
        (when (and (file-directory-p newname)
@@ -2052,7 +2052,7 @@ KEEP-DATE is non-nil if NEWNAME should have the same 
timestamp as FILENAME."
   ;; Check, whether file is too large.  Emacs checks in `insert-file-1'
   ;; and `find-file-noselect', but that's not called here.
   (abort-if-file-too-large
-   (tramp-compat-file-attribute-size (file-attributes (file-truename 
filename)))
+   (file-attribute-size (file-attributes (file-truename filename)))
    (symbol-name op) filename)
   ;; We must disable multibyte, because binary data shall not be
   ;; converted.  We don't want the target file to be compressed, so we
@@ -2074,8 +2074,7 @@ KEEP-DATE is non-nil if NEWNAME should have the same 
timestamp as FILENAME."
   (when keep-date
     (tramp-compat-set-file-times
      newname
-     (tramp-compat-file-attribute-modification-time
-      (file-attributes filename))
+     (file-attribute-modification-time (file-attributes filename))
      (unless ok-if-already-exists 'nofollow)))
   ;; Set the mode.
   (set-file-modes newname (tramp-default-file-modes filename))
@@ -2094,7 +2093,7 @@ as FILENAME.  PRESERVE-UID-GID, when non-nil, instructs 
to keep
 the uid and gid from FILENAME."
   (let ((t1 (tramp-tramp-file-p filename))
        (t2 (tramp-tramp-file-p newname))
-       (file-times (tramp-compat-file-attribute-modification-time
+       (file-times (file-attribute-modification-time
                     (file-attributes filename)))
        (file-modes (tramp-default-file-modes filename)))
     (with-parsed-tramp-file-name (if t1 filename newname) nil
@@ -2419,8 +2418,7 @@ The method used must be an out-of-band method."
        (when (and keep-date (not copy-keep-date))
          (tramp-compat-set-file-times
           newname
-          (tramp-compat-file-attribute-modification-time
-           (file-attributes filename))
+          (file-attribute-modification-time (file-attributes filename))
           (unless ok-if-already-exists 'nofollow)))
 
        ;; Set the mode.
@@ -2474,6 +2472,7 @@ The method used must be an out-of-band method."
 
 ;; Dired.
 
+;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
 (defun tramp-sh-handle-dired-compress-file (file)
   "Like `dired-compress-file' for Tramp files."
   ;; Code stolen mainly from dired-aux.el.
@@ -3199,9 +3198,9 @@ implementation will be used."
   "Like `file-local-copy' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (unless (file-exists-p (file-truename filename))
-      (tramp-compat-file-missing v filename))
+      (tramp-error v 'file-missing filename))
 
-    (let* ((size (tramp-compat-file-attribute-size
+    (let* ((size (file-attribute-size
                  (file-attributes (file-truename filename))))
           (rem-enc (tramp-get-inline-coding v "remote-encoding" size))
           (loc-dec (tramp-get-inline-coding v "local-decoding" size))
@@ -3288,11 +3287,9 @@ implementation will be used."
       (tramp-error v 'file-already-exists filename))
 
     (let ((file-locked (eq (file-locked-p lockname) t))
-         (uid (or (tramp-compat-file-attribute-user-id
-                   (file-attributes filename 'integer))
+         (uid (or (file-attribute-user-id (file-attributes filename 'integer))
                   (tramp-get-remote-uid v 'integer)))
-         (gid (or (tramp-compat-file-attribute-group-id
-                   (file-attributes filename 'integer))
+         (gid (or (file-attribute-group-id (file-attributes filename 'integer))
                   (tramp-get-remote-gid v 'integer))))
 
       ;; Lock file.
@@ -3371,8 +3368,7 @@ implementation will be used."
          ;; specified.  However, if the method _also_ specifies an
          ;; encoding function, then that is used for encoding the
          ;; contents of the tmp file.
-         (let* ((size (tramp-compat-file-attribute-size
-                       (file-attributes tmpfile)))
+         (let* ((size (file-attribute-size (file-attributes tmpfile)))
                 (rem-dec (tramp-get-inline-coding v "remote-decoding" size))
                 (loc-enc (tramp-get-inline-coding v "local-encoding" size)))
            (cond
@@ -3507,10 +3503,10 @@ implementation will be used."
              ;; We must pass modtime explicitly, because FILENAME can
              ;; be different from (buffer-file-name), f.e. if
              ;; `file-precious-flag' is set.
-            (or (tramp-compat-file-attribute-modification-time file-attr)
+            (or (file-attribute-modification-time file-attr)
                 (current-time)))
-            (when (and (= (tramp-compat-file-attribute-user-id file-attr) uid)
-                       (= (tramp-compat-file-attribute-group-id file-attr) 
gid))
+            (when (and (= (file-attribute-user-id file-attr) uid)
+                       (= (file-attribute-group-id file-attr) gid))
               (setq need-chown nil))))
 
        ;; Set the ownership.
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index 49f049d..ac567dc 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -234,6 +234,7 @@ See `tramp-actions-before-shell' for more info.")
     (directory-files . tramp-smb-handle-directory-files)
     (directory-files-and-attributes
      . tramp-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . ignore)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . ignore)
@@ -330,11 +331,10 @@ This can be used to disable echo etc."
 ;; It must be a `defsubst' in order to push the whole code into
 ;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
 ;;;###tramp-autoload
-(defsubst tramp-smb-file-name-p (filename)
-  "Check if it's a FILENAME for SMB servers."
-  (and (tramp-tramp-file-p filename)
-       (string= (tramp-file-name-method (tramp-dissect-file-name filename))
-               tramp-smb-method)))
+(defsubst tramp-smb-file-name-p (vec-or-filename)
+  "Check if it's a VEC-OR-FILENAME for SMB servers."
+  (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+    (string= (tramp-file-name-method vec) tramp-smb-method)))
 
 ;;;###tramp-autoload
 (defun tramp-smb-file-name-handler (operation &rest args)
@@ -419,7 +419,7 @@ arguments to pass to the OPERATION."
        target)
     (with-parsed-tramp-file-name (if t1 dirname newname) nil
       (unless (file-exists-p dirname)
-       (tramp-compat-file-missing v dirname))
+       (tramp-error v 'file-missing dirname))
 
       ;; `copy-directory-create-symlink' exists since Emacs 28.1.
       (if (and (bound-and-true-p copy-directory-create-symlink)
@@ -442,7 +442,7 @@ arguments to pass to the OPERATION."
          (with-tramp-progress-reporter
              v 0 (format "Copying %s to %s" dirname newname)
            (unless (file-exists-p dirname)
-             (tramp-compat-file-missing v dirname))
+             (tramp-error v 'file-missing dirname))
            (when (and (file-directory-p newname)
                       (not (directory-name-p newname)))
              (tramp-error v 'file-already-exists newname))
@@ -567,8 +567,7 @@ arguments to pass to the OPERATION."
              (when keep-date
                (tramp-compat-set-file-times
                 newname
-                (tramp-compat-file-attribute-modification-time
-                 (file-attributes dirname))
+                (file-attribute-modification-time (file-attributes dirname))
                 (unless ok-if-already-exists 'nofollow)))
 
              ;; Set the mode.
@@ -602,10 +601,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
        (copy-directory filename newname keep-date 'parents 'copy-contents)
 
       (unless (file-exists-p filename)
-       (tramp-compat-file-missing
+       (tramp-error
         (tramp-dissect-file-name
          (if (tramp-tramp-file-p filename) filename newname))
-        filename))
+        'file-missing filename))
 
       (if-let ((tmpfile (file-local-copy filename)))
          ;; Remote filename.
@@ -645,8 +644,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
     (when keep-date
       (tramp-compat-set-file-times
        newname
-       (tramp-compat-file-attribute-modification-time
-       (file-attributes filename))
+       (file-attribute-modification-time (file-attributes filename))
        (unless ok-if-already-exists 'nofollow)))))
 
 (defun tramp-smb-handle-delete-directory (directory &optional recursive trash)
@@ -706,7 +704,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
   (directory &optional full match nosort count)
   "Like `directory-files' for Tramp files."
   (unless (file-exists-p directory)
-    (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+    (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
   (let ((result (mapcar #'directory-file-name
                        (file-name-all-completions "" directory))))
     ;; Discriminate with regexp.
@@ -976,7 +974,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
   "Like `file-local-copy' for Tramp files."
   (with-parsed-tramp-file-name (file-truename filename) nil
     (unless (file-exists-p (file-truename filename))
-      (tramp-compat-file-missing v filename))
+      (tramp-error v 'file-missing filename))
     (let ((tmpfile (tramp-compat-make-temp-file filename)))
       (with-tramp-progress-reporter
          v 3 (format "Fetching %s to tmp file %s" filename tmpfile)
@@ -1041,8 +1039,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
   "Like `file-writable-p' for Tramp files."
   (if (file-exists-p filename)
       (tramp-compat-string-search
-       "w"
-       (or (tramp-compat-file-attribute-modes (file-attributes filename)) ""))
+       "w" (or (file-attribute-modes (file-attributes filename)) ""))
     (let ((dir (file-name-directory filename)))
       (and (file-exists-p dir)
           (file-writable-p dir)))))
@@ -1145,11 +1142,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
                   (insert
                    (format
                     "%10s %3d %-8s %-8s %8s %s "
-                    (or (tramp-compat-file-attribute-modes attr) (nth 1 x))
-                    (or (tramp-compat-file-attribute-link-number attr) 1)
-                    (or (tramp-compat-file-attribute-user-id attr) "nobody")
-                    (or (tramp-compat-file-attribute-group-id attr) "nogroup")
-                    (or (tramp-compat-file-attribute-size attr) (nth 2 x))
+                    (or (file-attribute-modes attr) (nth 1 x))
+                    (or (file-attribute-link-number attr) 1)
+                    (or (file-attribute-user-id attr) "nobody")
+                    (or (file-attribute-group-id attr) "nogroup")
+                    (or (file-attribute-size attr) (nth 2 x))
                     (format-time-string
                      (if (time-less-p
                           ;; Half a year.
@@ -1171,8 +1168,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
 
                 ;; Insert symlink.
                 (when (and (tramp-compat-string-search "l" switches)
-                           (stringp (tramp-compat-file-attribute-type attr)))
-                  (insert " -> " (tramp-compat-file-attribute-type attr))))
+                           (stringp (file-attribute-type attr)))
+                  (insert " -> " (file-attribute-type attr))))
 
               (insert "\n")
               (beginning-of-line)))
@@ -1394,7 +1391,7 @@ component is used as the target of the symlink."
   (with-parsed-tramp-file-name
       (if (tramp-tramp-file-p filename) filename newname) nil
     (unless (file-exists-p filename)
-      (tramp-compat-file-missing v filename))
+      (tramp-error v 'file-missing filename))
     (when (and (not ok-if-already-exists) (file-exists-p newname))
       (tramp-error v 'file-already-exists newname))
     (when (and (file-directory-p newname)
@@ -1647,8 +1644,7 @@ errors for shares like \"C$/\", which are common in 
Microsoft Windows."
       ;; Set file modification time.
       (when (or (eq visit t) (stringp visit))
        (set-visited-file-modtime
-        (or (tramp-compat-file-attribute-modification-time
-             (file-attributes filename))
+        (or (file-attribute-modification-time (file-attributes filename))
             (current-time))))
 
       ;; Unlock file.
diff --git a/lisp/net/tramp-sshfs.el b/lisp/net/tramp-sshfs.el
index a100786..fc77d99 100644
--- a/lisp/net/tramp-sshfs.el
+++ b/lisp/net/tramp-sshfs.el
@@ -83,6 +83,7 @@
     (directory-files . tramp-fuse-handle-directory-files)
     (directory-files-and-attributes
      . tramp-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . ignore)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . tramp-sshfs-handle-exec-path)
@@ -110,7 +111,7 @@
     (file-notify-rm-watch . ignore)
     (file-notify-valid-p . ignore)
     (file-ownership-preserved-p . ignore)
-    (file-readable-p . tramp-fuse-handle-file-readable-p)
+    (file-readable-p . tramp-handle-file-readable-p)
     (file-regular-p . tramp-handle-file-regular-p)
     (file-remote-p . tramp-handle-file-remote-p)
     (file-selinux-context . tramp-handle-file-selinux-context)
@@ -156,11 +157,10 @@ Operations not mentioned here will be handled by the 
default Emacs primitives.")
 ;; It must be a `defsubst' in order to push the whole code into
 ;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
 ;;;###tramp-autoload
-(defsubst tramp-sshfs-file-name-p (filename)
-  "Check if it's a FILENAME for sshfs."
-  (and (tramp-tramp-file-p filename)
-       (string= (tramp-file-name-method (tramp-dissect-file-name filename))
-               tramp-sshfs-method)))
+(defsubst tramp-sshfs-file-name-p (vec-or-filename)
+  "Check if it's a VEC-OR-FILENAME for sshfs."
+  (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+    (string= (tramp-file-name-method vec) tramp-sshfs-method)))
 
 ;;;###tramp-autoload
 (defun tramp-sshfs-file-name-handler (operation &rest args)
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index 845f31d..8429904 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -75,6 +75,7 @@ See `tramp-actions-before-shell' for more info.")
     (directory-files . tramp-handle-directory-files)
     (directory-files-and-attributes
      . tramp-handle-directory-files-and-attributes)
+    ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
     (dired-compress-file . ignore)
     (dired-uncache . tramp-handle-dired-uncache)
     (exec-path . ignore)
@@ -148,11 +149,10 @@ See `tramp-actions-before-shell' for more info.")
 ;; It must be a `defsubst' in order to push the whole code into
 ;; tramp-loaddefs.el.  Otherwise, there would be recursive autoloading.
 ;;;###tramp-autoload
-(defsubst tramp-sudoedit-file-name-p (filename)
-  "Check if it's a FILENAME for SUDOEDIT."
-  (and (tramp-tramp-file-p filename)
-       (string= (tramp-file-name-method (tramp-dissect-file-name filename))
-               tramp-sudoedit-method)))
+(defsubst tramp-sudoedit-file-name-p (vec-or-filename)
+  "Check if it's a VEC-OR-FILENAME for SUDOEDIT."
+  (when-let* ((vec (tramp-ensure-dissected-file-name vec-or-filename)))
+    (string= (tramp-file-name-method vec) tramp-sudoedit-method)))
 
 ;;;###tramp-autoload
 (defun tramp-sudoedit-file-name-handler (operation &rest args)
@@ -233,7 +233,7 @@ absolute file names."
 
     (let ((t1 (tramp-sudoedit-file-name-p filename))
          (t2 (tramp-sudoedit-file-name-p newname))
-         (file-times (tramp-compat-file-attribute-modification-time
+         (file-times (file-attribute-modification-time
                       (file-attributes filename)))
          (file-modes (tramp-default-file-modes filename))
          (attributes (and preserve-extended-attributes
@@ -247,7 +247,7 @@ absolute file names."
 
       (with-parsed-tramp-file-name (if t1 filename newname) nil
        (unless (file-exists-p filename)
-         (tramp-compat-file-missing v filename))
+         (tramp-error v 'file-missing filename))
        (when (and (not ok-if-already-exists) (file-exists-p newname))
          (tramp-error v 'file-already-exists newname))
        (when (and (file-directory-p newname)
@@ -721,11 +721,9 @@ ID-FORMAT valid values are `string' and `integer'."
   "Like `write-region' for Tramp files."
   (setq filename (expand-file-name filename))
   (with-parsed-tramp-file-name filename nil
-    (let* ((uid (or (tramp-compat-file-attribute-user-id
-                    (file-attributes filename 'integer))
+    (let* ((uid (or (file-attribute-user-id (file-attributes filename 
'integer))
                    (tramp-get-remote-uid v 'integer)))
-          (gid (or (tramp-compat-file-attribute-group-id
-                    (file-attributes filename 'integer))
+          (gid (or (file-attribute-group-id (file-attributes filename 
'integer))
                    (tramp-get-remote-gid v 'integer)))
           (flag (and (eq mustbenew 'excl) 'nofollow))
           (modes (tramp-default-file-modes filename flag))
@@ -736,10 +734,10 @@ ID-FORMAT valid values are `string' and `integer'."
 
        ;; Set the ownership, modes and extended attributes.  This is
        ;; not performed in `tramp-handle-write-region'.
-       (unless (and (= (tramp-compat-file-attribute-user-id
+       (unless (and (= (file-attribute-user-id
                         (file-attributes filename 'integer))
                        uid)
-                     (= (tramp-compat-file-attribute-group-id
+                     (= (file-attribute-group-id
                         (file-attributes filename 'integer))
                        gid))
           (tramp-set-file-uid-gid filename uid gid))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index a8972ce..f449360 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -751,11 +751,11 @@ The answer will be provided by 
`tramp-action-process-alive',
 
 (defconst tramp-temp-name-prefix "tramp."
   "Prefix to use for temporary files.
-If this is a relative file name (such as \"tramp.\"), it is considered
-relative to the directory name returned by the function
-`tramp-compat-temporary-file-directory' (which see).  It may also be an
-absolute file name; don't forget to include a prefix for the filename
-part, though.")
+If this is a relative file name (such as \"tramp.\"), it is
+considered relative to the directory name returned by the
+function `temporary-file-directory' (which see).  It may also be
+an absolute file name; don't forget to include a prefix for the
+filename part, though.")
 
 (defconst tramp-temp-buffer-name " *tramp temp*"
   "Buffer name for a temporary buffer.
@@ -822,11 +822,10 @@ to be set, depending on VALUE."
   (tramp-register-file-name-handlers))
 
 ;; Initialize the Tramp syntax variables.  We want to override initial
-;; value of `tramp-file-name-regexp'.  Other Tramp syntax variables
-;; must be initialized as well to proper values.  We do not call
+;; value of `tramp-file-name-regexp'.  We do not call
 ;; `custom-set-variable', this would load Tramp via custom.el.
 (tramp--with-startup
-  (tramp-set-syntax 'tramp-syntax (tramp-compat-tramp-syntax)))
+  (tramp-set-syntax 'tramp-syntax tramp-syntax))
 
 (defun tramp-syntax-values ()
   "Return possible values of `tramp-syntax', a list."
@@ -836,9 +835,9 @@ to be set, depending on VALUE."
     values))
 
 (defun tramp-lookup-syntax (alist)
-  "Look up a syntax string in ALIST according to `tramp-compat-tramp-syntax'.
-Raise an error if `tramp-syntax' is invalid."
-  (or (cdr (assq (tramp-compat-tramp-syntax) alist))
+  "Look up a syntax string in ALIST according to `tramp-syntax'.
+Raise an error if it is invalid."
+  (or (cdr (assq tramp-syntax alist))
       (error "Wrong `tramp-syntax' %s" tramp-syntax)))
 
 (defconst tramp-prefix-format-alist
@@ -1409,8 +1408,7 @@ calling HANDLER.")
 ;; internal data structure.  Convenience functions for internal
 ;; data structure.
 
-;; The basic structure for remote file names.  We use a list :type,
-;; in order to be compatible with Emacs 25.
+;; The basic structure for remote file names.
 (cl-defstruct (tramp-file-name (:type list) :named)
   method user domain host port localname hop)
 
@@ -1522,7 +1520,7 @@ of `process-file', `start-file-process', or 
`shell-command'."
   (or (and (tramp-tramp-file-p name)
            (string-match (nth 0 tramp-file-name-structure) name)
            (match-string (nth 4 tramp-file-name-structure) name))
-      (tramp-compat-file-local-name name)))
+      (file-local-name name)))
 
 ;; The localname can be quoted with "/:".  Extract this.
 (defun tramp-unquote-file-local-name (name)
@@ -1669,6 +1667,16 @@ default values are used."
 
 (put #'tramp-dissect-file-name 'tramp-suppress-trace t)
 
+(defun tramp-ensure-dissected-file-name (vec-or-filename)
+  "Return a `tramp-file-name' structure for VEC-OR-FILENAME.
+
+VEC-OR-FILENAME may be either a string or a `tramp-file-name'.
+If it's not a Tramp filename, return nil."
+  (cond
+   ((tramp-file-name-p vec-or-filename) vec-or-filename)
+   ((tramp-tramp-file-p vec-or-filename)
+    (tramp-dissect-file-name vec-or-filename))))
+
 (defun tramp-dissect-hop-name (name &optional nodefault)
   "Return a `tramp-file-name' structure of `hop' part of NAME.
 See `tramp-dissect-file-name' for details."
@@ -1839,9 +1847,7 @@ from the default one."
 If connection-local variables are not supported by this Emacs
 version, the function does nothing."
   (with-current-buffer (tramp-get-connection-buffer vec)
-    ;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
-    (tramp-compat-funcall
-     'hack-connection-local-variables-apply
+    (hack-connection-local-variables-apply
      `(:application tramp
        :protocol    ,(tramp-file-name-method vec)
        :user        ,(tramp-file-name-user-domain vec)
@@ -1852,9 +1858,7 @@ version, the function does nothing."
 If connection-local variables are not supported by this Emacs
 version, the function does nothing."
   (when (tramp-tramp-file-p default-directory)
-    ;; `hack-connection-local-variables-apply' exists since Emacs 26.1.
-    (tramp-compat-funcall
-     'hack-connection-local-variables-apply
+    (hack-connection-local-variables-apply
      `(:application tramp
        :protocol    ,(file-remote-p default-directory 'method)
        :user        ,(file-remote-p default-directory 'user)
@@ -2472,35 +2476,34 @@ Must be handled by the callers."
            '(access-file byte-compiler-base-file-name delete-directory
              delete-file diff-latest-backup-file directory-file-name
              directory-files directory-files-and-attributes
-             dired-compress-file dired-uncache file-acl
-             file-accessible-directory-p file-attributes
-             file-directory-p file-executable-p file-exists-p
-             file-local-copy file-modes file-name-as-directory
+             dired-uncache file-acl file-accessible-directory-p
+             file-attributes file-directory-p file-executable-p
+             file-exists-p file-local-copy file-modes
+             file-name-as-directory file-name-case-insensitive-p
              file-name-directory file-name-nondirectory
              file-name-sans-versions file-notify-add-watch
              file-ownership-preserved-p file-readable-p
              file-regular-p file-remote-p file-selinux-context
              file-symlink-p file-truename file-writable-p
-             find-backup-file-name get-file-buffer
-             insert-directory insert-file-contents load
-             make-directory make-directory-internal set-file-acl
-             set-file-modes set-file-selinux-context set-file-times
+             find-backup-file-name get-file-buffer insert-directory
+             insert-file-contents load make-directory
+             make-directory-internal set-file-acl set-file-modes
+             set-file-selinux-context set-file-times
              substitute-in-file-name unhandled-file-name-directory
              vc-registered
-             ;; Emacs 26+ only.
-             file-name-case-insensitive-p
              ;; Emacs 27+ only.
              file-system-info
              ;; Emacs 28+ only.
              file-locked-p lock-file make-lock-file-name unlock-file
+             ;; Starting with Emacs 29.1, `dired-compress-file' isn't
+             ;; magic anymore.
+             dired-compress-file
              ;; Tramp internal magic file name function.
              tramp-set-file-uid-gid))
     (if (file-name-absolute-p (nth 0 args))
        (nth 0 args)
       default-directory))
    ;; STRING FILE.
-   ;; Starting with Emacs 26.1, just the 2nd argument of
-   ;; `make-symbolic-link' matters.
    ((eq operation 'make-symbolic-link) (nth 1 args))
    ;; FILE DIRECTORY resp FILE1 FILE2.
    ((member operation
@@ -2531,9 +2534,8 @@ Must be handled by the callers."
      (if (bufferp (nth 0 args)) (nth 0 args) (current-buffer))))
    ;; COMMAND.
    ((member operation
-           '(process-file shell-command start-file-process
-             ;; Emacs 26+ only.
-             make-nearby-temp-file temporary-file-directory
+           '(make-nearby-temp-file process-file shell-command
+             start-file-process temporary-file-directory
              ;; Emacs 27+ only.
              exec-path make-process))
     default-directory)
@@ -2552,11 +2554,14 @@ Must be handled by the callers."
   "Return foreign file name handler if exists."
   (when (tramp-tramp-file-p filename)
     (let ((handler tramp-foreign-file-name-handler-alist)
+          (vec (tramp-dissect-file-name filename))
          elt res)
       (while handler
        (setq elt (car handler)
              handler (cdr handler))
-       (when (funcall (car elt) filename)
+        ;; Previously, this function was called with FILENAME, but now
+        ;; it's called with the VEC.
+        (when (with-demoted-errors "Error: %S" (funcall (car elt) vec))
          (setq handler nil
                res (cdr elt))))
       res)))
@@ -2755,8 +2760,9 @@ remote file names."
 (defun tramp-register-foreign-file-name-handler
     (func handler &optional append)
   "Register (FUNC . HANDLER) in `tramp-foreign-file-name-handler-alist'.
-FUNC is the function, which determines whether HANDLER is to be called.
-Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'."
+FUNC is the function, which takes a dissected filename and determines
+whether HANDLER is to be called.  Add operations defined in
+`HANDLER-alist' to `tramp-file-name-handler'."
   (add-to-list
    'tramp-foreign-file-name-handler-alist `(,func . ,handler) append)
   ;; Mark `operations' the handler is responsible for.
@@ -2814,11 +2820,7 @@ They are completed by \"M-x TAB\" only if the current 
buffer is remote."
 This is true, if either the remote host is already connected, or if we are
 not in completion mode."
   (let ((tramp-verbose 0)
-       (vec
-        (cond
-         ((tramp-file-name-p vec-or-filename) vec-or-filename)
-         ((tramp-tramp-file-p vec-or-filename)
-          (tramp-dissect-file-name vec-or-filename)))))
+       (vec (tramp-ensure-dissected-file-name vec-or-filename)))
     (or ;; We check this for the process related to
        ;; `tramp-buffer-name'; otherwise `start-file-process'
        ;; wouldn't run ever when `non-essential' is non-nil.
@@ -3288,8 +3290,9 @@ User is always nil."
             filename)
          (tramp-error
           v 'file-error (format "%s: Permission denied, %s" string filename)))
-      (tramp-compat-file-missing
-       v (format "%s: No such file or directory, %s" string filename)))))
+      (tramp-error
+       v 'file-missing
+       (format "%s: No such file or directory, %s" string filename)))))
 
 (defun tramp-handle-add-name-to-file
   (filename newname &optional ok-if-already-exists)
@@ -3323,7 +3326,7 @@ User is always nil."
   ;; `copy-directory' creates NEWNAME before running this check.  So
   ;; we do it ourselves.
   (unless (file-exists-p directory)
-    (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+    (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
   ;; We must do it file-wise.
   (tramp-run-real-handler
    #'copy-directory
@@ -3344,7 +3347,7 @@ User is always nil."
 (defun tramp-handle-directory-files (directory &optional full match nosort 
count)
   "Like `directory-files' for Tramp files."
   (unless (file-exists-p directory)
-    (tramp-compat-file-missing (tramp-dissect-file-name directory) directory))
+    (tramp-error (tramp-dissect-file-name directory) 'file-missing directory))
   (when (file-directory-p directory)
     (setq directory (file-name-as-directory (expand-file-name directory)))
     (let ((temp (nreverse (file-name-all-completions "" directory)))
@@ -3410,9 +3413,7 @@ User is always nil."
 
 (defun tramp-handle-file-directory-p (filename)
   "Like `file-directory-p' for Tramp files."
-  (eq (tramp-compat-file-attribute-type
-       (file-attributes (file-truename filename)))
-      t))
+  (eq (file-attribute-type (file-attributes (file-truename filename))) t))
 
 (defun tramp-handle-file-equal-p (filename1 filename2)
   "Like `file-equalp-p' for Tramp files."
@@ -3444,7 +3445,7 @@ User is always nil."
   "Like `file-local-copy' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (unless (file-exists-p filename)
-      (tramp-compat-file-missing v filename))
+      (tramp-error v 'file-missing filename))
     (let ((tmpfile (tramp-compat-make-temp-file filename)))
       (copy-file filename tmpfile 'ok-if-already-exists 'keep-time)
       tmpfile)))
@@ -3452,7 +3453,7 @@ User is always nil."
 (defun tramp-handle-file-modes (filename &optional flag)
   "Like `file-modes' for Tramp files."
   (when-let ((attrs (file-attributes filename))
-            (mode-string (tramp-compat-file-attribute-modes attrs)))
+            (mode-string (file-attribute-modes attrs)))
     (if (and (not (eq flag 'nofollow)) (eq ?l (aref mode-string 0)))
        (file-modes (file-truename filename))
       (tramp-mode-string-to-int mode-string))))
@@ -3505,16 +3506,13 @@ User is always nil."
                          (directory-file-name
                           (file-name-directory candidate))))
                  ;; Nothing found, so we must use a temporary file
-                 ;; for comparison.  `make-nearby-temp-file' is added
-                 ;; to Emacs 26+ like `file-name-case-insensitive-p',
-                 ;; so there is no compatibility problem calling it.
+                 ;; for comparison.
                  (unless (string-match-p
                           "[[:lower:]]" (tramp-file-local-name candidate))
                    (setq tmpfile
                          (let ((default-directory
-                                 (file-name-directory filename)))
-                           (tramp-compat-funcall
-                            'make-nearby-temp-file "tramp."))
+                                (file-name-directory filename)))
+                           (make-nearby-temp-file "tramp."))
                          candidate tmpfile))
                  ;; Check for the existence of the same file with
                  ;; upper case letters.
@@ -3575,9 +3573,8 @@ User is always nil."
    ((not (file-exists-p file1)) nil)
    ((not (file-exists-p file2)) t)
    (t (time-less-p
-       (tramp-compat-file-attribute-modification-time (file-attributes file2))
-       (tramp-compat-file-attribute-modification-time
-       (file-attributes file1))))))
+       (file-attribute-modification-time (file-attributes file2))
+       (file-attribute-modification-time (file-attributes file1))))))
 
 (defun tramp-handle-file-readable-p (filename)
   "Like `file-readable-p' for Tramp files."
@@ -3596,7 +3593,7 @@ User is always nil."
        ;; Sometimes, `file-attributes' does not return a proper value
        ;; even if `file-exists-p' does.
        (when-let ((attr (file-attributes filename)))
-        (eq ?- (aref (tramp-compat-file-attribute-modes attr) 0)))))
+        (eq ?- (aref (file-attribute-modes attr) 0)))))
 
 (defun tramp-handle-file-remote-p (filename &optional identification connected)
   "Like `file-remote-p' for Tramp files."
@@ -3628,7 +3625,7 @@ User is always nil."
 
 (defun tramp-handle-file-symlink-p (filename)
   "Like `file-symlink-p' for Tramp files."
-  (let ((x (tramp-compat-file-attribute-type (file-attributes filename))))
+  (let ((x (file-attribute-type (file-attributes filename))))
     (and (stringp x) x)))
 
 (defun tramp-handle-file-truename (filename)
@@ -3717,7 +3714,7 @@ User is always nil."
        (when (and (not tramp-allow-unsafe-temporary-files)
                   (not backup-inhibited)
                   (file-in-directory-p (car result) temporary-file-directory)
-                  (zerop (or (tramp-compat-file-attribute-user-id
+                  (zerop (or (file-attribute-user-id
                               (file-attributes filename 'integer))
                              tramp-unknown-id-integer))
                   (not (with-tramp-connection-property
@@ -3774,7 +3771,7 @@ User is always nil."
       (unwind-protect
          (if (not (file-exists-p filename))
               (let ((tramp-verbose (if visit 0 tramp-verbose)))
-               (tramp-compat-file-missing v filename))
+               (tramp-error v 'file-missing filename))
 
            (with-tramp-progress-reporter
                v 3 (format-message "Inserting `%s'" filename)
@@ -3939,7 +3936,7 @@ Return nil when there is no lockfile."
          (when (and (not tramp-allow-unsafe-temporary-files)
                     create-lockfiles
                     (file-in-directory-p lockname temporary-file-directory)
-                    (zerop (or (tramp-compat-file-attribute-user-id
+                    (zerop (or (file-attribute-user-id
                                 (file-attributes file 'integer))
                                tramp-unknown-id-integer))
                     (not (with-tramp-connection-property
@@ -3991,7 +3988,7 @@ Return nil when there is no lockfile."
         v 'file-error
         "File `%s' does not include a `.el' or `.elc' suffix" file)))
     (unless (or noerror (file-exists-p file))
-      (tramp-compat-file-missing v file))
+      (tramp-error v 'file-missing file))
     (if (not (file-exists-p file))
        nil
       (let ((signal-hook-function (unless noerror signal-hook-function))
@@ -4253,18 +4250,13 @@ substitution.  SPEC-LIST is a list of char/value pairs 
used for
            p))))))
 
 (defun tramp-handle-make-symbolic-link
-    (target linkname &optional ok-if-already-exists)
+    (_target linkname &optional _ok-if-already-exists)
   "Like `make-symbolic-link' for Tramp files.
 This is the fallback implementation for backends which do not
 support symbolic links."
-  (if (tramp-tramp-file-p (expand-file-name linkname))
-      (tramp-error
-       (tramp-dissect-file-name (expand-file-name linkname)) 'file-error
-       "make-symbolic-link not supported")
-    ;; This is needed prior Emacs 26.1, where TARGET has also be
-    ;; checked for a file name handler.
-    (tramp-run-real-handler
-     #'make-symbolic-link (list target linkname ok-if-already-exists))))
+  (tramp-error
+   (tramp-dissect-file-name (expand-file-name linkname)) 'file-error
+   "make-symbolic-link not supported"))
 
 (defun tramp-handle-shell-command (command &optional output-buffer 
error-buffer)
   "Like `shell-command' for Tramp files."
@@ -4482,7 +4474,7 @@ BUFFER might be a list, in this case STDERR is separated."
   (unless time-list
     (let ((remote-file-name-inhibit-cache t))
       (setq time-list
-           (or (tramp-compat-file-attribute-modification-time
+           (or (file-attribute-modification-time
                 (file-attributes (buffer-file-name)))
                tramp-time-doesnt-exist))))
   (unless (tramp-compat-time-equal-p time-list tramp-time-dont-know)
@@ -4506,7 +4498,7 @@ of."
          t
        (let* ((remote-file-name-inhibit-cache t)
               (attr (file-attributes f))
-              (modtime (tramp-compat-file-attribute-modification-time attr))
+              (modtime (file-attribute-modification-time attr))
               (mt (visited-file-modtime)))
 
          (cond
@@ -4537,11 +4529,9 @@ of."
          (tmpfile (tramp-compat-make-temp-file filename))
          (modes (tramp-default-file-modes
                  filename (and (eq mustbenew 'excl) 'nofollow)))
-         (uid (or (tramp-compat-file-attribute-user-id
-                   (file-attributes filename 'integer))
+         (uid (or (file-attribute-user-id (file-attributes filename 'integer))
                   (tramp-get-remote-uid v 'integer)))
-         (gid (or (tramp-compat-file-attribute-group-id
-                   (file-attributes filename 'integer))
+         (gid (or (file-attribute-group-id (file-attributes filename 'integer))
                   (tramp-get-remote-gid v 'integer))))
 
       ;; Lock file.
@@ -4577,8 +4567,7 @@ of."
       ;; Set file modification time.
       (when (or (eq visit t) (stringp visit))
        (set-visited-file-modtime
-        (or (tramp-compat-file-attribute-modification-time
-             (file-attributes filename))
+        (or (file-attribute-modification-time (file-attributes filename))
             (current-time))))
 
       ;; Set the ownership.
@@ -5245,7 +5234,7 @@ If FILENAME is remote, a file name handler is called."
   (let* ((dir (file-name-directory filename))
         (modes (file-modes dir)))
     (when (and modes (not (zerop (logand modes #o2000))))
-      (setq gid (tramp-compat-file-attribute-group-id (file-attributes dir)))))
+      (setq gid (file-attribute-group-id (file-attributes dir)))))
 
   (if-let ((handler (find-file-name-handler filename 'tramp-set-file-uid-gid)))
       (funcall handler #'tramp-set-file-uid-gid filename uid gid)
@@ -5274,8 +5263,7 @@ ID-FORMAT valid values are `string' and `integer'."
      ;; `group-name' has been introduced with Emacs 27.1.
      ((and (fboundp 'group-name) (equal id-format 'string))
       (tramp-compat-funcall 'group-name (group-gid)))
-     ((tramp-compat-file-attribute-group-id
-       (file-attributes "~/" id-format))))))
+     ((file-attribute-group-id (file-attributes "~/" id-format))))))
 
 (defun tramp-get-local-locale (&optional vec)
   "Determine locale, supporting UTF8 if possible.
@@ -5330,31 +5318,22 @@ be granted."
            file-attr
            (or
             ;; Not a symlink.
-            (eq t (tramp-compat-file-attribute-type file-attr))
-            (null (tramp-compat-file-attribute-type file-attr)))
+            (eq t (file-attribute-type file-attr))
+            (null (file-attribute-type file-attr)))
            (or
             ;; World accessible.
-            (eq access
-               (aref (tramp-compat-file-attribute-modes file-attr)
-                     (+ offset 6)))
+            (eq access (aref (file-attribute-modes file-attr) (+ offset 6)))
             ;; User accessible and owned by user.
             (and
-             (eq access
-                (aref (tramp-compat-file-attribute-modes file-attr) offset))
-            (or (equal remote-uid
-                       (tramp-compat-file-attribute-user-id file-attr))
-                (equal unknown-id
-                       (tramp-compat-file-attribute-user-id file-attr))))
+             (eq access (aref (file-attribute-modes file-attr) offset))
+            (or (equal remote-uid (file-attribute-user-id file-attr))
+                (equal unknown-id (file-attribute-user-id file-attr))))
             ;; Group accessible and owned by user's principal group.
             (and
              (eq access
-                (aref (tramp-compat-file-attribute-modes file-attr)
-                      (+ offset 3)))
-             (or (equal remote-gid
-                       (tramp-compat-file-attribute-group-id file-attr))
-                (equal unknown-id
-                       (tramp-compat-file-attribute-group-id
-                        file-attr))))))))))))
+                (aref (file-attribute-modes file-attr) (+ offset 3)))
+             (or (equal remote-gid (file-attribute-group-id file-attr))
+                (equal unknown-id (file-attribute-group-id 
file-attr))))))))))))
 
 (defun tramp-get-remote-uid (vec id-format)
   "The uid of the remote connection VEC, in ID-FORMAT.
@@ -5495,7 +5474,7 @@ this file, if that variable is non-nil."
        (when (and (not tramp-allow-unsafe-temporary-files)
                   auto-save-default
                   (file-in-directory-p result temporary-file-directory)
-                  (zerop (or (tramp-compat-file-attribute-user-id
+                  (zerop (or (file-attribute-user-id
                               (file-attributes filename 'integer))
                              tramp-unknown-id-integer))
                   (not (with-tramp-connection-property
@@ -5531,8 +5510,7 @@ ALIST is of the form ((FROM . TO) ...)."
 
 (defun tramp-handle-make-nearby-temp-file (prefix &optional dir-flag suffix)
   "Like `make-nearby-temp-file' for Tramp files."
-  (let ((temporary-file-directory
-        (tramp-compat-temporary-file-directory-function)))
+  (let ((temporary-file-directory (temporary-file-directory)))
     (make-temp-file prefix dir-flag suffix)))
 
 ;;; Compatibility functions section:
@@ -5702,15 +5680,12 @@ Invokes `password-read' if available, `read-passwd' 
else."
                   (setq auth-passwd (funcall auth-passwd)))
                 auth-passwd)
 
-              ;; Try the password cache.  Exists since Emacs 26.1.
+              ;; Try the password cache.
               (progn
                 (setq auth-passwd (password-read pw-prompt key)
                       tramp-password-save-function
                       (lambda () (password-cache-add key auth-passwd)))
-                auth-passwd)
-
-              ;; Else, get the password interactively w/o cache.
-              (read-passwd pw-prompt))
+                auth-passwd))
 
            ;; Workaround.  Prior Emacs 28.1, auth-source has saved
            ;; empty passwords.  See discussion in Bug#50399.
@@ -5822,13 +5797,11 @@ name of a process or buffer, or nil to default to the 
current buffer."
         (while (tramp-accept-process-output proc 0))
        (not (process-live-p proc))))))
 
-;; `interrupt-process-functions' exists since Emacs 26.1.
-(when (boundp 'interrupt-process-functions)
-  (add-hook 'interrupt-process-functions #'tramp-interrupt-process)
-  (add-hook
-   'tramp-unload-hook
-   (lambda ()
-     (remove-hook 'interrupt-process-functions #'tramp-interrupt-process))))
+(add-hook 'interrupt-process-functions #'tramp-interrupt-process)
+(add-hook
+ 'tramp-unload-hook
+ (lambda ()
+   (remove-hook 'interrupt-process-functions #'tramp-interrupt-process)))
 
 (defun tramp-get-remote-null-device (vec)
   "Return null device on the remote host identified by VEC.
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index 8baf078..226e9a3 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -7,8 +7,8 @@
 ;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
 ;; Keywords: comm, processes
 ;; Package: tramp
-;; Version: 2.5.2-pre
-;; Package-Requires: ((emacs "25.1"))
+;; Version: 2.6.0-pre
+;; Package-Requires: ((emacs "26.1"))
 ;; Package-Type: multi
 ;; URL: https://www.gnu.org/software/tramp/
 
@@ -40,7 +40,7 @@
 ;; ./configure" to change them.
 
 ;;;###tramp-autoload
-(defconst tramp-version "2.5.2-pre"
+(defconst tramp-version "2.6.0-pre"
   "This version of Tramp.")
 
 ;;;###tramp-autoload
@@ -74,9 +74,9 @@
   "The repository revision of the Tramp sources.")
 
 ;; Check for Emacs version.
-(let ((x   (if (not (string-lessp emacs-version "25.1"))
+(let ((x   (if (not (string-version-lessp emacs-version "26.1"))
       "ok"
-    (format "Tramp 2.5.2-pre is not fit for %s"
+    (format "Tramp 2.6.0-pre is not fit for %s"
             (replace-regexp-in-string "\n" "" (emacs-version))))))
   (unless (string-equal "ok" x) (error "%s" x)))
 
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index c6b6be5..4d51883 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -444,17 +444,19 @@ STYLE using `c-set-style' if the optional SET-P flag is 
non-nil."
                          defstr))
         (prompt (concat symname " offset " defstr))
         (keymap (make-sparse-keymap))
-        (minibuffer-completion-table obarray)
-        (minibuffer-completion-predicate 'fboundp)
         offset input)
     ;; In principle completing-read is used here, but SPC is unbound
     ;; to make it less annoying to enter lists.
     (set-keymap-parent keymap minibuffer-local-completion-map)
     (define-key keymap " " 'self-insert-command)
     (while (not offset)
-      (setq input (read-from-minibuffer prompt nil keymap t
-                                       'c-read-offset-history
-                                       (format "%s" oldoff)))
+      (minibuffer-with-setup-hook
+          (lambda ()
+            (setq-local minibuffer-completion-table obarray)
+            (setq-local minibuffer-completion-predicate 'fboundp))
+        (setq input (read-from-minibuffer prompt nil keymap t
+                                          'c-read-offset-history
+                                          (format "%s" oldoff))))
       (if (c-valid-offset input)
          (setq offset input)
        ;; error, but don't signal one, keep trying
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 403925c..4f9506c 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -332,7 +332,7 @@ retrieval with `flymake-diagnostic-data'.
 If LOCUS is a buffer BEG and END should be buffer positions
 inside it.  If LOCUS designates a file, BEG and END should be a
 cons (LINE . COL) indicating a file position.  In this second
-case, END may be ommited in which case the region is computed
+case, END may be omitted in which case the region is computed
 using `flymake-diag-region' if the diagnostic is appended to an
 actual buffer.
 
@@ -870,7 +870,7 @@ and other buffers."
   (dolist (d diags) (setf (flymake--diag-backend d) backend))
   (save-restriction
     (widen)
-    ;; First, clean up.  Remove diagnostics from bookeeping lists and
+    ;; First, clean up.  Remove diagnostics from bookkeeping lists and
     ;; their overlays from buffers.
     ;;
     (cond
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 26188bb..edb98aa 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1028,7 +1028,7 @@ GROUP is a string for decoration purposes and XREF is an
   (run-hooks 'xref-after-update-hook))
 
 (defun xref--group-name-for-display (group project-root)
-  "Return GROUP formatted in the prefered style.
+  "Return GROUP formatted in the preferred style.
 
 The style is determined by the value of `xref-file-name-display'.
 If GROUP looks like a file name, its value is formatted according
diff --git a/lisp/saveplace.el b/lisp/saveplace.el
index 4191a3f..3eff816 100644
--- a/lisp/saveplace.el
+++ b/lisp/saveplace.el
@@ -328,11 +328,18 @@ may have changed) back to `save-place-alist'."
       (with-current-buffer (car buf-list)
        ;; save-place checks buffer-file-name too, but we can avoid
        ;; overhead of function call by checking here too.
-       (and (or buffer-file-name (and (derived-mode-p 'dired-mode)
-                                       (boundp 'dired-subdir-alist)
-                                      dired-subdir-alist
-                                      (dired-current-directory)))
-            (save-place-to-alist))
+       (when (and (or buffer-file-name
+                       (and (derived-mode-p 'dired-mode)
+                            (boundp 'dired-subdir-alist)
+                           dired-subdir-alist
+                           (dired-current-directory)))
+                   ;; Don't save place in literally-visited file
+                   ;; because this will commonly differ from the place
+                   ;; when visiting literally (and
+                   ;; `find-file-literally' always places point at the
+                   ;; start of the buffer).
+                   (not find-file-literally))
+         (save-place-to-alist))
        (setq buf-list (cdr buf-list))))))
 
 (defun save-place-find-file-hook ()
diff --git a/lisp/select.el b/lisp/select.el
index a77a005..5e7f4a6 100644
--- a/lisp/select.el
+++ b/lisp/select.el
@@ -307,7 +307,10 @@ the formats available in the clipboard if TYPE is 
`CLIPBOARD'."
   (let ((data (gui-backend-get-selection (or type 'PRIMARY)
                                          (or data-type 'STRING))))
     (when (and (stringp data)
-              (setq data-type (get-text-property 0 'foreign-selection data)))
+               ;; If this text property is set, then the data needs to
+               ;; be decoded -- otherwise it has already been decoded
+               ;; by the lower level functions.
+               (get-text-property 0 'foreign-selection data))
       (let ((coding (or next-selection-coding-system
                         selection-coding-system
                         (pcase data-type
@@ -315,15 +318,22 @@ the formats available in the clipboard if TYPE is 
`CLIPBOARD'."
                           ('text/plain\;charset=utf-8 'utf-8)
                           ('COMPOUND_TEXT 'compound-text-with-extensions)
                           ('C_STRING nil)
-                          ('STRING 'iso-8859-1)
-                          (_ (error "Unknown selection data type: %S"
-                                    type))))))
-        (setq data (if coding (decode-coding-string data coding)
-                     ;; This is for C_STRING case.
+                          ('STRING 'iso-8859-1)))))
+        (setq data
+              (cond (coding (decode-coding-string data coding))
                      ;; We want to convert each non-ASCII byte to the
                      ;; corresponding eight-bit character, which has
                      ;; a codepoint >= #x3FFF00.
-                     (string-to-multibyte data))))
+                    ((eq data-type 'C_STRING)
+                     (string-to-multibyte data))
+                    ;; Guess at the charset for types like text/html
+                    ;; -- it can be anything, and different
+                    ;; applications use different encodings.
+                    ((string-match-p "\\`text/" (symbol-name data-type))
+                     (decode-coding-string
+                      data (car (detect-coding-string data))))
+                    ;; Do nothing.
+                    (t data))))
       (setq next-selection-coding-system nil)
       (put-text-property 0 (length data) 'foreign-selection data-type data))
     data))
diff --git a/lisp/server.el b/lisp/server.el
index 947311a..d510df1 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1721,6 +1721,9 @@ be a cons cell (LINENUMBER . COLUMNNUMBER)."
     (when server-raise-frame
       (select-frame-set-input-focus (window-frame)))))
 
+(defvar server-stop-automatically nil
+  "Internal status variable for `server-stop-automatically'.")
+
 ;;;###autoload
 (defun server-save-buffers-kill-terminal (arg)
   ;; Called from save-buffers-kill-terminal in files.el.
@@ -1729,27 +1732,103 @@ With ARG non-nil, silently save all file-visiting 
buffers, then kill.
 
 If emacsclient was started with a list of filenames to edit, then
 only these files will be asked to be saved."
-  (let ((proc (frame-parameter nil 'client)))
-    (cond ((eq proc 'nowait)
-          ;; Nowait frames have no client buffer list.
-          (if (cdr (frame-list))
-              (progn (save-some-buffers arg)
-                     (delete-frame))
-            ;; If we're the last frame standing, kill Emacs.
-            (save-buffers-kill-emacs arg)))
-         ((processp proc)
-          (let ((buffers (process-get proc 'buffers)))
-            (save-some-buffers
-             arg (if buffers
-                      ;; Only files from emacsclient file list.
-                     (lambda () (memq (current-buffer) buffers))
-                    ;; No emacsclient file list: don't override
-                    ;; `save-some-buffers-default-predicate' (unless
-                    ;; ARG is non-nil), since we're not killing
-                    ;; Emacs (unlike `save-buffers-kill-emacs').
-                   (and arg t)))
-            (server-delete-client proc)))
-         (t (error "Invalid client frame")))))
+  (if server-stop-automatically
+      (server-stop-automatically--handle-delete-frame (selected-frame))
+    (let ((proc (frame-parameter nil 'client)))
+      (cond ((eq proc 'nowait)
+            ;; Nowait frames have no client buffer list.
+            (if (cdr (frame-list))
+                (progn (save-some-buffers arg)
+                       (delete-frame))
+              ;; If we're the last frame standing, kill Emacs.
+              (save-buffers-kill-emacs arg)))
+           ((processp proc)
+            (let ((buffers (process-get proc 'buffers)))
+              (save-some-buffers
+               arg (if buffers
+                        ;; Only files from emacsclient file list.
+                       (lambda () (memq (current-buffer) buffers))
+                      ;; No emacsclient file list: don't override
+                      ;; `save-some-buffers-default-predicate' (unless
+                      ;; ARG is non-nil), since we're not killing
+                      ;; Emacs (unlike `save-buffers-kill-emacs').
+                     (and arg t)))
+              (server-delete-client proc)))
+           (t (error "Invalid client frame"))))))
+
+(defun server-stop-automatically--handle-delete-frame (frame)
+  "Handle deletion of FRAME when `server-stop-automatically' is used."
+  (when server-stop-automatically
+    (if (if (and (processp (frame-parameter frame 'client))
+                (eq this-command 'save-buffers-kill-terminal))
+           (progn
+             (dolist (f (frame-list))
+               (when (and (eq (frame-parameter frame 'client)
+                              (frame-parameter f 'client))
+                          (not (eq frame f)))
+                 (set-frame-parameter f 'client nil)
+                 (let ((server-stop-automatically nil))
+                   (delete-frame f))))
+             (if (cddr (frame-list))
+                 (let ((server-stop-automatically nil))
+                   (delete-frame frame)
+                   nil)
+               t))
+         (null (cddr (frame-list))))
+       (let ((server-stop-automatically nil))
+         (save-buffers-kill-emacs)
+         (delete-frame frame)))))
+
+(defun server-stop-automatically--maybe-kill-emacs ()
+  "Handle closing of Emacs daemon when `server-stop-automatically' is used."
+  (unless (cdr (frame-list))
+    (when (and
+          (not (memq t (mapcar (lambda (b)
+                                 (and (buffer-file-name b)
+                                      (buffer-modified-p b)))
+                               (buffer-list))))
+          (not (memq t (mapcar (lambda (p)
+                                 (and (memq (process-status p)
+                                            '(run stop open listen))
+                                      (process-query-on-exit-flag p)))
+                               (process-list)))))
+      (kill-emacs))))
+
+;;;###autoload
+(defun server-stop-automatically (arg)
+  "Automatically stop server as specified by ARG.
+
+If ARG is the symbol `empty', stop the server when it has no
+remaining clients, no remaining unsaved file-visiting buffers,
+and no running processes with a `query-on-exit' flag.
+
+If ARG is the symbol `delete-frame', ask the user when the last
+frame is deleted whether each unsaved file-visiting buffer must
+be saved and each running process with a `query-on-exit' flag
+can be stopped, and if so, stop the server itself.
+
+If ARG is the symbol `kill-terminal', ask the user when the
+terminal is killed with \\[save-buffers-kill-terminal] \
+whether each unsaved file-visiting
+buffer must be saved and each running process with a `query-on-exit'
+flag can be stopped, and if so, stop the server itself.
+
+Any other value of ARG will cause this function to signal an error.
+
+This function is meant to be called from the user init file."
+  (when (daemonp)
+    (setq server-stop-automatically arg)
+    (cond
+     ((eq arg 'empty)
+      (setq server-stop-automatically nil)
+      (run-with-timer 10 2
+                     #'server-stop-automatically--maybe-kill-emacs))
+     ((eq arg 'delete-frame)
+      (add-hook 'delete-frame-functions
+               #'server-stop-automatically--handle-delete-frame))
+     ((eq arg 'kill-terminal))
+     (t
+      (error "Unexpected argument")))))
 
 (define-key ctl-x-map "#" 'server-edit)
 
diff --git a/lisp/startup.el b/lisp/startup.el
index 8025321..98843e5 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -2528,7 +2528,15 @@ nil default-directory" name)
                      (let* ((file (command-line-normalize-file-name
                                    (or argval (pop command-line-args-left))))
                             ;; Take file from default dir.
-                            (file-ex (file-truename (expand-file-name file))))
+                            (file-ex (expand-file-name file))
+                            (truename (file-truename file-ex)))
+                       ;; We want to use the truename here if we can,
+                       ;; because that makes `eval-after-load' work
+                       ;; more reliably.  But if the file is, for
+                       ;; instance, /dev/stdin, the truename doesn't
+                       ;; actually exist on some systems.
+                       (when (file-exists-p truename)
+                         (setq file-ex truename))
                        (load file-ex nil t t)))
 
                     ((equal argi "-insert")
diff --git a/lisp/subr.el b/lisp/subr.el
index 5a5842d..3902251 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -2042,7 +2042,7 @@ performance impact when running `add-hook' and 
`remove-hook'."
       (when (or (get hook 'hook--depth-alist) (not (zerop depth)))
         ;; Note: The main purpose of the above `when' test is to avoid running
         ;; this `setf' before `gv' is loaded during bootstrap.
-        (push (cons function depth) (get hook 'hook--depth-alist)))
+        (setf (alist-get function (get hook 'hook--depth-alist) 0) depth))
       (setq hook-value
            (if (< 0 depth)
                (append hook-value (list function))
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 3f89fad..2d35061 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -1256,7 +1256,10 @@ log entries."
 
 (defun vc-git-mergebase (rev1 &optional rev2)
   (unless rev2 (setq rev2 "HEAD"))
-  (string-trim-right (vc-git--run-command-string nil "merge-base" rev1 rev2)))
+  (let ((base (vc-git--run-command-string nil "merge-base" rev1 rev2)))
+    (if base
+        (string-trim-right base)
+      (error "No common ancestor for merge base"))))
 
 (defvar log-view-message-re)
 (defvar log-view-file-re)
diff --git a/lisp/window.el b/lisp/window.el
index 2582743..0f17bb2 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -8574,7 +8574,7 @@ from the list of completions and default values."
   (let ((rbts-completion-table (internal-complete-buffer-except)))
     (minibuffer-with-setup-hook
         (lambda ()
-          (setq minibuffer-completion-table rbts-completion-table)
+          (setq-local minibuffer-completion-table rbts-completion-table)
           ;; Since rbts-completion-table is built dynamically, we
           ;; can't just add it to the default value of
           ;; icomplete-with-completion-tables, so we add it
diff --git a/lisp/xdg.el b/lisp/xdg.el
index 05fc3d7..6055898 100644
--- a/lisp/xdg.el
+++ b/lisp/xdg.el
@@ -121,7 +121,7 @@ According to the XDG Base Directory Specification version
     \"$XDG_CONFIG_DIRS defines the preference-ordered set of base
     directories to search for configuration files in addition to
     the $XDG_CONFIG_HOME base directory.  The directories in
-    $XDG_CONFIG_DIRS should be seperated with a colon ':'.
+    $XDG_CONFIG_DIRS should be separated with a colon ':'.
 
     \"If $XDG_CONFIG_DIRS is either not set or empty, a value equal to
     /etc/xdg should be used.\""
@@ -139,7 +139,7 @@ According to the XDG Base Directory Specification version
     \"$XDG_DATA_DIRS defines the preference-ordered set of base
     directories to search for data files in addition to the
     $XDG_DATA_HOME base directory.  The directories in
-    $XDG_DATA_DIRS should be seperated with a colon ':'.
+    $XDG_DATA_DIRS should be separated with a colon ':'.
 
     \"If $XDG_DATA_DIRS is either not set or empty, a value equal
     to /usr/local/share/:/usr/share/ should be used.\""
diff --git a/lisp/xwidget.el b/lisp/xwidget.el
index cc149cf..485d995 100644
--- a/lisp/xwidget.el
+++ b/lisp/xwidget.el
@@ -33,6 +33,7 @@
 
 (require 'cl-lib)
 (require 'bookmark)
+(require 'format-spec)
 
 (declare-function make-xwidget "xwidget.c"
                   (type title width height arguments &optional buffer related))
@@ -95,8 +96,12 @@ This returns the result of `make-xwidget'."
   :group 'web
   :prefix "xwidget-webkit-")
 
-(defcustom xwidget-webkit-buffer-name-prefix "*xwidget-webkit: "
-  "Buffer name prefix used by `xwidget-webkit' buffers."
+(defcustom xwidget-webkit-buffer-name-format "*xwidget-webkit: %T*"
+  "Template for naming `xwidget-webkit' buffers.
+It can use the following special constructs:
+
+  %T -- the title of the Web page loaded by the xwidget.
+  %U -- the URI of the Web page loaded by the xwidget."
   :type 'string
   :version "29.1")
 
@@ -141,11 +146,36 @@ in `split-window-right' with a new xwidget webkit 
session."
 
 (declare-function xwidget-perform-lispy-event "xwidget.c")
 
+(defvar xwidget-webkit--input-method-events nil
+  "Internal variable used to store input method events.")
+
+(defun xwidget-webkit-pass-command-event-with-input-method ()
+  "Handle a `with-input-method' event."
+  (interactive)
+  (let ((key (pop unread-command-events)))
+    (setq xwidget-webkit--input-method-events
+          (funcall input-method-function key))
+    (exit-minibuffer)))
+
 (defun xwidget-webkit-pass-command-event ()
-  "Pass `last-command-event' to the current buffer's WebKit widget."
+  "Pass `last-command-event' to the current buffer's WebKit widget.
+If `current-input-method' is non-nil, consult `input-method-function'
+for the actual events that will be sent."
   (interactive)
-  (xwidget-perform-lispy-event (xwidget-webkit-current-session)
-                               last-command-event))
+  (if (and current-input-method
+           (characterp last-command-event))
+      (let ((xwidget-webkit--input-method-events nil)
+            (minibuffer-local-map (make-keymap)))
+        (define-key minibuffer-local-map [with-input-method]
+          'xwidget-webkit-pass-command-event-with-input-method)
+        (push last-command-event unread-command-events)
+        (push 'with-input-method unread-command-events)
+        (read-from-minibuffer "" nil nil nil nil nil t)
+        (dolist (event xwidget-webkit--input-method-events)
+          (xwidget-perform-lispy-event (xwidget-webkit-current-session)
+                                       event)))
+    (xwidget-perform-lispy-event (xwidget-webkit-current-session)
+                                 last-command-event)))
 
 ;;todo.
 ;; - check that the webkit support is compiled in
@@ -358,7 +388,8 @@ XWIDGET instance, XWIDGET-EVENT-TYPE depends on the 
originating xwidget."
       (xwidget-log
        "error: callback called for xwidget with dead buffer")
     (cond ((eq xwidget-event-type 'load-changed)
-           (let ((title (xwidget-webkit-title xwidget)))
+           (let ((title (xwidget-webkit-title xwidget))
+                 (uri (xwidget-webkit-uri xwidget)))
              ;; This funciton will be called multi times, so only
              ;; change buffer name when the load actually completes
              ;; this can limit buffer-name flicker in mode-line.
@@ -372,9 +403,12 @@ XWIDGET instance, XWIDGET-EVENT-TYPE depends on the 
originating xwidget."
                  ;; Do not adjust webkit size to window here, the
                  ;; selected window can be the mini-buffer window
                  ;; unwantedly.
-                 (rename-buffer (concat xwidget-webkit-buffer-name-prefix
-                                        title "*")
-                                t)))))
+                 (rename-buffer
+                  (format-spec
+                   xwidget-webkit-buffer-name-format
+                   `((?T . ,title)
+                     (?U . ,uri)))
+                  t)))))
           ((eq xwidget-event-type 'decide-policy)
            (let ((strarg  (nth 3 last-input-event)))
              (if (string-match ".*#\\(.*\\)" strarg)
@@ -762,7 +796,8 @@ Return the buffer."
   "Goto URL with xwidget webkit."
   (if (xwidget-webkit-current-session)
       (progn
-        (xwidget-webkit-goto-uri (xwidget-webkit-current-session) url))
+        (xwidget-webkit-goto-uri (xwidget-webkit-current-session) url)
+        (switch-to-buffer (xwidget-buffer (xwidget-webkit-current-session))))
     (xwidget-webkit-new-session url)))
 
 (defun xwidget-webkit-back ()
@@ -863,6 +898,8 @@ WebKit widget."
   "The current search query.")
 (defvar-local xwidget-webkit-isearch--is-reverse nil
   "Whether or not the current isearch should be reverse.")
+(defvar xwidget-webkit-isearch--read-string-buffer nil
+  "The buffer we are reading input method text for, if any.")
 
 (defun xwidget-webkit-isearch--update (&optional only-message)
   "Update the current buffer's WebKit widget's search query.
@@ -873,8 +910,9 @@ WebKit widget.  The query will be set to the contents of
     (xwidget-webkit-search xwidget-webkit-isearch--string
                            (xwidget-webkit-current-session)
                            t xwidget-webkit-isearch--is-reverse t))
-  (message (concat (propertize "Search contents: " 'face 'minibuffer-prompt)
-                   xwidget-webkit-isearch--string)))
+  (let ((message-log-max nil))
+    (message (concat (propertize "Search contents: " 'face 'minibuffer-prompt)
+                     xwidget-webkit-isearch--string))))
 
 (defun xwidget-webkit-isearch-erasing-char (count)
   "Erase the last COUNT characters of the current query."
@@ -885,13 +923,43 @@ WebKit widget.  The query will be set to the contents of
                      (- (length xwidget-webkit-isearch--string) count))))
   (xwidget-webkit-isearch--update))
 
+(defun xwidget-webkit-isearch-with-input-method ()
+  "Handle a request to use the input method to modify the search query."
+  (interactive)
+  (let ((key (car unread-command-events))
+       events)
+    (setq unread-command-events (cdr unread-command-events)
+         events (funcall input-method-function key))
+    (dolist (k events)
+      (with-current-buffer xwidget-webkit-isearch--read-string-buffer
+        (setq xwidget-webkit-isearch--string
+              (concat xwidget-webkit-isearch--string
+                      (char-to-string k)))))
+    (exit-minibuffer)))
+
+(defun xwidget-webkit-isearch-printing-char-with-input-method (char)
+  "Handle printing char CHAR with the current input method."
+  (let ((minibuffer-local-map (make-keymap))
+        (xwidget-webkit-isearch--read-string-buffer (current-buffer)))
+    (define-key minibuffer-local-map [with-input-method]
+      'xwidget-webkit-isearch-with-input-method)
+    (setq unread-command-events
+          (cons 'with-input-method
+                (cons char unread-command-events)))
+    (read-string "Search contents: "
+                 xwidget-webkit-isearch--string
+                 'junk-hist nil t)
+    (xwidget-webkit-isearch--update)))
+
 (defun xwidget-webkit-isearch-printing-char (char &optional count)
   "Add ordinary character CHAR to the search string and search.
 With argument, add COUNT copies of CHAR."
   (interactive (list last-command-event
                      (prefix-numeric-value current-prefix-arg)))
-  (setq xwidget-webkit-isearch--string (concat xwidget-webkit-isearch--string
-                                               (make-string (or count 1) 
char)))
+  (if current-input-method
+      (xwidget-webkit-isearch-printing-char-with-input-method char)
+    (setq xwidget-webkit-isearch--string (concat xwidget-webkit-isearch--string
+                                                 (make-string (or count 1) 
char))))
   (xwidget-webkit-isearch--update))
 
 (defun xwidget-webkit-isearch-forward (count)
@@ -948,6 +1016,7 @@ With argument, add COUNT copies of CHAR."
 (define-key xwidget-webkit-isearch-mode-map "\C-r" 
'xwidget-webkit-isearch-backward)
 (define-key xwidget-webkit-isearch-mode-map "\C-s" 
'xwidget-webkit-isearch-forward)
 (define-key xwidget-webkit-isearch-mode-map "\C-y" 
'xwidget-webkit-isearch-yank-kill)
+(define-key xwidget-webkit-isearch-mode-map "\C-\\" 'toggle-input-method)
 (define-key xwidget-webkit-isearch-mode-map "\t" 
'xwidget-webkit-isearch-printing-char)
 
 (let ((meta-map (make-keymap)))
@@ -982,7 +1051,7 @@ Press 
\\<xwidget-webkit-isearch-mode-map>\\[xwidget-webkit-isearch-exit] to exit
     (xwidget-webkit-finish-search (xwidget-webkit-current-session))))
 
 (defun xwidget-webkit-isearch-yank-kill ()
-  "Pull string from kill ring and append it to the current query."
+  "Append the most recent kill from `kill-ring' to the current query."
   (interactive)
   (unless xwidget-webkit-isearch-mode
     (xwidget-webkit-isearch-mode t))
diff --git a/src/ChangeLog.11 b/src/ChangeLog.11
index 41c35ba..cf5e7b7 100644
--- a/src/ChangeLog.11
+++ b/src/ChangeLog.11
@@ -22399,7 +22399,7 @@
        * Makefile.in (${lispsource}international/charprop.el):
        Delete this target.
 
-       * search.c (boyer_moore): Fix incorrect synching of the trunk and
+       * search.c (boyer_moore): Fix incorrect syncing of the trunk and
        emacs-unicode-2.
 
 2008-02-11  Stefan Monnier  <monnier@iro.umontreal.ca>
@@ -23177,7 +23177,7 @@
 2008-02-01  Kenichi Handa  <handa@ni.aist.go.jp>
 
        * xfaces.c (face_for_overlay_string): Call lookup_face with
-       correct arguments (fix of synching with the trunk).
+       correct arguments (fix of syncing with the trunk).
 
 2008-02-01  Kenichi Handa  <handa@m17n.org>
 
diff --git a/src/atimer.c b/src/atimer.c
index 490c21b..9bde9c2 100644
--- a/src/atimer.c
+++ b/src/atimer.c
@@ -316,6 +316,13 @@ set_alarm (void)
              exit = true;
            }
 # endif
+
+# ifdef CYGWIN
+         /* Don't start both timerfd and alarms on Cygwin; this
+            causes a slowdown (bug#51734). */
+         if (exit)
+           return;
+# endif
          if (alarm_timer_ok
              && timer_settime (alarm_timer, TIMER_ABSTIME, &ispec, 0) == 0)
            exit = true;
diff --git a/src/callproc.c b/src/callproc.c
index fa43f97..c949fff 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -28,6 +28,20 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include <sys/file.h>
 #include <fcntl.h>
 
+/* In order to be able to use `posix_spawn', it needs to support some
+   variant of `chdir' as well as `setsid'.  */
+#if defined HAVE_SPAWN_H && defined HAVE_POSIX_SPAWN        \
+  && defined HAVE_POSIX_SPAWNATTR_SETFLAGS                  \
+  && (defined HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR        \
+      || defined HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR_NP) \
+  && defined HAVE_DECL_POSIX_SPAWN_SETSID                   \
+  && HAVE_DECL_POSIX_SPAWN_SETSID == 1
+# include <spawn.h>
+# define USABLE_POSIX_SPAWN 1
+#else
+# define USABLE_POSIX_SPAWN 0
+#endif
+
 #include "lisp.h"
 
 #ifdef SETUP_SLAVE_PTY
@@ -1247,6 +1261,130 @@ child_setup (int in, int out, int err, char **new_argv, 
char **env,
 #endif  /* not WINDOWSNT */
 }
 
+#if USABLE_POSIX_SPAWN
+
+/* Set up ACTIONS and ATTRIBUTES for `posix_spawn'.  Return an error
+   number.  */
+
+static int
+emacs_posix_spawn_init_actions (posix_spawn_file_actions_t *actions,
+                                int std_in, int std_out, int std_err,
+                                const char *cwd)
+{
+  int error = posix_spawn_file_actions_init (actions);
+  if (error != 0)
+    return error;
+
+  error = posix_spawn_file_actions_adddup2 (actions, std_in,
+                                            STDIN_FILENO);
+  if (error != 0)
+    goto out;
+
+  error = posix_spawn_file_actions_adddup2 (actions, std_out,
+                                            STDOUT_FILENO);
+  if (error != 0)
+    goto out;
+
+  error = posix_spawn_file_actions_adddup2 (actions,
+                                            std_err < 0 ? std_out
+                                                        : std_err,
+                                            STDERR_FILENO);
+  if (error != 0)
+    goto out;
+
+  error =
+#ifdef HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR
+    posix_spawn_file_actions_addchdir
+#else
+    posix_spawn_file_actions_addchdir_np
+#endif
+    (actions, cwd);
+  if (error != 0)
+    goto out;
+
+ out:
+  if (error != 0)
+    posix_spawn_file_actions_destroy (actions);
+  return error;
+}
+
+static int
+emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes)
+{
+  int error = posix_spawnattr_init (attributes);
+  if (error != 0)
+    return error;
+
+  error = posix_spawnattr_setflags (attributes,
+                                    POSIX_SPAWN_SETSID
+                                      | POSIX_SPAWN_SETSIGDEF
+                                      | POSIX_SPAWN_SETSIGMASK);
+  if (error != 0)
+    goto out;
+
+  sigset_t sigdefault;
+  sigemptyset (&sigdefault);
+
+#ifdef DARWIN_OS
+  /* Work around a macOS bug, where SIGCHLD is apparently
+     delivered to a vforked child instead of to its parent.  See:
+     https://lists.gnu.org/r/emacs-devel/2017-05/msg00342.html
+  */
+  sigaddset (&sigdefault, SIGCHLD);
+#endif
+
+  sigaddset (&sigdefault, SIGINT);
+  sigaddset (&sigdefault, SIGQUIT);
+#ifdef SIGPROF
+  sigaddset (&sigdefault, SIGPROF);
+#endif
+
+  /* Emacs ignores SIGPIPE, but the child should not.  */
+  sigaddset (&sigdefault, SIGPIPE);
+  /* Likewise for SIGPROF.  */
+#ifdef SIGPROF
+  sigaddset (&sigdefault, SIGPROF);
+#endif
+
+  error = posix_spawnattr_setsigdefault (attributes, &sigdefault);
+  if (error != 0)
+    goto out;
+
+  /* Stop blocking SIGCHLD in the child.  */
+  sigset_t oldset;
+  error = pthread_sigmask (SIG_SETMASK, NULL, &oldset);
+  if (error != 0)
+    goto out;
+  error = posix_spawnattr_setsigmask (attributes, &oldset);
+  if (error != 0)
+    goto out;
+
+ out:
+  if (error != 0)
+    posix_spawnattr_destroy (attributes);
+
+  return error;
+}
+
+static int
+emacs_posix_spawn_init (posix_spawn_file_actions_t *actions,
+                        posix_spawnattr_t *attributes, int std_in,
+                        int std_out, int std_err, const char *cwd)
+{
+  int error = emacs_posix_spawn_init_actions (actions, std_in,
+                                              std_out, std_err, cwd);
+  if (error != 0)
+    return error;
+
+  error = emacs_posix_spawn_init_attributes (attributes);
+  if (error != 0)
+    return error;
+
+  return 0;
+}
+
+#endif
+
 /* Start a new asynchronous subprocess.  If successful, return zero
    and store the process identifier of the new process in *NEWPID.
    Use STDIN, STDOUT, and STDERR as standard streams for the new
@@ -1266,10 +1404,58 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, 
int std_err,
              char **argv, char **envp, const char *cwd,
              const char *pty, const sigset_t *oldset)
 {
+#if USABLE_POSIX_SPAWN
+  /* Prefer the simpler `posix_spawn' if available.  `posix_spawn'
+     doesn't yet support setting up pseudoterminals, so we fall back
+     to `vfork' if we're supposed to use a pseudoterminal.  */
+
+  bool use_posix_spawn = pty == NULL;
+
+  posix_spawn_file_actions_t actions;
+  posix_spawnattr_t attributes;
+
+  if (use_posix_spawn)
+    {
+      /* Initialize optional attributes before blocking. */
+      int error
+        = emacs_posix_spawn_init (&actions, &attributes, std_in,
+                                  std_out, std_err, cwd);
+      if (error != 0)
+       return error;
+    }
+#endif
+
   int pid;
+  int vfork_error;
 
   eassert (input_blocked_p ());
 
+#if USABLE_POSIX_SPAWN
+  if (use_posix_spawn)
+    {
+      vfork_error = posix_spawn (&pid, argv[0], &actions, &attributes,
+                                 argv, envp);
+      if (vfork_error != 0)
+       pid = -1;
+
+      int error = posix_spawn_file_actions_destroy (&actions);
+      if (error != 0)
+       {
+         errno = error;
+         emacs_perror ("posix_spawn_file_actions_destroy");
+       }
+
+      error = posix_spawnattr_destroy (&attributes);
+      if (error != 0)
+       {
+         errno = error;
+         emacs_perror ("posix_spawnattr_destroy");
+       }
+
+      goto fork_done;
+    }
+#endif
+
 #ifndef WINDOWSNT
   /* vfork, and prevent local vars from being clobbered by the vfork.  */
   pid_t *volatile newpid_volatile = newpid;
@@ -1413,8 +1599,11 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int 
std_err,
 
   /* Back in the parent process.  */
 
-  int vfork_error = pid < 0 ? errno : 0;
+  vfork_error = pid < 0 ? errno : 0;
 
+#if USABLE_POSIX_SPAWN
+ fork_done:
+#endif
   if (pid < 0)
     {
       eassert (0 < vfork_error);
diff --git a/src/coding.c b/src/coding.c
index 7030a53..02dccf5 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -9455,11 +9455,12 @@ code_convert_region (Lisp_Object start, Lisp_Object end,
 DEFUN ("decode-coding-region", Fdecode_coding_region, Sdecode_coding_region,
        3, 4, "r\nzCoding system: ",
        doc: /* Decode the current region from the specified coding system.
+Interactively, prompt for the coding system to decode the region.
 
-What's meant by \"decoding\" is transforming bytes into text
-(characters).  If, for instance, you have a region that contains data
-that represents the two bytes #xc2 #xa9, after calling this function
-with the utf-8 coding system, the region will contain the single
+\"Decoding\" means transforming bytes into readable text (characters).
+If, for instance, you have a region that contains data that represents
+the two bytes #xc2 #xa9, after calling this function with the utf-8
+coding system, the region will contain the single
 character ?\\N{COPYRIGHT SIGN}.
 
 When called from a program, takes four arguments:
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index bb17241..49c3dab 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -60,92 +60,6 @@ EMACS_FIXED (GtkWidget *widget)
                                     EmacsFixed);
 }
 
-#ifdef HAVE_XWIDGETS
-
-static EmacsFixedClass *
-EMACS_FIXED_GET_CLASS (GtkWidget *widget)
-{
-  return G_TYPE_INSTANCE_GET_CLASS (widget, emacs_fixed_get_type (),
-                                   EmacsFixedClass);
-}
-
-struct GtkFixedPrivateL
-{
-  GList *children;
-};
-
-static void
-emacs_fixed_gtk_widget_size_allocate (GtkWidget *widget,
-                                     GtkAllocation *allocation)
-{
-  /* For xwidgets.
-
-     This basically re-implements the base class method and adds an
-     additional case for an xwidget view.
-
-     It would be nicer if the bse class method could be called first,
-     and the xview modification only would remain here. It wasn't
-     possible to solve it that way yet.  */
-  EmacsFixedClass *klass;
-  GtkWidgetClass *parent_class;
-  struct GtkFixedPrivateL *priv;
-
-  klass = EMACS_FIXED_GET_CLASS (widget);
-  parent_class = g_type_class_peek_parent (klass);
-  parent_class->size_allocate (widget, allocation);
-
-  priv = G_TYPE_INSTANCE_GET_PRIVATE (widget, GTK_TYPE_FIXED,
-                                     struct GtkFixedPrivateL);
-
-  gtk_widget_set_allocation (widget, allocation);
-
-  if (gtk_widget_get_has_window (widget))
-    {
-      if (gtk_widget_get_realized (widget))
-        gdk_window_move_resize (gtk_widget_get_window (widget),
-                                allocation->x,
-                                allocation->y,
-                                allocation->width,
-                                allocation->height);
-    }
-
-  for (GList *children = priv->children; children; children = children->next)
-    {
-      GtkFixedChild *child = children->data;
-
-      if (!gtk_widget_get_visible (child->widget))
-        continue;
-
-      GtkRequisition child_requisition;
-      gtk_widget_get_preferred_size (child->widget, &child_requisition, NULL);
-
-      GtkAllocation child_allocation;
-      child_allocation.x = child->x;
-      child_allocation.y = child->y;
-
-      if (!gtk_widget_get_has_window (widget))
-        {
-          child_allocation.x += allocation->x;
-          child_allocation.y += allocation->y;
-        }
-
-      child_allocation.width = child_requisition.width;
-      child_allocation.height = child_requisition.height;
-
-      struct xwidget_view *xv
-        = g_object_get_data (G_OBJECT (child->widget), XG_XWIDGET_VIEW);
-      if (xv)
-        {
-          child_allocation.width = xv->clip_right;
-          child_allocation.height = xv->clip_bottom - xv->clip_top;
-        }
-
-      gtk_widget_size_allocate (child->widget, &child_allocation);
-    }
-}
-
-#endif  /* HAVE_XWIDGETS */
-
 static void
 emacs_fixed_class_init (EmacsFixedClass *klass)
 {
@@ -155,9 +69,6 @@ emacs_fixed_class_init (EmacsFixedClass *klass)
 
   widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
   widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
-#ifdef HAVE_XWIDGETS
-  widget_class->size_allocate = emacs_fixed_gtk_widget_size_allocate;
-#endif
   g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
 }
 
diff --git a/src/fileio.c b/src/fileio.c
index 3c13d3f..a7b1649 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3827,6 +3827,7 @@ restore_window_points (Lisp_Object window_markers, 
ptrdiff_t inserted,
        Lisp_Object car = XCAR (window_markers);
        Lisp_Object marker = XCAR (car);
        Lisp_Object oldpos = XCDR (car);
+       ptrdiff_t newpos;
        if (MARKERP (marker) && FIXNUMP (oldpos)
            && XFIXNUM (oldpos) > same_at_start
            && XFIXNUM (oldpos) < same_at_end)
@@ -3834,10 +3835,12 @@ restore_window_points (Lisp_Object window_markers, 
ptrdiff_t inserted,
            ptrdiff_t oldsize = same_at_end - same_at_start;
            ptrdiff_t newsize = inserted;
            double growth = newsize / (double)oldsize;
-           ptrdiff_t newpos
-             = same_at_start + growth * (XFIXNUM (oldpos) - same_at_start);
-           Fset_marker (marker, make_fixnum (newpos), Qnil);
+           newpos = same_at_start
+             + growth * (XFIXNUM (oldpos) - same_at_start);
          }
+       else
+         newpos = XFIXNUM (oldpos);
+       Fset_marker (marker, make_fixnum (newpos), Qnil);
       }
 }
 
diff --git a/src/ftfont.c b/src/ftfont.c
index 12d0d72..03e44ec 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -225,8 +225,6 @@ ftfont_pattern_entity (FcPattern *p, Lisp_Object extra)
     }
   if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch)
     {
-      if (numeric >= FC_WEIGHT_REGULAR && numeric < FC_WEIGHT_MEDIUM)
-       numeric = FC_WEIGHT_MEDIUM;
       FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, make_fixnum (numeric));
     }
   if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch)
diff --git a/src/lread.c b/src/lread.c
index b3f9e6f..3052bcb 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1045,12 +1045,18 @@ lisp_file_lexically_bound_p (Lisp_Object readcharfun)
    safe to load.  Only files compiled with Emacs can be loaded.  */
 
 static int
-safe_to_load_version (int fd)
+safe_to_load_version (Lisp_Object file, int fd)
 {
+  struct stat st;
   char buf[512];
   int nbytes, i;
   int version = 1;
 
+  /* If the file is not regular, then we cannot safely seek it.
+     Assume that it is not safe to load as a compiled file.  */
+  if (fstat (fd, &st) == 0 && !S_ISREG (st.st_mode))
+    return 0;
+
   /* Read the first few bytes from the file, and look for a line
      specifying the byte compiler version used.  */
   nbytes = emacs_read_quit (fd, buf, sizeof buf);
@@ -1068,7 +1074,9 @@ safe_to_load_version (int fd)
        version = 0;
     }
 
-  lseek (fd, 0, SEEK_SET);
+  if (lseek (fd, 0, SEEK_SET) < 0)
+    report_file_error ("Seeking to start of file", file);
+
   return version;
 }
 
@@ -1401,7 +1409,7 @@ Return t if the file exists and loads successfully.  */)
   if (is_elc
       /* version = 1 means the file is empty, in which case we can
         treat it as not byte-compiled.  */
-      || (fd >= 0 && (version = safe_to_load_version (fd)) > 1))
+      || (fd >= 0 && (version = safe_to_load_version (file, fd)) > 1))
     /* Load .elc files directly, but not when they are
        remote and have no handler!  */
     {
@@ -1410,11 +1418,8 @@ Return t if the file exists and loads successfully.  */)
          struct stat s1, s2;
          int result;
 
-         if (version < 0
-             && ! (version = safe_to_load_version (fd)))
-           {
-             error ("File `%s' was not compiled in Emacs", SDATA (found));
-           }
+         if (version < 0 && !(version = safe_to_load_version (file, fd)))
+           error ("File `%s' was not compiled in Emacs", SDATA (found));
 
          compiled = 1;
 
diff --git a/src/term.c b/src/term.c
index 6f0b827..b4f3dfc 100644
--- a/src/term.c
+++ b/src/term.c
@@ -4152,10 +4152,12 @@ use the Bourne shell command 'TERM=...; export TERM' 
(C-shell:\n\
               could return 32767.  */
            tty->TN_max_colors = 16777216;
          }
-       /* Fall back to xterm+direct (semicolon version) if requested
-          by the COLORTERM environment variable.  */
-       else if ((bg = getenv("COLORTERM")) != NULL
-                && strcasecmp(bg, "truecolor") == 0)
+       /* Fall back to xterm+direct (semicolon version) if Tc is set
+          (de-facto standard introduced by tmux) or if requested by
+          the COLORTERM environment variable.  */
+       else if ((tigetflag ("Tc") > 0)
+                || ((bg = getenv ("COLORTERM")) != NULL
+                    && strcasecmp (bg, "truecolor") == 0))
          {
            tty->TS_set_foreground = 
"\033[%?%p1%{8}%<%t3%p1%d%e38;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m";
            tty->TS_set_background = 
"\033[%?%p1%{8}%<%t4%p1%d%e48;2;%p1%{65536}%/%d;%p1%{256}%/%{255}%&%d;%p1%{255}%&%d%;m";
diff --git a/src/w32.c b/src/w32.c
index e4b7ef3..2b2f8aa 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -6548,7 +6548,8 @@ acl_get_file (const char *fname, acl_type_t type)
                  xfree (psd);
                  err = GetLastError ();
                  if (err == ERROR_NOT_SUPPORTED
-                     || err == ERROR_ACCESS_DENIED)
+                     || err == ERROR_ACCESS_DENIED
+                     || err == ERROR_INVALID_FUNCTION)
                    errno = ENOTSUP;
                  else if (err == ERROR_FILE_NOT_FOUND
                           || err == ERROR_PATH_NOT_FOUND
@@ -6567,10 +6568,11 @@ acl_get_file (const char *fname, acl_type_t type)
                   || err == ERROR_INVALID_NAME)
            errno = ENOENT;
          else if (err == ERROR_NOT_SUPPORTED
-                  /* ERROR_ACCESS_DENIED is what we get for a volume
-                     mounted by WebDAV, which evidently doesn't
-                     support ACLs.  */
-                  || err == ERROR_ACCESS_DENIED)
+                  /* ERROR_ACCESS_DENIED or ERROR_INVALID_FUNCTION is
+                     what we get for a volume mounted by WebDAV,
+                     which evidently doesn't support ACLs.  */
+                  || err == ERROR_ACCESS_DENIED
+                  || err == ERROR_INVALID_FUNCTION)
            errno = ENOTSUP;
          else
            errno = EIO;
diff --git a/src/w32font.c b/src/w32font.c
index 4ceb430..752acdc 100644
--- a/src/w32font.c
+++ b/src/w32font.c
@@ -1974,10 +1974,11 @@ w32_decode_weight (int fnweight)
   if (fnweight >= FW_EXTRABOLD)  return 205;
   if (fnweight >= FW_BOLD)       return 200;
   if (fnweight >= FW_SEMIBOLD)   return 180;
-  if (fnweight >= FW_NORMAL)     return 100;
-  if (fnweight >= FW_LIGHT)      return 50;
-  if (fnweight >= FW_EXTRALIGHT) return 40;
-  if (fnweight >  FW_THIN)       return 20;
+  if (fnweight >= FW_MEDIUM)     return 100;
+  if (fnweight >= FW_NORMAL)     return  80;
+  if (fnweight >= FW_LIGHT)      return  50;
+  if (fnweight >= FW_EXTRALIGHT) return  40;
+  if (fnweight >= FW_THIN)       return  20;
   return 0;
 }
 
@@ -1988,10 +1989,11 @@ w32_encode_weight (int n)
   if (n >= 205) return FW_EXTRABOLD;
   if (n >= 200) return FW_BOLD;
   if (n >= 180) return FW_SEMIBOLD;
-  if (n >= 100) return FW_NORMAL;
-  if (n >= 50)  return FW_LIGHT;
-  if (n >= 40)  return FW_EXTRALIGHT;
-  if (n >= 20)  return FW_THIN;
+  if (n >= 100) return FW_MEDIUM;
+  if (n >=  80) return FW_NORMAL;
+  if (n >=  50) return FW_LIGHT;
+  if (n >=  40) return FW_EXTRALIGHT;
+  if (n >=  20) return FW_THIN;
   return 0;
 }
 
@@ -2000,14 +2002,15 @@ w32_encode_weight (int n)
 static Lisp_Object
 w32_to_fc_weight (int n)
 {
-  if (n >= FW_HEAVY)     return Qblack;
-  if (n >= FW_EXTRABOLD) return Qextra_bold;
-  if (n >= FW_BOLD)      return Qbold;
-  if (n >= FW_SEMIBOLD)  return intern ("demibold");
-  if (n >= FW_NORMAL)    return Qmedium;
-  if (n >= FW_LIGHT)     return Qlight;
+  if (n >= FW_HEAVY)      return Qblack;
+  if (n >= FW_EXTRABOLD)  return Qextra_bold;
+  if (n >= FW_BOLD)       return Qbold;
+  if (n >= FW_SEMIBOLD)   return Qsemi_bold;
+  if (n >= FW_MEDIUM)     return Qmedium;
+  if (n >= FW_NORMAL)     return Qnormal;
+  if (n >= FW_LIGHT)      return Qlight;
   if (n >= FW_EXTRALIGHT) return Qextra_light;
-  return intern ("thin");
+  return Qthin;
 }
 
 /* Fill in all the available details of LOGFONT from FONT_SPEC.  */
diff --git a/src/xfaces.c b/src/xfaces.c
index d4e6270..86ee18c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -1440,52 +1440,6 @@ enum xlfd_field
   XLFD_LAST
 };
 
-/* An enumerator for each possible slant value of a font.  Taken from
-   the XLFD specification.  */
-
-enum xlfd_slant
-{
-  XLFD_SLANT_UNKNOWN,
-  XLFD_SLANT_ROMAN,
-  XLFD_SLANT_ITALIC,
-  XLFD_SLANT_OBLIQUE,
-  XLFD_SLANT_REVERSE_ITALIC,
-  XLFD_SLANT_REVERSE_OBLIQUE,
-  XLFD_SLANT_OTHER
-};
-
-/* Relative font weight according to XLFD documentation.  */
-
-enum xlfd_weight
-{
-  XLFD_WEIGHT_UNKNOWN,
-  XLFD_WEIGHT_ULTRA_LIGHT,     /* 10 */
-  XLFD_WEIGHT_EXTRA_LIGHT,     /* 20 */
-  XLFD_WEIGHT_LIGHT,           /* 30 */
-  XLFD_WEIGHT_SEMI_LIGHT,      /* 40: SemiLight, Book, ...  */
-  XLFD_WEIGHT_MEDIUM,          /* 50: Medium, Normal, Regular, ...  */
-  XLFD_WEIGHT_SEMI_BOLD,       /* 60: SemiBold, DemiBold, ...  */
-  XLFD_WEIGHT_BOLD,            /* 70: Bold, ... */
-  XLFD_WEIGHT_EXTRA_BOLD,      /* 80: ExtraBold, Heavy, ...  */
-  XLFD_WEIGHT_ULTRA_BOLD       /* 90: UltraBold, Black, ...  */
-};
-
-/* Relative proportionate width.  */
-
-enum xlfd_swidth
-{
-  XLFD_SWIDTH_UNKNOWN,
-  XLFD_SWIDTH_ULTRA_CONDENSED, /* 10 */
-  XLFD_SWIDTH_EXTRA_CONDENSED, /* 20 */
-  XLFD_SWIDTH_CONDENSED,       /* 30: Condensed, Narrow, Compressed, ... */
-  XLFD_SWIDTH_SEMI_CONDENSED,  /* 40: semicondensed */
-  XLFD_SWIDTH_MEDIUM,          /* 50: Medium, Normal, Regular, ... */
-  XLFD_SWIDTH_SEMI_EXPANDED,   /* 60: SemiExpanded, DemiExpanded, ... */
-  XLFD_SWIDTH_EXPANDED,                /* 70: Expanded... */
-  XLFD_SWIDTH_EXTRA_EXPANDED,  /* 80: ExtraExpanded, Wide...  */
-  XLFD_SWIDTH_ULTRA_EXPANDED   /* 90: UltraExpanded... */
-};
-
 /* Order by which font selection chooses fonts.  The default values
    mean `first, find a best match for the font width, then for the
    font height, then for weight, then for slant.'  This variable can be
diff --git a/src/xwidget.c b/src/xwidget.c
index 6e2e8a9..66a905d 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -43,6 +43,8 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #endif
 
 static Lisp_Object id_to_xwidget_map;
+static Lisp_Object internal_xwidget_view_list;
+static Lisp_Object internal_xwidget_list;
 static uint32_t xwidget_counter = 0;
 
 #ifdef USE_GTK
@@ -89,6 +91,9 @@ webkit_decide_policy_cb (WebKitWebView *,
                          WebKitPolicyDecisionType,
                          gpointer);
 static GtkWidget *find_widget_at_pos (GtkWidget *, int, int, int *, int *);
+static gboolean run_file_chooser_cb (WebKitWebView *,
+                                    WebKitFileChooserRequest *,
+                                    gpointer);
 
 struct widget_search_data
 {
@@ -144,7 +149,8 @@ fails.  */)
   xw->width = XFIXNAT (width);
   xw->kill_without_query = false;
   XSETXWIDGET (val, xw);
-  Vxwidget_list = Fcons (val, Vxwidget_list);
+  internal_xwidget_list = Fcons (val, internal_xwidget_list);
+  Vxwidget_list = Fcopy_sequence (internal_xwidget_list);
   xw->plist = Qnil;
   xw->xwidget_id = ++xwidget_counter;
   xw->find_text = NULL;
@@ -262,6 +268,10 @@ fails.  */)
                            "script-dialog",
                            G_CALLBACK (webkit_script_dialog_cb),
                            NULL);
+         g_signal_connect (G_OBJECT (xw->widget_osr),
+                           "run-file-chooser",
+                           G_CALLBACK (run_file_chooser_cb),
+                           NULL);
         }
 
       g_signal_connect (G_OBJECT (xw->widgetwindow_osr), "damage-event",
@@ -276,6 +286,16 @@ fails.  */)
   return val;
 }
 
+DEFUN ("xwidget-live-p", Fxwidget_live_p, Sxwidget_live_p,
+       1, 1, 0, doc: /* Return t if OBJECT is an xwidget that has not been 
killed.
+Value is nil if OBJECT is not an xwidget or if it has been killed.  */)
+  (Lisp_Object object)
+{
+  return ((XWIDGETP (object)
+          && !NILP (XXWIDGET (object)->buffer))
+         ? Qt : Qnil);
+}
+
 #ifdef USE_GTK
 static void
 set_widget_if_text_view (GtkWidget *widget, void *data)
@@ -308,7 +328,7 @@ selected frame is not an X-Windows frame.  */)
   GtkWidget *temp = NULL;
 #endif
 
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   xw = XXWIDGET (xwidget);
 
   if (!NILP (frame))
@@ -442,7 +462,7 @@ BUFFER may be a buffer or the name of one.  */)
 
   xw_list = Qnil;
 
-  for (tail = Vxwidget_list; CONSP (tail); tail = XCDR (tail))
+  for (tail = internal_xwidget_list; CONSP (tail); tail = XCDR (tail))
     {
       xw = XCAR (tail);
       if (XWIDGETP (xw) && EQ (Fxwidget_buffer (xw), buffer))
@@ -492,7 +512,7 @@ find_xwidget_for_offscreen_window (GdkWindow *window)
   struct xwidget *xw;
   GdkWindow *w;
 
-  for (tem = Vxwidget_list; CONSP (tem); tem = XCDR (tem))
+  for (tem = internal_xwidget_list; CONSP (tem); tem = XCDR (tem))
     {
       if (XWIDGETP (XCAR (tem)))
        {
@@ -744,7 +764,7 @@ define_cursors (struct xwidget *xw, WebKitHitTestResult 
*res)
 
   xw->hit_result = webkit_hit_test_result_get_context (res);
 
-  for (Lisp_Object tem = Vxwidget_view_list; CONSP (tem);
+  for (Lisp_Object tem = internal_xwidget_view_list; CONSP (tem);
        tem = XCDR (tem))
     {
       if (XWIDGET_VIEW_P (XCAR (tem)))
@@ -769,6 +789,70 @@ mouse_target_changed (WebKitWebView *webview,
   define_cursors (xw, hitresult);
 }
 
+static gboolean
+run_file_chooser_cb (WebKitWebView *webview,
+                    WebKitFileChooserRequest *request,
+                    gpointer user_data)
+{
+  struct frame *f = SELECTED_FRAME ();
+  GtkWidget *chooser;
+  GtkFileFilter *filter;
+  bool select_multiple_p;
+  guint response;
+  GSList *filenames;
+  GSList *tem;
+  int i, len;
+  gchar **files;
+
+  /* Return TRUE to prevent WebKit from showing the default script
+     dialog in the offscreen window, which runs a nested main loop
+     Emacs can't respond to, and as such can't pass X events to.  */
+  if (!FRAME_WINDOW_P (f))
+    return TRUE;
+
+  chooser = gtk_file_chooser_dialog_new ("Select file",
+                                        GTK_WINDOW (FRAME_GTK_OUTER_WIDGET 
(f)),
+                                        GTK_FILE_CHOOSER_ACTION_OPEN,
+                                        "Cancel",
+                                        GTK_RESPONSE_CANCEL,
+                                        "Select",
+                                        GTK_RESPONSE_ACCEPT,
+                                        NULL);
+  filter = webkit_file_chooser_request_get_mime_types_filter (request);
+  select_multiple_p = webkit_file_chooser_request_get_select_multiple 
(request);
+
+  gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser),
+                                       select_multiple_p);
+  gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+  response = gtk_dialog_run (GTK_DIALOG (chooser));
+
+  if (response == GTK_RESPONSE_CANCEL)
+    {
+      gtk_widget_destroy (chooser);
+      webkit_file_chooser_request_cancel (request);
+
+      return TRUE;
+    }
+
+  filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (chooser));
+  len = g_slist_length (filenames);
+  files = alloca (sizeof *files * (len + 1));
+
+  for (tem = filenames, i = 0; tem; tem = tem->next, ++i)
+    files[i] = tem->data;
+  files[len] = NULL;
+
+  g_slist_free (filenames);
+  webkit_file_chooser_request_select_files (request, (const gchar **) files);
+
+  for (i = 0; i < len; ++i)
+    g_free (files[i]);
+
+  gtk_widget_destroy (chooser);
+
+  return TRUE;
+}
+
 
 static void
 xwidget_button_1 (struct xwidget_view *view,
@@ -810,6 +894,9 @@ xwidget_button (struct xwidget_view *view,
                bool down_p, int x, int y, int button,
                int modifier_state, Time time)
 {
+  if (NILP (XXWIDGET (view->model)->buffer))
+    return;
+
   record_osr_embedder (view);
 
   if (button < 4 || button > 8)
@@ -860,22 +947,29 @@ xwidget_button (struct xwidget_view *view,
 void
 xwidget_motion_or_crossing (struct xwidget_view *view, const XEvent *event)
 {
-  GdkEvent *xg_event = gdk_event_new (event->type == MotionNotify
-                                     ? GDK_MOTION_NOTIFY
-                                     : (event->type == LeaveNotify
-                                        ? GDK_LEAVE_NOTIFY
-                                        : GDK_ENTER_NOTIFY));
+  GdkEvent *xg_event;
   struct xwidget *model = XXWIDGET (view->model);
   int x;
   int y;
-  GtkWidget *target = find_widget_at_pos (model->widgetwindow_osr,
-                                         (event->type == MotionNotify
-                                          ? event->xmotion.x + view->clip_left
-                                          : event->xcrossing.x + 
view->clip_left),
-                                         (event->type == MotionNotify
-                                          ? event->xmotion.y + view->clip_top
-                                          : event->xcrossing.y + 
view->clip_top),
-                                         &x, &y);
+  GtkWidget *target;
+
+  if (NILP (model->buffer))
+    return;
+
+  xg_event = gdk_event_new (event->type == MotionNotify
+                           ? GDK_MOTION_NOTIFY
+                           : (event->type == LeaveNotify
+                              ? GDK_LEAVE_NOTIFY
+                              : GDK_ENTER_NOTIFY));
+
+  target = find_widget_at_pos (model->widgetwindow_osr,
+                              (event->type == MotionNotify
+                               ? event->xmotion.x + view->clip_left
+                               : event->xcrossing.x + view->clip_left),
+                              (event->type == MotionNotify
+                               ? event->xmotion.y + view->clip_top
+                               : event->xcrossing.y + view->clip_top),
+                              &x, &y);
 
   if (!target)
     target = model->widget_osr;
@@ -972,6 +1066,13 @@ xv_do_draw (struct xwidget_view *xw, struct xwidget *w)
 {
   GtkOffscreenWindow *wnd;
   cairo_surface_t *surface;
+
+  if (NILP (w->buffer))
+    {
+      XClearWindow (xw->dpy, xw->wdesc);
+      return;
+    }
+
   block_input ();
   wnd = GTK_OFFSCREEN_WINDOW (w->widgetwindow_osr);
   surface = gtk_offscreen_window_get_surface (wnd);
@@ -997,7 +1098,7 @@ offscreen_damage_event (GtkWidget *widget, GdkEvent *event,
 {
   block_input ();
 
-  for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+  for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
        tail = XCDR (tail))
     {
       if (XWIDGET_VIEW_P (XCAR (tail)))
@@ -1095,7 +1196,7 @@ webkit_ready_to_show (WebKitWebView *new_view,
   Lisp_Object tem;
   struct xwidget *xw;
 
-  for (tem = Vxwidget_list; CONSP (tem); tem = XCDR (tem))
+  for (tem = internal_xwidget_list; CONSP (tem); tem = XCDR (tem))
     {
       if (XWIDGETP (XCAR (tem)))
        {
@@ -1266,8 +1367,8 @@ webkit_javascript_finished_cb (GObject      *webview,
 
   if (!js_result)
     {
-      g_warning ("Error running javascript: %s", error->message);
-      g_error_free (error);
+      if (error)
+       g_error_free (error);
       return;
     }
 
@@ -1462,7 +1563,8 @@ xwidget_init_view (struct xwidget *xww,
   Lisp_Object val;
 
   XSETXWIDGET_VIEW (val, xv);
-  Vxwidget_view_list = Fcons (val, Vxwidget_view_list);
+  internal_xwidget_view_list = Fcons (val, internal_xwidget_view_list);
+  Vxwidget_view_list = Fcopy_sequence (internal_xwidget_view_list);
 
   XSETWINDOW (xv->w, s->w);
   XSETXWIDGET (xv->model, xww);
@@ -1654,40 +1756,40 @@ x_draw_xwidget_glyph_string (struct glyph_string *s)
      a redraw.  It seems its possible to get out of sync with emacs
      redraws so emacs background sometimes shows up instead of the
      xwidgets background.  It's just a visual glitch though.  */
-  if (!xwidget_hidden (xv))
+  /* When xww->buffer is nil, that means the xwidget has been killed.  */
+  if (!NILP (xww->buffer))
     {
+      if (!xwidget_hidden (xv))
+       {
 #ifdef USE_GTK
-      gtk_widget_queue_draw (xww->widget_osr);
+         gtk_widget_queue_draw (xww->widget_osr);
 #elif defined NS_IMPL_COCOA
-      nsxwidget_set_needsdisplay (xv);
+         nsxwidget_set_needsdisplay (xv);
 #endif
+       }
     }
-
 #ifdef USE_GTK
-  unblock_input ();
+  else
+    {
+      XSetWindowBackground (xv->dpy, xv->wdesc,
+                           FRAME_BACKGROUND_PIXEL (s->f));
+    }
 #endif
-}
 
-static bool
-xwidget_is_web_view (struct xwidget *xw)
-{
 #ifdef USE_GTK
-  return xw->widget_osr != NULL && WEBKIT_IS_WEB_VIEW (xw->widget_osr);
-#elif defined NS_IMPL_COCOA
-  return nsxwidget_is_web_view (xw);
+  unblock_input ();
 #endif
 }
 
+#define CHECK_WEBKIT_WIDGET(xw)                                \
+  if (NILP (xw->buffer) || !EQ (xw->type, Qwebkit))    \
+    error ("Not a WebKit widget")
+
 /* Macro that checks xwidget hold webkit web view first.  */
 #define WEBKIT_FN_INIT()                                               \
-  CHECK_XWIDGET (xwidget);                                             \
+  CHECK_LIVE_XWIDGET (xwidget);                                                
\
   struct xwidget *xw = XXWIDGET (xwidget);                             \
-  if (!xwidget_is_web_view (xw))                                       \
-    {                                                                  \
-      fputs ("ERROR xw->widget_osr does not hold a webkit instance\n", \
-            stdout);                                                   \
-      return Qnil;                                                     \
-    }
+  CHECK_WEBKIT_WIDGET (xw)
 
 DEFUN ("xwidget-webkit-uri",
        Fxwidget_webkit_uri, Sxwidget_webkit_uri,
@@ -1698,7 +1800,10 @@ DEFUN ("xwidget-webkit-uri",
   WEBKIT_FN_INIT ();
 #ifdef USE_GTK
   WebKitWebView *wkwv = WEBKIT_WEB_VIEW (xw->widget_osr);
-  return build_string (webkit_web_view_get_uri (wkwv));
+  const gchar *uri = webkit_web_view_get_uri (wkwv);
+  if (!uri)
+    return build_string ("");
+  return build_string (uri);
 #elif defined NS_IMPL_COCOA
   return nsxwidget_webkit_uri (xw);
 #endif
@@ -1859,7 +1964,7 @@ DEFUN ("xwidget-resize", Fxwidget_resize, 
Sxwidget_resize, 3, 3, 0,
        doc: /* Resize XWIDGET to NEW_WIDTH, NEW_HEIGHT.  */ )
   (Lisp_Object xwidget, Lisp_Object new_width, Lisp_Object new_height)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   int w = check_integer_range (new_width, 0, INT_MAX);
   int h = check_integer_range (new_height, 0, INT_MAX);
   struct xwidget *xw = XXWIDGET (xwidget);
@@ -1883,7 +1988,8 @@ DEFUN ("xwidget-resize", Fxwidget_resize, 
Sxwidget_resize, 3, 3, 0,
   nsxwidget_resize (xw);
 #endif
 
-  for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail); tail = XCDR (tail))
+  for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
+       tail = XCDR (tail))
     {
       if (XWIDGET_VIEW_P (XCAR (tail)))
         {
@@ -1911,7 +2017,7 @@ This can be used to read the xwidget desired size, and 
resizes the
 Emacs allocated area accordingly.  */)
   (Lisp_Object xwidget)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
 #ifdef USE_GTK
   GtkRequisition requisition;
   gtk_widget_size_request (XXWIDGET (xwidget)->widget_osr, &requisition);
@@ -1946,7 +2052,7 @@ DEFUN ("xwidget-info",
 Currently [TYPE TITLE WIDTH HEIGHT].  */)
   (Lisp_Object xwidget)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   struct xwidget *xw = XXWIDGET (xwidget);
   return CALLN (Fvector, xw->type, xw->title,
                make_fixed_natnum (xw->width), make_fixed_natnum (xw->height));
@@ -2009,7 +2115,7 @@ DEFUN ("delete-xwidget-view",
       unblock_input ();
     }
 
-  if (xw->embedder_view == xv)
+  if (xw->embedder_view == xv && !NILP (xw->buffer))
     {
       w = gtk_widget_get_window (xw->widgetwindow_osr);
 
@@ -2022,7 +2128,8 @@ DEFUN ("delete-xwidget-view",
   nsxwidget_delete_view (xv);
 #endif
 
-  Vxwidget_view_list = Fdelq (xwidget_view, Vxwidget_view_list);
+  internal_xwidget_view_list = Fdelq (xwidget_view, 
internal_xwidget_view_list);
+  Vxwidget_view_list = Fcopy_sequence (internal_xwidget_view_list);
   return Qnil;
 }
 
@@ -2040,7 +2147,7 @@ Return nil if no association is found.  */)
     window = Fselected_window ();
   CHECK_WINDOW (window);
 
-  for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+  for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
        tail = XCDR (tail))
     {
       Lisp_Object xwidget_view = XCAR (tail);
@@ -2058,7 +2165,7 @@ DEFUN ("xwidget-plist",
        doc: /* Return the plist of XWIDGET.  */)
   (Lisp_Object xwidget)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   return XXWIDGET (xwidget)->plist;
 }
 
@@ -2078,7 +2185,7 @@ DEFUN ("set-xwidget-buffer",
        doc: /* Set XWIDGET's buffer to BUFFER.  */)
   (Lisp_Object xwidget, Lisp_Object buffer)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   CHECK_BUFFER (buffer);
 
   XXWIDGET (xwidget)->buffer = buffer;
@@ -2092,7 +2199,7 @@ DEFUN ("set-xwidget-plist",
 Returns PLIST.  */)
   (Lisp_Object xwidget, Lisp_Object plist)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   CHECK_LIST (plist);
 
   XXWIDGET (xwidget)->plist = plist;
@@ -2108,7 +2215,7 @@ exiting or killing a buffer if XWIDGET is running.
 This function returns FLAG.  */)
   (Lisp_Object xwidget, Lisp_Object flag)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   XXWIDGET (xwidget)->kill_without_query = NILP (flag);
   return flag;
 }
@@ -2119,7 +2226,7 @@ DEFUN ("xwidget-query-on-exit-flag",
        doc: /* Return the current value of the query-on-exit flag for XWIDGET. 
 */)
   (Lisp_Object xwidget)
 {
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   return (XXWIDGET (xwidget)->kill_without_query ? Qnil : Qt);
 }
 
@@ -2152,10 +2259,12 @@ with QUERY.  */)
 #endif
 
   CHECK_STRING (query);
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
 
 #ifdef USE_GTK
   xw = XXWIDGET (xwidget);
+  CHECK_WEBKIT_WIDGET (xw);
+
   webview = WEBKIT_WEB_VIEW (xw->widget_osr);
   query = ENCODE_UTF_8 (query);
   opt = WEBKIT_FIND_OPTIONS_NONE;
@@ -2196,8 +2305,9 @@ using `xwidget-webkit-search'.  */)
   WebKitFindController *controller;
 #endif
 
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   xw = XXWIDGET (xwidget);
+  CHECK_WEBKIT_WIDGET (xw);
 
   if (!xw->find_text)
     error ("Widget has no ongoing search operation");
@@ -2228,8 +2338,9 @@ using `xwidget-webkit-search'.  */)
   WebKitFindController *controller;
 #endif
 
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   xw = XXWIDGET (xwidget);
+  CHECK_WEBKIT_WIDGET (xw);
 
   if (!xw->find_text)
     error ("Widget has no ongoing search operation");
@@ -2260,8 +2371,9 @@ using `xwidget-webkit-search'.  */)
   WebKitFindController *controller;
 #endif
 
-  CHECK_XWIDGET (xwidget);
+  CHECK_LIVE_XWIDGET (xwidget);
   xw = XXWIDGET (xwidget);
+  CHECK_WEBKIT_WIDGET (xw);
 
   if (!xw->find_text)
     error ("Widget has no ongoing search operation");
@@ -2283,12 +2395,53 @@ using `xwidget-webkit-search'.  */)
   return Qnil;
 }
 
+#ifdef USE_GTK
+DEFUN ("xwidget-webkit-load-html", Fxwidget_webkit_load_html,
+       Sxwidget_webkit_load_html, 2, 3, 0,
+       doc: /* Make XWIDGET's WebKit widget render TEXT.
+XWIDGET should be a WebKit xwidget, that will receive TEXT.  TEXT
+should be a string that will be displayed by XWIDGET as HTML markup.
+BASE-URI should be a string containing a URI that is used to locate
+resources with relative URLs, and if not specified, defaults
+to "about:blank".  */)
+  (Lisp_Object xwidget, Lisp_Object text, Lisp_Object base_uri)
+{
+  struct xwidget *xw;
+  WebKitWebView *webview;
+  char *data, *uri;
+
+  CHECK_LIVE_XWIDGET (xwidget);
+  CHECK_STRING (text);
+  if (NILP (base_uri))
+    base_uri = build_string ("about:blank");
+  else
+    CHECK_STRING (base_uri);
+
+  base_uri = ENCODE_UTF_8 (base_uri);
+  text = ENCODE_UTF_8 (text);
+  xw = XXWIDGET (xwidget);
+  CHECK_WEBKIT_WIDGET (xw);
+
+  data = SSDATA (text);
+  uri = SSDATA (base_uri);
+  webview = WEBKIT_WEB_VIEW (xw->widget_osr);
+
+  block_input ();
+  webkit_web_view_load_html (webview, data, uri);
+  unblock_input ();
+
+  return Qnil;
+}
+#endif
+
 void
 syms_of_xwidget (void)
 {
   defsubr (&Smake_xwidget);
   defsubr (&Sxwidgetp);
+  defsubr (&Sxwidget_live_p);
   DEFSYM (Qxwidgetp, "xwidgetp");
+  DEFSYM (Qxwidget_live_p, "xwidget-live-p");
   defsubr (&Sxwidget_view_p);
   DEFSYM (Qxwidget_view_p, "xwidget-view-p");
   defsubr (&Sxwidget_info);
@@ -2321,6 +2474,9 @@ syms_of_xwidget (void)
   defsubr (&Sxwidget_webkit_next_result);
   defsubr (&Sxwidget_webkit_previous_result);
   defsubr (&Sset_xwidget_buffer);
+#ifdef USE_GTK
+  defsubr (&Sxwidget_webkit_load_html);
+#endif
 
   DEFSYM (QCxwidget, ":xwidget");
   DEFSYM (QCtitle, ":title");
@@ -2343,9 +2499,15 @@ syms_of_xwidget (void)
 
   Fprovide (intern ("xwidget-internal"), Qnil);
 
-  id_to_xwidget_map = CALLN (Fmake_hash_table, QCtest, Qeq);
+  id_to_xwidget_map = CALLN (Fmake_hash_table, QCtest, Qeq,
+                            QCweakness, Qvalue);
   staticpro (&id_to_xwidget_map);
 
+  internal_xwidget_list = Qnil;
+  staticpro (&internal_xwidget_list);
+  internal_xwidget_view_list = Qnil;
+  staticpro (&internal_xwidget_view_list);
+
 #ifdef USE_GTK
   x_window_to_xwv_map = CALLN (Fmake_hash_table, QCtest, Qeq);
 
@@ -2391,7 +2553,7 @@ void
 xwidget_view_delete_all_in_window (struct window *w)
 {
   struct xwidget_view *xv = NULL;
-  for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+  for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
        tail = XCDR (tail))
     {
       if (XWIDGET_VIEW_P (XCAR (tail)))
@@ -2436,7 +2598,7 @@ lookup_xwidget (Lisp_Object spec)
 static void
 xwidget_start_redisplay (void)
 {
-  for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+  for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
        tail = XCDR (tail))
     {
       if (XWIDGET_VIEW_P (XCAR (tail)))
@@ -2507,7 +2669,7 @@ xwidget_end_redisplay (struct window *w, struct 
glyph_matrix *matrix)
          }
     }
 
-  for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+  for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
        tail = XCDR (tail))
     {
       if (XWIDGET_VIEW_P (XCAR (tail)))
@@ -2545,7 +2707,7 @@ kill_frame_xwidget_views (struct frame *f)
 {
   Lisp_Object rem = Qnil;
 
-  for (Lisp_Object tail = Vxwidget_view_list; CONSP (tail);
+  for (Lisp_Object tail = internal_xwidget_view_list; CONSP (tail);
        tail = XCDR (tail))
     {
       if (XWIDGET_VIEW_P (XCAR (tail))
@@ -2566,12 +2728,13 @@ kill_buffer_xwidgets (Lisp_Object buffer)
   for (tail = Fget_buffer_xwidgets (buffer); CONSP (tail); tail = XCDR (tail))
     {
       xwidget = XCAR (tail);
-      Vxwidget_list = Fdelq (xwidget, Vxwidget_list);
-      /* TODO free the GTK things in xw.  */
+      internal_xwidget_list = Fdelq (xwidget, internal_xwidget_list);
+      Vxwidget_list = Fcopy_sequence (internal_xwidget_list);
       {
-        CHECK_XWIDGET (xwidget);
+        CHECK_LIVE_XWIDGET (xwidget);
         struct xwidget *xw = XXWIDGET (xwidget);
-       Fremhash (make_fixnum (xw->xwidget_id), id_to_xwidget_map);
+       xw->buffer = Qnil;
+
 #ifdef USE_GTK
         if (xw->widget_osr && xw->widgetwindow_osr)
           {
@@ -2588,6 +2751,10 @@ kill_buffer_xwidgets (Lisp_Object buffer)
                xfree (xmint_pointer (XCAR (cb)));
              ASET (xw->script_callbacks, idx, Qnil);
            }
+
+       xw->widget_osr = NULL;
+       xw->widgetwindow_osr = NULL;
+       xw->find_text = NULL;
 #elif defined NS_IMPL_COCOA
         nsxwidget_kill (xw);
 #endif
diff --git a/src/xwidget.h b/src/xwidget.h
index 6e6b39c..4377b50 100644
--- a/src/xwidget.h
+++ b/src/xwidget.h
@@ -138,9 +138,16 @@ struct xwidget_view
 #define XXWIDGET(a) (eassert (XWIDGETP (a)), \
                     XUNTAG (a, Lisp_Vectorlike, struct xwidget))
 
+#define XWIDGET_LIVE_P(w) (!NILP ((w)->buffer))
+
 #define CHECK_XWIDGET(x) \
   CHECK_TYPE (XWIDGETP (x), Qxwidgetp, x)
 
+#define CHECK_LIVE_XWIDGET(x)                          \
+  CHECK_TYPE ((XWIDGETP (x)                            \
+              && XWIDGET_LIVE_P (XXWIDGET (x))),       \
+             Qxwidget_live_p, x)
+
 /* Test for xwidget_view pseudovector.  */
 #define XWIDGET_VIEW_P(x) PSEUDOVECTORP (x, PVEC_XWIDGET_VIEW)
 #define XXWIDGET_VIEW(a) (eassert (XWIDGET_VIEW_P (a)), \
diff --git a/test/lisp/files-resources/insert-directory/test_dir/bar 
b/test/lisp/files-resources/insert-directory/test_dir/bar
new file mode 100644
index 0000000..e69de29
diff --git a/test/lisp/files-resources/insert-directory/test_dir/foo 
b/test/lisp/files-resources/insert-directory/test_dir/foo
new file mode 100644
index 0000000..e69de29
diff --git a/test/lisp/files-resources/insert-directory/test_dir_other/bar 
b/test/lisp/files-resources/insert-directory/test_dir_other/bar
new file mode 100644
index 0000000..e69de29
diff --git a/test/lisp/files-resources/insert-directory/test_dir_other/foo 
b/test/lisp/files-resources/insert-directory/test_dir_other/foo
new file mode 100644
index 0000000..e69de29
diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el
index 1e20317..d00f1ce 100644
--- a/test/lisp/files-tests.el
+++ b/test/lisp/files-tests.el
@@ -1531,10 +1531,13 @@ The door of all subtleties!
   (ert-with-temp-file temp-file-name
     (with-temp-buffer
       (insert files-tests-lao)
-      (write-file temp-file-name)
-      (erase-buffer)
-      (insert files-tests-tzu)
-      (revert-buffer t t t)
+      ;; Disable lock files, since that barfs in
+      ;; userlock--check-content-unchanged on MS-Windows.
+      (let (create-lockfiles)
+        (write-file temp-file-name)
+        (erase-buffer)
+        (insert files-tests-tzu)
+        (revert-buffer t t t))
       (should (compare-strings files-tests-lao nil nil
                                (buffer-substring (point-min) (point-max))
                                nil nil)))))
@@ -1544,10 +1547,13 @@ The door of all subtleties!
   (ert-with-temp-file temp-file-name
     (with-temp-buffer
       (insert files-tests-lao)
-      (write-file temp-file-name)
-      (erase-buffer)
-      (insert files-tests-tzu)
-      (should (revert-buffer-with-fine-grain t t))
+      ;; Disable lock files, since that barfs in
+      ;; userlock--check-content-unchanged on MS-Windows.
+      (let (create-lockfiles)
+        (write-file temp-file-name)
+        (erase-buffer)
+        (insert files-tests-tzu)
+        (should (revert-buffer-with-fine-grain t t)))
       (should (compare-strings files-tests-lao nil nil
                                (buffer-substring (point-min) (point-max))
                                nil nil)))))
@@ -1800,12 +1806,86 @@ Prompt users for any modified buffer with 
`buffer-offer-save' non-nil."
          ;; `save-some-buffers-default-predicate' (i.e. the 2nd element) is 
ignored.
          (nil save-some-buffers-root ,nb-might-save))))))
 
-(defun test-file-name-split ()
+(ert-deftest test-file-name-split ()
   (should (equal (file-name-split "foo/bar") '("foo" "bar")))
   (should (equal (file-name-split "/foo/bar") '("" "foo" "bar")))
   (should (equal (file-name-split "/foo/bar/zot") '("" "foo" "bar" "zot")))
   (should (equal (file-name-split "/foo/bar/") '("" "foo" "bar" "")))
   (should (equal (file-name-split "foo/bar/") '("foo" "bar" ""))))
 
+;; `insert-directory' output tests.
+(let* ((data-dir "insert-directory")
+       (test-dir (file-name-as-directory
+                  (ert-resource-file
+                   (concat data-dir "/test_dir"))))
+       (test-dir-other (file-name-as-directory
+                        (ert-resource-file
+                         (concat data-dir "/test_dir_other"))))
+       (test-files `(,test-dir "foo" "bar")) ;expected files to be found
+       ;; Free space test data for `insert-directory'.
+       ;; Meaning: (path free-space-bytes-to-stub expected-free-space-string)
+       (free-data `((,test-dir 10 "available 10 B")
+                    (,test-dir-other 100 "available 100 B")
+                    (:default 999 "available 999 B"))))
+
+
+  (defun files-tests--look-up-free-data (path)
+    "Look up free space test data, with a default for unspecified paths."
+    (let ((path (file-name-as-directory path)))
+      (cdr (or (assoc path free-data)
+               (assoc :default free-data)))))
+
+  (defun files-tests--make-file-system-info-stub (&optional static-path)
+    "Return a stub for `file-system-info' using dynamic or static test data.
+If that data should be static, pass STATIC-PATH to choose which
+path's data to use."
+    (lambda (path)
+      (let* ((path (cond (static-path)
+                         ;; file-system-info knows how to handle ".", so we
+                         ;; do the same thing
+                         ((equal "." path) default-directory)
+                         (path)))
+             (return-size
+              (car (files-tests--look-up-free-data path))))
+        (list return-size return-size return-size))))
+
+  (defun files-tests--insert-directory-output (dir &optional verbose)
+    "Run `insert-directory' and return its output."
+    (with-current-buffer-window "files-tests--insert-directory" nil nil
+      (insert-directory dir "-l" nil t)
+      (buffer-substring-no-properties (point-min) (point-max))))
+
+  (ert-deftest files-tests-insert-directory-shows-files ()
+    "Verify `insert-directory' reports the files in the directory."
+    (let* ((test-dir (car test-files))
+           (files (cdr test-files))
+           (output (files-tests--insert-directory-output test-dir)))
+      (dolist (file files)
+        (should (string-match-p file output)))))
+
+  (defun files-tests--insert-directory-shows-given-free (dir &optional
+                                                             info-func)
+    "Run `insert-directory' and verify it reports the correct available space.
+Stub `file-system-info' to ensure the available space is consistent,
+either with the given stub function or a default one using test data."
+    (cl-letf (((symbol-function 'file-system-info)
+               (or info-func
+                   (files-tests--make-file-system-info-stub))))
+      (should (string-match-p (cadr
+                               (files-tests--look-up-free-data dir))
+                              (files-tests--insert-directory-output dir t)))))
+
+  (ert-deftest files-tests-insert-directory-shows-free ()
+    "Test that verbose `insert-directory' shows the correct available space."
+    (files-tests--insert-directory-shows-given-free
+     test-dir
+     (files-tests--make-file-system-info-stub test-dir)))
+
+  (ert-deftest files-tests-bug-50630 ()
+    "Verify verbose `insert-directory' shows free space of the target 
directory.
+The current directory at call time should not affect the result (Bug#50630)."
+    (let ((default-directory test-dir-other))
+      (files-tests--insert-directory-shows-given-free test-dir))))
+
 (provide 'files-tests)
 ;;; files-tests.el ends here
diff --git a/test/lisp/info-tests.el b/test/lisp/info-tests.el
new file mode 100644
index 0000000..3e2aa3e
--- /dev/null
+++ b/test/lisp/info-tests.el
@@ -0,0 +1,39 @@
+;;; info-tests.el --- Tests for info.el  -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;
+
+;;; Code:
+
+(require 'info)
+(require 'ert)
+(require 'ert-x)
+
+(ert-deftest test-info-urls ()
+  (should (equal (Info-url-for-node "(emacs)Minibuffer")
+                 
"https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer.html";))
+  (should (equal (Info-url-for-node "(emacs)Minibuffer File")
+                 
"https://www.gnu.org/software/emacs/manual/html_node/emacs/Minibuffer-File.html";))
+  (should (equal (Info-url-for-node "(elisp)Backups and Auto-Saving")
+                 
"https://www.gnu.org/software/emacs/manual/html_node/elisp/Backups-and-Auto_002dSaving.html";))
+  (should-error (Info-url-for-node "(gnus)Minibuffer File")))
+
+;;; info-tests.el ends here
diff --git a/test/lisp/mh-e/mh-utils-tests.el b/test/lisp/mh-e/mh-utils-tests.el
index ed97923..d9a26e5 100644
--- a/test/lisp/mh-e/mh-utils-tests.el
+++ b/test/lisp/mh-e/mh-utils-tests.el
@@ -152,7 +152,7 @@ select which."
 (defun mh-test-utils-setup ()
   "Set dynamically bound variables needed by mock and/or variants.
 Call `mh-variant-set' to look through the directories named by
-envionment variable `TEST_MH_PATH' (default: `mh-path' and `mh-sys-path')
+environment variable `TEST_MH_PATH' (default: `mh-path' and `mh-sys-path')
 to find the MH variant to use, if any.
 Return the name of the root of the created directory tree, if any."
   (when (getenv "TEST_MH_PATH")
diff --git a/test/lisp/net/tramp-archive-tests.el 
b/test/lisp/net/tramp-archive-tests.el
index 98012f4..a307a40 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -122,12 +122,6 @@ the origin of the temporary TMPFILE, have no write 
permissions."
      (directory-files tmpfile 'full directory-files-no-dot-files-regexp))
     (delete-directory tmpfile)))
 
-(defun tramp-archive--test-emacs26-p ()
-  "Check for Emacs version >= 26.1.
-Some semantics has been changed for there, w/o new functions or
-variables, so we check the Emacs version directly."
-  (>= emacs-major-version 26))
-
 (defun tramp-archive--test-emacs27-p ()
   "Check for Emacs version >= 27.1.
 Some semantics has been changed for there, w/o new functions or
@@ -265,21 +259,20 @@ variables, so we check the Emacs version directly."
               (concat
                (tramp-gvfs-url-file-name
                 (tramp-make-tramp-file-name
-                 tramp-archive-method
-                 ;; User and Domain.
-                 nil nil
-                 ;; Host.
-                 (url-hexify-string
-                  (concat
-                   "file://"
-                   ;; `directory-file-name' does not leave file
-                   ;; archive boundaries.  So we must cut the
-                   ;; trailing slash ourselves.
-                   (substring
-                    (file-name-directory
-                     (tramp-archive-test-file-archive-hexlified))
-                    0 -1)))
-                 nil "/"))
+                 (make-tramp-file-name
+                  :method tramp-archive-method
+                  :host
+                  (url-hexify-string
+                   (concat
+                    "file://"
+                    ;; `directory-file-name' does not leave file
+                    ;; archive boundaries.  So we must cut the
+                    ;; trailing slash ourselves.
+                    (substring
+                     (file-name-directory
+                      (tramp-archive-test-file-archive-hexlified))
+                     0 -1)))
+                  :localname "/")))
                (file-name-nondirectory tramp-archive-test-file-archive)))))
            (should-not port)
            (should (string-equal localname "/bar"))
@@ -434,7 +427,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
             (setq tmp-name
                   (file-local-copy
                    (expand-file-name "what" tramp-archive-test-archive)))
-            :type tramp-file-missing))
+            :type 'file-missing))
 
       ;; Cleanup.
       (ignore-errors (tramp-archive--test-delete tmp-name))
@@ -462,7 +455,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
          (should-error
           (insert-file-contents
            (expand-file-name "what" tramp-archive-test-archive))
-          :type tramp-file-missing))
+          :type 'file-missing))
 
        ;; Cleanup.
        (tramp-archive-cleanup-hash))))
@@ -553,11 +546,9 @@ This checks also `file-name-as-directory', 
`file-name-directory',
          (should (file-directory-p tmp-name2))
          (should (file-exists-p tmp-name4))
          ;; Target directory does exist already.
-         ;; This has been changed in Emacs 26.1.
-         (when (tramp-archive--test-emacs26-p)
-           (should-error
-            (copy-directory tmp-name1 tmp-name2)
-            :type 'file-error))
+         (should-error
+          (copy-directory tmp-name1 tmp-name2)
+          :type 'file-error)
          (tramp-archive--test-delete tmp-name4)
          (copy-directory tmp-name1 (file-name-as-directory tmp-name2))
          (should (file-directory-p tmp-name3))
@@ -622,13 +613,11 @@ This checks also `file-name-as-directory', 
`file-name-directory',
         (append '("LANG=C" "LANGUAGE=C" "LC_ALL=C") process-environment)))
     (unwind-protect
        (progn
-         ;; Due to Bug#29423, this works only since for Emacs 26.1.
-         (when nil ;; TODO (tramp-archive--test-emacs26-p)
-           (with-temp-buffer
-             (insert-directory tramp-archive-test-archive nil)
-             (goto-char (point-min))
-             (should
-              (looking-at-p (regexp-quote tramp-archive-test-archive)))))
+         (with-temp-buffer
+           (insert-directory tramp-archive-test-archive nil)
+           (goto-char (point-min))
+           (should
+            (looking-at-p (regexp-quote tramp-archive-test-archive))))
          (with-temp-buffer
            (insert-directory tramp-archive-test-archive "-al")
            (goto-char (point-min))
@@ -656,7 +645,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
            (should-error
             (insert-directory
              (expand-file-name "baz" tramp-archive-test-archive) nil)
-            :type tramp-file-missing)))
+            :type 'file-missing)))
 
       ;; Cleanup.
       (tramp-archive-cleanup-hash))))
@@ -716,7 +705,7 @@ This tests also `access-file', `file-readable-p' and 
`file-regular-p'."
          ;; Check error case.
          (should-error
           (access-file tmp-name4  "error")
-          :type tramp-file-missing))
+          :type 'file-missing))
 
       ;; Cleanup.
       (tramp-archive-cleanup-hash))))
@@ -855,38 +844,27 @@ This tests also `file-executable-p', `file-writable-p' 
and `set-file-modes'."
       ;; Cleanup.
       (tramp-archive-cleanup-hash))))
 
-;; The functions were introduced in Emacs 26.1.
 (ert-deftest tramp-archive-test40-make-nearby-temp-file ()
   "Check `make-nearby-temp-file' and `temporary-file-directory'."
   (skip-unless tramp-archive-enabled)
-  ;; Since Emacs 26.1.
-  (skip-unless
-   (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
 
-  ;; `make-nearby-temp-file' and `temporary-file-directory' exists
-  ;; since Emacs 26.1.  We don't want to see compiler warnings for
-  ;; older Emacsen.
   (let ((default-directory tramp-archive-test-archive)
        tmp-file)
     ;; The file archive shall know a temporary file directory.  It is
     ;; not in the archive itself.
-    (should
-     (stringp (with-no-warnings (with-no-warnings 
(temporary-file-directory)))))
-    (should-not
-     (tramp-archive-file-name-p (with-no-warnings (temporary-file-directory))))
+    (should (stringp (temporary-file-directory)))
+    (should-not (tramp-archive-file-name-p (temporary-file-directory)))
 
     ;; A temporary file or directory shall not be located in the
     ;; archive itself.
-    (setq tmp-file
-         (with-no-warnings (make-nearby-temp-file "tramp-archive-test")))
+    (setq tmp-file (make-nearby-temp-file "tramp-archive-test"))
     (should (file-exists-p tmp-file))
     (should (file-regular-p tmp-file))
     (should-not (tramp-archive-file-name-p tmp-file))
     (delete-file tmp-file)
     (should-not (file-exists-p tmp-file))
 
-    (setq tmp-file
-         (with-no-warnings (make-nearby-temp-file "tramp-archive-test" 'dir)))
+    (setq tmp-file (make-nearby-temp-file "tramp-archive-test" 'dir))
     (should (file-exists-p tmp-file))
     (should (file-directory-p tmp-file))
     (should-not (tramp-archive-file-name-p tmp-file))
@@ -910,7 +888,7 @@ This tests also `file-executable-p', `file-writable-p' and 
`set-file-modes'."
                 (zerop (nth 1 fsi))
                 (zerop (nth 2 fsi))))))
 
-(ert-deftest tramp-archive-test45-auto-load ()
+(ert-deftest tramp-archive-test46-auto-load ()
   "Check that `tramp-archive' autoloads properly."
   :tags '(:expensive-test)
   (skip-unless tramp-archive-enabled)
@@ -950,7 +928,7 @@ This tests also `file-executable-p', `file-writable-p' and 
`set-file-modes'."
            (mapconcat #'shell-quote-argument load-path " -L ")
            (shell-quote-argument (format code file))))))))))
 
-(ert-deftest tramp-archive-test45-delay-load ()
+(ert-deftest tramp-archive-test46-delay-load ()
   "Check that `tramp-archive' is loaded lazily, only when needed."
   :tags '(:expensive-test)
   (skip-unless tramp-archive-enabled)
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 3d6ce96..397e707 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -43,8 +43,10 @@
 
 (require 'cl-lib)
 (require 'dired)
+(require 'dired-aux)
 (require 'ert)
 (require 'ert-x)
+(require 'seq) ; For `seq-random-elt', autoloaded since Emacs 28.1
 (require 'trace)
 (require 'tramp)
 (require 'vc)
@@ -62,7 +64,6 @@
 (declare-function tramp-list-tramp-buffers "tramp-cmds")
 (declare-function tramp-method-out-of-band-p "tramp-sh")
 (declare-function tramp-smb-get-localname "tramp-smb")
-(declare-function dired-compress "dired-aux")
 (defvar ange-ftp-make-backup-files)
 (defvar auto-save-file-name-transforms)
 (defvar lock-file-name-transforms)
@@ -76,11 +77,6 @@
 (defvar tramp-remote-path)
 (defvar tramp-remote-process-environment)
 
-;; Needed for Emacs 25.
-(defvar connection-local-criteria-alist)
-(defvar connection-local-profile-alist)
-;; Needed for Emacs 26.
-(defvar async-shell-command-width)
 ;; Needed for Emacs 27.
 (defvar process-file-return-signal-string)
 (defvar shell-command-dont-erase-buffer)
@@ -2085,44 +2081,41 @@ Also see `ignore'."
       (substitute-in-file-name "/method:host:/:/path//foo")
       "/method:host:/:/path//foo"))
 
-    ;; Forwhatever reasons, the following tests let Emacs crash for
-    ;; Emacs 25, occasionally.  No idea what's up.
-    (when (tramp--test-emacs26-p)
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host://~" foo))
-       (concat "/~" foo)))
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host:/~" foo))
-       (concat "/method:host:/~" foo)))
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host:/path//~" foo))
-       (concat "/~" foo)))
-      ;; (substitute-in-file-name "/path/~foo") expands only for a local
-      ;; user "foo" to "/~foo"".  Otherwise, it doesn't expand.
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host:/path/~" foo))
-       (concat "/method:host:/path/~" foo)))
-      ;; Quoting local part.
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host:/://~" foo))
-       (concat "/method:host:/://~" foo)))
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host:/:/~" foo))
-       (concat "/method:host:/:/~" foo)))
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host:/:/path//~" foo))
-       (concat "/method:host:/:/path//~" foo)))
-      (should
-       (string-equal
-       (substitute-in-file-name (concat "/method:host:/:/path/~" foo))
-       (concat "/method:host:/:/path/~" foo))))
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host://~" foo))
+      (concat "/~" foo)))
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host:/~" foo))
+      (concat "/method:host:/~" foo)))
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host:/path//~" foo))
+      (concat "/~" foo)))
+    ;; (substitute-in-file-name "/path/~foo") expands only for a local
+    ;; user "foo" to "/~foo"".  Otherwise, it doesn't expand.
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host:/path/~" foo))
+      (concat "/method:host:/path/~" foo)))
+    ;; Quoting local part.
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host:/://~" foo))
+      (concat "/method:host:/://~" foo)))
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host:/:/~" foo))
+      (concat "/method:host:/:/~" foo)))
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host:/:/path//~" foo))
+      (concat "/method:host:/:/path//~" foo)))
+    (should
+     (string-equal
+      (substitute-in-file-name (concat "/method:host:/:/path/~" foo))
+      (concat "/method:host:/:/path/~" foo)))
 
     (let (process-environment)
       (should
@@ -2354,7 +2347,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
            (delete-file tmp-name2)
            (should-error
             (setq tmp-name2 (file-local-copy tmp-name1))
-            :type tramp-file-missing))
+            :type 'file-missing))
 
        ;; Cleanup.
        (ignore-errors
@@ -2393,7 +2386,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
            (delete-file tmp-name)
            (should-error
             (insert-file-contents tmp-name)
-            :type tramp-file-missing))
+            :type 'file-missing))
 
        ;; Cleanup.
        (ignore-errors (delete-file tmp-name))))))
@@ -2464,23 +2457,20 @@ This checks also `file-name-as-directory', 
`file-name-directory',
              (should (string-equal (buffer-string) "34")))
 
            ;; Check message.
-           ;; Macro `ert-with-message-capture' was introduced in Emacs 26.1.
-           (with-no-warnings (when (symbol-plist 'ert-with-message-capture)
-             (let (inhibit-message)
-               (dolist
-                   (noninteractive (unless (tramp--test-ange-ftp-p) '(nil t)))
-                 (dolist (visit '(nil t "string" no-message))
-                   (ert-with-message-capture tramp--test-messages
-                     (write-region "foo" nil tmp-name nil visit)
-                     ;; We must check the last line.  There could be
-                     ;; other messages from the progress reporter.
-                     (should
-                      (string-match-p
-                       (if (and (null noninteractive)
-                                (or (eq visit t) (null visit) (stringp visit)))
-                           (format "^Wrote %s\n\\'" (regexp-quote tmp-name))
-                         "^\\'")
-                       tramp--test-messages))))))))
+           (let (inhibit-message)
+             (dolist (noninteractive (unless (tramp--test-ange-ftp-p) '(nil 
t)))
+               (dolist (visit '(nil t "string" no-message))
+                 (ert-with-message-capture tramp--test-messages
+                   (write-region "foo" nil tmp-name nil visit)
+                   ;; We must check the last line.  There could be
+                   ;; other messages from the progress reporter.
+                   (should
+                    (string-match-p
+                     (if (and (null noninteractive)
+                              (or (eq visit t) (null visit) (stringp visit)))
+                         (format "^Wrote %s\n\\'" (regexp-quote tmp-name))
+                       "^\\'")
+                     tramp--test-messages))))))
 
            ;; We do not test lockname here.  See
            ;; `tramp-test39-make-lock-file-name'.
@@ -2490,17 +2480,15 @@ This checks also `file-name-as-directory', 
`file-name-directory',
                      ;; Ange-FTP.
                      ((symbol-function 'yes-or-no-p) #'tramp--test-always))
              (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
-           ;; `mustbenew' is passed to Tramp since Emacs 26.1.
-           (when (tramp--test-emacs26-p)
-             (should-error
-              (cl-letf (((symbol-function #'y-or-n-p) #'ignore)
-                        ;; Ange-FTP.
-                        ((symbol-function #'yes-or-no-p) #'ignore))
-                (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
-               :type 'file-already-exists)
-             (should-error
-              (write-region "foo" nil tmp-name nil nil nil 'excl)
-              :type 'file-already-exists)))
+           (should-error
+            (cl-letf (((symbol-function #'y-or-n-p) #'ignore)
+                      ;; Ange-FTP.
+                      ((symbol-function #'yes-or-no-p) #'ignore))
+              (write-region "foo" nil tmp-name nil nil nil 'mustbenew))
+             :type 'file-already-exists)
+           (should-error
+            (write-region "foo" nil tmp-name nil nil nil 'excl)
+            :type 'file-already-exists))
 
        ;; Cleanup.
        (ignore-errors (delete-file tmp-name))))))
@@ -2563,7 +2551,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
              (progn
                (should-error
                 (copy-file source target)
-                :type tramp-file-missing)
+                :type 'file-missing)
                (write-region "foo" nil source)
                (should (file-exists-p source))
                (copy-file source target)
@@ -2589,8 +2577,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
                (should (file-exists-p source))
                (make-directory target)
                (should (file-directory-p target))
-               ;; This has been changed in Emacs 26.1.
-               (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
+               (when (tramp--test-expensive-test)
                  (should-error
                   (copy-file source target)
                   :type 'file-already-exists)
@@ -2675,7 +2662,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
              (progn
                (should-error
                 (rename-file source target)
-                :type tramp-file-missing)
+                :type 'file-missing)
                (write-region "foo" nil source)
                (should (file-exists-p source))
                (rename-file source target)
@@ -2704,8 +2691,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
                (should (file-exists-p source))
                (make-directory target)
                (should (file-directory-p target))
-               ;; This has been changed in Emacs 26.1.
-               (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
+               (when (tramp--test-expensive-test)
                  (should-error
                   (rename-file source target)
                   :type 'file-already-exists)
@@ -2883,7 +2869,7 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
 (ert-deftest tramp-test15-copy-directory ()
   "Check `copy-directory'."
   (skip-unless (tramp--test-enabled))
-  (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+  (skip-unless (not (tramp--test-rclone-p)))
 
   (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
     (let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
@@ -2900,7 +2886,7 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
          (progn
            (should-error
             (copy-directory tmp-name1 tmp-name2)
-            :type tramp-file-missing)
+            :type 'file-missing)
            ;; Copy empty directory.
            (make-directory tmp-name1)
            (write-region "foo" nil tmp-name4)
@@ -2910,11 +2896,9 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
            (should (file-directory-p tmp-name2))
            (should (file-exists-p tmp-name5))
            ;; Target directory does exist already.
-           ;; This has been changed in Emacs 26.1.
-           (when (tramp--test-emacs26-p)
-             (should-error
-              (copy-directory tmp-name1 tmp-name2)
-              :type 'file-already-exists))
+           (should-error
+            (copy-directory tmp-name1 tmp-name2)
+            :type 'file-already-exists)
            (copy-directory tmp-name1 (file-name-as-directory tmp-name2))
            (should (file-directory-p tmp-name3))
            (should (file-exists-p tmp-name6)))
@@ -3004,7 +2988,7 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
          (progn
            (should-error
             (directory-files tmp-name1)
-            :type tramp-file-missing)
+            :type 'file-missing)
            (make-directory tmp-name1)
            (write-region "foo" nil tmp-name2)
            (write-region "bla" nil tmp-name3)
@@ -3127,14 +3111,12 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
              (insert-directory tmp-name1 nil)
              (goto-char (point-min))
              (should (looking-at-p (regexp-quote tmp-name1))))
-           ;; This has been fixed in Emacs 26.1.  See Bug#29423.
-           (when (tramp--test-emacs26-p)
-             (with-temp-buffer
-               (insert-directory (file-name-as-directory tmp-name1) nil)
-               (goto-char (point-min))
-               (should
-                 (looking-at-p
-                  (regexp-quote (file-name-as-directory tmp-name1))))))
+           (with-temp-buffer
+             (insert-directory (file-name-as-directory tmp-name1) nil)
+             (goto-char (point-min))
+             (should
+               (looking-at-p
+                (regexp-quote (file-name-as-directory tmp-name1)))))
            (with-temp-buffer
              (insert-directory tmp-name1 "-al")
              (goto-char (point-min))
@@ -3166,7 +3148,7 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
                       ;; modes are still "accessible".
                       (not (tramp--test-sshfs-p))
                       ;; A directory is always accessible for user "root".
-                      (not (zerop (tramp-compat-file-attribute-user-id
+                      (not (zerop (file-attribute-user-id
                                    (file-attributes tmp-name1)))))
              (set-file-modes tmp-name1 0)
              (with-temp-buffer
@@ -3178,7 +3160,7 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
            (with-temp-buffer
              (should-error
               (insert-directory tmp-name1 nil)
-              :type tramp-file-missing)))
+              :type 'file-missing)))
 
        ;; Cleanup.
        (ignore-errors (delete-directory tmp-name1 'recursive))))))
@@ -3192,8 +3174,6 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
   (skip-unless (not (tramp--test-rsync-p)))
   ;; Wildcards are not supported in tramp-crypt.el.
   (skip-unless (not (tramp--test-crypt-p)))
-  ;; Since Emacs 26.1.
-  (skip-unless (fboundp 'insert-directory-wildcard-in-dir-p))
 
   (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
     (let* ((tmp-name1
@@ -3381,15 +3361,14 @@ This tests also `access-file', `file-readable-p',
                             (file-modes tramp-test-temporary-file-directory))))
              (write-region "foo" nil tmp-name1)
              (setq test-file-ownership-preserved-p
-                   (= (tramp-compat-file-attribute-group-id
-                       (file-attributes tmp-name1))
+                   (= (file-attribute-group-id (file-attributes tmp-name1))
                       (tramp-get-remote-gid tramp-test-vec 'integer)))
              (delete-file tmp-name1))
 
            (when (tramp--test-supports-set-file-modes-p)
              (write-region "foo" nil tmp-name1)
              ;; A file is always accessible for user "root".
-             (when (not (zerop (tramp-compat-file-attribute-user-id
+             (when (not (zerop (file-attribute-user-id
                                 (file-attributes tmp-name1))))
                (set-file-modes tmp-name1 0)
                (should-error
@@ -3399,7 +3378,7 @@ This tests also `access-file', `file-readable-p',
              (delete-file tmp-name1))
            (should-error
             (access-file tmp-name1 "error")
-            :type tramp-file-missing)
+            :type 'file-missing)
 
            ;; `file-ownership-preserved-p' should return t for
            ;; non-existing files.
@@ -3416,33 +3395,29 @@ This tests also `access-file', `file-readable-p',
            ;; We do not test inodes and device numbers.
            (setq attr (file-attributes tmp-name1))
            (should (consp attr))
-           (should (null (tramp-compat-file-attribute-type attr)))
-           (should (numberp (tramp-compat-file-attribute-link-number attr)))
-           (should (numberp (tramp-compat-file-attribute-user-id attr)))
-           (should (numberp (tramp-compat-file-attribute-group-id attr)))
+           (should (null (file-attribute-type attr)))
+           (should (numberp (file-attribute-link-number attr)))
+           (should (numberp (file-attribute-user-id attr)))
+           (should (numberp (file-attribute-group-id attr)))
            (should
-            (stringp
-             (current-time-string
-              (tramp-compat-file-attribute-access-time attr))))
+            (stringp (current-time-string (file-attribute-access-time attr))))
            (should
             (stringp
-             (current-time-string
-              (tramp-compat-file-attribute-modification-time attr))))
+             (current-time-string (file-attribute-modification-time attr))))
            (should
             (stringp
-             (current-time-string
-              (tramp-compat-file-attribute-status-change-time attr))))
-           (should (numberp (tramp-compat-file-attribute-size attr)))
-           (should (stringp (tramp-compat-file-attribute-modes attr)))
+             (current-time-string (file-attribute-status-change-time attr))))
+           (should (numberp (file-attribute-size attr)))
+           (should (stringp (file-attribute-modes attr)))
 
            (setq attr (file-attributes tmp-name1 'string))
-           (should (stringp (tramp-compat-file-attribute-user-id attr)))
-           (should (stringp (tramp-compat-file-attribute-group-id attr)))
+           (should (stringp (file-attribute-user-id attr)))
+           (should (stringp (file-attribute-group-id attr)))
 
            (tramp--test-ignore-make-symbolic-link-error
              (should-error
               (access-file tmp-name2 "error")
-              :type tramp-file-missing)
+              :type 'file-missing)
              (when test-file-ownership-preserved-p
                (should (file-ownership-preserved-p tmp-name2 'group)))
              (make-symbolic-link tmp-name1 tmp-name2)
@@ -3456,7 +3431,7 @@ This tests also `access-file', `file-readable-p',
               (string-equal
                (funcall
                 (if quoted #'tramp-compat-file-name-quote #'identity)
-                (tramp-compat-file-attribute-type attr))
+                (file-attribute-type attr))
                (file-remote-p (file-truename tmp-name1) 'localname)))
              (delete-file tmp-name2))
 
@@ -3475,7 +3450,7 @@ This tests also `access-file', `file-readable-p',
              (setq attr (file-attributes tmp-name2))
              (should
               (string-equal
-               (tramp-compat-file-attribute-type attr)
+               (file-attribute-type attr)
                (tramp-file-name-localname
                 (tramp-dissect-file-name tmp-name3))))
              (delete-file tmp-name2))
@@ -3491,7 +3466,7 @@ This tests also `access-file', `file-readable-p',
            (when test-file-ownership-preserved-p
              (should (file-ownership-preserved-p tmp-name1 'group)))
            (setq attr (file-attributes tmp-name1))
-           (should (eq (tramp-compat-file-attribute-type attr) t)))
+           (should (eq (file-attribute-type attr) t)))
 
        ;; Cleanup.
        (ignore-errors (delete-directory tmp-name1))
@@ -3509,9 +3484,9 @@ They might differ only in time attributes or directory 
size."
        (start-time (- tramp--test-start-time 10)))
     ;; Link number.  For directories, it includes the number of
     ;; subdirectories.  Set it to 1.
-    (when (eq (tramp-compat-file-attribute-type attr1) t)
+    (when (eq (file-attribute-type attr1) t)
       (setcar (nthcdr 1 attr1) 1))
-    (when (eq (tramp-compat-file-attribute-type attr2) t)
+    (when (eq (file-attribute-type attr2) t)
       (setcar (nthcdr 1 attr2) 1))
     ;; Access time.
     (setcar (nthcdr 4 attr1) tramp-time-dont-know)
@@ -3524,42 +3499,33 @@ They might differ only in time attributes or directory 
size."
     ;; order to compensate a possible timestamp resolution higher than
     ;; a second on the remote machine.
     (when (or (tramp-compat-time-equal-p
-              (tramp-compat-file-attribute-modification-time attr1)
-              tramp-time-dont-know)
+              (file-attribute-modification-time attr1) tramp-time-dont-know)
              (tramp-compat-time-equal-p
-              (tramp-compat-file-attribute-modification-time attr2)
-              tramp-time-dont-know))
+              (file-attribute-modification-time attr2) tramp-time-dont-know))
       (setcar (nthcdr 5 attr1) tramp-time-dont-know)
       (setcar (nthcdr 5 attr2) tramp-time-dont-know))
     (when (< start-time
-            (float-time (tramp-compat-file-attribute-modification-time attr1)))
+            (float-time (file-attribute-modification-time attr1)))
       (setcar (nthcdr 5 attr1) tramp-time-dont-know))
     (when (< start-time
-            (float-time (tramp-compat-file-attribute-modification-time attr2)))
+            (float-time (file-attribute-modification-time attr2)))
       (setcar (nthcdr 5 attr2) tramp-time-dont-know))
     ;; Status change time.  Ditto.
     (when (or (tramp-compat-time-equal-p
-              (tramp-compat-file-attribute-status-change-time attr1)
-              tramp-time-dont-know)
+              (file-attribute-status-change-time attr1) tramp-time-dont-know)
              (tramp-compat-time-equal-p
-              (tramp-compat-file-attribute-status-change-time attr2)
-              tramp-time-dont-know))
+              (file-attribute-status-change-time attr2) tramp-time-dont-know))
       (setcar (nthcdr 6 attr1) tramp-time-dont-know)
       (setcar (nthcdr 6 attr2) tramp-time-dont-know))
-    (when
-       (< start-time
-          (float-time
-           (tramp-compat-file-attribute-status-change-time attr1)))
+    (when (< start-time (float-time (file-attribute-status-change-time attr1)))
       (setcar (nthcdr 6 attr1) tramp-time-dont-know))
-    (when
-       (< start-time
-          (float-time (tramp-compat-file-attribute-status-change-time attr2)))
+    (when (< start-time (float-time (file-attribute-status-change-time attr2)))
       (setcar (nthcdr 6 attr2) tramp-time-dont-know))
     ;; Size.  Set it to 0 for directories, because it might have
     ;; changed.  For example the upper directory "../".
-    (when (eq (tramp-compat-file-attribute-type attr1) t)
+    (when (eq (file-attribute-type attr1) t)
       (setcar (nthcdr 7 attr1) 0))
-    (when (eq (tramp-compat-file-attribute-type attr2) t)
+    (when (eq (file-attribute-type attr2) t)
       (setcar (nthcdr 7 attr2) 0))
     ;; The check.
     (unless (equal attr1 attr2) (tramp--test-message "%S\n%S" attr1 attr2))
@@ -3583,12 +3549,12 @@ They might differ only in time attributes or directory 
size."
          (progn
            (should-error
             (directory-files-and-attributes tmp-name1)
-            :type tramp-file-missing)
+            :type 'file-missing)
            (make-directory tmp-name1)
            (should (file-directory-p tmp-name1))
            (setq tramp--test-start-time
                  (float-time
-                  (tramp-compat-file-attribute-modification-time
+                  (file-attribute-modification-time
                    (file-attributes tmp-name1))))
            (make-directory tmp-name2)
            (should (file-directory-p tmp-name2))
@@ -3646,8 +3612,7 @@ This tests also `file-executable-p', `file-writable-p' 
and `set-file-modes'."
            (should (= (file-modes tmp-name1) #o444))
            (should-not (file-executable-p tmp-name1))
            ;; A file is always writable for user "root".
-           (unless (zerop (tramp-compat-file-attribute-user-id
-                           (file-attributes tmp-name1)))
+           (unless (zerop (file-attribute-user-id (file-attributes tmp-name1)))
              (should-not (file-writable-p tmp-name1)))
            ;; Check the NOFOLLOW arg.  It exists since Emacs 28.  For
            ;; regular files, there shouldn't be a difference.
@@ -3721,9 +3686,6 @@ This tests also `file-executable-p', `file-writable-p' 
and `set-file-modes'."
   "Check `file-symlink-p'.
 This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
   (skip-unless (tramp--test-enabled))
-  ;; The semantics have changed heavily in Emacs 26.1.  We cannot test
-  ;; older Emacsen, therefore.
-  (skip-unless (tramp--test-emacs26-p))
 
   (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
     ;; We must use `file-truename' for the temporary directory,
@@ -3940,11 +3902,11 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
              (when (tramp--test-expensive-test)
                (should-error
                 (with-temp-buffer (insert-file-contents tmp-name2))
-                :type tramp-file-missing))
+                :type 'file-missing))
              (when (tramp--test-expensive-test)
                (should-error
                 (with-temp-buffer (insert-file-contents tmp-name3))
-                :type tramp-file-missing))
+                :type 'file-missing))
              ;; `directory-files' does not show symlinks to
              ;; non-existing targets in the "smb" case.  So we remove
              ;; the symlinks manually.
@@ -4005,7 +3967,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
          (progn
            (write-region "foo" nil tmp-name1)
            (should (file-exists-p tmp-name1))
-           (should (consp (tramp-compat-file-attribute-modification-time
+           (should (consp (file-attribute-modification-time
                            (file-attributes tmp-name1))))
            ;; Skip the test, if the remote handler is not able to set
            ;; the correct time.
@@ -4013,13 +3975,12 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
            ;; Dumb remote shells without perl(1) or stat(1) are not
            ;; able to return the date correctly.  They say "don't know".
            (unless (tramp-compat-time-equal-p
-                    (tramp-compat-file-attribute-modification-time
+                    (file-attribute-modification-time
                      (file-attributes tmp-name1))
                     tramp-time-dont-know)
              (should
               (tramp-compat-time-equal-p
-                (tramp-compat-file-attribute-modification-time
-                (file-attributes tmp-name1))
+                (file-attribute-modification-time (file-attributes tmp-name1))
                (seconds-to-time 1)))
              (write-region "bla" nil tmp-name2)
              (should (file-exists-p tmp-name2))
@@ -4034,7 +3995,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
                  (set-file-times tmp-name1 (seconds-to-time 1) 'nofollow)
                  (should
                   (tramp-compat-time-equal-p
-                    (tramp-compat-file-attribute-modification-time
+                    (file-attribute-modification-time
                     (file-attributes tmp-name1))
                    (seconds-to-time 1)))))))
 
@@ -4948,8 +4909,6 @@ If UNSTABLE is non-nil, the test is tagged as 
`:unstable'."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
   (skip-unless (not (tramp--test-crypt-p)))
-  ;; Since Emacs 26.1.
-  (skip-unless (boundp 'interrupt-process-functions))
 
   ;; We must use `file-truename' for the temporary directory, in
   ;; order to establish the connection prior running an asynchronous
@@ -5364,9 +5323,6 @@ Use direct async.")
   ;; Since Emacs 27.1.
   (skip-unless (fboundp 'with-connection-local-variables))
 
-  ;; `connection-local-set-profile-variables' and
-  ;; `connection-local-set-profiles' exist since Emacs 26.1.  We don't
-  ;; want to see compiler warnings for older Emacsen.
   (let* ((default-directory tramp-test-temporary-file-directory)
         (tmp-name1 (tramp--test-make-temp-name))
         (tmp-name2 (expand-file-name "foo" tmp-name1))
@@ -5382,23 +5338,22 @@ Use direct async.")
 
          ;; `local-variable' is buffer-local due to explicit setting.
          (with-no-warnings
-           (defvar-local local-variable 'buffer))
+          (defvar-local local-variable 'buffer))
          (with-temp-buffer
            (should (eq local-variable 'buffer)))
 
          ;; `local-variable' is connection-local due to Tramp.
          (write-region "foo" nil tmp-name2)
          (should (file-exists-p tmp-name2))
-         (with-no-warnings
-           (connection-local-set-profile-variables
-            'local-variable-profile
-            '((local-variable . connect)))
-           (connection-local-set-profiles
-            `(:application tramp
-              :protocol ,(file-remote-p default-directory 'method)
-              :user ,(file-remote-p default-directory 'user)
-              :machine ,(file-remote-p default-directory 'host))
-            'local-variable-profile))
+         (connection-local-set-profile-variables
+          'local-variable-profile
+          '((local-variable . connect)))
+         (connection-local-set-profiles
+          `(:application tramp
+            :protocol ,(file-remote-p default-directory 'method)
+            :user ,(file-remote-p default-directory 'user)
+            :machine ,(file-remote-p default-directory 'host))
+          'local-variable-profile)
          (with-current-buffer (find-file-noselect tmp-name2)
            (should (eq local-variable 'connect))
            (kill-buffer (current-buffer)))
@@ -5423,7 +5378,6 @@ Use direct async.")
       ;; Cleanup.
       (ignore-errors (delete-directory tmp-name1 'recursive)))))
 
-;; The functions were introduced in Emacs 26.1.
 (ert-deftest tramp-test34-explicit-shell-file-name ()
   "Check that connection-local `explicit-shell-file-name' is set."
   :tags '(:expensive-test)
@@ -5433,13 +5387,7 @@ Use direct async.")
   ;; remote processes in Emacs.  That doesn't work for tramp-adb.el.
   (when (tramp--test-adb-p)
     (skip-unless (tramp--test-emacs27-p)))
-  ;; Since Emacs 26.1.
-  (skip-unless (and (fboundp 'connection-local-set-profile-variables)
-                   (fboundp 'connection-local-set-profiles)))
 
-  ;; `connection-local-set-profile-variables' and
-  ;; `connection-local-set-profiles' exist since Emacs 26.1.  We don't
-  ;; want to see compiler warnings for older Emacsen.
   (let ((default-directory tramp-test-temporary-file-directory)
        explicit-shell-file-name kill-buffer-query-functions
        connection-local-profile-alist connection-local-criteria-alist)
@@ -5448,19 +5396,16 @@ Use direct async.")
          ;; `shell-mode' would ruin our test, because it deletes all
          ;; buffer local variables.  Not needed in Emacs 27.1.
          (put 'explicit-shell-file-name 'permanent-local t)
-         ;; Declare connection-local variables `explicit-shell-file-name'
-         ;; and `explicit-sh-args'.
-         (with-no-warnings
-           (connection-local-set-profile-variables
-            'remote-sh
-            `((explicit-shell-file-name . ,(tramp--test-shell-file-name))
-              (explicit-sh-args . ("-c" "echo foo"))))
-           (connection-local-set-profiles
-            `(:application tramp
-              :protocol ,(file-remote-p default-directory 'method)
-              :user ,(file-remote-p default-directory 'user)
-              :machine ,(file-remote-p default-directory 'host))
-            'remote-sh))
+         (connection-local-set-profile-variables
+          'remote-sh
+          `((explicit-shell-file-name . ,(tramp--test-shell-file-name))
+            (explicit-sh-args . ("-c" "echo foo"))))
+         (connection-local-set-profiles
+          `(:application tramp
+            :protocol ,(file-remote-p default-directory 'method)
+            :user ,(file-remote-p default-directory 'user)
+            :machine ,(file-remote-p default-directory 'host))
+          'remote-sh)
          (put 'explicit-shell-file-name 'safe-local-variable #'identity)
          (put 'explicit-sh-args 'safe-local-variable #'identity)
 
@@ -5763,7 +5708,7 @@ Use direct async.")
            ;; files, owned by root.
            (let ((tramp-auto-save-directory temporary-file-directory))
              (write-region "foo" nil tmp-name1)
-             (when (zerop (or (tramp-compat-file-attribute-user-id
+             (when (zerop (or (file-attribute-user-id
                                (file-attributes tmp-name1))
                               tramp-unknown-id-integer))
                (with-temp-buffer
@@ -5910,8 +5855,7 @@ Use direct async.")
          (let ((backup-directory-alist `(("." . ,temporary-file-directory)))
                tramp-backup-directory-alist)
            (write-region "foo" nil tmp-name1)
-           (when (zerop (or (tramp-compat-file-attribute-user-id
-                             (file-attributes tmp-name1))
+           (when (zerop (or (file-attribute-user-id (file-attributes 
tmp-name1))
                             tramp-unknown-id-integer))
              (tramp-cleanup-connection
               tramp-test-vec 'keep-debug 'keep-password)
@@ -6047,8 +5991,7 @@ Use direct async.")
          ;; files, owned by root.
          (let ((lock-file-name-transforms auto-save-file-name-transforms))
            (write-region "foo" nil tmp-name1)
-           (when (zerop (or (tramp-compat-file-attribute-user-id
-                             (file-attributes tmp-name1))
+           (when (zerop (or (file-attribute-user-id (file-attributes 
tmp-name1))
                             tramp-unknown-id-integer))
              (tramp-cleanup-connection
               tramp-test-vec 'keep-debug 'keep-password)
@@ -6066,29 +6009,22 @@ Use direct async.")
        (ignore-errors (delete-file tmp-name1))
        (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)))))
 
-;; The functions were introduced in Emacs 26.1.
 (ert-deftest tramp-test40-make-nearby-temp-file ()
   "Check `make-nearby-temp-file' and `temporary-file-directory'."
   (skip-unless (tramp--test-enabled))
   (skip-unless (not (tramp--test-ange-ftp-p)))
-  ;; Since Emacs 26.1.
-  (skip-unless
-   (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory)))
 
-  ;; `make-nearby-temp-file' and `temporary-file-directory' exists
-  ;; since Emacs 26.1.  We don't want to see compiler warnings for
-  ;; older Emacsen.
   (let ((default-directory tramp-test-temporary-file-directory)
        tmp-file)
     ;; The remote host shall know a temporary file directory.
-    (should (stringp (with-no-warnings (temporary-file-directory))))
+    (should (stringp (temporary-file-directory)))
     (should
      (string-equal
       (file-remote-p default-directory)
-      (file-remote-p (with-no-warnings (temporary-file-directory)))))
+      (file-remote-p (temporary-file-directory))))
 
     ;; The temporary file shall be located on the remote host.
-    (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test")))
+    (setq tmp-file (make-nearby-temp-file "tramp-test"))
     (should (file-exists-p tmp-file))
     (should (file-regular-p tmp-file))
     (should
@@ -6098,18 +6034,12 @@ Use direct async.")
     (delete-file tmp-file)
     (should-not (file-exists-p tmp-file))
 
-    (setq tmp-file (with-no-warnings (make-nearby-temp-file "tramp-test" 
'dir)))
+    (setq tmp-file (make-nearby-temp-file "tramp-test" 'dir))
     (should (file-exists-p tmp-file))
     (should (file-directory-p tmp-file))
     (delete-directory tmp-file)
     (should-not (file-exists-p tmp-file))))
 
-(defun tramp--test-emacs26-p ()
-  "Check for Emacs version >= 26.1.
-Some semantics has been changed for there, w/o new functions or
-variables, so we check the Emacs version directly."
-  (>= emacs-major-version 26))
-
 (defun tramp--test-emacs27-p ()
   "Check for Emacs version >= 27.1.
 Some semantics has been changed for there, w/o new functions or
@@ -6122,6 +6052,12 @@ Some semantics has been changed for there, w/o new 
functions or
 variables, so we check the Emacs version directly."
   (>= emacs-major-version 28))
 
+(defun tramp--test-emacs29-p ()
+  "Check for Emacs version >= 29.1.
+Some semantics has been changed for there, w/o new functions or
+variables, so we check the Emacs version directly."
+  (>= emacs-major-version 29))
+
 (defun tramp--test-adb-p ()
   "Check, whether the remote host runs Android.
 This requires restrictions of file name syntax."
@@ -6337,7 +6273,7 @@ This requires restrictions of file name syntax."
                   (string-equal
                    (funcall
                     (if quoted #'tramp-compat-file-name-quote #'identity)
-                    (tramp-compat-file-attribute-type (file-attributes file3)))
+                    (file-attribute-type (file-attributes file3)))
                    (file-remote-p (file-truename file1) 'localname)))
                  ;; Check file contents.
                  (with-temp-buffer
@@ -6538,7 +6474,7 @@ This requires restrictions of file name syntax."
   (skip-unless (not (getenv "EMACS_HYDRA_CI"))) ; SLOW ~ 245s
   (skip-unless (tramp--test-enabled))
   (skip-unless (not (tramp--test-rsync-p)))
-  (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+  (skip-unless (not (tramp--test-rclone-p)))
 
   (tramp--test-special-characters))
 
@@ -6661,7 +6597,7 @@ Use the \"ls\" command."
   (skip-unless (not (tramp--test-ksh-p)))
   (skip-unless (not (tramp--test-gdrive-p)))
   (skip-unless (not (tramp--test-crypt-p)))
-  (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
+  (skip-unless (not (tramp--test-rclone-p)))
 
   (tramp--test-utf8))
 
@@ -6873,11 +6809,7 @@ process sentinels.  They shall not disturb each other."
                   (when buffers
                     (let ((time (float-time))
                           (default-directory tmp-name)
-                          (file
-                           (buffer-name
-                            ;; Use `seq-random-elt' once <26.1 support
-                            ;; is dropped.
-                            (nth (random (length buffers)) buffers)))
+                          (file (buffer-name (seq-random-elt buffers)))
                          ;; A remote operation in a timer could
                          ;; confuse Tramp heavily.  So we ignore this
                          ;; error here.
@@ -6942,8 +6874,7 @@ process sentinels.  They shall not disturb each other."
             ;; the buffers.  Mix with regular operation.
             (let ((buffers (copy-sequence buffers)))
               (while buffers
-                ;; Use `seq-random-elt' once <26.1 support is dropped.
-                (let* ((buf (nth (random (length buffers)) buffers))
+                (let* ((buf (seq-random-elt buffers))
                        (proc (get-buffer-process buf))
                        (file (process-get proc 'foo))
                        (count (process-get proc 'bar)))
@@ -7003,6 +6934,10 @@ process sentinels.  They shall not disturb each other."
   "Check that Tramp (un)compresses normal files."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
+  (skip-unless (not (tramp--test-crypt-p)))
+  ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
+  (skip-unless (not (tramp--test-emacs29-p)))
+
   (let ((default-directory tramp-test-temporary-file-directory)
         (tmp-name (tramp--test-make-temp-name)))
     (write-region "foo" nil tmp-name)
@@ -7019,6 +6954,10 @@ process sentinels.  They shall not disturb each other."
   "Check that Tramp (un)compresses directories."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
+  (skip-unless (not (tramp--test-crypt-p)))
+  ;; Starting with Emacs 29.1, `dired-compress-file' isn't magic anymore.
+  (skip-unless (not (tramp--test-emacs29-p)))
+
   (let ((default-directory tramp-test-temporary-file-directory)
         (tmp-name (tramp--test-make-temp-name)))
     (make-directory tmp-name)
@@ -7029,7 +6968,8 @@ process sentinels.  They shall not disturb each other."
     (should (string= (concat tmp-name ".tar.gz") (dired-get-filename)))
     (should-not (dired-compress))
     (should (string= tmp-name (dired-get-filename)))
-    (delete-directory tmp-name)))
+    (delete-directory tmp-name)
+    (delete-file (concat tmp-name ".tar.gz"))))
 
 ;; This test is inspired by Bug#29163.
 (ert-deftest tramp-test46-auto-load ()
@@ -7059,10 +6999,6 @@ process sentinels.  They shall not disturb each other."
 
 (ert-deftest tramp-test46-delay-load ()
   "Check that Tramp is loaded lazily, only when needed."
-  ;; The autoloaded Tramp objects are different since Emacs 26.1.  We
-  ;; cannot test older Emacsen, therefore.
-  (skip-unless (tramp--test-emacs26-p))
-
   ;; Tramp is neither loaded at Emacs startup, nor when completing a
   ;; non-Tramp file name like "/foo".  Completing a Tramp-alike file
   ;; name like "/foo:" autoloads Tramp, when `tramp-mode' is t.
@@ -7116,10 +7052,6 @@ process sentinels.  They shall not disturb each other."
 
 (ert-deftest tramp-test46-remote-load-path ()
   "Check that Tramp autoloads its packages with remote `load-path'."
-  ;; The autoloaded Tramp objects are different since Emacs 26.1.  We
-  ;; cannot test older Emacsen, therefore.
-  (skip-unless (tramp--test-emacs26-p))
-
   ;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el.
   ;; It shall still work, when a remote file name is in the
   ;; `load-path'.
@@ -7148,10 +7080,6 @@ process sentinels.  They shall not disturb each other."
 Since it unloads Tramp, it shall be the last test to run."
   :tags '(:expensive-test)
   (skip-unless noninteractive)
-  ;; The autoloaded Tramp objects are different since Emacs 26.1.  We
-  ;; cannot test older Emacsen, therefore.
-  (skip-unless (tramp--test-emacs26-p))
-
   ;; We have autoloaded objects from tramp.el and tramp-archive.el.
   ;; In order to remove them, we first need to load both packages.
   (require 'tramp)
@@ -7211,8 +7139,7 @@ If INTERACTIVE is non-nil, the tests are run 
interactively."
 
 ;; TODO:
 
-;; * dired-compress-file
-;; * dired-uncache
+;; * dired-uncache (partly done in other test functions)
 ;; * file-equal-p (partly done in `tramp-test21-file-links')
 ;; * file-in-directory-p
 ;; * file-name-case-insensitive-p
diff --git a/test/lisp/so-long-tests/so-long-tests.el 
b/test/lisp/so-long-tests/so-long-tests.el
index 7eee345..cda5ae4 100644
--- a/test/lisp/so-long-tests/so-long-tests.el
+++ b/test/lisp/so-long-tests/so-long-tests.el
@@ -32,7 +32,7 @@
 ;; Running manually:
 ;;
 ;; for test in lisp/so-long-tests/*-tests.el; do make ${test%.el}; done \
-;; 2>&1 | egrep -v '^(Loading|Source file|make|Changed to so-long-mode)'
+;; 2>&1 | grep -E -v '^(Loading|Source file|make|Changed to so-long-mode)'
 ;;
 ;; Which is equivalent to:
 ;;
@@ -41,7 +41,7 @@
 ;; "../src/emacs" --no-init-file --no-site-file --no-site-lisp \
 ;; -L ":." -l ert -l "$test" --batch --eval \
 ;; '(ert-run-tests-batch-and-exit (quote (not (tag :unstable))))'; \
-;; done 2>&1 | egrep -v '^(Loading|Source file|Changed to so-long-mode)'
+;; done 2>&1 | grep -E -v '^(Loading|Source file|Changed to so-long-mode)'
 ;;
 ;; See also `ert-run-tests-batch-and-exit'.
 



reply via email to

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