aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-05-27 09:49:49 +0800
committerPo Lu2023-05-27 09:49:49 +0800
commitcdca0fddcc3352bcd01bec147c264be1b2a04e12 (patch)
tree3b15e37936fecc34314883a41a355873c2b9133c
parent0eb1f4e57125117006f109a5549082008fc9fbb1 (diff)
parente77e986a9b7d735c0e39198c8b80a34a29005fc5 (diff)
downloademacs-cdca0fddcc3352bcd01bec147c264be1b2a04e12.tar.gz
emacs-cdca0fddcc3352bcd01bec147c264be1b2a04e12.zip
Merge remote-tracking branch 'origin/master' into feature/android
-rw-r--r--INSTALL6
-rw-r--r--configure.ac17
-rw-r--r--doc/emacs/display.texi5
-rw-r--r--doc/emacs/maintaining.texi19
-rw-r--r--doc/emacs/search.texi37
-rw-r--r--doc/lispref/minibuf.texi30
-rw-r--r--doc/lispref/modes.texi10
-rw-r--r--doc/lispref/parsing.texi6
-rw-r--r--doc/misc/gnus.texi25
-rw-r--r--etc/NEWS45
-rw-r--r--etc/NEWS.2980
-rw-r--r--etc/PROBLEMS7
-rw-r--r--lisp/comint.el35
-rw-r--r--lisp/emacs-lisp/benchmark.el2
-rw-r--r--lisp/emacs-lisp/package.el10
-rw-r--r--lisp/emacs-lisp/regexp-opt.el2
-rw-r--r--lisp/emacs-lisp/rx.el1
-rw-r--r--lisp/emacs-lisp/subr-x.el9
-rw-r--r--lisp/env.el3
-rw-r--r--lisp/international/mule.el16
-rw-r--r--lisp/menu-bar.el5
-rw-r--r--lisp/net/dictionary.el203
-rw-r--r--lisp/net/shr.el3
-rw-r--r--lisp/net/tramp.el12
-rw-r--r--lisp/pcmpl-linux.el3
-rw-r--r--lisp/pixel-scroll.el7
-rw-r--r--lisp/progmodes/c-ts-mode.el20
-rw-r--r--lisp/progmodes/cc-engine.el30
-rw-r--r--lisp/progmodes/project.el33
-rw-r--r--lisp/progmodes/python.el47
-rw-r--r--lisp/server.el20
-rw-r--r--lisp/subr.el29
-rw-r--r--lisp/tab-bar.el15
-rw-r--r--lisp/vc/vc-annotate.el2
-rw-r--r--lisp/vc/vc-hooks.el9
-rw-r--r--lisp/vc/vc.el48
-rw-r--r--lisp/wdired.el3
-rw-r--r--lisp/window.el2
-rw-r--r--src/fns.c16
-rw-r--r--src/lread.c17
-rw-r--r--src/pgtkterm.c7
-rw-r--r--src/sqlite.c82
-rw-r--r--src/xdisp.c4
-rw-r--r--test/lisp/emacs-lisp/package-tests.el11
-rw-r--r--test/lisp/progmodes/python-tests.el16
-rw-r--r--test/src/lread-tests.el16
-rw-r--r--test/src/sqlite-tests.el23
-rw-r--r--test/src/treesit-tests.el2
48 files changed, 808 insertions, 242 deletions
diff --git a/INSTALL b/INSTALL
index a69e1f2aec7..605be366e92 100644
--- a/INSTALL
+++ b/INSTALL
@@ -394,6 +394,12 @@ typical 32-bit host, Emacs integers have 62 bits instead of 30.
394 394
395Use --with-cairo to compile Emacs with Cairo drawing. 395Use --with-cairo to compile Emacs with Cairo drawing.
396 396
397Use --with-cairo-xcb to also utilize the Cairo XCB backend on systems
398where it is available. While such a configuration is moderately
399faster when running over X connections with high latency, it is likely
400to crash when a new frame is created on a display connection opened
401after a display connection is closed.
402
397Use --with-modules to build Emacs with support for dynamic modules. 403Use --with-modules to build Emacs with support for dynamic modules.
398This needs a C compiler that supports '__attribute__ ((cleanup (...)))', 404This needs a C compiler that supports '__attribute__ ((cleanup (...)))',
399as in GCC 3.4 and later. 405as in GCC 3.4 and later.
diff --git a/configure.ac b/configure.ac
index 2a2d31bb72d..529639bfa17 100644
--- a/configure.ac
+++ b/configure.ac
@@ -551,6 +551,7 @@ OPTION_DEFAULT_ON([sqlite3],[don't compile with sqlite3 support])
551OPTION_DEFAULT_ON([lcms2],[don't compile with Little CMS support]) 551OPTION_DEFAULT_ON([lcms2],[don't compile with Little CMS support])
552OPTION_DEFAULT_ON([libsystemd],[don't compile with libsystemd support]) 552OPTION_DEFAULT_ON([libsystemd],[don't compile with libsystemd support])
553OPTION_DEFAULT_ON([cairo],[don't compile with Cairo drawing]) 553OPTION_DEFAULT_ON([cairo],[don't compile with Cairo drawing])
554OPTION_DEFAULT_OFF([cairo-xcb], [use XCB surfaces for Cairo support])
554OPTION_DEFAULT_ON([xml2],[don't compile with XML parsing support]) 555OPTION_DEFAULT_ON([xml2],[don't compile with XML parsing support])
555OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support]) 556OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support])
556OPTION_DEFAULT_ON([native-image-api], [don't use native image APIs (GDI+ on Windows)]) 557OPTION_DEFAULT_ON([native-image-api], [don't use native image APIs (GDI+ on Windows)])
@@ -4355,14 +4356,14 @@ if test "${HAVE_X11}" = "yes"; then
4355 CAIRO_MODULE="cairo >= $CAIRO_REQUIRED" 4356 CAIRO_MODULE="cairo >= $CAIRO_REQUIRED"
4356 EMACS_CHECK_MODULES([CAIRO], [$CAIRO_MODULE]) 4357 EMACS_CHECK_MODULES([CAIRO], [$CAIRO_MODULE])
4357 if test $HAVE_CAIRO = yes; then 4358 if test $HAVE_CAIRO = yes; then
4358 CAIRO_XCB_MODULE="cairo-xcb >= $CAIRO_REQUIRED" 4359 AS_IF([test "x$with_cairo_xcb" = "xyes"], [
4359 EMACS_CHECK_MODULES([CAIRO_XCB], [$CAIRO_XCB_MODULE]) 4360 CAIRO_XCB_MODULE="cairo-xcb >= $CAIRO_REQUIRED"
4360 if test $HAVE_CAIRO_XCB = yes; then 4361 EMACS_CHECK_MODULES([CAIRO_XCB], [$CAIRO_XCB_MODULE])
4361 CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XCB_CFLAGS" 4362 AS_IF([test "x$HAVE_CAIRO_XCB" = "xyes"], [
4362 CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XCB_LIBS" 4363 CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XCB_CFLAGS"
4363 AC_DEFINE([USE_CAIRO_XCB], [1], 4364 CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XCB_LIBS"
4364 [Define to 1 if cairo XCB surfaces are available.]) 4365 AC_DEFINE([USE_CAIRO_XCB], [1],
4365 fi 4366 [Define to 1 if cairo XCB surfaces are available.])])])
4366 AC_DEFINE([USE_CAIRO], [1], [Define to 1 if using cairo.]) 4367 AC_DEFINE([USE_CAIRO], [1], [Define to 1 if using cairo.])
4367 CFLAGS="$CFLAGS $CAIRO_CFLAGS" 4368 CFLAGS="$CFLAGS $CAIRO_CFLAGS"
4368 LIBS="$LIBS $CAIRO_LIBS" 4369 LIBS="$LIBS $CAIRO_LIBS"
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 6b2eb014c82..fa8ca4cbf17 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -127,7 +127,10 @@ command leaves point in the window. This variable affects all the
127scroll commands documented in this section, as well as scrolling with 127scroll commands documented in this section, as well as scrolling with
128the mouse wheel (@pxref{Mouse Commands}); in general, it affects any 128the mouse wheel (@pxref{Mouse Commands}); in general, it affects any
129command that has a non-@code{nil} @code{scroll-command} property. 129command that has a non-@code{nil} @code{scroll-command} property.
130@xref{Property Lists,,, elisp, The Emacs Lisp Reference Manual}. 130@xref{Property Lists,,, elisp, The Emacs Lisp Reference Manual}. The
131same property also causes Emacs not to exit incremental search when
132one of these commands is invoked and @code{isearch-allow-scroll} is
133non-@code{nil} (@pxref{Not Exiting Isearch}).
131 134
132@vindex fast-but-imprecise-scrolling 135@vindex fast-but-imprecise-scrolling
133 Sometimes, particularly when you hold down keys such as @kbd{C-v} 136 Sometimes, particularly when you hold down keys such as @kbd{C-v}
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 7d49e28d11f..246e335cfe7 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -999,6 +999,10 @@ Display the change history for the current fileset
999Display the change history for the current repository 999Display the change history for the current repository
1000(@code{vc-print-root-log}). 1000(@code{vc-print-root-log}).
1001 1001
1002@item C-x v b l
1003Display the change history for another branch
1004(@code{vc-print-branch-log}).
1005
1002@item C-x v I 1006@item C-x v I
1003Display the changes that a ``pull'' operation will retrieve 1007Display the changes that a ``pull'' operation will retrieve
1004(@code{vc-log-incoming}). 1008(@code{vc-log-incoming}).
@@ -1063,6 +1067,14 @@ showing only the first line of each log entry. However, you can type
1063@file{*vc-change-log*} buffer to reveal the entire log entry for the 1067@file{*vc-change-log*} buffer to reveal the entire log entry for the
1064revision at point. A second @key{RET} hides it again. 1068revision at point. A second @key{RET} hides it again.
1065 1069
1070@kindex C-x v b l
1071@findex vc-print-branch-log
1072 @kbd{C-x v b l @var{branch-name} @key{RET}} (@code{vc-print-branch-log})
1073displays a @file{*vc-change-log*} buffer showing the history of the
1074version-controlled directory tree, like @code{vc-print-root-log} does,
1075but it shows the history of a branch other than the current one; it
1076prompts for the branch whose history to display.
1077
1066@kindex C-x v I 1078@kindex C-x v I
1067@kindex C-x v O 1079@kindex C-x v O
1068@findex vc-log-incoming 1080@findex vc-log-incoming
@@ -1523,6 +1535,8 @@ switch to another branch using the @kbd{svn switch} command. With
1523Mercurial, command @kbd{hg update} is used to switch to another 1535Mercurial, command @kbd{hg update} is used to switch to another
1524branch. 1536branch.
1525 1537
1538@kindex C-x v b s
1539@findex vc-switch-branch
1526 The VC command to switch to another branch in the current directory 1540 The VC command to switch to another branch in the current directory
1527is @kbd{C-x v b s @var{branch-name} @key{RET}} (@code{vc-switch-branch}). 1541is @kbd{C-x v b s @var{branch-name} @key{RET}} (@code{vc-switch-branch}).
1528 1542
@@ -1673,9 +1687,12 @@ branch ID for a branch starting at the current revision. For example,
1673if the current revision is 2.5, the branch ID should be 2.5.1, 2.5.2, 1687if the current revision is 2.5, the branch ID should be 2.5.1, 2.5.2,
1674and so on, depending on the number of existing branches at that point. 1688and so on, depending on the number of existing branches at that point.
1675 1689
1690@kindex C-x v b c
1691@findex vc-create-branch
1676 This procedure will not work for distributed version control systems 1692 This procedure will not work for distributed version control systems
1677like git or Mercurial. For those systems you should use the command 1693like git or Mercurial. For those systems you should use the command
1678@code{vc-create-branch} (@kbd{C-x v b c}) instead. 1694@code{vc-create-branch} (@w{@kbd{C-x v b c @var{branch-name} @key{RET}}})
1695instead.
1679 1696
1680 To create a new branch at an older revision (one that is no longer 1697 To create a new branch at an older revision (one that is no longer
1681the head of a branch), first select that revision (@pxref{Switching 1698the head of a branch), first select that revision (@pxref{Switching
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index fb79fe8f3fc..45378d95f65 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -587,26 +587,30 @@ i.e., they don't terminate the search, even if
587@item Scrolling Commands 587@item Scrolling Commands
588@cindex scrolling commands, during incremental search 588@cindex scrolling commands, during incremental search
589@vindex isearch-allow-scroll 589@vindex isearch-allow-scroll
590 Normally, scrolling commands exit incremental search. If you change 590@cindex @code{scroll-command} property, and incremental search
591the variable @code{isearch-allow-scroll} to a non-@code{nil} value, 591 Normally, scrolling commands exit incremental search. But if you
592that enables the use of the scroll-bar, as well as keyboard scrolling 592change the variable @code{isearch-allow-scroll} to a non-@code{nil}
593commands like @kbd{C-v}, @kbd{M-v}, and @kbd{C-l} (@pxref{Scrolling}). 593value, that enables the use of the scroll-bar, as well as keyboard
594This applies only to calling these commands via their bound key 594scrolling commands like @kbd{C-v}, @kbd{M-v}, and @kbd{C-l}
595sequences---typing @kbd{M-x} will still exit the search. You can give 595(@pxref{Scrolling}), which have a non-@code{nil} @code{scroll-command}
596prefix arguments to these commands in the usual way. This feature 596property, without exiting the search. This applies only to calling
597normally won't let you scroll the current match out of visibility; but 597these commands via their bound key sequences---typing @kbd{M-x} will
598if you customize @code{isearch-allow-scroll} to the special value 598still exit the search. You can give prefix arguments to these
599@code{unlimited}, that restriction is lifted. 599commands in the usual way. This feature normally won't let you scroll
600 600the current match out of visibility; but if you customize
601@code{isearch-allow-scroll} to the special value @code{unlimited},
602that restriction is lifted.
603
604@cindex @code{isearch-scroll} property
605@cindex prevent commands from exiting incremental search
601 The @code{isearch-allow-scroll} feature also affects some other 606 The @code{isearch-allow-scroll} feature also affects some other
602commands, such as @kbd{C-x 2} (@code{split-window-below}) and 607commands, such as @kbd{C-x 2} (@code{split-window-below}) and
603@kbd{C-x ^} (@code{enlarge-window}), which don't exactly scroll but do 608@kbd{C-x ^} (@code{enlarge-window}), which don't exactly scroll but do
604affect where the text appears on the screen. It applies to any 609affect where the text appears on the screen. In fact, it affects
605command whose name has a non-@code{nil} @code{isearch-scroll} 610any command that has a non-@code{nil} @code{isearch-scroll} property.
606property. So you can control which commands are affected by changing 611So you can control which commands are affected by changing these
607these properties. 612properties.
608 613
609@cindex prevent commands from exiting incremental search
610 For example, to make @kbd{C-h l} usable within an incremental search 614 For example, to make @kbd{C-h l} usable within an incremental search
611in all future Emacs sessions, use @kbd{C-h c} to find what command it 615in all future Emacs sessions, use @kbd{C-h c} to find what command it
612runs (@pxref{Key Help}), which is @code{view-lossage}. Then you can 616runs (@pxref{Key Help}), which is @code{view-lossage}. Then you can
@@ -643,6 +647,7 @@ you can extend the search string by holding down the shift key while
643typing cursor motion commands. It will yank text that ends at the new 647typing cursor motion commands. It will yank text that ends at the new
644position after moving point in the current buffer. 648position after moving point in the current buffer.
645 649
650@cindex @code{isearch-move} property
646When @code{isearch-yank-on-move} is @code{t}, you can extend the 651When @code{isearch-yank-on-move} is @code{t}, you can extend the
647search string without using the shift key for cursor motion commands, 652search string without using the shift key for cursor motion commands,
648but it applies only for certain motion command that have the 653but it applies only for certain motion command that have the
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi
index ff12808762f..feed70a7e89 100644
--- a/doc/lispref/minibuf.texi
+++ b/doc/lispref/minibuf.texi
@@ -2174,13 +2174,14 @@ will not have serious consequences. @code{yes-or-no-p} is suitable for
2174more momentous questions, since it requires three or four characters to 2174more momentous questions, since it requires three or four characters to
2175answer. 2175answer.
2176 2176
2177 If either of these functions is called in a command that was invoked 2177 If either of these functions is called in a command that was
2178using the mouse---more precisely, if @code{last-nonmenu-event} 2178invoked using the mouse or some other window-system gesture, or in a
2179(@pxref{Command Loop Info}) is either @code{nil} or a list---then it 2179command invoked via a menu, then they use a dialog box or pop-up menu
2180uses a dialog box or pop-up menu to ask the question. Otherwise, it 2180to ask the question if dialog boxes are supported. Otherwise, they
2181uses keyboard input. You can force use either of the mouse or of keyboard 2181use keyboard input. You can force use either of the mouse or of
2182input by binding @code{last-nonmenu-event} to a suitable value around 2182keyboard input by binding @code{last-nonmenu-event} to a suitable
2183the call. 2183value around the call---bind it to @code{t} to force keyboard
2184interaction, and to a list to force dialog boxes.
2184 2185
2185 Both @code{yes-or-no-p} and @code{y-or-n-p} use the minibuffer. 2186 Both @code{yes-or-no-p} and @code{y-or-n-p} use the minibuffer.
2186 2187
@@ -2386,13 +2387,14 @@ Normally, @code{map-y-or-n-p} binds @code{cursor-in-echo-area} while
2386prompting. But if @var{no-cursor-in-echo-area} is non-@code{nil}, it 2387prompting. But if @var{no-cursor-in-echo-area} is non-@code{nil}, it
2387does not do that. 2388does not do that.
2388 2389
2389If @code{map-y-or-n-p} is called in a command that was invoked using the 2390If @code{map-y-or-n-p} is called in a command that was invoked using
2390mouse---more precisely, if @code{last-nonmenu-event} (@pxref{Command 2391the mouse or some other window-system gesture, or a command invoked
2391Loop Info}) is either @code{nil} or a list---then it uses a dialog box 2392via a menu, then it uses a dialog box or pop-up menu to ask the
2392or pop-up menu to ask the question. In this case, it does not use 2393question if dialog boxes are supported. In this case, it does not use
2393keyboard input or the echo area. You can force use either of the mouse or 2394keyboard input or the echo area. You can force use either of the
2394of keyboard input by binding @code{last-nonmenu-event} to a suitable 2395mouse or of keyboard input by binding @code{last-nonmenu-event} to a
2395value around the call. 2396suitable value around the call---bind it to @code{t} to force keyboard
2397interaction, and to a list to force dialog boxes.
2396 2398
2397The return value of @code{map-y-or-n-p} is the number of objects acted on. 2399The return value of @code{map-y-or-n-p} is the number of objects acted on.
2398@end defun 2400@end defun
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index f1d0c41dfe4..c2698da6d99 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -4074,8 +4074,8 @@ replacing syntactic font lock, then the regexp-based font lock.
4074 4074
4075Although parser-based font lock doesn't share the same customization 4075Although parser-based font lock doesn't share the same customization
4076variables with regexp-based font lock, it uses similar customization 4076variables with regexp-based font lock, it uses similar customization
4077schemes. The tree-sitter counterpart of @var{font-lock-keywords} is 4077schemes. The tree-sitter counterpart of @code{font-lock-keywords} is
4078@var{treesit-font-lock-settings}. 4078@code{treesit-font-lock-settings}.
4079 4079
4080@cindex tree-sitter fontifications, overview 4080@cindex tree-sitter fontifications, overview
4081@cindex fontifications with tree-sitter, overview 4081@cindex fontifications with tree-sitter, overview
@@ -4109,9 +4109,9 @@ To setup tree-sitter fontification, a major mode should first set
4109@code{treesit-major-mode-setup}. 4109@code{treesit-major-mode-setup}.
4110 4110
4111@defun treesit-font-lock-rules &rest query-specs 4111@defun treesit-font-lock-rules &rest query-specs
4112This function is used to set @var{treesit-font-lock-settings}. It 4112This function is used to set @code{treesit-font-lock-settings}. It
4113takes care of compiling queries and other post-processing, and outputs 4113takes care of compiling queries and other post-processing, and outputs
4114a value that @var{treesit-font-lock-settings} accepts. Here's an 4114a value that @code{treesit-font-lock-settings} accepts. Here's an
4115example: 4115example:
4116 4116
4117@example 4117@example
@@ -4982,7 +4982,7 @@ below: then the major mode needs only to write some indentation rules
4982and the engine takes care of the rest. 4982and the engine takes care of the rest.
4983 4983
4984To enable the parser-based indentation engine, either set 4984To enable the parser-based indentation engine, either set
4985@var{treesit-simple-indent-rules} and call 4985@code{treesit-simple-indent-rules} and call
4986@code{treesit-major-mode-setup}, or equivalently, set the value of 4986@code{treesit-major-mode-setup}, or equivalently, set the value of
4987@code{indent-line-function} to @code{treesit-indent}. 4987@code{indent-line-function} to @code{treesit-indent}.
4988 4988
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index 38c9ec8c2f0..b0824faaaa2 100644
--- a/doc/lispref/parsing.texi
+++ b/doc/lispref/parsing.texi
@@ -1692,9 +1692,9 @@ directly translate into operations shown above.
1692@end example 1692@end example
1693 1693
1694@defun treesit-range-rules &rest query-specs 1694@defun treesit-range-rules &rest query-specs
1695This function is used to set @var{treesit-range-settings}. It 1695This function is used to set @code{treesit-range-settings}. It takes
1696takes care of compiling queries and other post-processing, and outputs 1696care of compiling queries and other post-processing, and outputs a
1697a value that @var{treesit-range-settings} can have. 1697value that @code{treesit-range-settings} can have.
1698 1698
1699It takes a series of @var{query-spec}s, where each @var{query-spec} is 1699It takes a series of @var{query-spec}s, where each @var{query-spec} is
1700a @var{query} preceded by zero or more @var{keyword}/@var{value} 1700a @var{query} preceded by zero or more @var{keyword}/@var{value}
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index be7504c92bf..e08a5587962 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -713,7 +713,6 @@ Choosing a Mail Back End
713 713
714Browsing the Web 714Browsing the Web
715 715
716* Archiving Mail::
717* Web Searches:: Creating groups from articles that match a string. 716* Web Searches:: Creating groups from articles that match a string.
718* RSS:: Reading RDF site summary. 717* RSS:: Reading RDF site summary.
719 718
@@ -17247,7 +17246,6 @@ Gnus has been getting a bit of a collection of back ends for providing
17247interfaces to these sources. 17246interfaces to these sources.
17248 17247
17249@menu 17248@menu
17250* Archiving Mail::
17251* Web Searches:: Creating groups from articles that match a string. 17249* Web Searches:: Creating groups from articles that match a string.
17252* RSS:: Reading RDF site summary. 17250* RSS:: Reading RDF site summary.
17253@end menu 17251@end menu
@@ -17264,29 +17262,6 @@ cases, it makes a lot of sense to let the Gnus Agent (@pxref{Gnus
17264Unplugged}) handle downloading articles, and then you can read them at 17262Unplugged}) handle downloading articles, and then you can read them at
17265leisure from your local disk. No more World Wide Wait for you. 17263leisure from your local disk. No more World Wide Wait for you.
17266 17264
17267@node Archiving Mail
17268@subsection Archiving Mail
17269@cindex archiving mail
17270@cindex backup of mail
17271
17272Some of the back ends, notably @code{nnml}, @code{nnfolder}, and
17273@code{nnmaildir}, now actually store the article marks with each group.
17274For these servers, archiving and restoring a group while preserving
17275marks is fairly simple.
17276
17277(Preserving the group level and group parameters as well still
17278requires ritual dancing and sacrifices to the @file{.newsrc.eld} deity
17279though.)
17280
17281To archive an entire @code{nnml}, @code{nnfolder}, or @code{nnmaildir}
17282server, take a recursive copy of the server directory. There is no need
17283to shut down Gnus, so archiving may be invoked by @code{cron} or
17284similar. You restore the data by restoring the directory tree, and
17285adding a server definition pointing to that directory in Gnus. The
17286@ref{Article Backlog}, @ref{Asynchronous Fetching} and other things
17287might interfere with overwriting data, so you may want to shut down Gnus
17288before you restore the data.
17289
17290@node Web Searches 17265@node Web Searches
17291@subsection Web Searches 17266@subsection Web Searches
17292@cindex nnweb 17267@cindex nnweb
diff --git a/etc/NEWS b/etc/NEWS
index ce4c3100f78..314ace50dbf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -360,6 +360,51 @@ The new Rmail commands 'rmail-mailing-list-post',
360'rmail-mailing-list-archive allow to, respectively, post to, 360'rmail-mailing-list-archive allow to, respectively, post to,
361unsubscribe from, request help about, and browse the archives, of the 361unsubscribe from, request help about, and browse the archives, of the
362mailing list from which the current email message was delivered. 362mailing list from which the current email message was delivered.
363
364** Dictionary
365
366---
367*** New user option 'dictionary-search-interface'.
368Controls how the 'dictionary-search' command prompts for and displays
369dictionary definitions. Customize this user option to 'help' to have
370'dictionary-search' display definitions in a *Help* buffer and provide
371dictionary-based minibuffer completion for word selection.
372
373---
374*** New user option 'dictionary-read-word-prompt'.
375This allows the user to customize the prompt that is used by
376'dictionary-search' when asking for a word to search in the
377dictionary.
378
379---
380*** New user option 'dictionary-display-definition-function'.
381This allows the user to customize the way in which 'dictionary-search'
382displays word definitions. If non-nil, this user option should be set
383to a function that displays a word definition obtained from a
384dictionary server. The new function
385'dictionary-display-definition-in-help-buffer' can be used to display
386the definition in a *Help* buffer, instead of the default *Dictionary*
387buffer.
388
389---
390*** New user option 'dictionary-read-word-function'.
391This allows the user to customize the way in which 'dictionary-search'
392prompts for a word to search in the dictionary. This user option
393should be set to a function that lets the user select a word and
394returns it as a string. The new function
395'dictionary-completing-read-word' can be used to prompt with
396completion based on dictionary matches.
397
398---
399*** New user option 'dictionary-read-dictionary-function'.
400This allows the user to customize the way in which 'dictionary-search'
401prompts for a dictionary to search in. This user option should be set
402to a function that lets the user select a dictionary and returns its
403name as a string. The new function
404'dictionary-completing-read-dictionary' can be used to prompt with
405completion based on dictionaries that the server supports.
406
407
363 408
364* New Modes and Packages in Emacs 30.1 409* New Modes and Packages in Emacs 30.1
365 410
diff --git a/etc/NEWS.29 b/etc/NEWS.29
index fa428d9c790..a3457d70340 100644
--- a/etc/NEWS.29
+++ b/etc/NEWS.29
@@ -91,24 +91,6 @@ available, and includes support for animated WebP images. To disable
91WebP support, use the '--without-webp' configure flag. Image 91WebP support, use the '--without-webp' configure flag. Image
92specifiers can now use ':type webp'. 92specifiers can now use ':type webp'.
93 93
94+++
95** Emacs has been ported to the Haiku operating system.
96The configuration process should automatically detect and build for
97Haiku. There is also an optional window-system port to Haiku, which
98can be enabled by configuring Emacs with the option '--with-be-app',
99which will require the Haiku Application Kit development headers and a
100C++ compiler to be present on your system. If Emacs is not built with
101the option '--with-be-app', the resulting Emacs will only run in
102text-mode terminals.
103
104To enable Cairo support, ensure that the Cairo and FreeType
105development files are present on your system, and configure Emacs with
106'--with-be-cairo'.
107
108Unlike X, there is no compile-time option to enable or disable
109double-buffering; it is always enabled. To disable it, change the
110frame parameter 'inhibit-double-buffering' instead.
111
112--- 94---
113** Emacs now installs the ".pdmp" file using a unique fingerprint in the name. 95** Emacs now installs the ".pdmp" file using a unique fingerprint in the name.
114The file is typically installed using a file name akin to 96The file is typically installed using a file name akin to
@@ -126,6 +108,16 @@ option '--without-xinput2' to disable this support.
126'(featurep 'xinput2)' can be used to test for the presence of XInput 2 108'(featurep 'xinput2)' can be used to test for the presence of XInput 2
127support from Lisp programs. 109support from Lisp programs.
128 110
111---
112** Emacs can now be optionally built with the Cairo XCB backend.
113Configure Emacs with the '--with-cairo-xcb' option to use the Cairo
114XCB backend; the default is not to use it. This backend makes Emacs
115moderately faster when running over X connections with high latency,
116but is currently known to crash when Emacs repeatedly closes and opens
117a display connection to the same terminal; this could happen, for
118example, if you repeatedly visit files via emacsclient in a single
119client frame, each time deleting the frame with 'C-x C-c'.
120
129+++ 121+++
130** Emacs now supports being built with pure GTK. 122** Emacs now supports being built with pure GTK.
131To use this option, make sure the GTK 3 (version 3.22.23 or later) and 123To use this option, make sure the GTK 3 (version 3.22.23 or later) and
@@ -139,6 +131,29 @@ known to have problems, such as undesirable frame positioning and
139various issues with keyboard input of sequences such as 'C-;' and 131various issues with keyboard input of sequences such as 'C-;' and
140'C-S-u'. 132'C-S-u'.
141 133
134Note that, unlike the X build of Emacs, the PGTK build cannot
135automatically switch to text-mode interface (thus emulating '-nw') if
136it cannot determine the default display; it will instead complain and
137ask you to invoke it with the explicit '-nw' option.
138
139+++
140** Emacs has been ported to the Haiku operating system.
141The configuration process should automatically detect and build for
142Haiku. There is also an optional window-system port to Haiku, which
143can be enabled by configuring Emacs with the option '--with-be-app',
144which will require the Haiku Application Kit development headers and a
145C++ compiler to be present on your system. If Emacs is not built with
146the option '--with-be-app', the resulting Emacs will only run in
147text-mode terminals.
148
149To enable Cairo support, ensure that the Cairo and FreeType
150development files are present on your system, and configure Emacs with
151'--with-be-cairo'.
152
153Unlike X, there is no compile-time option to enable or disable
154double-buffering; it is always enabled. To disable it, change the
155frame parameter 'inhibit-double-buffering' instead.
156
142--- 157---
143** Emacs no longer reduces the size of the Japanese dictionary. 158** Emacs no longer reduces the size of the Japanese dictionary.
144Building Emacs includes generation of a Japanese dictionary, which is 159Building Emacs includes generation of a Japanese dictionary, which is
@@ -1844,10 +1859,10 @@ this includes "binary" buffers like 'archive-mode' and 'image-mode'.
1844 1859
1845+++ 1860+++
1846*** New command 'package-upgrade'. 1861*** New command 'package-upgrade'.
1847This command allows you to upgrade packages without using 'M-x 1862This command allows you to upgrade packages without using 'list-packages'.
1848list-packages'. A package that comes with the Emacs distribution can 1863A package that comes with the Emacs distribution can only be upgraded
1849only be upgraded after you install, once, a newer version from ELPA 1864after you install, once, a newer version from ELPA via the
1850via the package-menu displayed by 'list-packages'. 1865package-menu displayed by 'list-packages'.
1851 1866
1852+++ 1867+++
1853*** New command 'package-upgrade-all'. 1868*** New command 'package-upgrade-all'.
@@ -1908,10 +1923,10 @@ enabled.
1908 1923
1909In addition, when this option is non-nil, built-in packages for which 1924In addition, when this option is non-nil, built-in packages for which
1910a new version is available in archives can be upgraded via the package 1925a new version is available in archives can be upgraded via the package
1911menu produced by 'M-x list-packages'. If you do set this option 1926menu produced by 'list-packages'. If you do set this option non-nil,
1912non-nil, we recommend not to use the 'U' command, but instead to use 1927we recommend not to use the 'U' command, but instead to use '/ u' to
1913'/ u' to show the packages which can be upgraded, and then decide 1928show the packages which can be upgraded, and then decide which ones of
1914which ones of them you actually want to update from the archives. 1929them you actually want to update from the archives.
1915 1930
1916If you customize this option, we recommend you place its non-default 1931If you customize this option, we recommend you place its non-default
1917setting in your early-init file. 1932setting in your early-init file.
@@ -3871,6 +3886,19 @@ The following generalized variables have been made obsolete:
3871'standard-case-table', 'syntax-table', 'visited-file-modtime', 3886'standard-case-table', 'syntax-table', 'visited-file-modtime',
3872'window-height', 'window-width', and 'x-get-secondary-selection'. 3887'window-height', 'window-width', and 'x-get-secondary-selection'.
3873 3888
3889---
3890** The 'dotimes' loop variable can no longer be manipulated in the loop body.
3891Previously, the 'dotimes' loop counter could be modified inside the
3892loop body, but only in code using dynamic binding. Now the behavior
3893is the same as when using lexical binding: changes to the loop
3894variable have no effect on subsequent iterations. That is,
3895
3896 (dotimes (i 10)
3897 (print i)
3898 (setq i (+ i 6)))
3899
3900now always prints the numbers 0 .. 9.
3901
3874 3902
3875* Lisp Changes in Emacs 29.1 3903* Lisp Changes in Emacs 29.1
3876 3904
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index c4363310541..f3bb2bd8333 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -516,6 +516,13 @@ directory copy is ineffective.
516This is due to an arbitrary limit in certain versions of awk. 516This is due to an arbitrary limit in certain versions of awk.
517The solution is to use gawk (GNU awk). 517The solution is to use gawk (GNU awk).
518 518
519*** Saving, via EasyPG, a file encrypted with GnuPG hangs
520
521This is known to happen with GnuPG v2.4.1. The only known workaround
522is to downgrade to a version of GnuPG older than 2.4.1 (or, in the
523future, upgrade to a newer version which solves the problem, when such
524a fixed version becomes available).
525
519** Problems with hostname resolution 526** Problems with hostname resolution
520 527
521*** Emacs does not know your host's fully-qualified domain name. 528*** Emacs does not know your host's fully-qualified domain name.
diff --git a/lisp/comint.el b/lisp/comint.el
index e1786e7e670..5161d01515c 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -258,6 +258,35 @@ to set this in a mode hook, rather than customize the default value."
258 file) 258 file)
259 :group 'comint) 259 :group 'comint)
260 260
261(defcustom comint-pager nil
262 "If non-nil, the program to use for pagination of program output.
263
264Some programs produce large amounts of output, and have provision for
265pagination of their output through a filter program, commonly known as
266a \"pager\". The pager limits the amount of output produced and
267allows the user to interactively browse the output one page at a time.
268Some programs paginate their output by default, by always starting a
269pager. The program they use as the pager is specified by the
270environment variable PAGER; if that variable is not defined, they use
271some fixed default, such as \"less\".
272
273The interactive browsing aspects of pagination are not needed, and get
274in the way, when the output of the program is directed to an Emacs
275buffer, so in those cases pagination might need to be disabled.
276Disabling pagination means that some programs will produce large
277amounts of output, but most such programs have other ways to limit
278their output, such as additional arguments or Emacs interfaces.
279To disable pagination, this variable's value should be a string that
280names a program, such as \"cat\", which passes through all of the
281output without any filtering or delays. Comint will then set the
282PAGER variable to name that program, when it invokes external
283programs."
284 :version "30.1"
285 :type '(choice (const :tag "Use default PAGER" nil)
286 (const :tag "Don't do paging (PAGER=cat)" "cat")
287 (string :tag "Program name or absolute path of pager"))
288 :group 'comint)
289
261(defvar comint-input-ring-file-prefix nil 290(defvar comint-input-ring-file-prefix nil
262 "The prefix to skip when parsing the input ring file. 291 "The prefix to skip when parsing the input ring file.
263This is useful in Zsh when the extended_history option is on.") 292This is useful in Zsh when the extended_history option is on.")
@@ -868,6 +897,10 @@ series of processes in the same Comint buffer. The hook
868 (nconc 897 (nconc
869 (comint-term-environment) 898 (comint-term-environment)
870 (list (format "INSIDE_EMACS=%s,comint" emacs-version)) 899 (list (format "INSIDE_EMACS=%s,comint" emacs-version))
900 (when comint-pager
901 (if (stringp comint-pager)
902 (list (format "PAGER=%s" comint-pager))
903 (error "comint-pager should be a string: %s" comint-pager)))
871 process-environment)) 904 process-environment))
872 (default-directory 905 (default-directory
873 (if (file-accessible-directory-p default-directory) 906 (if (file-accessible-directory-p default-directory)
@@ -1546,6 +1579,8 @@ Intended to be added to `isearch-mode-hook' in `comint-mode'."
1546 (setq isearch-message-function nil) 1579 (setq isearch-message-function nil)
1547 (setq isearch-wrap-function nil) 1580 (setq isearch-wrap-function nil)
1548 (setq isearch-push-state-function nil) 1581 (setq isearch-push-state-function nil)
1582 ;; Force isearch to not change mark.
1583 (setq isearch-opoint (point))
1549 (kill-local-variable 'isearch-lazy-count) 1584 (kill-local-variable 'isearch-lazy-count)
1550 (remove-hook 'isearch-mode-end-hook 'comint-history-isearch-end t) 1585 (remove-hook 'isearch-mode-end-hook 'comint-history-isearch-end t)
1551 (unless isearch-suspended 1586 (unless isearch-suspended
diff --git a/lisp/emacs-lisp/benchmark.el b/lisp/emacs-lisp/benchmark.el
index dc7889c40a0..e50b8524f29 100644
--- a/lisp/emacs-lisp/benchmark.el
+++ b/lisp/emacs-lisp/benchmark.el
@@ -152,7 +152,7 @@ to call it without any argument."
152(defmacro benchmark-progn (&rest body) 152(defmacro benchmark-progn (&rest body)
153 "Evaluate BODY and message the time taken. 153 "Evaluate BODY and message the time taken.
154The return value is the value of the final form in BODY." 154The return value is the value of the final form in BODY."
155 (declare (debug body) (indent 0)) 155 (declare (debug t) (indent 0))
156 (let ((value (make-symbol "value")) 156 (let ((value (make-symbol "value"))
157 (start (make-symbol "start")) 157 (start (make-symbol "start"))
158 (gcs (make-symbol "gcs")) 158 (gcs (make-symbol "gcs"))
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index 3d3158111b2..69595601bc8 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -1106,8 +1106,12 @@ untar into a directory named DIR; otherwise, signal an error."
1106 ;; Add the directory that will contain the autoload file to 1106 ;; Add the directory that will contain the autoload file to
1107 ;; the load path. We don't hard-code `pkg-dir', to avoid 1107 ;; the load path. We don't hard-code `pkg-dir', to avoid
1108 ;; issues if the package directory is moved around. 1108 ;; issues if the package directory is moved around.
1109 (or (and load-file-name (file-name-directory load-file-name)) 1109 ;; `loaddefs-generate' has code to do this for us, but it's
1110 (car load-path))))) 1110 ;; not currently exposed. (Bug#63625)
1111 (or (and load-file-name
1112 (directory-file-name
1113 (file-name-directory load-file-name)))
1114 (car load-path)))))
1111 (let ((buf (find-buffer-visiting output-file))) 1115 (let ((buf (find-buffer-visiting output-file)))
1112 (when buf (kill-buffer buf))) 1116 (when buf (kill-buffer buf)))
1113 auto-name)) 1117 auto-name))
@@ -1195,7 +1199,7 @@ boundaries."
1195 ;; the earliest in version 31.1. The idea is to phase out the 1199 ;; the earliest in version 31.1. The idea is to phase out the
1196 ;; requirement for a "footer line" without unduly impacting users 1200 ;; requirement for a "footer line" without unduly impacting users
1197 ;; on earlier Emacs versions. See Bug#26490 for more details. 1201 ;; on earlier Emacs versions. See Bug#26490 for more details.
1198 (unless (search-forward (concat ";;; " file-name ".el ends here") nil t) 1202 (unless (search-forward (concat ";;; " file-name ".el ends here") nil 'move)
1199 (lwarn '(package package-format) :warning 1203 (lwarn '(package package-format) :warning
1200 "Package lacks a terminating comment")) 1204 "Package lacks a terminating comment"))
1201 ;; Try to include a trailing newline. 1205 ;; Try to include a trailing newline.
diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el
index fd9fbbe25a4..39325a3c35e 100644
--- a/lisp/emacs-lisp/regexp-opt.el
+++ b/lisp/emacs-lisp/regexp-opt.el
@@ -154,6 +154,7 @@ usually more efficient than that of a simplified version:
154 "Return the depth of REGEXP. 154 "Return the depth of REGEXP.
155This means the number of non-shy regexp grouping constructs 155This means the number of non-shy regexp grouping constructs
156\(parenthesized expressions) in REGEXP." 156\(parenthesized expressions) in REGEXP."
157 (declare (pure t) (side-effect-free t))
157 (save-match-data 158 (save-match-data
158 ;; Hack to signal an error if REGEXP does not have balanced parentheses. 159 ;; Hack to signal an error if REGEXP does not have balanced parentheses.
159 (string-match regexp "") 160 (string-match regexp "")
@@ -270,6 +271,7 @@ Merges keywords to avoid backtracking in Emacs's regexp matcher."
270CHARS should be a list of characters. 271CHARS should be a list of characters.
271If CHARS is the empty list, the return value is a regexp that 272If CHARS is the empty list, the return value is a regexp that
272never matches anything." 273never matches anything."
274 (declare (pure t) (side-effect-free t))
273 ;; The basic idea is to find character ranges. Also we take care in the 275 ;; The basic idea is to find character ranges. Also we take care in the
274 ;; position of character set meta characters in the character set regexp. 276 ;; position of character set meta characters in the character set regexp.
275 ;; 277 ;;
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 46f61c26bc4..e82490ffee5 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -1144,6 +1144,7 @@ If NO-GROUP is non-nil, don't bracket the result in a non-capturing
1144group. 1144group.
1145 1145
1146For extending the `rx' notation in FORM, use `rx-define' or `rx-let-eval'." 1146For extending the `rx' notation in FORM, use `rx-define' or `rx-let-eval'."
1147 (declare (important-return-value t))
1147 (let* ((item (rx--translate form)) 1148 (let* ((item (rx--translate form))
1148 (exprs (if no-group 1149 (exprs (if no-group
1149 (car item) 1150 (car item)
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 947390b3de3..9e906930b92 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -81,18 +81,22 @@ Note how the single `-' got converted into a list before
81threading." 81threading."
82 (declare (indent 0) (debug thread-first)) 82 (declare (indent 0) (debug thread-first))
83 `(internal--thread-argument nil ,@forms)) 83 `(internal--thread-argument nil ,@forms))
84
84(defsubst hash-table-empty-p (hash-table) 85(defsubst hash-table-empty-p (hash-table)
85 "Check whether HASH-TABLE is empty (has 0 elements)." 86 "Check whether HASH-TABLE is empty (has 0 elements)."
87 (declare (side-effect-free t))
86 (zerop (hash-table-count hash-table))) 88 (zerop (hash-table-count hash-table)))
87 89
88(defsubst hash-table-keys (hash-table) 90(defsubst hash-table-keys (hash-table)
89 "Return a list of keys in HASH-TABLE." 91 "Return a list of keys in HASH-TABLE."
92 (declare (side-effect-free t))
90 (let ((keys nil)) 93 (let ((keys nil))
91 (maphash (lambda (k _) (push k keys)) hash-table) 94 (maphash (lambda (k _) (push k keys)) hash-table)
92 keys)) 95 keys))
93 96
94(defsubst hash-table-values (hash-table) 97(defsubst hash-table-values (hash-table)
95 "Return a list of values in HASH-TABLE." 98 "Return a list of values in HASH-TABLE."
99 (declare (side-effect-free t))
96 (let ((values nil)) 100 (let ((values nil))
97 (maphash (lambda (_ v) (push v values)) hash-table) 101 (maphash (lambda (_ v) (push v values)) hash-table)
98 values)) 102 values))
@@ -149,6 +153,7 @@ carriage return."
149All sequences of whitespaces in STRING are collapsed into a 153All sequences of whitespaces in STRING are collapsed into a
150single space character, and leading/trailing whitespace is 154single space character, and leading/trailing whitespace is
151removed." 155removed."
156 (declare (important-return-value t))
152 (let ((blank "[[:blank:]\r\n]+")) 157 (let ((blank "[[:blank:]\r\n]+"))
153 (string-trim (replace-regexp-in-string blank " " string t t) 158 (string-trim (replace-regexp-in-string blank " " string t t)
154 blank blank))) 159 blank blank)))
@@ -158,6 +163,7 @@ removed."
158Wrapping is done where there is whitespace. If there are 163Wrapping is done where there is whitespace. If there are
159individual words in STRING that are longer than LENGTH, the 164individual words in STRING that are longer than LENGTH, the
160result will have lines that are longer than LENGTH." 165result will have lines that are longer than LENGTH."
166 (declare (important-return-value t))
161 (with-temp-buffer 167 (with-temp-buffer
162 (insert string) 168 (insert string)
163 (goto-char (point-min)) 169 (goto-char (point-min))
@@ -189,6 +195,7 @@ coding system that doesn't specify a BOM, like `utf-16le' or `utf-16be'.
189When shortening strings for display purposes, 195When shortening strings for display purposes,
190`truncate-string-to-width' is almost always a better alternative 196`truncate-string-to-width' is almost always a better alternative
191than this function." 197than this function."
198 (declare (important-return-value t))
192 (unless (natnump length) 199 (unless (natnump length)
193 (signal 'wrong-type-argument (list 'natnump length))) 200 (signal 'wrong-type-argument (list 'natnump length)))
194 (if coding-system 201 (if coding-system
@@ -324,6 +331,7 @@ as the new values of the bound variables in the recursive invocation."
324;;;###autoload 331;;;###autoload
325(defun string-pixel-width (string) 332(defun string-pixel-width (string)
326 "Return the width of STRING in pixels." 333 "Return the width of STRING in pixels."
334 (declare (important-return-value t))
327 (if (zerop (length string)) 335 (if (zerop (length string))
328 0 336 0
329 ;; Keeping a work buffer around is more efficient than creating a 337 ;; Keeping a work buffer around is more efficient than creating a
@@ -344,6 +352,7 @@ This takes into account combining characters and grapheme clusters:
344if compositions are enabled, each sequence of characters composed 352if compositions are enabled, each sequence of characters composed
345on display into a single grapheme cluster is treated as a single 353on display into a single grapheme cluster is treated as a single
346indivisible unit." 354indivisible unit."
355 (declare (side-effect-free t))
347 (let ((result nil) 356 (let ((result nil)
348 (start 0) 357 (start 0)
349 comp) 358 comp)
diff --git a/lisp/env.el b/lisp/env.el
index faafcb6250f..281934af054 100644
--- a/lisp/env.el
+++ b/lisp/env.el
@@ -76,6 +76,7 @@ If it is non-nil and not a function, references to undefined variables are
76left unchanged. 76left unchanged.
77 77
78Use `$$' to insert a single dollar sign." 78Use `$$' to insert a single dollar sign."
79 (declare (important-return-value t))
79 (let ((start 0)) 80 (let ((start 0))
80 (while (string-match env--substitute-vars-regexp string start) 81 (while (string-match env--substitute-vars-regexp string start)
81 (cond ((match-beginning 1) 82 (cond ((match-beginning 1)
@@ -94,6 +95,7 @@ Use `$$' to insert a single dollar sign."
94 string)) 95 string))
95 96
96(defun substitute-env-in-file-name (filename) 97(defun substitute-env-in-file-name (filename)
98 (declare (important-return-value t))
97 (substitute-env-vars filename 99 (substitute-env-vars filename
98 ;; How 'bout we lookup other tables than the env? 100 ;; How 'bout we lookup other tables than the env?
99 ;; E.g. we could accept bookmark names as well! 101 ;; E.g. we could accept bookmark names as well!
@@ -104,6 +106,7 @@ Use `$$' to insert a single dollar sign."
104(defun setenv-internal (env variable value keep-empty) 106(defun setenv-internal (env variable value keep-empty)
105 "Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY. 107 "Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY.
106Changes ENV by side-effect, and returns its new value." 108Changes ENV by side-effect, and returns its new value."
109 (declare (important-return-value t))
107 (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)")) 110 (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)"))
108 (case-fold-search nil) 111 (case-fold-search nil)
109 (scan env) 112 (scan env)
diff --git a/lisp/international/mule.el b/lisp/international/mule.el
index 25b90b49c8f..2b44a2e0645 100644
--- a/lisp/international/mule.el
+++ b/lisp/international/mule.el
@@ -2484,10 +2484,12 @@ This function is intended to be added to `auto-coding-functions'."
2484 ;; called as part of visiting a file, as opposed 2484 ;; called as part of visiting a file, as opposed
2485 ;; to when saving a buffer to a file. 2485 ;; to when saving a buffer to a file.
2486 (if (and enable-multibyte-characters 2486 (if (and enable-multibyte-characters
2487 ;; 'charset' will signal an error in 2487 ;; 'charset' and 'iso-2022' will signal
2488 ;; coding-system-equal, since it isn't a 2488 ;; an error in coding-system-equal, since
2489 ;; coding-system. So test that up front. 2489 ;; they aren't coding-systems. So test
2490 ;; that up front.
2490 (not (equal sym-type 'charset)) 2491 (not (equal sym-type 'charset))
2492 (not (equal sym-type 'iso-2022))
2491 (coding-system-equal 'utf-8 sym-type) 2493 (coding-system-equal 'utf-8 sym-type)
2492 (coding-system-equal 'utf-8 bfcs-type)) 2494 (coding-system-equal 'utf-8 bfcs-type))
2493 buffer-file-coding-system 2495 buffer-file-coding-system
@@ -2540,11 +2542,13 @@ This function is intended to be added to `auto-coding-functions'."
2540 (bfcs-type 2542 (bfcs-type
2541 (coding-system-type buffer-file-coding-system))) 2543 (coding-system-type buffer-file-coding-system)))
2542 (if (and enable-multibyte-characters 2544 (if (and enable-multibyte-characters
2543 ;; 'charset' will signal an error in 2545 ;; 'charset' and 'iso-2022' will signal an error
2544 ;; coding-system-equal, since it isn't a 2546 ;; in coding-system-equal, since they aren't
2545 ;; coding-system. So test that up front. 2547 ;; coding-systems. So test that up front.
2546 (not (equal sym-type 'charset)) 2548 (not (equal sym-type 'charset))
2547 (not (equal bfcs-type 'charset)) 2549 (not (equal bfcs-type 'charset))
2550 (not (equal sym-type 'iso-2022))
2551 (not (equal bfcs-type 'iso-2022))
2548 (coding-system-equal 'utf-8 sym-type) 2552 (coding-system-equal 'utf-8 sym-type)
2549 (coding-system-equal 'utf-8 bfcs-type)) 2553 (coding-system-equal 'utf-8 bfcs-type))
2550 buffer-file-coding-system 2554 buffer-file-coding-system
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index da002a46621..003e774bbcc 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -2589,10 +2589,11 @@ See `menu-bar-mode' for more information."
2589 binding))) 2589 binding)))
2590 2590
2591(defun popup-menu (menu &optional position prefix from-menu-bar) 2591(defun popup-menu (menu &optional position prefix from-menu-bar)
2592 "Popup the given menu and call the selected option. 2592 "Popup MENU and call the selected option.
2593MENU can be a keymap, an easymenu-style menu or a list of keymaps as for 2593MENU can be a keymap, an easymenu-style menu or a list of keymaps as for
2594`x-popup-menu'. 2594`x-popup-menu'.
2595The menu is shown at the place where POSITION specifies. 2595The menu is shown at the location specified by POSITION, which
2596defaults to the place of the mouse click that popped the menu.
2596For the form of POSITION, see `popup-menu-normalize-position'. 2597For the form of POSITION, see `popup-menu-normalize-position'.
2597PREFIX is the prefix argument (if any) to pass to the command. 2598PREFIX is the prefix argument (if any) to pass to the command.
2598FROM-MENU-BAR, if non-nil, means we are dropping one of menu-bar's menus." 2599FROM-MENU-BAR, if non-nil, means we are dropping one of menu-bar's menus."
diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el
index ba65225692a..8d81b3ec9d8 100644
--- a/lisp/net/dictionary.el
+++ b/lisp/net/dictionary.el
@@ -38,6 +38,8 @@
38(require 'custom) 38(require 'custom)
39(require 'dictionary-connection) 39(require 'dictionary-connection)
40(require 'button) 40(require 'button)
41(require 'help-mode)
42(require 'external-completion)
41 43
42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
43;; Stuff for customizing. 45;; Stuff for customizing.
@@ -247,6 +249,65 @@ is utf-8"
247 ))) 249 )))
248 :version "28.1") 250 :version "28.1")
249 251
252(defcustom dictionary-read-word-prompt "Search word"
253 "Prompt string to use when prompting for a word."
254 :type 'string
255 :version "30.1")
256
257(defcustom dictionary-display-definition-function nil
258 "Function to use for displaying dictionary definitions.
259It is called with three string arguments: the word being defined,
260the dictionary name, and the full definition."
261 :type '(choice (const :tag "Dictionary buffer" nil)
262 (const :tag "Help buffer"
263 dictionary-display-definition-in-help-buffer)
264 (function :tag "Custom function"))
265 :version "30.1")
266
267(defcustom dictionary-read-word-function #'dictionary-read-word-default
268 "Function to use for prompting for a word.
269It is called with one string argument, the name of the dictionary to use, and
270must return a string."
271 :type '(choice (const :tag "Default" dictionary-read-word-default)
272 (const :tag "Dictionary-based completion"
273 dictionary-completing-read-word)
274 (function :tag "Custom function"))
275 :version "30.1")
276
277(defcustom dictionary-read-dictionary-function
278 #'dictionary-read-dictionary-default
279 "Function to use for prompting for a dictionary.
280It is called with no arguments and must return a string."
281 :type '(choice (const :tag "Default" dictionary-read-dictionary-default)
282 (const :tag "Choose among server-provided dictionaries"
283 dictionary-completing-read-dictionary)
284 (function :tag "Custom function"))
285 :version "30.1")
286
287(defcustom dictionary-search-interface nil
288 "Controls how `dictionary-search' prompts for words and displays definitions.
289
290When set to `help', `dictionary-search' displays definitions in a *Help* buffer,
291and provides completion for word selection based on dictionary matches.
292
293Otherwise, `dictionary-search' displays definitions in a *Dictionary* buffer."
294 :type '(choice (const :tag "Dictionary buffer" nil)
295 (const :tag "Help buffer" help))
296 :set (lambda (symbol value)
297 (let ((vals (pcase value
298 ('help '(dictionary-display-definition-in-help-buffer
299 dictionary-completing-read-word
300 dictionary-completing-read-dictionary))
301 (_ '(nil
302 dictionary-read-word-default
303 dictionary-read-dictionary-default)))))
304 (seq-setq (dictionary-display-definition-function
305 dictionary-read-word-function
306 dictionary-read-dictionary-function)
307 vals))
308 (set-default-toplevel-value symbol value))
309 :version "30.1")
310
250(defface dictionary-word-definition-face 311(defface dictionary-word-definition-face
251'((((supports (:family "DejaVu Serif"))) 312'((((supports (:family "DejaVu Serif")))
252 (:family "DejaVu Serif")) 313 (:family "DejaVu Serif"))
@@ -366,6 +427,8 @@ is utf-8"
366 '() 427 '()
367 "History list of searched word.") 428 "History list of searched word.")
368 429
430(defvar dictionary--last-match nil)
431
369;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 432;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
370;; Basic function providing startup actions 433;; Basic function providing startup actions
371;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 434;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1139,6 +1202,20 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
1139 ((car (get-char-property (point) 'data))) 1202 ((car (get-char-property (point) 'data)))
1140 (t (current-word t)))) 1203 (t (current-word t))))
1141 1204
1205(defun dictionary-read-dictionary-default ()
1206 "Prompt for a dictionary name."
1207 (read-string (if dictionary-default-dictionary
1208 (format "Dictionary (%s): "
1209 dictionary-default-dictionary)
1210 "Dictionary: ")
1211 nil nil dictionary-default-dictionary))
1212
1213(defun dictionary-read-word-default (_dictionary)
1214 "Prompt for a word to search in the dictionary."
1215 (let ((default (dictionary-search-default)))
1216 (read-string (format-prompt dictionary-read-word-prompt default)
1217 nil 'dictionary-word-history default)))
1218
1142;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1219;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1143;; User callable commands 1220;; User callable commands
1144;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1221;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1149,23 +1226,22 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"."
1149It presents the selection or word at point as default input and 1226It presents the selection or word at point as default input and
1150allows editing it." 1227allows editing it."
1151 (interactive 1228 (interactive
1152 (list (let ((default (dictionary-search-default))) 1229 (let ((dict
1153 (read-string (format-prompt "Search word" default) 1230 (if current-prefix-arg
1154 nil 'dictionary-word-history default)) 1231 (funcall dictionary-read-dictionary-function)
1155 (if current-prefix-arg 1232 dictionary-default-dictionary)))
1156 (read-string (if dictionary-default-dictionary 1233 (list (funcall dictionary-read-word-function dict) dict)))
1157 (format "Dictionary (%s): " dictionary-default-dictionary)
1158 "Dictionary: ")
1159 nil nil dictionary-default-dictionary)
1160 dictionary-default-dictionary)))
1161
1162 ;; if called by pressing the button
1163 (unless word
1164 (setq word (read-string "Search word: " nil 'dictionary-word-history)))
1165 ;; just in case non-interactively called
1166 (unless dictionary 1234 (unless dictionary
1167 (setq dictionary dictionary-default-dictionary)) 1235 (setq dictionary dictionary-default-dictionary))
1168 (dictionary-new-search (cons word dictionary))) 1236 (if dictionary-display-definition-function
1237 (if-let ((definition (dictionary-define-word word dictionary)))
1238 (funcall dictionary-display-definition-function word dictionary definition)
1239 (user-error "No definition found for \"%s\"" word))
1240 ;; if called by pressing the button
1241 (unless word
1242 (setq word (read-string "Search word: " nil 'dictionary-word-history)))
1243 ;; just in case non-interactively called
1244 (dictionary-new-search (cons word dictionary))))
1169 1245
1170;;;###autoload 1246;;;###autoload
1171(defun dictionary-lookup-definition () 1247(defun dictionary-lookup-definition ()
@@ -1386,5 +1462,102 @@ the word at mouse click."
1386 'dictionary-separator)) 1462 'dictionary-separator))
1387 menu) 1463 menu)
1388 1464
1465(defun dictionary-define-word (word dictionary)
1466 "Return the definition of WORD in DICTIONARY, or nil if not found."
1467 (dictionary-send-command
1468 (format "define %s \"%s\"" dictionary word))
1469 (when (and (= (read (dictionary-read-reply)) 150)
1470 (= (read (dictionary-read-reply)) 151))
1471 (dictionary-read-answer)))
1472
1473(defun dictionary-match-word (word &rest _)
1474 "Return dictionary matches for WORD as a list of strings.
1475Further arguments are currently ignored."
1476 (unless (string-empty-p word)
1477 (if (string= (car dictionary--last-match) word)
1478 (cdr dictionary--last-match)
1479 (dictionary-send-command
1480 (format "match %s %s \"%s\""
1481 dictionary-default-dictionary
1482 dictionary-default-strategy
1483 word))
1484 (when (and (= (read (dictionary-read-reply)) 152))
1485 (with-temp-buffer
1486 (insert (dictionary-read-answer))
1487 (goto-char (point-min))
1488 (let ((result nil))
1489 (while (not (eobp))
1490 (search-forward " " nil t)
1491 (push (read (current-buffer)) result)
1492 (search-forward "\n" nil t))
1493 (setq result (reverse result))
1494 (setq dictionary--last-match (cons word result))
1495 result))))))
1496
1497(defun dictionary-completing-read-word (dictionary)
1498 "Prompt for a word with completion based on matches in DICTIONARY."
1499 (let* ((completion-ignore-case t)
1500 (dictionary-default-dictionary dictionary)
1501 (word-at-point (thing-at-point 'word t))
1502 (default (dictionary-match-word word-at-point)))
1503 (completing-read (format-prompt dictionary-read-word-prompt default)
1504 (external-completion-table 'dictionary-definition
1505 #'dictionary-match-word)
1506 nil t nil 'dictionary-word-history default t)))
1507
1508(defun dictionary-dictionaries ()
1509 "Return the list of dictionaries the server supports."
1510 (dictionary-send-command "show db")
1511 (when (and (= (read (dictionary-read-reply)) 110))
1512 (with-temp-buffer
1513 (insert (dictionary-read-answer))
1514 (goto-char (point-min))
1515 (let ((result '(("!" . "First matching dictionary")
1516 ("*" . "All dictionaries"))))
1517 (while (not (eobp))
1518 (push (cons (buffer-substring
1519 (search-forward "\n" nil t)
1520 (1- (search-forward " " nil t)))
1521 (read (current-buffer)))
1522 result))
1523 (reverse result)))))
1524
1525(defun dictionary-completing-read-dictionary ()
1526 "Prompt for a dictionary the server supports."
1527 (let* ((dicts (dictionary-dictionaries))
1528 (len (apply #'max (mapcar #'length (mapcar #'car dicts))))
1529 (completion-extra-properties
1530 (list :annotation-function
1531 (lambda (key)
1532 (concat (make-string (1+ (- len (length key))) ?\s)
1533 (alist-get key dicts nil nil #'string=))))))
1534 (completing-read (format-prompt "Select dictionary"
1535 dictionary-default-dictionary)
1536 dicts nil t nil nil dictionary-default-dictionary)))
1537
1538(define-button-type 'help-word
1539 :supertype 'help-xref
1540 'help-function 'dictionary-search
1541 'help-echo "mouse-2, RET: describe this word")
1542
1543(defun dictionary-display-definition-in-help-buffer (word dictionary definition)
1544 "Display DEFINITION, the definition of WORD in DICTIONARY."
1545 (let ((help-buffer-under-preparation t))
1546 (help-setup-xref (list #'dictionary-search word dictionary)
1547 (called-interactively-p 'interactive))
1548 (with-help-window (help-buffer)
1549 (with-current-buffer (help-buffer)
1550 (insert definition)
1551 ;; Buttonize references to other definitions. These appear as
1552 ;; words enclosed with curly braces.
1553 (goto-char (point-min))
1554 (while (re-search-forward (rx "{"
1555 (group-n 1 (* (not (any ?}))))
1556 "}")
1557 nil t)
1558 (help-xref-button 1 'help-word
1559 (match-string 1)
1560 dictionary))))))
1561
1389(provide 'dictionary) 1562(provide 'dictionary)
1390;;; dictionary.el ends here 1563;;; dictionary.el ends here
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 4e44dfbef03..86987807153 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -1215,7 +1215,6 @@ START, and END. Note that START and END should be markers."
1215 (add-text-properties 1215 (add-text-properties
1216 start (point) 1216 start (point)
1217 (list 'shr-url url 1217 (list 'shr-url url
1218 'shr-tab-stop t
1219 'button t 1218 'button t
1220 'category 'shr ; For button.el button buffers. 1219 'category 'shr ; For button.el button buffers.
1221 'help-echo (let ((parsed (url-generic-parse-url 1220 'help-echo (let ((parsed (url-generic-parse-url
@@ -1240,6 +1239,8 @@ START, and END. Note that START and END should be markers."
1240 ;; Make separate regions not `eq' so that they'll get 1239 ;; Make separate regions not `eq' so that they'll get
1241 ;; separate mouse highlights. 1240 ;; separate mouse highlights.
1242 'mouse-face (list 'highlight))) 1241 'mouse-face (list 'highlight)))
1242 (when (< start (point))
1243 (add-text-properties start (1+ start) '(shr-tab-stop t)))
1243 ;; Don't overwrite any keymaps that are already in the buffer (i.e., 1244 ;; Don't overwrite any keymaps that are already in the buffer (i.e.,
1244 ;; image keymaps). 1245 ;; image keymaps).
1245 (while (and start 1246 (while (and start
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index b27465a98fa..3ceb20f2634 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -4135,8 +4135,10 @@ Let-bind it when necessary.")
4135(defun tramp-handle-file-name-as-directory (file) 4135(defun tramp-handle-file-name-as-directory (file)
4136 "Like `file-name-as-directory' for Tramp files." 4136 "Like `file-name-as-directory' for Tramp files."
4137 ;; `file-name-as-directory' would be sufficient except localname is 4137 ;; `file-name-as-directory' would be sufficient except localname is
4138 ;; the empty string. 4138 ;; the empty string. Suppress adding a hop to
4139 (let ((v (tramp-dissect-file-name file t))) 4139 ;; `tramp-default-proxies-alist' due to non-expanded default values.
4140 (let ((v (tramp-dissect-file-name file t))
4141 tramp-default-proxies-alist)
4140 ;; Run the command on the localname portion only unless we are in 4142 ;; Run the command on the localname portion only unless we are in
4141 ;; completion mode. 4143 ;; completion mode.
4142 (tramp-make-tramp-file-name 4144 (tramp-make-tramp-file-name
@@ -4225,8 +4227,10 @@ Let-bind it when necessary.")
4225 "Like `file-name-directory' for Tramp files." 4227 "Like `file-name-directory' for Tramp files."
4226 ;; Everything except the last filename thing is the directory. We 4228 ;; Everything except the last filename thing is the directory. We
4227 ;; cannot apply `with-parsed-tramp-file-name', because this expands 4229 ;; cannot apply `with-parsed-tramp-file-name', because this expands
4228 ;; the remote file name parts. 4230 ;; the remote file name parts. Suppress adding a hop to
4229 (let ((v (tramp-dissect-file-name file t))) 4231 ;; `tramp-default-proxies-alist' due to non-expanded default values.
4232 (let ((v (tramp-dissect-file-name file t))
4233 tramp-default-proxies-alist)
4230 ;; Run the command on the localname portion only. If this returns 4234 ;; Run the command on the localname portion only. If this returns
4231 ;; nil, mark also the localname part of `v' as nil. 4235 ;; nil, mark also the localname part of `v' as nil.
4232 (tramp-make-tramp-file-name 4236 (tramp-make-tramp-file-name
diff --git a/lisp/pcmpl-linux.el b/lisp/pcmpl-linux.el
index 082072d87d2..589b4799c8d 100644
--- a/lisp/pcmpl-linux.el
+++ b/lisp/pcmpl-linux.el
@@ -119,7 +119,8 @@ Test is done using `equal'."
119 (with-temp-buffer 119 (with-temp-buffer
120 (apply #'call-process 120 (apply #'call-process
121 "systemctl" nil '(t nil) nil 121 "systemctl" nil '(t nil) nil
122 "list-units" "--full" "--legend=no" "--plain" args) 122 ;; "--legend=no" doesn't exist before systemd v248
123 "list-units" "--full" "--no-legend" "--plain" args)
123 (goto-char (point-min)) 124 (goto-char (point-min))
124 (let (result) 125 (let (result)
125 (while (re-search-forward (rx bol (group (+ (not space))) 126 (while (re-search-forward (rx bol (group (+ (not space)))
diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el
index d3287d936bb..ac867a1351c 100644
--- a/lisp/pixel-scroll.el
+++ b/lisp/pixel-scroll.el
@@ -290,6 +290,10 @@ This is and alternative of `scroll-down'. Scope moves upward."
290 (scroll-down 1) ; relay on robust method 290 (scroll-down 1) ; relay on robust method
291 (pixel-scroll-pixel-down amt)))))) 291 (pixel-scroll-pixel-down amt))))))
292 292
293;; isearch-scroll support
294(put 'pixel-scroll-up 'scroll-command t)
295(put 'pixel-scroll-down 'scroll-command t)
296
293(defun pixel-bob-at-top-p (amt) 297(defun pixel-bob-at-top-p (amt)
294 "Return non-nil if window-start is at beginning of the current buffer. 298 "Return non-nil if window-start is at beginning of the current buffer.
295Window must be vertically scrolled by not more than AMT pixels." 299Window must be vertically scrolled by not more than AMT pixels."
@@ -730,6 +734,9 @@ wheel."
730 (message (error-message-string '(end-of-buffer)))))))))) 734 (message (error-message-string '(end-of-buffer))))))))))
731 (mwheel-scroll event nil)))) 735 (mwheel-scroll event nil))))
732 736
737;; isearch-scroll support
738(put 'pixel-scroll-precision 'scroll-command t)
739
733(defun pixel-scroll-kinetic-state (&optional window) 740(defun pixel-scroll-kinetic-state (&optional window)
734 "Return the kinetic scroll state of WINDOW. 741 "Return the kinetic scroll state of WINDOW.
735If WINDOW is nil, return the state of the current window. 742If WINDOW is nil, return the state of the current window.
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 5c0a1443823..4b83c6733a2 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -627,6 +627,13 @@ MODE is either `c' or `cpp'."
627 627
628 (function_definition 628 (function_definition
629 declarator: (_) @c-ts-mode--fontify-declarator) 629 declarator: (_) @c-ts-mode--fontify-declarator)
630 ;; When a function definition has preproc directives in its body,
631 ;; it can't correctly parse into a function_definition. We still
632 ;; want to highlight the function_declarator correctly, hence
633 ;; this rule. See bug#63390 for more detail.
634 ((function_declarator) @c-ts-mode--fontify-declarator
635 (:pred c-ts-mode--top-level-declarator
636 @c-ts-mode--fontify-declarator))
630 637
631 (parameter_declaration 638 (parameter_declaration
632 declarator: (_) @c-ts-mode--fontify-declarator) 639 declarator: (_) @c-ts-mode--fontify-declarator)
@@ -750,6 +757,19 @@ For NODE, OVERRIDE, START, END, and ARGS, see
750 (treesit-node-start identifier) (treesit-node-end identifier) 757 (treesit-node-start identifier) (treesit-node-end identifier)
751 face override start end)))) 758 face override start end))))
752 759
760(defun c-ts-mode--top-level-declarator (node)
761 "Return non-nil if NODE is a top-level function_declarator."
762 ;; These criterion are observed in
763 ;; xterm.c:x_draw_glyphless_glyph_string_foreground on emacs-29
764 ;; branch, described in bug#63390. They might not cover all cases
765 ;; where a function_declarator is at top-level, outside of a
766 ;; function_definition. We might need to amend them as we discover
767 ;; more cases.
768 (let* ((parent (treesit-node-parent node))
769 (grandparent (treesit-node-parent parent)))
770 (and (equal (treesit-node-type parent) "ERROR")
771 (null grandparent))))
772
753(defun c-ts-mode--fontify-variable (node override start end &rest _) 773(defun c-ts-mode--fontify-variable (node override start end &rest _)
754 "Fontify an identifier node if it is a variable. 774 "Fontify an identifier node if it is a variable.
755Don't fontify if it is a function identifier. For NODE, 775Don't fontify if it is a function identifier. For NODE,
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index d21e082d0b6..66cfd3dee9e 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -10636,6 +10636,10 @@ This function might do hidden buffer changes."
10636 got-parens 10636 got-parens
10637 ;; True if there is a terminated argument list. 10637 ;; True if there is a terminated argument list.
10638 got-arglist 10638 got-arglist
10639 ;; True when `got-arglist' and the token after the end of the
10640 ;; arglist is an opening brace. Used only when we have a
10641 ;; suspected typeless function name.
10642 got-stmt-block
10639 ;; True if there is an identifier in the declarator. 10643 ;; True if there is an identifier in the declarator.
10640 got-identifier 10644 got-identifier
10641 ;; True if we find a number where an identifier was expected. 10645 ;; True if we find a number where an identifier was expected.
@@ -10788,6 +10792,10 @@ This function might do hidden buffer changes."
10788 (setq got-arglist t)) 10792 (setq got-arglist t))
10789 t) 10793 t)
10790 (when (cond 10794 (when (cond
10795 ((and (eq (char-after) ?\()
10796 (c-safe (c-forward-sexp 1) t))
10797 (when (eq (char-before) ?\))
10798 (setq got-arglist t)))
10791 ((save-match-data (looking-at "\\s(")) 10799 ((save-match-data (looking-at "\\s("))
10792 (c-safe (c-forward-sexp 1) t)) 10800 (c-safe (c-forward-sexp 1) t))
10793 ((save-match-data 10801 ((save-match-data
@@ -10802,6 +10810,11 @@ This function might do hidden buffer changes."
10802 (setq got-suffix-after-parens (match-beginning 0))) 10810 (setq got-suffix-after-parens (match-beginning 0)))
10803 (setq got-suffix t)))) 10811 (setq got-suffix t))))
10804 10812
10813 ((and got-arglist
10814 (eq (char-after) ?{))
10815 (setq got-stmt-block t)
10816 nil)
10817
10805 (t 10818 (t
10806 ;; No suffix matched. We might have matched the 10819 ;; No suffix matched. We might have matched the
10807 ;; identifier as a type and the open paren of a 10820 ;; identifier as a type and the open paren of a
@@ -10870,9 +10883,17 @@ This function might do hidden buffer changes."
10870 (not (memq context '(arglist decl)))) 10883 (not (memq context '(arglist decl))))
10871 (or (and new-style-auto 10884 (or (and new-style-auto
10872 (looking-at c-auto-ops-re)) 10885 (looking-at c-auto-ops-re))
10873 (and (or maybe-typeless backup-maybe-typeless) 10886 (and (not got-prefix)
10874 (not got-prefix) 10887 at-type
10875 at-type))) 10888 (or maybe-typeless backup-maybe-typeless
10889 ;; Do we have a (typeless) constructor?
10890 (and got-stmt-block
10891 (save-excursion
10892 (goto-char type-start)
10893 (and
10894 (looking-at c-identifier-key)
10895 (c-directly-in-class-called-p
10896 (match-string 0)))))))))
10876 ;; Have found no identifier but `c-typeless-decl-kwds' has 10897 ;; Have found no identifier but `c-typeless-decl-kwds' has
10877 ;; matched so we know we're inside a declaration. The 10898 ;; matched so we know we're inside a declaration. The
10878 ;; preceding type must be the identifier instead. 10899 ;; preceding type must be the identifier instead.
@@ -12554,7 +12575,8 @@ comment at the start of cc-engine.el for more info."
12554 (looking-at c-class-key)) 12575 (looking-at c-class-key))
12555 (goto-char (match-end 1)) 12576 (goto-char (match-end 1))
12556 (c-forward-syntactic-ws) 12577 (c-forward-syntactic-ws)
12557 (looking-at name)))))) 12578 (and (looking-at c-identifier-key)
12579 (string= (match-string 0) name)))))))
12558 12580
12559(defun c-search-uplist-for-classkey (paren-state) 12581(defun c-search-uplist-for-classkey (paren-state)
12560 ;; Check if the closest containing paren sexp is a declaration 12582 ;; Check if the closest containing paren sexp is a declaration
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 7c51778d5d4..41a5c976629 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -412,8 +412,8 @@ the buffer's value of `default-directory'."
412 412
413(defcustom project-vc-ignores nil 413(defcustom project-vc-ignores nil
414 "List of patterns to add to `project-ignores'." 414 "List of patterns to add to `project-ignores'."
415 :type '(repeat string) 415 :type '(repeat string))
416 :safe #'listp) 416;;;###autoload(put 'project-vc-ignores 'safe-local-variable #'listp)
417 417
418(defcustom project-vc-merge-submodules t 418(defcustom project-vc-merge-submodules t
419 "Non-nil to consider submodules part of the parent project. 419 "Non-nil to consider submodules part of the parent project.
@@ -422,14 +422,14 @@ After changing this variable (using Customize or .dir-locals.el)
422you might have to restart Emacs to see the effect." 422you might have to restart Emacs to see the effect."
423 :type 'boolean 423 :type 'boolean
424 :version "28.1" 424 :version "28.1"
425 :package-version '(project . "0.2.0") 425 :package-version '(project . "0.2.0"))
426 :safe #'booleanp) 426;;;###autoload(put 'project-vc-merge-submodules 'safe-local-variable #'booleanp)
427 427
428(defcustom project-vc-include-untracked t 428(defcustom project-vc-include-untracked t
429 "When non-nil, the VC-aware project backend includes untracked files." 429 "When non-nil, the VC-aware project backend includes untracked files."
430 :type 'boolean 430 :type 'boolean
431 :version "29.1" 431 :version "29.1")
432 :safe #'booleanp) 432;;;###autoload(put 'project-vc-include-untracked 'safe-local-variable #'booleanp)
433 433
434(defcustom project-vc-name nil 434(defcustom project-vc-name nil
435 "When non-nil, the name of the current VC-aware project. 435 "When non-nil, the name of the current VC-aware project.
@@ -439,8 +439,8 @@ its name, is by setting this in .dir-locals.el."
439 :type '(choice (const :tag "Default to the base name" nil) 439 :type '(choice (const :tag "Default to the base name" nil)
440 (string :tag "Custom name")) 440 (string :tag "Custom name"))
441 :version "29.1" 441 :version "29.1"
442 :package-version '(project . "0.9.0") 442 :package-version '(project . "0.9.0"))
443 :safe #'stringp) 443;;;###autoload(put 'project-vc-name 'safe-local-variable #'stringp)
444 444
445;; Not using regexps because these wouldn't work in Git pathspecs, in 445;; Not using regexps because these wouldn't work in Git pathspecs, in
446;; case we decide we need to be able to list nested projects. 446;; case we decide we need to be able to list nested projects.
@@ -467,8 +467,8 @@ In either case, their behavior will still obey the relevant
467variables, such as `project-vc-ignores' or `project-vc-name'." 467variables, such as `project-vc-ignores' or `project-vc-name'."
468 :type '(repeat string) 468 :type '(repeat string)
469 :version "29.1" 469 :version "29.1"
470 :package-version '(project . "0.9.0") 470 :package-version '(project . "0.9.0"))
471 :safe (lambda (val) (and (listp val) (cl-every #'stringp val)))) 471;;;###autoload(put 'project-vc-extra-root-markers 'safe-local-variable (lambda (val) (and (listp val) (not (memq nil (mapcar #'stringp val))))))
472 472
473;; FIXME: Using the current approach, major modes are supposed to set 473;; FIXME: Using the current approach, major modes are supposed to set
474;; this variable to a buffer-local value. So we don't have access to 474;; this variable to a buffer-local value. So we don't have access to
@@ -1476,8 +1476,8 @@ Used by `project-kill-buffers'."
1476 :type 'boolean 1476 :type 'boolean
1477 :version "29.1" 1477 :version "29.1"
1478 :group 'project 1478 :group 'project
1479 :package-version '(project . "0.8.2") 1479 :package-version '(project . "0.8.2"))
1480 :safe #'booleanp) 1480;;;###autoload(put 'project-kill-buffers-display-buffer-list 'safe-local-variable #'booleanp)
1481 1481
1482(defun project--buffer-check (buf conditions) 1482(defun project--buffer-check (buf conditions)
1483 "Check if buffer BUF matches any element of the list CONDITIONS. 1483 "Check if buffer BUF matches any element of the list CONDITIONS.
@@ -1808,11 +1808,12 @@ invoked immediately without any dispatch menu."
1808 (symbol :tag "Single command"))) 1808 (symbol :tag "Single command")))
1809 1809
1810(defcustom project-switch-use-entire-map nil 1810(defcustom project-switch-use-entire-map nil
1811 "Make `project-switch-project' use entire `project-prefix-map'. 1811 "Whether `project-switch-project' will use the entire `project-prefix-map'.
1812If nil, `project-switch-project' will only recognize commands 1812If nil, `project-switch-project' will only recognize commands
1813listed in `project-switch-commands' and signal an error when 1813listed in `project-switch-commands', and will signal an error
1814others are invoked. Otherwise, all keys in `project-prefix-map' 1814when other commands are invoked. If this is non-nil, all the
1815are legal even if they aren't listed in the dispatch menu." 1815keys in `project-prefix-map' are valid even if they aren't
1816listed in the dispatch menu produced from `project-switch-commands'."
1816 :type 'boolean 1817 :type 'boolean
1817 :group 'project 1818 :group 'project
1818 :version "28.1") 1819 :version "28.1")
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 4f57eda3cfc..8c716ffb313 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -869,18 +869,22 @@ decorators, exceptions, and assignments.")
869Which one will be chosen depends on the value of 869Which one will be chosen depends on the value of
870`font-lock-maximum-decoration'.") 870`font-lock-maximum-decoration'.")
871 871
872(defun python-font-lock-extend-region (beg end _old-len) 872(defvar font-lock-beg)
873 "Extend font-lock region given by BEG and END to statement boundaries." 873(defvar font-lock-end)
874 (save-excursion 874(defun python-font-lock-extend-region ()
875 (save-match-data 875 "Extend font-lock region to statement boundaries."
876 (goto-char beg) 876 (let ((beg font-lock-beg)
877 (python-nav-beginning-of-statement) 877 (end font-lock-end))
878 (setq beg (point)) 878 (goto-char beg)
879 (goto-char end) 879 (python-nav-beginning-of-statement)
880 (python-nav-end-of-statement) 880 (beginning-of-line)
881 (setq end (point)) 881 (when (< (point) beg)
882 (cons beg end)))) 882 (setq font-lock-beg (point)))
883 883 (goto-char end)
884 (python-nav-end-of-statement)
885 (when (< end (point))
886 (setq font-lock-end (point)))
887 (or (/= beg font-lock-beg) (/= end font-lock-end))))
884 888
885(defconst python-syntax-propertize-function 889(defconst python-syntax-propertize-function
886 (syntax-propertize-rules 890 (syntax-propertize-rules
@@ -6078,8 +6082,7 @@ point's current `syntax-ppss'."
6078 (let ((counter 1) 6082 (let ((counter 1)
6079 (indentation (current-indentation)) 6083 (indentation (current-indentation))
6080 (backward-sexp-point) 6084 (backward-sexp-point)
6081 (re (concat "[uU]?[rR]?" 6085 (re "[uU]?[rR]?[\"']"))
6082 (python-rx string-delimiter))))
6083 (when (and 6086 (when (and
6084 (not (python-info-assignment-statement-p)) 6087 (not (python-info-assignment-statement-p))
6085 (looking-at-p re) 6088 (looking-at-p re)
@@ -6100,9 +6103,7 @@ point's current `syntax-ppss'."
6100 backward-sexp-point)) 6103 backward-sexp-point))
6101 (setq last-backward-sexp-point 6104 (setq last-backward-sexp-point
6102 backward-sexp-point)) 6105 backward-sexp-point))
6103 (looking-at-p 6106 (looking-at-p re))))
6104 (concat "[uU]?[rR]?"
6105 (python-rx string-delimiter))))))
6106 ;; Previous sexp was a string, restore point. 6107 ;; Previous sexp was a string, restore point.
6107 (goto-char backward-sexp-point) 6108 (goto-char backward-sexp-point)
6108 (cl-incf counter)) 6109 (cl-incf counter))
@@ -6754,8 +6755,6 @@ implementations: `python-mode' and `python-ts-mode'."
6754 6755
6755 (setq-local prettify-symbols-alist python-prettify-symbols-alist) 6756 (setq-local prettify-symbols-alist python-prettify-symbols-alist)
6756 6757
6757 (python-skeleton-add-menu-items)
6758
6759 (make-local-variable 'python-shell-internal-buffer) 6758 (make-local-variable 'python-shell-internal-buffer)
6760 6759
6761 (add-hook 'flymake-diagnostic-functions #'python-flymake nil t)) 6760 (add-hook 'flymake-diagnostic-functions #'python-flymake nil t))
@@ -6769,9 +6768,9 @@ implementations: `python-mode' and `python-ts-mode'."
6769 `(,python-font-lock-keywords 6768 `(,python-font-lock-keywords
6770 nil nil nil nil 6769 nil nil nil nil
6771 (font-lock-syntactic-face-function 6770 (font-lock-syntactic-face-function
6772 . python-font-lock-syntactic-face-function) 6771 . python-font-lock-syntactic-face-function)))
6773 (font-lock-extend-after-change-region-function 6772 (add-hook 'font-lock-extend-region-functions
6774 . python-font-lock-extend-region))) 6773 #'python-font-lock-extend-region nil t)
6775 (setq-local syntax-propertize-function 6774 (setq-local syntax-propertize-function
6776 python-syntax-propertize-function) 6775 python-syntax-propertize-function)
6777 (setq-local imenu-create-index-function 6776 (setq-local imenu-create-index-function
@@ -6779,6 +6778,8 @@ implementations: `python-mode' and `python-ts-mode'."
6779 6778
6780 (add-hook 'which-func-functions #'python-info-current-defun nil t) 6779 (add-hook 'which-func-functions #'python-info-current-defun nil t)
6781 6780
6781 (python-skeleton-add-menu-items)
6782
6782 (when python-indent-guess-indent-offset 6783 (when python-indent-guess-indent-offset
6783 (python-indent-guess-indent-offset))) 6784 (python-indent-guess-indent-offset)))
6784 6785
@@ -6805,6 +6806,8 @@ implementations: `python-mode' and `python-ts-mode'."
6805 #'python--treesit-defun-name) 6806 #'python--treesit-defun-name)
6806 (treesit-major-mode-setup) 6807 (treesit-major-mode-setup)
6807 6808
6809 (python-skeleton-add-menu-items)
6810
6808 (when python-indent-guess-indent-offset 6811 (when python-indent-guess-indent-offset
6809 (python-indent-guess-indent-offset)) 6812 (python-indent-guess-indent-offset))
6810 6813
diff --git a/lisp/server.el b/lisp/server.el
index 608e5df3a5b..c3325e5a24c 100644
--- a/lisp/server.el
+++ b/lisp/server.el
@@ -1143,8 +1143,18 @@ The following commands are accepted by the client:
1143 (process-put proc :authenticated t) 1143 (process-put proc :authenticated t)
1144 (server-log "Authentication successful" proc)) 1144 (server-log "Authentication successful" proc))
1145 (server-log "Authentication failed" proc) 1145 (server-log "Authentication failed" proc)
1146 ;; Display the error as a message and give the user time to see
1147 ;; it, in case the error written by emacsclient to stderr is not
1148 ;; visible for some reason.
1149 (message "Authentication failed")
1150 (sit-for 2)
1146 (server-send-string 1151 (server-send-string
1147 proc (concat "-error " (server-quote-arg "Authentication failed"))) 1152 proc (concat "-error " (server-quote-arg "Authentication failed")))
1153 (unless (eq system-type 'windows-nt)
1154 (let ((terminal (process-get proc 'terminal)))
1155 ;; Only delete the terminal if it is non-nil.
1156 (when (and terminal (eq (terminal-live-p terminal) t))
1157 (delete-terminal terminal))))
1148 ;; Before calling `delete-process', give emacsclient time to 1158 ;; Before calling `delete-process', give emacsclient time to
1149 ;; receive the error string and shut down on its own. 1159 ;; receive the error string and shut down on its own.
1150 (sit-for 1) 1160 (sit-for 1)
@@ -1462,10 +1472,20 @@ The following commands are accepted by the client:
1462 1472
1463(defun server-return-error (proc err) 1473(defun server-return-error (proc err)
1464 (ignore-errors 1474 (ignore-errors
1475 ;; Display the error as a message and give the user time to see
1476 ;; it, in case the error written by emacsclient to stderr is not
1477 ;; visible for some reason.
1478 (message (error-message-string err))
1479 (sit-for 2)
1465 (server-send-string 1480 (server-send-string
1466 proc (concat "-error " (server-quote-arg 1481 proc (concat "-error " (server-quote-arg
1467 (error-message-string err)))) 1482 (error-message-string err))))
1468 (server-log (error-message-string err) proc) 1483 (server-log (error-message-string err) proc)
1484 (unless (eq system-type 'windows-nt)
1485 (let ((terminal (process-get proc 'terminal)))
1486 ;; Only delete the terminal if it is non-nil.
1487 (when (and terminal (eq (terminal-live-p terminal) t))
1488 (delete-terminal terminal))))
1469 ;; Before calling `delete-process', give emacsclient time to 1489 ;; Before calling `delete-process', give emacsclient time to
1470 ;; receive the error string and shut down on its own. 1490 ;; receive the error string and shut down on its own.
1471 (sit-for 5) 1491 (sit-for 5)
diff --git a/lisp/subr.el b/lisp/subr.el
index 73f3cd4a28e..b5c59023f8e 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3611,8 +3611,10 @@ confusing to some users.")
3611(defun use-dialog-box-p () 3611(defun use-dialog-box-p ()
3612 "Return non-nil if the current command should prompt the user via a dialog box." 3612 "Return non-nil if the current command should prompt the user via a dialog box."
3613 (and last-input-event ; not during startup 3613 (and last-input-event ; not during startup
3614 (or (featurep 'android) ; prefer dialog boxes on Android 3614 (or (consp last-nonmenu-event) ; invoked by a mouse event
3615 (consp last-nonmenu-event) ; invoked by a mouse event 3615 (and (null last-nonmenu-event)
3616 (consp last-input-event))
3617 (featurep 'android) ; Prefer dialog boxes on Android.
3616 from--tty-menu-p) ; invoked via TTY menu 3618 from--tty-menu-p) ; invoked via TTY menu
3617 use-dialog-box)) 3619 use-dialog-box))
3618 3620
@@ -3649,8 +3651,9 @@ If the user enters `recenter', `scroll-up', or `scroll-down'
3649responses, perform the requested window recentering or scrolling 3651responses, perform the requested window recentering or scrolling
3650and ask again. 3652and ask again.
3651 3653
3652Under a windowing system a dialog box will be used if `last-nonmenu-event' 3654If dialog boxes are supported, this function will use a dialog box
3653is nil and `use-dialog-box' is non-nil. 3655if `use-dialog-box' is non-nil and the last input event was produced
3656by a mouse, or by some window-system gesture, or via a menu.
3654 3657
3655By default, this function uses the minibuffer to read the key. 3658By default, this function uses the minibuffer to read the key.
3656If `y-or-n-p-use-read-key' is non-nil, `read-key' is used 3659If `y-or-n-p-use-read-key' is non-nil, `read-key' is used
@@ -4041,6 +4044,7 @@ See also `locate-user-emacs-file'.")
4041 4044
4042(defsubst buffer-narrowed-p () 4045(defsubst buffer-narrowed-p ()
4043 "Return non-nil if the current buffer is narrowed." 4046 "Return non-nil if the current buffer is narrowed."
4047 (declare (side-effect-free t))
4044 (/= (- (point-max) (point-min)) (buffer-size))) 4048 (/= (- (point-max) (point-min)) (buffer-size)))
4045 4049
4046(defmacro with-restriction (start end &rest rest) 4050(defmacro with-restriction (start end &rest rest)
@@ -4167,7 +4171,7 @@ See Info node `(elisp)Security Considerations'.
4167If the optional POSIX argument is non-nil, ARGUMENT is quoted 4171If the optional POSIX argument is non-nil, ARGUMENT is quoted
4168according to POSIX shell quoting rules, regardless of the 4172according to POSIX shell quoting rules, regardless of the
4169system's shell." 4173system's shell."
4170(cond 4174 (cond
4171 ((and (not posix) (eq system-type 'ms-dos)) 4175 ((and (not posix) (eq system-type 'ms-dos))
4172 ;; Quote using double quotes, but escape any existing quotes in 4176 ;; Quote using double quotes, but escape any existing quotes in
4173 ;; the argument with backslashes. 4177 ;; the argument with backslashes.
@@ -4299,6 +4303,7 @@ string; otherwise returna 40-character string.
4299Note that SHA-1 is not collision resistant and should not be used 4303Note that SHA-1 is not collision resistant and should not be used
4300for anything security-related. See `secure-hash' for 4304for anything security-related. See `secure-hash' for
4301alternatives." 4305alternatives."
4306 (declare (side-effect-free t))
4302 (secure-hash 'sha1 object start end binary)) 4307 (secure-hash 'sha1 object start end binary))
4303 4308
4304(defun function-get (f prop &optional autoload) 4309(defun function-get (f prop &optional autoload)
@@ -4306,6 +4311,7 @@ alternatives."
4306If AUTOLOAD is non-nil and F is autoloaded, try to load it 4311If AUTOLOAD is non-nil and F is autoloaded, try to load it
4307in the hope that it will set PROP. If AUTOLOAD is `macro', do it only 4312in the hope that it will set PROP. If AUTOLOAD is `macro', do it only
4308if it's an autoloaded macro." 4313if it's an autoloaded macro."
4314 (declare (important-return-value t))
4309 (let ((val nil)) 4315 (let ((val nil))
4310 (while (and (symbolp f) 4316 (while (and (symbolp f)
4311 (null (setq val (get f prop))) 4317 (null (setq val (get f prop)))
@@ -5261,6 +5267,7 @@ In other words, all back-references in the form `\\&' and `\\N'
5261are substituted with actual strings matched by the last search. 5267are substituted with actual strings matched by the last search.
5262Optional FIXEDCASE, LITERAL, STRING and SUBEXP have the same 5268Optional FIXEDCASE, LITERAL, STRING and SUBEXP have the same
5263meaning as for `replace-match'." 5269meaning as for `replace-match'."
5270 (declare (side-effect-free t))
5264 (let ((match (match-string 0 string))) 5271 (let ((match (match-string 0 string)))
5265 (save-match-data 5272 (save-match-data
5266 (match-data--translate (- (match-beginning 0))) 5273 (match-data--translate (- (match-beginning 0)))
@@ -5322,6 +5329,7 @@ A non-subregexp context is for example within brackets, or within a
5322repetition bounds operator `\\=\\{...\\}', or right after a `\\'. 5329repetition bounds operator `\\=\\{...\\}', or right after a `\\'.
5323If START is non-nil, it should be a position in REGEXP, smaller 5330If START is non-nil, it should be a position in REGEXP, smaller
5324than POS, and known to be in a subregexp context." 5331than POS, and known to be in a subregexp context."
5332 (declare (important-return-value t))
5325 ;; Here's one possible implementation, with the great benefit that it 5333 ;; Here's one possible implementation, with the great benefit that it
5326 ;; reuses the regexp-matcher's own parser, so it understands all the 5334 ;; reuses the regexp-matcher's own parser, so it understands all the
5327 ;; details of the syntax. A disadvantage is that it needs to match the 5335 ;; details of the syntax. A disadvantage is that it needs to match the
@@ -5403,6 +5411,7 @@ case that you wish to retain zero-length substrings when splitting on
5403whitespace, use `(split-string STRING split-string-default-separators)'. 5411whitespace, use `(split-string STRING split-string-default-separators)'.
5404 5412
5405Modifies the match data; use `save-match-data' if necessary." 5413Modifies the match data; use `save-match-data' if necessary."
5414 (declare (important-return-value t))
5406 (let* ((keep-nulls (not (if separators omit-nulls t))) 5415 (let* ((keep-nulls (not (if separators omit-nulls t)))
5407 (rexp (or separators split-string-default-separators)) 5416 (rexp (or separators split-string-default-separators))
5408 (start 0) 5417 (start 0)
@@ -5460,6 +5469,7 @@ Only some SEPARATORs will work properly.
5460 5469
5461Note that this is not intended to protect STRINGS from 5470Note that this is not intended to protect STRINGS from
5462interpretation by shells, use `shell-quote-argument' for that." 5471interpretation by shells, use `shell-quote-argument' for that."
5472 (declare (important-return-value t))
5463 (let* ((sep (or separator " ")) 5473 (let* ((sep (or separator " "))
5464 (re (concat "[\\\"]" "\\|" (regexp-quote sep)))) 5474 (re (concat "[\\\"]" "\\|" (regexp-quote sep))))
5465 (mapconcat 5475 (mapconcat
@@ -5474,6 +5484,7 @@ interpretation by shells, use `shell-quote-argument' for that."
5474It understands Emacs Lisp quoting within STRING, such that 5484It understands Emacs Lisp quoting within STRING, such that
5475 (split-string-and-unquote (combine-and-quote-strings strs)) == strs 5485 (split-string-and-unquote (combine-and-quote-strings strs)) == strs
5476The SEPARATOR regexp defaults to \"\\s-+\"." 5486The SEPARATOR regexp defaults to \"\\s-+\"."
5487 (declare (important-return-value t))
5477 (let ((sep (or separator "\\s-+")) 5488 (let ((sep (or separator "\\s-+"))
5478 (i (string-search "\"" string))) 5489 (i (string-search "\"" string)))
5479 (if (null i) 5490 (if (null i)
@@ -5541,6 +5552,7 @@ To replace only the first match (if any), make REGEXP match up to \\\\='
5541and replace a sub-expression, e.g. 5552and replace a sub-expression, e.g.
5542 (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\\\='\" \"bar\" \" foo foo\" nil nil 1) 5553 (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\\\='\" \"bar\" \" foo foo\" nil nil 1)
5543 => \" bar foo\"" 5554 => \" bar foo\""
5555 (declare (important-return-value t))
5544 5556
5545 ;; To avoid excessive consing from multiple matches in long strings, 5557 ;; To avoid excessive consing from multiple matches in long strings,
5546 ;; don't just call `replace-match' continually. Walk down the 5558 ;; don't just call `replace-match' continually. Walk down the
@@ -5896,6 +5908,7 @@ from `standard-syntax-table' otherwise."
5896(defun syntax-after (pos) 5908(defun syntax-after (pos)
5897 "Return the raw syntax descriptor for the char after POS. 5909 "Return the raw syntax descriptor for the char after POS.
5898If POS is outside the buffer's accessible portion, return nil." 5910If POS is outside the buffer's accessible portion, return nil."
5911 (declare (important-return-value t))
5899 (unless (or (< pos (point-min)) (>= pos (point-max))) 5912 (unless (or (< pos (point-min)) (>= pos (point-max)))
5900 (let ((st (if parse-sexp-lookup-properties 5913 (let ((st (if parse-sexp-lookup-properties
5901 (get-char-property pos 'syntax-table)))) 5914 (get-char-property pos 'syntax-table))))
@@ -6710,6 +6723,7 @@ Examples of version conversion:
6710 \"22.8beta3\" (22 8 -2 3) 6723 \"22.8beta3\" (22 8 -2 3)
6711 6724
6712See documentation for `version-separator' and `version-regexp-alist'." 6725See documentation for `version-separator' and `version-regexp-alist'."
6726 (declare (side-effect-free t))
6713 (unless (stringp ver) 6727 (unless (stringp ver)
6714 (error "Version must be a string")) 6728 (error "Version must be a string"))
6715 ;; Change .x.y to 0.x.y 6729 ;; Change .x.y to 0.x.y
@@ -6840,6 +6854,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version
6840string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", 6854string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
6841which is higher than \"1alpha\", which is higher than \"1snapshot\". 6855which is higher than \"1alpha\", which is higher than \"1snapshot\".
6842Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions." 6856Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
6857 (declare (side-effect-free t))
6843 (version-list-< (version-to-list v1) (version-to-list v2))) 6858 (version-list-< (version-to-list v1) (version-to-list v2)))
6844 6859
6845(defun version<= (v1 v2) 6860(defun version<= (v1 v2)
@@ -6850,6 +6865,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version
6850string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", 6865string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
6851which is higher than \"1alpha\", which is higher than \"1snapshot\". 6866which is higher than \"1alpha\", which is higher than \"1snapshot\".
6852Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions." 6867Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
6868 (declare (side-effect-free t))
6853 (version-list-<= (version-to-list v1) (version-to-list v2))) 6869 (version-list-<= (version-to-list v1) (version-to-list v2)))
6854 6870
6855(defun version= (v1 v2) 6871(defun version= (v1 v2)
@@ -6860,6 +6876,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version
6860string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", 6876string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
6861which is higher than \"1alpha\", which is higher than \"1snapshot\". 6877which is higher than \"1alpha\", which is higher than \"1snapshot\".
6862Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions." 6878Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
6879 (declare (side-effect-free t))
6863 (version-list-= (version-to-list v1) (version-to-list v2))) 6880 (version-list-= (version-to-list v1) (version-to-list v2)))
6864 6881
6865(defvar package--builtin-versions 6882(defvar package--builtin-versions
@@ -6982,6 +6999,7 @@ returned list are in the same order as in TREE.
6982 "Trim STRING of leading string matching REGEXP. 6999 "Trim STRING of leading string matching REGEXP.
6983 7000
6984REGEXP defaults to \"[ \\t\\n\\r]+\"." 7001REGEXP defaults to \"[ \\t\\n\\r]+\"."
7002 (declare (important-return-value t))
6985 (if (string-match (if regexp 7003 (if (string-match (if regexp
6986 (concat "\\`\\(?:" regexp "\\)") 7004 (concat "\\`\\(?:" regexp "\\)")
6987 "\\`[ \t\n\r]+") 7005 "\\`[ \t\n\r]+")
@@ -7004,6 +7022,7 @@ REGEXP defaults to \"[ \\t\\n\\r]+\"."
7004 "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. 7022 "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT.
7005 7023
7006TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"." 7024TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"."
7025 (declare (important-return-value t))
7007 (string-trim-left (string-trim-right string trim-right) trim-left)) 7026 (string-trim-left (string-trim-right string trim-right) trim-left))
7008 7027
7009;; The initial anchoring is for better performance in searching matches. 7028;; The initial anchoring is for better performance in searching matches.
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 2471a90c8ad..08935a1b287 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -1408,8 +1408,8 @@ Negative TAB-NUMBER counts tabs from the end of the tab bar."
1408 1408
1409 (ws 1409 (ws
1410 ;; `window-state-put' fails when called in the minibuffer 1410 ;; `window-state-put' fails when called in the minibuffer
1411 (when (minibuffer-selected-window) 1411 (when (window-minibuffer-p)
1412 (select-window (minibuffer-selected-window))) 1412 (select-window (get-mru-window)))
1413 (window-state-put ws nil 'safe))) 1413 (window-state-put ws nil 'safe)))
1414 1414
1415 ;; Select the minibuffer when it was active before switching tabs 1415 ;; Select the minibuffer when it was active before switching tabs
@@ -1420,8 +1420,8 @@ Negative TAB-NUMBER counts tabs from the end of the tab bar."
1420 ;; another tab, then after going back to the first tab, it has 1420 ;; another tab, then after going back to the first tab, it has
1421 ;; such inconsistent state that the current buffer is the minibuffer, 1421 ;; such inconsistent state that the current buffer is the minibuffer,
1422 ;; but its window is not active. So try to undo this mess. 1422 ;; but its window is not active. So try to undo this mess.
1423 (when (and (minibufferp) (not (active-minibuffer-window))) 1423 (when (and (window-minibuffer-p) (not (active-minibuffer-window)))
1424 (other-window 1)) 1424 (select-window (get-mru-window)))
1425 1425
1426 (when tab-bar-history-mode 1426 (when tab-bar-history-mode
1427 (setq tab-bar-history-omit t)) 1427 (setq tab-bar-history-omit t))
@@ -1644,8 +1644,8 @@ After the tab is created, the hooks in
1644 1644
1645 (when tab-bar-new-tab-choice 1645 (when tab-bar-new-tab-choice
1646 ;; Handle the case when it's called in the active minibuffer. 1646 ;; Handle the case when it's called in the active minibuffer.
1647 (when (minibuffer-selected-window) 1647 (when (window-minibuffer-p)
1648 (select-window (minibuffer-selected-window))) 1648 (select-window (get-mru-window)))
1649 (let ((ignore-window-parameters t) 1649 (let ((ignore-window-parameters t)
1650 (window--sides-inhibit-check t)) 1650 (window--sides-inhibit-check t))
1651 (if (eq tab-bar-new-tab-choice 'clone) 1651 (if (eq tab-bar-new-tab-choice 'clone)
@@ -1662,7 +1662,8 @@ After the tab is created, the hooks in
1662 (window-state-put (window-state-get))) 1662 (window-state-put (window-state-get)))
1663 ;; Create a new window to get rid of old window parameters 1663 ;; Create a new window to get rid of old window parameters
1664 ;; (e.g. prev/next buffers) of old window. 1664 ;; (e.g. prev/next buffers) of old window.
1665 (split-window) (delete-window)))) 1665 (split-window nil window-safe-min-width t)
1666 (delete-window))))
1666 1667
1667 (let ((buffer 1668 (let ((buffer
1668 (if (and (functionp tab-bar-new-tab-choice) 1669 (if (and (functionp tab-bar-new-tab-choice)
diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el
index 70057a6aac7..d83660f9d79 100644
--- a/lisp/vc/vc-annotate.el
+++ b/lisp/vc/vc-annotate.el
@@ -330,7 +330,7 @@ cover the range from the oldest annotation to the newest."
330 ["Show changeset diff of revision at line" 330 ["Show changeset diff of revision at line"
331 vc-annotate-show-changeset-diff-revision-at-line 331 vc-annotate-show-changeset-diff-revision-at-line
332 :enable 332 :enable
333 (eq 'repository (vc-call-backend ,vc-annotate-backend 'revision-granularity)) 333 (eq 'repository (vc-call-backend vc-annotate-backend 'revision-granularity))
334 :help "Visit the diff of the revision at line from its previous revision"] 334 :help "Visit the diff of the revision at line from its previous revision"]
335 ["Visit revision at line" vc-annotate-find-revision-at-line 335 ["Visit revision at line" vc-annotate-find-revision-at-line
336 :help "Visit the revision identified in the current line"])) 336 :help "Visit the revision identified in the current line"]))
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index e242d1e48e2..00a7659209e 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -897,6 +897,15 @@ In the latter case, VC mode is deactivated for this buffer."
897 (bindings--define-key map [vc-create-tag] 897 (bindings--define-key map [vc-create-tag]
898 '(menu-item "Create Tag" vc-create-tag 898 '(menu-item "Create Tag" vc-create-tag
899 :help "Create version tag")) 899 :help "Create version tag"))
900 (bindings--define-key map [vc-print-branch-log]
901 '(menu-item "Show Branch History..." vc-print-branch-log
902 :help "List the change log for another branch"))
903 (bindings--define-key map [vc-switch-branch]
904 '(menu-item "Switch Branch..." vc-switch-branch
905 :help "Switch to another branch"))
906 (bindings--define-key map [vc-create-branch]
907 '(menu-item "Create Branch..." vc-create-branch
908 :help "Make a new branch"))
900 (bindings--define-key map [separator1] menu-bar-separator) 909 (bindings--define-key map [separator1] menu-bar-separator)
901 (bindings--define-key map [vc-annotate] 910 (bindings--define-key map [vc-annotate]
902 '(menu-item "Annotate" vc-annotate 911 '(menu-item "Annotate" vc-annotate
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 91d3f6f70d3..a93d85caedb 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -2504,9 +2504,13 @@ Otherwise, return nil."
2504(defun vc-create-tag (dir name branchp) 2504(defun vc-create-tag (dir name branchp)
2505 "Descending recursively from DIR, make a tag called NAME. 2505 "Descending recursively from DIR, make a tag called NAME.
2506For each registered file, the working revision becomes part of 2506For each registered file, the working revision becomes part of
2507the named configuration. If the prefix argument BRANCHP is 2507the configuration identified by the tag.
2508given, the tag is made as a new branch and the files are 2508If BRANCHP is non-nil (interactively, the prefix argument), the
2509checked out in that new branch." 2509tag NAME is a new branch, and the files are checked out and
2510updated to reflect their revisions on that branch.
2511In interactive use, DIR is `default-directory' for repository-granular
2512VCSes (all the modern decentralized VCSes belong to this group),
2513otherwise the command will prompt for DIR."
2510 (interactive 2514 (interactive
2511 (let ((granularity 2515 (let ((granularity
2512 (vc-call-backend (vc-responsible-backend default-directory) 2516 (vc-call-backend (vc-responsible-backend default-directory)
@@ -2529,9 +2533,23 @@ checked out in that new branch."
2529 2533
2530;;;###autoload 2534;;;###autoload
2531(defun vc-create-branch (dir name) 2535(defun vc-create-branch (dir name)
2532 "Descending recursively from DIR, make a branch called NAME. 2536 "Make a branch called NAME in directory DIR.
2533After a new branch is made, the files are checked out in that new branch. 2537After making the new branch, check out the branch, i.e. update the
2534Uses `vc-create-tag' with the non-nil arg `branchp'." 2538files in the tree to their revisions on the branch.
2539
2540Interactively, prompt for the NAME of the branch.
2541
2542With VCSes that maintain version information per file, this command also
2543prompts for the directory DIR whose files, recursively, will be tagged
2544with the NAME of new branch. For VCSes that maintain version
2545information for the entire repository (all the modern decentralized
2546VCSes belong to this group), DIR is always the `default-directory'.
2547
2548Finally, this command might prompt for the branch or tag from which to
2549start (\"fork\") the new branch, with completion candidates including
2550all the known branches and tags in the repository.
2551
2552This command invokes `vc-create-tag' with the non-nil BRANCHP argument."
2535 (interactive 2553 (interactive
2536 (let ((granularity 2554 (let ((granularity
2537 (vc-call-backend (vc-responsible-backend default-directory) 2555 (vc-call-backend (vc-responsible-backend default-directory)
@@ -2545,17 +2563,17 @@ Uses `vc-create-tag' with the non-nil arg `branchp'."
2545 2563
2546;;;###autoload 2564;;;###autoload
2547(defun vc-retrieve-tag (dir name &optional branchp) 2565(defun vc-retrieve-tag (dir name &optional branchp)
2548 "For each file in or below DIR, retrieve their tagged version NAME. 2566 "For each file in or below DIR, retrieve their version identified by tag NAME.
2549NAME can name a branch, in which case this command will switch to the 2567NAME can name a branch, in which case this command will switch to the
2550named branch in the directory DIR. 2568named branch in the directory DIR.
2551Interactively, prompt for DIR only for VCS that works at file level; 2569Interactively, prompt for DIR only for VCS that works at file level;
2552otherwise use the repository root of the current buffer. 2570otherwise use the root directory of the current buffer's VC tree.
2553If NAME is empty, it refers to the latest revisions of the current branch. 2571If NAME is empty, it refers to the latest revisions of the current branch.
2554If locking is used for the files in DIR, then there must not be any 2572If locking is used for the files in DIR, then there must not be any
2555locked files at or below DIR (but if NAME is empty, locked files are 2573locked files at or below DIR (but if NAME is empty, locked files are
2556allowed and simply skipped). 2574allowed and simply skipped).
2557If the prefix argument BRANCHP is given, switch the branch 2575If BRANCHP is non-nil (interactively, the prefix argument), switch to the
2558and check out the files in that branch. 2576branch and check out and update the files to their version on that branch.
2559This function runs the hook `vc-retrieve-tag-hook' when finished." 2577This function runs the hook `vc-retrieve-tag-hook' when finished."
2560 (interactive 2578 (interactive
2561 (let* ((granularity 2579 (let* ((granularity
@@ -2596,7 +2614,12 @@ This function runs the hook `vc-retrieve-tag-hook' when finished."
2596;;;###autoload 2614;;;###autoload
2597(defun vc-switch-branch (dir name) 2615(defun vc-switch-branch (dir name)
2598 "Switch to the branch NAME in the directory DIR. 2616 "Switch to the branch NAME in the directory DIR.
2599If NAME is empty, it refers to the latest revisions of the current branch. 2617If NAME is empty, it refers to the latest revision of the current branch.
2618Interactively, prompt for DIR only for VCS that works at file level;
2619otherwise use the root directory of the current buffer's VC tree.
2620Interactively, prompt for the NAME of the branch.
2621After switching to the branch, check out and update the files to their
2622version on that branch.
2600Uses `vc-retrieve-tag' with the non-nil arg `branchp'." 2623Uses `vc-retrieve-tag' with the non-nil arg `branchp'."
2601 (interactive 2624 (interactive
2602 (let* ((granularity 2625 (let* ((granularity
@@ -2851,7 +2874,8 @@ with its diffs (if the underlying VCS backend supports that)."
2851 2874
2852;;;###autoload 2875;;;###autoload
2853(defun vc-print-branch-log (branch) 2876(defun vc-print-branch-log (branch)
2854 "Show the change log for BRANCH root in a window." 2877 "Show the change log for BRANCH in another window.
2878The command prompts for the branch whose change log to show."
2855 (interactive 2879 (interactive
2856 (let* ((backend (vc-responsible-backend default-directory)) 2880 (let* ((backend (vc-responsible-backend default-directory))
2857 (rootdir (vc-call-backend backend 'root default-directory))) 2881 (rootdir (vc-call-backend backend 'root default-directory)))
diff --git a/lisp/wdired.el b/lisp/wdired.el
index 5572dcb32f3..9952da71078 100644
--- a/lisp/wdired.el
+++ b/lisp/wdired.el
@@ -470,6 +470,9 @@ non-nil means return old filename."
470 (insert wdired--old-content) 470 (insert wdired--old-content)
471 (goto-char wdired--old-point)) 471 (goto-char wdired--old-point))
472 (wdired-change-to-dired-mode) 472 (wdired-change-to-dired-mode)
473 ;; Make sure the display is in synch, and all the variables are set
474 ;; correctly.
475 (dired-revert)
473 (set-buffer-modified-p nil) 476 (set-buffer-modified-p nil)
474 (setq buffer-undo-list nil) 477 (setq buffer-undo-list nil)
475 (message "Changes aborted")) 478 (message "Changes aborted"))
diff --git a/lisp/window.el b/lisp/window.el
index aa7520f30fa..ab7dd5ced12 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -6391,7 +6391,7 @@ windows can get as small as `window-safe-min-height' and
6391 (selected-window))) 6391 (selected-window)))
6392 (delete-other-windows-internal window root) 6392 (delete-other-windows-internal window root)
6393 ;; Create a new window to replace the existing one. 6393 ;; Create a new window to replace the existing one.
6394 (setq window (prog1 (split-window window) 6394 (setq window (prog1 (split-window window window-safe-min-width t)
6395 (delete-window window))))) 6395 (delete-window window)))))
6396 6396
6397 (set-window-dedicated-p window nil) 6397 (set-window-dedicated-p window nil)
diff --git a/src/fns.c b/src/fns.c
index 1ad6eb57de4..d7b2e7908b6 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3213,16 +3213,21 @@ If the `use-short-answers' variable is non-nil, instead of asking for
3213\"yes\" or \"no\", this function will ask for \"y\" or \"n\" (and 3213\"yes\" or \"no\", this function will ask for \"y\" or \"n\" (and
3214ignore the value of `yes-or-no-prompt'). 3214ignore the value of `yes-or-no-prompt').
3215 3215
3216If dialog boxes are supported, a dialog box will be used 3216If dialog boxes are supported, this function will use a dialog box
3217if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) 3217if `use-dialog-box' is non-nil and the last input event was produced
3218by a mouse, or by some window-system gesture, or via a menu. */)
3218 (Lisp_Object prompt) 3219 (Lisp_Object prompt)
3219{ 3220{
3220 Lisp_Object ans; 3221 Lisp_Object ans, val;
3221 3222
3222 CHECK_STRING (prompt); 3223 CHECK_STRING (prompt);
3223 3224
3224 if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) 3225 if (!NILP (last_input_event)
3225 && use_dialog_box && ! NILP (last_input_event)) 3226 && (CONSP (last_nonmenu_event)
3227 || (NILP (last_nonmenu_event) && CONSP (last_input_event))
3228 || (val = find_symbol_value (Qfrom__tty_menu_p),
3229 (!NILP (val) && !EQ (val, Qunbound))))
3230 && use_dialog_box)
3226 { 3231 {
3227 Lisp_Object pane, menu, obj; 3232 Lisp_Object pane, menu, obj;
3228 redisplay_preserve_echo_area (4); 3233 redisplay_preserve_echo_area (4);
@@ -6401,4 +6406,5 @@ For best results this should end in a space. */);
6401 defsubr (&Sbuffer_line_statistics); 6406 defsubr (&Sbuffer_line_statistics);
6402 6407
6403 DEFSYM (Qreal_this_command, "real-this-command"); 6408 DEFSYM (Qreal_this_command, "real-this-command");
6409 DEFSYM (Qfrom__tty_menu_p, "from--tty-menu-p");
6404} 6410}
diff --git a/src/lread.c b/src/lread.c
index 3ac5d43a839..43fa23003ca 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -3646,8 +3646,9 @@ read_bool_vector (Lisp_Object readcharfun)
3646} 3646}
3647 3647
3648/* Skip (and optionally remember) a lazily-loaded string 3648/* Skip (and optionally remember) a lazily-loaded string
3649 preceded by "#@". */ 3649 preceded by "#@". Return true if this was a normal skip,
3650static void 3650 false if we read #@00 (which skips to EOB). */
3651static bool
3651skip_lazy_string (Lisp_Object readcharfun) 3652skip_lazy_string (Lisp_Object readcharfun)
3652{ 3653{
3653 ptrdiff_t nskip = 0; 3654 ptrdiff_t nskip = 0;
@@ -3673,9 +3674,9 @@ skip_lazy_string (Lisp_Object readcharfun)
3673 digits++; 3674 digits++;
3674 if (digits == 2 && nskip == 0) 3675 if (digits == 2 && nskip == 0)
3675 { 3676 {
3676 /* #@00 means "skip to end" */ 3677 /* #@00 means "read nil and skip to end" */
3677 skip_dyn_eof (readcharfun); 3678 skip_dyn_eof (readcharfun);
3678 return; 3679 return false;
3679 } 3680 }
3680 } 3681 }
3681 3682
@@ -3722,6 +3723,8 @@ skip_lazy_string (Lisp_Object readcharfun)
3722 else 3723 else
3723 /* Skip that many bytes. */ 3724 /* Skip that many bytes. */
3724 skip_dyn_bytes (readcharfun, nskip); 3725 skip_dyn_bytes (readcharfun, nskip);
3726
3727 return true;
3725} 3728}
3726 3729
3727/* Given a lazy-loaded string designator VAL, return the actual string. 3730/* Given a lazy-loaded string designator VAL, return the actual string.
@@ -4179,8 +4182,10 @@ read0 (Lisp_Object readcharfun, bool locate_syms)
4179 /* #@NUMBER is used to skip NUMBER following bytes. 4182 /* #@NUMBER is used to skip NUMBER following bytes.
4180 That's used in .elc files to skip over doc strings 4183 That's used in .elc files to skip over doc strings
4181 and function definitions that can be loaded lazily. */ 4184 and function definitions that can be loaded lazily. */
4182 skip_lazy_string (readcharfun); 4185 if (skip_lazy_string (readcharfun))
4183 goto read_obj; 4186 goto read_obj;
4187 obj = Qnil; /* #@00 skips to EOB and yields nil. */
4188 break;
4184 4189
4185 case '$': 4190 case '$':
4186 /* #$ -- reference to lazy-loaded string */ 4191 /* #$ -- reference to lazy-loaded string */
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index b8c626d81d8..91e4d828f51 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -376,6 +376,13 @@ mark_pgtkterm (void)
376 for (i = 0; i < n; i++) 376 for (i = 0; i < n; i++)
377 { 377 {
378 union buffered_input_event *ev = &evq->q[i]; 378 union buffered_input_event *ev = &evq->q[i];
379
380 /* Selection requests don't have Lisp object members. */
381
382 if (ev->ie.kind == SELECTION_REQUEST_EVENT
383 || ev->ie.kind == SELECTION_CLEAR_EVENT)
384 continue;
385
379 mark_object (ev->ie.x); 386 mark_object (ev->ie.x);
380 mark_object (ev->ie.y); 387 mark_object (ev->ie.y);
381 mark_object (ev->ie.frame_or_window); 388 mark_object (ev->ie.frame_or_window);
diff --git a/src/sqlite.c b/src/sqlite.c
index 0361514766a..fd528f2b0d5 100644
--- a/src/sqlite.c
+++ b/src/sqlite.c
@@ -23,6 +23,8 @@ YOSHIDA <syohex@gmail.com>, which can be found at:
23 https://github.com/syohex/emacs-sqlite3 */ 23 https://github.com/syohex/emacs-sqlite3 */
24 24
25#include <config.h> 25#include <config.h>
26
27#include <c-strcase.h>
26#include "lisp.h" 28#include "lisp.h"
27#include "coding.h" 29#include "coding.h"
28 30
@@ -30,6 +32,17 @@ YOSHIDA <syohex@gmail.com>, which can be found at:
30 32
31#include <sqlite3.h> 33#include <sqlite3.h>
32 34
35/* Support for loading SQLite extensions requires the ability to
36 enable and disable loading of extensions (by default this is
37 disabled, and we want to keep it that way). The required macro is
38 available since SQLite 3.13. */
39# if defined HAVE_SQLITE3_LOAD_EXTENSION && \
40 defined SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
41# define HAVE_LOAD_EXTENSION 1
42# else
43# define HAVE_LOAD_EXTENSION 0
44# endif
45
33#ifdef WINDOWSNT 46#ifdef WINDOWSNT
34 47
35# include <windows.h> 48# include <windows.h>
@@ -75,11 +88,14 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_exec,
75DEF_DLL_FN (SQLITE_API int, sqlite3_prepare_v2, 88DEF_DLL_FN (SQLITE_API int, sqlite3_prepare_v2,
76 (sqlite3*, const char*, int, sqlite3_stmt**, const char**)); 89 (sqlite3*, const char*, int, sqlite3_stmt**, const char**));
77 90
78# ifdef HAVE_SQLITE3_LOAD_EXTENSION 91# if HAVE_LOAD_EXTENSION
79DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension, 92DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension,
80 (sqlite3*, const char*, const char*, char**)); 93 (sqlite3*, const char*, const char*, char**));
81# undef sqlite3_load_extension 94# undef sqlite3_load_extension
82# define sqlite3_load_extension fn_sqlite3_load_extension 95# define sqlite3_load_extension fn_sqlite3_load_extension
96DEF_DLL_FN (SQLITE_API int, sqlite3_db_config, (sqlite3*, int, ...));
97# undef sqlite3_db_config
98# define sqlite3_db_config fn_sqlite3_db_config
83# endif 99# endif
84 100
85# undef sqlite3_finalize 101# undef sqlite3_finalize
@@ -170,8 +186,9 @@ load_dll_functions (HMODULE library)
170 LOAD_DLL_FN (library, sqlite3_column_text); 186 LOAD_DLL_FN (library, sqlite3_column_text);
171 LOAD_DLL_FN (library, sqlite3_column_name); 187 LOAD_DLL_FN (library, sqlite3_column_name);
172 LOAD_DLL_FN (library, sqlite3_exec); 188 LOAD_DLL_FN (library, sqlite3_exec);
173# ifdef HAVE_SQLITE3_LOAD_EXTENSION 189# if HAVE_LOAD_EXTENSION
174 LOAD_DLL_FN (library, sqlite3_load_extension); 190 LOAD_DLL_FN (library, sqlite3_load_extension);
191 LOAD_DLL_FN (library, sqlite3_db_config);
175# endif 192# endif
176 LOAD_DLL_FN (library, sqlite3_prepare_v2); 193 LOAD_DLL_FN (library, sqlite3_prepare_v2);
177 return true; 194 return true;
@@ -669,7 +686,7 @@ DEFUN ("sqlite-pragma", Fsqlite_pragma, Ssqlite_pragma, 2, 2, 0,
669 SSDATA (concat2 (build_string ("PRAGMA "), pragma))); 686 SSDATA (concat2 (build_string ("PRAGMA "), pragma)));
670} 687}
671 688
672#ifdef HAVE_SQLITE3_LOAD_EXTENSION 689#if HAVE_LOAD_EXTENSION
673DEFUN ("sqlite-load-extension", Fsqlite_load_extension, 690DEFUN ("sqlite-load-extension", Fsqlite_load_extension,
674 Ssqlite_load_extension, 2, 2, 0, 691 Ssqlite_load_extension, 2, 2, 0,
675 doc: /* Load an SQlite MODULE into DB. 692 doc: /* Load an SQlite MODULE into DB.
@@ -684,9 +701,28 @@ Only modules on Emacs' list of allowed modules can be loaded. */)
684 CHECK_STRING (module); 701 CHECK_STRING (module);
685 702
686 /* Add names of useful and free modules here. */ 703 /* Add names of useful and free modules here. */
687 const char *allowlist[3] = { "pcre", "csvtable", NULL }; 704 const char *allowlist[] = {
705 "base64",
706 "cksumvfs",
707 "compress",
708 "csv",
709 "csvtable",
710 "fts3",
711 "icu",
712 "pcre",
713 "percentile",
714 "regexp",
715 "rot13",
716 "rtree",
717 "sha1",
718 "uuid",
719 "vfslog",
720 "zipfile",
721 NULL
722 };
688 char *name = SSDATA (Ffile_name_nondirectory (module)); 723 char *name = SSDATA (Ffile_name_nondirectory (module));
689 /* Possibly skip past a common prefix. */ 724 /* Possibly skip past a common prefix (libsqlite3_mod_ is used by
725 Debian, see https://packages.debian.org/source/sid/sqliteodbc). */
690 const char *prefix = "libsqlite3_mod_"; 726 const char *prefix = "libsqlite3_mod_";
691 if (!strncmp (name, prefix, strlen (prefix))) 727 if (!strncmp (name, prefix, strlen (prefix)))
692 name += strlen (prefix); 728 name += strlen (prefix);
@@ -694,10 +730,12 @@ Only modules on Emacs' list of allowed modules can be loaded. */)
694 bool do_allow = false; 730 bool do_allow = false;
695 for (const char **allow = allowlist; *allow; allow++) 731 for (const char **allow = allowlist; *allow; allow++)
696 { 732 {
697 if (strlen (*allow) < strlen (name) 733 ptrdiff_t allow_len = strlen (*allow);
698 && !strncmp (*allow, name, strlen (*allow)) 734 if (allow_len < strlen (name)
699 && (!strcmp (name + strlen (*allow), ".so") 735 && !strncmp (*allow, name, allow_len)
700 || !strcmp (name + strlen (*allow), ".DLL"))) 736 && (!strcmp (name + allow_len, ".so")
737 ||!strcmp (name + allow_len, ".dylib")
738 || !strcasecmp (name + allow_len, ".dll")))
701 { 739 {
702 do_allow = true; 740 do_allow = true;
703 break; 741 break;
@@ -707,15 +745,25 @@ Only modules on Emacs' list of allowed modules can be loaded. */)
707 if (!do_allow) 745 if (!do_allow)
708 xsignal1 (Qsqlite_error, build_string ("Module name not on allowlist")); 746 xsignal1 (Qsqlite_error, build_string ("Module name not on allowlist"));
709 747
710 int result = sqlite3_load_extension 748 /* Expand all Lisp data explicitly, so as to avoid signaling an
711 (XSQLITE (db)->db, 749 error while extension loading is enabled -- we don't want to
712 SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))), 750 "leak" this outside this function. */
713 NULL, NULL); 751 sqlite3 *sdb = XSQLITE (db)->db;
714 if (result == SQLITE_OK) 752 char *ext_fn = SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil)));
715 return Qt; 753 /* Temporarily enable loading extensions via the C API. */
754 int result = sqlite3_db_config (sdb, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1,
755 NULL);
756 if (result == SQLITE_OK)
757 {
758 result = sqlite3_load_extension (sdb, ext_fn, NULL, NULL);
759 /* Disable loading extensions via C API. */
760 sqlite3_db_config (sdb, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 0, NULL);
761 if (result == SQLITE_OK)
762 return Qt;
763 }
716 return Qnil; 764 return Qnil;
717} 765}
718#endif /* HAVE_SQLITE3_LOAD_EXTENSION */ 766#endif /* HAVE_LOAD_EXTENSION */
719 767
720DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0, 768DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0,
721 doc: /* Return the next result set from SET. 769 doc: /* Return the next result set from SET.
@@ -825,7 +873,7 @@ syms_of_sqlite (void)
825 defsubr (&Ssqlite_commit); 873 defsubr (&Ssqlite_commit);
826 defsubr (&Ssqlite_rollback); 874 defsubr (&Ssqlite_rollback);
827 defsubr (&Ssqlite_pragma); 875 defsubr (&Ssqlite_pragma);
828#ifdef HAVE_SQLITE3_LOAD_EXTENSION 876#if HAVE_LOAD_EXTENSION
829 defsubr (&Ssqlite_load_extension); 877 defsubr (&Ssqlite_load_extension);
830#endif 878#endif
831 defsubr (&Ssqlite_next); 879 defsubr (&Ssqlite_next);
diff --git a/src/xdisp.c b/src/xdisp.c
index 09f2f31816e..543dcba5fee 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -21186,8 +21186,10 @@ try_window_reusing_current_matrix (struct window *w)
21186 pt_row = first_row_to_display; 21186 pt_row = first_row_to_display;
21187 } 21187 }
21188 21188
21189 if (first_row_to_display->y >= yb)
21190 return false;
21191
21189 /* Start displaying at the start of first_row_to_display. */ 21192 /* Start displaying at the start of first_row_to_display. */
21190 eassert (first_row_to_display->y < yb);
21191 init_to_row_start (&it, w, first_row_to_display); 21193 init_to_row_start (&it, w, first_row_to_display);
21192 21194
21193 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix) 21195 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el
index 0016fb586b7..113b4ec12a8 100644
--- a/test/lisp/emacs-lisp/package-tests.el
+++ b/test/lisp/emacs-lisp/package-tests.el
@@ -219,9 +219,14 @@ Must called from within a `tar-mode' buffer."
219 219
220(ert-deftest package-test-desc-from-buffer () 220(ert-deftest package-test-desc-from-buffer ()
221 "Parse an elisp buffer to get a `package-desc' object." 221 "Parse an elisp buffer to get a `package-desc' object."
222 (with-package-test (:basedir (ert-resource-directory) :file "simple-single-1.3.el") 222 (with-package-test (:basedir (ert-resource-directory)
223 (should (package-test--compatible-p 223 :file "simple-single-1.3.el")
224 (package-buffer-info) simple-single-desc 'kind))) 224 (let ((pi (package-buffer-info)))
225 (should (package-test--compatible-p pi simple-single-desc 'kind))
226 ;; The terminating line is not mandatory any more.
227 (re-search-forward "^;;; .* ends here")
228 (delete-region (match-beginning 0) (point-max))
229 (should (equal (package-buffer-info) pi))))
225 (with-package-test (:basedir (ert-resource-directory) :file "simple-depend-1.0.el") 230 (with-package-test (:basedir (ert-resource-directory) :file "simple-depend-1.0.el")
226 (should (package-test--compatible-p 231 (should (package-test--compatible-p
227 (package-buffer-info) simple-depend-desc 'kind))) 232 (package-buffer-info) simple-depend-desc 'kind)))
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 60b11d572cf..b916232c4be 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -729,6 +729,7 @@ u\"\\n\""
729 (845 . font-lock-string-face) (886)))) 729 (845 . font-lock-string-face) (886))))
730 730
731(ert-deftest python-font-lock-escape-sequence-bytes-newline () 731(ert-deftest python-font-lock-escape-sequence-bytes-newline ()
732 :expected-result :failed
732 (python-tests-assert-faces 733 (python-tests-assert-faces
733 "b'\\n' 734 "b'\\n'
734b\"\\n\"" 735b\"\\n\""
@@ -741,6 +742,7 @@ b\"\\n\""
741 (11 . font-lock-doc-face)))) 742 (11 . font-lock-doc-face))))
742 743
743(ert-deftest python-font-lock-escape-sequence-hex-octal () 744(ert-deftest python-font-lock-escape-sequence-hex-octal ()
745 :expected-result :failed
744 (python-tests-assert-faces 746 (python-tests-assert-faces
745 "b'\\x12 \\777 \\1\\23' 747 "b'\\x12 \\777 \\1\\23'
746'\\x12 \\777 \\1\\23'" 748'\\x12 \\777 \\1\\23'"
@@ -761,6 +763,7 @@ b\"\\n\""
761 (36 . font-lock-doc-face)))) 763 (36 . font-lock-doc-face))))
762 764
763(ert-deftest python-font-lock-escape-sequence-unicode () 765(ert-deftest python-font-lock-escape-sequence-unicode ()
766 :expected-result :failed
764 (python-tests-assert-faces 767 (python-tests-assert-faces
765 "b'\\u1234 \\U00010348 \\N{Plus-Minus Sign}' 768 "b'\\u1234 \\U00010348 \\N{Plus-Minus Sign}'
766'\\u1234 \\U00010348 \\N{Plus-Minus Sign}'" 769'\\u1234 \\U00010348 \\N{Plus-Minus Sign}'"
@@ -775,6 +778,7 @@ b\"\\n\""
775 (80 . font-lock-doc-face)))) 778 (80 . font-lock-doc-face))))
776 779
777(ert-deftest python-font-lock-raw-escape-sequence () 780(ert-deftest python-font-lock-raw-escape-sequence ()
781 :expected-result :failed
778 (python-tests-assert-faces 782 (python-tests-assert-faces
779 "rb'\\x12 \123 \\n' 783 "rb'\\x12 \123 \\n'
780r'\\x12 \123 \\n \\u1234 \\U00010348 \\N{Plus-Minus Sign}'" 784r'\\x12 \123 \\n \\u1234 \\U00010348 \\N{Plus-Minus Sign}'"
@@ -6710,6 +6714,18 @@ class Class:
6710 (python-tests-look-at "'''Not a method docstring.'''") 6714 (python-tests-look-at "'''Not a method docstring.'''")
6711 (should (not (python-info-docstring-p))))) 6715 (should (not (python-info-docstring-p)))))
6712 6716
6717(ert-deftest python-info-docstring-p-7 ()
6718 "Test string in a dictionary."
6719 (python-tests-with-temp-buffer
6720 "
6721{'Not a docstring': 1}
6722'Also not a docstring'
6723"
6724 (python-tests-look-at "Not a docstring")
6725 (should-not (python-info-docstring-p))
6726 (python-tests-look-at "Also not a docstring")
6727 (should-not (python-info-docstring-p))))
6728
6713(ert-deftest python-info-triple-quoted-string-p-1 () 6729(ert-deftest python-info-triple-quoted-string-p-1 ()
6714 "Test triple quoted string." 6730 "Test triple quoted string."
6715 (python-tests-with-temp-buffer 6731 (python-tests-with-temp-buffer
diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el
index fc00204ce7b..eae4893ee1b 100644
--- a/test/src/lread-tests.el
+++ b/test/src/lread-tests.el
@@ -360,4 +360,20 @@ literals (Bug#20852)."
360 (should (byte-code-function-p f)) 360 (should (byte-code-function-p f))
361 (should (equal (aref f 4) "My little\ndoc string\nhere")))))) 361 (should (equal (aref f 4) "My little\ndoc string\nhere"))))))
362 362
363(ert-deftest lread-skip-to-eof ()
364 ;; Check the special #@00 syntax that, for compatibility, reads as
365 ;; nil while absorbing the remainder of the input.
366 (with-temp-buffer
367 (insert "#@00 and the rest\n"
368 "should be ignored) entirely\n")
369 (goto-char (point-min))
370 (should (equal (read (current-buffer)) nil))
371 (should (eobp))
372 ;; Add an unbalanced bracket to the beginning and try again;
373 ;; we should get an error.
374 (goto-char (point-min))
375 (insert "( ")
376 (goto-char (point-min))
377 (should-error (read (current-buffer)) :type 'end-of-file)))
378
363;;; lread-tests.el ends here 379;;; lread-tests.el ends here
diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el
index 460651def78..f7144c15887 100644
--- a/test/src/sqlite-tests.el
+++ b/test/src/sqlite-tests.el
@@ -197,10 +197,13 @@
197 (sqlite-load-extension db "/usr/lib/sqlite3/")) 197 (sqlite-load-extension db "/usr/lib/sqlite3/"))
198 (should-error 198 (should-error
199 (sqlite-load-extension db "/usr/lib/sqlite3")) 199 (sqlite-load-extension db "/usr/lib/sqlite3"))
200 (should 200 (if (eq system-type 'windows-nt)
201 (memq 201 (should
202 (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so") 202 (eq (sqlite-load-extension db "/usr/lib/sqlite3/pcre.dll")
203 '(nil t))) 203 (file-readable-p "/usr/lib/sqlite3/pcre.dll")))
204 (should
205 (eq (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so")
206 (file-readable-p "/usr/lib/sqlite3/pcre.so"))))
204 207
205 (should-error 208 (should-error
206 (sqlite-load-extension 209 (sqlite-load-extension
@@ -211,11 +214,13 @@
211 (should-error 214 (should-error
212 (sqlite-load-extension 215 (sqlite-load-extension
213 db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable")) 216 db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable"))
214 (should 217 (if (eq system-type 'windows-nt)
215 (memq 218 (should
216 (sqlite-load-extension 219 (eq (sqlite-load-extension db "/usr/lib/sqlite3/csvtable.dll")
217 db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so") 220 (file-readable-p "/usr/lib/sqlite3/csvtable.dll")))
218 '(nil t))))) 221 (should
222 (eq (sqlite-load-extension db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so")
223 (file-readable-p "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so"))))))
219 224
220(ert-deftest sqlite-blob () 225(ert-deftest sqlite-blob ()
221 (skip-unless (sqlite-available-p)) 226 (skip-unless (sqlite-available-p))
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el
index 4aa81a9ce0b..7a8e53924eb 100644
--- a/test/src/treesit-tests.el
+++ b/test/src/treesit-tests.el
@@ -69,7 +69,7 @@
69 (should 69 (should
70 (equal (treesit-node-string 70 (equal (treesit-node-string
71 (treesit-parser-root-node parser)) 71 (treesit-parser-root-node parser))
72 "(ERROR)")) 72 "(document)"))
73 73
74 (insert "[1,2,3]") 74 (insert "[1,2,3]")
75 (should 75 (should