emacs-diffs
[Top][All Lists]
Advanced

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

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


From: Yuuki Harano
Subject: feature/pgtk 01b0a90: Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs into feature/pgtk
Date: Sun, 20 Jun 2021 05:24:13 -0400 (EDT)

branch: feature/pgtk
commit 01b0a909b5ca858a09484821cc866127652f4153
Merge: 11c835e a17f409
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
---
 doc/emacs/fixit.texi                     |   7 +
 doc/emacs/help.texi                      |   7 +
 doc/emacs/killing.texi                   |  13 +-
 doc/emacs/mini.texi                      |   8 +
 doc/lispref/commands.texi                |  11 +-
 doc/lispref/debugging.texi               |  13 +-
 doc/lispref/display.texi                 |   5 +-
 doc/lispref/modes.texi                   |   4 -
 doc/lispref/syntax.texi                  |   5 +
 doc/lispref/text.texi                    |   2 +-
 doc/lispref/windows.texi                 |  57 ++++---
 doc/misc/ert.texi                        |   4 +
 doc/misc/gnus.texi                       |  20 ++-
 doc/misc/tramp.texi                      |  17 +-
 etc/NEWS                                 |  41 ++++-
 lib-src/etags.c                          | 124 +++++++++-----
 lisp/bindings.el                         |   4 +-
 lisp/calendar/iso8601.el                 |  17 +-
 lisp/cedet/pulse.el                      |   6 +-
 lisp/delsel.el                           |   5 +-
 lisp/emacs-lisp/bytecomp.el              |  42 +++--
 lisp/emacs-lisp/cl-generic.el            |  10 +-
 lisp/emacs-lisp/ert.el                   |  31 +++-
 lisp/gnus/gnus-sum.el                    |  57 ++++++-
 lisp/gnus/gnus-topic.el                  |  39 +++--
 lisp/gnus/message.el                     |  11 +-
 lisp/gnus/mml.el                         |   2 +-
 lisp/help-fns.el                         |  67 +++++---
 lisp/help-mode.el                        |  39 ++++-
 lisp/mh-e/mh-junk.el                     |  26 +--
 lisp/mouse.el                            |   6 +-
 lisp/net/tramp-archive.el                |   2 +
 lisp/net/tramp-cache.el                  |   7 +-
 lisp/net/tramp-sh.el                     |   3 +-
 lisp/net/tramp.el                        | 103 ++++++++----
 lisp/play/morse.el                       |  21 ++-
 lisp/profiler.el                         |   8 +-
 lisp/progmodes/hideif.el                 |   2 +-
 lisp/simple.el                           |  41 +++--
 lisp/startup.el                          |   4 +-
 lisp/textmodes/reftex-vars.el            |   6 +-
 lisp/textmodes/sgml-mode.el              |  15 +-
 lisp/windmove.el                         | 111 ++++++++-----
 lisp/window.el                           |  82 ++++++----
 src/comp.c                               |   2 +-
 src/doprnt.c                             |   4 +-
 src/fileio.c                             |   3 +
 src/fns.c                                |   5 +-
 src/gnutls.c                             |  11 +-
 src/lisp.h                               |   4 +-
 src/pdumper.c                            |  27 +++-
 src/syntax.c                             |  18 +++
 src/xdisp.c                              |   2 +-
 src/xfaces.c                             |   9 +-
 test/lisp/calendar/iso8601-tests.el      |  10 +-
 test/lisp/filenotify-tests.el            |   5 +-
 test/lisp/net/tramp-archive-tests.el     |   1 +
 test/lisp/net/tramp-tests.el             |  85 ++++++++--
 test/lisp/shadowfile-tests.el            |   3 +
 test/lisp/textmodes/sgml-mode-tests.el   |  27 ++++
 test/manual/etags/CTAGS.good             |  31 +---
 test/manual/etags/ETAGS.good_1           | 149 ++++++++---------
 test/manual/etags/ETAGS.good_2           | 266 ++++++++++++++-----------------
 test/manual/etags/ETAGS.good_3           | 149 ++++++++---------
 test/manual/etags/ETAGS.good_4           | 149 ++++++++---------
 test/manual/etags/ETAGS.good_5           | 266 ++++++++++++++-----------------
 test/manual/etags/ETAGS.good_6           | 266 ++++++++++++++-----------------
 test/manual/etags/merc-src/accumulator.m |   8 +
 test/manual/indent/scss-mode.scss        |   6 +-
 test/src/syntax-tests.el                 |  11 ++
 70 files changed, 1534 insertions(+), 1088 deletions(-)

diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi
index acc0381..b558ebc 100644
--- a/doc/emacs/fixit.texi
+++ b/doc/emacs/fixit.texi
@@ -263,6 +263,13 @@ systems.
 @xref{Top, Aspell,, aspell, The Aspell Manual}.
 @end ifnottex
 
+@vindex ispell-program-name
+  If you have only one of the spelling checker programs installed,
+Emacs will find it when you invoke for the first time one of the
+commands described here.  If you have more than one of them installed,
+you can control which one is used by customizing the variable
+@code{ispell-program-name}.
+
 @table @kbd
 @item M-$
 Check and correct spelling of the word at point (@code{ispell-word}).
diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi
index 90a2ddc..f144fd2 100644
--- a/doc/emacs/help.texi
+++ b/doc/emacs/help.texi
@@ -451,6 +451,13 @@ Go forward to the next help topic (@code{help-go-forward}).
 @item C-c C-b
 @itemx l
 Go back to the previous help topic (@code{help-go-back}).
+@item s
+View the source of the current help topic (if any)
+(@code{help-view-source}).
+@item i
+Look up the current topic in the manual(s) (@code{help-goto-info}).
+@item c
+Customize the variable or the face (@code{help-customize}).
 @end table
 
 @cindex hyperlink
diff --git a/doc/emacs/killing.texi b/doc/emacs/killing.texi
index 56763b2..4291afe 100644
--- a/doc/emacs/killing.texi
+++ b/doc/emacs/killing.texi
@@ -522,11 +522,14 @@ clipboard.
 
 @vindex save-interprogram-paste-before-kill
   When an Emacs kill command puts text in the clipboard, the existing
-clipboard contents are normally lost.  Optionally, you can change
-@code{save-interprogram-paste-before-kill} to @code{t}.  Then Emacs
-will first save the clipboard to its kill ring, preventing you from
-losing the old clipboard data---at the risk of high memory consumption
-if that data turns out to be large.
+clipboard contents are normally lost.  Optionally, Emacs can save the
+existing clipboard contents to the kill ring, preventing you from
+losing the old clipboard data.  If
+@code{save-interprogram-paste-before-kill} changed to a number, then
+this data is copied over if it's smaller (in characters) than this
+number.  If this variable is any other non-@code{nil} value, it's
+always copied over---at the risk of high memory consumption if that
+data turns out to be large.
 
   Yank commands, such as @kbd{C-y} (@code{yank}), also use the
 clipboard.  If another application ``owns'' the clipboard---i.e., if
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 2fdb1e7..6dcee3f 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -630,6 +630,14 @@ in a cyclic manner.  If you give 
@code{completion-cycle-threshold} a
 numeric value @var{n}, completion commands switch to this cycling
 behavior only when there are @var{n} or fewer alternatives.
 
+@vindex completions-format
+  When displaying completions, Emacs will normally pop up a new buffer
+to display the completions.  The completions will (by default) be
+sorted in columns horizontally in alphabetical order, but this can be
+changed by changing the @code{completions-format} user option.  If
+@code{vertical}, sort the completions vertically in columns instead,
+and if @code{one-column}, just use a single column.
+
 @node Minibuffer History
 @section Minibuffer History
 @cindex minibuffer history
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 8199ece..f30419c 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -454,10 +454,13 @@ This kind of input is used by commands such as 
@code{describe-key} and
 @code{global-set-key}.
 
 @item K
-A key sequence, whose definition you intend to change.  This works like
-@samp{k}, except that it suppresses, for the last input event in the key
-sequence, the conversions that are normally used (when necessary) to
-convert an undefined key into a defined one.
+A key sequence on a form that can be used as input to functions like
+@code{define-key}.  This works like @samp{k}, except that it
+suppresses, for the last input event in the key sequence, the
+conversions that are normally used (when necessary) to convert an
+undefined key into a defined one (@pxref{Key Sequence Input}), so this
+form is usually used when prompting for a new key sequence that is to
+be bound to a command.
 
 @item m
 @cindex marker argument
diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi
index de98d22..e458d76 100644
--- a/doc/lispref/debugging.texi
+++ b/doc/lispref/debugging.texi
@@ -997,11 +997,12 @@ start looking for ways to optimize that piece.
 @findex profiler-report
 @findex profiler-stop
 Emacs has built-in support for this.  To begin profiling, type
-@kbd{M-x profiler-start}.  You can choose to profile by processor
-usage, memory usage, or both.  Then run the code you'd like to speed
-up.  After that, type @kbd{M-x profiler-report} to display a summary
-buffer for each resource (cpu and memory) that you chose to profile.
-The names of the report buffers include the times at which the reports
+@w{@kbd{M-x profiler-start}}.  You can choose to sample CPU usage
+periodically (@code{cpu}), when memory is allocated (@code{memory}),
+or both.  Then run the code you'd like to speed up.  After that, type
+@kbd{M-x profiler-report} to display a summary buffer for CPU usage
+sampled by each type (cpu and memory) that you chose to profile.  The
+names of the report buffers include the times at which the reports
 were generated, so you can generate another report later on without
 erasing previous results.  When you have finished profiling, type
 @kbd{M-x profiler-stop} (there is a small overhead associated with
@@ -1009,7 +1010,7 @@ profiling, so we don't recommend leaving it active except 
when you are
 actually running the code you want to examine).
 
 The profiler report buffer shows, on each line, a function that was
-called, preceded by how much resources (cpu or memory) it used in
+called, preceded by how much CPU resources it used in
 absolute and percentage terms since profiling started.  If a given
 line has a @samp{+} symbol to the left of the function name, you can
 expand that line by typing @kbd{@key{RET}}, in order to see the
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 2ed03f6..3336338 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -3007,9 +3007,10 @@ This function returns non-@code{nil} if face @var{face} 
specifies
 a non-@code{nil} @code{:inverse-video} attribute.
 @end defun
 
-@defun face-extend-p face &optional frame
+@defun face-extend-p face &optional frame inherit
 This function returns non-@code{nil} if face @var{face} specifies
-a non-@code{nil} @code{:extend} attribute.
+a non-@code{nil} @code{:extend} attribute.  The @var{inherit} argument
+is passed to @code{face-attribute}.
 @end defun
 
 
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 02064e7..5869f53 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -2985,10 +2985,6 @@ highlighted (instead of the entire text that 
@var{matcher} matched).
 ("fu\\(bar\\)" . 1)
 @end example
 
-If you use @code{regexp-opt} to produce the regular expression
-@var{matcher}, you can use @code{regexp-opt-depth} (@pxref{Regexp
-Functions}) to calculate the value for @var{subexp}.
-
 @item (@var{matcher} . @var{facespec})
 In this kind of element, @var{facespec} is an expression whose value
 specifies the face to use for highlighting.  In the simplest case,
diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi
index bde7075..deec3f4 100644
--- a/doc/lispref/syntax.texi
+++ b/doc/lispref/syntax.texi
@@ -1047,6 +1047,11 @@ Given a syntax descriptor @var{desc} (a string), this 
function returns
 the corresponding raw syntax descriptor.
 @end defun
 
+@defun syntax-class-to-char syntax
+Given a raw syntax descriptor @var{syntax} (an integer), this function
+returns the corresponding syntax descriptor (a character).
+@end defun
+
 @defun syntax-after pos
 This function returns the raw syntax descriptor for the character in
 the buffer after position @var{pos}, taking account of syntax
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index c90a959..0c87a19 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -4166,7 +4166,7 @@ file names only:
 If the condition value is anything else, then the position is inside a
 link and the condition itself is the action code.  Clearly, you should
 specify this kind of condition only when applying the condition via a
-text or property overlay on the link text (so that it does not apply
+text or overlay property on the link text (so that it does not apply
 to the entire buffer).
 @end table
 
diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 3b6f74b..26f85df 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -2191,12 +2191,13 @@ the name of an existing buffer; if omitted or 
@code{nil}, it defaults to
 the current buffer.
 
 The replacement buffer in each window is chosen via
-@code{switch-to-prev-buffer} (@pxref{Window History}).  Any dedicated
-window displaying @var{buffer-or-name} is deleted if possible
-(@pxref{Dedicated Windows}).  If such a window is the only window on its
-frame and there are other frames on the same terminal, the frame is
-deleted as well.  If the dedicated window is the only window on the only
-frame on its terminal, the buffer is replaced anyway.
+@code{switch-to-prev-buffer} (@pxref{Window History}).  With the
+exception of side windows (@pxref{Side Windows}), any dedicated window
+displaying @var{buffer-or-name} is deleted if possible (@pxref{Dedicated
+Windows}).  If such a window is the only window on its frame and there
+are other frames on the same terminal, the frame is deleted as well.
+If the dedicated window is the only window on the only frame on its
+terminal, the buffer is replaced anyway.
 @end deffn
 
 
@@ -3013,6 +3014,8 @@ If non-@code{nil}, such an entry tells 
@code{display-buffer} to mark
 any window it creates as dedicated to its buffer (@pxref{Dedicated
 Windows}).  It does that by calling @code{set-window-dedicated-p} with
 the chosen window as first argument and the entry's value as second.
+Side windows are by default dedicated with the value @code{side}
+((@pxref{Side Window Options and Functions}).
 
 @vindex preserve-size@r{, a buffer display action alist entry}
 @item preserve-size
@@ -4061,18 +4064,19 @@ slightly different, see below.
 
    Functions supposed to remove a buffer from a window or a window from
 a frame can behave specially when a window they operate on is dedicated.
-We will distinguish three basic cases, namely where (1) the window is
+We will distinguish four basic cases, namely where (1) the window is
 not the only window on its frame, (2) the window is the only window on
-its frame but there are other frames on the same terminal left, and (3)
-the window is the only window on the only frame on the same terminal.
+its frame but there are other frames on the same terminal left, (3)
+the window is the only window on the only frame on the same terminal,
+and (4) the dedication's value is @code{side}
+(@pxref{Displaying Buffers in Side Windows}).
 
    In particular, @code{delete-windows-on} (@pxref{Deleting Windows})
-handles case (2) by deleting the associated frame and case (3) by
-showing another buffer in that frame's only window.  The function
+handles case (2) by deleting the associated frame and cases (3) and (4)
+by showing another buffer in that frame's only window.  The function
 @code{replace-buffer-in-windows} (@pxref{Buffers and Windows}) which is
 called when a buffer gets killed, deletes the window in case (1) and
 behaves like @code{delete-windows-on} otherwise.
-@c FIXME: Does replace-buffer-in-windows _delete_ a window in case (1)?
 
    When @code{bury-buffer} (@pxref{Buffer List}) operates on the
 selected window (which shows the buffer that shall be buried), it
@@ -4335,6 +4339,25 @@ means to use a slot following (that is, below or on the 
right of) the
 middle slot.  Hence, all windows on a specific side are ordered by their
 @code{slot} value.  If unspecified, the window is located in the middle
 of the specified side.
+
+@item dedicated
+The dedicated flag (@pxref{Dedicated Windows}) has a slightly different
+meaning for side windows.  When a side window is created, that flag is
+set to the value @code{side} to prevent @code{display-buffer} to use the
+window in other action functions.  Its value persists across invocations
+of @code{quit-window}, @code{kill-buffer}, @code{previous-buffer} and
+@code{next-buffer}.
+
+In particular, these commands will refrain from showing, in a side
+window, buffers that have not been displayed in that window before.
+They will also refrain from having a normal, non-side window show a
+buffer that has been already displayed in a side window.  A notable
+exception to the latter rule occurs when an application, after
+displaying a buffer, resets that buffer’s local variables.  To override
+these rules and always delete a side window with @code{quit-window} or
+@code{kill-buffer}, and eventually prevent the use of
+@code{previous-buffer} and @code{next-buffer}, set this value to
+@code{t} or specify a value via @code{display-buffer-mark-dedicated}.
 @end table
 
 If you specify the same slot on the same side for two or more different
@@ -4355,16 +4378,6 @@ Functions}) unless it is explicitly specified as target 
of that
 action.  Note also that @code{delete-other-windows} cannot make a side
 window the only window on its frame (@pxref{Deleting Windows}).
 
-   Once set up, side windows also change the behavior of the commands
-@code{switch-to-prev-buffer} and @code{switch-to-next-buffer}
-(@pxref{Window History}).  In particular, these commands will refrain
-from showing, in a side window, buffers that have not been displayed in
-that window before.  They will also refrain from having a normal,
-non-side window show a buffer that has been already displayed in a side
-window.  A notable exception to the latter rule occurs when an
-application, after displaying a buffer, resets that buffer's local
-variables.
-
 
 @node Side Window Options and Functions
 @subsection Side Window Options and Functions
diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi
index a4e2cb5..fafdb8c 100644
--- a/doc/misc/ert.texi
+++ b/doc/misc/ert.texi
@@ -347,6 +347,10 @@ emacs -batch -l ert -l my-tests.el \
       -eval '(ert-run-tests-batch-and-exit "to-match")'
 @end example
 
+By default, ERT test failure summaries are quite brief in batch
+mode--only the names of the failed tests are listed.  If the
+EMACS_TEST_VERBOSE environment variable is set, the failure summaries
+will also include the data from the failing test.
 
 @node Test Selectors
 @section Test Selectors
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index b63947c..c9b5b2d 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -4126,6 +4126,8 @@ Visibility.
 Level.
 @item g
 Number of groups in the topic.
+@item G
+Number of groups in the topic and all its subtopics.
 @item a
 Number of unread articles in the topic.
 @item A
@@ -7525,6 +7527,7 @@ Matching}).
 @findex gnus-thread-sort-by-author
 @findex gnus-thread-sort-by-recipient
 @findex gnus-thread-sort-by-number
+@findex gnus-thread-sort-by-newsgroups
 @findex gnus-thread-sort-by-random
 @vindex gnus-thread-sort-functions
 @findex gnus-thread-sort-by-most-recent-number
@@ -7542,6 +7545,7 @@ predicate functions include 
@code{gnus-thread-sort-by-number},
 @code{gnus-thread-sort-by-score},
 @code{gnus-thread-sort-by-most-recent-number},
 @code{gnus-thread-sort-by-most-recent-date},
+@code{gnus-thread-sort-by-newsgroups} and
 @code{gnus-thread-sort-by-random} and
 @code{gnus-thread-sort-by-total-score}.
 
@@ -7603,6 +7607,7 @@ tickles your fancy.
 @findex gnus-article-sort-by-score
 @findex gnus-article-sort-by-subject
 @findex gnus-article-sort-by-author
+@findex gnus-article-sort-by-newsgroups
 @findex gnus-article-sort-by-random
 @findex gnus-article-sort-by-number
 @findex gnus-article-sort-by-most-recent-number
@@ -7614,8 +7619,8 @@ different functions for article comparison.  Available 
sorting
 predicate functions are @code{gnus-article-sort-by-number},
 @code{gnus-article-sort-by-author},
 @code{gnus-article-sort-by-subject}, @code{gnus-article-sort-by-date},
-@code{gnus-article-sort-by-random}, and
-@code{gnus-article-sort-by-score}.
+@code{gnus-article-sort-by-newsgroups}, @code{gnus-article-sort-by-random},
+and @code{gnus-article-sort-by-score}.
 
 If you want to sort an unthreaded summary display by subject, you could
 say something like:
@@ -10403,6 +10408,17 @@ Sort by article ``readedness'' marks 
(@code{gnus-summary-sort-by-marks}).
 @findex gnus-summary-sort-by-score
 Sort by score (@code{gnus-summary-sort-by-score}).
 
+@item C-c C-s C-u
+@kindex C-c C-s C-u @r{(Summary)}
+@findex gnus-summary-sort-by-newsgroups
+Sort by newsgroups (@code{gnus-summary-sort-by-newsgroups}).
+
+@item C-c C-s C-x
+@kindex C-c C-s C-x @r{(Summary)}
+@findex gnus-summary-sort-by-extra
+Prompts for extra header to sort by (@code{gnus-summary-sort-by-extra}).
+An error will be raised if no sort functions for the header are defined.
+
 @item C-c C-s C-r
 @kindex C-c C-s C-r @r{(Summary)}
 @findex gnus-summary-sort-by-random
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index e5a0bb9..6ef9459 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -1261,7 +1261,7 @@ uses @file{@trampfn{mtp,,}} as the default name.
 As the name indicates, the method @option{nextcloud} allows you to
 access OwnCloud or NextCloud hosted files and directories.  Like the
 @option{gdrive} method, your credentials must be populated in your
-@command{Online Accounts} application outside Emacs. The method
+@command{Online Accounts} application outside Emacs.  The method
 supports port numbers.
 
 @item @option{sftp}
@@ -2842,6 +2842,13 @@ auto-saved files to the same directory as the original 
file.
 Alternatively, set the user option @code{tramp-auto-save-directory}
 to direct all auto saves to that location.
 
+@vindex tramp-allow-unsafe-temporary-files
+Per default, @value{tramp} asks for confirmation if a
+@samp{root}-owned backup or auto-save remote file has to be written to
+your local temporary directory.  If you want to suppress this
+confirmation question, set user option
+@code{tramp-allow-unsafe-temporary-files} to @code{t}.
+
 
 @node Keeping files encrypted
 @section Protect remote files by encryption
@@ -3309,12 +3316,12 @@ For ad-hoc definitions to be saved automatically in
 
 Ad-hoc proxies can take patterns @code{%h} or @code{%u} like in
 @code{tramp-default-proxies-alist}.  The following file name expands
-to user @code{root} on host @code{remotehost}, starting with an
-@option{ssh} session on host @code{remotehost}:
+to user @samp{root} on host @samp{remotehost}, starting with an
+@option{ssh} session on host @samp{remotehost}:
 
@samp{@value{prefix}ssh@value{postfixhop}%h|su@value{postfixhop}remotehost@value{postfix}}.
 
 On the other hand, if a trailing hop does not specify a host name,
-the host name of the previous hop is reused. Therefore, the following
+the host name of the previous hop is reused.  Therefore, the following
 file name is equivalent to the previous example:
 
@samp{@value{prefix}ssh@value{postfixhop}remotehost|su@value{postfixhop}@value{postfix}}.
 
@@ -5294,7 +5301,7 @@ attributes cache in its process sentinel with this code:
 @end lisp
 
 Since @value{tramp} traverses subdirectories starting with the
-root-directory, it is most likely sufficient to make the
+root directory, it is most likely sufficient to make the
 @code{default-directory} of the process buffer as the root directory.
 
 
diff --git a/etc/NEWS b/etc/NEWS
index 1693342..889a0e6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -605,7 +605,7 @@ These options include 'windmove-default-keybindings',
 ** Windows
 
 +++
-*** New option 'delete-window-choose-selected'.
+*** New user option 'delete-window-choose-selected'.
 This allows to choose a frame's selected window after deleting the
 previously selected one.
 
@@ -898,6 +898,12 @@ String or list of strings specifying switches for Git log 
under VC.
 ** Gnus
 
 +++
+*** New Summary buffer sort options for extra headers.
+The extra header sort option ('C-c C-s C-x') prompts for a header
+and fails if no sort function has been defined. Sorting by
+Newsgroups ('C-c C-s C-u') has been pre-defined.
+
++++
 *** The '#' command in the Group and Summary buffer now toggles,
 instead of sets, the process mark.
 
@@ -1124,6 +1130,14 @@ This change is for better compatibility with old 
versions of non-GNU
 
 ** Help
 
++++
+*** New convenience commands with short keys in the Help buffer.
+New command 'help-view-source' ('s') will view the source file (if
+any) of the current help topic.  New command 'help-goto-info' ('i')
+will look up the current symbol (if any) in Info.  New command
+'help-customize' ('c') will customize the variable or the face
+(if any) whose doc string is being shown in the Help buffer.
+
 ---
 *** The 'help-for-help' ('C-h C-h') screen has been redesigned.
 
@@ -1403,6 +1417,11 @@ When non-nil, this user option instructs Tramp to mirror 
the debug
 buffer to a file under the "/tmp/" directory.  This is useful, if (in
 rare cases) Tramp blocks Emacs, and we need further debug information.
 
++++
+*** Writing sensitive auto-save or backup files to the local temporary
+directory must be confirmed.  In order to suppress this confirmation,
+set user option 'tramp-allow-unsafe-temporary-files' to t.
+
 ** Tempo
 
 ---
@@ -2085,8 +2104,22 @@ This allows mode-specific alterations to how 
'thing-at-point' works.
 This is so 'C-a' works as in other modes, and in particular holding
 Shift while typing 'C-a', i.e. 'C-S-a', will now highlight the text.
 
+** ERT
+
++++
+*** ERT can now output more verbose test failure reports.
+If the EMACS_TEST_VERBOSE environment variable is set, failure
+summaries will include the failing condition.
+
 ** Miscellaneous
 
