emacs-diffs
[Top][All Lists]
Advanced

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

feature/android 6abed48e5c2: Merge remote-tracking branch 'origin/master


From: Po Lu
Subject: feature/android 6abed48e5c2: Merge remote-tracking branch 'origin/master' into feature/android
Date: Thu, 6 Apr 2023 20:27:17 -0400 (EDT)

branch: feature/android
commit 6abed48e5c20559d63617a13fd379aaf5580594d
Merge: 65987f85061 5e5f5b28e92
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Merge remote-tracking branch 'origin/master' into feature/android
---
 admin/notes/emba                     |  40 +++++++++
 doc/emacs/trouble.texi               |  12 ++-
 doc/lispref/commands.texi            |   6 +-
 doc/lispref/display.texi             |  74 ++++++++++++----
 doc/lispref/frames.texi              |   2 +-
 doc/lispref/functions.texi           |  19 ++--
 doc/lispref/keymaps.texi             |  19 ++--
 etc/NEWS.29                          |  28 +++---
 etc/refcards/orgcard.tex             |   2 +-
 lisp/Makefile.in                     |   8 ++
 lisp/image.el                        |  50 +++++++----
 lisp/international/emoji.el          |  60 +++++++++----
 lisp/international/mule-cmds.el      |   3 +-
 lisp/minibuffer.el                   |  26 +++++-
 lisp/net/eww.el                      |   2 +-
 lisp/org/ob-comint.el                |  37 ++++----
 lisp/org/org-version.el              |   4 +-
 lisp/org/org.el                      |  35 ++++----
 lisp/progmodes/c-ts-mode.el          |   6 +-
 lisp/progmodes/cc-engine.el          |  13 ++-
 lisp/progmodes/eglot.el              |   6 +-
 lisp/progmodes/elixir-ts-mode.el     |  47 ++++++++--
 lisp/progmodes/typescript-ts-mode.el |   5 +-
 lisp/progmodes/vhdl-mode.el          |   2 +-
 lisp/saveplace.el                    | 163 +++++++++++++++++++++--------------
 lisp/subr.el                         |   7 +-
 src/xterm.c                          |   2 +-
 test/infra/Dockerfile.emba           |  21 +++--
 28 files changed, 477 insertions(+), 222 deletions(-)

diff --git a/admin/notes/emba b/admin/notes/emba
index 564cc3c54ac..c88b422a4fa 100644
--- a/admin/notes/emba
+++ b/admin/notes/emba
@@ -83,6 +83,46 @@ Lisp packages, Makefiles, scripts, and other software could 
determine
 whether they run on emba by checking for the environment variable
 EMACS_EMBA_CI.
 
+* Running Emba tests locally
+
+As usual in GitLab, the tests run in containers, which could be
+applied also locally.  Unfortunately, the Emba container registry,
+emba.gnu.org:5050, is not accessible publicly.  Instead, the container
+images must be build locally.  Change the current directory to a
+recent Emacs branch, and apply the command
+
+  docker build --target emacs-inotify --tag emacs-inotify \
+    -f test/infra/Dockerfile.emba .
+
+This creates the Debian-based image emacs-inotify, based on the
+instructions in the file Dockerfile.emba.  This image is good for the
+majority of tests.  However, there are also other image build
+instructions like emacs-filenotify-gio, emacs-eglot, emacs-gnustep and
+emacs-native-comp-speed{0,1,2}.  Use the appropriate one.
+
+The image contains a directory "/checkout", which is a copy of your
+local Emacs git repository.  Emacs has been built in this directory
+via "make bootstrap".  In order to use the image, start a container
+like
+
+  docker run --interactive --env EMACS_EMBA_CI=1 --name emacs-inotify \
+    emacs-inotify /bin/sh -i
+
+In this container, change the current directory to "/checkout".  Now
+you can apply all commands known for Emacs, like
+
+  cd /checkout
+  make -C test files-tests.log
+
+While this container runs, you can also access its filesystem from
+your local Emacs via Tramp.  For example, in order to see the result
+of the above test run, open the log file in your local Emacs with
+
+  C-x C-f /docker:emacs-inotify:/checkout/test/lisp/files-tests.log
+
+Note: On local Red Hat-based systems, use "podman" instead of "docker"
+in the shell commands and Tramp file names.
+
 
 This file is part of GNU Emacs.
 
diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi
index ded9d02cf54..db78895bb5b 100644
--- a/doc/emacs/trouble.texi
+++ b/doc/emacs/trouble.texi
@@ -856,7 +856,7 @@ customizations.
 @cindex dribble file
 @cindex logging keystrokes
 One way to record the input to Emacs precisely is to write a dribble
-file.  To start the file, use the @kbd{M-x open-dribble-file} command.
+file.  To start the file, use the command @w{@kbd{M-x open-dribble-file}}.
 From then on, Emacs copies all your input to the specified dribble
 file until the Emacs process is killed.  Be aware that sensitive
 information (such as passwords) may end up recorded in the dribble
@@ -1071,9 +1071,13 @@ backtrace for the error.  To make a backtrace for the 
error, use
 say, you must give that command and then make the bug happen).  This
 causes the error to start the Lisp debugger, which shows you a
 backtrace.  Copy the text of the debugger's backtrace into the bug
-report.  @xref{Edebug,, Edebug, elisp, the Emacs Lisp Reference
-Manual}, for information on debugging Emacs Lisp programs with the
-Edebug package.
+report.  (The backtrace is more detailed if you load the relevant Lisp
+@file{*.el} source files before triggering the error, so do that if
+you know how to find and load those files.)
+
+To debug the error, we suggest using Edebug.  @xref{Edebug,, Edebug,
+elisp, the Emacs Lisp Reference Manual}, for information on debugging
+Emacs Lisp programs with the Edebug package.
 
 This use of the debugger is possible only if you know how to make the
 bug happen again.  If you can't make it happen again, at least copy
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index c150ae05de3..e199000514d 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -1960,8 +1960,8 @@ end-position of a drag event, this position list may 
represent a
 location outside the boundaries of the initially selected frame, in
 which case the list contains that frame in place of a window.
 
-The special form @code{track-mouse} enables generation of motion
-events within its body.  Outside of @code{track-mouse} forms, Emacs
+The @code{track-mouse} macro enables generation of motion
+events within its body.  Outside of @code{track-mouse} body, Emacs
 does not generate events for mere motion of the mouse, and these
 events do not appear.  @xref{Mouse Tracking}.
 
@@ -2552,7 +2552,7 @@ into another window.  That produces a pair of events like 
these:
 
 The frame with input focus might not take up the entire screen, and
 the user might move the mouse outside the scope of the frame.  Inside