++++
+*** 'save-interprogram-paste-before-kill' can now be a number.
+In that case, it's interpreted as a limit on the size of the clipboard
+data that will be saved to the 'kill-ring' prior to killing text: if
+the size of the clipboard data is greater than or equal to the limit,
+it will not be saved.
+
 ---
 *** New variable 'hl-line-overlay-priority'.
 This can be used to change the priority of the hl-line overlays.
@@ -2832,6 +2865,12 @@ customize them.
 * Lisp Changes in Emacs 28.1
 
 +++
+** New function 'syntax-class-to-char'.
+This does almost the opposite of 'string-to-syntax' -- it returns the
+syntax descriptor (a character) given a raw syntax descriptor (an
+integer).
+
++++
 ** New function 'buffer-local-boundp'.
 This predicate says whether a symbol is bound in a specific buffer.
 
diff --git a/lib-src/etags.c b/lib-src/etags.c
index 9f20e44c..c39c93d 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -6081,10 +6081,10 @@ prolog_atom (char *s, size_t pos)
              pos++;
              if (s[pos] != '\'')
                break;
-             pos++;            /* A double quote */
+             pos++;            /* A double quote  */
            }
          else if (s[pos] == '\0')
-           /* Multiline quoted atoms are ignored. */
+           /* Multiline quoted atoms are ignored.  */
            return 0;
          else if (s[pos] == '\\')
            {
@@ -6119,6 +6119,13 @@ static void mercury_skip_comment (linebuffer *, FILE *);
 static bool is_mercury_type = false;
 static bool is_mercury_quantifier = false;
 static bool is_mercury_declaration = false;
+typedef struct
+{
+  size_t pos;          /* Position reached in parsing tag name.  */
+  size_t namelength;   /* Length of tag name  */
+  size_t totlength;    /* Total length of parsed tag: this field is currently
+                         reserved for control and debugging.   */
+} mercury_pos_t;
 
 /*
  * Objective-C and Mercury have identical file extension .m.
@@ -6374,10 +6381,12 @@ static const char *Mercury_decl_tags[] = {"type", 
"solver type", "pred",
   "initialise", "finalise", "mutable", "module", "interface", "implementation",
   "import_module", "use_module", "include_module", "end_module", "some", 
"all"};
 
-static size_t
+static mercury_pos_t
 mercury_decl (char *s, size_t pos)
 {
-  if (s == NULL) return 0;
+  mercury_pos_t null_pos = {0, 0, 0};
+
+  if (s == NULL) return null_pos;
 
   size_t origpos;
   origpos = pos;
@@ -6398,7 +6407,8 @@ mercury_decl (char *s, size_t pos)
   if (is_mercury_quantifier)
     {
       if (strcmp (buf, "pred") != 0 && strcmp (buf, "func") != 0) /* Bad 
syntax.  */
-       return 0;
+       return null_pos;
+
       is_mercury_quantifier = false; /* Reset to base value.  */
       found_decl_tag = true;
     }
@@ -6418,7 +6428,7 @@ mercury_decl (char *s, size_t pos)
                  is_mercury_quantifier = true;
                }
 
-             break;  /* Found declaration tag of rank j. */
+             break;  /* Found declaration tag of rank j.  */
            }
          else
            /* 'solver type' has a blank in the middle,
@@ -6461,24 +6471,36 @@ mercury_decl (char *s, size_t pos)
       if (found_decl_tag)
        pos = skip_spaces (s + pos) - s; /* Skip len blanks again.  */
       else
-       return 0;
+       return null_pos;
     }
 
   /* From now on it is the same as for Prolog except for module dots.  */
 
+  size_t start_of_name = pos;
+
   if (c_islower (s[pos]) || s[pos] == '_' )
     {
       /* The name is unquoted.
          Do not confuse module dots with end-of-declaration dots.  */
+      int module_dot_pos = 0;
 
       while (c_isalnum (s[pos])
              || s[pos] == '_'
              || (s[pos] == '.' /* A module dot.  */
                  && s + pos + 1 != NULL
-                 && (c_isalnum (s[pos + 1]) || s[pos + 1] == '_')))
+                 && (c_isalnum (s[pos + 1]) || s[pos + 1] == '_')
+                && (module_dot_pos = pos)))  /* Record module dot position.
+                                                Erase module from name.  */
        ++pos;
 
-      return pos - origpos;
+      if (module_dot_pos)
+       {
+         start_of_name = module_dot_pos + 2;
+         ++pos;
+        }
+
+      mercury_pos_t position = {pos, pos - start_of_name + 1, pos - origpos};
+      return position;
     }
   else if (s[pos] == '\'')
     {
@@ -6493,28 +6515,37 @@ mercury_decl (char *s, size_t pos)
              ++pos; /* A double quote.  */
            }
          else if (s[pos] == '\0')  /* Multiline quoted atoms are ignored.  */
-           return 0;
+           return null_pos;
          else if (s[pos] == '\\')
            {
              if (s[pos+1] == '\0')
-               return 0;
+               return null_pos;
              pos += 2;
            }
          else
            ++pos;
        }
-      return pos - origpos;
+
+      mercury_pos_t position = {pos, pos - start_of_name + 1, pos - origpos};
+      return position;
     }
   else if (is_mercury_quantifier && s[pos] == '[')   /* :- some [T] pred/func. 
 */
     {
       for (++pos; s + pos != NULL && s[pos] != ']'; ++pos) {}
-      if (s + pos == NULL) return 0;
+      if (s + pos == NULL) return null_pos;
       ++pos;
       pos = skip_spaces (s + pos) - s;
-      return mercury_decl (s, pos) + pos - origpos;
+      mercury_pos_t position = mercury_decl (s, pos);
+      position.totlength += pos - origpos;
+      return position;
+    }
+  else if (s[pos] == '.')  /* as in ':- interface.'  */
+    {
+      mercury_pos_t position = {pos, pos - origpos + 1, pos - origpos};
+      return position;
     }
   else
-    return 0;
+    return null_pos;
 }
 
 static ptrdiff_t
@@ -6523,6 +6554,7 @@ mercury_pr (char *s, char *last, ptrdiff_t lastlen)
   size_t len0 = 0;
   is_mercury_type = false;
   is_mercury_quantifier = false;
+  bool stop_at_rule = false;
 
   if (is_mercury_declaration)
     {
@@ -6530,38 +6562,44 @@ mercury_pr (char *s, char *last, ptrdiff_t lastlen)
       len0 = skip_spaces (s + 2) - s;
     }
 
-  size_t len = mercury_decl (s, len0);
-  if (len == 0) return 0;
-  len += len0;
-
-  if (( (s[len] == '.'  /* This is a statement dot, not a module dot.  */
-        || (s[len] == '(' && (len += 1))
-         || (s[len] == ':'  /* Stopping in case of a rule.  */
-            && s[len + 1] == '-'
-            && (len += 2)))
-       && (lastlen != len || memcmp (s, last, len) != 0)
+  mercury_pos_t position = mercury_decl (s, len0);
+  size_t pos = position.pos;
+  int offset = 0;  /* may be < 0  */
+  if (pos == 0) return 0;
+
+  /* Skip white space for:
+     a. rules in definitions before :-
+     b. 0-arity predicates with inlined modes.
+     c. possibly multiline type definitions  */
+
+  while (c_isspace (s[pos])) { ++pos; ++offset; }
+
+  if (( ((s[pos] == '.' && (pos += 1))     /* case 1
+                                              This is a statement dot,
+                                              not a module dot. */
+        || c_isalnum(s[pos])              /* 0-arity procedures  */
+        || (s[pos] == '(' && (pos += 1))  /* case 2: arity > 0   */
+        || ((s[pos] == ':')               /* case 3: rules  */
+            && s[pos + 1] == '-' && (stop_at_rule = true)))
+     && (lastlen != pos || memcmp (s, last, pos) != 0)
        )
       /* Types are often declared on several lines so keeping just
         the first line.  */
-      || is_mercury_type)
+
+      || is_mercury_type)  /* When types are implemented.  */
     {
-      char *name = skip_non_spaces (s + len0);
-      size_t namelen;
-      if (name >= s + len)
-       {
-         name = s;
-         namelen = len;
-       }
-      else
-       {
-         name = skip_spaces (name);
-         namelen = len - (name - s);
-       }
-      /* Remove trailing non-name characters.  */
-      while (namelen > 0 && notinname (name[namelen - 1]))
-       namelen--;
-      make_tag (name, namelen, true, s, len, lineno, linecharno);
-      return len;
+      size_t namelength = position.namelength;
+      if (stop_at_rule && offset) --offset;
+
+      /* Left-trim type definitions.  */
+
+      while (pos > namelength + offset
+            && c_isspace (s[pos - namelength - offset]))
+       --offset;
+
+      make_tag (s + pos - namelength - offset, namelength - 1, true,
+                               s, pos - offset - 1, lineno, linecharno);
+      return pos;
     }
 
   return 0;
diff --git a/lisp/bindings.el b/lisp/bindings.el
index 6eac528..4e5497c 100644
--- a/lisp/bindings.el
+++ b/lisp/bindings.el
@@ -610,7 +610,9 @@ Switch to the most recently selected buffer other than the 
current one."
     (previous-buffer)))
 
 (defmacro bound-and-true-p (var)
-  "Return the value of symbol VAR if it is bound, else nil."
+  "Return the value of symbol VAR if it is bound, else nil.
+Note that if `lexical-binding' is in effect, this refers to the
+global value outside of any lexical scope."
   `(and (boundp (quote ,var)) ,var))
 
 ;; Use mode-line-mode-menu for local minor-modes only.
diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el
index 44c4811..f22f060 100644
--- a/lisp/calendar/iso8601.el
+++ b/lisp/calendar/iso8601.el
@@ -231,17 +231,22 @@ See `decode-time' for the meaning of FORM."
                            (string-to-number (match-string 2 time))))
               (second (and (match-string 3 time)
                            (string-to-number (match-string 3 time))))
-             (fraction (and (not (zerop (length (match-string 4 time))))
-                             (string-to-number (match-string 4 time)))))
+              (frac-string (match-string 4 time))
+              fraction fraction-precision)
+          (when frac-string
+            ;; Remove trailing zeroes.
+            (setq frac-string (replace-regexp-in-string "0+\\'" "" 
frac-string))
+            (when (length> frac-string 0)
+              (setq fraction (string-to-number frac-string)
+                    fraction-precision (length frac-string))))
           (when (and fraction
                      (eq form t))
             (cond
              ;; Sub-second time.
              (second
-              (let ((digits (1+ (truncate (log fraction 10)))))
-                (setq second (cons (+ (* second (expt 10 digits))
-                                      fraction)
-                                   (expt 10 digits)))))
+              (setq second (cons (+ (* second (expt 10 fraction-precision))
+                                    fraction)
+                                 (expt 10 fraction-precision))))
              ;; Fractional minute.
              (minute
               (setq second (iso8601--decimalize fraction 60)))
diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el
index 62b2072..7928fa1 100644
--- a/lisp/cedet/pulse.el
+++ b/lisp/cedet/pulse.el
@@ -120,9 +120,9 @@ Face used for temporary highlighting of tags for effect."
                           (face-background face nil t)
                         (face-background 'pulse-highlight-start-face)
                         ))
-  (and face
-       (set-face-extend 'pulse-highlight-face
-                        (face-extend-p face nil t)))
+  (set-face-extend 'pulse-highlight-face
+                   (face-extend-p (or face 'pulse-highlight-start-face)
+                                  nil t))
   (put 'pulse-highlight-face :startface (or face
                                            'pulse-highlight-start-face))
   (setq pulse-momentary-iteration 0))
diff --git a/lisp/delsel.el b/lisp/delsel.el
index 96a9dcc..3c99dd2 100644
--- a/lisp/delsel.el
+++ b/lisp/delsel.el
@@ -87,7 +87,8 @@ information on adapting behavior of commands in Delete 
Selection mode."
 ;;;###autoload
 (defun delete-active-region (&optional killp)
   "Delete the active region.
-If KILLP in not-nil, the active region is killed instead of deleted."
+If KILLP is non-nil, or if called interactively with a prefix argument,
+the active region is killed instead of deleted."
   (interactive "P")
   (cond
    (killp
@@ -107,7 +108,7 @@ If KILLP in not-nil, the active region is killed instead of 
deleted."
   "Repeat replacing text of highlighted region with typed text.
 Search for the next stretch of text identical to the region last replaced
 by typing text over it and replaces it with the same stretch of text.
-With ARG, repeat that many times.  `C-u' means until end of buffer."
+With ARG, repeat that many times.  `\\[universal-argument]' means until end of 
buffer."
   (interactive "P")
   (let ((old-text (and delete-selection-save-to-register
                        (get-register delete-selection-save-to-register)))
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 96a0da9..472e0ba 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -603,15 +603,11 @@ Each element is (INDEX . VALUE)")
   form lexical)
 
 (defvar byte-native-compiling nil
-  "Non nil while native compiling.")
+  "Non-nil while native compiling.")
 (defvar byte-native-qualities nil
   "To spill default qualities from the compiled file.")
 (defvar byte+native-compile nil
-  "Non nil while compiling for bootstrap."
-  ;; During bootstrap we produce both the .eln and the .elc together.
-  ;; Because the make target is the later this has to be produced as
-  ;; last to be resilient against build interruptions.
-)
+  "Non-nil while producing at the same time byte and native code.")
 (defvar byte-to-native-lambdas-h nil
   "Hash byte-code -> byte-to-native-lambda.")
 (defvar byte-to-native-top-level-forms nil
@@ -1639,7 +1635,10 @@ URLs."
          ;; Ignore these `substitute-command-keys' substitutions.
          (seq "\\" (or "="
                        (seq "<" (* (not ">")) ">")
-                       (seq "{" (* (not "}")) "}")))))
+                       (seq "{" (* (not "}")) "}")))
+         ;; Ignore the function signature that's stashed at the end of
+         ;; the doc string (in some circumstances).
+         (seq bol "(fn (" (* nonl))))
     ""
     ;; Heuristic: assume these substitutions are of some length N.
     (replace-regexp-in-string
@@ -2071,16 +2070,17 @@ See also `emacs-lisp-byte-compile-and-load'."
          (insert "\n")                 ; aaah, unix.
          (cond
           ((null target-file) nil)     ;We only wanted the warnings!
-          ((or byte-native-compiling
-               (and (file-writable-p target-file)
-                    ;; We attempt to create a temporary file in the
-                    ;; target directory, so the target directory must be
-                    ;; writable.
-                    (file-writable-p
-                     (file-name-directory
-                      ;; Need to expand in case TARGET-FILE doesn't
-                      ;; include a directory (Bug#45287).
-                      (expand-file-name target-file)))))
+          ((and (or (null byte-native-compiling)
+                     (and byte-native-compiling byte+native-compile))
+                 (file-writable-p target-file)
+                ;; We attempt to create a temporary file in the
+                ;; target directory, so the target directory must be
+                ;; writable.
+                (file-writable-p
+                 (file-name-directory
+                  ;; Need to expand in case TARGET-FILE doesn't
+                  ;; include a directory (Bug#45287).
+                  (expand-file-name target-file))))
            ;; We must disable any code conversion here.
            (let* ((coding-system-for-write 'no-conversion)
                   ;; Write to a tempfile so that if another Emacs
@@ -2109,11 +2109,9 @@ See also `emacs-lisp-byte-compile-and-load'."
              ;; recompiled).  Previously this was accomplished by
              ;; deleting target-file before writing it.
              (if byte-native-compiling
-                  (if byte+native-compile
-                      ;; Defer elc final renaming.
-                      (setf byte-to-native-output-file
-                            (cons tempfile target-file))
-                    (delete-file tempfile))
+                  ;; Defer elc final renaming.
+                  (setf byte-to-native-output-file
+                        (cons tempfile target-file))
                 (rename-file tempfile target-file t)))
            (or noninteractive
                byte-native-compiling
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index 31aa0cb..544704b 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -568,17 +568,17 @@ The set of acceptable TYPEs (also called 
\"specializers\") is defined
               (cons method mt)
             ;; Keep the ordering; important for methods with :extra qualifiers.
             (mapcar (lambda (x) (if (eq x (car me)) method x)) mt)))
-    (let ((sym (cl--generic-name generic))) ; Actual name (for aliases).
+    (let ((sym (cl--generic-name generic)) ; Actual name (for aliases).
+          ;; FIXME: Try to avoid re-constructing a new function if the old one
+          ;; is still valid (e.g. still empty method cache)?
+          (gfun (cl--generic-make-function generic)))
       (unless (symbol-function sym)
         (defalias sym 'dummy))   ;Record definition into load-history.
       (cl-pushnew `(cl-defmethod . ,(cl--generic-load-hist-format
                                      (cl--generic-name generic)
                                      qualifiers specializers))
                   current-load-list :test #'equal)
-      ;; FIXME: Try to avoid re-constructing a new function if the old one
-      ;; is still valid (e.g. still empty method cache)?
-      (let ((gfun (cl--generic-make-function generic))
-            ;; Prevent `defalias' from recording this as the definition site of
+      (let (;; Prevent `defalias' from recording this as the definition site of
             ;; the generic function.
             current-load-list
             ;; BEWARE!  Don't purify this function definition, since that leads
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index e91ec0a..6793b37 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -1279,6 +1279,23 @@ EXPECTEDP specifies whether the result was expected."
              (ert-test-quit '("quit" "QUIT")))))
     (elt s (if expectedp 0 1))))
 
+(defun ert-reason-for-test-result (result)
+  "Return the reason given for RESULT, as a string.
+
+The reason is the argument given when invoking `ert-fail' or `ert-skip'.
+It is output using `prin1' prefixed by two spaces.
+
+If no reason was given, or for a successful RESULT, return the
+empty string."
+  (let ((reason
+         (and
+          (ert-test-result-with-condition-p result)
+          (cadr (ert-test-result-with-condition-condition result))))
+        (print-escape-newlines t)
+        (print-level 6)
+        (print-length 10))
+    (if reason (format "  %S" reason) "")))
+
 (defun ert--pp-with-indentation-and-newline (object)
   "Pretty-print OBJECT, indenting it to the current column of point.
 Ensures a final newline is inserted."
@@ -1369,18 +1386,24 @@ Returns the stats object."
               (cl-loop for test across (ert--stats-tests stats)
                        for result = (ert-test-most-recent-result test) do
                        (when (not (ert-test-result-expected-p test result))
-                         (message "%9s  %S"
+                         (message "%9s  %S%s"
                                   (ert-string-for-test-result result nil)
-                                  (ert-test-name test))))
+                                  (ert-test-name test)
+                                  (if (getenv "EMACS_TEST_VERBOSE")
+                                      (ert-reason-for-test-result result)
+                                    ""))))
               (message "%s" ""))
             (unless (zerop skipped)
               (message "%s skipped results:" skipped)
               (cl-loop for test across (ert--stats-tests stats)
                        for result = (ert-test-most-recent-result test) do
                        (when (ert-test-result-type-p result :skipped)
-                         (message "%9s  %S"
+                         (message "%9s  %S%s"
                                   (ert-string-for-test-result result nil)
-                                  (ert-test-name test))))
+                                  (ert-test-name test)
+                                  (if (getenv "EMACS_TEST_VERBOSE")
+                                      (ert-reason-for-test-result result)
+                                    ""))))
               (message "%s" "")))))
        (test-started
         )
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index bcd76dd..908c10c 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -879,8 +879,9 @@ this reverses the sort order.
 
 Ready-made functions include `gnus-article-sort-by-number',
 `gnus-article-sort-by-author', `gnus-article-sort-by-subject',
-`gnus-article-sort-by-date', `gnus-article-sort-by-random'
-and `gnus-article-sort-by-score'.
+`gnus-article-sort-by-date', `gnus-article-sort-by-score',
+`gnus-article-sort-by-rsv', `gnus-article-sort-by-newsgroups',
+and `gnus-article-sort-by-random'.
 
 When threading is turned on, the variable `gnus-thread-sort-functions'
 controls how articles are sorted."
@@ -892,6 +893,7 @@ controls how articles are sorted."
                           (function-item gnus-article-sort-by-date)
                           (function-item gnus-article-sort-by-score)
                           (function-item gnus-article-sort-by-rsv)
+                          (function-item gnus-article-sort-by-newsgroups)
                           (function-item gnus-article-sort-by-random)
                           (function :tag "other"))
                   (boolean :tag "Reverse order"))))
@@ -916,8 +918,8 @@ Ready-made functions include `gnus-thread-sort-by-number',
 `gnus-thread-sort-by-author', `gnus-thread-sort-by-recipient'
 `gnus-thread-sort-by-subject', `gnus-thread-sort-by-date',
 `gnus-thread-sort-by-score', `gnus-thread-sort-by-most-recent-number',
-`gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-random',
-and `gnus-thread-sort-by-total-score' (see
+`gnus-thread-sort-by-most-recent-date', `gnus-thread-sort-by-newsgroups',
+`gnus-thread-sort-by-random', and `gnus-thread-sort-by-total-score' (see
 `gnus-thread-score-function').
 
 When threading is turned off, the variable
@@ -938,6 +940,7 @@ subthreads, customize `gnus-subthread-sort-functions'."
                    (function-item gnus-thread-sort-by-rsv)
                    (function-item gnus-thread-sort-by-most-recent-number)
                    (function-item gnus-thread-sort-by-most-recent-date)
+                   (function-item gnus-thread-sort-by-newsgroups)
                    (function-item gnus-thread-sort-by-random)
                    (function-item gnus-thread-sort-by-total-score)
                    (function :tag "other"))
@@ -961,6 +964,7 @@ according to the value of `gnus-thread-sort-functions'."
                    (function-item gnus-thread-sort-by-score)
                    (function-item gnus-thread-sort-by-most-recent-number)
                    (function-item gnus-thread-sort-by-most-recent-date)
+                    (function-item gnus-thread-sort-by-newsgroups)
                    (function-item gnus-thread-sort-by-random)
                    (function-item gnus-thread-sort-by-total-score)
                    (function :tag "other"))
@@ -1976,6 +1980,8 @@ increase the score of each group you read."
   "\C-c\C-s\C-i" gnus-summary-sort-by-score
   "\C-c\C-s\C-o" gnus-summary-sort-by-original
   "\C-c\C-s\C-r" gnus-summary-sort-by-random
+  "\C-c\C-s\C-u" gnus-summary-sort-by-newsgroups
+  "\C-c\C-s\C-x" gnus-summary-sort-by-extra
   "=" gnus-summary-expand-window
   "\C-x\C-s" gnus-summary-reselect-current-group
   "\M-g" gnus-summary-rescan-group
@@ -2831,6 +2837,8 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
         ["Sort by lines" gnus-summary-sort-by-lines t]
         ["Sort by characters" gnus-summary-sort-by-chars t]
         ["Sort by marks" gnus-summary-sort-by-marks t]
+        ["Sort by newsgroup" gnus-summary-sort-by-newsgroups t]
+        ["Sort by extra" gnus-summary-sort-by-extra t]
         ["Randomize" gnus-summary-sort-by-random t]
         ["Original sort" gnus-summary-sort-by-original t])
        ("Help"
@@ -5180,6 +5188,23 @@ Unscored articles will be counted as having a score of 
zero."
   "Sort threads such that the thread with the most recently dated article 
comes first."
   (> (gnus-thread-latest-date h1) (gnus-thread-latest-date h2)))
 
+(defun gnus-article-sort-by-newsgroups (h1 h2)
+  "Sort articles by newsgroups."
+  (let ((ex
+         (lambda (h)
+           (let ((extract
+                  (funcall gnus-extract-address-components
+                          (or (cdr (assq 'Newsgroups (mail-header-extra h)))
+                               ""))))
+             (or (car extract) (cadr extract))))))
+    (gnus-string< (funcall ex h1) (funcall ex h2))))
+
+(defun gnus-thread-sort-by-newsgroups (h1 h2)
+  "Sort threads by root newsgroups."
+  (gnus-article-sort-by-newsgroups
+   (gnus-thread-header h1) (gnus-thread-header h2)))
+
+
 ; Since this is called not only to sort the top-level threads, but
 ; also in recursive sorts to order the articles within a thread, each
 ; article will be processed many times.  Thus it speeds things up
@@ -12122,6 +12147,12 @@ Argument REVERSE means reverse order."
   (interactive "P" gnus-summary-mode)
   (gnus-summary-sort 'marks reverse))
 
+(defun gnus-summary-sort-by-newsgroups (&optional reverse)
+  "Sort the summary buffer by newsgroups alphabetically.
+Argument REVERSE means reverse order."
+  (interactive "P" gnus-summary-mode)
+  (gnus-summary-sort 'newsgroups reverse))
+
 (defun gnus-summary-sort-by-original (&optional _reverse)
   "Sort the summary buffer using the default sorting method.
 Argument REVERSE means reverse order."
@@ -12133,6 +12164,24 @@ Argument REVERSE means reverse order."
     ;; Hide subthreads if needed.
     (gnus-summary-maybe-hide-threads)))
 
+(defun gnus-summary-sort-by-extra (&optional reverse)
+  "Sort the summary buffer using an extra header.
+Argument REVERSE means reverse order."
+  (interactive "P" gnus-summary-mode)
+  (let* ((extra-header
+         (gnus-completing-read "Sort by extra header"
+          (mapcar #'symbol-name gnus-extra-headers)
+          t nil nil
+          (symbol-name
+           (car gnus-extra-headers))))
+       (header (downcase extra-header)))
+    (if (and (fboundp (intern
+                      (format "gnus-thread-sort-by-%s" header)))
+            (fboundp
+             (intern (format "gnus-article-sort-by-%s" header))))
+       (gnus-summary-sort header reverse)
+      (error "No sort function defined for header: %s" extra-header))))
+
 (defun gnus-summary-sort (predicate reverse)
   "Sort summary buffer by PREDICATE.  REVERSE means reverse order."
   (let* ((current (gnus-summary-article-number))
diff --git a/lisp/gnus/gnus-topic.el b/lisp/gnus/gnus-topic.el
index b974dff..568fbbc 100644
--- a/lisp/gnus/gnus-topic.el
+++ b/lisp/gnus/gnus-topic.el
@@ -54,6 +54,7 @@ with some simple extensions.
 %n  Topic name.
 %v  Nothing if the topic is visible, \"...\" otherwise.
 %g  Number of groups in the topic.
+%G  Number of groups in the topic and its subtopics.
 %a  Number of unread articles in the groups in the topic.
 %A  Number of unread articles in the groups in the topic and its subtopics.
 
@@ -87,6 +88,7 @@ See Info node `(gnus)Formatting Variables'."
     (?v visible ?s)
     (?i indentation ?s)
     (?g number-of-groups ?d)
+    (?G total-number-of-groups ?d)
     (?a (gnus-topic-articles-in-topic entries) ?d)
     (?A total-number-of-articles ?d)
     (?l level ?d)))