-the @code{track-mouse} special form, that produces an event like this:
+the @code{track-mouse} macro, that produces an event like this:
 
 @smallexample
 (mouse-movement (#<frame *ielm* 0x102849a30> nil (563 . 205) 532301936))
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index bb7ba057eb4..a61150d9f69 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -310,29 +310,29 @@ reformatted, with undesirable results.  Instead, use 
@code{(message
 "%s" @var{string})}.
 @end defun
 
+The following facilities allow users and Lisp programs to control how
+echo-area messages are displayed.
+
 @defvar set-message-function
 If this variable is non-@code{nil}, it should be a function of one
-argument, the text of a message to display in the echo area.  This
+argument, the text of a message to display in the echo area.  That
 function will be called by @code{message} and related functions.  If
 the function returns @code{nil}, the message is displayed in the echo
-area as usual.  If this function returns a string, that string is
-displayed in the echo area instead of the original one.  If this
-function returns other non-@code{nil} values, that means the message
-was already handled, so @code{message} will not display anything in
-the echo area.  See also @code{clear-message-function} that can be
-used to clear the message displayed by this function.
-
-The default value is the function that displays the message at the end
-of the minibuffer when the minibuffer is active.  However, if the text
-shown in the active minibuffer has the @code{minibuffer-message} text
-property (@pxref{Special Properties}) on some character, the message
-will be displayed before the first character having that property.
+area as usual.  If the function returns a string, that string is
+displayed in the echo area @emph{instead} of the original message.  If
+the function returns any other non-@code{nil} value, that means the
+message was already handled, so @code{message} will not display
+anything in the echo area.
+
+The default value calls @code{set-minibuffer-message}, described
+below.
 @end defvar
 
 @defvar clear-message-function
-If this variable is non-@code{nil}, @code{message} and related
-functions call it with no arguments when their argument message is
-@code{nil} or the empty string.
+If this variable is non-@code{nil}, it should be a function of no
+arguments; @code{message} and related functions call it when their
+argument message is @code{nil} or the empty string, to clear the echo
+area.
 
 Usually this function is called when the next input event arrives
 after displaying an echo-area message.  The function is expected to
@@ -358,11 +358,51 @@ with the same text; if the last function in the list 
returns
 function returns a non-@code{nil} value that is not a string, the
 message is considered to be handled, and no further functions in the
 list are called.
+
+The three useful functions to be put in the list that is the value of
+this option are described below.
 @end defopt
 
+@defun set-minibuffer-message message
+This function displays @var{message} in the echo-area when the
+minibuffer is not active, and at the end of the minibuffer when the
+minibuffer is active.  However, if the text shown in the active
+minibuffer has the @code{minibuffer-message} text property
+(@pxref{Special Properties}) on some character, the message will be
+displayed before the first character having that property.
+
+This function is by default the only member of the list in
+@code{set-message-functions}.
+@end defun
+
+@vindex inhibit-message-regexps
+@defun inhibit-message message
+If an echo-area @var{message} matches any regexp in the list that is
+the value of the user option @code{inhibit-message-regexps}, this
+function suppresses the display of that message and returns a
+non-@code{nil} value that is not a string.  Thus, if this function is
+in the list @code{set-message-functions}, the rest of the functions in
+the list will not be called when @var{message} matches the regexps in
+@code{inhibit-message-regexps}.  To ensure a matching @var{message}
+will never be displayed, make this function be the first element of
+the list in @code{set-message-functions}.
+@end defun
+
+@vindex multi-message-max
+@vindex multi-message-timeout
+@defun set-multi-message message
+This function accumulates several echo-area messages emitted one after
+another, and returns them as a single string in which individual
+messages are separated by newlines.  Up to @code{multi-message-max}
+recent messages can be accumulated.  The accumulated messages are
+discarded when more than @code{multi-message-timeout} seconds have
+elapsed since the time the first message was emitted.
+@end defun
+
 @defvar inhibit-message
 When this variable is non-@code{nil}, @code{message} and related functions
-will not use the Echo Area to display messages.
+will not display any messages in the Echo Area.  Echo-area messages
+are still logged in the @file{*Messages*} buffer, though.
 @end defvar
 
 @defmac with-temp-message message &rest body
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 2208363aea8..9083b4b01c9 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -3579,7 +3579,7 @@ the mouse position list will be @code{nil} if the value is
 @code{drag-source}.  This is useful to determine if a frame is not
 directly visible underneath the mouse pointer.
 
-The @code{track-mouse} form causes Emacs to generate mouse motion
+The @code{track-mouse} macro causes Emacs to generate mouse motion
 events by binding the variable @code{track-mouse} to a
 non-@code{nil} value.  If that variable has the special value
 @code{dragging}, it additionally instructs the display engine to
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index e9841821431..42441361fea 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -593,8 +593,8 @@ symbol a function definition, its function cell is said to 
be
   In practice, nearly all functions have names, and are referred to by
 their names.  You can create a named Lisp function by defining a
 lambda expression and putting it in a function cell (@pxref{Function
-Cells}).  However, it is more common to use the @code{defun} special
-form, described in the next section.
+Cells}).  However, it is more common to use the @code{defun} macro,
+described in the next section.
 @ifnottex
 @xref{Defining Functions}.
 @end ifnottex
@@ -2693,13 +2693,14 @@ byte compiler can check that the calls match the 
declaration.
 Tell the byte compiler to assume that @var{function} is defined in the
 file @var{file}.  The optional third argument @var{arglist} is either
 @code{t}, meaning the argument list is unspecified, or a list of
-formal parameters in the same style as @code{defun}.  An omitted
-@var{arglist} defaults to @code{t}, not @code{nil}; this is atypical
-behavior for omitted arguments, and it means that to supply a fourth
-but not third argument one must specify @code{t} for the third-argument
-placeholder instead of the usual @code{nil}.  The optional fourth
-argument @var{fileonly} non-@code{nil} means check only that
-@var{file} exists, not that it actually defines @var{function}.
+formal parameters in the same style as @code{defun} (including the
+parentheses).  An omitted @var{arglist} defaults to @code{t}, not
+@code{nil}; this is atypical behavior for omitted arguments, and it
+means that to supply a fourth but not third argument one must specify
+@code{t} for the third-argument placeholder instead of the usual
+@code{nil}.  The optional fourth argument @var{fileonly}
+non-@code{nil} means check only that @var{file} exists, not that it
+actually defines @var{function}.
 @end defmac
 
 @findex check-declare-file
diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi
index fdab5075b94..6d07ad5be2c 100644
--- a/doc/lispref/keymaps.texi
+++ b/doc/lispref/keymaps.texi
@@ -768,8 +768,8 @@ prefix definition, and then by those from the global map.
   In the following example, we make @kbd{C-p} a prefix key in the local
 keymap, in such a way that @kbd{C-p} is identical to @kbd{C-x}.  Then
 the binding for @kbd{C-p C-f} is the function @code{find-file}, just
-like @kbd{C-x C-f}.  The key sequence @kbd{C-p 6} is not found in any
-active keymap.
+like @kbd{C-x C-f}.  By contrast, the key sequence @kbd{C-p 9} is not
+found in any active keymap.
 
 @example
 @group
@@ -778,15 +778,14 @@ active keymap.
 @end group
 @group
 (keymap-local-set "C-p" ctl-x-map)
-    @result{} nil
+    @result{} (keymap #^[nil nil keymap @dots{}
 @end group
 @group
-(keymap-binding "C-p C-f")
+(keymap-lookup nil "C-p C-f")
     @result{} find-file
 @end group
-
 @group
-(keymap-binding "C-p 6")
+(keymap-lookup nil "C-p 9")
     @result{} nil
 @end group
 @end example
@@ -883,7 +882,7 @@ Normally it ignores @code{overriding-local-map} and
 then it pays attention to them.  @var{position} can optionally be either
 an event position as returned by @code{event-start} or a buffer
 position, and may change the keymaps as described for
-@code{keymap-binding}.
+@code{keymap-lookup} (@pxref{Functions for Key Lookup, keymap-lookup}).
 @end defun
 
 @node Searching Keymaps
@@ -1308,7 +1307,11 @@ the second example.
 @end group
 @end example
 
-The @var{keymap} argument can also be a list of keymaps.
+The @var{keymap} argument can be @code{nil}, meaning to look up
+@var{key} in the current keymaps (as returned by
+@code{current-active-maps}, @pxref{Active Keymaps}); or it can be a
+keymap or a list of keymaps, meaning to look up @var{key} only in the
+specified keymaps.
 
 Unlike @code{read-key-sequence}, this function does not modify the
 specified events in ways that discard information (@pxref{Key Sequence
diff --git a/etc/NEWS.29 b/etc/NEWS.29
index d7a6cf7986d..dc4eb64a63a 100644
--- a/etc/NEWS.29
+++ b/etc/NEWS.29
@@ -795,13 +795,14 @@ part of the buffer.
 
 +++
 ** New user option 'set-message-functions'.
-It allows selecting more functions for 'set-message-function'
-in addition to the default function that handles messages
-in the active minibuffer.  The most useful are 'inhibit-message'
-that allows specifying a list of messages to inhibit via
-'inhibit-message-regexps', and 'set-multi-message' that
-accumulates recent messages and displays them stacked
-in the echo area.
+It allows more flexible control of how echo-area messages are displayed
+by adding functions to this list.  The default value is a list of one
+element: 'set-minibuffer-message', which displays echo-area messages
+at the end of the minibuffer text when the minibuffer is active.
+Other useful functions include 'inhibit-message', which allows
+specifying, via 'inhibit-message-regexps', the list of messages whose
+display shall be inhibited; and 'set-multi-message' that accumulates
+recent messages and displays them stacked together.
 
 ---
 ** New user option 'find-library-include-other-files'.
@@ -1020,6 +1021,11 @@ works for non-Emoji characters.)
 These are bound to 'C-x 8 e +' and 'C-x 8 e -', respectively.  They
 can be used on any character, but are mainly useful for Emoji.
 
+---
+*** New command 'emoji-zoom-reset'.
+This is bound to 'C-x 8 e 0', and undoes any size changes performed by
+'emoji-zoom-increase' and 'emoji-zoom-decrease'.
+
 ---
 *** New input method 'emoji'.
 This allows you to enter Emoji using short strings, eg ':face_palm:'
@@ -4322,9 +4328,11 @@ that binding is ignored by 'where-is-internal'.
 
 +++
 *** New functions for defining and manipulating keystrokes.
-These all take the syntax defined by 'key-valid-p'.  None of the older
-functions have been deprecated or altered, but they are now
-de-emphasized in the documentation.
+These all take the syntax defined by 'key-valid-p', which is basically
+the same syntax as the one accepted by the 'kbd' macro.  None of the
+older functions have been deprecated or altered, but they are now
+de-emphasized in the documentation, and we encourage Lisp programs to
+switch to these new functions.
 
 +++
 *** Use 'keymap-set' instead of 'define-key'.
diff --git a/etc/refcards/orgcard.tex b/etc/refcards/orgcard.tex
index 0ef05353341..f8894d9dc1c 100644
--- a/etc/refcards/orgcard.tex
+++ b/etc/refcards/orgcard.tex
@@ -1,5 +1,5 @@
 % Reference Card for Org Mode
-\def\orgversionnumber{9.6.2}
+\def\orgversionnumber{9.6.3}
 \def\versionyear{2023}          % latest update
 \input emacsver.tex
 
diff --git a/lisp/Makefile.in b/lisp/Makefile.in
index 1e0935f565f..437667e7586 100644
--- a/lisp/Makefile.in
+++ b/lisp/Makefile.in
@@ -543,4 +543,12 @@ $(lisp)/progmodes/cc-styles.elc: 
$(lisp)/progmodes/cc-vars.elc \
 $(lisp)/progmodes/js.elc: $(lisp)/progmodes/cc-defs.elc \
    $(lisp)/progmodes/cc-engine.elc $(lisp)/progmodes/cc-mode.elc
 
+# When org-version.el gets updated with a new version, all the Org
+# files need to be recompiled, or else the build will fail due to
+# version mismatch, prompting the naive users to bootstrap.  So we
+# make all the Org *.elc files dependent of org-version.el, to trigger
+# their recompilation automatically.
+$(lisp)/org/org.elc $(filter-out $(lisp)/org/org-version.elc,$(filter-out 
$(lisp)/org/org.elc,$(wildcard $(lisp)/org/*.elc))): \
+   $(lisp)/org/org-version.el
+
 # Makefile ends here.
diff --git a/lisp/image.el b/lisp/image.el
index 2372fd1ce09..838cc0f8942 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -595,8 +595,8 @@ If nil, use the `image-scaling-factor' variable."
 IMAGE must be an image created with `create-image' or `defimage'.
 IMAGE is displayed by putting an overlay into the current buffer with a
 `before-string' STRING that has a `display' property whose value is the
-image.  STRING is defaulted if you omit it.
-The overlay created will have the `put-image' property set to t.
+image.  STRING defaults to \"x\" if it's nil or omitted.
+The overlay created by this function has the `put-image' property set to t.
 POS may be an integer or marker.
 AREA is where to display the image.  AREA nil or omitted means
 display it in the text area, a value of `left-margin' means
@@ -1158,9 +1158,11 @@ has no effect."
   "r" #'image-rotate)
 
 (defun image-increase-size (&optional n position)
-  "Increase the image size by a factor of N.
-If N is 3, then the image size will be increased by 30%.  The
-default is 20%."
+  "Increase the image size at POSITION by a factor specified by N.
+If N is 3, then the image size will be increased by 30%.  More
+generally, the image size is multiplied by 1 plus N divided by 10.
+N defaults to 2, which increases the image size by 20%.
+POSITION can be a buffer position or a marker, and defaults to point."
   (interactive "P")
   (image--delayed-change-size (if n
                                   (1+ (/ (prefix-numeric-value n) 10.0))
@@ -1179,9 +1181,11 @@ default is 20%."
   (run-with-idle-timer 0.3 nil #'image--change-size size position))
 
 (defun image-decrease-size (&optional n position)
-  "Decrease the image size by a factor of N.
-If N is 3, then the image size will be decreased by 30%.  The
-default is 20%."
+  "Decrease the image size at POSITION by a factor specified by N.
+If N is 3, then the image size will be decreased by 30%.  More
+generally, the image size is multiplied by 1 minus N divided by 10.
+N defaults to 2, which decreases the image size by 20%.
+POSITION can be a buffer position or a marker, and defaults to point."
   (interactive "P")
   (image--delayed-change-size (if n
                                   (- 1 (/ (prefix-numeric-value n) 10.0))
@@ -1191,7 +1195,9 @@ default is 20%."
                      "Use %k for further adjustments"))
 
 (defun image-mouse-increase-size (&optional event)
-  "Increase the image size using the mouse."
+  "Increase the image size using the mouse-gesture EVENT.
+This increases the size of the image at the position specified by
+EVENT, if any, by the default factor used by `image-increase-size'."
   (interactive "e")
   (when (listp event)
     (save-window-excursion
@@ -1199,7 +1205,9 @@ default is 20%."
       (image-increase-size nil (point-marker)))))
 
 (defun image-mouse-decrease-size (&optional event)
-  "Decrease the image size using the mouse."
+  "Decrease the image size using the mouse-gesture EVENT.
+This decreases the size of the image at the position specified by
+EVENT, if any, by the default factor used by `image-decrease-size'."
   (interactive "e")
   (when (listp event)
     (save-window-excursion
@@ -1207,12 +1215,24 @@ default is 20%."
       (image-decrease-size nil (point-marker)))))
 
 (defun image--get-image (&optional position)
-  "Return the image at point."
-  (let ((image (get-char-property (or position (point)) 'display
-                                  (when (markerp position)
-                                    (marker-buffer position)))))
+  "Return the image at POSITION.
+POSITION can be a buffer position or a marker, and defaults to point."
+  (let* ((image (get-char-property (or position (point)) 'display
+                                   (when (markerp position)
+                                     (marker-buffer position))))
+         (image-car (car-safe image))
+         (image
+          (cond ((eq image-car 'image)
+                 image)
+                ;; The value of the display property could be a sliced
+                ;; image of the form ((slice ...) (image ...)).
+                ;; FIXME: can we have more than 2 members in the list,
+                ;; so that the (image ...) part is NOT the cadr?
+                ((and (listp image) (consp image-car))
+                 (cadr image))
+                (t nil))))
     (unless (eq (car-safe image) 'image)
-      (error "No image under point"))
+      (error "No recognizable image under point"))
     image))
 
 ;;;###autoload
diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el
index fec3e637f0c..856c405b545 100644
--- a/lisp/international/emoji.el
+++ b/lisp/international/emoji.el
@@ -684,30 +684,41 @@ We prefer the earliest unique letter."
 
 (defvar-keymap emoji-zoom-map
   "+" #'emoji-zoom-increase
-  "-" #'emoji-zoom-decrease)
+  "-" #'emoji-zoom-decrease
+  "0" #'emoji-zoom-reset)
 
 ;;;###autoload
 (defun emoji-zoom-increase (&optional factor)
   "Increase the size of the character under point.
 FACTOR is the multiplication factor for the size."
   (interactive)
-  (set-transient-map emoji-zoom-map t nil "Zoom with %k")
-  (let* ((factor (or factor 1.1))
-         (old (get-text-property (point) 'face))
-         (height (or (and (consp old)
-                          (plist-get old :height))
-                     1.0))
-         (inhibit-read-only t))
-    (with-silent-modifications
-      (if (consp old)
-          (add-text-properties
-           (point) (1+ (point))
-           (list 'face (plist-put (copy-sequence old) :height (* height 
factor))
-                 'rear-nonsticky t))
-        (add-face-text-property (point) (1+ (point))
-                                (list :height (* height factor)))
-        (put-text-property (point) (1+ (point))
-                           'rear-nonsticky t)))))
+  (set-transient-map emoji-zoom-map t #'redisplay "Zoom with %k")
+  (unless (eobp)
+    (let* ((factor (or factor 1.1))
+           (old (get-text-property (point) 'face))
+           ;; The text property is either a named face, or a plist
+           ;; with :height, or a list starting with such a plist,
+           ;; followed by one or more faces.
+           (newheight (* (or (and (consp old)
+                                  (or (plist-get (car old) :height)
+                                      (plist-get old :height)))
+                             1.0)
+                         factor))
+           (inhibit-read-only t))
+      (with-silent-modifications
+        (if (consp old)
+            (add-text-properties
+             (point) (1+ (point))
+             (list 'face
+                   (if (eq (car old) :height)
+                       (plist-put (copy-sequence old) :height newheight)
+                     (cons (plist-put (car old) :height newheight)
+                           (cdr old)))
+                   'rear-nonsticky t))
+          (add-face-text-property (point) (1+ (point))
+                                  (list :height newheight))
+          (put-text-property (point) (1+ (point))
+                             'rear-nonsticky t))))))
 
 ;;;###autoload
 (defun emoji-zoom-decrease ()
@@ -715,6 +726,19 @@ FACTOR is the multiplication factor for the size."
   (interactive)
   (emoji-zoom-increase 0.9))
 
+;;;###autoload
+(defun emoji-zoom-reset ()
+  "Reset the size of the character under point."
+  (interactive)
+  (with-silent-modifications
+    (let ((old (get-text-property (point) 'face)))
+      (when (and (consp old)
+                 (remove-text-properties (point) (1+ (point)) '(rear-nonsticky 
nil)))
+        (if (eq (car old) :height)
+            (remove-text-properties (point) (1+ (point)) '(face nil))
+          (add-text-properties (point) (1+ (point)) (list 'face
+                                                      (cdr old))))))))
+
 (provide 'emoji)
 
 ;;; emoji.el ends here
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index 4e38b13b1a5..3d6d66970d3 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -3269,7 +3269,8 @@ single characters to be treated as standing for 
themselves."
               "r" #'emoji-recent
               "l" #'emoji-list
               "+" #'emoji-zoom-increase
-              "-" #'emoji-zoom-decrease))
+              "-" #'emoji-zoom-decrease
+              "0" #'emoji-zoom-reset))
 
 (defface confusingly-reordered
   '((((supports :underline (:style wave)))
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 0055914105d..36fff1520ac 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -862,7 +862,18 @@ If a function returns a string, the returned string is 
given to the
 next function in the list, and if the last function returns a string,
 it's displayed in the echo area.
 If a function returns any other non-nil value, no more functions are
-called from the list, and no message will be displayed in the echo area."
+called from the list, and no message will be displayed in the echo area.
+
+Useful functions to add to this list are:
+
+ `inhibit-message'        -- if this function is the first in the list,
+                             messages that match the value of
+                             `inhibit-message-regexps' will be suppressed.
+ `set-multi-message'      -- accumulate multiple messages and display them
+                             together as a single message.
+ `set-minibuffer-message' -- if the minibuffer is active, display the
+                             message at the end of the minibuffer text
+                             (this is the default)."
   :type '(choice (const :tag "No special message handling" nil)
                  (repeat
                   (choice (function-item :tag "Inhibit some messages"
@@ -884,13 +895,18 @@ called from the list, and no message will be displayed in 
the echo area."
   message)
 
 (defcustom inhibit-message-regexps nil
-  "List of regexps that inhibit messages by the function `inhibit-message'."
+  "List of regexps that inhibit messages by the function `inhibit-message'.
+When the list in `set-message-functions' has `inhibit-message' as its
+first element, echo-area messages which match the value of this variable
+will not be displayed."
   :type '(repeat regexp)
   :version "29.1")
 
 (defun inhibit-message (message)
   "Don't display MESSAGE when it matches the regexp `inhibit-message-regexps'.
-This function is intended to be added to `set-message-functions'."
+This function is intended to be added to `set-message-functions'.
+To suppress display of echo-area messages that match `inhibit-message-regexps',
+make this function be the first element of `set-message-functions'."
   (or (and (consp inhibit-message-regexps)
            (string-match-p (mapconcat #'identity inhibit-message-regexps "\\|")
                            message))
@@ -912,6 +928,10 @@ This function is intended to be added to 
`set-message-functions'."
 
 (defun set-multi-message (message)
   "Return recent messages as one string to display in the echo area.
+Individual messages will be separated by a newline.
+Up to `multi-message-max' messages can be accumulated, and the
+accumulated messages are discarded when `multi-message-timeout'
+seconds have elapsed since the first message.
 Note that this feature works best only when `resize-mini-windows'
 is at its default value `grow-only'."
   (let ((last-message (car multi-message-list)))
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index a66332904de..9f5fa435f35 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -1015,7 +1015,7 @@ the like."
                       (list 'base (list (cons 'href base))
                             (eww-highest-readability dom))
                      nil (current-buffer))
-    (dolist (elem '(:source :url :title :next :previous :up))
+    (dolist (elem '(:source :url :title :next :previous :up :peer))
       (plist-put eww-data elem (plist-get old-data elem)))
     (eww--after-page-change)))
 
diff --git a/lisp/org/ob-comint.el b/lisp/org/ob-comint.el
index 54bf5127e16..adfe31c4008 100644
--- a/lisp/org/ob-comint.el
+++ b/lisp/org/ob-comint.el
@@ -81,19 +81,7 @@ or user `keyboard-quit' during execution of body."
        (let* ((string-buffer "")
              (comint-output-filter-functions
               (cons (lambda (text)
-                       (setq string-buffer
-                             (concat
-                              string-buffer
-                              ;; Upon concatenation, the prompt may no
-                              ;; longer match `comint-prompt-regexp'.
-                              ;; In particular, when the regexp has ^
-                              ;; and the output does not contain
-                              ;; trailing newline.  Use more reliable
-                              ;; match to split the output later.
-                              (replace-regexp-in-string
-                               comint-prompt-regexp
-                               ,org-babel-comint-prompt-separator
-                               text))))
+                       (setq string-buffer (concat string-buffer text)))
                     comint-output-filter-functions))
              dangling-text)
         ;; got located, and save dangling text
@@ -108,21 +96,28 @@ or user `keyboard-quit' during execution of body."
         (while (progn
                  (goto-char comint-last-input-end)
                  (not (save-excursion
-                        (and (re-search-forward
-                              (regexp-quote ,eoe-indicator) nil t)
-                             (re-search-forward
-                              comint-prompt-regexp nil t)))))
+                      (and (re-search-forward
+                            (regexp-quote ,eoe-indicator) nil t)
+                           (re-search-forward
+                            comint-prompt-regexp nil t)))))
           (accept-process-output (get-buffer-process (current-buffer))))
         ;; replace cut dangling text
         (goto-char (process-mark (get-buffer-process (current-buffer))))
         (insert dangling-text)
 
-         ;; Replace partially supplied input lines.
-         ;; This is needed when output filter spits partial lines that
-         ;; do not include a full prompt at a time.
+         ;; Filter out prompts.
          (setq string-buffer
                (replace-regexp-in-string
-                comint-prompt-regexp
+                ;; Sometimes, we get multiple agglomerated
+                ;; prompts together in a single output:
+                ;; "prompt prompt prompt output"
+                ;; Remove them progressively, so that
+                ;; possible "^" in the prompt regexp gets to
+                ;; work as we remove the heading prompt
+                ;; instance.
+                (if (string-prefix-p "^" comint-prompt-regexp)
+                    (format "^\\(%s\\)+" (substring comint-prompt-regexp 1))
+                  comint-prompt-regexp)
                 ,org-babel-comint-prompt-separator
                 string-buffer))
         ;; remove echo'd FULL-BODY from input
diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el
index fd75f4785d6..43fdcb82832 100644
--- a/lisp/org/org-version.el
+++ b/lisp/org/org-version.el
@@ -5,13 +5,13 @@
 (defun org-release ()
   "The release version of Org.
 Inserted by installing Org mode or when a release is made."
-   (let ((org-release "9.6.2"))
+   (let ((org-release "9.6.3"))
      org-release))
 ;;;###autoload
 (defun org-git-version ()
   "The Git version of Org mode.
 Inserted by installing Org or when a release is made."
-   (let ((org-git-version "release_9.6.2"))
+   (let ((org-git-version "release_9.6.3-2-gf2949d"))
      org-git-version))
 
 (provide 'org-version)
diff --git a/lisp/org/org.el b/lisp/org/org.el
index 1649722ab0c..be9d0e32dd0 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -9,7 +9,7 @@
 ;; URL: https://orgmode.org
 ;; Package-Requires: ((emacs "26.1"))
 
-;; Version: 9.6.2
+;; Version: 9.6.3
 
 ;; This file is part of GNU Emacs.
 ;;
@@ -3600,13 +3600,13 @@ following symbols:
               (const :tag "Entities" entities))))
 
 (defcustom org-hide-emphasis-markers nil
-  "Non-nil mean font-lock should hide the emphasis marker characters."
+  "Non-nil means font-lock should hide the emphasis marker characters."
   :group 'org-appearance
   :type 'boolean
   :safe #'booleanp)
 
 (defcustom org-hide-macro-markers nil
-  "Non-nil mean font-lock should hide the brackets marking macro calls."
+  "Non-nil means font-lock should hide the brackets marking macro calls."
   :group 'org-appearance
   :type 'boolean)
 
@@ -3618,7 +3618,7 @@ When nil, the \\name form remains in the buffer."
   :type 'boolean)
 
 (defcustom org-pretty-entities-include-sub-superscripts t
-  "Non-nil means, pretty entity display includes formatting sub/superscripts."
+  "Non-nil means pretty entity display includes formatting sub/superscripts."
   :group 'org-appearance
   :version "24.1"
   :type 'boolean)
@@ -10215,7 +10215,7 @@ nil."
        (replace-match "")
         (if (and (string-match "\\S-" (buffer-substring 
(line-beginning-position) (point)))
                 (equal (char-before) ?\ ))
-           (backward-delete-char 1)
+           (delete-char -1)
          (when (string-match "^[ \t]*$" (buffer-substring
                                           (line-beginning-position) 
(line-end-position)))
             (delete-region (line-beginning-position)
@@ -12006,18 +12006,17 @@ Returns the new tags string, or nil to not change the 
current settings."
                    (setq current nil)
                    (when exit-after-next (setq exit-after-next 'now)))
                   ((= c ?\t)
-                    (condition-case nil
-                        (unless tab-tags
-                          (setq tab-tags
-                                (delq nil
-                                      (mapcar (lambda (x)
-                                                (let ((item (car-safe x)))
-                                                  (and (stringp item)
-                                                       (list item))))
-                                              (org--tag-add-to-alist
-                                               (with-current-buffer buf
-                                                 (org-get-buffer-tags))
-                                               table))))))
+                    (unless tab-tags
+                      (setq tab-tags
+                            (delq nil
+                                  (mapcar (lambda (x)
+                                            (let ((item (car-safe x)))
+                                              (and (stringp item)
+                                                   (list item))))
+                                          (org--tag-add-to-alist
+                                           (with-current-buffer buf
+                                             (org-get-buffer-tags))
+                                           table)))))
                     (setq tg (completing-read "Tag: " tab-tags))
                    (when (string-match "\\S-" tg)
                      (cl-pushnew (list tg) tab-tags :test #'equal)
@@ -16532,7 +16531,7 @@ because, in this case the deletion might narrow the 
column."
             (looking-at-p ".*?|")
             (org-at-table-p))
        (progn (forward-char -1) (org-delete-char 1))
-      (backward-delete-char N)
+      (funcall-interactively #'backward-delete-char N)
       (org-fix-tags-on-the-fly))))
 
 (defun org-delete-char (N)
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index d773b4a41f4..385e3918842 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -1027,7 +1027,11 @@ To use tree-sitter C/C++ modes by default, evaluate
     (add-to-list \\='major-mode-remap-alist
                  \\='(c-or-c++-mode . c-or-c++-ts-mode))
 
-in your configuration."
+in your configuration.
+
+Since this mode uses a parser, unbalanced brackets might cause
+some breakage in indentation/fontification.  Therefore, it's
+recommended to enable `electric-pair-mode' with this mode."
   :group 'c++
   :after-hook (c-ts-mode-set-modeline)
 
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index fe9e62ee569..4045576630c 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -9120,7 +9120,7 @@ multi-line strings (but not C++, for example)."
     (c-forward-syntactic-ws))
 
   (let ((start (point)) pos res name-res id-start id-end id-range
-       post-prefix-pos)
+       post-prefix-pos prefix-end-pos)
 
     ;; Skip leading type modifiers.  If any are found we know it's a
     ;; prefix of a type.
@@ -9130,6 +9130,7 @@ multi-line strings (but not C++, for example)."
          (when (looking-at c-no-type-key)
            (setq res 'no-id)))
        (goto-char (match-end 1))
+       (setq prefix-end-pos (point))
        (setq pos (point))
        (c-forward-syntactic-ws)
        (or (eq res 'no-id)
@@ -9281,7 +9282,10 @@ multi-line strings (but not C++, for example)."
                  (not (looking-at c-type-decl-prefix-key)))))
       ;; A C specifier followed by an implicit int, e.g.
       ;; "register count;"
-      (goto-char id-start)
+      (goto-char prefix-end-pos)
+      (setq pos (point))
+      (unless stop-at-end
+       (c-forward-syntactic-ws))
       (setq res 'no-id))
 
      (name-res
@@ -9289,6 +9293,7 @@ multi-line strings (but not C++, for example)."
             ;; A normal identifier.
             (goto-char id-end)
             (setq pos (point))
+            (c-forward-syntactic-ws)
             (if (or res c-promote-possible-types)
                 (progn
                   (when (not (eq c-promote-possible-types 'just-one))
@@ -9296,7 +9301,9 @@ multi-line strings (but not C++, for example)."
                   (when (and c-record-type-identifiers id-range)
                     (c-record-type-id id-range))
                   (unless res
-                    (setq res 'found)))
+                    (setq res 'found))
+                  (when (eq res 'prefix)
+                    (setq res t)))
               (setq res (if (c-check-qualified-type id-start)
                             ;; It's an identifier that has been used as
                             ;; a type somewhere else.
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 10b6c0cc2ca..f3b806e5613 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -1626,6 +1626,7 @@ If optional MARKER, return a marker instead"
                (directory-file-name (file-local-name truepath))
                eglot--uri-path-allowed-chars)))))
 
+(declare-function w32-long-file-name "w32proc.c" (fn))
 (defun eglot--uri-to-path (uri)
   "Convert URI to file path, helped by `eglot--current-server'."
   (when (keywordp uri) (setq uri (substring (symbol-name uri) 1)))
@@ -3488,8 +3489,9 @@ at point.  With prefix argument, prompt for ACTION-KIND."
       (unwind-protect
           (progn
             (dolist (dir dirs-to-watch)
-              (push (file-notify-add-watch dir '(change) #'handle-event)
-                    (gethash id (eglot--file-watches server))))
+              (when (file-readable-p dir)
+                (push (file-notify-add-watch dir '(change) #'handle-event)
+                      (gethash id (eglot--file-watches server)))))
             (setq
              success
              `(:message ,(format "OK, watching %s directories in %s watchers"
diff --git a/lisp/progmodes/elixir-ts-mode.el b/lisp/progmodes/elixir-ts-mode.el
index 6d7420b63dc..c58854c41c3 100644
--- a/lisp/progmodes/elixir-ts-mode.el
+++ b/lisp/progmodes/elixir-ts-mode.el
@@ -55,7 +55,9 @@
 (declare-function treesit-parser-list "treesit.c")
 (declare-function treesit-node-parent "treesit.c")
 (declare-function treesit-node-start "treesit.c")
+(declare-function treesit-node-end "treesit.c")
 (declare-function treesit-query-compile "treesit.c")
+(declare-function treesit-query-capture "treesit.c")
 (declare-function treesit-node-eq "treesit.c")
 (declare-function treesit-node-prev-sibling "treesit.c")
 
@@ -550,13 +552,43 @@ Return nil if NODE is not a defun node or doesn't have a 
name."
                 (_ nil))))
     (_ nil)))
 
+(defvar elixir-ts--syntax-propertize-query
+  (when (treesit-available-p)
+    (treesit-query-compile
+     'elixir
+     '(((["\"\"\""] @quoted-text))))))
+
+(defun elixir-ts--syntax-propertize (start end)
+  "Apply syntax text properties between START and END for `elixir-ts-mode'."
+  (let ((captures
+         (treesit-query-capture 'elixir elixir-ts--syntax-propertize-query 
start end)))
+    (pcase-dolist (`(,name . ,node) captures)
+      (pcase-exhaustive name
+        ('quoted-text
+         (put-text-property (1- (treesit-node-end node)) (treesit-node-end 
node)
+                            'syntax-table (string-to-syntax "$")))))))
+
+(defun elixir-ts--electric-pair-string-delimiter ()
+  "Insert corresponding multi-line string for `electric-pair-mode'."
+  (when (and electric-pair-mode
+             (eq last-command-event ?\")
+             (let ((count 0))
+               (while (eq (char-before (- (point) count)) last-command-event)
+                 (cl-incf count))
+               (= count 3))
+             (eq (char-after) last-command-event))
+    (save-excursion
+      (insert (make-string 2 last-command-event)))
+    (save-excursion
+      (newline 1 t))))
+
 ;;;###autoload
 (define-derived-mode elixir-ts-mode prog-mode "Elixir"
   "Major mode for editing Elixir, powered by tree-sitter."
   :group 'elixir-ts
   :syntax-table elixir-ts--syntax-table
 
-  ;; Comments
+  ;; Comments.
   (setq-local comment-start "# ")
   (setq-local comment-start-skip
               (rx "#" (* (syntax whitespace))))
@@ -566,9 +598,13 @@ Return nil if NODE is not a defun node or doesn't have a 
name."
               (rx (* (syntax whitespace))
                   (group (or (syntax comment-end) "\n"))))
 
-  ;; Compile
+  ;; Compile.
   (setq-local compile-command "mix")
 
+  ;; Electric pair.
+  (add-hook 'post-self-insert-hook
+            #'elixir-ts--electric-pair-string-delimiter 'append t)
+
   (when (treesit-ready-p 'elixir)
     ;; The HEEx parser has to be created first for elixir to ensure elixir
     ;; is the first language when looking for treesit ranges.
@@ -599,14 +635,14 @@ Return nil if NODE is not a defun node or doesn't have a 
name."
     ;; Indent.
     (setq-local treesit-simple-indent-rules elixir-ts--indent-rules)
 
-    ;; Navigation
+    ;; Navigation.
     (setq-local forward-sexp-function #'elixir-ts--forward-sexp)
     (setq-local treesit-defun-type-regexp
                 '("call" . elixir-ts--defun-p))
 
     (setq-local treesit-defun-name-function #'elixir-ts--defun-name)
 
-    ;; Embedded Heex
+    ;; Embedded Heex.
     (when (treesit-ready-p 'heex)
       (setq-local treesit-range-settings elixir-ts--treesit-range-rules)
 
@@ -630,7 +666,8 @@ Return nil if NODE is not a defun node or doesn't have a 
name."
                     ( elixir-sigil elixir-string-escape
                       elixir-string-interpolation ))))
 
-    (treesit-major-mode-setup)))
+    (treesit-major-mode-setup)
+    (setq-local syntax-propertize-function #'elixir-ts--syntax-propertize)))
 
 (if (treesit-ready-p 'elixir)
     (progn
diff --git a/lisp/progmodes/typescript-ts-mode.el 
b/lisp/progmodes/typescript-ts-mode.el
index ef87bb29d52..3f198e9f180 100644
--- a/lisp/progmodes/typescript-ts-mode.el
+++ b/lisp/progmodes/typescript-ts-mode.el
@@ -453,7 +453,10 @@ See `treesit-sexp-type-regexp' for more information.")
 This major mode defines two additional JSX-specific faces:
 `typescript-ts-jsx-attribute-face' and
 `typescript-ts-jsx-attribute-face' that are used for HTML tags
-and attributes, respectively."
+and attributes, respectively.
+
+The JSX-specific faces are used when `treesit-font-lock-level' is
+at least 3 (which is the default value)."
   :group 'typescript
   :syntax-table typescript-ts-mode--syntax-table
 
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index c5ab5013fc8..45fd17f65c4 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -286,7 +286,7 @@ Overrides local variable `indent-tabs-mode'."
     ;;    counter_rtl.vhd(29):Conditional signal assignment line__29
     ("ModelSim" "vcom" "-93 -work \\1" "make" "-f \\1"
      nil "vlib \\1; vmap \\2 \\1" "./" "work/" "Makefile" "modelsim"
-     ("\\(ERROR:\\|WARNING\\[[0-9]+\\]:\\|\\*\\* Error:\\|\\*\\* Warning: 
\\[[0-9]+\\]\\| +\\) \\([^ ]+\\)(\\([0-9]+\\)):" 2 3 nil)
+     ("^\\(ERROR\\|WARNING\\|\\*\\* Error\\|\\*\\* Warning\\)[^:]*:\\( 
*\\[[0-9]+]\\| ([^)]+)\\)? \\([^ \t\n]+\\)(\\([0-9]+\\)):" 3 4 nil)
      ("" 0)
      ("\\1/_primary.dat" "\\2/\\1.dat" "\\1/_primary.dat"
       "\\1/_primary.dat" "\\1/body.dat" downcase))
diff --git a/lisp/saveplace.el b/lisp/saveplace.el
index 7512fc87c5d..18d296ba2d9 100644
--- a/lisp/saveplace.el
+++ b/lisp/saveplace.el
@@ -35,6 +35,8 @@
 
 ;;; Code:
 
+(require 'cl-lib)
+
 ;; this is what I was using during testing:
 ;; (define-key ctl-x-map "p" 'toggle-save-place-globally)
 
@@ -87,11 +89,77 @@ this happens automatically before saving `save-place-alist' 
to
 `save-place-file'."
   :type 'boolean)
 
+(defun save-place-load-alist-from-file ()
+  (if (not save-place-loaded)
+      (progn
+        (setq save-place-loaded t)
+        (let ((file (expand-file-name save-place-file)))
+          ;; make sure that the alist does not get overwritten, and then
+          ;; load it if it exists:
+          (if (file-readable-p file)
+              ;; don't want to use find-file because we have been
+              ;; adding hooks to it.
+              (with-current-buffer (get-buffer-create " *Saved Places*")
+                (delete-region (point-min) (point-max))
+                ;; Make sure our 'coding:' cookie in the save-place
+                ;; file will take effect, in case the caller binds
+                ;; coding-system-for-read.
+                (let (coding-system-for-read)
+                  (insert-file-contents file))
+                (goto-char (point-min))
+                (setq save-place-alist
+                      (with-demoted-errors "Error reading save-place-file: %S"
+                        (car (read-from-string
+                              (buffer-substring (point-min) (point-max))))))
+
+                ;; If there is a limit, and we're over it, then we'll
+                ;; have to truncate the end of the list:
+                (if save-place-limit
+                    (if (<= save-place-limit 0)
+                        ;; Zero gets special cased.  I'm not thrilled
+                        ;; with this, but the loop for >= 1 is tight.
+                        (setq save-place-alist nil)
+                      ;; Else the limit is >= 1, so enforce it by
+                      ;; counting and then `setcdr'ing.
+                      (let ((s save-place-alist)
+                            (count 1))
+                        (while s
+                          (if (>= count save-place-limit)
+                              (setcdr s nil)
+                            (setq count (1+ count)))
+                          (setq s (cdr s))))))
+
+                (kill-buffer (current-buffer))))
+          nil))))
+
 (defcustom save-place-abbreviate-file-names nil
   "If non-nil, abbreviate file names before saving them.
 This can simplify sharing the `save-place-file' file across
-different hosts."
+different hosts.
+
+Changing this option requires rewriting `save-place-alist' with
+corresponding file name format, therefore setting this option
+just using `setq' may cause out-of-sync problems.  You should use
+either `setopt' or M-x customize-variable to set this option."
   :type 'boolean
+  :set (lambda (sym val)
+         (set-default sym val)
+         (or save-place-loaded (save-place-load-alist-from-file))
+         (let ((fun (if val #'abbreviate-file-name #'expand-file-name)))
+           (setq save-place-alist
+                 (cl-delete-duplicates
+                  (cl-loop for (k . v) in save-place-alist
+                           collect
+                           (cons (funcall fun k)
+                                 (if (listp v)
+                                     (cl-loop for (k1 . v1) in v
+                                              collect
+                                              (cons k1 (funcall fun v1)))
+                                   v)))
+                  :key #'car
+                  :from-end t
+                  :test #'equal)))
+         val)
   :version "28.1")
 
 (defcustom save-place-save-skipped t
@@ -214,7 +282,11 @@ file names."
                            ((and (derived-mode-p 'dired-mode) directory)
                             (let ((filename (dired-get-filename nil t)))
                               (if filename
-                                  `((dired-filename . ,filename))
+                                   (list
+                                    (cons 'dired-filename
+                                          (if save-place-abbreviate-file-names
+                                              (abbreviate-file-name filename)
+                                            filename)))
                                 (point))))
                            (t (point)))))
         (if cell
@@ -278,49 +350,6 @@ may have changed) back to `save-place-alist'."
          (file-error (message "Saving places: can't write %s" file)))
         (kill-buffer (current-buffer))))))
 
-(defun save-place-load-alist-from-file ()
-  (if (not save-place-loaded)
-      (progn
-        (setq save-place-loaded t)
-        (let ((file (expand-file-name save-place-file)))
-          ;; make sure that the alist does not get overwritten, and then
-          ;; load it if it exists:
-          (if (file-readable-p file)
-              ;; don't want to use find-file because we have been
-              ;; adding hooks to it.
-              (with-current-buffer (get-buffer-create " *Saved Places*")
-                (delete-region (point-min) (point-max))
-                ;; Make sure our 'coding:' cookie in the save-place
-                ;; file will take effect, in case the caller binds
-                ;; coding-system-for-read.
-                (let (coding-system-for-read)
-                  (insert-file-contents file))
-                (goto-char (point-min))
-                (setq save-place-alist
-                      (with-demoted-errors "Error reading save-place-file: %S"
-                        (car (read-from-string
-                              (buffer-substring (point-min) (point-max))))))
-
-                ;; If there is a limit, and we're over it, then we'll
-                ;; have to truncate the end of the list:
-                (if save-place-limit
-                    (if (<= save-place-limit 0)
-                        ;; Zero gets special cased.  I'm not thrilled
-                        ;; with this, but the loop for >= 1 is tight.
-                        (setq save-place-alist nil)
-                      ;; Else the limit is >= 1, so enforce it by
-                      ;; counting and then `setcdr'ing.
-                      (let ((s save-place-alist)
-                            (count 1))
-                        (while s
-                          (if (>= count save-place-limit)
-                              (setcdr s nil)
-                            (setq count (1+ count)))
-                          (setq s (cdr s))))))
-
-                (kill-buffer (current-buffer))))
-          nil))))
-
 (defun save-places-to-alist ()
   ;; go through buffer-list, saving places to alist if save-place-mode
   ;; is non-nil, deleting them from alist if it is nil.
@@ -353,7 +382,11 @@ may have changed) back to `save-place-alist'."
   "Function added to `find-file-hook' by `save-place-mode'.
 It runs the hook `save-place-after-find-file-hook'."
   (or save-place-loaded (save-place-load-alist-from-file))
-  (let ((cell (assoc buffer-file-name save-place-alist)))
+  (let ((cell (and (stringp buffer-file-name)
+                   (assoc (if save-place-abbreviate-file-names
+                              (abbreviate-file-name buffer-file-name)
+                            buffer-file-name)
+                          save-place-alist))))
     (if cell
        (progn
          (or revert-buffer-in-progress-p
@@ -368,25 +401,25 @@ It runs the hook `save-place-after-find-file-hook'."
 (defun save-place-dired-hook ()
   "Position the point in a Dired buffer."
   (or save-place-loaded (save-place-load-alist-from-file))
-  (let* ((directory (and (derived-mode-p 'dired-mode)
-                         (boundp 'dired-subdir-alist)
-                        dired-subdir-alist
-                        (dired-current-directory)))
-        (cell (assoc (and directory
-                          (expand-file-name (if (consp directory)
-                                                (car directory)
-                                              directory)))
-                     save-place-alist)))
-    (if cell
-        (progn
-          (or revert-buffer-in-progress-p
-              (cond
-              ((integerp (cdr cell))
-               (goto-char (cdr cell)))
-              ((and (listp (cdr cell)) (assq 'dired-filename (cdr cell)))
-               (dired-goto-file (cdr (assq 'dired-filename (cdr cell)))))))
-          ;; and make sure it will be saved again for later
-          (setq save-place-mode t)))))
+  (when-let ((directory (and (derived-mode-p 'dired-mode)
+                             (boundp 'dired-subdir-alist)
+                            dired-subdir-alist
+                            (dired-current-directory)))
+             (item (expand-file-name (if (consp directory)
+                                        (car directory)
+                                      directory)))
+            (cell (assoc (if save-place-abbreviate-file-names
+                              (abbreviate-file-name item) item)
+                         save-place-alist)))
+    (or revert-buffer-in-progress-p
+        (cond
+        ((integerp (cdr cell))
+         (goto-char (cdr cell)))
+        ((listp (cdr cell))
+          (when-let ((elt (assq 'dired-filename (cdr cell))))
+            (dired-goto-file (expand-file-name (cdr elt)))))))
+    ;; and make sure it will be saved again for later
+    (setq save-place-mode t)))
 
 (defun save-place-kill-emacs-hook ()
   ;; First update the alist.  This loads the old save-place-file if nec.
diff --git a/lisp/subr.el b/lisp/subr.el
index 3761ee6764b..46faff1cd18 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -45,7 +45,8 @@ declaration.  A FILE with an \"ext:\" prefix is an external 
file.
 `check-declare' will check such files if they are found, and skip
 them without error if they are not.
 
-Optional ARGLIST specifies FN's arguments, or is t to not specify
+Optional ARGLIST specifies FN's arguments, in the same form as
+in `defun' (including the parentheses); or it is t to not specify
 FN's arguments.  An omitted ARGLIST defaults to t, not nil: a nil
 ARGLIST specifies an empty argument list, and an explicit t
 ARGLIST is a placeholder that allows supplying a later arg.
@@ -3596,9 +3597,9 @@ confusing to some users.")
 (defvar from--tty-menu-p nil
   "Non-nil means the current command was invoked from a TTY menu.")
 (defun use-dialog-box-p ()
-  "Say whether the current command should prompt the user via a dialog box."
+  "Return non-nil if the current command should prompt the user via a dialog 
box."
   (and last-input-event                 ; not during startup
-       (or (listp last-nonmenu-event)   ; invoked by a mouse event
+       (or (consp last-nonmenu-event)   ; invoked by a mouse event
            from--tty-menu-p)            ; invoked via TTY menu
        use-dialog-box))
 
diff --git a/src/xterm.c b/src/xterm.c
index 5e6378db30d..621ee5b0ef2 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -30815,7 +30815,7 @@ x_term_init (Lisp_Object display_name, char 
*xrm_option, char *resource_name)
 
   dpyinfo->invisible_cursor = make_invisible_cursor (dpyinfo);
 #if defined HAVE_XFIXES && XFIXES_VERSION >= 40000
-  dpyinfo->fixes_pointer_blanking = egetenv ("EMACS_XFIXES");
+  dpyinfo->fixes_pointer_blanking = (egetenv ("EMACS_XFIXES") != NULL);
 #endif
 
 #ifdef HAVE_X_I18N
diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba
index d7b0b0d3ded..722a449b636 100644
--- a/test/infra/Dockerfile.emba
+++ b/test/infra/Dockerfile.emba
@@ -60,17 +60,22 @@ RUN ./autogen.sh autoconf
 RUN ./configure --with-file-notification=gfile
 RUN make bootstrap
 
-FROM emacs-base as emacs-eglot
+# Debian bullseye doesn't provide proper packages.  So we use Debian
+# sid for this.
+FROM debian:sid as emacs-eglot
 
+# This corresponds to emacs-base.
 RUN apt-get update && \
     apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
-      wget lsb-release software-properties-common gpg \
+      libc-dev gcc g++ make autoconf automake libncurses-dev gnutls-dev \
+      libdbus-1-dev libacl1-dev acl git texinfo gdb \
     && rm -rf /var/lib/apt/lists/*
 
-# A recent clangd.  It must be at least clangd 14, which is in Debian
-# bookworm.
-RUN bash -c "$(wget --no-check-certificate -O - https://apt.llvm.org/llvm.sh)"
-RUN ln -s /usr/bin/clangd-15 /usr/bin/clangd
+# Some language servers.
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
+      clangd python3-pylsp python3-autopep8 python3-yapf \
+    && rm -rf /var/lib/apt/lists/*
 
 COPY . /checkout
 WORKDIR /checkout
@@ -82,14 +87,14 @@ FROM emacs-base as emacs-gnustep
 
 RUN apt-get update && \
     apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \
-      gnustep-devel \
+      gnustep-devel zlib1g-dev \
     && rm -rf /var/lib/apt/lists/*
 
 COPY . /checkout
 WORKDIR /checkout
 RUN ./autogen.sh autoconf
 RUN ./configure --with-ns
-RUN make V=1 bootstrap
+RUN make bootstrap
 
 FROM emacs-base as emacs-native-comp
 



reply via email to

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