@@ -485,16 +487,18 @@ If LOWEST is non-nil, list all newsgroups of level LOWEST 
or higher."
 If SILENT, don't insert anything.  Return the number of unread
 articles in the topic and its subtopics."
   (let* ((type (pop topicl))
+        (entries-level (if gnus-group-listed-groups
+                           gnus-level-killed
+                         list-level))
+        (all (or predicate gnus-group-listed-groups
+                 (cdr (assq 'visible
+                            (gnus-topic-hierarchical-parameters
+                             (car type))))))
+        (lowest (if gnus-group-listed-groups 0 lowest))
         (entries (gnus-topic-find-groups
-                  (car type)
-                  (if gnus-group-listed-groups
-                      gnus-level-killed
-                    list-level)
-                  (or predicate gnus-group-listed-groups
-                      (cdr (assq 'visible
-                                 (gnus-topic-hierarchical-parameters
-                                  (car type)))))
-                  (if gnus-group-listed-groups 0 lowest)))
+                  (car type) entries-level all lowest))
+        (all-groups (gnus-topic-find-groups
+                     (car type) entries-level all lowest t))
         (visiblep (and (eq (nth 1 type) 'visible) (not silent)))
         (gnus-group-indentation
          (make-string (* gnus-topic-indent-level level) ? ))
@@ -573,7 +577,7 @@ articles in the topic and its subtopics."
       (gnus-topic-insert-topic-line
        (car type) visiblep
        (not (eq (nth 2 type) 'hidden))
-       level all-entries unread))
+       level all-entries unread all-groups))
     (gnus-topic-update-unreads (car type) unread)
     (gnus-group--setup-tool-bar-update beg end)
     (goto-char end)
@@ -627,10 +631,10 @@ articles in the topic and its subtopics."
 (defvar gnus-tmp-header)
 
 (defun gnus-topic-insert-topic-line (name visiblep shownp level entries
-                                         &optional unread)
+                                         &optional unread all-groups)
   (gnus--\,@
    (let ((vars '(indentation visible name level number-of-groups
-                 total-number-of-articles entries)))
+                 total-number-of-groups total-number-of-articles entries)))
      `((with-suppressed-warnings ((lexical ,@vars))
          ,@(mapcar (lambda (s) `(defvar ,s)) vars)))))
   (let* ((visible (if visiblep "" "..."))
@@ -639,6 +643,7 @@ articles in the topic and its subtopics."
         (indentation (make-string (* gnus-topic-indent-level level) ? ))
         (total-number-of-articles unread)
         (number-of-groups (length entries))
+        (total-number-of-groups (length all-groups))
         (active-topic (eq gnus-topic-alist gnus-topic-active-alist))
         gnus-tmp-header)
     (gnus-topic-update-unreads name unread)
@@ -731,6 +736,9 @@ articles in the topic and its subtopics."
         (entries (gnus-topic-find-groups
                   (car type) (car gnus-group-list-mode)
                   (cdr gnus-group-list-mode)))
+        (all-groups (gnus-topic-find-groups
+                  (car type) (car gnus-group-list-mode)
+                  (cdr gnus-group-list-mode) nil t))
        entry)
     (while children
       (cl-incf unread (gnus-topic-unread (caar (pop children)))))
@@ -738,7 +746,7 @@ articles in the topic and its subtopics."
       (when (numberp (car entry))
        (cl-incf unread (car entry))))
     (gnus-topic-insert-topic-line
-     topic t t (car (gnus-topic-find-topology topic)) nil unread)))
+     topic t t (car (gnus-topic-find-topology topic)) nil unread all-groups)))
 
 (defun gnus-topic-goto-missing-topic (topic)
   (if (gnus-topic-goto-topic topic)
@@ -768,6 +776,9 @@ articles in the topic and its subtopics."
         (entries (gnus-topic-find-groups
                   (car type) (car gnus-group-list-mode)
                   (cdr gnus-group-list-mode)))
+        (all-groups (gnus-topic-find-groups
+                  (car type) (car gnus-group-list-mode)
+                  (cdr gnus-group-list-mode) t))
         (parent (gnus-topic-parent-topic topic-name))
         (all-entries entries)
         (unread 0)
@@ -786,7 +797,7 @@ articles in the topic and its subtopics."
       (gnus-topic-insert-topic-line
        (car type) (gnus-topic-visible-p)
        (not (eq (nth 2 type) 'hidden))
-       (gnus-group-topic-level) all-entries unread)
+       (gnus-group-topic-level) all-entries unread all-groups)
       (gnus-delete-line)
       (forward-line -1)
       (setq new-unread (gnus-group-topic-unread)))
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 02db387..0c027ca 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -8722,16 +8722,19 @@ Header and body are separated by 
`mail-header-separator'."
 
 (defun message-replace-header (header new-value &optional after force)
   "Remove HEADER and insert the NEW-VALUE.
-If AFTER, insert after this header.  If FORCE, insert new field
-even if NEW-VALUE is empty."
+If AFTER, insert after this header.  AFTER may be a list of
+headers.  If FORCE, insert new field even if NEW-VALUE is empty."
   ;; Similar to `nnheader-replace-header' but for message buffers.
   (save-excursion
     (save-restriction
       (message-narrow-to-headers)
       (message-remove-header header))
     (when (or force (> (length new-value) 0))
-      (if after
-         (message-position-on-field header after)
+      (when after
+        (if (listp after)
+            (apply #'message-position-on-field
+                   (append (list header) after))
+          (message-position-on-field header after))
        (message-position-on-field header))
       (insert new-value))))
 
diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el
index dcc9ea5..5f35e73 100644
--- a/lisp/gnus/mml.el
+++ b/lisp/gnus/mml.el
@@ -550,7 +550,7 @@ type detected."
                 (end (point))
                 (parsed (url-generic-parse-url (cdr (assq 'src (cadr img))))))
            (when (and (null (url-type parsed))
-                      (url-filename parsed)
+                       (not (zerop (length (url-filename parsed))))
                       (file-exists-p (url-filename parsed)))
              (goto-char start)
              (when (search-forward (url-filename parsed) end t)
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 133763a..afdb0d1 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -130,23 +130,25 @@ with the current prefix.  The files are chosen according 
to
   "Return symbol class characters for symbol S."
   (when (stringp s)
     (setq s (intern-soft s)))
-  (cond ((commandp s)
-         "c")                           ; command
-        ((eq (car-safe (symbol-function s)) 'macro)
-         "m")                           ; macro
-        ((fboundp s)
-         "f")                           ; function
-        ((custom-variable-p s)
-         "u")                           ; user option
-        ((boundp s)
-         "v")                           ; variable
-        ((facep s)
-         "a")                           ; fAce
-        ((and (fboundp 'cl-find-class)
-              (cl-find-class s))
-         "t")                           ; CL type
-        (" ")                           ; something else
-        ))
+  (concat
+   (when (fboundp s)
+     (concat
+      (cond
+       ((commandp s) "c")
+       ((eq (car-safe (symbol-function s)) 'macro) "m")
+       (t "f"))
+      (and (let ((flist (indirect-function s)))
+             (advice--p (if (eq 'macro (car-safe flist)) (cdr flist) flist)))
+           "!")
+      (and (get s 'byte-obsolete-info) "-")))
+   (when (boundp s)
+     (concat
+      (if (custom-variable-p s) "u" "v")
+      (and (local-variable-if-set-p s) "'")
+      (and (ignore-errors (not (equal (symbol-value s) (default-value s)))) 
"*")
+      (and (get s 'byte-obsolete-variable) "-")))
+   (and (facep s) "a")
+   (and (fboundp 'cl-find-class) (cl-find-class s) "t")))
 
 (defun help--symbol-completion-table-affixation (completions)
   (mapcar (lambda (c)
@@ -154,7 +156,7 @@ with the current prefix.  The files are chosen according to
                    (doc (condition-case nil (documentation s) (error nil)))
                    (doc (and doc (substring doc 0 (string-match "\n" doc)))))
               (list c (propertize
-                       (concat (help--symbol-class s) " ") ; prefix separator
+                       (format "%-4s" (help--symbol-class s))
                        'face 'completions-annotations)
                     (if doc (propertize (format " -- %s" doc)
                                         'face 'completions-annotations)
@@ -887,7 +889,9 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED 
REAL-DEF)."
                                       nil t)
              (help-xref-button 1 'help-function real-def)))))
 
-      (when file-name
+      (if (not file-name)
+         (with-current-buffer standard-output
+            (setq help-mode--current-data (list :symbol function)))
        ;; We used to add .el to the file name,
        ;; but that's completely wrong when the user used load-file.
        (princ (format-message " in `%s'"
@@ -896,6 +900,8 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED 
REAL-DEF)."
                                  (help-fns-short-filename file-name))))
        ;; Make a hyperlink to the library.
        (with-current-buffer standard-output
+          (setq help-mode--current-data (list :symbol function
+                                              :file file-name))
          (save-excursion
            (re-search-backward (substitute-command-keys "`\\([^`']+\\)'")
                                 nil t)
@@ -1070,7 +1076,10 @@ it is displayed along with the global value."
                                        "C source code"
                                      (help-fns-short-filename file-name))))
                           (with-current-buffer standard-output
-                            (save-excursion
+                             (setq help-mode--current-data
+                                   (list :symbol variable
+                                         :file file-name))
+                             (save-excursion
                               (re-search-backward (substitute-command-keys
                                                     "`\\([^`']+\\)'")
                                                    nil t)
@@ -1079,6 +1088,8 @@ it is displayed along with the global value."
                           (if valvoid
                               "It is void as a variable."
                              "Its "))
+                      (with-current-buffer standard-output
+                         (setq help-mode--current-data (list :symbol 
variable)))
                        (if valvoid
                           " is void as a variable."
                          (substitute-command-keys "'s ")))))
@@ -1448,7 +1459,10 @@ If FRAME is omitted or nil, use the selected frame."
                   (concat "\\(" customize-label "\\)") nil t)
                  (help-xref-button 1 'help-customize-face f)))
              (setq file-name (find-lisp-object-file-name f 'defface))
-             (when file-name
+             (if (not file-name)
+                  (setq help-mode--current-data (list :symbol f))
+                (setq help-mode--current-data (list :symbol f
+                                                    :file file-name))
                (princ (substitute-command-keys "Defined in `"))
                (princ (help-fns-short-filename file-name))
                (princ (substitute-command-keys "'"))
@@ -1738,7 +1752,9 @@ keymap value."
           (unless used-gentemp
             (princ (format-message "%S is a keymap variable" keymap))
             (if (not file-name)
-                (princ ".\n\n")
+                (progn
+                  (setq help-mode--current-data (list :symbol keymap))
+                  (princ ".\n\n"))
               (princ (format-message
                       " defined in `%s'.\n\n"
                       (if (eq file-name 'C-source)
@@ -1748,6 +1764,8 @@ keymap value."
                 (re-search-backward (substitute-command-keys
                                      "`\\([^`']+\\)'")
                                     nil t)
+                (setq help-mode--current-data (list :symbol keymap
+                                                    :file file-name))
                 (help-xref-button 1 'help-variable-def
                                   keymap file-name))))
           (when (and (not (equal "" doc)) doc)
@@ -1855,7 +1873,8 @@ documentation for the major and minor modes of that 
buffer."
        (princ " mode")
        (let* ((mode major-mode)
               (file-name (find-lisp-object-file-name mode nil)))
-         (when file-name
+         (if (not file-name)
+              (setq help-mode--current-data (list :symbol mode))
            (princ (format-message " defined in `%s'"
                                    (help-fns-short-filename file-name)))
            ;; Make a hyperlink to the library.
@@ -1863,6 +1882,8 @@ documentation for the major and minor modes of that 
buffer."
              (save-excursion
                (re-search-backward (substitute-command-keys "`\\([^`']+\\)'")
                                     nil t)
+                (setq help-mode--current-data (list :symbol mode
+                                                    :file file-name))
                 (help-xref-button 1 'help-function-def mode file-name)))))
         (let ((fundoc (help-split-fundoc (documentation major-mode) nil 'doc)))
           (with-current-buffer standard-output
diff --git a/lisp/help-mode.el b/lisp/help-mode.el
index c7eaae5..4e73551 100644
--- a/lisp/help-mode.el
+++ b/lisp/help-mode.el
@@ -44,6 +44,9 @@
     (define-key map [XF86Forward] 'help-go-forward)
     (define-key map "\C-c\C-c" 'help-follow-symbol)
     (define-key map "\r" 'help-follow)
+    (define-key map "s" 'help-view-source)
+    (define-key map "i" 'help-goto-info)
+    (define-key map "c" 'help-customize)
     map)
   "Keymap for Help mode.")
 
@@ -61,7 +64,13 @@
     ["Move to Previous Button" backward-button
      :help "Move to the Previous Button in the help buffer"]
     ["Move to Next Button" forward-button
-      :help "Move to the Next Button in the help buffer"]))
+     :help "Move to the Next Button in the help buffer"]
+    ["View Source" help-view-source
+     :help "Go to the source file for the current help item"]
+    ["Goto Info" help-goto-info
+     :help "Go to the info node for the current help item"]
+    ["Customize" help-customize
+     :help "Customize variable or face"]))
 
 (defvar help-mode-tool-bar-map
   (let ((map (make-sparse-keymap)))
@@ -323,6 +332,7 @@ The format is (FUNCTION ARGS...).")
   'help-echo (purecopy "mouse-2, RET: show corresponding NEWS announcement"))
 
 (defvar bookmark-make-record-function)
+(defvar help-mode--current-data nil)
 
 ;;;###autoload
 (define-derived-mode help-mode special-mode "Help"
@@ -334,6 +344,7 @@ Commands:
               #'help-mode-revert-buffer)
   (setq-local tool-bar-map
               help-mode-tool-bar-map)
+  (setq-local help-mode--current-data nil)
   (setq-local bookmark-make-record-function
               #'help-bookmark-make-record))
 
@@ -722,6 +733,32 @@ See `help-make-xrefs'."
       (help-xref-go-forward (current-buffer))
     (user-error "No next help buffer")))
 
+(defun help-view-source ()
+  "View the source of the current help item."
+  (interactive nil help-mode)
+  (unless (plist-get help-mode--current-data :file)
+    (error "Source file for the current help item is not defined"))
+  (help-function-def--button-function (plist-get help-mode--current-data 
:symbol)
+                                      (plist-get help-mode--current-data 
:file)))
+
+(defun help-goto-info ()
+  "View the *info* node of the current help item."
+  (interactive nil help-mode)
+  (unless help-mode--current-data
+    (error "No symbol to look up in the current buffer"))
+  (info-lookup-symbol (plist-get help-mode--current-data :symbol)
+                      'emacs-lisp-mode))
+
+(defun help-customize ()
+  "Customize variable or face whose doc string is shown in the current buffer."
+  (interactive nil help-mode)
+  (let ((sym (plist-get help-mode--current-data :symbol)))
+    (unless (or (boundp sym) (facep sym))
+      (user-error "No variable or face to customize"))
+    (cond
+     ((boundp sym) (customize-variable sym))
+     ((facep sym) (customize-face sym)))))
+
 (defun help-do-xref (_pos function args)
   "Call the help cross-reference function FUNCTION with args ARGS.
 Things are set up properly so that the resulting help-buffer has
diff --git a/lisp/mh-e/mh-junk.el b/lisp/mh-e/mh-junk.el
index e50bf8d..95a9bb4 100644
--- a/lisp/mh-e/mh-junk.el
+++ b/lisp/mh-e/mh-junk.el
@@ -175,7 +175,7 @@ classified as spam (see the option `mh-junk-program')."
 
 SpamAssassin is one of the more popular spam filtering programs.
 Get it from your local distribution or from the SpamAssassin web
-site at URL `http://spamassassin.org/'.
+site at URL `https://spamassassin.apache.org/'.
 
 To use SpamAssassin, add the following recipes to
 \".procmailrc\":
@@ -196,7 +196,7 @@ To use SpamAssassin, add the following recipes to
     * ^X-Spam-Status: Yes
     spam/.
 
-If you don't use \"spamc\", use \"spamassassin -P -a\".
+If you don't use \"spamc\", use \"spamassassin\".
 
 Note that one of the recipes above throws away messages with a
 score greater than or equal to 10. Here's how you can determine a
@@ -243,16 +243,7 @@ in the \"blacklist_from\" entries from the last blank line 
in
 information can be used so that you can replace multiple
 \"blacklist_from\" entries with a single wildcard entry such as:
 
-    blacklist_from *@*amazingoffersdirect2u.com
-
-In versions of SpamAssassin (2.50 and on) that support a Bayesian
-classifier, \\[mh-junk-blacklist] uses the program \"sa-learn\"
-to recategorize the message as spam. Neither MH-E, nor
-SpamAssassin, rebuilds the database after adding words, so you
-will need to run \"sa-learn --rebuild\" periodically. This can be
-done by adding the following to your crontab:
-
-    0 * * * *   sa-learn --rebuild > /dev/null 2>&1"
+    blacklist_from *@*amazingoffersdirect2u.com"
   (unless mh-spamassassin-executable
     (error "Unable to find the spamassassin executable"))
   (let ((current-folder mh-current-folder)
@@ -264,13 +255,13 @@ done by adding the following to your crontab:
     ;; (this happens if mh-junk-background is t).
     (with-current-buffer mh-log-buffer
       (call-process mh-spamassassin-executable msg-file mh-junk-background nil
-                    ;;"--report" "--remove-from-whitelist"
-                    "-r" "-R")          ; spamassassin V2.20
+                    ;; -R removes from allow-list
+                    "--report" "-R")
     (when mh-sa-learn-executable
       (message "Recategorizing message %d as spam..." msg)
       (mh-truncate-log-buffer)
       (call-process mh-sa-learn-executable msg-file mh-junk-background nil
-                    "--single" "--spam" "--local" "--no-rebuild")))
+                    "--spam" "--local" "--no-sync")))
     (message "Blacklisting sender of message %d..." msg)
     (with-current-buffer (get-buffer-create mh-temp-buffer)
       (erase-buffer)
@@ -304,8 +295,7 @@ See `mh-spamassassin-blacklist' for more information."
       (erase-buffer)
       (message "Removing spamassassin markup from message %d..." msg)
       (call-process mh-spamassassin-executable msg-file t nil
-                    ;; "--remove-markup"
-                    "-d")               ; spamassassin V2.20
+                    "--remove-markup")
       (if show-buffer
           (kill-buffer show-buffer))
       (write-file msg-file)
@@ -316,7 +306,7 @@ See `mh-spamassassin-blacklist' for more information."
         ;; (this happens if mh-junk-background is t).
         (with-current-buffer mh-log-buffer
           (call-process mh-sa-learn-executable msg-file mh-junk-background nil
-                        "--single" "--ham" "--local" "--no-rebuild")))
+                        "--ham" "--local" "--no-sync")))
       (message "Whitelisting sender of message %d..." msg)
       (setq from
             (car (mh-funcall-if-exists
diff --git a/lisp/mouse.el b/lisp/mouse.el
index f4979e3..d0064ee 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -415,7 +415,7 @@ must be one of the symbols `header', `mode', or `vertical'."
                (when (window-live-p (setq posn-window (posn-window start)))
                  ;; Add left edge of `posn-window' to `position'.
                  (setq position (+ (window-pixel-left posn-window) position))
-                 (unless (nth 1 start)
+                 (unless (posn-area start)
                    ;; Add width of objects on the left of the text area to
                    ;; `position'.
                    (when (eq (window-current-scroll-bars posn-window) 'left)
@@ -494,9 +494,11 @@ must be one of the symbols `header', `mode', or 
`vertical'."
               (define-key map [header-line] map)
               (define-key map [vertical-line] map)
               ;; ... and some maybe even with a right- or bottom-divider
-              ;; prefix.
+              ;; or left- or right-margin prefix ...
               (define-key map [right-divider] map)
               (define-key map [bottom-divider] map)
+              (define-key map [left-margin] map)
+              (define-key map [right-margin] map)
               map)
             t (lambda () (setq track-mouse old-track-mouse)))))))
 
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index d2ee729..d723fd5 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -328,6 +328,8 @@ arguments to pass to the OPERATION."
         ;; `filename' could be a quoted file name.  Or the file
         ;; archive could be a directory, see Bug#30293.
         (if (or (null archive)
+                (not (tramp-archive-run-real-handler
+                      #'file-exists-p (list archive)))
                (tramp-archive-run-real-handler
                  #'file-directory-p (list archive)))
             (tramp-archive-run-real-handler operation args)
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index fdde7fb..a41620a 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -70,7 +70,8 @@
 ;;   process key retrieved by `tramp-get-process' (the main connection
 ;;   process).  Other processes could reuse these properties, avoiding
 ;;   recomputation when a new asynchronous process is created by
-;;   `make-process'.  Examples are "remote-path" or "device" (tramp-adb.el).
+;;   `make-process'.  Examples are "remote-path",
+;;   "unsafe-temporary-file" or "device" (tramp-adb.el).
 
 ;;; Code:
 
@@ -470,11 +471,11 @@ used to cache connection properties of the local machine."
        ;; don't save either, because all other properties might
        ;; depend on the login name, and we want to give the
        ;; possibility to use another login name later on.  Key
-       ;; "started" exists for the "ftp" method only, which must be
+       ;; "started" exists for the "ftp" method only, which must not
        ;; be kept persistent.
        (maphash
         (lambda (key value)
-          (if (and (tramp-file-name-p key) value
+          (if (and (tramp-file-name-p key) (hash-table-p value)
                    (not (string-equal
                          (tramp-file-name-method key) tramp-archive-method))
                    (not (tramp-file-name-localname key))
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 29ed944..b613ad3 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -5296,8 +5296,7 @@ Nonexistent directories are removed from spec."
        ;; cache the result for the session only.  Otherwise, the
        ;; result is cached persistently.
        (if (memq 'tramp-own-remote-path tramp-remote-path)
-           (tramp-get-process vec)
-         vec)
+           (tramp-get-process vec) vec)
        "remote-path"
       (let* ((remote-path (copy-tree tramp-remote-path))
             (elt1 (memq 'tramp-default-remote-path remote-path))
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 838464e..5284981 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -3627,6 +3627,11 @@ User is always nil."
        (and (file-directory-p (file-name-directory filename))
             (file-writable-p (file-name-directory filename)))))))
 
+(defcustom tramp-allow-unsafe-temporary-files nil
+  "Whether root-owned auto-save or backup files can be written to \"/tmp\"."
+  :version "28.1"
+  :type 'boolean)
+
 (defun tramp-handle-find-backup-file-name (filename)
   "Like `find-backup-file-name' for Tramp files."
   (with-parsed-tramp-file-name filename nil
@@ -3642,8 +3647,25 @@ User is always nil."
                       (tramp-make-tramp-file-name v (cdr x))
                     (cdr x))))
                tramp-backup-directory-alist)
-            backup-directory-alist)))
-      (tramp-run-real-handler #'find-backup-file-name (list filename)))))
+            backup-directory-alist))
+         (uid (tramp-compat-file-attribute-user-id
+               (file-attributes filename 'integer)))
+         result)
+      (prog1 ;; Run plain `find-backup-file-name'.
+         (setq result
+               (tramp-run-real-handler
+                #'find-backup-file-name (list filename)))
+        ;; Protect against security hole.
+       (when (and (natnump uid) (zerop uid)
+                  (file-in-directory-p (car result) temporary-file-directory)
+                  (not tramp-allow-unsafe-temporary-files)
+                  (not (with-tramp-connection-property
+                           (tramp-get-process v) "unsafe-temporary-file"
+                         (yes-or-no-p
+                          (concat
+                           "Backup file on local temporary directory, "
+                           "do you want to continue? ")))))
+         (tramp-error v 'file-error "Unsafe backup file name"))))))
 
 (defun tramp-handle-insert-directory
   (filename switches &optional wildcard full-directory-p)
@@ -5225,37 +5247,52 @@ Return the local name of the temporary file."
   "Like `make-auto-save-file-name' for Tramp files.
 Returns a file name in `tramp-auto-save-directory' for autosaving
 this file, if that variable is non-nil."
-  (when (stringp tramp-auto-save-directory)
-    (setq tramp-auto-save-directory
-         (expand-file-name tramp-auto-save-directory)))
-  ;; Create directory.
-  (unless (or (null tramp-auto-save-directory)
-             (file-exists-p tramp-auto-save-directory))
-    (make-directory tramp-auto-save-directory t))
-
-  (let ((system-type
-        (if (and (stringp tramp-auto-save-directory)
-                 (tramp-tramp-file-p tramp-auto-save-directory))
-            'not-windows
-          system-type))
-       (auto-save-file-name-transforms
-        (if (null tramp-auto-save-directory)
-            auto-save-file-name-transforms))
-       (buffer-file-name
-        (if (null tramp-auto-save-directory)
-            buffer-file-name
-          (expand-file-name
-           (tramp-subst-strs-in-string
-            '(("_" . "|")
-              ("/" . "_a")
-              (":" . "_b")
-              ("|" . "__")
-              ("[" . "_l")
-              ("]" . "_r"))
-            (tramp-compat-file-name-unquote (buffer-file-name)))
-           tramp-auto-save-directory))))
-    ;; Run plain `make-auto-save-file-name'.
-    (tramp-run-real-handler #'make-auto-save-file-name nil)))
+  (with-parsed-tramp-file-name buffer-file-name nil
+    (when (stringp tramp-auto-save-directory)
+      (setq tramp-auto-save-directory
+           (expand-file-name tramp-auto-save-directory)))
+    ;; Create directory.
+    (unless (or (null tramp-auto-save-directory)
+               (file-exists-p tramp-auto-save-directory))
+      (make-directory tramp-auto-save-directory t))
+
+    (let ((system-type
+          (if (and (stringp tramp-auto-save-directory)
+                   (tramp-tramp-file-p tramp-auto-save-directory))
+              'not-windows
+            system-type))
+         (auto-save-file-name-transforms
+          (if (null tramp-auto-save-directory)
+              auto-save-file-name-transforms))
+         (uid (tramp-compat-file-attribute-user-id
+               (file-attributes buffer-file-name 'integer)))
+         (buffer-file-name
+          (if (null tramp-auto-save-directory)
+              buffer-file-name
+            (expand-file-name
+             (tramp-subst-strs-in-string
+              '(("_" . "|")
+                ("/" . "_a")
+                (":" . "_b")
+                ("|" . "__")
+                ("[" . "_l")
+                ("]" . "_r"))
+              (tramp-compat-file-name-unquote (buffer-file-name)))
+             tramp-auto-save-directory)))
+         result)
+      (prog1 ;; Run plain `make-auto-save-file-name'.
+         (setq result (tramp-run-real-handler #'make-auto-save-file-name nil))
+       ;; Protect against security hole.
+       (when (and (natnump uid) (zerop uid)
+                  (file-in-directory-p result temporary-file-directory)
+                  (not tramp-allow-unsafe-temporary-files)
+                  (not (with-tramp-connection-property
+                           (tramp-get-process v) "unsafe-temporary-file"
+                         (yes-or-no-p
+                          (concat
+                           "Autosave file on local temporary directory, "
+                           "do you want to continue? ")))))
+         (tramp-error v 'file-error "Unsafe autosave file name"))))))
 
 (defun tramp-subst-strs-in-string (alist string)
   "Replace all occurrences of the string FROM with TO in STRING.
diff --git a/lisp/play/morse.el b/lisp/play/morse.el
index 66a826f..bfb25ba 100644
--- a/lisp/play/morse.el
+++ b/lisp/play/morse.el
@@ -79,17 +79,16 @@
                     ("8" . "---..")
                     ("9" . "----.")
                     ;; Non-ASCII
-                    ("Ä" . ".-.-")
-                    ("Æ" . ".-.-")
-                    ("Á" . ".--.-")
-                    ("Å" . ".--.-")
-                    ;; ligature character?? ("Ch" . "----")
-                    ("ß" . ".../...")
-                    ("É" . "..-..")
-                    ("Ñ" . "--.--")
-                    ("Ö" . "---.")
-                    ("Ø" . "---.")
-                    ("Ü" . "..--")
+                    ("ä" . ".-.-")
+                    ("æ" . ".-.-")
+                    ("á" . ".--.-")
+                    ("å" . ".--.-")
+                    ("ß" . ".../...")  ; also ...--..
+                    ("é" . "..-..")
+                    ("ñ" . "--.--")
+                    ("ö" . "---.")
+                    ("ø" . "---.")
+                    ("ü" . "..--")
                     ;; Recently standardized
                     ("@" . ".--.-."))
   "Morse code character set.")
diff --git a/lisp/profiler.el b/lisp/profiler.el
index 64d71f4..8145e51 100644
--- a/lisp/profiler.el
+++ b/lisp/profiler.el
@@ -822,8 +822,12 @@ below entry at point."
 (defun profiler-start (mode)
   "Start/restart profilers.
 MODE can be one of `cpu', `mem', or `cpu+mem'.
-If MODE is `cpu' or `cpu+mem', time-based profiler will be started.
-Also, if MODE is `mem' or `cpu+mem', then memory profiler will be started."
+If MODE is `cpu' or `cpu+mem', start the time-based profiler,
+   whereby CPU is sampled periodically using the SIGPROF signal.
+If MODE is `mem' or `cpu+mem', start profiler that samples CPU
+   whenever memory-allocation functions are called -- this is useful
+   if SIGPROF is not supported, or is unreliable, or is not sampling
+   at a high enough frequency."
   (interactive
    (list (if (not (fboundp 'profiler-cpu-start)) 'mem
            (intern (completing-read (format-prompt "Mode" "cpu")
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el
index d127575..4a1da62 100644
--- a/lisp/progmodes/hideif.el
+++ b/lisp/progmodes/hideif.el
@@ -694,7 +694,7 @@ that form should be displayed.")
    "\\|\\(\\w+\\)"))
 
 ;; C++11 Unicode string literals (L"" u8"" u"" U"" R"" LR"" u8R"" uR"")
-(defconst hif-unicode-prefix-regexp  "\\(?:u8R?\\|[uUL]R?\\\|R\\)")
+(defconst hif-unicode-prefix-regexp  "\\(?:u8R?\\|[uUL]R?\\|R\\)")
 (defconst hif-string-literal-regexp
   (concat hif-unicode-prefix-regexp "?"
           "\\(\"\\(?:[^\"\\]\\|\\\\.\\)*\"\\)"))
diff --git a/lisp/simple.el b/lisp/simple.el
index b00918e..a2dc633 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5037,12 +5037,19 @@ ring directly.")
   "The tail of the kill ring whose car is the last thing yanked.")
 
 (defcustom save-interprogram-paste-before-kill nil
-  "Save existing clipboard text into kill ring before replacing it.
-A non-nil value ensures that Emacs kill operations do not
-irrevocably overwrite existing clipboard text by saving it to the
-`kill-ring' prior to the kill.  Such text can subsequently be
-retrieved via \\[yank] \\[yank-pop]."
-  :type 'boolean
+  "Whether to save existing clipboard text into kill ring before replacing it.
+A non-nil value means the clipboard text is saved to the `kill-ring'
+prior to any kill command.  Such text can subsequently be retrieved
+via \\[yank] \\[yank-pop].  This ensures that Emacs kill operations
+do not irrevocably overwrite existing clipboard text.
+
+The value of this variable can also be a number, in which case the
+clipboard data is only saved to the `kill-ring' if it's shorter
+(in characters) than that number.  Any other non-nil value will save
+the clipboard data unconditionally."
+  :type '(choice (const nil)
+                 number
+                 (other :tag "Always" t))
   :group 'killing
   :version "23.2")
 
@@ -5079,13 +5086,18 @@ argument should still be a \"useful\" string for such 
uses."
     (let ((interprogram-paste (and interprogram-paste-function
                                    (funcall interprogram-paste-function))))
       (when interprogram-paste
-        (dolist (s (if (listp interprogram-paste)
-                       ;; Use `reverse' to avoid modifying external data.
-                       (reverse interprogram-paste)
-                    (list interprogram-paste)))
-         (unless (and kill-do-not-save-duplicates
-                      (equal-including-properties s (car kill-ring)))
-           (push s kill-ring))))))
+        (setq interprogram-paste
+              (if (listp interprogram-paste)
+                  ;; Use `reverse' to avoid modifying external data.
+                  (reverse interprogram-paste)
+               (list interprogram-paste)))
+        (when (or (not (numberp save-interprogram-paste-before-kill))
+                  (< (seq-reduce #'+ (mapcar #'length interprogram-paste) 0)
+                     save-interprogram-paste-before-kill))
+          (dolist (s interprogram-paste)
+           (unless (and kill-do-not-save-duplicates
+                         (equal-including-properties s (car kill-ring)))
+             (push s kill-ring)))))))
   (unless (and kill-do-not-save-duplicates
               (equal-including-properties string (car kill-ring)))
     (if (and replace kill-ring)
@@ -9075,6 +9087,9 @@ Type \\<completion-list-mode-map>\\[choose-completion] in 
the completion list\
  to select the completion near point.
 Or click to select one with the mouse.
 
+See the `completions-format' user option to control how this
+buffer is formatted.
+
 \\{completion-list-mode-map}")
 
 (defun completion-list-mode-finish ()
diff --git a/lisp/startup.el b/lisp/startup.el
index 9edbe02..3c3f791 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -2502,7 +2502,7 @@ nil default-directory" name)
                                    (or argval (pop command-line-args-left))))
                             ;; Take file from default dir if it exists there;
                             ;; otherwise let `load' search for it.
-                            (file-ex (expand-file-name file)))
+                            (file-ex (file-truename (expand-file-name file))))
                        (when (file-regular-p file-ex)
                          (setq file file-ex))
                        (load file nil t)))
@@ -2513,7 +2513,7 @@ 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 (expand-file-name file)))
+                            (file-ex (file-truename (expand-file-name file))))
                        (load file-ex nil t t)))
 
                     ((equal argi "-insert")
diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el
index 0d6bfb5..96065ee 100644
--- a/lisp/textmodes/reftex-vars.el
+++ b/lisp/textmodes/reftex-vars.el
@@ -121,7 +121,7 @@
        (regexp "tables?" "tab\\." "Tabellen?"))
       ("table*"    ?t nil nil caption)
 
-      ("\\footnote[]{}" ?n "fn:" "~\\ref{%s}" 2
+      ("\\footnote[]{}" ?n "fn:" "~\\footref{%s}" 2
        (regexp "footnotes?" "Fussnoten?"))
 
       ("any"       ?\  " "   "~\\ref{%s}" nil)
@@ -1059,7 +1059,7 @@ This is used to string together whole reference sets, like
 
 (defcustom reftex-ref-style-alist
   '(("Default" t
-     (("\\ref" ?\C-m) ("\\Ref" ?R) ("\\pageref" ?p)))
+     (("\\ref" ?\C-m) ("\\Ref" ?R) ("\\footref" ?n) ("\\pageref" ?p)))
     ("Varioref" "varioref"
      (("\\vref" ?v) ("\\Vref" ?V) ("\\vpageref" ?g)))
     ("Fancyref" "fancyref"
@@ -1079,7 +1079,7 @@ the macro type is being prompted for.  (See also
 `reftex-ref-macro-prompt'.)  The keys, represented as characters,
 have to be unique."
   :group 'reftex-referencing-labels
-  :version "27.1"
+  :version "28.1"
   :type '(alist :key-type (string :tag "Style name")
                :value-type (group (choice :tag "Package"
                                           (const :tag "Any package" t)
diff --git a/lisp/textmodes/sgml-mode.el b/lisp/textmodes/sgml-mode.el
index d5930e8..fda00ec 100644
--- a/lisp/textmodes/sgml-mode.el
+++ b/lisp/textmodes/sgml-mode.el
@@ -190,8 +190,19 @@ This takes effect when first loading the `sgml-mode' 
library.")
   "Syntax table used in SGML mode.  See also `sgml-specials'.")
 
 (defconst sgml-tag-syntax-table
-  (let ((table (sgml-make-syntax-table sgml-specials)))
-    (dolist (char '(?\( ?\) ?\{ ?\} ?\[ ?\] ?$ ?% ?& ?* ?+ ?/))
+  (let ((table (sgml-make-syntax-table sgml-specials))
+       brackets)
+    (map-char-table
+     (lambda (key value)
+       (setq brackets (cons (list
+                            (if (consp key)
+                                (list (car key) (cdr key))
+                              key)
+                            value)
+                           brackets)))
+     (unicode-property-table-internal 'paired-bracket))
+    (setq brackets (delete-dups (flatten-tree brackets)))
+    (dolist (char (append brackets (list ?$ ?% ?& ?* ?+ ?/)))
       (modify-syntax-entry char "." table))
     (unless (memq ?' sgml-specials)
       ;; Avoid that skipping a tag backwards skips any "'" prefixing it.
diff --git a/lisp/windmove.el b/lisp/windmove.el
index f558903..f747c40 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -138,17 +138,24 @@ If this variable is set to t, moving left from the 
leftmost window in
 a frame will find the rightmost one, and similarly for the other
 directions.  The minibuffer is skipped over in up/down movements if it
 is inactive."
-  :type 'boolean
-  :group 'windmove)
+  :type 'boolean)
 
 (defcustom windmove-create-window nil
   "Whether movement off the edge of the frame creates a new window.
 If this variable is set to t, moving left from the leftmost window in
 a frame will create a new window on the left, and similarly for the other
-directions."
-  :type 'boolean
-  :group 'windmove
-  :version "27.1")
+directions.
+This variable may also be a function to be called in this circumstance
+by `windmove-do-window-select'.  The function should accept then as
+argument the DIRECTION targeted, an interactive ARG and a WINDOW
+corresponding to the currently selected window.  It should also return
+a valid window that `windmove-do-window-select' will select,
+or the symbol `no-select' to ignore that final selection."
+  :type '(choice
+          (const :tag "Don't create new windows" nil)
+          (const :tag "Create new windows" t)
+          (function :tag "Provide a function"))
+  :version "28.1")
 
 ;; If your Emacs sometimes places an empty column between two adjacent
 ;; windows, you may wish to set this delta to 2.
@@ -157,11 +164,18 @@ directions."
 Measured in characters either horizontally or vertically; setting this
 to a value larger than 1 may be useful in getting around window-
 placement bugs in old versions of Emacs."
-  :type 'number
-  :group 'windmove)
+  :type 'number)
 (make-obsolete-variable 'windmove-window-distance-delta
                         "no longer used." "27.1")
 
+(defcustom windmove-allow-all-windows nil
+  "Whether the windmove commands are allowed to target all type of windows.
+If this variable is set to non-nil, all windmove commmands will
+ignore the `no-other-window' parameter applied by `display-buffer-alist'
+or `set-window-parameter'."
+  :type 'boolean
+  :version "28.1")
+
 
 ;; Note:
 ;;
@@ -342,7 +356,8 @@ WINDOW must be a live window and defaults to the selected 
one.
 Optional ARG, if negative, means to use the right or bottom edge of
 WINDOW as reference position, instead of `window-point'; if positive,
 use the left or top edge of WINDOW as reference point."
-  (window-in-direction dir window nil arg windmove-wrap-around t))
+  (window-in-direction dir window windmove-allow-all-windows
+                       arg windmove-wrap-around t))
 
 ;; Selects the window that's hopefully at the location returned by
 ;; `windmove-find-other-window', or screams if there's no window there.
@@ -350,19 +365,23 @@ use the left or top edge of WINDOW as reference point."
   "Move to the window at direction DIR as seen from WINDOW.
 DIR, ARG, and WINDOW are handled as by `windmove-find-other-window'.
 If no window is at direction DIR, an error is signaled.
-If `windmove-create-window' is non-nil, try to create a new window
+If `windmove-create-window' is a function, call that function with
+DIR, ARG and WINDOW.  If it is non-nil, try to create a new window
 in direction DIR instead."
   (let ((other-window (windmove-find-other-window dir arg window)))
     (when (and windmove-create-window
                (or (null other-window)
                    (and (window-minibuffer-p other-window)
                         (not (minibuffer-window-active-p other-window)))))
-      (setq other-window (split-window window nil dir)))
+      (setq other-window (if (functionp windmove-create-window)
+                             (funcall windmove-create-window dir arg window)
+                           (split-window window nil dir))))
     (cond ((null other-window)
            (user-error "No window %s from selected window" dir))
           ((and (window-minibuffer-p other-window)
                 (not (minibuffer-window-active-p other-window)))
            (user-error "Minibuffer is inactive"))
+          ((eq other-window 'no-select))
           (t
            (select-window other-window)))))
 
@@ -478,9 +497,20 @@ Default value of MODIFIERS is `shift'."
 ;;; Directional window display and selection
 
 (defcustom windmove-display-no-select nil
-  "Whether the window should be selected after displaying the buffer in it."
-  :type 'boolean
-  :group 'windmove
+  "Whether the window should be selected after displaying the buffer in it.
+If `nil', then the new window where the buffer is displayed will be selected.
+If `ignore', then don't select a window: neither the new nor the old window,
+thus allowing the next command to decide what window it selects.
+Other non-nil values will reselect the old window that was selected before.
+
+The value of this variable can be overridden by the prefix arg of the
+windmove-display-* commands that use `windmove-display-in-direction'.
+
+When `switch-to-buffer-obey-display-actions' is non-nil,
+`switch-to-buffer' commands are also supported."
+  :type '(choice (const :tag "Select new window" nil)
+                 (const :tag "Select old window" t)
+                 (const :tag "Don't select a window" ignore))
   :version "27.1")
 
 (defun windmove-display-in-direction (dir &optional arg)
@@ -488,11 +518,17 @@ Default value of MODIFIERS is `shift'."
 The next buffer is the buffer displayed by the next command invoked
 immediately after this command (ignoring reading from the minibuffer).
 Create a new window if there is no window in that direction.
-By default, select the window with a displayed buffer.
-If prefix ARG is `C-u', reselect a previously selected window.
-If `windmove-display-no-select' is non-nil, this command doesn't
-select the window with a displayed buffer, and the meaning of
-the prefix argument is reversed.
+
+By default, select the new window with a displayed buffer.
+If `windmove-display-no-select' is `ignore', then allow the next command
+to decide what window it selects.  With other non-nil values of
+`windmove-display-no-select', this function reselects
+a previously selected old window.
+
+If prefix ARG is `C-u', reselect a previously selected old window.
+If `windmove-display-no-select' is non-nil, the meaning of
+the prefix argument is reversed and it selects the new window.
+
 When `switch-to-buffer-obey-display-actions' is non-nil,
 `switch-to-buffer' commands are also supported."
   (let ((no-select (xor (consp arg) windmove-display-no-select)))
@@ -517,42 +553,47 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
                        ((eq dir 'same-window)
                         (selected-window))
                        (t (window-in-direction
-                           dir nil nil
+                           dir nil windmove-allow-all-windows
                            (and arg (prefix-numeric-value arg))
                            windmove-wrap-around 'nomini)))))
          (unless window
            (setq window (split-window nil nil dir) type 'window))
          (cons window type)))
      (lambda (old-window new-window)
-       (when (window-live-p (if no-select old-window new-window))
+       (when (and (not (eq windmove-display-no-select 'ignore))
+                  (window-live-p (if no-select old-window new-window)))
          (select-window (if no-select old-window new-window))))
      (format "[display-%s]" dir))))
 
 ;;;###autoload
 (defun windmove-display-left (&optional arg)
   "Display the next buffer in window to the left of the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'left arg))
 
 ;;;###autoload
 (defun windmove-display-up (&optional arg)
   "Display the next buffer in window above the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'up arg))
 
 ;;;###autoload
 (defun windmove-display-right (&optional arg)
   "Display the next buffer in window to the right of the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'right arg))
 
 ;;;###autoload
 (defun windmove-display-down (&optional arg)
   "Display the next buffer in window below the current one.
-See the logic of the prefix ARG in `windmove-display-in-direction'."
+See the logic of the prefix ARG and `windmove-display-no-select'
+in `windmove-display-in-direction'."
   (interactive "P")
   (windmove-display-in-direction 'down arg))
 
@@ -606,8 +647,8 @@ With `M-0' prefix, delete the selected window and
 select the window at direction DIR.
 When `windmove-wrap-around' is non-nil, takes the window
 from the opposite side of the frame."
-  (let ((other-window (window-in-direction dir nil nil arg
-                                           windmove-wrap-around 'nomini)))
+  (let ((other-window (window-in-direction dir nil windmove-allow-all-windows
+                                           arg windmove-wrap-around 'nomini)))
     (cond ((null other-window)
            (user-error "No window %s from selected window" dir))
           (t
@@ -680,8 +721,8 @@ Default value of PREFIX is `C-x' and MODIFIERS is `shift'."
   "Swap the states of the selected window and the window at direction DIR.
 When `windmove-wrap-around' is non-nil, takes the window
 from the opposite side of the frame."
-  (let ((other-window (window-in-direction dir nil nil nil
-                                           windmove-wrap-around 'nomini)))
+  (let ((other-window (window-in-direction dir nil windmove-allow-all-windows
+                                           nil windmove-wrap-around 'nomini)))
     (cond ((or (null other-window) (window-minibuffer-p other-window))
            (user-error "No window %s from selected window" dir))
           (t
@@ -761,8 +802,7 @@ See `windmove-default-keybindings' for more detail."
           (null val))
          (set-default sym val))
   :type windmove--default-keybindings-type
-  :version "28.1"
-  :group 'windmove)
+  :version "28.1")
 
 (defcustom windmove-display-default-keybindings nil
   "Default keybindings for windmove directional buffer display commands.
@@ -780,8 +820,7 @@ See `windmove-display-default-keybindings' for more detail."
           (null val))
          (set-default sym val))
   :type windmove--default-keybindings-type
-  :version "28.1"
-  :group 'windmove)
+  :version "28.1")
 
 (defcustom windmove-delete-default-keybindings nil
   "Default keybindings for windmove directional window deletion commands.
@@ -796,8 +835,7 @@ See `windmove-delete-default-keybindings' for more detail."
           (null val))
          (set-default sym val))
   :type windmove--default-keybindings-type
-  :version "28.1"
-  :group 'windmove)
+  :version "28.1")
 
 (defcustom windmove-swap-states-default-keybindings nil
   "Default keybindings for windmove's directional window swap-state commands.
@@ -812,8 +850,7 @@ See `windmove-swap-states-default-keybindings' for more 
detail."
           (null val))
          (set-default sym val))
   :type windmove--default-keybindings-type
-  :version "28.1"
-  :group 'windmove)
+  :version "28.1")
 
 
 (provide 'windmove)
diff --git a/lisp/window.el b/lisp/window.el
index ff4a39a..c0511be 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4526,8 +4526,10 @@ point to POINT.  If WINDOW is selected this also sets 
BUFFER's
 before was current this also makes BUFFER the current buffer."
   (setq window (window-normalize-window window t))
   (let ((selected (eq window (selected-window)))
-       (current (eq (window-buffer window) (current-buffer))))
+       (current (eq (window-buffer window) (current-buffer)))
+        (dedicated-side (eq (window-dedicated-p window) 'side)))
     (set-window-buffer window buffer)
+    (and dedicated-side (set-window-dedicated-p window 'side))
     (when (and selected current)
       (set-buffer buffer))
     (when start
@@ -4661,11 +4663,11 @@ This function is called by `prev-buffer'."
       ;; Scan WINDOW's previous buffers first, skipping entries of next
       ;; buffers.
       (dolist (entry (window-prev-buffers window))
-       (when (and (setq new-buffer (car entry))
+       (when (and (not (eq (car entry) old-buffer))
+                   (setq new-buffer (car entry))
                   (or (buffer-live-p new-buffer)
                       (not (setq killed-buffers
                                  (cons new-buffer killed-buffers))))
-                  (not (eq new-buffer old-buffer))
                    (or (null pred) (funcall pred new-buffer))
                   ;; When BURY-OR-KILL is nil, avoid switching to a
                   ;; buffer in WINDOW's next buffers list.
@@ -4828,11 +4830,11 @@ This function is called by `next-buffer'."
       ;; Scan WINDOW's reverted previous buffers last (must not use
       ;; nreverse here!)
       (dolist (entry (reverse (window-prev-buffers window)))
-       (when (and (setq new-buffer (car entry))
+       (when (and (not (eq new-buffer (car entry)))
+                   (setq new-buffer (car entry))
                   (or (buffer-live-p new-buffer)
                       (not (setq killed-buffers
                                  (cons new-buffer killed-buffers))))
-                  (not (eq new-buffer old-buffer))
                    (or (null pred) (funcall pred new-buffer)))
           (if (switch-to-prev-buffer-skip-p skip window new-buffer)
              (setq skipped (or skipped new-buffer))
@@ -5059,9 +5061,10 @@ window's lists of previous and next buffers."
        (all-frames (cond ((not frame) t) ((eq frame t) nil) (t frame))))
     (dolist (window (window-list-1 nil nil all-frames))
       (if (eq (window-buffer window) buffer)
-         (let ((deletable (window-deletable-p window)))
+         (let ((deletable (window-deletable-p window))
+                (dedicated (window-dedicated-p window)))
            (cond
-            ((and (eq deletable 'frame) (window-dedicated-p window))
+            ((and (eq deletable 'frame) dedicated)
              ;; Delete frame if and only if window is dedicated.
              (delete-frame (window-frame window)))
             ((eq deletable t)
@@ -5070,7 +5073,10 @@ window's lists of previous and next buffers."
             (t
              ;; In window switch to previous buffer.
              (set-window-dedicated-p window nil)
-             (switch-to-prev-buffer window 'bury))))
+             (switch-to-prev-buffer window 'bury)
+              ;; Restore the dedicated 'side' flag.
+              (when (eq dedicated 'side)
+                (set-window-dedicated-p window 'side)))))
        ;; If a window doesn't show BUFFER, unrecord BUFFER in it.
        (unrecord-window-buffer window buffer)))))
 
@@ -5079,10 +5085,10 @@ window's lists of previous and next buffers."
 BUFFER-OR-NAME may be a buffer or the name of an existing buffer
 and defaults to the current buffer.
 
-When a window showing BUFFER-OR-NAME is dedicated, that window is
-deleted.  If that window is the only window on its frame, the
-frame is deleted too when there are other frames left.  If there
-are no other frames left, some other buffer is displayed in that
+With the exception of side windows, when a window showing BUFFER-OR-NAME
+is dedicated, that window is deleted.  If that window is the only window
+on its frame, the frame is deleted too when there are other frames left.
+If there are no other frames left, some other buffer is displayed in that
 window.
 
 This function removes the buffer denoted by BUFFER-OR-NAME from
@@ -5091,10 +5097,14 @@ all window-local buffer lists."
   (let ((buffer (window-normalize-buffer buffer-or-name)))
     (dolist (window (window-list-1 nil nil t))
       (if (eq (window-buffer window) buffer)
-         (unless (window--delete window t t)
-           ;; Switch to another buffer in window.
-           (set-window-dedicated-p window nil)
-           (switch-to-prev-buffer window 'kill))
+          ;; Delete a dedicated window unless it is a side window.
+          (let ((dedicated-side (eq (window-dedicated-p window) 'side)))
+            (when (or dedicated-side (not (window--delete window t t)))
+              ;; Switch to another buffer in that window.
+              (set-window-dedicated-p window nil)
+              (if (switch-to-prev-buffer window 'kill)
+                  (and dedicated-side (set-window-dedicated-p window 'side))
+                (window--delete window nil 'kill))))
        ;; Unrecord BUFFER in WINDOW.
        (unrecord-window-buffer window buffer)))))
 
@@ -5116,6 +5126,10 @@ buffer.  If WINDOW is not deleted, reset its 
`quit-restore'
 parameter to nil.  See Info node `(elisp) Quitting Windows' for
 more details.
 
+If WINDOW's dedicated flag is t, try to delete WINDOW.  If it
+equals the value 'side', restore that value when WINDOW is not
+deleted.
+
 Optional second argument BURY-OR-KILL tells how to proceed with
 the buffer of WINDOW.  The following values are handled:
 
@@ -5142,8 +5156,12 @@ nil means to not handle the buffer in a particular way.  
This
                         (dolist (buf (window-prev-buffers window))
                           (unless (eq (car buf) buffer)
                             (throw 'prev-buffer (car buf))))))
+         (dedicated (window-dedicated-p window))
         quad entry)
     (cond
+     ;; First try to delete dedicated windows that are not side windows.
+     ((and dedicated (not (eq dedicated 'side))
+           (window--delete window 'dedicated (eq bury-or-kill 'kill))))
      ((and (not prev-buffer)
           (eq (nth 1 quit-restore) 'tab)
           (eq (nth 3 quit-restore) buffer))
@@ -5186,6 +5204,9 @@ nil means to not handle the buffer in a particular way.  
This
       ;; Restore WINDOW's previous buffer, start and point position.
       (set-window-buffer-start-and-point
        window (nth 0 quad) (nth 1 quad) (nth 2 quad))
+      ;; Restore the 'side' dedicated flag as well.
+      (when (eq dedicated 'side)
+        (set-window-dedicated-p window 'side))
       ;; Deal with the buffer we just removed from WINDOW.
       (setq entry (and (eq bury-or-kill 'append)
                       (assq buffer (window-prev-buffers window))))
@@ -5212,9 +5233,14 @@ nil means to not handle the buffer in a particular way.  
This
       (set-window-parameter window 'quit-restore nil)
       ;; Make sure that WINDOW is no more dedicated.
       (set-window-dedicated-p window nil)
-      (unless (switch-to-prev-buffer window bury-or-kill)
-        ;; Delete WINDOW if there is no previous buffer (Bug#48367).
-        (window--delete window nil (eq bury-or-kill 'kill)))))
+      ;; Try to switch to a previous buffer.  Delete the window only if
+      ;; that is not possible (Bug#48367).
+      (if (switch-to-prev-buffer window bury-or-kill)
+          (when (eq dedicated 'side)
+            (set-window-dedicated-p window 'side))
+        (window--delete window nil (eq bury-or-kill 'kill))
+        (when (window-live-p (nth 2 quit-restore))
+          (select-window (nth 2 quit-restore))))))
 
     ;; Deal with the buffer.
     (cond
@@ -8742,6 +8768,7 @@ to deactivate this overriding action."
          (new-window nil)
          (minibuffer-depth (minibuffer-depth))
          (clearfun (make-symbol "clear-display-buffer-overriding-action"))
+         (postfun (make-symbol "post-display-buffer-override-next-command"))
          (action (lambda (buffer alist)
                    (unless (> (minibuffer-depth) minibuffer-depth)
                      (let* ((ret (funcall pre-function buffer alist))
@@ -8750,22 +8777,24 @@ to deactivate this overriding action."
                        (setq new-window (window--display-buffer buffer window
                                                                 type alist))
                        ;; Reset display-buffer-overriding-action
-                       ;; after the first buffer display action
+                       ;; after the first display-buffer action (bug#39722).
                        (funcall clearfun)
-                       (setq post-function nil)
                        new-window))))
          (command this-command)
          (echofun (when echo (lambda () echo)))
          (exitfun
           (lambda ()
-            (setcar display-buffer-overriding-action
-                    (delq action (car display-buffer-overriding-action)))
-            (remove-hook 'post-command-hook clearfun)
+            (funcall clearfun)
+            (remove-hook 'post-command-hook postfun)
             (remove-hook 'prefix-command-echo-keystrokes-functions echofun)
             (when (functionp post-function)
               (funcall post-function old-window new-window)))))
     (fset clearfun
           (lambda ()
+            (setcar display-buffer-overriding-action
+                    (delq action (car display-buffer-overriding-action)))))
+    (fset postfun
+          (lambda ()
             (unless (or
                     ;; Remove the hook immediately
                     ;; after exiting the minibuffer.
@@ -8774,9 +8803,8 @@ to deactivate this overriding action."
                     ;; adding the hook by the same command below.
                     (eq this-command command))
               (funcall exitfun))))
-    ;; Reset display-buffer-overriding-action
-    ;; after the next command finishes
-    (add-hook 'post-command-hook clearfun)
+    ;; Call post-function after the next command finishes (bug#49057).
+    (add-hook 'post-command-hook postfun)
     (when echofun
       (add-hook 'prefix-command-echo-keystrokes-functions echofun))
     (push action (car display-buffer-overriding-action))
diff --git a/src/comp.c b/src/comp.c
index 056d086..ea05952 100644
--- a/src/comp.c
+++ b/src/comp.c
@@ -2687,7 +2687,7 @@ declare_runtime_imported_funcs (void)
   Lisp_Object field_list = Qnil;
 
 #define ADD_IMPORTED(f_name, ret_type, nargs, args)                           \
-  {                                                                           \
+  do {                                                                        \
     Lisp_Object name = intern_c_string (STR (f_name));                        \
     Lisp_Object field =                                                        
       \
       make_mint_ptr (declare_imported_func (name, ret_type, nargs, args));     
\
diff --git a/src/doprnt.c b/src/doprnt.c
index b6b5978..fe484b8 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -563,7 +563,7 @@ esprintf (char *buf, char const *format, ...)
    BUFSIZE_MAX.  */
 ptrdiff_t
 exprintf (char **buf, ptrdiff_t *bufsize,
-         char const *nonheapbuf, ptrdiff_t bufsize_max,
+         char *nonheapbuf, ptrdiff_t bufsize_max,
          char const *format, ...)
 {
   ptrdiff_t nbytes;
@@ -579,7 +579,7 @@ exprintf (char **buf, ptrdiff_t *bufsize,
 /* Act like exprintf, except take a va_list.  */
 ptrdiff_t
 evxprintf (char **buf, ptrdiff_t *bufsize,
-          char const *nonheapbuf, ptrdiff_t bufsize_max,
+          char *nonheapbuf, ptrdiff_t bufsize_max,
           char const *format, va_list ap)
 {
   for (;;)
diff --git a/src/fileio.c b/src/fileio.c
index caf077e..c0d1a50 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1830,6 +1830,9 @@ the value of that variable.  The variable name should be 
terminated
 with a character not a letter, digit or underscore; otherwise, enclose
 the entire variable name in braces.
 
+If FOO is not defined in the environment, `$FOO' is left unchanged in
+the value of this function.
+
 If `/~' appears, all of FILENAME through that `/' is discarded.
 If `//' appears, everything up to and including the first of
 those `/' is discarded.  */)
diff --git a/src/fns.c b/src/fns.c
index 40ade57..a178216 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -39,8 +39,9 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 #include "puresize.h"
 #include "gnutls.h"
 
-static void sort_vector_copy (Lisp_Object, ptrdiff_t,
-                             Lisp_Object *restrict, Lisp_Object *restrict);
+static void sort_vector_copy (Lisp_Object pred, ptrdiff_t len,
+                             Lisp_Object src[restrict VLA_ELEMS (len)],
+                             Lisp_Object dest[restrict VLA_ELEMS (len)]);
 enum equal_kind { EQUAL_NO_QUIT, EQUAL_PLAIN, EQUAL_INCLUDING_PROPERTIES };
 static bool internal_equal (Lisp_Object, Lisp_Object,
                            enum equal_kind, int, Lisp_Object);
diff --git a/src/gnutls.c b/src/gnutls.c
index 4d5a909..22e7f2c 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -625,16 +625,11 @@ gnutls_try_handshake (struct Lisp_Process *proc)
 
   while ((ret = gnutls_handshake (state)) < 0)
     {
-      if (gnutls_error_is_fatal (ret))
-       return emacs_gnutls_handle_error (state, ret);
-      do
-       ret = gnutls_handshake (state);
-      while (ret == GNUTLS_E_INTERRUPTED);
-
-      if (0 <= ret || emacs_gnutls_handle_error (state, ret) == 0
-         || non_blocking)
+      if (emacs_gnutls_handle_error (state, ret) == 0) /* fatal */
        break;
       maybe_quit ();
+      if (non_blocking && ret != GNUTLS_E_INTERRUPTED)
+       break;
     }
 
   proc->gnutls_initstage = GNUTLS_STAGE_HANDSHAKE_TRIED;
diff --git a/src/lisp.h b/src/lisp.h
index 91b7a89..4fb8923 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4064,10 +4064,10 @@ extern ptrdiff_t doprnt (char *, ptrdiff_t, const char 
*, const char *,
                         va_list);
 extern ptrdiff_t esprintf (char *, char const *, ...)
   ATTRIBUTE_FORMAT_PRINTF (2, 3);
-extern ptrdiff_t exprintf (char **, ptrdiff_t *, char const *, ptrdiff_t,
+extern ptrdiff_t exprintf (char **, ptrdiff_t *, char *, ptrdiff_t,
                           char const *, ...)
   ATTRIBUTE_FORMAT_PRINTF (5, 6);
-extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char const *, ptrdiff_t,
+extern ptrdiff_t evxprintf (char **, ptrdiff_t *, char *, ptrdiff_t,
                            char const *, va_list)
   ATTRIBUTE_FORMAT_PRINTF (5, 0);
 
diff --git a/src/pdumper.c b/src/pdumper.c
index dfc7388..7730ea3 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -489,6 +489,10 @@ struct dump_context
 {
   /* Header we'll write to the dump file when done.  */
   struct dump_header header;
+  /* Data that will be written to the dump file.  */
+  void *buf;
+  dump_off buf_size;
+  dump_off max_offset;
 
   Lisp_Object old_purify_flag;
   Lisp_Object old_post_gc_hook;
@@ -597,6 +601,13 @@ static struct link_weight const
 
 /* Dump file creation */
 
+static void dump_grow_buffer (struct dump_context *ctx)
+{
+  ctx->buf = xrealloc (ctx->buf, ctx->buf_size = (ctx->buf_size ?
+                                                 (ctx->buf_size * 2)
+                                                 : 8 * 1024 * 1024));
+}
+
 static dump_off dump_object (struct dump_context *ctx, Lisp_Object object);
 static dump_off dump_object_for_offset (struct dump_context *ctx,
                                        Lisp_Object object);
@@ -763,8 +774,9 @@ dump_write (struct dump_context *ctx, const void *buf, 
dump_off nbyte)
   eassert (nbyte == 0 || buf != NULL);
   eassert (ctx->obj_offset == 0);
   eassert (ctx->flags.dump_object_contents);
-  if (emacs_write (ctx->fd, buf, nbyte) < nbyte)
-    report_file_error ("Could not write to dump file", ctx->dump_filename);
+  while (ctx->offset + nbyte > ctx->buf_size)
+    dump_grow_buffer (ctx);
+  memcpy ((char *)ctx->buf + ctx->offset, buf, nbyte);
   ctx->offset += nbyte;
 }
 
@@ -844,10 +856,9 @@ dump_tailq_pop (struct dump_tailq *tailq)
 static void
 dump_seek (struct dump_context *ctx, dump_off offset)
 {
+  if (ctx->max_offset < ctx->offset)
+    ctx->max_offset = ctx->offset;
   eassert (ctx->obj_offset == 0);
-  if (lseek (ctx->fd, offset, SEEK_SET) < 0)
-    report_file_error ("Setting file position",
-                       ctx->dump_filename);
   ctx->offset = offset;
 }
 
@@ -4270,6 +4281,12 @@ types.  */)
   ctx->header.magic[0] = dump_magic[0];
   dump_seek (ctx, 0);
   dump_write (ctx, &ctx->header, sizeof (ctx->header));
+  if (emacs_write (ctx->fd, ctx->buf, ctx->max_offset) < ctx->max_offset)
+    report_file_error ("Could not write to dump file", ctx->dump_filename);
+  xfree (ctx->buf);
+  ctx->buf = NULL;
+  ctx->buf_size = 0;
+  ctx->max_offset = 0;
 
   dump_off
     header_bytes = header_end - header_start,
diff --git a/src/syntax.c b/src/syntax.c
index 9fbf885..7bba336 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -1109,6 +1109,23 @@ this is probably the wrong function to use, because it 
can't take
   return make_fixnum (syntax_code_spec[SYNTAX (char_int)]);
 }
 
+DEFUN ("syntax-class-to-char", Fsyntax_class_to_char,
+       Ssyntax_class_to_char, 1, 1, 0,
+       doc: /* Return the syntax char of CLASS, described by an integer.
+For example, if SYNTAX is word constituent (the integer 2), the
+character `w' (119) is returned.  */)
+  (Lisp_Object syntax)
+{
+  int syn;
+  CHECK_FIXNUM (syntax);
+  syn = XFIXNUM (syntax);
+
+  if (syn < 0 || syn >= sizeof syntax_code_spec)
+    args_out_of_range (make_fixnum (sizeof syntax_code_spec - 1),
+                      syntax);
+  return make_fixnum (syntax_code_spec[syn]);
+}
+
 DEFUN ("matching-paren", Fmatching_paren, Smatching_paren, 1, 1, 0,
        doc: /* Return the matching parenthesis of CHARACTER, or nil if none.  
*/)
   (Lisp_Object character)
@@ -3782,6 +3799,7 @@ In both cases, LIMIT bounds the search. */);
   defsubr (&Scopy_syntax_table);
   defsubr (&Sset_syntax_table);
   defsubr (&Schar_syntax);
+  defsubr (&Ssyntax_class_to_char);
   defsubr (&Smatching_paren);
   defsubr (&Sstring_to_syntax);
   defsubr (&Smodify_syntax_entry);
diff --git a/src/xdisp.c b/src/xdisp.c
index e95e64a..290a91e 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -34395,7 +34395,7 @@ gui_draw_bottom_divider (struct window *w)
                  && !NILP (XWINDOW (p->parent)->next))))
        x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
 
-       FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
+      FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
     }
 }
 
diff --git a/src/xfaces.c b/src/xfaces.c
index c931408..2bd2f4b 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -357,10 +357,13 @@ static bool menu_face_changed_default;
 
 struct named_merge_point;
 
-static struct face *realize_face (struct face_cache *, Lisp_Object *,
+static struct face *realize_face (struct face_cache *,
+                                 Lisp_Object [LFACE_VECTOR_SIZE],
                                  int);
-static struct face *realize_gui_face (struct face_cache *, Lisp_Object *);
-static struct face *realize_tty_face (struct face_cache *, Lisp_Object *);
+static struct face *realize_gui_face (struct face_cache *,
+                                     Lisp_Object [LFACE_VECTOR_SIZE]);
+static struct face *realize_tty_face (struct face_cache *,
+                                     Lisp_Object [LFACE_VECTOR_SIZE]);
 static bool realize_basic_faces (struct frame *);
 static bool realize_default_face (struct frame *);
 static void realize_named_face (struct frame *, Lisp_Object, int);
diff --git a/test/lisp/calendar/iso8601-tests.el 
b/test/lisp/calendar/iso8601-tests.el
index 618e5b1..c4d038a 100644
--- a/test/lisp/calendar/iso8601-tests.el
+++ b/test/lisp/calendar/iso8601-tests.el
@@ -183,7 +183,15 @@
   (should (equal (iso8601-parse-time "15:27:35.123" t)
                  '((35123 . 1000) 27 15 nil nil nil nil -1 nil)))
   (should (equal (iso8601-parse-time "15:27:35.123456789" t)
-                 '((35123456789 . 1000000000) 27 15 nil nil nil nil -1 nil))))
+                '((35123456789 . 1000000000) 27 15 nil nil nil nil -1 nil)))
+  (should (equal (iso8601-parse-time "15:27:35.012345678" t)
+                '((35012345678 . 1000000000) 27 15 nil nil nil nil -1 nil)))
+  (should (equal (iso8601-parse-time "15:27:35.00001" t)
+                 '((3500001 . 100000) 27 15 nil nil nil nil -1 nil)))
+  (should (equal (iso8601-parse-time "15:27:35.0000100" t)
+                 '((3500001 . 100000) 27 15 nil nil nil nil -1 nil)))
+  (should (equal (iso8601-parse-time "15:27:35.0" t)
+                 '(35 27 15 nil nil nil nil -1 nil))))
 
 (ert-deftest standard-test-time-of-day-beginning-of-day ()
   (should (equal (iso8601-parse-time "000000")
diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el
index 13350b2..e0fa66a 100644
--- a/test/lisp/filenotify-tests.el
+++ b/test/lisp/filenotify-tests.el
@@ -200,7 +200,10 @@ Return nil when any other file notification watch is still 
active."
 
 (setq file-notify-debug nil
       password-cache-expiry nil
-      tramp-verbose 0)
+      tramp-verbose 0
+      ;; When the remote user id is 0, Tramp refuses unsafe temporary files.
+      tramp-allow-unsafe-temporary-files
+      (or tramp-allow-unsafe-temporary-files noninteractive))
 
 ;; This should happen on hydra only.
 (when (getenv "EMACS_HYDRA_CI")
diff --git a/test/lisp/net/tramp-archive-tests.el 
b/test/lisp/net/tramp-archive-tests.el
index 773bc8f..9a97974 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -321,6 +321,7 @@ They shall still be supported"
   "Check `directory-file-name'.
 This checks also `file-name-as-directory', `file-name-directory',
 `file-name-nondirectory' and `unhandled-file-name-directory'."
+  :tags '(:unstable) ;; Temporarily.
   (skip-unless tramp-archive-enabled)
 
   (should
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 5e4626a..37cd701 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -229,6 +229,16 @@ is greater than 10.
        "%s %f sec"
        ,message (float-time (time-subtract (current-time) start))))))
 
+;; `always' is introduced with Emacs 28.1.
+(defalias 'tramp--test-always
+  (if (fboundp 'always)
+      #'always
+    (lambda (&rest _arguments)
+      "Do nothing and return t.
+This function accepts any number of ARGUMENTS, but ignores them.
+Also see `ignore'."
+      t)))
+
 (ert-deftest tramp-test00-availability ()
   "Test availability of Tramp functions."
   :expected-result (if (tramp--test-enabled) :passed :failed)
@@ -2454,9 +2464,9 @@ This checks also `file-name-as-directory', 
`file-name-directory',
                        tramp--test-messages))))))))
 
            ;; Do not overwrite if excluded.
-           (cl-letf (((symbol-function #'y-or-n-p) (lambda (_prompt) t))
+           (cl-letf (((symbol-function #'y-or-n-p) #'tramp--test-always)
                      ;; Ange-FTP.
-                     ((symbol-function 'yes-or-no-p) (lambda (_prompt) t)))
+                     ((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)
@@ -3671,7 +3681,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
                (should-error
                 (make-symbolic-link tmp-name1 tmp-name2 0)
                 :type 'file-already-exists)))
-           (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_prompt) t)))
+           (cl-letf (((symbol-function #'yes-or-no-p) #'tramp--test-always))
              (make-symbolic-link tmp-name1 tmp-name2 0)
              (should
               (string-equal
@@ -3747,7 +3757,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
               (should-error
                (add-name-to-file tmp-name1 tmp-name2 0)
                :type 'file-already-exists))
-            (cl-letf (((symbol-function #'yes-or-no-p) (lambda (_prompt) t)))
+            (cl-letf (((symbol-function #'yes-or-no-p) #'tramp--test-always))
               (add-name-to-file tmp-name1 tmp-name2 0)
               (should (file-regular-p tmp-name2)))
             (add-name-to-file tmp-name1 tmp-name2 'ok-if-already-exists)
@@ -4545,7 +4555,7 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
 If UNSTABLE is non-nil, the test is tagged as `:unstable'."
   (declare (indent 1))
   ;; `make-process' supports file name handlers since Emacs 27.
-  (when (let ((file-name-handler-alist '(("" . (lambda (&rest _) t)))))
+  (when (let ((file-name-handler-alist '(("" . #'tramp--test-always))))
          (ignore-errors (make-process :file-handler t)))
     `(ert-deftest ,(intern (concat (symbol-name test) "-direct-async")) ()
        ,docstring
@@ -4561,7 +4571,7 @@ If UNSTABLE is non-nil, the test is tagged as 
`:unstable'."
         ;; `file-truename' does it by side-effect.  Suppress
         ;; `tramp--test-enabled', in order to keep the connection.
         ;; Suppress "Process ... finished" messages.
-        (cl-letf (((symbol-function #'tramp--test-enabled) (lambda nil t))
+        (cl-letf (((symbol-function #'tramp--test-enabled) 
#'tramp--test-always)
                   ((symbol-function #'internal-default-process-sentinel)
                    #'ignore))
           (file-truename tramp-test-temporary-file-directory)
@@ -5554,11 +5564,38 @@ Use direct async.")
                         ("]" . "_r"))
                       (tramp-compat-file-name-unquote tmp-name1)))
                     tmp-name2)))
-                 (should (file-directory-p tmp-name2))))))
+                 (should (file-directory-p tmp-name2)))))
+
+           ;; Create temporary file.  This shall check for sensible
+           ;; files, owned by root.
+           (let ((tramp-auto-save-directory temporary-file-directory)
+                 tramp-allow-unsafe-temporary-files)
+             (write-region "foo" nil tmp-name1)
+             (when (zerop (or (tramp-compat-file-attribute-user-id
+                               (file-attributes tmp-name1))
+                              tramp-unknown-id-integer))
+               (with-temp-buffer
+                 (setq buffer-file-name tmp-name1)
+                 (tramp-cleanup-connection
+                  tramp-test-vec 'keep-debug 'keep-password)
+                 (let ((tramp-allow-unsafe-temporary-files t))
+                   (should (stringp (make-auto-save-file-name))))
+                 (tramp-cleanup-connection
+                  tramp-test-vec 'keep-debug 'keep-password)
+                 (cl-letf (((symbol-function #'yes-or-no-p) #'ignore))
+                   (should-error
+                    (make-auto-save-file-name)
+                    :type 'file-error))
+                 (tramp-cleanup-connection
+                  tramp-test-vec 'keep-debug 'keep-password)
+                 (cl-letf (((symbol-function #'yes-or-no-p)
+                            #'tramp--test-always))
+                   (should (stringp (make-auto-save-file-name))))))))
 
        ;; Cleanup.
        (ignore-errors (delete-file tmp-name1))
-       (ignore-errors (delete-directory tmp-name2 'recursive))))))
+       (ignore-errors (delete-directory tmp-name2 'recursive))
+       (tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)))))
 
 (ert-deftest tramp-test38-find-backup-file-name ()
   "Check `find-backup-file-name'."
@@ -5672,7 +5709,37 @@ Use direct async.")
              (should (file-directory-p tmp-name2))))
 
        ;; Cleanup.
-       (ignore-errors (delete-directory tmp-name2 'recursive))))))
+       (ignore-errors (delete-directory tmp-name2 'recursive)))
+
+      (unwind-protect
+         ;; Create temporary file.  This shall check for sensible
+         ;; files, owned by root.
+         (let ((backup-directory-alist `(("." . ,temporary-file-directory)))
+               tramp-allow-unsafe-temporary-files
+               tramp-backup-directory-alist)
+           (write-region "foo" nil tmp-name1)
+           (when (zerop (or (tramp-compat-file-attribute-user-id
+                             (file-attributes tmp-name1))
+                            tramp-unknown-id-integer))
+             (tramp-cleanup-connection
+              tramp-test-vec 'keep-debug 'keep-password)
+             (let ((tramp-allow-unsafe-temporary-files t))
+               (should (stringp (car (find-backup-file-name tmp-name1)))))
+             (tramp-cleanup-connection
+              tramp-test-vec 'keep-debug 'keep-password)
+             (cl-letf (((symbol-function #'yes-or-no-p) #'ignore))
+               (should-error
+                (find-backup-file-name tmp-name1)
+                :type 'file-error))
+             (tramp-cleanup-connection
+              tramp-test-vec 'keep-debug 'keep-password)
+             (cl-letf (((symbol-function #'yes-or-no-p)
+                        #'tramp--test-always))
+               (should (stringp (car (find-backup-file-name tmp-name1)))))))
+
+       ;; Cleanup.
+       (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-test39-make-nearby-temp-file ()
diff --git a/test/lisp/shadowfile-tests.el b/test/lisp/shadowfile-tests.el
index 7b9c2ff..7c9d05a 100644
--- a/test/lisp/shadowfile-tests.el
+++ b/test/lisp/shadowfile-tests.el
@@ -72,6 +72,9 @@
 (setq password-cache-expiry nil
       shadow-debug (getenv "EMACS_HYDRA_CI")
       tramp-verbose 0
+      ;; When the remote user id is 0, Tramp refuses unsafe temporary files.
+      tramp-allow-unsafe-temporary-files
+      (or tramp-allow-unsafe-temporary-files noninteractive)
       ;; On macOS, `temporary-file-directory' is a symlinked directory.
       temporary-file-directory (file-truename temporary-file-directory)
       shadow-test-remote-temporary-file-directory
diff --git a/test/lisp/textmodes/sgml-mode-tests.el 
b/test/lisp/textmodes/sgml-mode-tests.el
index 697c96c..b4c0186 100644
--- a/test/lisp/textmodes/sgml-mode-tests.el
+++ b/test/lisp/textmodes/sgml-mode-tests.el
@@ -204,5 +204,32 @@ The point is set to the beginning of the buffer."
     (should (= 1 (- (car (syntax-ppss (1- (point-max))))
                     (car (syntax-ppss (point-max))))))))
 
+(ert-deftest sgml-test-brackets ()
+  "Test fontification of apostrophe preceded by paired-bracket character."
+  (let (brackets)
+    (map-char-table
+     (lambda (key value)
+       (setq brackets (cons (list
+                            (if (consp key)
+                                (list (car key) (cdr key))
+                              key)
+                            value)
+                           brackets)))
+     (unicode-property-table-internal 'paired-bracket))
+    (setq brackets (delete-dups (flatten-tree brackets)))
+    (setq brackets (append brackets (list ?$ ?% ?& ?* ?+ ?/)))
+    (with-temp-buffer
+      (while brackets
+       (let ((char (string (pop brackets))))
+         (insert (concat "<p>" char "'s</p>\n"))))
+      (html-mode)
+      (font-lock-ensure (point-min) (point-max))
+      (goto-char (point-min))
+      (while (not (eobp))
+       (goto-char (next-single-char-property-change (point) 'face))
+       (let ((val (get-text-property (point) 'face)))
+         (when val
+           (should-not (eq val 'font-lock-string-face))))))))
+
 (provide 'sgml-mode-tests)
 ;;; sgml-mode-tests.el ends here
diff --git a/test/manual/etags/CTAGS.good b/test/manual/etags/CTAGS.good
index e265836..84a56b2 100644
--- a/test/manual/etags/CTAGS.good
+++ b/test/manual/etags/CTAGS.good
@@ -3102,6 +3102,7 @@ foperator c-src/etags.c   2411
 force_auto_save_soon   c-src/emacs/src/keyboard.c      /^force_auto_save_soon 
(void)$/
 force_explicit_name    c-src/etags.c   265
 force_quit_count       c-src/emacs/src/keyboard.c      10387
+foreign_export merc-src/accumulator.m  /^:- pragma foreign_export("C", 
unravel_univ(in, out/
 formatSize     objc-src/PackInsp.m     /^-(const char *)formatSize:(const char 
*)size inBuf/
 found  c-src/emacs/src/lisp.h  2344
 fracas html-src/software.html  /^Fracas$/
@@ -3230,20 +3231,6 @@ help_form_saved_window_configs   
c-src/emacs/src/keyboard.c      2156
 helpwin        pyt-src/server.py       /^def helpwin(helpdict):$/
 hide_cursor    cp-src/screen.cpp       /^void hide_cursor(void)$/
 hlds   merc-src/accumulator.m  /^:- import_module hlds.$/
-hlds.assertion merc-src/accumulator.m  /^:- import_module hlds.assertion.$/
-hlds.goal_util merc-src/accumulator.m  /^:- import_module hlds.goal_util.$/
-hlds.hlds_error_util   merc-src/accumulator.m  /^:- import_module 
hlds.hlds_error_util.$/
-hlds.hlds_goal merc-src/accumulator.m  /^:- import_module hlds.hlds_goal.$/
-hlds.hlds_module       merc-src/accumulator.m  /^:- import_module 
hlds.hlds_module.$/
-hlds.hlds_out  merc-src/accumulator.m  /^:- import_module hlds.hlds_out.$/
-hlds.hlds_out.hlds_out_util    merc-src/accumulator.m  /^:- import_module 
hlds.hlds_out.hlds_out_util.$/
-hlds.hlds_pred merc-src/accumulator.m  /^:- import_module hlds.hlds_pred.$/
-hlds.hlds_promise      merc-src/accumulator.m  /^:- import_module 
hlds.hlds_promise.$/
-hlds.instmap   merc-src/accumulator.m  /^:- import_module hlds.instmap.$/
-hlds.pred_table        merc-src/accumulator.m  /^:- import_module 
hlds.pred_table.$/
-hlds.quantification    merc-src/accumulator.m  /^:- import_module 
hlds.quantification.$/
-hlds.status    merc-src/accumulator.m  /^:- import_module hlds.status.$/
-hlds.vartypes  merc-src/accumulator.m  /^:- import_module hlds.vartypes.$/
 htmltreelist   prol-src/natded.prolog  /^htmltreelist([]).$/
 hybrid_aligned_alloc   c-src/emacs/src/gmalloc.c       /^hybrid_aligned_alloc 
(size_t alignment, size_t siz/
 hybrid_calloc  c-src/emacs/src/gmalloc.c       /^hybrid_calloc (size_t nmemb, 
size_t size)$/
@@ -3272,6 +3259,7 @@ ignore_mouse_drag_p       c-src/emacs/src/keyboard.c      
1256
 ill=\relax     tex-src/texinfo.tex     /^\\let\\refill=\\relax$/
 immediate_quit c-src/emacs/src/keyboard.c      174
 impatto        html-src/softwarelibero.html    /^Impatto pratico del software 
libero$/
+implementation merc-src/accumulator.m  /^:- implementation.$/
 in_word_set    c-src/etags.c   /^in_word_set (register const char *str, 
register un/
 inattribute    c-src/etags.c   2400
 inc    cp-src/Range.h  /^  double inc (void) const { return rng_inc;   }$/
@@ -3320,6 +3308,7 @@ integertonmstr    pas-src/common.pas      /^function 
integertonmstr; (* (TheInteger : in
 intensity1     f-src/entry.for /^     & 
intensity1(efv,fv,svin,svquad,sfpv,maxp,val/
 intensity1     f-src/entry.strange_suffix      /^     & 
intensity1(efv,fv,svin,svquad,sfpv,maxp,val/
 intensity1     f-src/entry.strange     /^     & 
intensity1(efv,fv,svin,svquad,sfpv,maxp,val/
+interface      merc-src/accumulator.m  /^:- interface.$/
 interface_locate       c-src/c.c       /^interface_locate(void)$/
 intern c-src/emacs/src/lisp.h  /^intern (const char *str)$/
 intern_c_string        c-src/emacs/src/lisp.h  /^intern_c_string (const char 
*str)$/
@@ -3451,9 +3440,6 @@ level     c-src/emacs/src/lisp.h  3153
 lex    prol-src/natded.prolog  /^lex(W,SynOut,Sem):-$/
 lexptr y-src/cccp.y    332
 libs   merc-src/accumulator.m  /^:- import_module libs.$/
-libs.globals   merc-src/accumulator.m  /^:- import_module libs.globals.$/
-libs.optimization_options      merc-src/accumulator.m  /^:- import_module 
libs.optimization_options.$/
-libs.options   merc-src/accumulator.m  /^:- import_module libs.options.$/
 licenze        html-src/softwarelibero.html    /^Licenze d'uso di un 
programma$/
 limit  cp-src/Range.h  /^  double limit (void) const { return rng_limit; }$/
 line   c-src/etags.c   2493
@@ -3595,7 +3581,6 @@ mcheck    c-src/emacs/src/gmalloc.c       /^mcheck (void 
(*func) (enum mcheck_status))$/
 mcheck_status  c-src/emacs/src/gmalloc.c       283
 mcheck_used    c-src/emacs/src/gmalloc.c       2012
 mdbcomp        merc-src/accumulator.m  /^:- import_module mdbcomp.$/
-mdbcomp.sym_name       merc-src/accumulator.m  /^:- import_module 
mdbcomp.sym_name.$/
 me22b  lua-src/test.lua        /^   local function test.me22b (one)$/
 me_22a lua-src/test.lua        /^   function test.me_22a(one, two)$/
 memalign       c-src/emacs/src/gmalloc.c       /^memalign (size_t alignment, 
size_t size)$/
@@ -3890,11 +3875,6 @@ parse_return_error       y-src/cccp.y    70
 parse_solitary_modifier        c-src/emacs/src/keyboard.c      
/^parse_solitary_modifier (Lisp_Object symbol)$/
 parse_tool_bar_item    c-src/emacs/src/keyboard.c      /^parse_tool_bar_item 
(Lisp_Object key, Lisp_Object /
 parse_tree     merc-src/accumulator.m  /^:- import_module parse_tree.$/
-parse_tree.error_util  merc-src/accumulator.m  /^:- import_module 
parse_tree.error_util.$/
-parse_tree.prog_data   merc-src/accumulator.m  /^:- import_module 
parse_tree.prog_data.$/
-parse_tree.prog_mode   merc-src/accumulator.m  /^:- import_module 
parse_tree.prog_mode.$/
-parse_tree.prog_util   merc-src/accumulator.m  /^:- import_module 
parse_tree.prog_util.$/
-parse_tree.set_of_var  merc-src/accumulator.m  /^:- import_module 
parse_tree.set_of_var.$/
 pat    c-src/etags.c   262
 pattern        c-src/etags.c   260
 pdlcount       c-src/emacs/src/lisp.h  3046
@@ -4277,6 +4257,7 @@ step_everybody    cp-src/clheir.cpp       /^void 
step_everybody(void)$/
 stop_polling   c-src/emacs/src/keyboard.c      /^stop_polling (void)$/
 store_info     merc-src/accumulator.m  /^:- type store_info$/
 store_user_signal_events       c-src/emacs/src/keyboard.c      
/^store_user_signal_events (void)$/
+stored_goal_plain_call merc-src/accumulator.m  /^:- inst 
stored_goal_plain_call for goal_store.stor/
 str    go-src/test1.go 9
 strcaseeq      c-src/etags.c   /^#define strcaseeq(s,t)        (assert 
((s)!=NULL && (t)!=/
 streq  c-src/etags.c   /^#define streq(s,t)    (assert ((s)!=NULL || (t)!=NULL/
@@ -4484,9 +4465,6 @@ tpcmd     c-src/h.h       15
 track-mouse    c-src/emacs/src/keyboard.c      /^DEFUN 
("internal--track-mouse", Ftrack_mouse, Stra/
 tracking_off   c-src/emacs/src/keyboard.c      /^tracking_off (Lisp_Object 
old_value)$/
 traffic_light  cp-src/conway.cpp       /^void traffic_light(int x, int y)$/
-transform_hlds.accumulator     merc-src/accumulator.m  /^:- module 
transform_hlds.accumulator.$/
-transform_hlds.accumulator     merc-src/accumulator.m  /^:- end_module 
transform_hlds.accumulator.$/
-transform_hlds.goal_store      merc-src/accumulator.m  /^:- import_module 
transform_hlds.goal_store.$/
 translate      c-src/emacs/src/regex.h 361
 treats cp-src/c.C      131
 tt     prol-src/natded.prolog  /^tt:-$/
@@ -4533,6 +4511,7 @@ unblock_input_to  c-src/emacs/src/keyboard.c      
/^unblock_input_to (int level)$/
 unchar c-src/h.h       99
 unexpand-abbrev        c-src/abbrev.c  /^DEFUN ("unexpand-abbrev", 
Funexpand_abbrev, Sunexp/
 univ   merc-src/accumulator.m  /^:- import_module univ.$/
+unravel_univ   merc-src/accumulator.m  /^:- some [T] pred 
unravel_univ(univ::in, T::out) is/
 unread_switch_frame    c-src/emacs/src/keyboard.c      204
 unsignedp      y-src/cccp.y    112
 unwind c-src/emacs/src/lisp.h  2962
diff --git a/test/manual/etags/ETAGS.good_1 b/test/manual/etags/ETAGS.good_1
index e05b8f2..4eae68b 100644
--- a/test/manual/etags/ETAGS.good_1
+++ b/test/manual/etags/ETAGS.good_1
@@ -3881,38 +3881,15 @@ 
Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
 \global\def={=3307,107500
 \def\normalbackslash{\normalbackslash3321,107882
 
-merc-src/accumulator.m,4275
-:- module transform_hlds.accumulator145,5333
+merc-src/accumulator.m,3228
+:- interface146,5371
 :- import_module hlds148,5386
-:- import_module hlds.hlds_module149,5409
-:- import_module hlds.hlds_pred150,5444
 :- import_module univ152,5478
-:- pred accu_transform_proc(159,5793
-:- import_module hlds.assertion168,6135
-:- import_module hlds.goal_util169,6168
-:- import_module hlds.hlds_error_util170,6201
-:- import_module hlds.hlds_goal171,6240
-:- import_module hlds.hlds_out172,6273
-:- import_module hlds.hlds_out.hlds_out_util173,6305
-:- import_module hlds.hlds_promise174,6351
-:- import_module hlds.instmap175,6387
-:- import_module hlds.pred_table176,6418
-:- import_module hlds.quantification177,6452
-:- import_module hlds.status178,6490
-:- import_module hlds.vartypes179,6520
+:- pred accu_transform_proc159,5793
+:- implementation166,6115
 :- import_module libs180,6552
-:- import_module libs.globals181,6575
-:- import_module libs.optimization_options182,6606
-:- import_module libs.options183,6650
 :- import_module mdbcomp184,6681
-:- import_module mdbcomp.sym_name185,6707
 :- import_module parse_tree186,6742
-:- import_module parse_tree.error_util187,6771
-:- import_module parse_tree.prog_data188,6811
-:- import_module parse_tree.prog_mode189,6850
-:- import_module parse_tree.prog_util190,6889
-:- import_module parse_tree.set_of_var191,6928
-:- import_module transform_hlds.goal_store192,6968
 :- import_module assoc_list194,7013
 :- import_module bool195,7042
 :- import_module int196,7065
@@ -3933,69 +3910,71 @@ merc-src/accumulator.m,4275
 :- type accu_goal_store234,8091
 :- type accu_subst238,8216
 :- type accu_warning240,8264
-:- pred generate_warnings(334,12550
-:- pred generate_warning(342,12895
-:- pred should_attempt_accu_transform(365,13886
-:- pred should_attempt_accu_transform_2(398,15406
-:- pred accu_standardize(440,17390
-:- pred identify_goal_type(465,18169
-:- pred is_recursive_case(549,21175
+:- pred generate_warnings334,12550
+:- pred generate_warning342,12895
+:- pred should_attempt_accu_transform365,13886
+:- pred should_attempt_accu_transform_2398,15406
+:- pred accu_standardize440,17390
+:- pred identify_goal_type465,18169
+:- pred is_recursive_case549,21175
 :- type store_info560,21713
-:- func initialize_goal_store(570,22060
-:- pred accu_store(580,22421
-:- pred identify_recursive_calls(601,23288
-:- pred identify_out_and_out_prime(626,24396
+:- func initialize_goal_store570,22060
+:- pred accu_store580,22421
+:- pred identify_recursive_calls601,23288
+:- pred identify_out_and_out_prime626,24396
 :- type accu_sets676,26425
-:- pred accu_stage1(689,26977
-:- pred accu_stage1_2(727,28347
-:- pred accu_sets_init(781,30557
-:- func set_upto(796,30984
-:- pred accu_before(812,31498
-:- pred accu_assoc(835,32477
-:- pred accu_construct(862,33712
-:- pred accu_construct_assoc(896,35307
-:- pred accu_update(938,37069
-:- pred member_lessthan_goalid(964,38219
+:- pred accu_stage1689,26977
+:- pred accu_stage1_2727,28347
+:- pred accu_sets_init781,30557
+:- func set_upto796,30984
+:- pred accu_before812,31498
+:- pred accu_assoc835,32477
+:- pred accu_construct862,33712
+:- pred accu_construct_assoc896,35307
+:- pred accu_update938,37069
+:- pred member_lessthan_goalid964,38219
 :- type accu_assoc975,38652
-:- pred accu_is_associative(986,39138
-:- pred associativity_assertion(1014,40263
-:- pred commutativity_assertion(1037,41242
-:- pred accu_is_update(1057,41952
-:- pred is_associative_construction(1078,42802
+:- pred accu_is_associative986,39138
+:- pred associativity_assertion1014,40263
+:- pred commutativity_assertion1037,41242
+:- pred accu_is_update1057,41952
+:- pred is_associative_construction1078,42802
 :- type accu_substs1095,43480
 :- type accu_base1103,43744
-:- pred accu_stage2(1124,44605
-:- pred accu_substs_init(1179,46957
-:- pred acc_var_subst_init(1194,47573
-:- pred create_new_var(1207,48147
-:- pred accu_process_assoc_set(1223,48862
-:- pred accu_has_heuristic(1297,52081
-:- pred accu_heuristic(1304,52336
-:- pred accu_process_update_set(1318,52906
-:- pred accu_divide_base_case(1380,55844
-:- pred accu_related(1412,57146
-:- pred lookup_call(1449,58601
-:- pred accu_stage3(1470,59432
-:- pred acc_proc_info(1508,61326
-:- pred acc_pred_info(1556,63449
-:- pred accu_create_goal(1600,65285
-:- func create_acc_call(1621,66400
-:- pred create_orig_goal(1634,66987
-:- pred create_acc_goal(1662,68157
-:- func create_new_orig_recursive_goals(1709,70225
-:- func create_new_recursive_goals(1723,70918
-:- func create_new_base_goals(1738,71717
-:- pred acc_unification(1749,72156
-:- pred accu_top_level(1766,72896
-:- pred update_accumulator_pred(1856,76290
-:- func accu_rename(1876,77253
-:- func base_case_ids(1889,77784
-:- func base_case_ids_set(1898,78048
-:- func accu_goal_list(1905,78269
-:- pred calculate_goal_info(1916,78680
-:- func chain_subst(1932,79319
-:- pred chain_subst_2(1938,79482
-:- end_module transform_hlds.accumulator1953,79939
+:- pred accu_stage21124,44605
+:- pred accu_substs_init1179,46957
+:- pred acc_var_subst_init1194,47573
+:- pred create_new_var1207,48147
+:- pred accu_process_assoc_set1223,48862
+:- pred accu_has_heuristic1297,52081
+:- pred accu_heuristic1304,52336
+:- pred accu_process_update_set1318,52906
+:- pred accu_divide_base_case1380,55844
+:- pred accu_related1412,57146
+:- inst stored_goal_plain_call1444,58415
+:- pred lookup_call1449,58601
+:- pred accu_stage31470,59432
+:- pred acc_proc_info1508,61326
+:- pred acc_pred_info1556,63449
+:- pred accu_create_goal1600,65285
+:- func create_acc_call1621,66400
+:- pred create_orig_goal1634,66987
+:- pred create_acc_goal1662,68157
+:- func create_new_orig_recursive_goals1709,70225
+:- func create_new_recursive_goals1723,70918
+:- func create_new_base_goals1738,71717
+:- pred acc_unification1749,72156
+:- pred accu_top_level1766,72896
+:- pred update_accumulator_pred1856,76290
+:- func accu_rename1876,77253
+:- func base_case_ids1889,77784
+:- func base_case_ids_set1898,78048
+:- func accu_goal_list1905,78269
+:- pred calculate_goal_info1916,78680
+:- func chain_subst1932,79319
+:- pred chain_subst_21938,79482
+:- some [T] pred unravel_univ1956,80060
+:- pragma foreign_export1957,80116
 
 c-src/c.c,76
 T f(1,0
diff --git a/test/manual/etags/ETAGS.good_2 b/test/manual/etags/ETAGS.good_2
index c3d2726..45979d6 100644
--- a/test/manual/etags/ETAGS.good_2
+++ b/test/manual/etags/ETAGS.good_2
@@ -4454,38 +4454,15 @@ 
Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
 \global\def={=3307,107500
 \def\normalbackslash{\normalbackslash3321,107882
 
-merc-src/accumulator.m,5996
-:- module transform_hlds.accumulator145,5333
+merc-src/accumulator.m,4915
+:- interface146,5371
 :- import_module hlds148,5386
-:- import_module hlds.hlds_module149,5409
-:- import_module hlds.hlds_pred150,5444
 :- import_module univ152,5478
-:- pred accu_transform_proc(159,5793
-:- import_module hlds.assertion168,6135
-:- import_module hlds.goal_util169,6168
-:- import_module hlds.hlds_error_util170,6201
-:- import_module hlds.hlds_goal171,6240
-:- import_module hlds.hlds_out172,6273
-:- import_module hlds.hlds_out.hlds_out_util173,6305
-:- import_module hlds.hlds_promise174,6351
-:- import_module hlds.instmap175,6387
-:- import_module hlds.pred_table176,6418
-:- import_module hlds.quantification177,6452
-:- import_module hlds.status178,6490
-:- import_module hlds.vartypes179,6520
+:- pred accu_transform_proc159,5793
+:- implementation166,6115
 :- import_module libs180,6552
-:- import_module libs.globals181,6575
-:- import_module libs.optimization_options182,6606
-:- import_module libs.options183,6650
 :- import_module mdbcomp184,6681
-:- import_module mdbcomp.sym_name185,6707
 :- import_module parse_tree186,6742
-:- import_module parse_tree.error_util187,6771
-:- import_module parse_tree.prog_data188,6811
-:- import_module parse_tree.prog_mode189,6850
-:- import_module parse_tree.prog_util190,6889
-:- import_module parse_tree.set_of_var191,6928
-:- import_module transform_hlds.goal_store192,6968
 :- import_module assoc_list194,7013
 :- import_module bool195,7042
 :- import_module int196,7065
@@ -4506,127 +4483,130 @@ merc-src/accumulator.m,5996
 :- type accu_goal_store234,8091
 :- type accu_subst238,8216
 :- type accu_warning240,8264
-accu_transform_proc(247,8578
-:- pred generate_warnings(334,12550
-generate_warnings(337,12669
-:- pred generate_warning(342,12895
-generate_warning(345,13001
-:- pred should_attempt_accu_transform(365,13886
-should_attempt_accu_transform(370,14123
-:- pred should_attempt_accu_transform_2(398,15406
-should_attempt_accu_transform_2(405,15763
-:- pred accu_standardize(440,17390
-accu_standardize(442,17455
-:- pred identify_goal_type(465,18169
-identify_goal_type(469,18359
-:- pred is_recursive_case(549,21175
-is_recursive_case(551,21253
+accu_transform_proc247,8578
+:- pred generate_warnings334,12550
+generate_warnings337,12669
+:- pred generate_warning342,12895
+generate_warning345,13001
+:- pred should_attempt_accu_transform365,13886
+should_attempt_accu_transform370,14123
+:- pred should_attempt_accu_transform_2398,15406
+should_attempt_accu_transform_2405,15763
+:- pred accu_standardize440,17390
+accu_standardize442,17455
+:- pred identify_goal_type465,18169
+identify_goal_type469,18359
+:- pred is_recursive_case549,21175
+is_recursive_case551,21253
 :- type store_info560,21713
-:- func initialize_goal_store(570,22060
-initialize_goal_store(573,22166
-:- pred accu_store(580,22421
-accu_store(584,22576
-:- pred identify_recursive_calls(601,23288
-identify_recursive_calls(604,23406
-:- pred identify_out_and_out_prime(626,24396
-identify_out_and_out_prime(631,24631
+:- func initialize_goal_store570,22060
+initialize_goal_store573,22166
+:- pred accu_store580,22421
+accu_store584,22576
+:- pred identify_recursive_calls601,23288
+identify_recursive_calls604,23406
+:- pred identify_out_and_out_prime626,24396
+identify_out_and_out_prime631,24631
 :- type accu_sets676,26425
-:- pred accu_stage1(689,26977
-accu_stage1(693,27155
-:- pred accu_stage1_2(727,28347
-accu_stage1_2(731,28515
-:- pred accu_sets_init(781,30557
-accu_sets_init(783,30605
-:- func set_upto(796,30984
-set_upto(798,31039
-:- pred accu_before(812,31498
-accu_before(815,31639
-:- pred accu_assoc(835,32477
-accu_assoc(838,32617
-:- pred accu_construct(862,33712
-accu_construct(865,33856
-:- pred accu_construct_assoc(896,35307
-accu_construct_assoc(899,35457
-:- pred accu_update(938,37069
-accu_update(941,37210
-:- pred member_lessthan_goalid(964,38219
-member_lessthan_goalid(967,38342
+:- pred accu_stage1689,26977
+accu_stage1693,27155
+:- pred accu_stage1_2727,28347
+accu_stage1_2731,28515
+:- pred accu_sets_init781,30557
+accu_sets_init783,30605
+:- func set_upto796,30984
+set_upto798,31039
+:- pred accu_before812,31498
+accu_before815,31639
+:- pred accu_assoc835,32477
+accu_assoc838,32617
+:- pred accu_construct862,33712
+accu_construct865,33856
+:- pred accu_construct_assoc896,35307
+accu_construct_assoc899,35457
+:- pred accu_update938,37069
+accu_update941,37210
+:- pred member_lessthan_goalid964,38219
+member_lessthan_goalid967,38342
 :- type accu_assoc975,38652
-:- pred accu_is_associative(986,39138
-accu_is_associative(989,39250
-:- pred associativity_assertion(1014,40263
-associativity_assertion(1017,40404
-:- pred commutativity_assertion(1037,41242
-commutativity_assertion(1040,41369
-:- pred accu_is_update(1057,41952
-accu_is_update(1060,42066
-:- pred is_associative_construction(1078,42802
-is_associative_construction(1081,42898
+:- pred accu_is_associative986,39138
+accu_is_associative989,39250
+:- pred associativity_assertion1014,40263
+associativity_assertion1017,40404
+:- pred commutativity_assertion1037,41242
+commutativity_assertion1040,41369
+:- pred accu_is_update1057,41952
+accu_is_update1060,42066
+:- pred is_associative_construction1078,42802
+is_associative_construction1081,42898
 :- type accu_substs1095,43480
 :- type accu_base1103,43744
-:- pred accu_stage2(1124,44605
-accu_stage2(1131,44946
-:- pred accu_substs_init(1179,46957
-accu_substs_init(1182,47097
-:- pred acc_var_subst_init(1194,47573
-acc_var_subst_init(1198,47718
-:- pred create_new_var(1207,48147
-create_new_var(1210,48288
-:- pred accu_process_assoc_set(1223,48862
-accu_process_assoc_set(1229,49150
-:- pred accu_has_heuristic(1297,52081
-accu_has_heuristic(1299,52161
-:- pred accu_heuristic(1304,52336
-accu_heuristic(1307,52457
-:- pred accu_process_update_set(1318,52906
-accu_process_update_set(1325,53221
-:- pred accu_divide_base_case(1380,55844
-accu_divide_base_case(1385,56059
-:- pred accu_related(1412,57146
-accu_related(1415,57270
-:- pred lookup_call(1449,58601
-lookup_call(1452,58715
-:- pred accu_stage3(1470,59432
-accu_stage3(1477,59826
-:- pred acc_proc_info(1508,61326
-acc_proc_info(1512,61485
-:- pred acc_pred_info(1556,63449
-acc_pred_info(1559,63597
-:- pred accu_create_goal(1600,65285
-accu_create_goal(1607,65628
-:- func create_acc_call(1621,66400
-create_acc_call(1625,66569
-:- pred create_orig_goal(1634,66987
-create_orig_goal(1638,67176
-:- pred create_acc_goal(1662,68157
-create_acc_goal(1667,68380
-:- func create_new_orig_recursive_goals(1709,70225
-create_new_orig_recursive_goals(1712,70368
-:- func create_new_recursive_goals(1723,70918
-create_new_recursive_goals(1727,71108
-:- func create_new_base_goals(1738,71717
-create_new_base_goals(1741,71831
-:- pred acc_unification(1749,72156
-acc_unification(1751,72225
-:- pred accu_top_level(1766,72896
-accu_top_level(1770,73058
-:- pred update_accumulator_pred(1856,76290
-update_accumulator_pred(1859,76411
-:- func accu_rename(1876,77253
-accu_rename(1879,77363
-:- func base_case_ids(1889,77784
-base_case_ids(1891,77846
-:- func base_case_ids_set(1898,78048
-base_case_ids_set(1900,78113
-:- func accu_goal_list(1905,78269
-accu_goal_list(1907,78349
-:- pred calculate_goal_info(1916,78680
-calculate_goal_info(1918,78753
-:- func chain_subst(1932,79319
-chain_subst(1934,79378
-:- pred chain_subst_2(1938,79482
-chain_subst_2(1941,79576
-:- end_module transform_hlds.accumulator1953,79939
+:- pred accu_stage21124,44605
+accu_stage21131,44946
+:- pred accu_substs_init1179,46957
+accu_substs_init1182,47097
+:- pred acc_var_subst_init1194,47573
+acc_var_subst_init1198,47718
+:- pred create_new_var1207,48147
+create_new_var1210,48288
+:- pred accu_process_assoc_set1223,48862
+accu_process_assoc_set1229,49150
+:- pred accu_has_heuristic1297,52081
+accu_has_heuristic1299,52161
+:- pred accu_heuristic1304,52336
+accu_heuristic1307,52457
+:- pred accu_process_update_set1318,52906
+accu_process_update_set1325,53221
+:- pred accu_divide_base_case1380,55844
+accu_divide_base_case1385,56059
+:- pred accu_related1412,57146
+accu_related1415,57270
+:- inst stored_goal_plain_call1444,58415
+:- pred lookup_call1449,58601
+lookup_call1452,58715
+:- pred accu_stage31470,59432
+accu_stage31477,59826
+:- pred acc_proc_info1508,61326
+acc_proc_info1512,61485
+:- pred acc_pred_info1556,63449
+acc_pred_info1559,63597
+:- pred accu_create_goal1600,65285
+accu_create_goal1607,65628
+:- func create_acc_call1621,66400
+create_acc_call1625,66569
+:- pred create_orig_goal1634,66987
+create_orig_goal1638,67176
+:- pred create_acc_goal1662,68157
+create_acc_goal1667,68380
+:- func create_new_orig_recursive_goals1709,70225
+create_new_orig_recursive_goals1712,70368
+:- func create_new_recursive_goals1723,70918
+create_new_recursive_goals1727,71108
+:- func create_new_base_goals1738,71717
+create_new_base_goals1741,71831
+:- pred acc_unification1749,72156
+acc_unification1751,72225
+:- pred accu_top_level1766,72896
+accu_top_level1770,73058
+:- pred update_accumulator_pred1856,76290
+update_accumulator_pred1859,76411
+:- func accu_rename1876,77253
+accu_rename1879,77363
+:- func base_case_ids1889,77784
+base_case_ids1891,77846
+:- func base_case_ids_set1898,78048
+base_case_ids_set1900,78113
+:- func accu_goal_list1905,78269
+accu_goal_list1907,78349
+:- pred calculate_goal_info1916,78680
+calculate_goal_info1918,78753
+:- func chain_subst1932,79319
+chain_subst1934,79378
+:- pred chain_subst_21938,79482
+chain_subst_21941,79576
+:- some [T] pred unravel_univ1956,80060
+:- pragma foreign_export1957,80116
+unravel_univ1961,80340
 
 c-src/c.c,76
 T f(1,0
diff --git a/test/manual/etags/ETAGS.good_3 b/test/manual/etags/ETAGS.good_3
index 85897feb..36edc38 100644
--- a/test/manual/etags/ETAGS.good_3
+++ b/test/manual/etags/ETAGS.good_3
@@ -4288,38 +4288,15 @@ 
Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
 \global\def={=3307,107500
 \def\normalbackslash{\normalbackslash3321,107882
 
-merc-src/accumulator.m,4275
-:- module transform_hlds.accumulator145,5333
+merc-src/accumulator.m,3228
+:- interface146,5371
 :- import_module hlds148,5386
-:- import_module hlds.hlds_module149,5409
-:- import_module hlds.hlds_pred150,5444
 :- import_module univ152,5478
-:- pred accu_transform_proc(159,5793
-:- import_module hlds.assertion168,6135
-:- import_module hlds.goal_util169,6168
-:- import_module hlds.hlds_error_util170,6201
-:- import_module hlds.hlds_goal171,6240
-:- import_module hlds.hlds_out172,6273
-:- import_module hlds.hlds_out.hlds_out_util173,6305
-:- import_module hlds.hlds_promise174,6351
-:- import_module hlds.instmap175,6387
-:- import_module hlds.pred_table176,6418
-:- import_module hlds.quantification177,6452
-:- import_module hlds.status178,6490
-:- import_module hlds.vartypes179,6520
+:- pred accu_transform_proc159,5793
+:- implementation166,6115
 :- import_module libs180,6552
-:- import_module libs.globals181,6575
-:- import_module libs.optimization_options182,6606
-:- import_module libs.options183,6650
 :- import_module mdbcomp184,6681
-:- import_module mdbcomp.sym_name185,6707
 :- import_module parse_tree186,6742
-:- import_module parse_tree.error_util187,6771
-:- import_module parse_tree.prog_data188,6811
-:- import_module parse_tree.prog_mode189,6850
-:- import_module parse_tree.prog_util190,6889
-:- import_module parse_tree.set_of_var191,6928
-:- import_module transform_hlds.goal_store192,6968
 :- import_module assoc_list194,7013
 :- import_module bool195,7042
 :- import_module int196,7065
@@ -4340,69 +4317,71 @@ merc-src/accumulator.m,4275
 :- type accu_goal_store234,8091
 :- type accu_subst238,8216
 :- type accu_warning240,8264
-:- pred generate_warnings(334,12550
-:- pred generate_warning(342,12895
-:- pred should_attempt_accu_transform(365,13886
-:- pred should_attempt_accu_transform_2(398,15406
-:- pred accu_standardize(440,17390
-:- pred identify_goal_type(465,18169
-:- pred is_recursive_case(549,21175
+:- pred generate_warnings334,12550
+:- pred generate_warning342,12895
+:- pred should_attempt_accu_transform365,13886
+:- pred should_attempt_accu_transform_2398,15406
+:- pred accu_standardize440,17390
+:- pred identify_goal_type465,18169
+:- pred is_recursive_case549,21175
 :- type store_info560,21713
-:- func initialize_goal_store(570,22060
-:- pred accu_store(580,22421
-:- pred identify_recursive_calls(601,23288
-:- pred identify_out_and_out_prime(626,24396
+:- func initialize_goal_store570,22060
+:- pred accu_store580,22421
+:- pred identify_recursive_calls601,23288
+:- pred identify_out_and_out_prime626,24396
 :- type accu_sets676,26425
-:- pred accu_stage1(689,26977
-:- pred accu_stage1_2(727,28347
-:- pred accu_sets_init(781,30557
-:- func set_upto(796,30984
-:- pred accu_before(812,31498
-:- pred accu_assoc(835,32477
-:- pred accu_construct(862,33712
-:- pred accu_construct_assoc(896,35307
-:- pred accu_update(938,37069
-:- pred member_lessthan_goalid(964,38219
+:- pred accu_stage1689,26977
+:- pred accu_stage1_2727,28347
+:- pred accu_sets_init781,30557
+:- func set_upto796,30984
+:- pred accu_before812,31498
+:- pred accu_assoc835,32477
+:- pred accu_construct862,33712
+:- pred accu_construct_assoc896,35307
+:- pred accu_update938,37069
+:- pred member_lessthan_goalid964,38219
 :- type accu_assoc975,38652
-:- pred accu_is_associative(986,39138
-:- pred associativity_assertion(1014,40263
-:- pred commutativity_assertion(1037,41242
-:- pred accu_is_update(1057,41952
-:- pred is_associative_construction(1078,42802
+:- pred accu_is_associative986,39138
+:- pred associativity_assertion1014,40263
+:- pred commutativity_assertion1037,41242
+:- pred accu_is_update1057,41952
+:- pred is_associative_construction1078,42802
 :- type accu_substs1095,43480
 :- type accu_base1103,43744
-:- pred accu_stage2(1124,44605
-:- pred accu_substs_init(1179,46957
-:- pred acc_var_subst_init(1194,47573
-:- pred create_new_var(1207,48147
-:- pred accu_process_assoc_set(1223,48862
-:- pred accu_has_heuristic(1297,52081
-:- pred accu_heuristic(1304,52336
-:- pred accu_process_update_set(1318,52906
-:- pred accu_divide_base_case(1380,55844
-:- pred accu_related(1412,57146
-:- pred lookup_call(1449,58601
-:- pred accu_stage3(1470,59432
-:- pred acc_proc_info(1508,61326
-:- pred acc_pred_info(1556,63449
-:- pred accu_create_goal(1600,65285
-:- func create_acc_call(1621,66400
-:- pred create_orig_goal(1634,66987
-:- pred create_acc_goal(1662,68157
-:- func create_new_orig_recursive_goals(1709,70225
-:- func create_new_recursive_goals(1723,70918
-:- func create_new_base_goals(1738,71717
-:- pred acc_unification(1749,72156
-:- pred accu_top_level(1766,72896
-:- pred update_accumulator_pred(1856,76290
-:- func accu_rename(1876,77253
-:- func base_case_ids(1889,77784
-:- func base_case_ids_set(1898,78048
-:- func accu_goal_list(1905,78269
-:- pred calculate_goal_info(1916,78680
-:- func chain_subst(1932,79319
-:- pred chain_subst_2(1938,79482
-:- end_module transform_hlds.accumulator1953,79939
+:- pred accu_stage21124,44605
+:- pred accu_substs_init1179,46957
+:- pred acc_var_subst_init1194,47573
+:- pred create_new_var1207,48147
+:- pred accu_process_assoc_set1223,48862
+:- pred accu_has_heuristic1297,52081
+:- pred accu_heuristic1304,52336
+:- pred accu_process_update_set1318,52906
+:- pred accu_divide_base_case1380,55844
+:- pred accu_related1412,57146
+:- inst stored_goal_plain_call1444,58415
+:- pred lookup_call1449,58601
+:- pred accu_stage31470,59432
+:- pred acc_proc_info1508,61326
+:- pred acc_pred_info1556,63449
+:- pred accu_create_goal1600,65285
+:- func create_acc_call1621,66400
+:- pred create_orig_goal1634,66987
+:- pred create_acc_goal1662,68157
+:- func create_new_orig_recursive_goals1709,70225
+:- func create_new_recursive_goals1723,70918
+:- func create_new_base_goals1738,71717
+:- pred acc_unification1749,72156
+:- pred accu_top_level1766,72896
+:- pred update_accumulator_pred1856,76290
+:- func accu_rename1876,77253
+:- func base_case_ids1889,77784
+:- func base_case_ids_set1898,78048
+:- func accu_goal_list1905,78269
+:- pred calculate_goal_info1916,78680
+:- func chain_subst1932,79319
+:- pred chain_subst_21938,79482
+:- some [T] pred unravel_univ1956,80060
+:- pragma foreign_export1957,80116
 
 c-src/c.c,76
 T f(1,0
diff --git a/test/manual/etags/ETAGS.good_4 b/test/manual/etags/ETAGS.good_4
index 828a6b8..e726a99 100644
--- a/test/manual/etags/ETAGS.good_4
+++ b/test/manual/etags/ETAGS.good_4
@@ -4043,38 +4043,15 @@ 
Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
 \global\def={=3307,107500
 \def\normalbackslash{\normalbackslash3321,107882
 
-merc-src/accumulator.m,4275
-:- module transform_hlds.accumulator145,5333
+merc-src/accumulator.m,3228
+:- interface146,5371
 :- import_module hlds148,5386
-:- import_module hlds.hlds_module149,5409
-:- import_module hlds.hlds_pred150,5444
 :- import_module univ152,5478
-:- pred accu_transform_proc(159,5793
-:- import_module hlds.assertion168,6135
-:- import_module hlds.goal_util169,6168
-:- import_module hlds.hlds_error_util170,6201
-:- import_module hlds.hlds_goal171,6240
-:- import_module hlds.hlds_out172,6273
-:- import_module hlds.hlds_out.hlds_out_util173,6305
-:- import_module hlds.hlds_promise174,6351
-:- import_module hlds.instmap175,6387
-:- import_module hlds.pred_table176,6418
-:- import_module hlds.quantification177,6452
-:- import_module hlds.status178,6490
-:- import_module hlds.vartypes179,6520
+:- pred accu_transform_proc159,5793
+:- implementation166,6115
 :- import_module libs180,6552
-:- import_module libs.globals181,6575
-:- import_module libs.optimization_options182,6606
-:- import_module libs.options183,6650
 :- import_module mdbcomp184,6681
-:- import_module mdbcomp.sym_name185,6707
 :- import_module parse_tree186,6742
-:- import_module parse_tree.error_util187,6771
-:- import_module parse_tree.prog_data188,6811
-:- import_module parse_tree.prog_mode189,6850
-:- import_module parse_tree.prog_util190,6889
-:- import_module parse_tree.set_of_var191,6928
-:- import_module transform_hlds.goal_store192,6968
 :- import_module assoc_list194,7013
 :- import_module bool195,7042
 :- import_module int196,7065
@@ -4095,69 +4072,71 @@ merc-src/accumulator.m,4275
 :- type accu_goal_store234,8091
 :- type accu_subst238,8216
 :- type accu_warning240,8264
-:- pred generate_warnings(334,12550
-:- pred generate_warning(342,12895
-:- pred should_attempt_accu_transform(365,13886
-:- pred should_attempt_accu_transform_2(398,15406
-:- pred accu_standardize(440,17390
-:- pred identify_goal_type(465,18169
-:- pred is_recursive_case(549,21175
+:- pred generate_warnings334,12550
+:- pred generate_warning342,12895
+:- pred should_attempt_accu_transform365,13886
+:- pred should_attempt_accu_transform_2398,15406
+:- pred accu_standardize440,17390
+:- pred identify_goal_type465,18169
+:- pred is_recursive_case549,21175
 :- type store_info560,21713
-:- func initialize_goal_store(570,22060
-:- pred accu_store(580,22421
-:- pred identify_recursive_calls(601,23288
-:- pred identify_out_and_out_prime(626,24396
+:- func initialize_goal_store570,22060
+:- pred accu_store580,22421
+:- pred identify_recursive_calls601,23288
+:- pred identify_out_and_out_prime626,24396
 :- type accu_sets676,26425
-:- pred accu_stage1(689,26977
-:- pred accu_stage1_2(727,28347
-:- pred accu_sets_init(781,30557
-:- func set_upto(796,30984
-:- pred accu_before(812,31498
-:- pred accu_assoc(835,32477
-:- pred accu_construct(862,33712
-:- pred accu_construct_assoc(896,35307
-:- pred accu_update(938,37069
-:- pred member_lessthan_goalid(964,38219
+:- pred accu_stage1689,26977
+:- pred accu_stage1_2727,28347
+:- pred accu_sets_init781,30557
+:- func set_upto796,30984
+:- pred accu_before812,31498
+:- pred accu_assoc835,32477
+:- pred accu_construct862,33712
+:- pred accu_construct_assoc896,35307
+:- pred accu_update938,37069
+:- pred member_lessthan_goalid964,38219
 :- type accu_assoc975,38652
-:- pred accu_is_associative(986,39138
-:- pred associativity_assertion(1014,40263
-:- pred commutativity_assertion(1037,41242
-:- pred accu_is_update(1057,41952
-:- pred is_associative_construction(1078,42802
+:- pred accu_is_associative986,39138
+:- pred associativity_assertion1014,40263
+:- pred commutativity_assertion1037,41242
+:- pred accu_is_update1057,41952
+:- pred is_associative_construction1078,42802
 :- type accu_substs1095,43480
 :- type accu_base1103,43744
-:- pred accu_stage2(1124,44605
-:- pred accu_substs_init(1179,46957
-:- pred acc_var_subst_init(1194,47573
-:- pred create_new_var(1207,48147
-:- pred accu_process_assoc_set(1223,48862
-:- pred accu_has_heuristic(1297,52081
-:- pred accu_heuristic(1304,52336
-:- pred accu_process_update_set(1318,52906
-:- pred accu_divide_base_case(1380,55844
-:- pred accu_related(1412,57146
-:- pred lookup_call(1449,58601
-:- pred accu_stage3(1470,59432
-:- pred acc_proc_info(1508,61326
-:- pred acc_pred_info(1556,63449
-:- pred accu_create_goal(1600,65285
-:- func create_acc_call(1621,66400
-:- pred create_orig_goal(1634,66987
-:- pred create_acc_goal(1662,68157
-:- func create_new_orig_recursive_goals(1709,70225
-:- func create_new_recursive_goals(1723,70918
-:- func create_new_base_goals(1738,71717
-:- pred acc_unification(1749,72156
-:- pred accu_top_level(1766,72896
-:- pred update_accumulator_pred(1856,76290
-:- func accu_rename(1876,77253
-:- func base_case_ids(1889,77784
-:- func base_case_ids_set(1898,78048
-:- func accu_goal_list(1905,78269
-:- pred calculate_goal_info(1916,78680
-:- func chain_subst(1932,79319
-:- pred chain_subst_2(1938,79482
-:- end_module transform_hlds.accumulator1953,79939
+:- pred accu_stage21124,44605
+:- pred accu_substs_init1179,46957
+:- pred acc_var_subst_init1194,47573
+:- pred create_new_var1207,48147
+:- pred accu_process_assoc_set1223,48862
+:- pred accu_has_heuristic1297,52081
+:- pred accu_heuristic1304,52336
+:- pred accu_process_update_set1318,52906
+:- pred accu_divide_base_case1380,55844
+:- pred accu_related1412,57146
+:- inst stored_goal_plain_call1444,58415
+:- pred lookup_call1449,58601
+:- pred accu_stage31470,59432
+:- pred acc_proc_info1508,61326
+:- pred acc_pred_info1556,63449
+:- pred accu_create_goal1600,65285
+:- func create_acc_call1621,66400
+:- pred create_orig_goal1634,66987
+:- pred create_acc_goal1662,68157
+:- func create_new_orig_recursive_goals1709,70225
+:- func create_new_recursive_goals1723,70918
+:- func create_new_base_goals1738,71717
+:- pred acc_unification1749,72156
+:- pred accu_top_level1766,72896
+:- pred update_accumulator_pred1856,76290
+:- func accu_rename1876,77253
+:- func base_case_ids1889,77784
+:- func base_case_ids_set1898,78048
+:- func accu_goal_list1905,78269
+:- pred calculate_goal_info1916,78680
+:- func chain_subst1932,79319
+:- pred chain_subst_21938,79482
+:- some [T] pred unravel_univ1956,80060
+:- pragma foreign_export1957,80116
 
 c-src/c.c,76
 T f(1,0
diff --git a/test/manual/etags/ETAGS.good_5 b/test/manual/etags/ETAGS.good_5
index 5b1dc4f..5133cc9 100644
--- a/test/manual/etags/ETAGS.good_5
+++ b/test/manual/etags/ETAGS.good_5
@@ -5023,38 +5023,15 @@ 
Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
 \global\def={=3307,107500
 \def\normalbackslash{\normalbackslash3321,107882
 
-merc-src/accumulator.m,5996
-:- module transform_hlds.accumulator145,5333
+merc-src/accumulator.m,4915
+:- interface146,5371
 :- import_module hlds148,5386
-:- import_module hlds.hlds_module149,5409
-:- import_module hlds.hlds_pred150,5444
 :- import_module univ152,5478
-:- pred accu_transform_proc(159,5793
-:- import_module hlds.assertion168,6135
-:- import_module hlds.goal_util169,6168
-:- import_module hlds.hlds_error_util170,6201
-:- import_module hlds.hlds_goal171,6240
-:- import_module hlds.hlds_out172,6273
-:- import_module hlds.hlds_out.hlds_out_util173,6305
-:- import_module hlds.hlds_promise174,6351
-:- import_module hlds.instmap175,6387
-:- import_module hlds.pred_table176,6418
-:- import_module hlds.quantification177,6452
-:- import_module hlds.status178,6490
-:- import_module hlds.vartypes179,6520
+:- pred accu_transform_proc159,5793
+:- implementation166,6115
 :- import_module libs180,6552
-:- import_module libs.globals181,6575
-:- import_module libs.optimization_options182,6606
-:- import_module libs.options183,6650
 :- import_module mdbcomp184,6681
-:- import_module mdbcomp.sym_name185,6707
 :- import_module parse_tree186,6742
-:- import_module parse_tree.error_util187,6771
-:- import_module parse_tree.prog_data188,6811
-:- import_module parse_tree.prog_mode189,6850
-:- import_module parse_tree.prog_util190,6889
-:- import_module parse_tree.set_of_var191,6928
-:- import_module transform_hlds.goal_store192,6968
 :- import_module assoc_list194,7013
 :- import_module bool195,7042
 :- import_module int196,7065
@@ -5075,127 +5052,130 @@ merc-src/accumulator.m,5996
 :- type accu_goal_store234,8091
 :- type accu_subst238,8216
 :- type accu_warning240,8264
-accu_transform_proc(247,8578
-:- pred generate_warnings(334,12550
-generate_warnings(337,12669
-:- pred generate_warning(342,12895
-generate_warning(345,13001
-:- pred should_attempt_accu_transform(365,13886
-should_attempt_accu_transform(370,14123
-:- pred should_attempt_accu_transform_2(398,15406
-should_attempt_accu_transform_2(405,15763
-:- pred accu_standardize(440,17390
-accu_standardize(442,17455
-:- pred identify_goal_type(465,18169
-identify_goal_type(469,18359
-:- pred is_recursive_case(549,21175
-is_recursive_case(551,21253
+accu_transform_proc247,8578
+:- pred generate_warnings334,12550
+generate_warnings337,12669
+:- pred generate_warning342,12895
+generate_warning345,13001
+:- pred should_attempt_accu_transform365,13886
+should_attempt_accu_transform370,14123
+:- pred should_attempt_accu_transform_2398,15406
+should_attempt_accu_transform_2405,15763
+:- pred accu_standardize440,17390
+accu_standardize442,17455
+:- pred identify_goal_type465,18169
+identify_goal_type469,18359
+:- pred is_recursive_case549,21175
+is_recursive_case551,21253
 :- type store_info560,21713
-:- func initialize_goal_store(570,22060
-initialize_goal_store(573,22166
-:- pred accu_store(580,22421
-accu_store(584,22576
-:- pred identify_recursive_calls(601,23288
-identify_recursive_calls(604,23406
-:- pred identify_out_and_out_prime(626,24396
-identify_out_and_out_prime(631,24631
+:- func initialize_goal_store570,22060
+initialize_goal_store573,22166
+:- pred accu_store580,22421
+accu_store584,22576
+:- pred identify_recursive_calls601,23288
+identify_recursive_calls604,23406
+:- pred identify_out_and_out_prime626,24396
+identify_out_and_out_prime631,24631
 :- type accu_sets676,26425
-:- pred accu_stage1(689,26977
-accu_stage1(693,27155
-:- pred accu_stage1_2(727,28347
-accu_stage1_2(731,28515
-:- pred accu_sets_init(781,30557
-accu_sets_init(783,30605
-:- func set_upto(796,30984
-set_upto(798,31039
-:- pred accu_before(812,31498
-accu_before(815,31639
-:- pred accu_assoc(835,32477
-accu_assoc(838,32617
-:- pred accu_construct(862,33712
-accu_construct(865,33856
-:- pred accu_construct_assoc(896,35307
-accu_construct_assoc(899,35457
-:- pred accu_update(938,37069
-accu_update(941,37210
-:- pred member_lessthan_goalid(964,38219
-member_lessthan_goalid(967,38342
+:- pred accu_stage1689,26977
+accu_stage1693,27155
+:- pred accu_stage1_2727,28347
+accu_stage1_2731,28515
+:- pred accu_sets_init781,30557
+accu_sets_init783,30605
+:- func set_upto796,30984
+set_upto798,31039
+:- pred accu_before812,31498
+accu_before815,31639
+:- pred accu_assoc835,32477
+accu_assoc838,32617
+:- pred accu_construct862,33712
+accu_construct865,33856
+:- pred accu_construct_assoc896,35307
+accu_construct_assoc899,35457
+:- pred accu_update938,37069
+accu_update941,37210
+:- pred member_lessthan_goalid964,38219
+member_lessthan_goalid967,38342
 :- type accu_assoc975,38652
-:- pred accu_is_associative(986,39138
-accu_is_associative(989,39250
-:- pred associativity_assertion(1014,40263
-associativity_assertion(1017,40404
-:- pred commutativity_assertion(1037,41242
-commutativity_assertion(1040,41369
-:- pred accu_is_update(1057,41952
-accu_is_update(1060,42066
-:- pred is_associative_construction(1078,42802
-is_associative_construction(1081,42898
+:- pred accu_is_associative986,39138
+accu_is_associative989,39250
+:- pred associativity_assertion1014,40263
+associativity_assertion1017,40404
+:- pred commutativity_assertion1037,41242
+commutativity_assertion1040,41369
+:- pred accu_is_update1057,41952
+accu_is_update1060,42066
+:- pred is_associative_construction1078,42802
+is_associative_construction1081,42898
 :- type accu_substs1095,43480
 :- type accu_base1103,43744
-:- pred accu_stage2(1124,44605
-accu_stage2(1131,44946
-:- pred accu_substs_init(1179,46957
-accu_substs_init(1182,47097
-:- pred acc_var_subst_init(1194,47573
-acc_var_subst_init(1198,47718
-:- pred create_new_var(1207,48147
-create_new_var(1210,48288
-:- pred accu_process_assoc_set(1223,48862
-accu_process_assoc_set(1229,49150
-:- pred accu_has_heuristic(1297,52081
-accu_has_heuristic(1299,52161
-:- pred accu_heuristic(1304,52336
-accu_heuristic(1307,52457
-:- pred accu_process_update_set(1318,52906
-accu_process_update_set(1325,53221
-:- pred accu_divide_base_case(1380,55844
-accu_divide_base_case(1385,56059
-:- pred accu_related(1412,57146
-accu_related(1415,57270
-:- pred lookup_call(1449,58601
-lookup_call(1452,58715
-:- pred accu_stage3(1470,59432
-accu_stage3(1477,59826
-:- pred acc_proc_info(1508,61326
-acc_proc_info(1512,61485
-:- pred acc_pred_info(1556,63449
-acc_pred_info(1559,63597
-:- pred accu_create_goal(1600,65285
-accu_create_goal(1607,65628
-:- func create_acc_call(1621,66400
-create_acc_call(1625,66569
-:- pred create_orig_goal(1634,66987
-create_orig_goal(1638,67176
-:- pred create_acc_goal(1662,68157
-create_acc_goal(1667,68380
-:- func create_new_orig_recursive_goals(1709,70225
-create_new_orig_recursive_goals(1712,70368
-:- func create_new_recursive_goals(1723,70918
-create_new_recursive_goals(1727,71108
-:- func create_new_base_goals(1738,71717
-create_new_base_goals(1741,71831
-:- pred acc_unification(1749,72156
-acc_unification(1751,72225
-:- pred accu_top_level(1766,72896
-accu_top_level(1770,73058
-:- pred update_accumulator_pred(1856,76290
-update_accumulator_pred(1859,76411
-:- func accu_rename(1876,77253
-accu_rename(1879,77363
-:- func base_case_ids(1889,77784
-base_case_ids(1891,77846
-:- func base_case_ids_set(1898,78048
-base_case_ids_set(1900,78113
-:- func accu_goal_list(1905,78269
-accu_goal_list(1907,78349
-:- pred calculate_goal_info(1916,78680
-calculate_goal_info(1918,78753
-:- func chain_subst(1932,79319
-chain_subst(1934,79378
-:- pred chain_subst_2(1938,79482
-chain_subst_2(1941,79576
-:- end_module transform_hlds.accumulator1953,79939
+:- pred accu_stage21124,44605
+accu_stage21131,44946
+:- pred accu_substs_init1179,46957
+accu_substs_init1182,47097
+:- pred acc_var_subst_init1194,47573
+acc_var_subst_init1198,47718
+:- pred create_new_var1207,48147
+create_new_var1210,48288
+:- pred accu_process_assoc_set1223,48862
+accu_process_assoc_set1229,49150
+:- pred accu_has_heuristic1297,52081
+accu_has_heuristic1299,52161
+:- pred accu_heuristic1304,52336
+accu_heuristic1307,52457
+:- pred accu_process_update_set1318,52906
+accu_process_update_set1325,53221
+:- pred accu_divide_base_case1380,55844
+accu_divide_base_case1385,56059
+:- pred accu_related1412,57146
+accu_related1415,57270
+:- inst stored_goal_plain_call1444,58415
+:- pred lookup_call1449,58601
+lookup_call1452,58715
+:- pred accu_stage31470,59432
+accu_stage31477,59826
+:- pred acc_proc_info1508,61326
+acc_proc_info1512,61485
+:- pred acc_pred_info1556,63449
+acc_pred_info1559,63597
+:- pred accu_create_goal1600,65285
+accu_create_goal1607,65628
+:- func create_acc_call1621,66400
+create_acc_call1625,66569
+:- pred create_orig_goal1634,66987
+create_orig_goal1638,67176
+:- pred create_acc_goal1662,68157
+create_acc_goal1667,68380
+:- func create_new_orig_recursive_goals1709,70225
+create_new_orig_recursive_goals1712,70368
+:- func create_new_recursive_goals1723,70918
+create_new_recursive_goals1727,71108
+:- func create_new_base_goals1738,71717
+create_new_base_goals1741,71831
+:- pred acc_unification1749,72156
+acc_unification1751,72225
+:- pred accu_top_level1766,72896
+accu_top_level1770,73058
+:- pred update_accumulator_pred1856,76290
+update_accumulator_pred1859,76411
+:- func accu_rename1876,77253
+accu_rename1879,77363
+:- func base_case_ids1889,77784
+base_case_ids1891,77846
+:- func base_case_ids_set1898,78048
+base_case_ids_set1900,78113
+:- func accu_goal_list1905,78269
+accu_goal_list1907,78349
+:- pred calculate_goal_info1916,78680
+calculate_goal_info1918,78753
+:- func chain_subst1932,79319
+chain_subst1934,79378
+:- pred chain_subst_21938,79482
+chain_subst_21941,79576
+:- some [T] pred unravel_univ1956,80060
+:- pragma foreign_export1957,80116
+unravel_univ1961,80340
 
 c-src/c.c,76
 T f(1,0
diff --git a/test/manual/etags/ETAGS.good_6 b/test/manual/etags/ETAGS.good_6
index 68cbaa9..7504795 100644
--- a/test/manual/etags/ETAGS.good_6
+++ b/test/manual/etags/ETAGS.good_6
@@ -5023,38 +5023,15 @@ 
Section\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
 \global\def={=3307,107500
 \def\normalbackslash{\normalbackslash3321,107882
 
-merc-src/accumulator.m,5996
-:- module transform_hlds.accumulator145,5333
+merc-src/accumulator.m,4915
+:- interface146,5371
 :- import_module hlds148,5386
-:- import_module hlds.hlds_module149,5409
-:- import_module hlds.hlds_pred150,5444
 :- import_module univ152,5478
-:- pred accu_transform_proc(159,5793
-:- import_module hlds.assertion168,6135
-:- import_module hlds.goal_util169,6168
-:- import_module hlds.hlds_error_util170,6201
-:- import_module hlds.hlds_goal171,6240
-:- import_module hlds.hlds_out172,6273
-:- import_module hlds.hlds_out.hlds_out_util173,6305
-:- import_module hlds.hlds_promise174,6351
-:- import_module hlds.instmap175,6387
-:- import_module hlds.pred_table176,6418
-:- import_module hlds.quantification177,6452
-:- import_module hlds.status178,6490
-:- import_module hlds.vartypes179,6520
+:- pred accu_transform_proc159,5793
+:- implementation166,6115
 :- import_module libs180,6552
-:- import_module libs.globals181,6575
-:- import_module libs.optimization_options182,6606
-:- import_module libs.options183,6650
 :- import_module mdbcomp184,6681
-:- import_module mdbcomp.sym_name185,6707
 :- import_module parse_tree186,6742
-:- import_module parse_tree.error_util187,6771
-:- import_module parse_tree.prog_data188,6811
-:- import_module parse_tree.prog_mode189,6850
-:- import_module parse_tree.prog_util190,6889
-:- import_module parse_tree.set_of_var191,6928
-:- import_module transform_hlds.goal_store192,6968
 :- import_module assoc_list194,7013
 :- import_module bool195,7042
 :- import_module int196,7065
@@ -5075,127 +5052,130 @@ merc-src/accumulator.m,5996
 :- type accu_goal_store234,8091
 :- type accu_subst238,8216
 :- type accu_warning240,8264
-accu_transform_proc(247,8578
-:- pred generate_warnings(334,12550
-generate_warnings(337,12669
-:- pred generate_warning(342,12895
-generate_warning(345,13001
-:- pred should_attempt_accu_transform(365,13886
-should_attempt_accu_transform(370,14123
-:- pred should_attempt_accu_transform_2(398,15406
-should_attempt_accu_transform_2(405,15763
-:- pred accu_standardize(440,17390
-accu_standardize(442,17455
-:- pred identify_goal_type(465,18169
-identify_goal_type(469,18359
-:- pred is_recursive_case(549,21175
-is_recursive_case(551,21253
+accu_transform_proc247,8578
+:- pred generate_warnings334,12550
+generate_warnings337,12669
+:- pred generate_warning342,12895
+generate_warning345,13001
+:- pred should_attempt_accu_transform365,13886
+should_attempt_accu_transform370,14123
+:- pred should_attempt_accu_transform_2398,15406
+should_attempt_accu_transform_2405,15763
+:- pred accu_standardize440,17390
+accu_standardize442,17455
+:- pred identify_goal_type465,18169
+identify_goal_type469,18359
+:- pred is_recursive_case549,21175
+is_recursive_case551,21253
 :- type store_info560,21713
-:- func initialize_goal_store(570,22060
-initialize_goal_store(573,22166
-:- pred accu_store(580,22421
-accu_store(584,22576
-:- pred identify_recursive_calls(601,23288
-identify_recursive_calls(604,23406
-:- pred identify_out_and_out_prime(626,24396
-identify_out_and_out_prime(631,24631
+:- func initialize_goal_store570,22060
+initialize_goal_store573,22166
+:- pred accu_store580,22421
+accu_store584,22576
+:- pred identify_recursive_calls601,23288
+identify_recursive_calls604,23406
+:- pred identify_out_and_out_prime626,24396
+identify_out_and_out_prime631,24631
 :- type accu_sets676,26425
-:- pred accu_stage1(689,26977
-accu_stage1(693,27155
-:- pred accu_stage1_2(727,28347
-accu_stage1_2(731,28515
-:- pred accu_sets_init(781,30557
-accu_sets_init(783,30605
-:- func set_upto(796,30984
-set_upto(798,31039
-:- pred accu_before(812,31498
-accu_before(815,31639
-:- pred accu_assoc(835,32477
-accu_assoc(838,32617
-:- pred accu_construct(862,33712
-accu_construct(865,33856
-:- pred accu_construct_assoc(896,35307
-accu_construct_assoc(899,35457
-:- pred accu_update(938,37069
-accu_update(941,37210
-:- pred member_lessthan_goalid(964,38219
-member_lessthan_goalid(967,38342
+:- pred accu_stage1689,26977
+accu_stage1693,27155
+:- pred accu_stage1_2727,28347
+accu_stage1_2731,28515
+:- pred accu_sets_init781,30557
+accu_sets_init783,30605
+:- func set_upto796,30984
+set_upto798,31039
+:- pred accu_before812,31498
+accu_before815,31639
+:- pred accu_assoc835,32477
+accu_assoc838,32617
+:- pred accu_construct862,33712
+accu_construct865,33856
+:- pred accu_construct_assoc896,35307
+accu_construct_assoc899,35457
+:- pred accu_update938,37069
+accu_update941,37210
+:- pred member_lessthan_goalid964,38219
+member_lessthan_goalid967,38342
 :- type accu_assoc975,38652
-:- pred accu_is_associative(986,39138
-accu_is_associative(989,39250
-:- pred associativity_assertion(1014,40263
-associativity_assertion(1017,40404
-:- pred commutativity_assertion(1037,41242
-commutativity_assertion(1040,41369
-:- pred accu_is_update(1057,41952
-accu_is_update(1060,42066
-:- pred is_associative_construction(1078,42802
-is_associative_construction(1081,42898
+:- pred accu_is_associative986,39138
+accu_is_associative989,39250
+:- pred associativity_assertion1014,40263
+associativity_assertion1017,40404
+:- pred commutativity_assertion1037,41242
+commutativity_assertion1040,41369
+:- pred accu_is_update1057,41952
+accu_is_update1060,42066
+:- pred is_associative_construction1078,42802
+is_associative_construction1081,42898
 :- type accu_substs1095,43480
 :- type accu_base1103,43744
-:- pred accu_stage2(1124,44605
-accu_stage2(1131,44946
-:- pred accu_substs_init(1179,46957
-accu_substs_init(1182,47097
-:- pred acc_var_subst_init(1194,47573
-acc_var_subst_init(1198,47718
-:- pred create_new_var(1207,48147
-create_new_var(1210,48288
-:- pred accu_process_assoc_set(1223,48862
-accu_process_assoc_set(1229,49150
-:- pred accu_has_heuristic(1297,52081
-accu_has_heuristic(1299,52161
-:- pred accu_heuristic(1304,52336
-accu_heuristic(1307,52457
-:- pred accu_process_update_set(1318,52906
-accu_process_update_set(1325,53221
-:- pred accu_divide_base_case(1380,55844
-accu_divide_base_case(1385,56059
-:- pred accu_related(1412,57146
-accu_related(1415,57270
-:- pred lookup_call(1449,58601
-lookup_call(1452,58715
-:- pred accu_stage3(1470,59432
-accu_stage3(1477,59826
-:- pred acc_proc_info(1508,61326
-acc_proc_info(1512,61485
-:- pred acc_pred_info(1556,63449
-acc_pred_info(1559,63597
-:- pred accu_create_goal(1600,65285
-accu_create_goal(1607,65628
-:- func create_acc_call(1621,66400
-create_acc_call(1625,66569
-:- pred create_orig_goal(1634,66987
-create_orig_goal(1638,67176
-:- pred create_acc_goal(1662,68157
-create_acc_goal(1667,68380
-:- func create_new_orig_recursive_goals(1709,70225
-create_new_orig_recursive_goals(1712,70368
-:- func create_new_recursive_goals(1723,70918
-create_new_recursive_goals(1727,71108
-:- func create_new_base_goals(1738,71717
-create_new_base_goals(1741,71831
-:- pred acc_unification(1749,72156
-acc_unification(1751,72225
-:- pred accu_top_level(1766,72896
-accu_top_level(1770,73058
-:- pred update_accumulator_pred(1856,76290
-update_accumulator_pred(1859,76411
-:- func accu_rename(1876,77253
-accu_rename(1879,77363
-:- func base_case_ids(1889,77784
-base_case_ids(1891,77846
-:- func base_case_ids_set(1898,78048
-base_case_ids_set(1900,78113
-:- func accu_goal_list(1905,78269
-accu_goal_list(1907,78349
-:- pred calculate_goal_info(1916,78680
-calculate_goal_info(1918,78753
-:- func chain_subst(1932,79319
-chain_subst(1934,79378
-:- pred chain_subst_2(1938,79482
-chain_subst_2(1941,79576
-:- end_module transform_hlds.accumulator1953,79939
+:- pred accu_stage21124,44605
+accu_stage21131,44946
+:- pred accu_substs_init1179,46957
+accu_substs_init1182,47097
+:- pred acc_var_subst_init1194,47573
+acc_var_subst_init1198,47718
+:- pred create_new_var1207,48147
+create_new_var1210,48288
+:- pred accu_process_assoc_set1223,48862
+accu_process_assoc_set1229,49150
+:- pred accu_has_heuristic1297,52081
+accu_has_heuristic1299,52161
+:- pred accu_heuristic1304,52336
+accu_heuristic1307,52457
+:- pred accu_process_update_set1318,52906
+accu_process_update_set1325,53221
+:- pred accu_divide_base_case1380,55844
+accu_divide_base_case1385,56059
+:- pred accu_related1412,57146
+accu_related1415,57270
+:- inst stored_goal_plain_call1444,58415
+:- pred lookup_call1449,58601
+lookup_call1452,58715
+:- pred accu_stage31470,59432
+accu_stage31477,59826
+:- pred acc_proc_info1508,61326
+acc_proc_info1512,61485
+:- pred acc_pred_info1556,63449
+acc_pred_info1559,63597
+:- pred accu_create_goal1600,65285
+accu_create_goal1607,65628
+:- func create_acc_call1621,66400
+create_acc_call1625,66569
+:- pred create_orig_goal1634,66987
+create_orig_goal1638,67176
+:- pred create_acc_goal1662,68157
+create_acc_goal1667,68380
+:- func create_new_orig_recursive_goals1709,70225
+create_new_orig_recursive_goals1712,70368
+:- func create_new_recursive_goals1723,70918
+create_new_recursive_goals1727,71108
+:- func create_new_base_goals1738,71717
+create_new_base_goals1741,71831
+:- pred acc_unification1749,72156
+acc_unification1751,72225
+:- pred accu_top_level1766,72896
+accu_top_level1770,73058
+:- pred update_accumulator_pred1856,76290
+update_accumulator_pred1859,76411
+:- func accu_rename1876,77253
+accu_rename1879,77363
+:- func base_case_ids1889,77784
+base_case_ids1891,77846
+:- func base_case_ids_set1898,78048
+base_case_ids_set1900,78113
+:- func accu_goal_list1905,78269
+accu_goal_list1907,78349
+:- pred calculate_goal_info1916,78680
+calculate_goal_info1918,78753
+:- func chain_subst1932,79319
+chain_subst1934,79378
+:- pred chain_subst_21938,79482
+chain_subst_21941,79576
+:- some [T] pred unravel_univ1956,80060
+:- pragma foreign_export1957,80116
+unravel_univ1961,80340
 
 c-src/c.c,76
 T f(1,0
diff --git a/test/manual/etags/merc-src/accumulator.m 
b/test/manual/etags/merc-src/accumulator.m
index 94a6b1d..c82dbf5 100644
--- a/test/manual/etags/merc-src/accumulator.m
+++ b/test/manual/etags/merc-src/accumulator.m
@@ -1952,3 +1952,11 @@ chain_subst_2([A | As], AtoB, BtoC, AtoC) :-
 %---------------------------------------------------------------------------%
 :- end_module transform_hlds.accumulator.
 %---------------------------------------------------------------------------%
+
+:- some [T] pred unravel_univ(univ::in, T::out) is det.
+:- pragma foreign_export("C", unravel_univ(in, out), "ML_unravel_univ").
+:- pragma foreign_export("C#", unravel_univ(in, out), "ML_unravel_univ").
+:- pragma foreign_export("Java", unravel_univ(in, out), "ML_unravel_univ").
+
+unravel_univ(Univ, X) :-
+    univ_value(Univ) = X.
diff --git a/test/manual/indent/scss-mode.scss 
b/test/manual/indent/scss-mode.scss
index 189ec4e..2cd4adb 100644
--- a/test/manual/indent/scss-mode.scss
+++ b/test/manual/indent/scss-mode.scss
@@ -1,5 +1,7 @@
 // Comment!
 
+@use "sass:math";
+
 nav {
     ul {
         margin: 0;              /* More comment */
@@ -44,8 +46,8 @@ article[role="main"] {
     $var_with_underscores: #fff;
     $_var-starting-with-underscore: none;
     float: left !important;
-    width: 600px / 888px * 100%;
-    height: 100px / 888px * 100%;
+    width: math.div(600px, 888px) * 100%;
+    height: math.div(100px, 888px) * 100%;
     color: $var_with_underscores;
     display: $_var-starting-with-underscore;
 }
diff --git a/test/src/syntax-tests.el b/test/src/syntax-tests.el
index 479b818..e4e3054 100644
--- a/test/src/syntax-tests.el
+++ b/test/src/syntax-tests.el
@@ -21,6 +21,7 @@
 
 (require 'ert)
 (require 'ert-x)
+(require 'cl-lib)
 
 (ert-deftest parse-partial-sexp-continue-over-comment-marker ()
   "Continue a parse that stopped in the middle of a comment marker."
@@ -56,6 +57,16 @@
       (should (equal (parse-partial-sexp aftC pointX nil nil pps-aftC)
                      ppsX)))))
 
+(ert-deftest syntax-class-character-test ()
+  (cl-loop for char across " .w_()'\"$\\/<>@!|"
+           for i from 0
+           do (should (= char (syntax-class-to-char i)))
+           when (string-to-syntax (string char))
+           do (should (= char (syntax-class-to-char
+                               (car (string-to-syntax (string char)))))))
+  (should-error (syntax-class-to-char -1))
+  (should-error (syntax-class-to-char 200)))
+
 (ert-deftest parse-partial-sexp-paren-comments ()
   "Test syntax parsing with paren comment markers.
 Specifically, where the first character of the comment marker is



reply via email to

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