aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--admin/authors.el2
-rwxr-xr-xadmin/emake2
-rw-r--r--admin/unidata/unidata-gen.el4
-rw-r--r--doc/emacs/glossary.texi4
-rw-r--r--doc/emacs/misc.texi96
-rw-r--r--doc/emacs/msdos.texi6
-rw-r--r--doc/lispintro/emacs-lisp-intro.texi45
-rw-r--r--doc/lispref/debugging.texi44
-rw-r--r--doc/lispref/display.texi6
-rw-r--r--doc/lispref/functions.texi8
-rw-r--r--doc/lispref/loading.texi2
-rw-r--r--doc/lispref/objects.texi3
-rw-r--r--doc/lispref/os.texi10
-rw-r--r--doc/lispref/processes.texi1
-rw-r--r--doc/misc/auth.texi10
-rw-r--r--doc/misc/calc.texi2
-rw-r--r--doc/misc/efaq-w32.texi6
-rw-r--r--doc/misc/efaq.texi28
-rw-r--r--doc/misc/emacs-mime.texi6
-rw-r--r--doc/misc/eshell.texi82
-rw-r--r--doc/misc/gnus-faq.texi217
-rw-r--r--doc/misc/gnus.texi102
-rw-r--r--doc/misc/htmlfontify.texi10
-rw-r--r--doc/misc/idlwave.texi11
-rw-r--r--doc/misc/message.texi11
-rw-r--r--doc/misc/mh-e.texi13
-rw-r--r--doc/misc/tramp.texi4
-rw-r--r--doc/misc/viper.texi4
-rw-r--r--etc/AUTHORS2
-rw-r--r--etc/NEWS71
-rw-r--r--etc/PROBLEMS17
-rw-r--r--lisp/array.el87
-rw-r--r--lisp/bookmark.el2
-rw-r--r--lisp/calc/calc-vec.el4
-rw-r--r--lisp/calc/calc.el12
-rw-r--r--lisp/calendar/time-date.el12
-rw-r--r--lisp/cedet/cedet.el6
-rw-r--r--lisp/cedet/ede.el9
-rw-r--r--lisp/cedet/ede/emacs.el1
-rw-r--r--lisp/cedet/semantic.el6
-rw-r--r--lisp/cedet/semantic/bovine.el4
-rw-r--r--lisp/cedet/semantic/db-file.el2
-rw-r--r--lisp/cedet/semantic/wisent/comp.el2
-rw-r--r--lisp/cedet/srecode.el4
-rw-r--r--lisp/descr-text.el4
-rw-r--r--lisp/emacs-lisp/advice.el19
-rw-r--r--lisp/emacs-lisp/byte-opt.el57
-rw-r--r--lisp/emacs-lisp/bytecomp.el24
-rw-r--r--lisp/emacs-lisp/checkdoc.el21
-rw-r--r--lisp/emacs-lisp/cl-macs.el2
-rw-r--r--lisp/emacs-lisp/ert.el3
-rw-r--r--lisp/emacs-lisp/helper.el1
-rw-r--r--lisp/emacs-lisp/loaddefs-gen.el35
-rw-r--r--lisp/emacs-lisp/macroexp.el2
-rw-r--r--lisp/emacs-lisp/nadvice.el24
-rw-r--r--lisp/emacs-lisp/package.el2
-rw-r--r--lisp/emacs-lisp/pcase.el13
-rw-r--r--lisp/emacs-lisp/ring.el4
-rw-r--r--lisp/emacs-lisp/seq.el20
-rw-r--r--lisp/emacs-lisp/subr-x.el22
-rw-r--r--lisp/emulation/viper.el2
-rw-r--r--lisp/eshell/em-alias.el2
-rw-r--r--lisp/eshell/esh-cmd.el85
-rw-r--r--lisp/eshell/esh-io.el50
-rw-r--r--lisp/eshell/esh-proc.el68
-rw-r--r--lisp/faces.el33
-rw-r--r--lisp/finder.el16
-rw-r--r--lisp/gnus/deuglify.el1
-rw-r--r--lisp/gnus/gnus-diary.el6
-rw-r--r--lisp/gnus/gnus-util.el8
-rw-r--r--lisp/gnus/gnus-uu.el3
-rw-r--r--lisp/gnus/gnus.el3
-rw-r--r--lisp/gnus/message.el9
-rw-r--r--lisp/gnus/mm-decode.el9
-rw-r--r--lisp/gnus/mml.el3
-rw-r--r--lisp/gnus/nnagent.el1
-rw-r--r--lisp/gnus/nnbabyl.el1
-rw-r--r--lisp/gnus/nndiary.el2
-rw-r--r--lisp/gnus/nndir.el1
-rw-r--r--lisp/gnus/nndoc.el1
-rw-r--r--lisp/gnus/nndraft.el1
-rw-r--r--lisp/gnus/nneething.el1
-rw-r--r--lisp/gnus/nnfolder.el1
-rw-r--r--lisp/gnus/nnmaildir.el1
-rw-r--r--lisp/gnus/nnmbox.el1
-rw-r--r--lisp/gnus/nnmh.el1
-rw-r--r--lisp/gnus/nnml.el1
-rw-r--r--lisp/gnus/nnrss.el1
-rw-r--r--lisp/gnus/nnspool.el1
-rw-r--r--lisp/gnus/nntp.el1
-rw-r--r--lisp/gnus/nnvirtual.el1
-rw-r--r--lisp/help-fns.el10
-rw-r--r--lisp/htmlfontify.el11
-rw-r--r--lisp/international/characters.el23
-rw-r--r--lisp/leim/quail/indian.el2
-rw-r--r--lisp/loadup.el3
-rw-r--r--lisp/mh-e/mh-e.el4
-rw-r--r--lisp/net/newst-treeview.el11
-rw-r--r--lisp/net/tramp-adb.el2
-rw-r--r--lisp/net/tramp-archive.el2
-rw-r--r--lisp/net/tramp-compat.el23
-rw-r--r--lisp/net/tramp-crypt.el2
-rw-r--r--lisp/net/tramp-gvfs.el7
-rw-r--r--lisp/net/tramp-sh.el47
-rw-r--r--lisp/org/org.el5
-rw-r--r--lisp/outline.el10
-rw-r--r--lisp/play/5x5.el12
-rw-r--r--lisp/printing.el44
-rw-r--r--lisp/progmodes/ebnf2ps.el51
-rw-r--r--lisp/progmodes/f90.el7
-rw-r--r--lisp/progmodes/gdb-mi.el28
-rw-r--r--lisp/progmodes/gud.el13
-rw-r--r--lisp/progmodes/js.el7
-rw-r--r--lisp/progmodes/ps-mode.el8
-rw-r--r--lisp/ps-print.el39
-rw-r--r--lisp/select.el9
-rw-r--r--lisp/simple.el35
-rw-r--r--lisp/subr.el6
-rw-r--r--lisp/textmodes/emacs-authors-mode.el145
-rw-r--r--lisp/textmodes/emacs-news-mode.el13
-rw-r--r--lisp/textmodes/etc-authors-mode.el133
-rw-r--r--lisp/thingatpt.el13
-rw-r--r--lisp/vc/add-log.el14
-rw-r--r--lisp/vc/diff-mode.el4
-rw-r--r--lisp/vc/ediff-mult.el26
-rw-r--r--lisp/vc/ediff.el11
-rw-r--r--lisp/vc/emerge.el2
-rw-r--r--lisp/vc/vc-annotate.el30
-rw-r--r--lisp/vc/vc-bzr.el24
-rw-r--r--lisp/vc/vc-dir.el16
-rw-r--r--lisp/vc/vc-git.el57
-rw-r--r--lisp/vc/vc-hg.el11
-rw-r--r--lisp/vc/vc-hooks.el57
-rw-r--r--src/Makefile.in1
-rw-r--r--src/buffer.c21
-rw-r--r--src/eval.c59
-rw-r--r--src/ftcrfont.c6
-rw-r--r--src/indent.c60
-rw-r--r--src/keyboard.c25
-rw-r--r--src/lisp.h2
-rw-r--r--src/timefns.c71
-rw-r--r--src/window.c9
-rw-r--r--src/xdisp.c203
-rw-r--r--src/xfns.c19
-rw-r--r--src/xterm.c250
-rw-r--r--test/lisp/emacs-lisp/seq-tests.el7
-rw-r--r--test/lisp/eshell/esh-cmd-tests.el283
-rw-r--r--test/lisp/eshell/esh-var-tests.el59
-rw-r--r--test/lisp/eshell/eshell-tests.el53
-rw-r--r--test/lisp/international/ucs-normalize-tests.el2
-rw-r--r--test/lisp/net/tramp-tests.el3
151 files changed, 2125 insertions, 1533 deletions
diff --git a/admin/authors.el b/admin/authors.el
index de43d914544..12fe25fa4e1 100644
--- a/admin/authors.el
+++ b/admin/authors.el
@@ -1883,7 +1883,7 @@ list of their contributions.\n")
1883 (insert "\n ")) 1883 (insert "\n "))
1884 (insert " " file)) 1884 (insert " " file))
1885 (insert "\n"))))) 1885 (insert "\n")))))
1886 (insert "\nLocal" " Variables:\nmode: etc-authors\ncoding: " 1886 (insert "\nLocal" " Variables:\nmode: emacs-authors\ncoding: "
1887 (symbol-name authors-coding-system) "\nEnd:\n") 1887 (symbol-name authors-coding-system) "\nEnd:\n")
1888 (message "Generating buffer %s... done" buffer-name) 1888 (message "Generating buffer %s... done" buffer-name)
1889 (unless noninteractive 1889 (unless noninteractive
diff --git a/admin/emake b/admin/emake
index 9bebd340678..548611c6afc 100755
--- a/admin/emake
+++ b/admin/emake
@@ -29,6 +29,7 @@ s#^Running # Running #
29s#^Configured for # Configured for # 29s#^Configured for # Configured for #
30s#^./temacs.*# \\& # 30s#^./temacs.*# \\& #
31s#^make.*Error# \\& # 31s#^make.*Error# \\& #
32s#^Dumping under the name# \\& #
32' | \ 33' | \
33grep -E --line-buffered -v "^make|\ 34grep -E --line-buffered -v "^make|\
34^Loading|\ 35^Loading|\
@@ -43,7 +44,6 @@ GEN.*autoloads|\
43^Adding name|\ 44^Adding name|\
44^Dump mode|\ 45^Dump mode|\
45^Dumping finger|\ 46^Dumping finger|\
46^Dumping under the name|\
47^Byte counts|\ 47^Byte counts|\
48^Reloc counts|\ 48^Reloc counts|\
49^Pure-hashed|\ 49^Pure-hashed|\
diff --git a/admin/unidata/unidata-gen.el b/admin/unidata/unidata-gen.el
index 0a9fd5108ce..78dd1c37288 100644
--- a/admin/unidata/unidata-gen.el
+++ b/admin/unidata/unidata-gen.el
@@ -1083,8 +1083,8 @@ Property value is a symbol `o' (Open), `c' (Close), or `n' (None)."
1083 1083
1084(defun unidata--ensure-compiled (&rest funcs) 1084(defun unidata--ensure-compiled (&rest funcs)
1085 (dolist (fun funcs) 1085 (dolist (fun funcs)
1086 (or (byte-code-function-p (symbol-function fun)) 1086 (unless (compiled-function-p (symbol-function fun))
1087 (byte-compile fun)))) 1087 (byte-compile fun))))
1088 1088
1089(defun unidata-gen-table-name (prop index &rest _ignore) 1089(defun unidata-gen-table-name (prop index &rest _ignore)
1090 (let* ((table (unidata-gen-table-word-list prop index 'unidata-split-name)) 1090 (let* ((table (unidata-gen-table-word-list prop index 'unidata-split-name))
diff --git a/doc/emacs/glossary.texi b/doc/emacs/glossary.texi
index 5224e313407..9a537019974 100644
--- a/doc/emacs/glossary.texi
+++ b/doc/emacs/glossary.texi
@@ -1457,8 +1457,8 @@ level by aborting (q.v.@:) and quitting (q.v.). @xref{Quitting}.
1457@item Transient Mark Mode 1457@item Transient Mark Mode
1458The default behavior of the mark (q.v.@:) and region (q.v.), in which 1458The default behavior of the mark (q.v.@:) and region (q.v.), in which
1459setting the mark activates it and highlights the region, is called 1459setting the mark activates it and highlights the region, is called
1460Transient Mark mode. In GNU Emacs 23 and onwards, it is enabled by 1460Transient Mark mode. It is enabled by default. @xref{Disabled
1461default. @xref{Disabled Transient Mark}. 1461Transient Mark}.
1462 1462
1463@item Transposition 1463@item Transposition
1464Transposing two units of text means putting each one into the place 1464Transposing two units of text means putting each one into the place
diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi
index 841a285520a..da1b87b48bd 100644
--- a/doc/emacs/misc.texi
+++ b/doc/emacs/misc.texi
@@ -1,6 +1,5 @@
1@c This is part of the Emacs manual. 1@c This is part of the Emacs manual.
2@c Copyright (C) 1985--1987, 1993--1995, 1997, 2000--2022 Free Software 2@c Copyright (C) 1985--2022 Free Software Foundation, Inc.
3@c Foundation, Inc.
4@c See file emacs.texi for copying conditions. 3@c See file emacs.texi for copying conditions.
5@iftex 4@iftex
6@chapter Miscellaneous Commands 5@chapter Miscellaneous Commands
@@ -2870,99 +2869,6 @@ new major mode which provides a command to switch back. These
2870approaches give you more flexibility to go back to unfinished tasks in 2869approaches give you more flexibility to go back to unfinished tasks in
2871the order you choose. 2870the order you choose.
2872 2871
2873@ignore
2874@c Apart from edt and viper, this is all obsolete.
2875@c (Can't believe we were saying "most other editors" into 2014!)
2876@c There seems no point having a node just for those, which both have
2877@c their own manuals.
2878@node Emulation
2879@section Emulation
2880@cindex emulating other editors
2881@cindex other editors
2882@cindex EDT
2883@cindex vi
2884@cindex WordStar
2885
2886 GNU Emacs can be programmed to emulate (more or less) most other
2887editors. Standard facilities can emulate these:
2888
2889@table @asis
2890@item CRiSP/Brief (PC editor)
2891@findex crisp-mode
2892@vindex crisp-override-meta-x
2893@findex scroll-all-mode
2894@cindex CRiSP mode
2895@cindex Brief emulation
2896@cindex emulation of Brief
2897@cindex mode, CRiSP
2898@kbd{M-x crisp-mode} enables key bindings to emulate the CRiSP/Brief
2899editor. Note that this rebinds @kbd{M-x} to exit Emacs unless you set
2900the variable @code{crisp-override-meta-x}. You can also use the
2901command @kbd{M-x scroll-all-mode} or set the variable
2902@code{crisp-load-scroll-all} to emulate CRiSP's scroll-all feature
2903(scrolling all windows together).
2904
2905@item EDT (DEC VMS editor)
2906@findex edt-emulation-on
2907@findex edt-emulation-off
2908Turn on EDT emulation with @kbd{M-x edt-emulation-on}; restore normal
2909command bindings with @kbd{M-x edt-emulation-off}.
2910
2911Most of the EDT emulation commands are keypad keys, and most standard
2912Emacs key bindings are still available. The EDT emulation rebindings
2913are done in the global keymap, so there is no problem switching
2914buffers or major modes while in EDT emulation.
2915
2916@item TPU (DEC VMS editor)
2917@findex tpu-edt-on
2918@cindex TPU
2919@kbd{M-x tpu-edt-on} turns on emulation of the TPU editor emulating EDT.
2920
2921@item vi (Berkeley editor)
2922@findex viper-mode
2923Viper is an emulator for vi. It implements several levels of
2924emulation; level 1 is closest to vi itself, while level 5 departs
2925somewhat from strict emulation to take advantage of the capabilities of
2926Emacs. To invoke Viper, type @kbd{M-x viper-mode}; it will guide you
2927the rest of the way and ask for the emulation level. @inforef{Top,
2928Viper, viper}.
2929
2930@item vi (another emulator)
2931@findex vi-mode
2932@kbd{M-x vi-mode} enters a major mode that replaces the previously
2933established major mode. All of the vi commands that, in real vi, enter
2934input mode are programmed instead to return to the previous major
2935mode. Thus, ordinary Emacs serves as vi's input mode.
2936
2937Because vi emulation works through major modes, it does not work
2938to switch buffers during emulation. Return to normal Emacs first.
2939
2940If you plan to use vi emulation much, you probably want to bind a key
2941to the @code{vi-mode} command.
2942
2943@item vi (alternate emulator)
2944@findex vip-mode
2945@kbd{M-x vip-mode} invokes another vi emulator, said to resemble real vi
2946more thoroughly than @kbd{M-x vi-mode}. Input mode in this emulator
2947is changed from ordinary Emacs so you can use @key{ESC} to go back to
2948emulated vi command mode. To get from emulated vi command mode back to
2949ordinary Emacs, type @kbd{C-z}.
2950
2951This emulation does not work through major modes, and it is possible
2952to switch buffers in various ways within the emulator. It is not
2953so necessary to assign a key to the command @code{vip-mode} as
2954it is with @code{vi-mode} because terminating insert mode does
2955not use it.
2956
2957@inforef{Top, VIP, vip}, for full information.
2958
2959@item WordStar (old wordprocessor)
2960@findex wordstar-mode
2961@kbd{M-x wordstar-mode} provides a major mode with WordStar-like
2962key bindings.
2963@end table
2964@end ignore
2965
2966 2872
2967@node Hyperlinking 2873@node Hyperlinking
2968@section Hyperlinking and Web Navigation Features 2874@section Hyperlinking and Web Navigation Features
diff --git a/doc/emacs/msdos.texi b/doc/emacs/msdos.texi
index e30d623a77c..dd0787cd38d 100644
--- a/doc/emacs/msdos.texi
+++ b/doc/emacs/msdos.texi
@@ -986,9 +986,9 @@ printer, put this in your @file{.emacs} file:
986@section Specifying Fonts on MS-Windows 986@section Specifying Fonts on MS-Windows
987@cindex font specification (MS Windows) 987@cindex font specification (MS Windows)
988 988
989 Starting with Emacs 23, fonts are specified by their name, size 989 Fonts are specified by their name, size and optional properties.
990and optional properties. The format for specifying fonts comes from the 990The format for specifying fonts comes from the fontconfig library used
991fontconfig library used in modern Free desktops: 991in modern Free desktops:
992 992
993@example 993@example
994 [Family[-PointSize]][:Option1=Value1[:Option2=Value2[...]]] 994 [Family[-PointSize]][:Option1=Value1[:Option2=Value2[...]]]
diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi
index 049c8a65a8f..47a5a870fde 100644
--- a/doc/lispintro/emacs-lisp-intro.texi
+++ b/doc/lispintro/emacs-lisp-intro.texi
@@ -2020,7 +2020,6 @@ the arguments to the function @code{concat} are the strings
2020@w{@code{"The "}} and @w{@code{" red foxes."}} and the list 2020@w{@code{"The "}} and @w{@code{" red foxes."}} and the list
2021@code{(number-to-string (+ 2 fill-column))}. 2021@code{(number-to-string (+ 2 fill-column))}.
2022 2022
2023@c For GNU Emacs 22, need number-to-string
2024@smallexample 2023@smallexample
2025(concat "The " (number-to-string (+ 2 fill-column)) " red foxes.") 2024(concat "The " (number-to-string (+ 2 fill-column)) " red foxes.")
2026@end smallexample 2025@end smallexample
@@ -10297,9 +10296,8 @@ loop with a list.
10297 10296
10298@cindex @file{*scratch*} buffer 10297@cindex @file{*scratch*} buffer
10299The function requires several lines for its output. If you are 10298The function requires several lines for its output. If you are
10300reading this in a recent instance of GNU Emacs, 10299reading this in a recent instance of GNU Emacs, you can evaluate the
10301@c GNU Emacs 21, GNU Emacs 22, or a later version, 10300following expression inside of Info, as usual.
10302you can evaluate the following expression inside of Info, as usual.
10303 10301
10304If you are using an earlier version of Emacs, you need to copy the 10302If you are using an earlier version of Emacs, you need to copy the
10305necessary expressions to your @file{*scratch*} buffer and evaluate 10303necessary expressions to your @file{*scratch*} buffer and evaluate
@@ -15134,16 +15132,16 @@ Emacs may produce different results.)
15134@end group 15132@end group
15135 15133
15136@group 15134@group
15137(lengths-list-file "./lisp/makesum.el") 15135(lengths-list-file "./lisp/hex-util.el")
15138 @result{} (85 181) 15136 @result{} (82 71)
15139@end group 15137@end group
15140 15138
15141@group 15139@group
15142 (recursive-lengths-list-many-files 15140 (recursive-lengths-list-many-files
15143 '("./lisp/macros.el" 15141 '("./lisp/macros.el"
15144 "./lisp/mail/mailalias.el" 15142 "./lisp/mail/mailalias.el"
15145 "./lisp/makesum.el")) 15143 "./lisp/hex-util.el"))
15146 @result{} (283 263 480 90 38 32 29 95 178 180 321 218 324 85 181) 15144 @result{} (283 263 480 90 38 32 29 95 178 180 321 218 324 82 71)
15147@end group 15145@end group
15148@end smallexample 15146@end smallexample
15149 15147
@@ -15235,27 +15233,13 @@ Sorting the list returned by the
15235@code{recursive-lengths-list-many-files} function is straightforward; 15233@code{recursive-lengths-list-many-files} function is straightforward;
15236it uses the @code{<} function: 15234it uses the @code{<} function:
15237 15235
15238@ignore
152392006 Oct 29
15240In GNU Emacs 22, eval
15241(progn
15242 (cd "/usr/local/share/emacs/22.0.50/")
15243 (sort
15244 (recursive-lengths-list-many-files
15245 '("./lisp/macros.el"
15246 "./lisp/mail/mailalias.el"
15247 "./lisp/makesum.el"))
15248 '<))
15249
15250@end ignore
15251
15252@smallexample 15236@smallexample
15253@group 15237@group
15254(sort 15238(sort
15255 (recursive-lengths-list-many-files 15239 (recursive-lengths-list-many-files
15256 '("./lisp/macros.el" 15240 '("./lisp/macros.el"
15257 "./lisp/mailalias.el" 15241 "./lisp/mailalias.el"
15258 "./lisp/makesum.el")) 15242 "./lisp/hex-util.el"))
15259 '<) 15243 '<)
15260@end group 15244@end group
15261@end smallexample 15245@end smallexample
@@ -15265,7 +15249,7 @@ In GNU Emacs 22, eval
15265which produces: 15249which produces:
15266 15250
15267@smallexample 15251@smallexample
15268(29 32 38 85 90 95 178 180 181 218 263 283 321 324 480) 15252(29 32 38 71 82 90 95 178 180 218 263 283 321 324 480)
15269@end smallexample 15253@end smallexample
15270 15254
15271@noindent 15255@noindent
@@ -15313,7 +15297,7 @@ as a list that looks like this (but with more elements):
15313@group 15297@group
15314("./lisp/macros.el" 15298("./lisp/macros.el"
15315 "./lisp/mail/rmail.el" 15299 "./lisp/mail/rmail.el"
15316 "./lisp/makesum.el") 15300 "./lisp/hex-util.el")
15317@end group 15301@end group
15318@end smallexample 15302@end smallexample
15319 15303
@@ -17711,17 +17695,6 @@ or start GNU Emacs with the command @code{emacs -nbc}.
17711(setq grep-command "grep -i -nH -e ") 17695(setq grep-command "grep -i -nH -e ")
17712@end smallexample 17696@end smallexample
17713 17697
17714@ignore
17715@c Evidently, no longer needed in GNU Emacs 22
17716
17717item Automatically uncompress compressed files when visiting them
17718
17719smallexample
17720(load "uncompress")
17721end smallexample
17722
17723@end ignore
17724
17725@item Find an existing buffer, even if it has a different name@* 17698@item Find an existing buffer, even if it has a different name@*
17726This avoids problems with symbolic links. 17699This avoids problems with symbolic links.
17727 17700
diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi
index 058c9319544..9ae40949d1e 100644
--- a/doc/lispref/debugging.texi
+++ b/doc/lispref/debugging.texi
@@ -77,6 +77,7 @@ debugger recursively. @xref{Recursive Editing}.
77 77
78@menu 78@menu
79* Error Debugging:: Entering the debugger when an error happens. 79* Error Debugging:: Entering the debugger when an error happens.
80* Debugging Redisplay:: Getting backtraces from redisplay errors.
80* Infinite Loops:: Stopping and debugging a program that doesn't exit. 81* Infinite Loops:: Stopping and debugging a program that doesn't exit.
81* Function Debugging:: Entering it when a certain function is called. 82* Function Debugging:: Entering it when a certain function is called.
82* Variable Debugging:: Entering it when a variable is modified. 83* Variable Debugging:: Entering it when a variable is modified.
@@ -105,6 +106,10 @@ debugger, set the variable @code{debug-on-error} to non-@code{nil}.
105(The command @code{toggle-debug-on-error} provides an easy way to do 106(The command @code{toggle-debug-on-error} provides an easy way to do
106this.) 107this.)
107 108
109Note that, for technical reasons, you cannot use the facilities
110defined in this subsection to debug errors in Lisp that the redisplay
111code has invoked. @xref{Debugging Redisplay}, for help with these.
112
108@defopt debug-on-error 113@defopt debug-on-error
109This variable determines whether the debugger is called when an error 114This variable determines whether the debugger is called when an error
110is signaled and not handled. If @code{debug-on-error} is @code{t}, 115is signaled and not handled. If @code{debug-on-error} is @code{t},
@@ -213,6 +218,45 @@ file, use the option @samp{--debug-init}. This binds
213bypasses the @code{condition-case} which normally catches errors in the 218bypasses the @code{condition-case} which normally catches errors in the
214init file. 219init file.
215 220
221@node Debugging Redisplay
222@subsection Debugging Redisplay Errors
223@cindex redisplay errors
224@cindex debugging redisplay errors
225
226When an error occurs in Lisp code which redisplay has invoked, Emacs's
227usual debugging mechanisms are unusable, for technical reasons. This
228subsection describes how to get a backtrace from such an error, which
229should be helpful in debugging it.
230
231These directions apply to Lisp forms used, for example, in
232@code{:eval} mode line constructs (@pxref{Mode Line Data}), and in all
233hooks invoked from redisplay, such as:
234
235@itemize
236@item
237@code{fontification-functions} (@pxref{Auto Faces}).
238@item
239@code{window-scroll-functions} (@pxref{Window Hooks}).
240@end itemize
241
242Note that if you have had an error in a hook function called from
243redisplay, the error handling might have removed this function from
244the hook. You will thus need to reinitialize that hook somehow,
245perhaps with @code{add-hook}, to be able to replay the bug.
246
247To generate a backtrace in these circumstances, set the variable
248@code{backtrace-on-redisplay-error} to non-@code{nil}. When the error
249occurs, Emacs will dump the backtrace to the buffer
250@file{*Redisplay-trace*}, but won't automatically display it in a
251window. This is to avoid needlessly corrupting the redisplay you are
252debugging. You will thus need to display the buffer yourself, with a
253command such as @code{switch-to-buffer-other-frame} @key{C-x 5 b}.
254
255@defvar backtrace-on-redisplay-error
256Set this variable to non-@code{nil} to enable the generation of a
257backtrace when an error occurs in any Lisp called from redisplay.
258@end defvar
259
216@node Infinite Loops 260@node Infinite Loops
217@subsection Debugging Infinite Loops 261@subsection Debugging Infinite Loops
218@cindex infinite loops 262@cindex infinite loops
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index ace67fbedb7..96079dc106a 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -8596,9 +8596,9 @@ Characters of Unicode General Category [Cf], such as U+200E
8596images, such as U+00AD @sc{soft hyphen}. 8596images, such as U+00AD @sc{soft hyphen}.
8597 8597
8598@item variation-selectors 8598@item variation-selectors
8599Unicode VS-1 through VS-16 (U+FE00 through U+FE0F), which are used to 8599Unicode VS-1 through VS-256 (U+FE00 through U+FE0F and U+E0100 through
8600select between different glyphs for the same codepoints (typically 8600U+E01EF), which are used to select between different glyphs for the same
8601emojis). 8601codepoints (typically emojis).
8602 8602
8603@item no-font 8603@item no-font
8604Characters for which there is no suitable font, or which cannot be 8604Characters for which there is no suitable font, or which cannot be
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index 8265e58210e..ddf7cff6c2e 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -217,6 +217,14 @@ function. For example:
217@end example 217@end example
218@end defun 218@end defun
219 219
220@defun compiled-function-p object
221This function returns @code{t} if @var{object} is a function object
222that was either built-in (a.k.a.@: ``primitive'', @pxref{What Is a
223Function}), or byte-compiled (@pxref{Byte Compilation}), or
224natively-compiled (@pxref{Native Compilation}), or a function loaded
225from a dynamic module (@pxref{Dynamic Modules}).
226@end defun
227
220@defun subr-arity subr 228@defun subr-arity subr
221This works like @code{func-arity}, but only for built-in functions and 229This works like @code{func-arity}, but only for built-in functions and
222without symbol indirection. It signals an error for non-built-in 230without symbol indirection. It signals an error for non-built-in
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 0972a7a123c..4e4f12dc324 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -440,7 +440,7 @@ similarly-named file in a directory earlier on @code{load-path}.
440For instance, suppose @code{load-path} is set to 440For instance, suppose @code{load-path} is set to
441 441
442@example 442@example
443 ("/opt/emacs/site-lisp" "/usr/share/emacs/23.3/lisp") 443 ("/opt/emacs/site-lisp" "/usr/share/emacs/29.1/lisp")
444@end example 444@end example
445 445
446@noindent 446@noindent
diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi
index 1bae1924557..7b5e9adee29 100644
--- a/doc/lispref/objects.texi
+++ b/doc/lispref/objects.texi
@@ -2022,6 +2022,9 @@ with references to further information.
2022@item byte-code-function-p 2022@item byte-code-function-p
2023@xref{Byte-Code Type, byte-code-function-p}. 2023@xref{Byte-Code Type, byte-code-function-p}.
2024 2024
2025@item compiled-function-p
2026@xref{Byte-Code Type, compiled-function-p}.
2027
2025@item case-table-p 2028@item case-table-p
2026@xref{Case Tables, case-table-p}. 2029@xref{Case Tables, case-table-p}.
2027 2030
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index d591b219cd0..35828018417 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1544,11 +1544,11 @@ as traditional Gregorian years do; for example, the year number
1544@defun time-convert time form 1544@defun time-convert time form
1545This function converts a time value into a Lisp timestamp. 1545This function converts a time value into a Lisp timestamp.
1546 1546
1547The optional @var{form} argument specifies the timestamp form to be 1547The @var{form} argument specifies the timestamp form to be returned.
1548returned. If @var{form} is the symbol @code{integer}, this function 1548If @var{form} is the symbol @code{integer}, this function returns an
1549returns an integer count of seconds. If @var{form} is a positive 1549integer count of seconds. If @var{form} is a positive integer, it
1550integer, it specifies a clock frequency and this function returns an 1550specifies a clock frequency and this function returns an integer-pair
1551integer-pair timestamp @code{(@var{ticks} . @var{form})}. If @var{form} is 1551timestamp @code{(@var{ticks} . @var{form})}. If @var{form} is
1552@code{t}, this function treats it as a positive integer suitable for 1552@code{t}, this function treats it as a positive integer suitable for
1553representing the timestamp; for example, it is treated as 1000000000 1553representing the timestamp; for example, it is treated as 1000000000
1554if @var{time} is @code{nil} and the platform timestamp has nanosecond 1554if @var{time} is @code{nil} and the platform timestamp has nanosecond
diff --git a/doc/lispref/processes.texi b/doc/lispref/processes.texi
index 382053ab24a..db6b4c35ef7 100644
--- a/doc/lispref/processes.texi
+++ b/doc/lispref/processes.texi
@@ -1960,7 +1960,6 @@ because @var{seconds} can be floating point to specify
1960waiting a fractional number of seconds. If @var{seconds} is 0, the 1960waiting a fractional number of seconds. If @var{seconds} is 0, the
1961function accepts whatever output is pending but does not wait. 1961function accepts whatever output is pending but does not wait.
1962 1962
1963@c Emacs 22.1 feature
1964If @var{process} is a process, and the argument @var{just-this-one} is 1963If @var{process} is a process, and the argument @var{just-this-one} is
1965non-@code{nil}, only output from that process is handled, suspending output 1964non-@code{nil}, only output from that process is handled, suspending output
1966from other processes until some output has been received from that 1965from other processes until some output has been received from that
diff --git a/doc/misc/auth.texi b/doc/misc/auth.texi
index 829d7f4fa03..91a9afd9c9f 100644
--- a/doc/misc/auth.texi
+++ b/doc/misc/auth.texi
@@ -652,14 +652,8 @@ before @file{~/.authinfo}, the auth-source library will try to
652read the GnuPG encrypted @file{.gpg} file first, before 652read the GnuPG encrypted @file{.gpg} file first, before
653the unencrypted file. 653the unencrypted file.
654 654
655In Emacs 23 or later there is an option @code{auto-encryption-mode} to 655There is an option @code{auto-encryption-mode} to automatically
656automatically decrypt @file{*.gpg} files. It is enabled by default. 656decrypt @file{*.gpg} files. It is enabled by default.
657If you are using earlier versions of Emacs, you will need:
658
659@lisp
660(require 'epa-file)
661(epa-file-enable)
662@end lisp
663 657
664If you want your GnuPG passwords to be cached, set up @code{gpg-agent} 658If you want your GnuPG passwords to be cached, set up @code{gpg-agent}
665or EasyPG Assistant 659or EasyPG Assistant
diff --git a/doc/misc/calc.texi b/doc/misc/calc.texi
index 9bda6af1c5b..98f59b89c01 100644
--- a/doc/misc/calc.texi
+++ b/doc/misc/calc.texi
@@ -1,7 +1,7 @@
1\input texinfo @c -*- mode: texinfo; coding: utf-8 -*- 1\input texinfo @c -*- mode: texinfo; coding: utf-8 -*-
2@setfilename ../../info/calc.info
2@comment %**start of header (This is for running Texinfo on a region.) 3@comment %**start of header (This is for running Texinfo on a region.)
3@c smallbook 4@c smallbook
4@setfilename ../../info/calc.info
5@c [title] 5@c [title]
6@settitle GNU Emacs Calc Manual 6@settitle GNU Emacs Calc Manual
7@include docstyle.texi 7@include docstyle.texi
diff --git a/doc/misc/efaq-w32.texi b/doc/misc/efaq-w32.texi
index 084b5a3254e..46c257e42e5 100644
--- a/doc/misc/efaq-w32.texi
+++ b/doc/misc/efaq-w32.texi
@@ -930,9 +930,9 @@ an indication of whether the font is outline (.TTF, .ATM) or raster (.FON)
930based when fonts are listed, which may let you differentiate between two 930based when fonts are listed, which may let you differentiate between two
931fonts with the same name and different technologies. 931fonts with the same name and different technologies.
932 932
933Starting with Emacs 23, the preferred font name format will be moving 933Starting with Emacs 23, the preferred font name format is the simpler
934to the simpler and more flexible fontconfig format. XLFD names will 934and more flexible fontconfig format. XLFD names will continue to be
935continue to be supported for backward compatibility. 935supported for backward compatibility.
936 936
937@example 937@example
938XLFD: -*-Courier New-normal-r-*-*-13-*-*-*-c-*-iso8859-1 938XLFD: -*-Courier New-normal-r-*-*-13-*-*-*-c-*-iso8859-1
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index a98c4b6a614..c29e4fe4875 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -2891,20 +2891,20 @@ and cause an annoying delay in display, so several features exist to
2891work around this. 2891work around this.
2892 2892
2893@cindex Just-In-Time syntax highlighting 2893@cindex Just-In-Time syntax highlighting
2894In Emacs 21 and later, turning on @code{font-lock-mode} automatically 2894Turning on @code{font-lock-mode} automatically activates
2895activates the new @dfn{Just-In-Time fontification} provided by 2895@dfn{Just-In-Time fontification} provided by @code{jit-lock-mode}.
2896@code{jit-lock-mode}. @code{jit-lock-mode} defers the fontification of 2896@code{jit-lock-mode} defers the fontification of portions of buffer
2897portions of buffer until you actually need to see them, and can also 2897until you actually need to see them, and can also fontify while Emacs
2898fontify while Emacs is idle. This makes display of the visible portion 2898is idle. This makes display of the visible portion of a buffer almost
2899of a buffer almost instantaneous. For details about customizing 2899instantaneous. For details about customizing @code{jit-lock-mode},
2900@code{jit-lock-mode}, type @kbd{C-h f jit-lock-mode @key{RET}}. 2900type @kbd{C-h f jit-lock-mode @key{RET}}.
2901 2901
2902@cindex Levels of syntax highlighting 2902@cindex Levels of syntax highlighting
2903@cindex Decoration level, in @code{font-lock-mode} 2903@cindex Decoration level, in @code{font-lock-mode}
2904In versions of Emacs before 21, different levels of decoration are 2904Different levels of decoration are available, from slight to gaudy.
2905available, from slight to gaudy. More decoration means you need to wait 2905More decoration means you need to wait more time for a buffer to be
2906more time for a buffer to be fontified (or a faster machine). To 2906fontified (or a faster machine). To control how decorated your
2907control how decorated your buffers should become, set the value of 2907buffers should become, set the value of
2908@code{font-lock-maximum-decoration} in your @file{.emacs} file, with a 2908@code{font-lock-maximum-decoration} in your @file{.emacs} file, with a
2909@code{nil} value indicating default (usually minimum) decoration, and a 2909@code{nil} value indicating default (usually minimum) decoration, and a
2910@code{t} value indicating the maximum decoration. For the gaudiest 2910@code{t} value indicating the maximum decoration. For the gaudiest
@@ -2985,11 +2985,7 @@ Add the following line to your @file{.emacs} file:
2985In many systems, @code{ls} is aliased to @samp{ls --color}, which 2985In many systems, @code{ls} is aliased to @samp{ls --color}, which
2986prints using ANSI color escape sequences. Emacs includes the 2986prints using ANSI color escape sequences. Emacs includes the
2987@code{ansi-color} package, which lets Shell mode recognize these 2987@code{ansi-color} package, which lets Shell mode recognize these
2988escape sequences. In Emacs 23.2 and later, the package is enabled by 2988escape sequences. It is enabled by default.
2989default; in earlier versions you can enable it by typing @kbd{M-x
2990ansi-color-for-comint-mode} in the Shell buffer, or by adding
2991@code{(add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)} to
2992your init file.
2993 2989
2994@node Fullscreen mode on MS-Windows 2990@node Fullscreen mode on MS-Windows
2995@section How can I start Emacs in fullscreen mode on MS-Windows? 2991@section How can I start Emacs in fullscreen mode on MS-Windows?
diff --git a/doc/misc/emacs-mime.texi b/doc/misc/emacs-mime.texi
index 640712edf33..5f4e1a639be 100644
--- a/doc/misc/emacs-mime.texi
+++ b/doc/misc/emacs-mime.texi
@@ -403,9 +403,9 @@ This selects the function used to render @acronym{HTML}. The
403predefined renderers are selected by the symbols @code{shr}, 403predefined renderers are selected by the symbols @code{shr},
404@code{gnus-w3m}, @code{w3m}@footnote{See 404@code{gnus-w3m}, @code{w3m}@footnote{See
405@uref{http://emacs-w3m.namazu.org/} for more information about 405@uref{http://emacs-w3m.namazu.org/} for more information about
406emacs-w3m}, @code{links}, @code{lynx}, @code{w3m-standalone} or 406emacs-w3m}, @code{links}, @code{lynx}, or @code{w3m-standalone}. You
407@code{html2text}. You can also specify a function, which will be 407can also specify a function, which will be called with a
408called with a @acronym{MIME} handle as the argument. 408@acronym{MIME} handle as the argument.
409 409
410@item mm-html-inhibit-images 410@item mm-html-inhibit-images
411@vindex mm-html-inhibit-images 411@vindex mm-html-inhibit-images
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi
index 9f9c88582f3..13f13163dd7 100644
--- a/doc/misc/eshell.texi
+++ b/doc/misc/eshell.texi
@@ -201,7 +201,7 @@ history and invoking commands in a script file.
201* Aliases:: 201* Aliases::
202* History:: 202* History::
203* Completion:: 203* Completion::
204* for loop:: 204* Control Flow::
205* Scripts:: 205* Scripts::
206@end menu 206@end menu
207 207
@@ -219,12 +219,18 @@ same name; if there is no match, it then tries to execute it as an
219external command. 219external command.
220 220
221The semicolon (@code{;}) can be used to separate multiple command 221The semicolon (@code{;}) can be used to separate multiple command
222invocations on a single line. A command invocation followed by an 222invocations on a single line. You can also separate commands with
223ampersand (@code{&}) will be run in the background. Eshell has no job 223@code{&&} or @code{||}. When using @code{&&}, Eshell will execute the
224control, so you can not suspend or background the current process, or 224second command only if the first succeeds (i.e.@: has an exit
225bring a background process into the foreground. That said, background 225status of 0); with @code{||}, Eshell will execute the second command
226processes invoked from Eshell can be controlled the same way as any 226only if the first fails.
227other background process in Emacs. 227
228A command invocation followed by an ampersand (@code{&}) will be run
229in the background. Eshell has no job control, so you can not suspend
230or background the current process, or bring a background process into
231the foreground. That said, background processes invoked from Eshell
232can be controlled the same way as any other background process in
233Emacs.
228 234
229@node Arguments 235@node Arguments
230@section Arguments 236@section Arguments
@@ -884,14 +890,18 @@ command (excluding the command name itself).
884 890
885@vindex $$ 891@vindex $$
886@item $$ 892@item $$
887This is the result of the last command. In case of an external 893This is the result of the last command. For external commands, it is
888command, it is @code{t} or @code{nil}. 894@code{t} if the exit code was 0 or @code{nil} otherwise.
889 895
896@vindex eshell-lisp-form-nil-is-failure
890@vindex $? 897@vindex $?
891@item $? 898@item $?
892This variable contains the exit code of the last command. If the last 899This variable contains the exit code of the last command. If the last
893command was a Lisp function, it is 0 for successful completion or 1 900command was a Lisp function, it is 0 for successful completion or 1
894otherwise. 901otherwise. If @code{eshell-lisp-form-nil-is-failure} is
902non-@code{nil}, then a command with a Lisp form, like
903@samp{(@var{command} @var{args}@dots{})}, that returns @code{nil} will
904set this variable to 2.
895 905
896@vindex $COLUMNS 906@vindex $COLUMNS
897@vindex $LINES 907@vindex $LINES
@@ -1008,19 +1018,46 @@ command for which this function provides completions; you can also name
1008the function @code{pcomplete/MAJOR-MODE/COMMAND} to define completions 1018the function @code{pcomplete/MAJOR-MODE/COMMAND} to define completions
1009for a specific major mode. 1019for a specific major mode.
1010 1020
1011@node for loop 1021@node Control Flow
1012@section @code{for} loop 1022@section Control Flow
1013Because Eshell commands can not (easily) be combined with lisp forms, 1023Because Eshell commands can not (easily) be combined with lisp forms,
1014Eshell provides a command-oriented @command{for}-loop for convenience. 1024Eshell provides command-oriented control flow statements for
1015The syntax is as follows: 1025convenience.
1016 1026
1017@example 1027Most of Eshell's control flow statements accept a @var{conditional}.
1018@code{for VAR in TOKENS @{ command invocation(s) @}} 1028This can take a few different forms. If @var{conditional} is a dollar
1019@end example 1029expansion, the condition is satisfied if the result is a
1030non-@code{nil} value. If @var{conditional} is a @samp{@{
1031@var{subcommand} @}} or @samp{(@var{lisp form})}, the condition is
1032satisfied if the command's exit status is 0.
1033
1034@table @code
1035
1036@item if @var{conditional} @{ @var{true-commands} @}
1037@itemx if @var{conditional} @{ @var{true-commands} @} @{ @var{false-commands} @}
1038Evaluate @var{true-commands} if @var{conditional} is satisfied;
1039otherwise, evaluate @var{false-commands}.
1040
1041@item unless @var{conditional} @{ @var{false-commands} @}
1042@itemx unless @var{conditional} @{ @var{false-commands} @} @{ @var{true-commands} @}
1043Evaluate @var{false-commands} if @var{conditional} is not satisfied;
1044otherwise, evaluate @var{true-commands}.
1020 1045
1021where @samp{TOKENS} is a space-separated sequence of values of 1046@item while @var{conditional} @{ @var{commands} @}
1022@var{VAR} for each iteration. This can even be the output of a 1047Repeatedly evaluate @var{commands} so long as @var{conditional} is
1023command if @samp{TOKENS} is replaced with @samp{@{ command invocation @}}. 1048satisfied.
1049
1050@item until @var{conditional} @{ @var{commands} @}
1051Repeatedly evaluate @var{commands} until @var{conditional} is
1052satisfied.
1053
1054@item for @var{var} in @var{list}@dots{} @{ @var{commands} @}
1055Iterate over each element of of @var{list}, storing the element in
1056@var{var} and evaluating @var{commands}. If @var{list} is not a list,
1057treat it as a list of one element. If you specify multiple
1058@var{lists}, this will iterate over each of them in turn.
1059
1060@end table
1024 1061
1025@node Scripts 1062@node Scripts
1026@section Scripts 1063@section Scripts
@@ -1811,11 +1848,6 @@ scrolls back.
1811 1848
1812@item Menu support was removed, but never put back 1849@item Menu support was removed, but never put back
1813 1850
1814@item Using C-p and C-n with rebind gets into a locked state
1815
1816This happened a few times in Emacs 21, but has been irreproducible
1817since.
1818
1819@item If an interactive process is currently running, @kbd{M-!} doesn't work 1851@item If an interactive process is currently running, @kbd{M-!} doesn't work
1820 1852
1821@item Use a timer instead of @code{sleep-for} when killing child processes 1853@item Use a timer instead of @code{sleep-for} when killing child processes
diff --git a/doc/misc/gnus-faq.texi b/doc/misc/gnus-faq.texi
index 4923efb3dbe..c442ca1bacd 100644
--- a/doc/misc/gnus-faq.texi
+++ b/doc/misc/gnus-faq.texi
@@ -1,7 +1,7 @@
1@c \input texinfo @c -*-texinfo-*- 1@c \input texinfo @c -*-texinfo-*-
2@c Uncomment 1st line before texing this file alone. 2@c Uncomment 1st line before texing this file alone.
3@c %**start of header 3@c %**start of header
4@c Copyright (C) 1995, 2001--2022 Free Software Foundation, Inc. 4@c Copyright (C) 1995--2022 Free Software Foundation, Inc.
5@c 5@c
6@c @setfilename gnus-faq.info 6@c @setfilename gnus-faq.info
7@c @settitle Frequently Asked Questions 7@c @settitle Frequently Asked Questions
@@ -13,7 +13,6 @@
13@section Frequently Asked Questions 13@section Frequently Asked Questions
14 14
15@menu 15@menu
16* FAQ - Changes::
17* FAQ - Introduction:: About Gnus and this FAQ. 16* FAQ - Introduction:: About Gnus and this FAQ.
18* FAQ 1 - Installation FAQ:: Installation of Gnus. 17* FAQ 1 - Installation FAQ:: Installation of Gnus.
19* FAQ 2 - Startup / Group buffer:: Start up questions and the 18* FAQ 2 - Startup / Group buffer:: Start up questions and the
@@ -41,21 +40,6 @@ This is the new Gnus Frequently Asked Questions list.
41Please submit features and suggestions to the 40Please submit features and suggestions to the
42@email{ding@@gnus.org, ding list}. 41@email{ding@@gnus.org, ding list}.
43 42
44@node FAQ - Changes
45@subsection Changes
46
47
48
49@itemize @bullet
50
51@item
522008-06-15: Adjust for message-fill-column. Add x-face-file.
53Clarify difference between ding and gnu.emacs.gnus. Remove
54reference to discontinued service.
55
56@item
572006-04-15: Added tip on how to delete sent buffer on exit.
58@end itemize
59 43
60@node FAQ - Introduction 44@node FAQ - Introduction
61@subsection Introduction 45@subsection Introduction
@@ -63,11 +47,11 @@ reference to discontinued service.
63This is the Gnus Frequently Asked Questions list. 47This is the Gnus Frequently Asked Questions list.
64 48
65Gnus is a Usenet Newsreader and Electronic Mail User Agent implemented 49Gnus is a Usenet Newsreader and Electronic Mail User Agent implemented
66as a part of Emacs. It's been around in some form for almost a decade 50as a part of Emacs. It's been around in some form since the early
67now, and has been distributed as a standard part of Emacs for much of 511990s, and has been distributed as a standard part of Emacs for much
68that time. Gnus 5 is the latest (and greatest) incarnation. The 52of that time. Gnus 5 is the latest (and greatest) incarnation. The
69original version was called GNUS, and was written by Masanobu UMEDA@. 53original version was called GNUS, and was written by Masanobu UMEDA@.
70When autumn crept up in '94, Lars Magne Ingebrigtsen grew bored and 54When autumn crept up in 1994, Lars Magne Ingebrigtsen grew bored and
71decided to rewrite Gnus. 55decided to rewrite Gnus.
72 56
73Its biggest strength is the fact that it is extremely 57Its biggest strength is the fact that it is extremely
@@ -84,11 +68,6 @@ would like to thank Steve Baur and Per Abrahamsen for doing a wonderful
84job with this FAQ before him. We would like to do the same: thanks, 68job with this FAQ before him. We would like to do the same: thanks,
85Justin! 69Justin!
86 70
87This version is much nicer than the unofficial hypertext
88versions that are archived at Utrecht, Oxford, Smart Pages, Ohio
89State, and other FAQ archives. See the resources question below
90if you want information on obtaining it in another format.
91
92The information contained here was compiled with the assistance 71The information contained here was compiled with the assistance
93of the Gnus development mailing list, and any errors or 72of the Gnus development mailing list, and any errors or
94misprints are the Gnus team's fault, sorry. 73misprints are the Gnus team's fault, sorry.
@@ -98,11 +77,9 @@ misprints are the Gnus team's fault, sorry.
98 77
99@menu 78@menu
100* FAQ 1-1:: What is the latest version of Gnus? 79* FAQ 1-1:: What is the latest version of Gnus?
101* FAQ 1-2:: What's new in 5.10? 80* FAQ 1-2:: Where and how to get Gnus?
102* FAQ 1-3:: Where and how to get Gnus? 81* FAQ 1-3:: I sometimes read references to No Gnus and Oort Gnus,
103* FAQ 1-4:: I sometimes read references to No Gnus and Oort Gnus,
104 what are those? 82 what are those?
105* FAQ 1-5:: Which version of Emacs do I need?
106@end menu 83@end menu
107 84
108@node FAQ 1-1 85@node FAQ 1-1
@@ -112,80 +89,28 @@ What is the latest version of Gnus?
112 89
113@subsubheading Answer 90@subsubheading Answer
114 91
115Jingle please: Gnus 5.10 is released, get it while it's 92The latest version of Gnus is bundled with Emacs.
116hot! As well as the step in version number is rather
117small, Gnus 5.10 has tons of new features which you
118shouldn't miss. The current release (5.13) should be at
119least as stable as the latest release of the 5.8 series.
120 93
121@node FAQ 1-2 94@node FAQ 1-2
122@subsubheading Question 1.2 95@subsubheading Question 1.2
123 96
124What's new in 5.10?
125
126@subsubheading Answer
127
128First of all, you should have a look into the file
129GNUS-NEWS in the toplevel directory of the Gnus tarball,
130there the most important changes are listed. Here's a
131short list of the changes I find especially
132important/interesting:
133
134@itemize @bullet
135
136@item
137Major rewrite of the Gnus agent, Gnus agent is now
138active by default.
139
140@item
141Many new article washing functions for dealing with
142ugly formatted articles.
143
144@item
145Anti Spam features.
146
147@item
148Message-utils now included in Gnus.
149
150@item
151New format specifiers for summary lines, e.g., %B for
152a complex trn-style thread tree.
153@end itemize
154
155@node FAQ 1-3
156@subsubheading Question 1.3
157
158Where and how to get Gnus? 97Where and how to get Gnus?
159 98
160@subsubheading Answer 99@subsubheading Answer
161 100
162Gnus is bundled with Emacs. 101Gnus is bundled with Emacs.
163 102
164@node FAQ 1-4 103@node FAQ 1-3
165@subsubheading Question 1.4 104@subsubheading Question 1.3
166 105
167I sometimes read references to No Gnus and Oort Gnus, 106I sometimes read references to No Gnus and Oort Gnus,
168what are those? 107what are those?
169 108
170@subsubheading Answer 109@subsubheading Answer
171 110
172Oort Gnus was the name of the development version of 111Oort Gnus was the name of the development version of Gnus, which
173Gnus, which became Gnus 5.10 in autumn 2003. No Gnus is 112became Gnus 5.10 in autumn 2003. No Gnus was the name of the
174the name of the current development version which will 113development version that became Gnus 5.12.
175once become Gnus 5.12 or Gnus 6. (If you're wondering why
176not 5.11, the odd version numbers are normally used for
177the Gnus versions bundled with Emacs)
178
179@node FAQ 1-5
180@subsubheading Question 1.5
181
182Which version of Emacs do I need?
183
184@subsubheading Answer
185
186Gnus 5.13 requires an Emacs version that is greater than or equal
187to Emacs 23.1, although there are some features that
188only work on Emacs 24.
189 114
190@node FAQ 2 - Startup / Group buffer 115@node FAQ 2 - Startup / Group buffer
191@subsection Startup / Group buffer 116@subsection Startup / Group buffer
@@ -718,9 +643,8 @@ in @file{~/.gnus.el} to load enough old articles to prevent teared threads, repl
718all articles (Warning: Both settings enlarge the amount of data which is 643all articles (Warning: Both settings enlarge the amount of data which is
719fetched when you enter a group and slow down the process of entering a group). 644fetched when you enter a group and slow down the process of entering a group).
720 645
721If you already use Gnus 5.10, you can say 646You can say @samp{/o N} in the summary buffer to load the last N
722@samp{/o N} 647messages.
723In summary buffer to load the last N messages, this feature is not available in 5.8.8
724 648
725If you don't want all old messages, but the parent of the message you're just reading, 649If you don't want all old messages, but the parent of the message you're just reading,
726you can say @samp{^}, if you want to retrieve the whole thread 650you can say @samp{^}, if you want to retrieve the whole thread
@@ -820,11 +744,10 @@ Can I use some other browser than w3m to render my HTML-mails?
820 744
821@subsubheading Answer 745@subsubheading Answer
822 746
823Only if you use Gnus 5.10 or younger. In this case you've got the 747You've got the choice between @samp{shr}, @samp{w3m}, @samp{links},
824choice between shr, w3m, links, lynx and html2text, which 748and @samp{lynx}. Which one is used is specified in the variable
825one is used can be specified in the variable 749@code{mm-text-html-renderer}, so if you want links to render your
826mm-text-html-renderer, so if you want links to render your 750mail, say:
827mail say
828 751
829@example 752@example
830(setq mm-text-html-renderer 'links) 753(setq mm-text-html-renderer 'links)
@@ -847,8 +770,7 @@ long lines'' (@samp{W w}), ``Decode ROT13''
847the dumb quoting used by many users of Microsoft products 770the dumb quoting used by many users of Microsoft products
848(@samp{W Y f} gives you full deuglify. 771(@samp{W Y f} gives you full deuglify.
849See @samp{W Y C-h} or have a look at the menus for 772See @samp{W Y C-h} or have a look at the menus for
850other deuglifications). Outlook deuglify is only available since 773other deuglifications).
851Gnus 5.10.
852 774
853@node FAQ 4-9 775@node FAQ 4-9
854@subsubheading Question 4.9 776@subsubheading Question 4.9
@@ -1038,7 +960,7 @@ you'll find useful things like positioning the cursor and
1038tabulators which allow you a summary in table form, but 960tabulators which allow you a summary in table form, but
1039sadly hard tabulators are broken in 5.8.8. 961sadly hard tabulators are broken in 5.8.8.
1040 962
1041Since 5.10, Gnus offers you some very nice new specifiers, 963Gnus offers you some very nice new specifiers,
1042e.g., %B which draws a thread-tree and %&user-date which 964e.g., %B which draws a thread-tree and %&user-date which
1043gives you a date where the details are dependent of the 965gives you a date where the details are dependent of the
1044articles age. Here's an example which uses both: 966articles age. Here's an example which uses both:
@@ -1245,7 +1167,7 @@ How to set stuff like From, Organization, Reply-To, signature...?
1245@subsubheading Answer 1167@subsubheading Answer
1246 1168
1247There are other ways, but you should use posting styles 1169There are other ways, but you should use posting styles
1248for this. (See below why). 1170for this. (See below why.)
1249This example should make the syntax clear: 1171This example should make the syntax clear:
1250 1172
1251@example 1173@example
@@ -1329,19 +1251,14 @@ Is there a spell-checker? Perhaps even on-the-fly spell-checking?
1329 1251
1330@subsubheading Answer 1252@subsubheading Answer
1331 1253
1332You can use ispell.el to spell-check stuff in Emacs. So the 1254You can use ispell.el to spell-check stuff in Emacs, and flyspell.el
1333first thing to do is to make sure that you've got either 1255for on-the-fly spell-checking. So the first thing to do is to make
1334@uref{https://www.cs.hmc.edu/~geoff/ispell.html, ispell} 1256sure that you've got either
1335or @uref{http://aspell.net, aspell} 1257@uref{https://hunspell.github.io/, hunspell},
1336installed and in your Path. Then you need 1258@uref{https://www.cs.hmc.edu/~geoff/ispell.html, ispell} or
1337ispell.el 1259@uref{http://aspell.net, aspell} installed and in your Path.
1338and for on-the-fly spell-checking
1339@uref{https://www-sop.inria.fr/members/Manuel.Serrano/flyspell/flyspell.html, flyspell.el}.
1340Ispell.el is shipped with Emacs,
1341flyspell.el is shipped with Emacs, so there should be no need to install them
1342manually.
1343 1260
1344Ispell.el assumes you use ispell, if you choose aspell say 1261Ispell.el assumes you use ispell. If you use aspell say
1345 1262
1346@example 1263@example
1347(setq ispell-program-name "aspell") 1264(setq ispell-program-name "aspell")
@@ -1494,14 +1411,14 @@ Now you only have to tell Gnus to include the X-face in your postings by saying
1494@end example 1411@end example
1495@noindent 1412@noindent
1496 1413
1497in @file{~/.gnus.el}. If you use Gnus 5.10, you can simply add an entry 1414in @file{~/.gnus.el}. You can add an entry
1498 1415
1499@example 1416@example
1500(x-face-file "~/.xface") 1417(x-face-file "~/.xface")
1501@end example 1418@end example
1502@noindent 1419@noindent
1503 1420
1504to gnus-posting-styles. 1421to @code{gnus-posting-styles}.
1505 1422
1506@node FAQ 5-9 1423@node FAQ 5-9
1507@subsubheading Question 5.9 1424@subsubheading Question 5.9
@@ -1519,21 +1436,6 @@ Put this in @file{~/.gnus.el}:
1519@end example 1436@end example
1520@noindent 1437@noindent
1521 1438
1522if you already use Gnus 5.10, if you still use 5.8.8 or
15235.9 try this instead:
1524
1525@example
1526(with-eval-after-load "gnus-msg"
1527 (unless (boundp 'gnus-confirm-mail-reply-to-news)
1528 (defadvice gnus-summary-reply (around reply-in-news activate)
1529 "Request confirmation when replying to news."
1530 (interactive)
1531 (when (or (not (gnus-news-group-p gnus-newsgroup-name))
1532 (y-or-n-p "Really reply by mail to article author?"))
1533 ad-do-it))))
1534@end example
1535@noindent
1536
1537@node FAQ 5-10 1439@node FAQ 5-10
1538@subsubheading Question 5.10 1440@subsubheading Question 5.10
1539 1441
@@ -1541,14 +1443,7 @@ How to tell Gnus not to generate a sender header?
1541 1443
1542@subsubheading Answer 1444@subsubheading Answer
1543 1445
1544Since 5.10 Gnus doesn't generate a sender header by 1446Gnus doesn't generate a sender header by default.
1545default. For older Gnus' try this in @file{~/.gnus.el}:
1546
1547@example
1548(with-eval-after-load "message"
1549 (add-to-list 'message-syntax-checks '(sender . disabled)))
1550@end example
1551@noindent
1552 1447
1553@node FAQ 5-11 1448@node FAQ 5-11
1554@subsubheading Question 5.11 1449@subsubheading Question 5.11
@@ -1729,7 +1624,7 @@ more then one article."
1729You can now say @samp{M-x 1624You can now say @samp{M-x
1730my-archive-article} in summary buffer to 1625my-archive-article} in summary buffer to
1731archive the article under the cursor in a nnml 1626archive the article under the cursor in a nnml
1732group. (Change nnml to your preferred back end) 1627group. (Change nnml to your preferred back end.)
1733 1628
1734Of course you can also make sure the cache is enabled by saying 1629Of course you can also make sure the cache is enabled by saying
1735 1630
@@ -1756,7 +1651,7 @@ if you found the posting there, tell Google to display
1756the raw message, look for the message-id, and say 1651the raw message, look for the message-id, and say
1757@samp{M-^ the@@message.id @key{RET}} in a 1652@samp{M-^ the@@message.id @key{RET}} in a
1758summary buffer. 1653summary buffer.
1759Since Gnus 5.10 there's also a Gnus interface for 1654There's a Gnus interface for
1760groups.google.com which you can call with 1655groups.google.com which you can call with
1761@samp{G W}) in group buffer. 1656@samp{G W}) in group buffer.
1762 1657
@@ -1770,25 +1665,6 @@ instead. Further on there are the
1770gnus-summary-limit-to-foo functions, which can help you, 1665gnus-summary-limit-to-foo functions, which can help you,
1771too. 1666too.
1772 1667
1773Of course you can also use grep to search through your
1774local mail, but this is both slow for big archives and
1775inconvenient since you are not displaying the found mail
1776in Gnus. Here nnir comes into action. Nnir is a front end
1777to search engines like swish-e or swish++ and
1778others. You index your mail with one of those search
1779engines and with the help of nnir you can search through
1780the indexed mail and generate a temporary group with all
1781messages which met your search criteria. If this sounds
1782cool to you, get nnir.el from
1783@c FIXME Isn't this file in Gnus?
1784@ignore
1785@c Dead link 2013/7.
1786@uref{ftp://ls6-ftp.cs.uni-dortmund.de/pub/src/emacs/}
1787or
1788@end ignore
1789@uref{ftp://ftp.is.informatik.uni-duisburg.de/pub/src/emacs/}.
1790Instructions on how to use it are at the top of the file.
1791
1792@node FAQ 6-4 1668@node FAQ 6-4
1793@subsubheading Question 6.4 1669@subsubheading Question 6.4
1794 1670
@@ -1937,16 +1813,9 @@ So what was this thing about the Agent?
1937The Gnus agent is part of Gnus, it allows you to fetch 1813The Gnus agent is part of Gnus, it allows you to fetch
1938mail and news and store them on disk for reading them 1814mail and news and store them on disk for reading them
1939later when you're offline. It kind of mimics offline 1815later when you're offline. It kind of mimics offline
1940newsreaders like Forte Agent. If you want to use 1816newsreaders like Forte Agent. It is enabled by default.
1941the Agent place the following in @file{~/.gnus.el} if you are
1942still using 5.8.8 or 5.9 (it's the default since 5.10):
1943 1817
1944@example 1818You've got to select the servers whose groups can be
1945(setq gnus-agent t)
1946@end example
1947@noindent
1948
1949Now you've got to select the servers whose groups can be
1950stored locally. To do this, open the server buffer 1819stored locally. To do this, open the server buffer
1951(that is press @samp{^} while in the 1820(that is press @samp{^} while in the
1952group buffer). Now select a server by moving point to 1821group buffer). Now select a server by moving point to
@@ -2161,12 +2030,12 @@ How to speed up the process of entering a group?
2161 2030
2162@subsubheading Answer 2031@subsubheading Answer
2163 2032
2164A speed killer is setting the variable 2033A speed killer is setting the variable @code{gnus-fetch-old-headers}
2165gnus-fetch-old-headers to anything different from @code{nil}, 2034to anything different from @code{nil}, so don't do this if speed is an
2166so don't do this if speed is an issue. 2035issue.
2167 2036
2168You could increase the value of gc-cons-threshold 2037You could increase the value of @code{gc-cons-threshold} by saying
2169by saying something like 2038something like:
2170 2039
2171@example 2040@example
2172(setq gc-cons-threshold 3500000) 2041(setq gc-cons-threshold 3500000)
@@ -2204,10 +2073,6 @@ between core Gnus and the real NNTP-, POP3-, IMAP- or
2204whatever-server which offers Gnus a standardized interface 2073whatever-server which offers Gnus a standardized interface
2205to functions like "get message", "get Headers" etc. 2074to functions like "get message", "get Headers" etc.
2206 2075
2207@item Emacs
2208When the term Emacs is used in this FAQ, it means GNU
2209Emacs.
2210
2211@item Message 2076@item Message
2212In this FAQ message means either a mail or a posting to a 2077In this FAQ message means either a mail or a posting to a
2213Usenet Newsgroup or to some other fancy back end, no matter 2078Usenet Newsgroup or to some other fancy back end, no matter
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 7da90dfb1d6..c5298d8ef59 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -885,8 +885,6 @@ History
885* Why?:: What's the point of Gnus? 885* Why?:: What's the point of Gnus?
886* Compatibility:: Just how compatible is Gnus with @sc{gnus}? 886* Compatibility:: Just how compatible is Gnus with @sc{gnus}?
887* Conformity:: Gnus tries to conform to all standards. 887* Conformity:: Gnus tries to conform to all standards.
888* Emacsen:: Gnus can be run on a few modern Emacsen.
889* Gnus Development:: How Gnus is developed.
890* Contributors:: Oodles of people. 888* Contributors:: Oodles of people.
891* New Features:: Pointers to some of the new stuff in Gnus. 889* New Features:: Pointers to some of the new stuff in Gnus.
892 890
@@ -8621,14 +8619,6 @@ uuencoded files that have had trailing spaces deleted.
8621@vindex gnus-uu-pre-uudecode-hook 8619@vindex gnus-uu-pre-uudecode-hook
8622Hook run before sending a message to @code{uudecode}. 8620Hook run before sending a message to @code{uudecode}.
8623 8621
8624@item gnus-uu-view-with-metamail
8625@vindex gnus-uu-view-with-metamail
8626@cindex metamail
8627Non-@code{nil} means that @code{gnus-uu} will ignore the viewing
8628commands defined by the rule variables and just fudge a @acronym{MIME}
8629content type based on the file name. The result will be fed to
8630@code{metamail} for viewing.
8631
8632@item gnus-uu-save-in-digest 8622@item gnus-uu-save-in-digest
8633@vindex gnus-uu-save-in-digest 8623@vindex gnus-uu-save-in-digest
8634Non-@code{nil} means that @code{gnus-uu}, when asked to save without 8624Non-@code{nil} means that @code{gnus-uu}, when asked to save without
@@ -9364,9 +9354,6 @@ Use @uref{https://almende.github.io/chap-links-library/, CHAP Links}.
9364@item lynx 9354@item lynx
9365Use @uref{https://lynx.browser.org/, Lynx}. 9355Use @uref{https://lynx.browser.org/, Lynx}.
9366 9356
9367@item html2text
9368Use html2text---a simple @acronym{HTML} converter included with Gnus.
9369
9370@end table 9357@end table
9371 9358
9372@item W D F 9359@item W D F
@@ -15440,8 +15427,6 @@ files. If a positive number, delete files older than number of days
15440(the deletion will only happen when receiving new mail). You may also 15427(the deletion will only happen when receiving new mail). You may also
15441set @code{mail-source-delete-incoming} to @code{nil} and call 15428set @code{mail-source-delete-incoming} to @code{nil} and call
15442@code{mail-source-delete-old-incoming} from a hook or interactively. 15429@code{mail-source-delete-old-incoming} from a hook or interactively.
15443@code{mail-source-delete-incoming} defaults to @code{10} in alpha Gnusae
15444and @code{2} in released Gnusae. @xref{Gnus Development}.
15445 15430
15446@item mail-source-delete-old-incoming-confirm 15431@item mail-source-delete-old-incoming-confirm
15447@vindex mail-source-delete-old-incoming-confirm 15432@vindex mail-source-delete-old-incoming-confirm
@@ -21962,7 +21947,7 @@ you can set up a local @acronym{IMAP} server, which you then access via
21962@code{nnimap}. This is a rather massive setup for accessing some mbox 21947@code{nnimap}. This is a rather massive setup for accessing some mbox
21963files, so just change to MH or Maildir already... However, if you're 21948files, so just change to MH or Maildir already... However, if you're
21964really, really passionate about using mbox, you might want to look into 21949really, really passionate about using mbox, you might want to look into
21965the package @file{mairix.el}, which comes with Emacs 23. 21950the package @file{mairix.el}, which comes with Emacs.
21966 21951
21967@node What nnmairix does 21952@node What nnmairix does
21968@subsection What nnmairix does 21953@subsection What nnmairix does
@@ -26919,8 +26904,6 @@ renamed it back again to ``Gnus''. But in mixed case. ``Gnus'' vs.
26919* Why?:: What's the point of Gnus? 26904* Why?:: What's the point of Gnus?
26920* Compatibility:: Just how compatible is Gnus with @sc{gnus}? 26905* Compatibility:: Just how compatible is Gnus with @sc{gnus}?
26921* Conformity:: Gnus tries to conform to all standards. 26906* Conformity:: Gnus tries to conform to all standards.
26922* Emacsen:: Gnus can be run on a few modern Emacsen.
26923* Gnus Development:: How Gnus is developed.
26924* Contributors:: Oodles of people. 26907* Contributors:: Oodles of people.
26925* New Features:: Pointers to some of the new stuff in Gnus. 26908* New Features:: Pointers to some of the new stuff in Gnus.
26926@end menu 26909@end menu
@@ -27035,16 +27018,6 @@ maintains a hash table that points to the entries in this alist (which
27035speeds up many functions), and changing the alist directly will lead to 27018speeds up many functions), and changing the alist directly will lead to
27036peculiar results. 27019peculiar results.
27037 27020
27038@cindex hilit19
27039@cindex highlighting
27040Old hilit19 code does not work at all. In fact, you should probably
27041remove all hilit code from all Gnus hooks
27042(@code{gnus-group-prepare-hook} and @code{gnus-summary-prepare-hook}).
27043Gnus provides various integrated functions for highlighting. These are
27044faster and more accurate. To make life easier for everybody, Gnus will
27045by default remove all hilit calls from all hilit hooks. Uncleanliness!
27046Away!
27047
27048Packages like @code{expire-kill} will no longer work. As a matter of 27021Packages like @code{expire-kill} will no longer work. As a matter of
27049fact, you should probably remove all old @sc{gnus} packages (and other 27022fact, you should probably remove all old @sc{gnus} packages (and other
27050code) when you start using Gnus. More likely than not, Gnus already 27023code) when you start using Gnus. More likely than not, Gnus already
@@ -27147,79 +27120,6 @@ mentioned above, don't hesitate to drop a note to Gnus Towers and let us
27147know. 27120know.
27148 27121
27149 27122
27150@node Emacsen
27151@subsection Emacsen
27152@cindex Emacsen
27153@cindex Mule
27154@cindex Emacs
27155
27156This version of Gnus should work on:
27157
27158@itemize @bullet
27159
27160@item
27161Emacs 23.1 and up.
27162
27163@end itemize
27164
27165This Gnus version will absolutely not work on any Emacsen older than
27166that. Not reliably, at least. Older versions of Gnus may work on older
27167Emacs versions. Particularly, Gnus 5.10.8 should also work on Emacs
2716820.7.
27169
27170@c No-merge comment: The paragraph added in v5-10 here must not be
27171@c synced here!
27172
27173@node Gnus Development
27174@subsection Gnus Development
27175
27176Gnus is developed in a two-phased cycle. The first phase involves much
27177discussion on the development mailing list @samp{ding@@gnus.org}, where people
27178propose changes and new features, post patches and new back ends. This
27179phase is called the @dfn{alpha} phase, since the Gnusae released in this
27180phase are @dfn{alpha releases}, or (perhaps more commonly in other
27181circles) @dfn{snapshots}. During this phase, Gnus is assumed to be
27182unstable and should not be used by casual users. Gnus alpha releases
27183have names like ``Oort Gnus'' and ``No Gnus''. @xref{Gnus Versions}.
27184
27185After futzing around for 10--100 alpha releases, Gnus is declared
27186@dfn{frozen}, and only bug fixes are applied. Gnus loses the prefix,
27187and is called things like ``Gnus 5.10.1'' instead. Normal people are
27188supposed to be able to use these, and these are mostly discussed on the
27189@samp{gnu.emacs.gnus} newsgroup. This newgroup is mirrored to the
27190mailing list @samp{info-gnus-english@@gnu.org} which is carried on Gmane
27191as @samp{gmane.emacs.gnus.user}. These releases are finally integrated
27192in Emacs.
27193
27194@cindex Incoming*
27195@vindex mail-source-delete-incoming
27196Some variable defaults differ between alpha Gnusae and released Gnusae,
27197in particular, @code{mail-source-delete-incoming}. This is to prevent
27198lossage of mail if an alpha release hiccups while handling the mail.
27199@xref{Mail Source Customization}.
27200
27201The division of discussion between the ding mailing list and the Gnus
27202newsgroup is not purely based on publicity concerns. It's true that
27203having people write about the horrible things that an alpha Gnus release
27204can do (sometimes) in a public forum may scare people off, but more
27205importantly, talking about new experimental features that have been
27206introduced may confuse casual users. New features are frequently
27207introduced, fiddled with, and judged to be found wanting, and then
27208either discarded or totally rewritten. People reading the mailing list
27209usually keep up with these rapid changes, while people on the newsgroup
27210can't be assumed to do so.
27211
27212So if you have problems with or questions about the alpha versions,
27213direct those to the ding mailing list @samp{ding@@gnus.org}. This list
27214is also available on Gmane as @samp{gmane.emacs.gnus.general}.
27215
27216@cindex Incoming*
27217@vindex mail-source-delete-incoming
27218Some variable defaults differ between alpha Gnusae and released Gnusae,
27219in particular, @code{mail-source-delete-incoming}. This is to prevent
27220lossage of mail if an alpha release hiccups while handling the mail.
27221@xref{Mail Source Customization}.
27222
27223@node Contributors 27123@node Contributors
27224@subsection Contributors 27124@subsection Contributors
27225@cindex contributors 27125@cindex contributors
diff --git a/doc/misc/htmlfontify.texi b/doc/misc/htmlfontify.texi
index 0ab000b70f1..fadc6a5cbe3 100644
--- a/doc/misc/htmlfontify.texi
+++ b/doc/misc/htmlfontify.texi
@@ -10,8 +10,7 @@
10This manual documents Htmlfontify, a source code -> crosslinked + 10This manual documents Htmlfontify, a source code -> crosslinked +
11formatted + syntax colorized html transformer. 11formatted + syntax colorized html transformer.
12 12
13Copyright @copyright{} 2002--2003, 2013--2022 Free Software Foundation, 13Copyright @copyright{} 2002--2022 Free Software Foundation, Inc.
14Inc.
15 14
16@quotation 15@quotation
17Permission is granted to copy, distribute and/or modify this document 16Permission is granted to copy, distribute and/or modify this document
@@ -1540,13 +1539,6 @@ Htmlfontify has a couple of external requirements:
1540@itemize @bullet 1539@itemize @bullet
1541 1540
1542@item 1541@item
1543GNU Emacs 20.7+ or 21.1+
1544
1545Other versions may work---these have been used successfully by the
1546author. If you intend to use Htmlfontify in batch mode, 21.1+ is
1547pretty much required.
1548
1549@item
1550A copy of etags (exuberant-ctags or GNU etags). Htmlfontify attempts 1542A copy of etags (exuberant-ctags or GNU etags). Htmlfontify attempts
1551to autodetect the version you have and customize itself accordingly, 1543to autodetect the version you have and customize itself accordingly,
1552but you should be able to override this. 1544but you should be able to override this.
diff --git a/doc/misc/idlwave.texi b/doc/misc/idlwave.texi
index 6aaa4309a16..0ba87b2e58b 100644
--- a/doc/misc/idlwave.texi
+++ b/doc/misc/idlwave.texi
@@ -4116,17 +4116,6 @@ configuration files (e.g., @file{.cshrc}), but from the file
4116@file{~/.MacOSX/environment.plist}. Either include your path settings 4116@file{~/.MacOSX/environment.plist}. Either include your path settings
4117there, or start Emacs and IDLWAVE from the shell. 4117there, or start Emacs and IDLWAVE from the shell.
4118 4118
4119@item @strong{I'm getting errors like @samp{Symbol's value as variable is void:
4120cl-builtin-gethash} on completion or routine info.}
4121
4122This error arises if you upgraded Emacs from 20.x to 21.x without
4123re-installing IDLWAVE@. Old Emacs and new Emacs are not byte-compatible
4124in compiled lisp files. Presumably, you kept the original .elc files in
4125place, and this is the source of the error. If you recompile (or just
4126"make; make install") from source, it should resolve this problem.
4127Another option is to recompile the @file{idlw*.el} files by hand using
4128@kbd{M-x byte-compile-file}.
4129
4130@item @strong{@kbd{M-@key{TAB}} doesn't complete words, it switches 4119@item @strong{@kbd{M-@key{TAB}} doesn't complete words, it switches
4131windows on my desktop.} 4120windows on my desktop.}
4132 4121
diff --git a/doc/misc/message.texi b/doc/misc/message.texi
index 29fbdfe1786..49e3faed7b1 100644
--- a/doc/misc/message.texi
+++ b/doc/misc/message.texi
@@ -1152,12 +1152,11 @@ programs are required to make things work, and some small general hints.
1152@uref{https://www.gnupg.org/, GNU Privacy Guard} or 1152@uref{https://www.gnupg.org/, GNU Privacy Guard} or
1153@uref{https://www.openssl.org/, OpenSSL}. The default Emacs interface 1153@uref{https://www.openssl.org/, OpenSSL}. The default Emacs interface
1154to the S/MIME implementation is EasyPG (@pxref{Top,,EasyPG Assistant 1154to the S/MIME implementation is EasyPG (@pxref{Top,,EasyPG Assistant
1155User's Manual, epa, EasyPG Assistant User's Manual}), which has been 1155User's Manual, epa, EasyPG Assistant User's Manual}), which is
1156included in Emacs since version 23 and which relies on the command 1156included in Emacs and relies on the command line tool @command{gpgsm}
1157line tool @command{gpgsm} provided by @acronym{GnuPG}. That tool 1157provided by @acronym{GnuPG}. That tool implements certificate
1158implements certificate management, including certificate revocation 1158management, including certificate revocation and expiry, while such
1159and expiry, while such tasks need to be performed manually, if OpenSSL 1159tasks need to be performed manually, if OpenSSL is used.
1160is used.
1161 1160
1162The choice between EasyPG and OpenSSL is controlled by the variable 1161The choice between EasyPG and OpenSSL is controlled by the variable
1163@code{mml-smime-use}, which needs to be set to the value @code{epg} 1162@code{mml-smime-use}, which needs to be set to the value @code{epg}
diff --git a/doc/misc/mh-e.texi b/doc/misc/mh-e.texi
index 12841860d91..6a948ce2ca8 100644
--- a/doc/misc/mh-e.texi
+++ b/doc/misc/mh-e.texi
@@ -213,8 +213,8 @@ more niceties about GNU Emacs and MH@. Now I'm fully hooked on both of
213them. 213them.
214 214
215The MH-E package is distributed with Emacs@footnote{Version 215The MH-E package is distributed with Emacs@footnote{Version
216@value{VERSION} of MH-E appeared in Emacs 24.4. It is supported in GNU 216@value{VERSION} of MH-E appeared in Emacs 24.4.
217Emacs 23 and higher. It is compatible with MH versions 6.8.4 and 217It is compatible with MH versions 6.8.4 and
218higher, all versions of nmh, and GNU mailutils 1.0 and higher}, so you 218higher, all versions of nmh, and GNU mailutils 1.0 and higher}, so you
219shouldn't have to do anything special to use it. Gnus is also 219shouldn't have to do anything special to use it. Gnus is also
220required; version 5.10 or higher is recommended. This manual covers 220required; version 5.10 or higher is recommended. This manual covers
@@ -1488,7 +1488,7 @@ Binding} of @samp{m}.
1488@cindex Unix commands, @command{xbuffy} 1488@cindex Unix commands, @command{xbuffy}
1489 1489
1490You can use @command{xbuffy} to automate the incorporation of this 1490You can use @command{xbuffy} to automate the incorporation of this
1491mail using the Emacs 23 command @command{emacsclient} as follows: 1491mail using the Emacs command @command{emacsclient} as follows:
1492 1492
1493@smallexample 1493@smallexample
1494box ~/mail/mh-e 1494box ~/mail/mh-e
@@ -2553,13 +2553,6 @@ produces pretty nice output, and it highlights links. It renders
2553@samp{&ndash;} and @samp{&reg;} okay. It sometimes fails to wrap lines 2553@samp{&ndash;} and @samp{&reg;} okay. It sometimes fails to wrap lines
2554properly. It always downloads remote images. 2554properly. It always downloads remote images.
2555@c ------------------------- 2555@c -------------------------
2556@cindex browser, @samp{html2text}
2557@cindex @samp{html2text}
2558@item @samp{html2text}
2559The @samp{html2text} browser requires an external program. Some users
2560have reported problems with it, such as filling the entire message as
2561if it were one paragraph, or displaying chunks of raw HTML.
2562@c -------------------------
2563@cindex browser, @samp{links} 2556@cindex browser, @samp{links}
2564@cindex @samp{links} 2557@cindex @samp{links}
2565@item @samp{links} 2558@item @samp{links}
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index cfbc96f4692..924aa66d444 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -3383,7 +3383,7 @@ names. Beside the @code{default} value, @var{syntax} can be
3383@item @code{simplified} 3383@item @code{simplified}
3384@cindex simplified syntax 3384@cindex simplified syntax
3385 3385
3386The remote file name syntax is similar to the syntax used by Ange FTP@. 3386This remote file name syntax is similar to the syntax used by Ange FTP@.
3387A remote file name has the form 3387A remote file name has the form
3388@code{@value{prefix}user@@host@value{postfix}path/to/file}. The 3388@code{@value{prefix}user@@host@value{postfix}path/to/file}. The
3389@code{user@@} part is optional, and the method is determined by 3389@code{user@@} part is optional, and the method is determined by
@@ -3395,7 +3395,7 @@ A remote file name has the form
3395@clear unified 3395@clear unified
3396@set separate 3396@set separate
3397@include trampver.texi 3397@include trampver.texi
3398The remote file name syntax is similar to the syntax used by XEmacs. 3398This remote file name syntax originated in the XEmacs text editor.
3399A remote file name has the form 3399A remote file name has the form
3400@code{@trampfn{method,user@@host,path/to/file}}. The @code{method} 3400@code{@trampfn{method,user@@host,path/to/file}}. The @code{method}
3401and @code{user@@} parts are optional. 3401and @code{user@@} parts are optional.
diff --git a/doc/misc/viper.texi b/doc/misc/viper.texi
index b0deb31d108..0703667ecce 100644
--- a/doc/misc/viper.texi
+++ b/doc/misc/viper.texi
@@ -1842,7 +1842,7 @@ usually most effective:
1842(set-face-background viper-replace-overlay-face "yellow") 1842(set-face-background viper-replace-overlay-face "yellow")
1843@end smallexample 1843@end smallexample
1844For a complete list of colors available to you, evaluate the expression 1844For a complete list of colors available to you, evaluate the expression
1845@code{(x-defined-colors)}. (Type it in the buffer @file{*scratch*} and then 1845@code{(defined-colors)}. (Type it in the buffer @file{*scratch*} and then
1846hit the @kbd{C-j} key. 1846hit the @kbd{C-j} key.
1847 1847
1848@item viper-replace-overlay-cursor-color "Red" 1848@item viper-replace-overlay-cursor-color "Red"
@@ -2571,7 +2571,7 @@ The GNU Emacs Manual}, for more information on tags.
2571 2571
2572The following two commands are normally bound to a mouse click and are part 2572The following two commands are normally bound to a mouse click and are part
2573of Viper. They work only if Emacs runs as an application under X 2573of Viper. They work only if Emacs runs as an application under X
2574Windows (or under some other window system for which a port of GNU Emacs 20 2574Windows (or under some other window system for which a port of GNU Emacs
2575is available). Clicking the mouse when Emacs is invoked in an Xterm window 2575is available). Clicking the mouse when Emacs is invoked in an Xterm window
2576(using @code{emacs -nw}) will do no good. 2576(using @code{emacs -nw}) will do no good.
2577 2577
diff --git a/etc/AUTHORS b/etc/AUTHORS
index 4ad8a54130d..f6349df5bc2 100644
--- a/etc/AUTHORS
+++ b/etc/AUTHORS
@@ -6062,6 +6062,6 @@ Zoran Milojevic: changed avoid.el
6062উৎসব রায়: changed quail/indian.el 6062উৎসব রায়: changed quail/indian.el
6063 6063
6064Local Variables: 6064Local Variables:
6065mode: etc-authors 6065mode: emacs-authors
6066coding: utf-8 6066coding: utf-8
6067End: 6067End:
diff --git a/etc/NEWS b/etc/NEWS
index 8d54ccc0dc8..c982684d3a9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -385,6 +385,10 @@ longer choke when a buffer on display contains long lines. The
385variable 'long-line-threshold' controls whether and when these display 385variable 'long-line-threshold' controls whether and when these display
386optimizations are in effect. 386optimizations are in effect.
387 387
388A companion variable 'large-hscroll-threshold' controls when another
389set of display optimizations are in effect, which are aimed
390specifically at speeding up display of long lines that are truncated.
391
388If you still experience slowdowns while editing files with long lines, 392If you still experience slowdowns while editing files with long lines,
389this may be due to line truncation, or to one of the enabled minor 393this may be due to line truncation, or to one of the enabled minor
390modes, or to the current major mode. Try turning off line truncation 394modes, or to the current major mode. Try turning off line truncation
@@ -396,6 +400,9 @@ and the major mode with 'M-x so-long-mode', or visit the file with
396Note that the display optimizations in these cases may cause the 400Note that the display optimizations in these cases may cause the
397buffer to be occasionally mis-fontified. 401buffer to be occasionally mis-fontified.
398 402
403The new function 'long-line-optimizations-p' returns non-nil when
404these optimizations are in effect in the current buffer.
405
399+++ 406+++
400** New command to change the font size globally. 407** New command to change the font size globally.
401To increase the font size, type 'C-x C-M-+' or 'C-x C-M-='; to 408To increase the font size, type 'C-x C-M-+' or 'C-x C-M-='; to
@@ -454,7 +461,7 @@ duplicated on its right-hand side.
454 461
455+++ 462+++
456** 'network-lookup-address-info' can now check numeric IP address validity. 463** 'network-lookup-address-info' can now check numeric IP address validity.
457Specifying 'numeric as the new optional 'hints' argument makes it 464Specifying 'numeric' as the new optional 'hints' argument makes it
458check if the passed address is a valid IPv4/IPv6 address (without DNS 465check if the passed address is a valid IPv4/IPv6 address (without DNS
459traffic). 466traffic).
460 467
@@ -1250,6 +1257,12 @@ be used as a file-local variable.
1250If given a prefix, it will query the user for an argument to use for 1257If given a prefix, it will query the user for an argument to use for
1251the run/continue command. 1258the run/continue command.
1252 1259
1260---
1261*** 'perldb' now recognizes '-E'.
1262As of Perl 5.10, 'perl -E 0' behaves like 'perl -e 0' but also activates
1263all optional features of the Perl version in use. 'perldb' now uses
1264this invocation as its default.
1265
1253** Customize 1266** Customize
1254 1267
1255--- 1268---
@@ -1265,7 +1278,6 @@ Sets the value of the buffer-local variable 'whitespace-style' in
1265'diff-mode' buffers. By default, this variable is '(face trailing)', 1278'diff-mode' buffers. By default, this variable is '(face trailing)',
1266which preserves behavior from previous Emacs versions. 1279which preserves behavior from previous Emacs versions.
1267 1280
1268
1269** Ispell 1281** Ispell
1270 1282
1271--- 1283---
@@ -1339,6 +1351,13 @@ When invoked with a non-zero prefix argument, as in 'C-u C-x C-e',
1339this command will pop up a new buffer and show the full pretty-printed 1351this command will pop up a new buffer and show the full pretty-printed
1340value there. 1352value there.
1341 1353
1354+++
1355*** You can now generate a backtrace from Lisp errors in redisplay.
1356To do this, set the new variable 'backtrace-on-redisplay-error' to a
1357non-nil value. The backtrace will be written to a special buffer
1358named "*Redisplay-trace*". This buffer will not be automatically
1359displayed in a window.
1360
1342** Compile 1361** Compile
1343 1362
1344+++ 1363+++
@@ -1741,11 +1760,6 @@ The new ':doc-spec-function' element can be used to compute the
1741':doc-spec' element when the user asks for info on that particular 1760':doc-spec' element when the user asks for info on that particular
1742mode (instead of at load time). 1761mode (instead of at load time).
1743 1762
1744** Subr-x
1745
1746+++
1747*** New macro 'with-memoization' provides a very primitive form of memoization.
1748
1749** Ansi-color 1763** Ansi-color
1750 1764
1751--- 1765---
@@ -2035,7 +2049,7 @@ This command displays a buffer containing the page load history of
2035the current WebKit widget, and allows you to navigate it. 2049the current WebKit widget, and allows you to navigate it.
2036 2050
2037--- 2051---
2038*** On X11, the WebKit inspector is now available inside xwidgets. 2052*** On X, the WebKit inspector is now available inside xwidgets.
2039To access the inspector, right click on the widget and select "Inspect 2053To access the inspector, right click on the widget and select "Inspect
2040Element". 2054Element".
2041 2055
@@ -2149,6 +2163,13 @@ Additionally, globs ending with '**/' or '***/' no longer raise an
2149error, and now expand to all directories recursively (following 2163error, and now expand to all directories recursively (following
2150symlinks in the latter case). 2164symlinks in the latter case).
2151 2165
2166+++
2167*** Lisp forms in Eshell now treat a 'nil' result as a failed exit status.
2168When executing a command that looks like '(lisp form)', Eshell will
2169set the exit status (available in the '$?' variable) to 2. This
2170allows commands like that to be used as conditionals. To change this
2171behavior, customize the new 'eshell-lisp-form-nil-is-failure' option.
2172
2152** Shell 2173** Shell
2153 2174
2154--- 2175---
@@ -2229,10 +2250,10 @@ instead of also trying to ping it. Customize the user option
2229To respect Emacs naming conventions, the variable 'unread-bib-file' 2250To respect Emacs naming conventions, the variable 'unread-bib-file'
2230has been renamed to 'bib-unread-file'. The following commands have 2251has been renamed to 'bib-unread-file'. The following commands have
2231also been renamed: 2252also been renamed:
2232 'addbib' to 'bib-add' 2253 'addbib' to 'bib-add'
2233 'return-key-bib' to 'bib-return-key' 2254 'return-key-bib' to 'bib-return-key'
2234 'mark-bib' to 'bib-mark' 2255 'mark-bib' to 'bib-mark'
2235 'unread-bib' to 'bib-unread' 2256 'unread-bib' to 'bib-unread'
2236 2257
2237--- 2258---
2238*** proced.el shows system processes of remote hosts. 2259*** proced.el shows system processes of remote hosts.
@@ -2551,6 +2572,18 @@ patcomp.el, pc-mode.el, pc-select.el, s-region.el, and sregex.el.
2551* Lisp Changes in Emacs 29.1 2572* Lisp Changes in Emacs 29.1
2552 2573
2553+++ 2574+++
2575** New function 'compiled-function-p'.
2576This returns non-nil if its argument is either a built-in, or a
2577byte-compiled, or a natively-compiled function object, or a function
2578loaded from a dynamic module.
2579
2580---
2581** 'deactivate-mark' can have new value 'dont-save'.
2582This value means that Emacs should deactivate the mark as usual, but
2583without setting the primary selection, if 'select-active-regions' is
2584enabled.
2585
2586+++
2554** New 'declare' form 'interactive-args'. 2587** New 'declare' form 'interactive-args'.
2555This can be used to specify what forms to put into 'command-history' 2588This can be used to specify what forms to put into 'command-history'
2556when executing commands interactively. 2589when executing commands interactively.
@@ -2562,8 +2595,8 @@ compiler now emits a warning about this deprecated usage.
2562 2595
2563+++ 2596+++
2564** Emacs now supports user-customizable and themable icons. 2597** Emacs now supports user-customizable and themable icons.
2565These can be used for buttons in buffers and the like. See 2598These can be used for buttons in buffers and the like. See the
2566'(elisp)Icons' and '(emacs)Icons' for details. 2599"(elisp) Icons" and "(emacs) Icons" nodes in the manuals for details.
2567 2600
2568+++ 2601+++
2569** New arguments MESSAGE and TIMEOUT of 'set-transient-map'. 2602** New arguments MESSAGE and TIMEOUT of 'set-transient-map'.
@@ -2624,11 +2657,13 @@ things to be saved.
2624** New function 'string-equal-ignore-case'. 2657** New function 'string-equal-ignore-case'.
2625This compares strings ignoring case differences. 2658This compares strings ignoring case differences.
2626 2659
2627--- 2660** 'symbol-file' can now report natively-compiled ".eln" files.
2628** 'symbol-file' can now report natively-compiled .eln files.
2629If Emacs was built with native-compilation enabled, Lisp programs can 2661If Emacs was built with native-compilation enabled, Lisp programs can
2630now call 'symbol-file' with the new optional 3rd argument non-nil to 2662now call 'symbol-file' with the new optional 3rd argument non-nil to
2631request the name of the .eln file which defined a given symbol. 2663request the name of the ".eln" file which defined a given symbol.
2664
2665+++
2666** New macro 'with-memoization' provides a very primitive form of memoization.
2632 2667
2633** Themes 2668** Themes
2634 2669
@@ -2860,7 +2895,7 @@ This is like 'get-text-property', but works on the 'display' text
2860property. 2895property.
2861 2896
2862+++ 2897+++
2863** New function 'add-text-display-property'. 2898** New function 'add-display-text-property'.
2864This is like 'put-text-property', but works on the 'display' text 2899This is like 'put-text-property', but works on the 'display' text
2865property. 2900property.
2866 2901
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 98c8d0c3026..6624f747c87 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -3435,14 +3435,6 @@ The fix is to install a newer version of ncurses, such as version 4.2.
3435Bootstrapping (compiling the .el files) is normally only necessary 3435Bootstrapping (compiling the .el files) is normally only necessary
3436with development builds, since the .elc files are pre-compiled in releases. 3436with development builds, since the .elc files are pre-compiled in releases.
3437 3437
3438*** "No rule to make target" with Ubuntu 8.04 make 3.81-3build1
3439
3440Compiling the lisp files fails at random places, complaining:
3441"No rule to make target '/path/to/some/lisp.elc'".
3442The causes of this problem are not understood. Using GNU make 3.81 compiled
3443from source, rather than the Ubuntu version, worked.
3444See <URL:https://debbugs.gnu.org/327>, <URL:https://debbugs.gnu.org/821>.
3445
3446** Dumping 3438** Dumping
3447 3439
3448*** Segfault during 'make' 3440*** Segfault during 'make'
@@ -3567,6 +3559,15 @@ This section covers bugs reported on very old hardware or software.
3567If you are using hardware and an operating system shipped after 2000, 3559If you are using hardware and an operating system shipped after 2000,
3568it is unlikely you will see any of these. 3560it is unlikely you will see any of these.
3569 3561
3562** GNU/Linux
3563
3564*** Ubuntu 8.04 make 3.81-3build1: "No rule to make target"
3565Compiling the lisp files fails at random places, complaining:
3566"No rule to make target '/path/to/some/lisp.elc'".
3567The causes of this problem are not understood. Using GNU make 3.81 compiled
3568from source, rather than the Ubuntu version, worked.
3569See <URL:https://debbugs.gnu.org/327>, <URL:https://debbugs.gnu.org/821>.
3570
3570** Solaris 3571** Solaris
3571 3572
3572*** Problem with remote X server on Suns. 3573*** Problem with remote X server on Suns.
diff --git a/lisp/array.el b/lisp/array.el
index 08c5ff45ddd..aed93ffb65b 100644
--- a/lisp/array.el
+++ b/lisp/array.el
@@ -103,7 +103,7 @@ Set them to the optional arguments A-ROW and A-COLUMN if those are supplied."
103 103
104(defun array-update-buffer-position () 104(defun array-update-buffer-position ()
105 "Set `array-buffer-line' and `array-buffer-column' to their current values." 105 "Set `array-buffer-line' and `array-buffer-column' to their current values."
106 (setq array-buffer-line (current-line) 106 (setq array-buffer-line (array-current-line)
107 array-buffer-column (current-column))) 107 array-buffer-column (current-column)))
108 108
109 109
@@ -113,7 +113,7 @@ Set them to the optional arguments A-ROW and A-COLUMN if those are supplied."
113(defun array-what-position () 113(defun array-what-position ()
114 "Display the row and column in which the cursor is positioned." 114 "Display the row and column in which the cursor is positioned."
115 (interactive) 115 (interactive)
116 (let ((array-buffer-line (current-line)) 116 (let ((array-buffer-line (array-current-line))
117 (array-buffer-column (current-column))) 117 (array-buffer-column (current-column)))
118 (message "Array row: %s Array column: %s" 118 (message "Array row: %s Array column: %s"
119 (prin1-to-string (array-current-row)) 119 (prin1-to-string (array-current-row))
@@ -147,13 +147,13 @@ Set them to the optional arguments A-ROW and A-COLUMN if those are supplied."
147;;; Internal movement functions. 147;;; Internal movement functions.
148 148
149(defun array-beginning-of-field (&optional go-there) 149(defun array-beginning-of-field (&optional go-there)
150 "Return the column of the beginning of the current field. 150 "Return the column of the beginning of the current field.
151Optional argument GO-THERE, if non-nil, means go there too." 151Optional argument GO-THERE, if non-nil, means go there too."
152 ;; Requires that array-buffer-column be current. 152 ;; Requires that array-buffer-column be current.
153 (let ((goal-column (- array-buffer-column (% array-buffer-column array-field-width)))) 153 (let ((goal-column (- array-buffer-column (% array-buffer-column array-field-width))))
154 (if go-there 154 (if go-there
155 (move-to-column-untabify goal-column) 155 (array-move-to-column-untabify goal-column)
156 goal-column))) 156 goal-column)))
157 157
158(defun array-end-of-field (&optional go-there) 158(defun array-end-of-field (&optional go-there)
159 "Return the column of the end of the current array field. 159 "Return the column of the end of the current array field.
@@ -162,7 +162,7 @@ If optional argument GO-THERE is non-nil, go there too."
162 (let ((goal-column (+ (- array-buffer-column (% array-buffer-column array-field-width)) 162 (let ((goal-column (+ (- array-buffer-column (% array-buffer-column array-field-width))
163 array-field-width))) 163 array-field-width)))
164 (if go-there 164 (if go-there
165 (move-to-column-untabify goal-column) 165 (array-move-to-column-untabify goal-column)
166 goal-column))) 166 goal-column)))
167 167
168(defun array-move-to-cell (a-row a-column) 168(defun array-move-to-cell (a-row a-column)
@@ -174,7 +174,7 @@ Leave point at the beginning of the field and return the new buffer column."
174 (goal-column (* array-field-width (% (1- a-column) array-columns-per-line)))) 174 (goal-column (* array-field-width (% (1- a-column) array-columns-per-line))))
175 (goto-char (point-min)) 175 (goto-char (point-min))
176 (forward-line goal-line) 176 (forward-line goal-line)
177 (move-to-column-untabify goal-column))) 177 (array-move-to-column-untabify goal-column)))
178 178
179(defun array-move-to-row (a-row) 179(defun array-move-to-row (a-row)
180 "Move to array row A-ROW preserving the current array column. 180 "Move to array row A-ROW preserving the current array column.
@@ -184,7 +184,7 @@ Leave point at the beginning of the field and return the new array row."
184 (% array-buffer-line array-lines-per-row))) 184 (% array-buffer-line array-lines-per-row)))
185 (goal-column (- array-buffer-column (% array-buffer-column array-field-width)))) 185 (goal-column (- array-buffer-column (% array-buffer-column array-field-width))))
186 (forward-line (- goal-line array-buffer-line)) 186 (forward-line (- goal-line array-buffer-line))
187 (move-to-column-untabify goal-column) 187 (array-move-to-column-untabify goal-column)
188 a-row)) 188 a-row))
189 189
190(defun array-move-to-column (a-column) 190(defun array-move-to-column (a-column)
@@ -196,7 +196,7 @@ Leave point at the beginning of the field and return the new array column."
196 (floor (1- a-column) array-columns-per-line))) 196 (floor (1- a-column) array-columns-per-line)))
197 (goal-column (* array-field-width (% (1- a-column) array-columns-per-line)))) 197 (goal-column (* array-field-width (% (1- a-column) array-columns-per-line))))
198 (forward-line (- goal-line array-buffer-line)) 198 (forward-line (- goal-line array-buffer-line))
199 (move-to-column-untabify goal-column) 199 (array-move-to-column-untabify goal-column)
200 a-column)) 200 a-column))
201 201
202(defun array-move-one-row (sign) 202(defun array-move-one-row (sign)
@@ -214,7 +214,7 @@ If requested to move beyond the array bounds, signal an error."
214 (t 214 (t
215 (progn 215 (progn
216 (forward-line (* sign array-lines-per-row)) 216 (forward-line (* sign array-lines-per-row))
217 (move-to-column-untabify goal-column) 217 (array-move-to-column-untabify goal-column)
218 (+ array-row sign)))))) 218 (+ array-row sign))))))
219 219
220(defun array-move-one-column (sign) 220(defun array-move-one-column (sign)
@@ -233,15 +233,15 @@ If requested to move beyond the array bounds, signal an error."
233 ;; Going backward from first column on the line. 233 ;; Going backward from first column on the line.
234 ((and (= sign -1) (= 1 (% array-column array-columns-per-line))) 234 ((and (= sign -1) (= 1 (% array-column array-columns-per-line)))
235 (forward-line -1) 235 (forward-line -1)
236 (move-to-column-untabify 236 (array-move-to-column-untabify
237 (* array-field-width (1- array-columns-per-line)))) 237 (* array-field-width (1- array-columns-per-line))))
238 ;; Going forward from last column on the line. 238 ;; Going forward from last column on the line.
239 ((and (= sign 1) (zerop (% array-column array-columns-per-line))) 239 ((and (= sign 1) (zerop (% array-column array-columns-per-line)))
240 (forward-line 1)) 240 (forward-line 1))
241 ;; Somewhere in the middle of the line. 241 ;; Somewhere in the middle of the line.
242 (t 242 (t
243 (move-to-column-untabify (+ (array-beginning-of-field) 243 (array-move-to-column-untabify (+ (array-beginning-of-field)
244 (* array-field-width sign))))) 244 (* array-field-width sign)))))
245 (+ array-column sign))))) 245 (+ array-column sign)))))
246 246
247(defun array-normalize-cursor () 247(defun array-normalize-cursor ()
@@ -281,15 +281,15 @@ If necessary, scroll horizontally to keep the cursor in view."
281 "Move down one array row, staying in the current array column. 281 "Move down one array row, staying in the current array column.
282If optional ARG is given, move down ARG array rows." 282If optional ARG is given, move down ARG array rows."
283 (interactive "p") 283 (interactive "p")
284 (let ((array-buffer-line (current-line)) 284 (let ((array-buffer-line (array-current-line))
285 (array-buffer-column (current-column))) 285 (array-buffer-column (current-column)))
286 (if (= (abs arg) 1) 286 (if (= (abs arg) 1)
287 (array-move-one-row arg) 287 (array-move-one-row arg)
288 (array-move-to-row 288 (array-move-to-row
289 (limit-index (+ (or (array-current-row) 289 (array--limit-index (+ (or (array-current-row)
290 (error "Cursor is not in an array cell")) 290 (error "Cursor is not in an array cell"))
291 arg) 291 arg)
292 array-max-row)))) 292 array-max-row))))
293 (array-normalize-cursor)) 293 (array-normalize-cursor))
294 294
295(defun array-previous-row (&optional arg) 295(defun array-previous-row (&optional arg)
@@ -303,15 +303,15 @@ If optional ARG is given, move up ARG array rows."
303If optional ARG is given, move forward ARG array columns. 303If optional ARG is given, move forward ARG array columns.
304If necessary, keep the cursor in the window by scrolling right or left." 304If necessary, keep the cursor in the window by scrolling right or left."
305 (interactive "p") 305 (interactive "p")
306 (let ((array-buffer-line (current-line)) 306 (let ((array-buffer-line (array-current-line))
307 (array-buffer-column (current-column))) 307 (array-buffer-column (current-column)))
308 (if (= (abs arg) 1) 308 (if (= (abs arg) 1)
309 (array-move-one-column arg) 309 (array-move-one-column arg)
310 (array-move-to-column 310 (array-move-to-column
311 (limit-index (+ (or (array-current-column) 311 (array--limit-index (+ (or (array-current-column)
312 (error "Cursor is not in an array cell")) 312 (error "Cursor is not in an array cell"))
313 arg) 313 arg)
314 array-max-column)))) 314 array-max-column))))
315 (array-normalize-cursor)) 315 (array-normalize-cursor))
316 316
317(defun array-backward-column (&optional arg) 317(defun array-backward-column (&optional arg)
@@ -325,8 +325,8 @@ If necessary, keep the cursor in the window by scrolling right or left."
325 "Go to array row A-ROW and array column A-COLUMN." 325 "Go to array row A-ROW and array column A-COLUMN."
326 (interactive "nArray row: \nnArray column: ") 326 (interactive "nArray row: \nnArray column: ")
327 (array-move-to-cell 327 (array-move-to-cell
328 (limit-index a-row array-max-row) 328 (array--limit-index a-row array-max-row)
329 (limit-index a-column array-max-column)) 329 (array--limit-index a-column array-max-column))
330 (array-normalize-cursor)) 330 (array-normalize-cursor))
331 331
332 332
@@ -417,7 +417,7 @@ Leave point at the beginning of the field."
417 "Copy the current field one array row down. 417 "Copy the current field one array row down.
418If optional ARG is given, copy down through ARG array rows." 418If optional ARG is given, copy down through ARG array rows."
419 (interactive "p") 419 (interactive "p")
420 (let* ((array-buffer-line (current-line)) 420 (let* ((array-buffer-line (array-current-line))
421 (array-buffer-column (current-column)) 421 (array-buffer-column (current-column))
422 (array-row (or (array-current-row) 422 (array-row (or (array-current-row)
423 (error "Cursor is not in a valid array cell"))) 423 (error "Cursor is not in a valid array cell")))
@@ -425,7 +425,7 @@ If optional ARG is given, copy down through ARG array rows."
425 (if (= (abs arg) 1) 425 (if (= (abs arg) 1)
426 (array-copy-once-vertically arg) 426 (array-copy-once-vertically arg)
427 (array-copy-to-row 427 (array-copy-to-row
428 (limit-index (+ array-row arg) array-max-row)))) 428 (array--limit-index (+ array-row arg) array-max-row))))
429 (array-normalize-cursor)) 429 (array-normalize-cursor))
430 430
431(defun array-copy-up (&optional arg) 431(defun array-copy-up (&optional arg)
@@ -438,7 +438,7 @@ If optional ARG is given, copy up through ARG array rows."
438 "Copy the current field one array column to the right. 438 "Copy the current field one array column to the right.
439If optional ARG is given, copy through ARG array columns to the right." 439If optional ARG is given, copy through ARG array columns to the right."
440 (interactive "p") 440 (interactive "p")
441 (let* ((array-buffer-line (current-line)) 441 (let* ((array-buffer-line (array-current-line))
442 (array-buffer-column (current-column)) 442 (array-buffer-column (current-column))
443 (array-column (or (array-current-column) 443 (array-column (or (array-current-column)
444 (error "Cursor is not in a valid array cell"))) 444 (error "Cursor is not in a valid array cell")))
@@ -446,7 +446,7 @@ If optional ARG is given, copy through ARG array columns to the right."
446 (if (= (abs arg) 1) 446 (if (= (abs arg) 1)
447 (array-copy-once-horizontally arg) 447 (array-copy-once-horizontally arg)
448 (array-copy-to-column 448 (array-copy-to-column
449 (limit-index (+ array-column arg) array-max-column)))) 449 (array--limit-index (+ array-column arg) array-max-column))))
450 (array-normalize-cursor)) 450 (array-normalize-cursor))
451 451
452(defun array-copy-backward (&optional arg) 452(defun array-copy-backward (&optional arg)
@@ -473,7 +473,7 @@ If optional ARG is given, copy through ARG array columns to the right."
473 (if (= (abs arg) 1) 473 (if (= (abs arg) 1)
474 (array-copy-once-horizontally arg) 474 (array-copy-once-horizontally arg)
475 (array-copy-to-column 475 (array-copy-to-column
476 (limit-index (+ array-column arg) array-max-column)))))) 476 (array--limit-index (+ array-column arg) array-max-column))))))
477 (message "Working...done") 477 (message "Working...done")
478 (array-move-to-row array-row) 478 (array-move-to-row array-row)
479 (array-normalize-cursor)) 479 (array-normalize-cursor))
@@ -506,7 +506,7 @@ If optional ARG is given, copy through ARG rows down."
506 (forward-line 1) 506 (forward-line 1)
507 (point)))) 507 (point))))
508 (this-row array-row) 508 (this-row array-row)
509 (goal-row (limit-index (+ this-row arg) array-max-row)) 509 (goal-row (array--limit-index (+ this-row arg) array-max-row))
510 (num (- goal-row this-row)) 510 (num (- goal-row this-row))
511 (count (abs num)) 511 (count (abs num))
512 (sign (if (not (zerop count)) (/ num count)))) 512 (sign (if (not (zerop count)) (/ num count))))
@@ -700,13 +700,13 @@ of `array-rows-numbered'."
700 (floor (1- temp-max-column) new-columns-per-line)) 700 (floor (1- temp-max-column) new-columns-per-line))
701 (newlines-added 0)) 701 (newlines-added 0))
702 (while (< newlines-removed newlines-to-be-removed) 702 (while (< newlines-removed newlines-to-be-removed)
703 (move-to-column-untabify 703 (array-move-to-column-untabify
704 (* (1+ newlines-removed) old-line-length)) 704 (* (1+ newlines-removed) old-line-length))
705 (kill-line 1) 705 (kill-line 1)
706 (setq newlines-removed (1+ newlines-removed))) 706 (setq newlines-removed (1+ newlines-removed)))
707 (beginning-of-line) 707 (beginning-of-line)
708 (while (< newlines-added newlines-to-be-added) 708 (while (< newlines-added newlines-to-be-added)
709 (move-to-column-untabify (* old-field-width new-columns-per-line)) 709 (array-move-to-column-untabify (* old-field-width new-columns-per-line))
710 (newline) 710 (newline)
711 (setq newlines-added (1+ newlines-added))) 711 (setq newlines-added (1+ newlines-added)))
712 (forward-line 1)))) 712 (forward-line 1))))
@@ -735,16 +735,16 @@ of `array-rows-numbered'."
735 735
736;;; Utilities. 736;;; Utilities.
737 737
738(defun limit-index (index limit) 738(defun array--limit-index (index limit)
739 (cond ((< index 1) 1) 739 (cond ((< index 1) 1)
740 ((> index limit) limit) 740 ((> index limit) limit)
741 (t index))) 741 (t index)))
742 742
743(defun current-line () 743(defun array-current-line ()
744 "Return the current buffer line at point. The first line is 0." 744 "Return the current buffer line at point. The first line is 0."
745 (count-lines (point-min) (line-beginning-position))) 745 (count-lines (point-min) (line-beginning-position)))
746 746
747(defun move-to-column-untabify (column) 747(defun array-move-to-column-untabify (column)
748 "Move to COLUMN on the current line, untabifying if necessary. 748 "Move to COLUMN on the current line, untabifying if necessary.
749Return COLUMN." 749Return COLUMN."
750 (or (and (= column (move-to-column column)) 750 (or (and (= column (move-to-column column))
@@ -753,10 +753,10 @@ Return COLUMN."
753 (if array-respect-tabs 753 (if array-respect-tabs
754 (error "There is a TAB character in the way") 754 (error "There is a TAB character in the way")
755 (progn 755 (progn
756 (untabify-backward) 756 (array--untabify-backward)
757 (move-to-column column))))) 757 (move-to-column column)))))
758 758
759(defun untabify-backward () 759(defun array--untabify-backward ()
760 "Untabify the preceding TAB." 760 "Untabify the preceding TAB."
761 (save-excursion 761 (save-excursion
762 (let ((start (point))) 762 (let ((start (point)))
@@ -885,7 +885,10 @@ Entering array mode calls the function `array-mode-hook'."
885 (setq-local truncate-lines t) 885 (setq-local truncate-lines t)
886 (setq overwrite-mode 'overwrite-mode-textual)) 886 (setq overwrite-mode 'overwrite-mode-textual))
887 887
888 888(define-obsolete-function-alias 'limit-index #'array--limit-index "29.1")
889(define-obsolete-function-alias 'current-line #'array-current-line "29.1")
890(define-obsolete-function-alias 'move-to-column-untabify #'array-move-to-column-untabify "29.1")
891(define-obsolete-function-alias 'untabify-backward #'array--untabify-backward "29.1")
889 892
890(provide 'array) 893(provide 'array)
891 894
diff --git a/lisp/bookmark.el b/lisp/bookmark.el
index 30a03e0431e..d0893e932b4 100644
--- a/lisp/bookmark.el
+++ b/lisp/bookmark.el
@@ -966,7 +966,7 @@ it removes only the first instance of a bookmark with that name from
966the list of bookmarks.)" 966the list of bookmarks.)"
967 (interactive (list nil current-prefix-arg)) 967 (interactive (list nil current-prefix-arg))
968 (let ((prompt 968 (let ((prompt
969 (if no-overwrite "Append bookmark named" "Set bookmark named"))) 969 (if no-overwrite "Add bookmark named" "Set bookmark named")))
970 (bookmark-set-internal prompt name (if no-overwrite 'push 'overwrite)))) 970 (bookmark-set-internal prompt name (if no-overwrite 'push 'overwrite))))
971 971
972;;;###autoload 972;;;###autoload
diff --git a/lisp/calc/calc-vec.el b/lisp/calc/calc-vec.el
index 3b8629b797d..8d99f62a9ba 100644
--- a/lisp/calc/calc-vec.el
+++ b/lisp/calc/calc-vec.el
@@ -647,9 +647,7 @@
647(defun calcFunc-rhead (vec) 647(defun calcFunc-rhead (vec)
648 (if (and (Math-vectorp vec) 648 (if (and (Math-vectorp vec)
649 (cdr vec)) 649 (cdr vec))
650 (let ((vec (copy-sequence vec))) 650 (butlast vec)
651 (setcdr (nthcdr (- (length vec) 2) vec) nil)
652 vec)
653 (calc-record-why 'vectorp vec) 651 (calc-record-why 'vectorp vec)
654 (list 'calcFunc-rhead vec))) 652 (list 'calcFunc-rhead vec)))
655 653
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 254c703ee22..6c21430b1b3 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -1959,12 +1959,8 @@ See calc-keypad for details."
1959 (or n (setq n 1)) 1959 (or n (setq n 1))
1960 (or m (setq m 1)) 1960 (or m (setq m 1))
1961 (calc-check-stack (+ n m -1)) 1961 (calc-check-stack (+ n m -1))
1962 (and (> n 0) 1962 (nreverse (mapcar (lambda (x) (calc-get-stack-element x sel-mode))
1963 (let ((top (copy-sequence (nthcdr (+ m calc-stack-top -1) 1963 (take n (nthcdr (+ m calc-stack-top -1) calc-stack)))))
1964 calc-stack))))
1965 (setcdr (nthcdr (1- n) top) nil)
1966 (nreverse
1967 (mapcar (lambda (x) (calc-get-stack-element x sel-mode)) top)))))
1968 1964
1969(defun calc-top-list-n (&optional n m sel-mode) 1965(defun calc-top-list-n (&optional n m sel-mode)
1970 (mapcar #'math-check-complete 1966 (mapcar #'math-check-complete
@@ -2291,9 +2287,7 @@ the United States."
2291 ((and (null n) 2287 ((and (null n)
2292 (eq (car-safe top) 'incomplete) 2288 (eq (car-safe top) 'incomplete)
2293 (> (length top) (if (eq (nth 1 top) 'intv) 3 2))) 2289 (> (length top) (if (eq (nth 1 top) 'intv) 3 2)))
2294 (calc-pop-push-list 1 (let ((tt (copy-sequence top))) 2290 (calc-pop-push-list 1 (list (butlast top))))
2295 (setcdr (nthcdr (- (length tt) 2) tt) nil)
2296 (list tt))))
2297 ((< nn 0) 2291 ((< nn 0)
2298 (if (and calc-any-selections 2292 (if (and calc-any-selections
2299 (calc-top-selected 1 (- nn))) 2293 (calc-top-selected 1 (- nn)))
diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index 7e911d814dc..bbdcaa4db4e 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -171,13 +171,13 @@ If DATE lacks timezone information, GMT is assumed."
171 (error "Invalid date: %s" date))))))))) 171 (error "Invalid date: %s" date)))))))))
172 172
173;;;###autoload 173;;;###autoload
174(defalias 'time-to-seconds 'float-time) 174(defalias 'time-to-seconds #'float-time)
175 175
176;;;###autoload 176;;;###autoload
177(defun seconds-to-time (seconds &rest form) 177(defun seconds-to-time (seconds)
178 "Convert SECONDS to a proper time, like `current-time' would. 178 "Convert SECONDS to a proper time, like `current-time' would."
179FORM means the same as in `time-convert'." 179 ;; FIXME: Should we (declare (obsolete time-convert "27.1")) ?
180 (time-convert seconds form)) 180 (time-convert seconds 'list))
181 181
182;;;###autoload 182;;;###autoload
183(defun days-to-time (days) 183(defun days-to-time (days)
@@ -202,7 +202,7 @@ TIME should be either a time value or a date-time string."
202 (time-subtract nil time)) 202 (time-subtract nil time))
203 203
204;;;###autoload 204;;;###autoload
205(define-obsolete-function-alias 'subtract-time 'time-subtract "26.1") 205(define-obsolete-function-alias 'subtract-time #'time-subtract "26.1")
206 206
207;;;###autoload 207;;;###autoload
208(defun date-to-day (date) 208(defun date-to-day (date)
diff --git a/lisp/cedet/cedet.el b/lisp/cedet/cedet.el
index e6befb10e91..c33ac850722 100644
--- a/lisp/cedet/cedet.el
+++ b/lisp/cedet/cedet.el
@@ -25,15 +25,12 @@
25;;; Commentary: 25;;; Commentary:
26 26
27;;; Code: 27;;; Code:
28;;
29;; This file depends on the major components of CEDET, so that you can
30;; load them all by doing (require 'cedet). This is mostly for
31;; compatibility with the upstream, stand-alone CEDET distribution.
32 28
33(declare-function inversion-find-version "inversion") 29(declare-function inversion-find-version "inversion")
34 30
35(defconst cedet-version "2.0" 31(defconst cedet-version "2.0"
36 "Current version of CEDET.") 32 "Current version of CEDET.")
33(make-obsolete-variable 'cedet-version 'emacs-version "29.1")
37 34
38(defconst cedet-packages 35(defconst cedet-packages
39 `( 36 `(
@@ -45,6 +42,7 @@
45 (ede "1.2" nil "ede" ) 42 (ede "1.2" nil "ede" )
46 ) 43 )
47 "Table of CEDET packages to install.") 44 "Table of CEDET packages to install.")
45(make-obsolete-variable 'cedet-packages 'package-built-in-p "29.1")
48 46
49(defvar cedet-menu-map ;(make-sparse-keymap "CEDET menu") 47(defvar cedet-menu-map ;(make-sparse-keymap "CEDET menu")
50 (let ((map (make-sparse-keymap "CEDET menu"))) 48 (let ((map (make-sparse-keymap "CEDET menu")))
diff --git a/lisp/cedet/ede.el b/lisp/cedet/ede.el
index 4ea14e33c5d..e6bfd0b1e85 100644
--- a/lisp/cedet/ede.el
+++ b/lisp/cedet/ede.el
@@ -1,10 +1,10 @@
1;;; ede.el --- Emacs Development Environment gloss -*- lexical-binding: t; -*- 1;;; ede.el --- Emacs Development Environment gloss -*- lexical-binding: t; -*-
2 2
3;; Copyright (C) 1998-2005, 2007-2022 Free Software Foundation, Inc. 3;; Copyright (C) 1998-2022 Free Software Foundation, Inc.
4 4
5;; Author: Eric M. Ludlam <zappo@gnu.org> 5;; Author: Eric M. Ludlam <zappo@gnu.org>
6;; Keywords: project, make 6;; Keywords: project, make
7;; Version: 1.2 7;; Version: 2.0
8 8
9;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
10 10
@@ -39,6 +39,8 @@
39;; 39;;
40;; (global-ede-mode t) 40;; (global-ede-mode t)
41 41
42;;; Code:
43
42(require 'cedet) 44(require 'cedet)
43(require 'cl-lib) 45(require 'cl-lib)
44(require 'eieio) 46(require 'eieio)
@@ -66,10 +68,11 @@
66 68
67(defconst ede-version "2.0" 69(defconst ede-version "2.0"
68 "Current version of the Emacs EDE.") 70 "Current version of the Emacs EDE.")
71(make-obsolete-variable 'ede-version 'emacs-version "29.1")
69 72
70;;; Code:
71(defun ede-version () 73(defun ede-version ()
72 "Display the current running version of EDE." 74 "Display the current running version of EDE."
75 (declare (obsolete emacs-version "29.1"))
73 (interactive) (message "EDE %s" ede-version)) 76 (interactive) (message "EDE %s" ede-version))
74 77
75(defgroup ede nil 78(defgroup ede nil
diff --git a/lisp/cedet/ede/emacs.el b/lisp/cedet/ede/emacs.el
index cbe766cedb6..c83e6873679 100644
--- a/lisp/cedet/ede/emacs.el
+++ b/lisp/cedet/ede/emacs.el
@@ -80,7 +80,6 @@ ROOTPROJ is nil, since there is only one project."
80 ;; Doesn't already exist, so let's make one. 80 ;; Doesn't already exist, so let's make one.
81 (let* ((vertuple (ede-emacs-version dir))) 81 (let* ((vertuple (ede-emacs-version dir)))
82 (ede-emacs-project 82 (ede-emacs-project
83 (car vertuple)
84 :name (car vertuple) 83 :name (car vertuple)
85 :version (cdr vertuple) 84 :version (cdr vertuple)
86 :directory (file-name-as-directory dir) 85 :directory (file-name-as-directory dir)
diff --git a/lisp/cedet/semantic.el b/lisp/cedet/semantic.el
index 78002dd8abc..3166279de40 100644
--- a/lisp/cedet/semantic.el
+++ b/lisp/cedet/semantic.el
@@ -34,6 +34,8 @@
34;; menu). To enable it at startup, put (semantic-mode 1) in your init 34;; menu). To enable it at startup, put (semantic-mode 1) in your init
35;; file. 35;; file.
36 36
37;;; Code:
38
37(require 'cedet) 39(require 'cedet)
38(require 'semantic/tag) 40(require 'semantic/tag)
39(require 'semantic/lex) 41(require 'semantic/lex)
@@ -41,6 +43,7 @@
41 43
42(defvar semantic-version "2.2" 44(defvar semantic-version "2.2"
43 "Current version of Semantic.") 45 "Current version of Semantic.")
46(make-obsolete-variable 'semantic-version 'emacs-version "29.1")
44 47
45(declare-function inversion-test "inversion") 48(declare-function inversion-test "inversion")
46(declare-function semanticdb-load-ebrowse-caches "semantic/db-ebrowse") 49(declare-function semanticdb-load-ebrowse-caches "semantic/db-ebrowse")
@@ -73,9 +76,6 @@ introduced."
73 76
74(require 'semantic/fw) 77(require 'semantic/fw)
75 78
76;;; Code:
77;;
78
79;;; Variables and Configuration 79;;; Variables and Configuration
80;; 80;;
81(defvar-local semantic--parse-table nil 81(defvar-local semantic--parse-table nil
diff --git a/lisp/cedet/semantic/bovine.el b/lisp/cedet/semantic/bovine.el
index 1e52b1f8504..a6cf8d89a4f 100644
--- a/lisp/cedet/semantic/bovine.el
+++ b/lisp/cedet/semantic/bovine.el
@@ -143,14 +143,14 @@ list of semantic tokens found."
143 cvl nil ;re-init the collected value list. 143 cvl nil ;re-init the collected value list.
144 lte (car matchlist) ;Get the local matchlist entry. 144 lte (car matchlist) ;Get the local matchlist entry.
145 ) 145 )
146 (if (or (byte-code-function-p (car lte)) 146 (if (or (compiled-function-p (car lte))
147 (listp (car lte))) 147 (listp (car lte)))
148 ;; In this case, we have an EMPTY match! Make 148 ;; In this case, we have an EMPTY match! Make
149 ;; stuff up. 149 ;; stuff up.
150 (setq cvl (list nil)))) 150 (setq cvl (list nil))))
151 151
152 (while (and lte 152 (while (and lte
153 (not (byte-code-function-p (car lte))) 153 (not (compiled-function-p (car lte)))
154 (not (listp (car lte)))) 154 (not (listp (car lte))))
155 155
156 ;; GRAMMAR SOURCE DEBUGGING! 156 ;; GRAMMAR SOURCE DEBUGGING!
diff --git a/lisp/cedet/semantic/db-file.el b/lisp/cedet/semantic/db-file.el
index d00ab47ce69..e2c9d618ba2 100644
--- a/lisp/cedet/semantic/db-file.el
+++ b/lisp/cedet/semantic/db-file.el
@@ -29,7 +29,7 @@
29(require 'cedet-files) 29(require 'cedet-files)
30(require 'data-debug) 30(require 'data-debug)
31 31
32(defvar semanticdb-file-version semantic-version 32(defvar semanticdb-file-version "2.2"
33 "Version of semanticdb we are writing files to disk with.") 33 "Version of semanticdb we are writing files to disk with.")
34(defvar semanticdb-file-incompatible-version "1.4" 34(defvar semanticdb-file-incompatible-version "1.4"
35 "Version of semanticdb we are not reverse compatible with.") 35 "Version of semanticdb we are not reverse compatible with.")
diff --git a/lisp/cedet/semantic/wisent/comp.el b/lisp/cedet/semantic/wisent/comp.el
index 17cd3b1d59a..e24f6128a68 100644
--- a/lisp/cedet/semantic/wisent/comp.el
+++ b/lisp/cedet/semantic/wisent/comp.el
@@ -38,7 +38,7 @@
38;;; Code: 38;;; Code:
39(require 'semantic/wisent) 39(require 'semantic/wisent)
40(eval-when-compile (require 'cl-lib)) 40(eval-when-compile (require 'cl-lib))
41(eval-when-compile (require 'subr-x)) ; `string-pad' 41(require 'subr-x) ; `string-pad'
42 42
43;;;; ------------------- 43;;;; -------------------
44;;;; Misc. useful things 44;;;; Misc. useful things
diff --git a/lisp/cedet/srecode.el b/lisp/cedet/srecode.el
index 7c054d4c100..9691f906a4c 100644
--- a/lisp/cedet/srecode.el
+++ b/lisp/cedet/srecode.el
@@ -37,14 +37,16 @@
37;; 37;;
38;; See the srecode manual for specific details. 38;; See the srecode manual for specific details.
39 39
40;;; Code:
41
40(require 'eieio) 42(require 'eieio)
41(require 'mode-local) 43(require 'mode-local)
42(load "srecode/loaddefs" nil 'nomessage) 44(load "srecode/loaddefs" nil 'nomessage)
43 45
44(defvar srecode-version "1.2" 46(defvar srecode-version "1.2"
45 "Current version of the Semantic Recoder.") 47 "Current version of the Semantic Recoder.")
48(make-obsolete-variable 'srecode-version 'emacs-version "29.1")
46 49
47;;; Code:
48(defgroup srecode nil 50(defgroup srecode nil
49 "Semantic Recoder." 51 "Semantic Recoder."
50 :group 'extensions 52 :group 'extensions
diff --git a/lisp/descr-text.el b/lisp/descr-text.el
index 16971aa6611..7fad031add6 100644
--- a/lisp/descr-text.el
+++ b/lisp/descr-text.el
@@ -655,7 +655,9 @@ The character information includes:
655 ("file code" 655 ("file code"
656 ,@(if multibyte-p 656 ,@(if multibyte-p
657 (let* ((coding buffer-file-coding-system) 657 (let* ((coding buffer-file-coding-system)
658 (encoded (encode-coding-char char coding charset))) 658 (encoded
659 (and coding
660 (encode-coding-char char coding charset))))
659 (if encoded 661 (if encoded
660 (list (encoded-string-description encoded coding) 662 (list (encoded-string-description encoded coding)
661 (format "(encoded by coding system %S)" 663 (format "(encoded by coding system %S)"
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 2a2bcca7007..d383650f4e5 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -1054,9 +1054,9 @@
1054;; (print "Let's clean up now!")) 1054;; (print "Let's clean up now!"))
1055;; foo 1055;; foo
1056;; 1056;;
1057;; Now `foo's advice is byte-compiled: 1057;; Now `foo's advice is compiled:
1058;; 1058;;
1059;; (byte-code-function-p 'ad-Advice-foo) 1059;; (compiled-function-p 'ad-Advice-foo)
1060;; t 1060;; t
1061;; 1061;;
1062;; (foo 3) 1062;; (foo 3)
@@ -1298,7 +1298,7 @@
1298;; constructed during preactivation was used, even though we did not specify 1298;; constructed during preactivation was used, even though we did not specify
1299;; the `compile' flag: 1299;; the `compile' flag:
1300;; 1300;;
1301;; (byte-code-function-p 'ad-Advice-fum) 1301;; (compiled-function-p 'ad-Advice-fum)
1302;; t 1302;; t
1303;; 1303;;
1304;; (fum 2) 1304;; (fum 2)
@@ -1329,7 +1329,7 @@
1329;; 1329;;
1330;; A new uncompiled advised definition got constructed: 1330;; A new uncompiled advised definition got constructed:
1331;; 1331;;
1332;; (byte-code-function-p 'ad-Advice-fum) 1332;; (compiled-function-p 'ad-Advice-fum)
1333;; nil 1333;; nil
1334;; 1334;;
1335;; (fum 2) 1335;; (fum 2)
@@ -1580,8 +1580,6 @@
1580 :link '(custom-manual "(elisp)Advising Functions") 1580 :link '(custom-manual "(elisp)Advising Functions")
1581 :group 'lisp) 1581 :group 'lisp)
1582 1582
1583(defconst ad-version "2.14")
1584
1585;;;###autoload 1583;;;###autoload
1586(defcustom ad-redefinition-action 'warn 1584(defcustom ad-redefinition-action 'warn
1587 "Defines what to do with redefinitions during Advice de/activation. 1585 "Defines what to do with redefinitions during Advice de/activation.
@@ -2118,9 +2116,9 @@ the cache-id will clear the cache."
2118 2116
2119(defsubst ad-compiled-p (definition) 2117(defsubst ad-compiled-p (definition)
2120 "Return non-nil if DEFINITION is a compiled byte-code object." 2118 "Return non-nil if DEFINITION is a compiled byte-code object."
2121 (or (byte-code-function-p definition) 2119 (or (compiled-function-p definition)
2122 (and (macrop definition) 2120 (and (macrop definition)
2123 (byte-code-function-p (ad-lambdafy definition))))) 2121 (compiled-function-p (ad-lambdafy definition)))))
2124 2122
2125(defsubst ad-compiled-code (compiled-definition) 2123(defsubst ad-compiled-code (compiled-definition)
2126 "Return the byte-code object of a COMPILED-DEFINITION." 2124 "Return the byte-code object of a COMPILED-DEFINITION."
@@ -3250,6 +3248,9 @@ Use only in REAL emergencies."
3250 (message "Oops! Left over advised function %S" function) 3248 (message "Oops! Left over advised function %S" function)
3251 (ad-pop-advised-function function))) 3249 (ad-pop-advised-function function)))
3252 3250
3251(defconst ad-version "2.14")
3252(make-obsolete-variable 'ad-version 'emacs-version "29.1")
3253
3253(provide 'advice) 3254(provide 'advice)
3254 3255
3255;;; advice.el ends here 3256;;; advice.el ends here
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index 7a4bbf2e8af..52e00952846 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1207,25 +1207,26 @@ See Info node `(elisp) Integer Basics'."
1207 form))) 1207 form)))
1208 1208
1209(defun byte-optimize-apply (form) 1209(defun byte-optimize-apply (form)
1210 ;; If the last arg is a literal constant, turn this into a funcall. 1210 (let ((len (length form)))
1211 ;; The funcall optimizer can then transform (funcall 'foo ...) -> (foo ...). 1211 (if (>= len 2)
1212 (if (= (length form) 2) 1212 (let ((fn (nth 1 form))
1213 ;; single-argument `apply' is not worth optimizing (bug#40968) 1213 (last (nth (1- len) form)))
1214 form 1214 (cond
1215 (let ((fn (nth 1 form)) 1215 ;; (apply F ... '(X Y ...)) -> (funcall F ... 'X 'Y ...)
1216 (last (nth (1- (length form)) form))) ; I think this really is fastest 1216 ((or (null last)
1217 (or (if (or (null last) 1217 (eq (car-safe last) 'quote))
1218 (eq (car-safe last) 'quote)) 1218 (let ((last-value (nth 1 last)))
1219 (if (listp (nth 1 last)) 1219 (if (listp last-value)
1220 (let ((butlast (nreverse (cdr (reverse (cdr (cdr form))))))) 1220 `(funcall ,fn ,@(butlast (cddr form))
1221 (nconc (list 'funcall fn) butlast 1221 ,@(mapcar (lambda (x) (list 'quote x)) last-value))
1222 (mapcar (lambda (x) (list 'quote x)) (nth 1 last))))
1223 (byte-compile-warn-x 1222 (byte-compile-warn-x
1224 last 1223 last "last arg to apply can't be a literal atom: `%s'" last)
1225 "last arg to apply can't be a literal atom: `%s'" 1224 nil)))
1226 last) 1225 ;; (apply F ... (list X Y ...)) -> (funcall F ... X Y ...)
1227 nil)) 1226 ((eq (car-safe last) 'list)
1228 form)))) 1227 `(funcall ,fn ,@(butlast (cddr form)) ,@(cdr last)))
1228 (t form)))
1229 form)))
1229 1230
1230(put 'funcall 'byte-optimizer #'byte-optimize-funcall) 1231(put 'funcall 'byte-optimizer #'byte-optimize-funcall)
1231(put 'apply 'byte-optimizer #'byte-optimize-apply) 1232(put 'apply 'byte-optimizer #'byte-optimize-apply)
@@ -1747,10 +1748,10 @@ See Info node `(elisp) Integer Basics'."
1747 byte-goto-if-not-nil-else-pop)) 1748 byte-goto-if-not-nil-else-pop))
1748 1749
1749(defconst byte-after-unbind-ops 1750(defconst byte-after-unbind-ops
1750 '(byte-constant byte-dup 1751 '(byte-constant byte-dup byte-stack-ref byte-stack-set byte-discard
1751 byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-integerp 1752 byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-integerp
1752 byte-eq byte-not 1753 byte-eq byte-not
1753 byte-cons byte-list1 byte-list2 ; byte-list3 byte-list4 1754 byte-cons byte-list1 byte-list2 byte-list3 byte-list4 byte-listN
1754 byte-interactive-p) 1755 byte-interactive-p)
1755 ;; How about other side-effect-free-ops? Is it safe to move an 1756 ;; How about other side-effect-free-ops? Is it safe to move an
1756 ;; error invocation (such as from nth) out of an unwind-protect? 1757 ;; error invocation (such as from nth) out of an unwind-protect?
@@ -1762,7 +1763,8 @@ See Info node `(elisp) Integer Basics'."
1762(defconst byte-compile-side-effect-and-error-free-ops 1763(defconst byte-compile-side-effect-and-error-free-ops
1763 '(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp 1764 '(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp
1764 byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe 1765 byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe
1765 byte-cdr-safe byte-cons byte-list1 byte-list2 byte-point byte-point-max 1766 byte-cdr-safe byte-cons byte-list1 byte-list2 byte-list3 byte-list4
1767 byte-listN byte-point byte-point-max
1766 byte-point-min byte-following-char byte-preceding-char 1768 byte-point-min byte-following-char byte-preceding-char
1767 byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp 1769 byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp
1768 byte-current-buffer byte-stack-ref)) 1770 byte-current-buffer byte-stack-ref))
@@ -2113,13 +2115,15 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
2113 (setcar (cdr rest) lap0) 2115 (setcar (cdr rest) lap0)
2114 (setq keep-going t)) 2116 (setq keep-going t))
2115 ;; 2117 ;;
2116 ;; varbind-X unbind-N --> discard unbind-(N-1) 2118 ;; varbind-X unbind-N --> discard unbind-(N-1)
2117 ;; save-excursion unbind-N --> unbind-(N-1) 2119 ;; save-excursion unbind-N --> unbind-(N-1)
2118 ;; save-restriction unbind-N --> unbind-(N-1) 2120 ;; save-restriction unbind-N --> unbind-(N-1)
2121 ;; save-current-buffer unbind-N --> unbind-(N-1)
2119 ;; 2122 ;;
2120 ((and (eq 'byte-unbind (car lap1)) 2123 ((and (eq 'byte-unbind (car lap1))
2121 (memq (car lap0) '(byte-varbind byte-save-excursion 2124 (memq (car lap0) '(byte-varbind byte-save-excursion
2122 byte-save-restriction)) 2125 byte-save-restriction
2126 byte-save-current-buffer))
2123 (< 0 (cdr lap1))) 2127 (< 0 (cdr lap1)))
2124 (if (zerop (setcdr lap1 (1- (cdr lap1)))) 2128 (if (zerop (setcdr lap1 (1- (cdr lap1))))
2125 (delq lap1 rest)) 2129 (delq lap1 rest))
@@ -2475,8 +2479,7 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
2475;; itself, compile some of its most used recursive functions (at load time). 2479;; itself, compile some of its most used recursive functions (at load time).
2476;; 2480;;
2477(eval-when-compile 2481(eval-when-compile
2478 (or (byte-code-function-p (symbol-function 'byte-optimize-form)) 2482 (or (compiled-function-p (symbol-function 'byte-optimize-form))
2479 (subr-native-elisp-p (symbol-function 'byte-optimize-form))
2480 (assq 'byte-code (symbol-function 'byte-optimize-form)) 2483 (assq 'byte-code (symbol-function 'byte-optimize-form))
2481 (let ((byte-optimize nil) 2484 (let ((byte-optimize nil)
2482 (byte-compile-warnings nil)) 2485 (byte-compile-warnings nil))
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 9d5f6682b5a..907015eb48e 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1395,7 +1395,7 @@ when printing the error message."
1395 (or (symbolp (symbol-function fn)) 1395 (or (symbolp (symbol-function fn))
1396 (consp (symbol-function fn)) 1396 (consp (symbol-function fn))
1397 (and (not macro-p) 1397 (and (not macro-p)
1398 (byte-code-function-p (symbol-function fn))))) 1398 (compiled-function-p (symbol-function fn)))))
1399 (setq fn (symbol-function fn))) 1399 (setq fn (symbol-function fn)))
1400 (let ((advertised (gethash (if (and (symbolp fn) (fboundp fn)) 1400 (let ((advertised (gethash (if (and (symbolp fn) (fboundp fn))
1401 ;; Could be a subr. 1401 ;; Could be a subr.
@@ -1407,7 +1407,7 @@ when printing the error message."
1407 (if macro-p 1407 (if macro-p
1408 `(macro lambda ,advertised) 1408 `(macro lambda ,advertised)
1409 `(lambda ,advertised))) 1409 `(lambda ,advertised)))
1410 ((and (not macro-p) (byte-code-function-p fn)) fn) 1410 ((and (not macro-p) (compiled-function-p fn)) fn)
1411 ((not (consp fn)) nil) 1411 ((not (consp fn)) nil)
1412 ((eq 'macro (car fn)) (cdr fn)) 1412 ((eq 'macro (car fn)) (cdr fn))
1413 (macro-p nil) 1413 (macro-p nil)
@@ -2946,11 +2946,11 @@ If FORM is a lambda or a macro, byte-compile it as a function."
2946 (setq fun (cdr fun))) 2946 (setq fun (cdr fun)))
2947 (prog1 2947 (prog1
2948 (cond 2948 (cond
2949 ;; Up until Emacs-24.1, byte-compile silently did nothing when asked to 2949 ;; Up until Emacs-24.1, byte-compile silently did nothing
2950 ;; compile something invalid. So let's tune down the complaint from an 2950 ;; when asked to compile something invalid. So let's tone
2951 ;; error to a simple message for the known case where signaling an error 2951 ;; down the complaint from an error to a simple message for
2952 ;; causes problems. 2952 ;; the known case where signaling an error causes problems.
2953 ((byte-code-function-p fun) 2953 ((compiled-function-p fun)
2954 (message "Function %s is already compiled" 2954 (message "Function %s is already compiled"
2955 (if (symbolp form) form "provided")) 2955 (if (symbolp form) form "provided"))
2956 fun) 2956 fun)
@@ -3527,7 +3527,7 @@ lambda-expression."
3527 (byte-compile-out-tag endtag))) 3527 (byte-compile-out-tag endtag)))
3528 3528
3529(defun byte-compile-unfold-bcf (form) 3529(defun byte-compile-unfold-bcf (form)
3530 "Inline call to byte-code-functions." 3530 "Inline call to byte-code function."
3531 (let* ((byte-compile-bound-variables byte-compile-bound-variables) 3531 (let* ((byte-compile-bound-variables byte-compile-bound-variables)
3532 (fun (car form)) 3532 (fun (car form))
3533 (fargs (aref fun 0)) 3533 (fargs (aref fun 0))
@@ -5254,11 +5254,13 @@ invoked interactively."
5254 ((not (consp f)) 5254 ((not (consp f))
5255 "<malformed function>") 5255 "<malformed function>")
5256 ((eq 'macro (car f)) 5256 ((eq 'macro (car f))
5257 (if (or (byte-code-function-p (cdr f)) 5257 (if (or (compiled-function-p (cdr f))
5258 ;; FIXME: Can this still happen?
5258 (assq 'byte-code (cdr (cdr (cdr f))))) 5259 (assq 'byte-code (cdr (cdr (cdr f)))))
5259 " <compiled macro>" 5260 " <compiled macro>"
5260 " <macro>")) 5261 " <macro>"))
5261 ((assq 'byte-code (cdr (cdr f))) 5262 ((assq 'byte-code (cdr (cdr f)))
5263 ;; FIXME: Can this still happen?
5262 "<compiled lambda>") 5264 "<compiled lambda>")
5263 ((eq 'lambda (car f)) 5265 ((eq 'lambda (car f))
5264 "<function>") 5266 "<function>")
@@ -5507,9 +5509,7 @@ and corresponding effects."
5507;; itself, compile some of its most used recursive functions (at load time). 5509;; itself, compile some of its most used recursive functions (at load time).
5508;; 5510;;
5509(eval-when-compile 5511(eval-when-compile
5510 (or (byte-code-function-p (symbol-function 'byte-compile-form)) 5512 (or (compiled-function-p (symbol-function 'byte-compile-form))
5511 (subr-native-elisp-p (symbol-function 'byte-compile-form))
5512 (assq 'byte-code (symbol-function 'byte-compile-form))
5513 (let ((byte-optimize nil) ; do it fast 5513 (let ((byte-optimize nil) ; do it fast
5514 (byte-compile-warnings nil)) 5514 (byte-compile-warnings nil))
5515 (mapc (lambda (x) 5515 (mapc (lambda (x)
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index ac589b82f83..04ead562f2f 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -1,6 +1,6 @@
1;;; checkdoc.el --- check documentation strings for style requirements -*- lexical-binding:t -*- 1;;; checkdoc.el --- check documentation strings for style requirements -*- lexical-binding:t -*-
2 2
3;; Copyright (C) 1997-1998, 2001-2022 Free Software Foundation, Inc. 3;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
4 4
5;; Author: Eric M. Ludlam <zappo@gnu.org> 5;; Author: Eric M. Ludlam <zappo@gnu.org>
6;; Old-Version: 0.6.2 6;; Old-Version: 0.6.2
@@ -1357,23 +1357,6 @@ checking of documentation strings.
1357 checkdoc-common-verbs-wrong-voice "\\|") 1357 checkdoc-common-verbs-wrong-voice "\\|")
1358 "\\)\\>")))) 1358 "\\)\\>"))))
1359 1359
1360;; Profiler says this is not yet faster than just calling assoc
1361;;(defun checkdoc-word-in-alist-vector (word vector)
1362;; "Check to see if WORD is in the car of an element of VECTOR.
1363;;VECTOR must be sorted. The CDR should be a replacement. Since the
1364;;word list is getting bigger, it is time for a quick bisecting search."
1365;; (let ((max (length vector)) (min 0) i
1366;; (found nil) (fw nil))
1367;; (setq i (/ max 2))
1368;; (while (and (not found) (/= min max))
1369;; (setq fw (car (aref vector i)))
1370;; (cond ((string= word fw) (setq found (cdr (aref vector i))))
1371;; ((string< word fw) (setq max i))
1372;; (t (setq min i)))
1373;; (setq i (/ (+ max min) 2))
1374;; )
1375;; found))
1376
1377;;; Checking engines 1360;;; Checking engines
1378;; 1361;;
1379(defun checkdoc-this-string-valid (&optional take-notes) 1362(defun checkdoc-this-string-valid (&optional take-notes)
@@ -2860,8 +2843,6 @@ function called to create the messages."
2860 2843
2861(custom-add-option 'emacs-lisp-mode-hook 'checkdoc-minor-mode) 2844(custom-add-option 'emacs-lisp-mode-hook 'checkdoc-minor-mode)
2862 2845
2863;; Obsolete
2864
2865(define-obsolete-function-alias 'checkdoc-run-hooks 2846(define-obsolete-function-alias 'checkdoc-run-hooks
2866 #'run-hook-with-args-until-success "28.1") 2847 #'run-hook-with-args-until-success "28.1")
2867(defvar checkdoc-version "0.6.2" 2848(defvar checkdoc-version "0.6.2"
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index eefaa36b911..80ca43c902a 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -3411,7 +3411,7 @@ Of course, we really can't know that for sure, so it's just a heuristic."
3411 (character . natnump) 3411 (character . natnump)
3412 (char-table . char-table-p) 3412 (char-table . char-table-p)
3413 (command . commandp) 3413 (command . commandp)
3414 (compiled-function . byte-code-function-p) 3414 (compiled-function . compiled-function-p)
3415 (hash-table . hash-table-p) 3415 (hash-table . hash-table-p)
3416 (cons . consp) 3416 (cons . consp)
3417 (fixnum . fixnump) 3417 (fixnum . fixnump)
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index c8ff6b68144..047b0069bb9 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -1813,8 +1813,7 @@ Ran \\([0-9]+\\) tests, \\([0-9]+\\) results as expected\
1813 (unless (or (null tests) (zerop high)) 1813 (unless (or (null tests) (zerop high))
1814 (message "\nLONG-RUNNING TESTS") 1814 (message "\nLONG-RUNNING TESTS")
1815 (message "------------------") 1815 (message "------------------")
1816 (setq tests (sort tests (lambda (x y) (> (car x) (car y))))) 1816 (setq tests (ntake high (sort tests (lambda (x y) (> (car x) (car y))))))
1817 (when (< high (length tests)) (setcdr (nthcdr (1- high) tests) nil))
1818 (message "%s" (mapconcat #'cdr tests "\n"))) 1817 (message "%s" (mapconcat #'cdr tests "\n")))
1819 ;; More details on hydra and emba, where the logs are harder to get to. 1818 ;; More details on hydra and emba, where the logs are harder to get to.
1820 (when (and (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI")) 1819 (when (and (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI"))
diff --git a/lisp/emacs-lisp/helper.el b/lisp/emacs-lisp/helper.el
index 654dbbc5fef..10bb2973253 100644
--- a/lisp/emacs-lisp/helper.el
+++ b/lisp/emacs-lisp/helper.el
@@ -131,7 +131,6 @@
131(defun Helper-describe-bindings () 131(defun Helper-describe-bindings ()
132 "Describe local key bindings of current mode." 132 "Describe local key bindings of current mode."
133 (interactive) 133 (interactive)
134 (message "Making binding list...")
135 (save-window-excursion (describe-bindings)) 134 (save-window-excursion (describe-bindings))
136 (Helper-help-scroller)) 135 (Helper-help-scroller))
137 136
diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el
index 3b329357ad9..31e1514193f 100644
--- a/lisp/emacs-lisp/loaddefs-gen.el
+++ b/lisp/emacs-lisp/loaddefs-gen.el
@@ -519,15 +519,21 @@ binds `generated-autoload-file' as a file-local variable, write
519its autoloads into the specified file instead. 519its autoloads into the specified file instead.
520 520
521The function does NOT recursively descend into subdirectories of the 521The function does NOT recursively descend into subdirectories of the
522directory or directories specified. 522directory or directories specified by DIRS.
523 523
524If EXTRA-DATA, include this string at the start of the generated 524Optional argument EXCLUDED-FILES, if non-nil, should be a list of
525file. This will also force generation of OUTPUT-FILE even if 525files, such as preloaded files, whose autoloads should not be written
526there are no autoloads to put into the file. 526to OUTPUT-FILE.
527 527
528If INCLUDE-PACKAGE-VERSION, include package version data. 528If EXTRA-DATA is non-nil, it should be a string; include that string
529at the beginning of the generated file. This will also force the
530generation of OUTPUT-FILE even if there are no autoloads to put into
531that file.
529 532
530If GENERATE-FULL, don't update, but regenerate all the loaddefs files." 533If INCLUDE-PACKAGE-VERSION is non-nil, include package version data.
534
535If GENERATE-FULL is non-nil, regenerate all the loaddefs files anew,
536instead of just updating them with the new/changed autoloads."
531 (let* ((files-re (let ((tmp nil)) 537 (let* ((files-re (let ((tmp nil))
532 (dolist (suf (get-load-suffixes)) 538 (dolist (suf (get-load-suffixes))
533 ;; We don't use module-file-suffix below because 539 ;; We don't use module-file-suffix below because
@@ -545,6 +551,11 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files."
545 (updating (and (file-exists-p output-file) (not generate-full))) 551 (updating (and (file-exists-p output-file) (not generate-full)))
546 (defs nil)) 552 (defs nil))
547 553
554 ;; Allow the excluded files to be relative.
555 (setq excluded-files
556 (mapcar (lambda (file) (expand-file-name file dir))
557 excluded-files))
558
548 ;; Collect all the autoload data. 559 ;; Collect all the autoload data.
549 (let ((progress (make-progress-reporter 560 (let ((progress (make-progress-reporter
550 (byte-compile-info 561 (byte-compile-info
@@ -583,7 +594,8 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files."
583 ;; We have some data, so generate the loaddef files. First 594 ;; We have some data, so generate the loaddef files. First
584 ;; group per output file. 595 ;; group per output file.
585 (dolist (fdefs (seq-group-by #'car defs)) 596 (dolist (fdefs (seq-group-by #'car defs))
586 (let ((loaddefs-file (car fdefs))) 597 (let ((loaddefs-file (car fdefs))
598 hash)
587 (with-temp-buffer 599 (with-temp-buffer
588 (if (and updating (file-exists-p loaddefs-file)) 600 (if (and updating (file-exists-p loaddefs-file))
589 (insert-file-contents loaddefs-file) 601 (insert-file-contents loaddefs-file)
@@ -593,6 +605,7 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files."
593 (when extra-data 605 (when extra-data
594 (insert extra-data) 606 (insert extra-data)
595 (ensure-empty-lines 1))) 607 (ensure-empty-lines 1)))
608 (setq hash (buffer-hash))
596 ;; Then group by source file (and sort alphabetically). 609 ;; Then group by source file (and sort alphabetically).
597 (dolist (section (sort (seq-group-by #'cadr (cdr fdefs)) 610 (dolist (section (sort (seq-group-by #'cadr (cdr fdefs))
598 (lambda (e1 e2) 611 (lambda (e1 e2)
@@ -629,9 +642,11 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files."
629 (loaddefs-generate--print-form def)) 642 (loaddefs-generate--print-form def))
630 (unless (bolp) 643 (unless (bolp)
631 (insert "\n"))))) 644 (insert "\n")))))
632 (write-region (point-min) (point-max) loaddefs-file nil 'silent) 645 ;; Only write the file if we actually made a change.
633 (byte-compile-info (file-relative-name loaddefs-file lisp-directory) 646 (unless (equal (buffer-hash) hash)
634 t "GEN"))))))) 647 (write-region (point-min) (point-max) loaddefs-file nil 'silent)
648 (byte-compile-info
649 (file-relative-name loaddefs-file lisp-directory) t "GEN"))))))))
635 650
636(defun loaddefs-generate--print-form (def) 651(defun loaddefs-generate--print-form (def)
637 "Print DEF in a format that makes sense for version control." 652 "Print DEF in a format that makes sense for version control."
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 6a193a56d2d..5ae9d8368f0 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -823,7 +823,7 @@ test of free variables in the following ways:
823(eval-when-compile 823(eval-when-compile
824 (add-hook 'emacs-startup-hook 824 (add-hook 'emacs-startup-hook
825 (lambda () 825 (lambda ()
826 (and (not (byte-code-function-p 826 (and (not (compiled-function-p
827 (symbol-function 'macroexpand-all))) 827 (symbol-function 'macroexpand-all)))
828 (locate-library "macroexp.elc") 828 (locate-library "macroexp.elc")
829 (load "macroexp.elc"))))) 829 (load "macroexp.elc")))))
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index 2d5a1b5e77b..a9a20ab5abf 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -167,31 +167,31 @@ DOC is a string where \"FUNCTION\" and \"OLDFUN\" are expected.")
167 167
168(defun advice--interactive-form (function) 168(defun advice--interactive-form (function)
169 "Like `interactive-form' but tries to avoid autoloading functions." 169 "Like `interactive-form' but tries to avoid autoloading functions."
170 (when (commandp function) 170 (if (not (and (symbolp function) (autoloadp (indirect-function function))))
171 (if (not (and (symbolp function) (autoloadp (indirect-function function)))) 171 (interactive-form function)
172 (interactive-form function) 172 (when (commandp function)
173 `(interactive (advice-eval-interactive-spec 173 `(interactive (advice-eval-interactive-spec
174 (cadr (interactive-form ',function))))))) 174 (cadr (interactive-form ',function)))))))
175 175
176(defun advice--make-interactive-form (function main) 176(defun advice--make-interactive-form (iff ifm)
177 ;; TODO: make it so that interactive spec can be a constant which 177 ;; TODO: make it so that interactive spec can be a constant which
178 ;; dynamically checks the advice--car/cdr to do its job. 178 ;; dynamically checks the advice--car/cdr to do its job.
179 ;; For that, advice-eval-interactive-spec needs to be more faithful. 179 ;; For that, advice-eval-interactive-spec needs to be more faithful.
180 (let* ((iff (advice--interactive-form function)) 180 (let* ((fspec (cadr iff)))
181 (ifm (advice--interactive-form main))
182 (fspec (cadr iff)))
183 (when (eq 'function (car-safe fspec)) ;; Macroexpanded lambda? 181 (when (eq 'function (car-safe fspec)) ;; Macroexpanded lambda?
184 (setq fspec (nth 1 fspec))) 182 (setq fspec (eval fspec t)))
185 (if (functionp fspec) 183 (if (functionp fspec)
186 `(funcall ',fspec ',(cadr ifm)) 184 `(funcall ',fspec ',(cadr ifm))
187 (cadr (or iff ifm))))) 185 (cadr (or iff ifm)))))
188 186
189 187
190(cl-defmethod oclosure-interactive-form ((ad advice) &optional _) 188(cl-defmethod oclosure-interactive-form ((ad advice) &optional _)
191 (let ((car (advice--car ad)) 189 (let* ((car (advice--car ad))
192 (cdr (advice--cdr ad))) 190 (cdr (advice--cdr ad))
193 (when (or (commandp car) (commandp cdr)) 191 (ifa (advice--interactive-form car))
194 `(interactive ,(advice--make-interactive-form car cdr))))) 192 (ifd (advice--interactive-form cdr)))
193 (when (or ifa ifd)
194 `(interactive ,(advice--make-interactive-form ifa ifd)))))
195 195
196(cl-defmethod cl-print-object ((object advice) stream) 196(cl-defmethod cl-print-object ((object advice) stream)
197 (cl-assert (advice--p object)) 197 (cl-assert (advice--p object))
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index d2959f7728c..ed23ee5f221 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -3530,7 +3530,7 @@ If optional arg BUTTON is non-nil, describe its associated package."
3530 (let ((place (cdr desc)) 3530 (let ((place (cdr desc))
3531 (out (copy-sequence (car desc)))) 3531 (out (copy-sequence (car desc))))
3532 (add-text-properties place (1+ place) 3532 (add-text-properties place (1+ place)
3533 '(face (bold font-lock-warning-face)) 3533 '(face help-key-binding)
3534 out) 3534 out)
3535 out)) 3535 out))
3536 (package--prettify-quick-help-key (cons desc 0)))) 3536 (package--prettify-quick-help-key (cons desc 0))))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 07443dabfef..10bd4bc6886 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -607,31 +607,38 @@ recording whether the var has been referenced by earlier parts of the match."
607 (symbolp . vectorp) 607 (symbolp . vectorp)
608 (symbolp . stringp) 608 (symbolp . stringp)
609 (symbolp . byte-code-function-p) 609 (symbolp . byte-code-function-p)
610 (symbolp . compiled-function-p)
610 (symbolp . recordp) 611 (symbolp . recordp)
611 (integerp . consp) 612 (integerp . consp)
612 (integerp . arrayp) 613 (integerp . arrayp)
613 (integerp . vectorp) 614 (integerp . vectorp)
614 (integerp . stringp) 615 (integerp . stringp)
615 (integerp . byte-code-function-p) 616 (integerp . byte-code-function-p)
617 (integerp . compiled-function-p)
616 (integerp . recordp) 618 (integerp . recordp)
617 (numberp . consp) 619 (numberp . consp)
618 (numberp . arrayp) 620 (numberp . arrayp)
619 (numberp . vectorp) 621 (numberp . vectorp)
620 (numberp . stringp) 622 (numberp . stringp)
621 (numberp . byte-code-function-p) 623 (numberp . byte-code-function-p)
624 (numberp . compiled-function-p)
622 (numberp . recordp) 625 (numberp . recordp)
623 (consp . arrayp) 626 (consp . arrayp)
624 (consp . atom) 627 (consp . atom)
625 (consp . vectorp) 628 (consp . vectorp)
626 (consp . stringp) 629 (consp . stringp)
627 (consp . byte-code-function-p) 630 (consp . byte-code-function-p)
631 (consp . compiled-function-p)
628 (consp . recordp) 632 (consp . recordp)
629 (arrayp . byte-code-function-p) 633 (arrayp . byte-code-function-p)
634 (arrayp . compiled-function-p)
630 (vectorp . byte-code-function-p) 635 (vectorp . byte-code-function-p)
636 (vectorp . compiled-function-p)
631 (vectorp . recordp) 637 (vectorp . recordp)
632 (stringp . vectorp) 638 (stringp . vectorp)
633 (stringp . recordp) 639 (stringp . recordp)
634 (stringp . byte-code-function-p))) 640 (stringp . byte-code-function-p)
641 (stringp . compiled-function-p)))
635 642
636(defun pcase--mutually-exclusive-p (pred1 pred2) 643(defun pcase--mutually-exclusive-p (pred1 pred2)
637 (or (member (cons pred1 pred2) 644 (or (member (cons pred1 pred2)
@@ -771,8 +778,8 @@ A and B can be one of:
771 ((consp (cadr pat)) #'consp) 778 ((consp (cadr pat)) #'consp)
772 ((stringp (cadr pat)) #'stringp) 779 ((stringp (cadr pat)) #'stringp)
773 ((vectorp (cadr pat)) #'vectorp) 780 ((vectorp (cadr pat)) #'vectorp)
774 ((byte-code-function-p (cadr pat)) 781 ((compiled-function-p (cadr pat))
775 #'byte-code-function-p)))) 782 #'compiled-function-p))))
776 (pcase--mutually-exclusive-p (cadr upat) otherpred)) 783 (pcase--mutually-exclusive-p (cadr upat) otherpred))
777 '(:pcase--fail . nil)) 784 '(:pcase--fail . nil))
778 ;; Since we turn (or 'a 'b 'c) into (pred (pcase--flip (memq '(a b c)))) 785 ;; Since we turn (or 'a 'b 'c) into (pred (pcase--flip (memq '(a b c))))
diff --git a/lisp/emacs-lisp/ring.el b/lisp/emacs-lisp/ring.el
index 2b2039f9d15..e8b92a532fa 100644
--- a/lisp/emacs-lisp/ring.el
+++ b/lisp/emacs-lisp/ring.el
@@ -42,6 +42,8 @@
42 42
43;;; Code: 43;;; Code:
44 44
45(eval-when-compile (require 'cl-lib))
46
45;;; User Functions: 47;;; User Functions:
46 48
47;;;###autoload 49;;;###autoload
@@ -51,6 +53,8 @@
51 (consp (cdr x)) (integerp (cadr x)) 53 (consp (cdr x)) (integerp (cadr x))
52 (vectorp (cddr x)))) 54 (vectorp (cddr x))))
53 55
56(cl-deftype ring () '(satisfies ring-p))
57
54;;;###autoload 58;;;###autoload
55(defun make-ring (size) 59(defun make-ring (size)
56 "Make a ring that can contain SIZE elements." 60 "Make a ring that can contain SIZE elements."
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 6ddd8de6e8d..b6f0f66e5b1 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -458,11 +458,21 @@ TESTFN is used to compare elements, or `equal' if TESTFN is nil."
458(cl-defmethod seq-uniq ((sequence list) &optional testfn) 458(cl-defmethod seq-uniq ((sequence list) &optional testfn)
459 (let ((result nil)) 459 (let ((result nil))
460 (if (not testfn) 460 (if (not testfn)
461 ;; Fast path. 461 ;; Fast path. If the list is long, use a hash table to speed
462 (while sequence 462 ;; things up even more.
463 (unless (member (car sequence) result) 463 (let ((l (length sequence)))
464 (push (car sequence) result)) 464 (if (> l 100)
465 (pop sequence)) 465 (let ((hash (make-hash-table :test #'equal :size l)))
466 (while sequence
467 (unless (gethash (car sequence) hash)
468 (setf (gethash (car sequence) hash) t)
469 (push (car sequence) result))
470 (setq sequence (cdr sequence))))
471 ;; Short list.
472 (while sequence
473 (unless (member (car sequence) result)
474 (push (car sequence) result))
475 (pop sequence))))
466 ;; Slower path. 476 ;; Slower path.
467 (while sequence 477 (while sequence
468 (unless (seq-find (lambda (elem) 478 (unless (seq-find (lambda (elem)
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index b7083bfe7cc..bd7c3c82f97 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -254,13 +254,9 @@ the string."
254 (unless (natnump length) 254 (unless (natnump length)
255 (signal 'wrong-type-argument (list 'natnump length))) 255 (signal 'wrong-type-argument (list 'natnump length)))
256 (let ((pad-length (- length (length string)))) 256 (let ((pad-length (- length (length string))))
257 (if (< pad-length 0) 257 (cond ((<= pad-length 0) string)
258 string 258 (start (concat (make-string pad-length (or padding ?\s)) string))
259 (concat (and start 259 (t (concat string (make-string pad-length (or padding ?\s)))))))
260 (make-string pad-length (or padding ?\s)))
261 string
262 (and (not start)
263 (make-string pad-length (or padding ?\s)))))))
264 260
265(defun string-chop-newline (string) 261(defun string-chop-newline (string)
266 "Remove the final newline (if any) from STRING." 262 "Remove the final newline (if any) from STRING."
@@ -471,6 +467,18 @@ be marked unmodified, effectively ignoring those changes."
471 (equal ,hash (buffer-hash))) 467 (equal ,hash (buffer-hash)))
472 (restore-buffer-modified-p nil)))))))) 468 (restore-buffer-modified-p nil))))))))
473 469
470(defun emacs-etc--hide-local-variables ()
471 "Hide local variables.
472Used by `emacs-authors-mode' and `emacs-news-mode'."
473 (narrow-to-region (point-min)
474 (save-excursion
475 (goto-char (point-max))
476 ;; Obfuscate to avoid this being interpreted
477 ;; as a local variable section itself.
478 (if (re-search-backward "^Local\sVariables:$" nil t)
479 (progn (forward-line -1) (point))
480 (point-max)))))
481
474(provide 'subr-x) 482(provide 'subr-x)
475 483
476;;; subr-x.el ends here 484;;; subr-x.el ends here
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el
index d1634c64ad3..d1c8b5ff2dd 100644
--- a/lisp/emulation/viper.el
+++ b/lisp/emulation/viper.el
@@ -7,7 +7,7 @@
7 7
8;; Author: Michael Kifer <kifer@cs.stonybrook.edu> 8;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
9;; Keywords: emulations 9;; Keywords: emulations
10;; Version: 3.14.1 10;; Version: 3.14.2
11 11
12;; Yoni Rabkin <yoni@rabkins.net> contacted the maintainer of this 12;; Yoni Rabkin <yoni@rabkins.net> contacted the maintainer of this
13;; file on 20/3/2008, and the maintainer agreed that when a bug is 13;; file on 20/3/2008, and the maintainer agreed that when a bug is
diff --git a/lisp/eshell/em-alias.el b/lisp/eshell/em-alias.el
index 5d3aaf7c81c..9ad218d5988 100644
--- a/lisp/eshell/em-alias.el
+++ b/lisp/eshell/em-alias.el
@@ -206,7 +206,7 @@ file named by `eshell-aliases-file'.")
206 (let ((eshell-current-handles 206 (let ((eshell-current-handles
207 (eshell-create-handles eshell-aliases-file 'overwrite))) 207 (eshell-create-handles eshell-aliases-file 'overwrite)))
208 (eshell/alias) 208 (eshell/alias)
209 (eshell-close-handles 0)))) 209 (eshell-close-handles 0 'nil))))
210 210
211(defsubst eshell-lookup-alias (name) 211(defsubst eshell-lookup-alias (name)
212 "Check whether NAME is aliased. Return the alias if there is one." 212 "Check whether NAME is aliased. Return the alias if there is one."
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index 775e4c1057e..62c95056fd2 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -133,6 +133,10 @@ There are several different kinds of commands, however."
133Such arguments will be passed to `read', and then evaluated." 133Such arguments will be passed to `read', and then evaluated."
134 :type 'regexp) 134 :type 'regexp)
135 135
136(defcustom eshell-lisp-form-nil-is-failure t
137 "If non-nil, Lisp forms like (COMMAND ARGS) treat a nil result as failure."
138 :type 'boolean)
139
136(defcustom eshell-pre-command-hook nil 140(defcustom eshell-pre-command-hook nil
137 "A hook run before each interactive command is invoked." 141 "A hook run before each interactive command is invoked."
138 :type 'hook) 142 :type 'hook)
@@ -541,9 +545,7 @@ implemented via rewriting, rather than as a function."
541 ,(eshell-invokify-arg body t))) 545 ,(eshell-invokify-arg body t)))
542 (setcar for-items (cadr for-items)) 546 (setcar for-items (cadr for-items))
543 (setcdr for-items (cddr for-items))) 547 (setcdr for-items (cddr for-items)))
544 (eshell-close-handles 548 (eshell-close-handles)))))
545 eshell-last-command-status
546 (list 'quote eshell-last-command-result))))))
547 549
548(defun eshell-structure-basic-command (func names keyword test body 550(defun eshell-structure-basic-command (func names keyword test body
549 &optional else) 551 &optional else)
@@ -551,10 +553,11 @@ implemented via rewriting, rather than as a function."
551The first of NAMES should be the positive form, and the second the 553The first of NAMES should be the positive form, and the second the
552negative. It's not likely that users should ever need to call this 554negative. It's not likely that users should ever need to call this
553function." 555function."
554 ;; If the test form begins with `eshell-convert', it means 556 ;; If the test form begins with `eshell-convert' or
555 ;; something data-wise will be returned, and we should let 557 ;; `eshell-escape-arg', it means something data-wise will be
556 ;; that determine the truth of the statement. 558 ;; returned, and we should let that determine the truth of the
557 (unless (eq (car test) 'eshell-convert) 559 ;; statement.
560 (unless (memq (car test) '(eshell-convert eshell-escape-arg))
558 (setq test 561 (setq test
559 `(progn ,test 562 `(progn ,test
560 (eshell-exit-success-p)))) 563 (eshell-exit-success-p))))
@@ -574,9 +577,7 @@ function."
574 `(let ((eshell-command-body '(nil)) 577 `(let ((eshell-command-body '(nil))
575 (eshell-test-body '(nil))) 578 (eshell-test-body '(nil)))
576 (,func ,test ,body ,else) 579 (,func ,test ,body ,else)
577 (eshell-close-handles 580 (eshell-close-handles)))
578 eshell-last-command-status
579 (list 'quote eshell-last-command-result))))
580 581
581(defun eshell-rewrite-while-command (terms) 582(defun eshell-rewrite-while-command (terms)
582 "Rewrite a `while' command into its equivalent Eshell command form. 583 "Rewrite a `while' command into its equivalent Eshell command form.
@@ -1415,43 +1416,53 @@ via `eshell-errorn'."
1415(defun eshell-lisp-command (object &optional args) 1416(defun eshell-lisp-command (object &optional args)
1416 "Insert Lisp OBJECT, using ARGS if a function." 1417 "Insert Lisp OBJECT, using ARGS if a function."
1417 (catch 'eshell-external ; deferred to an external command 1418 (catch 'eshell-external ; deferred to an external command
1419 (setq eshell-last-command-status 0
1420 eshell-last-arguments args)
1418 (let* ((eshell-ensure-newline-p (eshell-interactive-output-p)) 1421 (let* ((eshell-ensure-newline-p (eshell-interactive-output-p))
1422 (command-form-p (functionp object))
1419 (result 1423 (result
1420 (if (functionp object) 1424 (if command-form-p
1421 (progn 1425 (let ((numeric (not (get object
1422 (setq eshell-last-arguments args 1426 'eshell-no-numeric-conversions)))
1423 eshell-last-command-name 1427 (fname-args (get object 'eshell-filename-arguments)))
1428 (when (or numeric fname-args)
1429 (while args
1430 (let ((arg (car args)))
1431 (cond
1432 ((and numeric (stringp arg) (> (length arg) 0)
1433 (text-property-any 0 (length arg)
1434 'number t arg))
1435 ;; If any of the arguments are flagged as
1436 ;; numbers waiting for conversion, convert
1437 ;; them now.
1438 (setcar args (string-to-number arg)))
1439 ((and fname-args (stringp arg)
1440 (string-equal arg "~"))
1441 ;; If any of the arguments match "~",
1442 ;; prepend "./" to treat it as a regular
1443 ;; file name.
1444 (setcar args (concat "./" arg)))))
1445 (setq args (cdr args))))
1446 (setq eshell-last-command-name
1424 (concat "#<function " (symbol-name object) ">")) 1447 (concat "#<function " (symbol-name object) ">"))
1425 (let ((numeric (not (get object
1426 'eshell-no-numeric-conversions)))
1427 (fname-args (get object 'eshell-filename-arguments)))
1428 (when (or numeric fname-args)
1429 (while args
1430 (let ((arg (car args)))
1431 (cond ((and numeric (stringp arg) (> (length arg) 0)
1432 (text-property-any 0 (length arg)
1433 'number t arg))
1434 ;; If any of the arguments are
1435 ;; flagged as numbers waiting for
1436 ;; conversion, convert them now.
1437 (setcar args (string-to-number arg)))
1438 ((and fname-args (stringp arg)
1439 (string-equal arg "~"))
1440 ;; If any of the arguments match "~",
1441 ;; prepend "./" to treat it as a
1442 ;; regular file name.
1443 (setcar args (concat "./" arg)))))
1444 (setq args (cdr args)))))
1445 (eshell-apply object eshell-last-arguments)) 1448 (eshell-apply object eshell-last-arguments))
1446 (setq eshell-last-arguments args 1449 (setq eshell-last-command-name "#<Lisp object>")
1447 eshell-last-command-name "#<Lisp object>")
1448 (eshell-eval object)))) 1450 (eshell-eval object))))
1449 (if (and eshell-ensure-newline-p 1451 (if (and eshell-ensure-newline-p
1450 (save-excursion 1452 (save-excursion
1451 (goto-char eshell-last-output-end) 1453 (goto-char eshell-last-output-end)
1452 (not (bolp)))) 1454 (not (bolp))))
1453 (eshell-print "\n")) 1455 (eshell-print "\n"))
1454 (eshell-close-handles 0 (list 'quote result))))) 1456 (eshell-close-handles
1457 ;; If `eshell-lisp-form-nil-is-failure' is non-nil, Lisp forms
1458 ;; that succeeded but have a nil result should have an exit
1459 ;; status of 2.
1460 (when (and eshell-lisp-form-nil-is-failure
1461 (not command-form-p)
1462 (= eshell-last-command-status 0)
1463 (not result))
1464 2)
1465 (list 'quote result)))))
1455 1466
1456(defalias 'eshell-lisp-command* #'eshell-lisp-command) 1467(defalias 'eshell-lisp-command* #'eshell-lisp-command)
1457 1468
diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el
index 68e52a2c9c8..27703976f6d 100644
--- a/lisp/eshell/esh-io.el
+++ b/lisp/eshell/esh-io.el
@@ -254,6 +254,30 @@ a nil value of mode defaults to `insert'."
254 (setq idx (1+ idx)))) 254 (setq idx (1+ idx))))
255 handles) 255 handles)
256 256
257(defun eshell-close-handles (&optional exit-code result handles)
258 "Close all of the current HANDLES, taking refcounts into account.
259If HANDLES is nil, use `eshell-current-handles'.
260
261EXIT-CODE is the process exit code (zero, if the command
262completed successfully). If nil, then use the exit code already
263set in `eshell-last-command-status'.
264
265RESULT is the quoted value of the last command. If nil, then use
266the value already set in `eshell-last-command-result'."
267 (when exit-code
268 (setq eshell-last-command-status exit-code))
269 (when result
270 (cl-assert (eq (car result) 'quote))
271 (setq eshell-last-command-result (cadr result)))
272 (let ((handles (or handles eshell-current-handles)))
273 (dotimes (idx eshell-number-of-handles)
274 (when-let ((handle (aref handles idx)))
275 (setcdr handle (1- (cdr handle)))
276 (when (= (cdr handle) 0)
277 (dolist (target (ensure-list (car (aref handles idx))))
278 (eshell-close-target target (= eshell-last-command-status 0)))
279 (setcar handle nil))))))
280
257(defun eshell-close-target (target status) 281(defun eshell-close-target (target status)
258 "Close an output TARGET, passing STATUS as the result. 282 "Close an output TARGET, passing STATUS as the result.
259STATUS should be non-nil on successful termination of the output." 283STATUS should be non-nil on successful termination of the output."
@@ -305,32 +329,6 @@ STATUS should be non-nil on successful termination of the output."
305 ((consp target) 329 ((consp target)
306 (apply (car target) status (cdr target))))) 330 (apply (car target) status (cdr target)))))
307 331
308(defun eshell-close-handles (exit-code &optional result handles)
309 "Close all of the current handles, taking refcounts into account.
310EXIT-CODE is the process exit code; mainly, it is zero, if the command
311completed successfully. RESULT is the quoted value of the last
312command. If nil, then the meta variables for keeping track of the
313last execution result should not be changed."
314 (let ((idx 0))
315 (cl-assert (or (not result) (eq (car result) 'quote)))
316 (setq eshell-last-command-status exit-code
317 eshell-last-command-result (cadr result))
318 (while (< idx eshell-number-of-handles)
319 (let ((handles (or handles eshell-current-handles)))
320 (when (aref handles idx)
321 (setcdr (aref handles idx)
322 (1- (cdr (aref handles idx))))
323 (when (= (cdr (aref handles idx)) 0)
324 (let ((target (car (aref handles idx))))
325 (if (not (listp target))
326 (eshell-close-target target (= exit-code 0))
327 (while target
328 (eshell-close-target (car target) (= exit-code 0))
329 (setq target (cdr target)))))
330 (setcar (aref handles idx) nil))))
331 (setq idx (1+ idx)))
332 nil))
333
334(defun eshell-kill-append (string) 332(defun eshell-kill-append (string)
335 "Call `kill-append' with STRING, if it is indeed a string." 333 "Call `kill-append' with STRING, if it is indeed a string."
336 (if (stringp string) 334 (if (stringp string)
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index 99b43661f2c..c367b5cd643 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -346,7 +346,9 @@ Used only on systems which do not support async subprocesses.")
346 (defvar eshell-last-output-end) ;Defined in esh-mode.el. 346 (defvar eshell-last-output-end) ;Defined in esh-mode.el.
347 (eshell-update-markers eshell-last-output-end) 347 (eshell-update-markers eshell-last-output-end)
348 ;; Simulate the effect of eshell-sentinel. 348 ;; Simulate the effect of eshell-sentinel.
349 (eshell-close-handles (if (numberp exit-status) exit-status -1)) 349 (eshell-close-handles
350 (if (numberp exit-status) exit-status -1)
351 (list 'quote (and (numberp exit-status) (= exit-status 0))))
350 (eshell-kill-process-function command exit-status) 352 (eshell-kill-process-function command exit-status)
351 (or (bound-and-true-p eshell-in-pipeline-p) 353 (or (bound-and-true-p eshell-in-pipeline-p)
352 (setq eshell-last-sync-output-start nil)) 354 (setq eshell-last-sync-output-start nil))
@@ -398,40 +400,36 @@ PROC is the process that's exiting. STRING is the exit message."
398 (when (buffer-live-p (process-buffer proc)) 400 (when (buffer-live-p (process-buffer proc))
399 (with-current-buffer (process-buffer proc) 401 (with-current-buffer (process-buffer proc)
400 (unwind-protect 402 (unwind-protect
401 (let ((entry (assq proc eshell-process-list))) 403 (when-let ((entry (assq proc eshell-process-list)))
402; (if (not entry) 404 (unwind-protect
403; (error "Sentinel called for unowned process `%s'" 405 (unless (string= string "run")
404; (process-name proc)) 406 ;; Write the exit message if the status is
405 (when entry 407 ;; abnormal and the process is already writing
406 (unwind-protect 408 ;; to the terminal.
407 (progn 409 (when (and (eq proc (eshell-tail-process))
408 (unless (string= string "run") 410 (not (string-match "^\\(finished\\|exited\\)"
409 ;; Write the exit message if the status is 411 string)))
410 ;; abnormal and the process is already writing 412 (funcall (process-filter proc) proc string))
411 ;; to the terminal. 413 (let ((handles (nth 1 entry))
412 (when (and (eq proc (eshell-tail-process)) 414 (str (prog1 (nth 3 entry)
413 (not (string-match "^\\(finished\\|exited\\)" 415 (setf (nth 3 entry) nil)))
414 string))) 416 (status (process-exit-status proc)))
415 (funcall (process-filter proc) proc string)) 417 ;; If we're in the middle of handling output
416 (let ((handles (nth 1 entry)) 418 ;; from this process then schedule the EOF for
417 (str (prog1 (nth 3 entry) 419 ;; later.
418 (setf (nth 3 entry) nil))) 420 (letrec ((finish-io
419 (status (process-exit-status proc))) 421 (lambda ()
420 ;; If we're in the middle of handling output 422 (if (nth 4 entry)
421 ;; from this process then schedule the EOF for 423 (run-at-time 0 nil finish-io)
422 ;; later. 424 (when str
423 (letrec ((finish-io 425 (ignore-error 'eshell-pipe-broken
424 (lambda () 426 (eshell-output-object
425 (if (nth 4 entry) 427 str nil handles)))
426 (run-at-time 0 nil finish-io) 428 (eshell-close-handles
427 (when str 429 status (list 'quote (= status 0))
428 (ignore-error 'eshell-pipe-broken 430 handles)))))
429 (eshell-output-object 431 (funcall finish-io))))
430 str nil handles))) 432 (eshell-remove-process-entry entry)))
431 (eshell-close-handles
432 status 'nil handles)))))
433 (funcall finish-io)))))
434 (eshell-remove-process-entry entry))))
435 (eshell-kill-process-function proc string))))) 433 (eshell-kill-process-function proc string)))))
436 434
437(defun eshell-process-interact (func &optional all query) 435(defun eshell-process-interact (func &optional all query)
diff --git a/lisp/faces.el b/lisp/faces.el
index c7acbf57587..390ddbf606a 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -2046,18 +2046,29 @@ as backgrounds."
2046 (when msg (message "Color: `%s'" color)) 2046 (when msg (message "Color: `%s'" color))
2047 color)) 2047 color))
2048 2048
2049(defun face-at-point (&optional thing multiple) 2049(defun face-at-point (&optional text multiple)
2050 "Return the face of the character after point. 2050 "Return a face name from point in the current buffer.
2051If it has more than one face, return the first one. 2051This function is meant to be used as a conveniency function for
2052If THING is non-nil try first to get a face name from the buffer. 2052providing defaults when prompting the user for a face name.
2053IF MULTIPLE is non-nil, return a list of all faces. 2053
2054Return nil if there is no face." 2054If TEXT is non-nil, return the text at point if it names an
2055existing face.
2056
2057Otherwise, look at the faces in effect at point as text
2058properties or overlay properties, and return one of these face
2059names.
2060
2061IF MULTIPLE is non-nil, return a list of faces.
2062
2063Return nil if there is no face at point.
2064
2065This function is not meant for handling faces programatically; to
2066do that, use `get-text-property' and `get-char-property'."
2055 (let (faces) 2067 (let (faces)
2056 (if thing 2068 (when text
2057 ;; Try to get a face name from the buffer. 2069 ;; Try to get a face name from the buffer.
2058 (let ((face (intern-soft (thing-at-point 'symbol)))) 2070 (when-let ((face (thing-at-point 'face)))
2059 (if (facep face) 2071 (push face faces)))
2060 (push face faces))))
2061 ;; Add the named faces that the `read-face-name' or `face' property uses. 2072 ;; Add the named faces that the `read-face-name' or `face' property uses.
2062 (let ((faceprop (or (get-char-property (point) 'read-face-name) 2073 (let ((faceprop (or (get-char-property (point) 'read-face-name)
2063 (get-char-property (point) 'face)))) 2074 (get-char-property (point) 'face))))
diff --git a/lisp/finder.el b/lisp/finder.el
index 73072c0cd48..08d20963b46 100644
--- a/lisp/finder.el
+++ b/lisp/finder.el
@@ -77,6 +77,7 @@ Each element has the form (KEYWORD . DESCRIPTION).")
77 77
78(defvar-keymap finder-mode-map 78(defvar-keymap finder-mode-map
79 :doc "Keymap used in `finder-mode'." 79 :doc "Keymap used in `finder-mode'."
80 :parent special-mode-map
80 "SPC" #'finder-select 81 "SPC" #'finder-select
81 "f" #'finder-select 82 "f" #'finder-select
82 "<follow-link>" 'mouse-face 83 "<follow-link>" 'mouse-face
@@ -420,15 +421,14 @@ FILE should be in a form suitable for passing to `locate-library'."
420 (interactive) 421 (interactive)
421 (finder-list-keywords)) 422 (finder-list-keywords))
422 423
423(define-derived-mode finder-mode nil "Finder" 424(define-derived-mode finder-mode special-mode "Finder"
424 "Major mode for browsing package documentation. 425 "Major mode for browsing package documentation.
425\\<finder-mode-map> 426\\<finder-mode-map>
426\\[finder-select] more help for the item on the current line 427\\[finder-select] more help for the item on the current line
427\\[finder-exit] exit Finder mode and kill the Finder buffer." 428\\[finder-exit] exit Finder mode and kill the Finder buffer.
428 :syntax-table finder-mode-syntax-table 429
430\\{finder-mode-map}"
429 :interactive nil 431 :interactive nil
430 (setq buffer-read-only t
431 buffer-undo-list t)
432 (setq-local finder-headmark nil)) 432 (setq-local finder-headmark nil))
433 433
434(defun finder-summary () 434(defun finder-summary ()
@@ -436,9 +436,9 @@ FILE should be in a form suitable for passing to `locate-library'."
436 (interactive nil finder-mode) 436 (interactive nil finder-mode)
437 (message "%s" 437 (message "%s"
438 (substitute-command-keys 438 (substitute-command-keys
439 "\\<finder-mode-map>\\[finder-select] = select, \ 439 "\\<finder-mode-map>\\[finder-select] select, \
440\\[finder-mouse-select] = select, \\[finder-list-keywords] = to \ 440\\[finder-mouse-select] select, \\[finder-list-keywords] go to \
441finder directory, \\[finder-exit] = quit, \\[finder-summary] = help"))) 441finder directory, \\[finder-exit] quit, \\[finder-summary] help")))
442 442
443(defun finder-exit () 443(defun finder-exit ()
444 "Exit Finder mode. 444 "Exit Finder mode.
diff --git a/lisp/gnus/deuglify.el b/lisp/gnus/deuglify.el
index 732c6062b8b..41fc2d83ac3 100644
--- a/lisp/gnus/deuglify.el
+++ b/lisp/gnus/deuglify.el
@@ -223,6 +223,7 @@
223 223
224(defconst gnus-outlook-deuglify-version "1.5 Gnus version" 224(defconst gnus-outlook-deuglify-version "1.5 Gnus version"
225 "Version of gnus-outlook-deuglify.") 225 "Version of gnus-outlook-deuglify.")
226(make-obsolete-variable 'gnus-outlook-deuglify-version 'emacs-version "29.1")
226 227
227;;; User Customizable Variables: 228;;; User Customizable Variables:
228 229
diff --git a/lisp/gnus/gnus-diary.el b/lisp/gnus/gnus-diary.el
index cd2b53064b9..6028d4fcb2f 100644
--- a/lisp/gnus/gnus-diary.el
+++ b/lisp/gnus/gnus-diary.el
@@ -65,8 +65,9 @@ There are currently two built-in format functions:
65 (const :tag "french" gnus-diary-delay-format-french) 65 (const :tag "french" gnus-diary-delay-format-french)
66 (symbol :tag "other"))) 66 (symbol :tag "other")))
67 67
68(defconst gnus-diary-version nndiary-version 68(defconst gnus-diary-version "0.2-b14"
69 "Current Diary back end version.") 69 "Current Diary back end version.")
70(make-obsolete-variable 'gnus-diary-version 'emacs-version "29.1")
70 71
71 72
72;; Compatibility functions ================================================== 73;; Compatibility functions ==================================================
@@ -377,8 +378,9 @@ If ARG (or prefix) is non-nil, force prompting for all fields."
377 378
378(defun gnus-diary-version () 379(defun gnus-diary-version ()
379 "Current Diary back end version." 380 "Current Diary back end version."
381 (declare (obsolete emacs-version "29.1"))
380 (interactive) 382 (interactive)
381 (message "NNDiary version %s" nndiary-version)) 383 (message "NNDiary version %s" gnus-diary-version))
382 384
383(provide 'gnus-diary) 385(provide 'gnus-diary)
384 386
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index d1ad5bd7b2d..4c93814e0dc 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -40,17 +40,14 @@
40 40
41(defcustom gnus-completing-read-function 'gnus-emacs-completing-read 41(defcustom gnus-completing-read-function 'gnus-emacs-completing-read
42 "Function use to do completing read." 42 "Function use to do completing read."
43 :version "24.1" 43 :version "29.1"
44 :group 'gnus-meta 44 :group 'gnus-meta
45 :type '(radio (function-item 45 :type '(radio (function-item
46 :doc "Use Emacs standard `completing-read' function." 46 :doc "Use Emacs standard `completing-read' function."
47 gnus-emacs-completing-read) 47 gnus-emacs-completing-read)
48 (function-item 48 (function-item
49 :doc "Use `ido-completing-read' function." 49 :doc "Use `ido-completing-read' function."
50 gnus-ido-completing-read) 50 gnus-ido-completing-read)))
51 (function-item
52 :doc "Use iswitchb based completing-read function."
53 gnus-iswitchb-completing-read)))
54 51
55(defcustom gnus-completion-styles 52(defcustom gnus-completion-styles
56 (append (when (and (assq 'substring completion-styles-alist) 53 (append (when (and (assq 'substring completion-styles-alist)
@@ -1202,6 +1199,7 @@ SPEC is a predicate specifier that contains stuff like `or', `and',
1202(defun gnus-iswitchb-completing-read (prompt collection &optional require-match 1199(defun gnus-iswitchb-completing-read (prompt collection &optional require-match
1203 initial-input history def) 1200 initial-input history def)
1204 "`iswitchb' based completing-read function." 1201 "`iswitchb' based completing-read function."
1202 (declare (obsolete nil "29.1"))
1205 ;; Make sure iswitchb is loaded before we let-bind its variables. 1203 ;; Make sure iswitchb is loaded before we let-bind its variables.
1206 ;; If it is loaded inside the let, variables can become unbound afterwards. 1204 ;; If it is loaded inside the let, variables can become unbound afterwards.
1207 (require 'iswitchb) 1205 (require 'iswitchb)
diff --git a/lisp/gnus/gnus-uu.el b/lisp/gnus/gnus-uu.el
index 6990d8ee778..ee6cab365f3 100644
--- a/lisp/gnus/gnus-uu.el
+++ b/lisp/gnus/gnus-uu.el
@@ -260,9 +260,10 @@ Default is t."
260 "Non-nil means that files will be viewed with metamail. 260 "Non-nil means that files will be viewed with metamail.
261The gnus-uu viewing functions will be ignored and gnus-uu will try 261The gnus-uu viewing functions will be ignored and gnus-uu will try
262to guess at a content-type based on file name suffixes. Default 262to guess at a content-type based on file name suffixes. Default
263it nil." 263is nil."
264 :group 'gnus-extract 264 :group 'gnus-extract
265 :type 'boolean) 265 :type 'boolean)
266(make-obsolete-variable 'gnus-uu-view-with-metamail "don't use it." "29.1")
266 267
267(defcustom gnus-uu-unmark-articles-not-decoded nil 268(defcustom gnus-uu-unmark-articles-not-decoded nil
268 "If non-nil, gnus-uu will mark unsuccessfully decoded articles as unread. 269 "If non-nil, gnus-uu will mark unsuccessfully decoded articles as unread.
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el
index b036978efa8..0afd873a5df 100644
--- a/lisp/gnus/gnus.el
+++ b/lisp/gnus/gnus.el
@@ -4166,8 +4166,7 @@ prompt the user for the name of an NNTP server to use."
4166 ;; file. 4166 ;; file.
4167 (unless (string-match "^Gnus" gnus-version) 4167 (unless (string-match "^Gnus" gnus-version)
4168 (load "gnus-load" nil t)) 4168 (load "gnus-load" nil t))
4169 (unless (or (byte-code-function-p (symbol-function 'gnus)) 4169 (unless (compiled-function-p (symbol-function 'gnus))
4170 (subr-native-elisp-p (symbol-function 'gnus)))
4171 (message "You should compile Gnus") 4170 (message "You should compile Gnus")
4172 (sit-for 2)) 4171 (sit-for 2))
4173 (let ((gnus-action-message-log (list nil))) 4172 (let ((gnus-action-message-log (list nil)))
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 00a27fb5f51..8a3967f3461 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -2086,6 +2086,7 @@ You must have the \"hashcash\" binary installed, see `hashcash-path'."
2086 2086
2087(defun message-mark-active-p () 2087(defun message-mark-active-p ()
2088 "Non-nil means the mark and region are currently active in this buffer." 2088 "Non-nil means the mark and region are currently active in this buffer."
2089 (declare (obsolete mark-active "29.1"))
2089 mark-active) 2090 mark-active)
2090 2091
2091(defun message-unquote-tokens (elems) 2092(defun message-unquote-tokens (elems)
@@ -2953,12 +2954,12 @@ Consider adding this function to `message-header-setup-hook'"
2953 ["Fill Yanked Message" message-fill-yanked-message t] 2954 ["Fill Yanked Message" message-fill-yanked-message t]
2954 ["Insert Signature" message-insert-signature t] 2955 ["Insert Signature" message-insert-signature t]
2955 ["Caesar (rot13) Message" message-caesar-buffer-body t] 2956 ["Caesar (rot13) Message" message-caesar-buffer-body t]
2956 ["Caesar (rot13) Region" message-caesar-region (message-mark-active-p)] 2957 ["Caesar (rot13) Region" message-caesar-region mark-active]
2957 ["Elide Region" message-elide-region 2958 ["Elide Region" message-elide-region
2958 :active (message-mark-active-p) 2959 :active mark-active
2959 :help "Replace text in region with an ellipsis"] 2960 :help "Replace text in region with an ellipsis"]
2960 ["Delete Outside Region" message-delete-not-region 2961 ["Delete Outside Region" message-delete-not-region
2961 :active (message-mark-active-p) 2962 :active mark-active
2962 :help "Delete all quoted text outside region"] 2963 :help "Delete all quoted text outside region"]
2963 ["Kill To Signature" message-kill-to-signature t] 2964 ["Kill To Signature" message-kill-to-signature t]
2964 ["Newline and Reformat" message-newline-and-reformat t] 2965 ["Newline and Reformat" message-newline-and-reformat t]
@@ -2966,7 +2967,7 @@ Consider adding this function to `message-header-setup-hook'"
2966 ["Spellcheck" ispell-message :help "Spellcheck this message"] 2967 ["Spellcheck" ispell-message :help "Spellcheck this message"]
2967 "----" 2968 "----"
2968 ["Insert Region Marked" message-mark-inserted-region 2969 ["Insert Region Marked" message-mark-inserted-region
2969 :active (message-mark-active-p) :help "Mark region with enclosing tags"] 2970 :active mark-active :help "Mark region with enclosing tags"]
2970 ["Insert File Marked..." message-mark-insert-file 2971 ["Insert File Marked..." message-mark-insert-file
2971 :help "Insert file at point marked with enclosing tags"] 2972 :help "Insert file at point marked with enclosing tags"]
2972 ["Attach File..." mml-attach-file t] 2973 ["Attach File..." mml-attach-file t]
diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el
index 79217d34001..1417ecdccc8 100644
--- a/lisp/gnus/mm-decode.el
+++ b/lisp/gnus/mm-decode.el
@@ -117,8 +117,7 @@
117 (cond ((fboundp 'libxml-parse-html-region) 'shr) 117 (cond ((fboundp 'libxml-parse-html-region) 'shr)
118 ((executable-find "w3m") 'gnus-w3m) 118 ((executable-find "w3m") 'gnus-w3m)
119 ((executable-find "links") 'links) 119 ((executable-find "links") 'links)
120 ((executable-find "lynx") 'lynx) 120 ((executable-find "lynx") 'lynx))
121 ((locate-library "html2text") 'html2text))
122 "Render of HTML contents. 121 "Render of HTML contents.
123It is one of defined renderer types, or a rendering function. 122It is one of defined renderer types, or a rendering function.
124The defined renderer types are: 123The defined renderer types are:
@@ -127,16 +126,14 @@ The defined renderer types are:
127`w3m': use emacs-w3m; 126`w3m': use emacs-w3m;
128`w3m-standalone': use plain w3m; 127`w3m-standalone': use plain w3m;
129`links': use links; 128`links': use links;
130`lynx': use lynx; 129`lynx': use lynx."
131`html2text': use html2text." 130 :version "29.1"
132 :version "27.1"
133 :type '(choice (const shr) 131 :type '(choice (const shr)
134 (const gnus-w3m) 132 (const gnus-w3m)
135 (const w3m :tag "emacs-w3m") 133 (const w3m :tag "emacs-w3m")
136 (const w3m-standalone :tag "standalone w3m" ) 134 (const w3m-standalone :tag "standalone w3m" )
137 (const links) 135 (const links)
138 (const lynx) 136 (const lynx)
139 (const html2text)
140 (function)) 137 (function))
141 :group 'mime-display) 138 :group 'mime-display)
142 139
diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el
index 5cd57d2f801..e8291cfe6f7 100644
--- a/lisp/gnus/mml.el
+++ b/lisp/gnus/mml.el
@@ -35,7 +35,6 @@
35(declare-function gnus-setup-posting-charset "gnus-msg" (group)) 35(declare-function gnus-setup-posting-charset "gnus-msg" (group))
36(autoload 'gnus-completing-read "gnus-util") 36(autoload 'gnus-completing-read "gnus-util")
37(autoload 'message-fetch-field "message") 37(autoload 'message-fetch-field "message")
38(autoload 'message-mark-active-p "message")
39(autoload 'message-info "message") 38(autoload 'message-info "message")
40(autoload 'fill-flowed-encode "flow-fill") 39(autoload 'fill-flowed-encode "flow-fill")
41(autoload 'message-posting-charset "message") 40(autoload 'message-posting-charset "message")
@@ -1236,7 +1235,7 @@ If HANDLES is non-nil, use it instead reparsing the buffer."
1236 ;; 1235 ;;
1237 ;;["Narrow" mml-narrow-to-part t] 1236 ;;["Narrow" mml-narrow-to-part t]
1238 ["Quote MML in region" mml-quote-region 1237 ["Quote MML in region" mml-quote-region
1239 :active (message-mark-active-p) 1238 :active mark-active
1240 :help "Quote MML tags in region"] 1239 :help "Quote MML tags in region"]
1241 ["Validate MML" mml-validate t] 1240 ["Validate MML" mml-validate t]
1242 ["Preview" mml-preview t] 1241 ["Preview" mml-preview t]
diff --git a/lisp/gnus/nnagent.el b/lisp/gnus/nnagent.el
index 60140a46411..d7e32e45809 100644
--- a/lisp/gnus/nnagent.el
+++ b/lisp/gnus/nnagent.el
@@ -35,6 +35,7 @@
35 35
36 36
37(defconst nnagent-version "nnagent 1.0") 37(defconst nnagent-version "nnagent 1.0")
38(make-obsolete-variable 'nnagent-version 'emacs-version "29.1")
38 39
39(defvoo nnagent-directory nil 40(defvoo nnagent-directory nil
40 "Internal variable." 41 "Internal variable."
diff --git a/lisp/gnus/nnbabyl.el b/lisp/gnus/nnbabyl.el
index ff0dea8ecdd..5f9903a5b06 100644
--- a/lisp/gnus/nnbabyl.el
+++ b/lisp/gnus/nnbabyl.el
@@ -55,6 +55,7 @@
55 55
56(defconst nnbabyl-version "nnbabyl 1.0" 56(defconst nnbabyl-version "nnbabyl 1.0"
57 "nnbabyl version.") 57 "nnbabyl version.")
58(make-obsolete-variable 'nnbabyl-version 'emacs-version "29.1")
58 59
59(defvoo nnbabyl-mbox-buffer nil) 60(defvoo nnbabyl-mbox-buffer nil)
60(defvoo nnbabyl-current-group nil) 61(defvoo nnbabyl-current-group nil)
diff --git a/lisp/gnus/nndiary.el b/lisp/gnus/nndiary.el
index bd60c43f59d..14540ac7e87 100644
--- a/lisp/gnus/nndiary.el
+++ b/lisp/gnus/nndiary.el
@@ -234,9 +234,11 @@ all. This may very well take some time.")
234 234
235(defconst nndiary-version "0.2-b14" 235(defconst nndiary-version "0.2-b14"
236 "Current Diary back end version.") 236 "Current Diary back end version.")
237(make-obsolete-variable 'nndiary-version 'emacs-version "29.1")
237 238
238(defun nndiary-version () 239(defun nndiary-version ()
239 "Current Diary back end version." 240 "Current Diary back end version."
241 (declare (obsolete emacs-version "29.1"))
240 (interactive) 242 (interactive)
241 (message "NNDiary version %s" nndiary-version)) 243 (message "NNDiary version %s" nndiary-version))
242 244
diff --git a/lisp/gnus/nndir.el b/lisp/gnus/nndir.el
index 2ca25534ce1..75a6ace107a 100644
--- a/lisp/gnus/nndir.el
+++ b/lisp/gnus/nndir.el
@@ -48,6 +48,7 @@
48 48
49(defvoo nndir-status-string "" nil nnmh-status-string) 49(defvoo nndir-status-string "" nil nnmh-status-string)
50(defconst nndir-version "nndir 1.0") 50(defconst nndir-version "nndir 1.0")
51(make-obsolete-variable 'nndir-version 'emacs-version "29.1")
51 52
52 53
53 54
diff --git a/lisp/gnus/nndoc.el b/lisp/gnus/nndoc.el
index 19ccce47b50..cdff7c9accf 100644
--- a/lisp/gnus/nndoc.el
+++ b/lisp/gnus/nndoc.el
@@ -218,6 +218,7 @@ from the document.")
218 218
219(defconst nndoc-version "nndoc 1.0" 219(defconst nndoc-version "nndoc 1.0"
220 "nndoc version.") 220 "nndoc version.")
221(make-obsolete-variable 'nndoc-version 'emacs-version "29.1")
221 222
222 223
223 224
diff --git a/lisp/gnus/nndraft.el b/lisp/gnus/nndraft.el
index fa88b8a87e0..f21e4faf559 100644
--- a/lisp/gnus/nndraft.el
+++ b/lisp/gnus/nndraft.el
@@ -56,6 +56,7 @@ are generated if and only if they are also in `message-draft-headers'."
56(defvoo nndraft-current-directory nil nil nnmh-current-directory) 56(defvoo nndraft-current-directory nil nil nnmh-current-directory)
57 57
58(defconst nndraft-version "nndraft 1.0") 58(defconst nndraft-version "nndraft 1.0")
59(make-obsolete-variable 'nndraft-version 'emacs-version "29.1")
59(defvoo nndraft-status-string "" nil nnmh-status-string) 60(defvoo nndraft-status-string "" nil nnmh-status-string)
60 61
61 62
diff --git a/lisp/gnus/nneething.el b/lisp/gnus/nneething.el
index 0c565a8230c..ff72842a2ee 100644
--- a/lisp/gnus/nneething.el
+++ b/lisp/gnus/nneething.el
@@ -57,6 +57,7 @@ included.")
57 57
58(defconst nneething-version "nneething 1.0" 58(defconst nneething-version "nneething 1.0"
59 "nneething version.") 59 "nneething version.")
60(make-obsolete-variable 'nneething-version 'emacs-version "29.1")
60 61
61(defvoo nneething-current-directory nil 62(defvoo nneething-current-directory nil
62 "Current news group directory.") 63 "Current news group directory.")
diff --git a/lisp/gnus/nnfolder.el b/lisp/gnus/nnfolder.el
index c3f7073a7b8..a2b461c15f0 100644
--- a/lisp/gnus/nnfolder.el
+++ b/lisp/gnus/nnfolder.el
@@ -91,6 +91,7 @@ message, a huge time saver for large mailboxes.")
91 91
92(defconst nnfolder-version "nnfolder 2.0" 92(defconst nnfolder-version "nnfolder 2.0"
93 "nnfolder version.") 93 "nnfolder version.")
94(make-obsolete-variable 'nnfolder-version 'emacs-version "29.1")
94 95
95(defconst nnfolder-article-marker "X-Gnus-Article-Number: " 96(defconst nnfolder-article-marker "X-Gnus-Article-Number: "
96 "String used to demarcate what the article number for a message is.") 97 "String used to demarcate what the article number for a message is.")
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index 3dc74c95fb3..4d1ecbf8642 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -62,6 +62,7 @@
62 (require 'subr-x)) 62 (require 'subr-x))
63 63
64(defconst nnmaildir-version "Gnus") 64(defconst nnmaildir-version "Gnus")
65(make-obsolete-variable 'nnmaildir-version 'emacs-version "29.1")
65 66
66(defconst nnmaildir-flag-mark-mapping 67(defconst nnmaildir-flag-mark-mapping
67 '((?F . tick) 68 '((?F . tick)
diff --git a/lisp/gnus/nnmbox.el b/lisp/gnus/nnmbox.el
index 96ecc34e156..5735c97805e 100644
--- a/lisp/gnus/nnmbox.el
+++ b/lisp/gnus/nnmbox.el
@@ -52,6 +52,7 @@
52 52
53(defconst nnmbox-version "nnmbox 1.0" 53(defconst nnmbox-version "nnmbox 1.0"
54 "nnmbox version.") 54 "nnmbox version.")
55(make-obsolete-variable 'nnmbox-version 'emacs-version "29.1")
55 56
56(defvoo nnmbox-current-group nil 57(defvoo nnmbox-current-group nil
57 "Current nnmbox news group directory.") 58 "Current nnmbox news group directory.")
diff --git a/lisp/gnus/nnmh.el b/lisp/gnus/nnmh.el
index 3902af7d2f6..bced527d03f 100644
--- a/lisp/gnus/nnmh.el
+++ b/lisp/gnus/nnmh.el
@@ -55,6 +55,7 @@ as unread by Gnus.")
55 55
56(defconst nnmh-version "nnmh 1.0" 56(defconst nnmh-version "nnmh 1.0"
57 "nnmh version.") 57 "nnmh version.")
58(make-obsolete-variable 'nnmh-version 'emacs-version "29.1")
58 59
59(defvoo nnmh-current-directory nil 60(defvoo nnmh-current-directory nil
60 "Current news group directory.") 61 "Current news group directory.")
diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el
index 7fe2b516cce..ae726ba0f7b 100644
--- a/lisp/gnus/nnml.el
+++ b/lisp/gnus/nnml.el
@@ -89,6 +89,7 @@ non-nil.")
89 89
90(defconst nnml-version "nnml 1.0" 90(defconst nnml-version "nnml 1.0"
91 "nnml version.") 91 "nnml version.")
92(make-obsolete-variable 'nnml-version 'emacs-version "29.1")
92 93
93(defvoo nnml-nov-file-name ".overview") 94(defvoo nnml-nov-file-name ".overview")
94 95
diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el
index 8c96d3e0678..99e7b2a6f3f 100644
--- a/lisp/gnus/nnrss.el
+++ b/lisp/gnus/nnrss.el
@@ -71,6 +71,7 @@ this variable to the list of fields to be ignored.")
71(defvoo nnrss-status-string "") 71(defvoo nnrss-status-string "")
72 72
73(defconst nnrss-version "nnrss 1.0") 73(defconst nnrss-version "nnrss 1.0")
74(make-obsolete-variable 'nnrss-version 'emacs-version "29.1")
74 75
75(defvar nnrss-group-alist '() 76(defvar nnrss-group-alist '()
76 "List of RSS addresses.") 77 "List of RSS addresses.")
diff --git a/lisp/gnus/nnspool.el b/lisp/gnus/nnspool.el
index 39b89abb88a..e5eb4b81604 100644
--- a/lisp/gnus/nnspool.el
+++ b/lisp/gnus/nnspool.el
@@ -114,6 +114,7 @@ there.")
114 114
115(defconst nnspool-version "nnspool 2.0" 115(defconst nnspool-version "nnspool 2.0"
116 "Version numbers of this version of NNSPOOL.") 116 "Version numbers of this version of NNSPOOL.")
117(make-obsolete-variable 'nnspool-version 'emacs-version "29.1")
117 118
118(defvoo nnspool-current-directory nil 119(defvoo nnspool-current-directory nil
119 "Current news group directory.") 120 "Current news group directory.")
diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el
index 29570fa8c9f..6fa424a1555 100644
--- a/lisp/gnus/nntp.el
+++ b/lisp/gnus/nntp.el
@@ -259,6 +259,7 @@ update their active files often, this can help.")
259(defvoo nntp-connection-alist nil) 259(defvoo nntp-connection-alist nil)
260(defvoo nntp-status-string "") 260(defvoo nntp-status-string "")
261(defconst nntp-version "nntp 5.0") 261(defconst nntp-version "nntp 5.0")
262(make-obsolete-variable 'nntp-version 'emacs-version "29.1")
262(defvoo nntp-inhibit-erase nil) 263(defvoo nntp-inhibit-erase nil)
263(defvoo nntp-inhibit-output nil) 264(defvoo nntp-inhibit-output nil)
264 265
diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el
index ae4265de7fb..7b192aa1d2e 100644
--- a/lisp/gnus/nnvirtual.el
+++ b/lisp/gnus/nnvirtual.el
@@ -57,6 +57,7 @@ component group will show up when you enter the virtual group.")
57 57
58 58
59(defconst nnvirtual-version "nnvirtual 1.1") 59(defconst nnvirtual-version "nnvirtual 1.1")
60(make-obsolete-variable 'nnvirtual-version 'emacs-version "29.1")
60 61
61(defvoo nnvirtual-current-group nil) 62(defvoo nnvirtual-current-group nil)
62 63
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index 59a509b2215..74e18285e64 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -1005,9 +1005,9 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
1005 (help-fns--analyze-function function)) 1005 (help-fns--analyze-function function))
1006 (file-name (find-lisp-object-file-name 1006 (file-name (find-lisp-object-file-name
1007 function (if aliased 'defun def))) 1007 function (if aliased 'defun def)))
1008 (beg (if (and (or (byte-code-function-p def) 1008 (beg (if (and (or (functionp def)
1009 (keymapp def) 1009 (keymapp def)
1010 (memq (car-safe def) '(macro lambda closure))) 1010 (eq (car-safe def) 'macro))
1011 (stringp file-name) 1011 (stringp file-name)
1012 (help-fns--autoloaded-p function)) 1012 (help-fns--autoloaded-p function))
1013 (concat 1013 (concat
@@ -1040,7 +1040,7 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
1040 (t "Lisp function")))) 1040 (t "Lisp function"))))
1041 ((or (eq (car-safe def) 'macro) 1041 ((or (eq (car-safe def) 'macro)
1042 ;; For advised macros, def is a lambda 1042 ;; For advised macros, def is a lambda
1043 ;; expression or a byte-code-function-p, so we 1043 ;; expression or a compiled-function-p, so we
1044 ;; need to check macros before functions. 1044 ;; need to check macros before functions.
1045 (macrop function)) 1045 (macrop function))
1046 (concat beg "Lisp macro")) 1046 (concat beg "Lisp macro"))
@@ -1534,8 +1534,8 @@ This cancels value editing without updating the value."
1534 (when safe-var 1534 (when safe-var
1535 (princ " This variable is safe as a file local variable ") 1535 (princ " This variable is safe as a file local variable ")
1536 (princ "if its value\n satisfies the predicate ") 1536 (princ "if its value\n satisfies the predicate ")
1537 (princ (if (byte-code-function-p safe-var) 1537 (princ (if (compiled-function-p safe-var)
1538 "which is a byte-compiled expression.\n" 1538 "which is a compiled expression.\n"
1539 (format-message "`%s'.\n" safe-var)))))) 1539 (format-message "`%s'.\n" safe-var))))))
1540 1540
1541(add-hook 'help-fns-describe-variable-functions #'help-fns--var-risky) 1541(add-hook 'help-fns-describe-variable-functions #'help-fns--var-risky)
diff --git a/lisp/htmlfontify.el b/lisp/htmlfontify.el
index dbcc152c15d..bf7446f151a 100644
--- a/lisp/htmlfontify.el
+++ b/lisp/htmlfontify.el
@@ -81,11 +81,9 @@
81(eval-when-compile (require 'cl-lib)) 81(eval-when-compile (require 'cl-lib))
82(require 'cus-edit) 82(require 'cus-edit)
83 83
84(defconst htmlfontify-version 0.21)
85
86(defconst hfy-meta-tags 84(defconst hfy-meta-tags
87 (format "<meta name=\"generator\" content=\"emacs %s; htmlfontify %0.2f\" />" 85 (format "<meta name=\"generator\" content=\"emacs %s; htmlfontify\" />"
88 emacs-version htmlfontify-version) 86 emacs-version)
89 "The generator meta tag for this version of htmlfontify.") 87 "The generator meta tag for this version of htmlfontify.")
90 88
91(defconst htmlfontify-manual "Htmlfontify Manual" 89(defconst htmlfontify-manual "Htmlfontify Manual"
@@ -2392,13 +2390,14 @@ You may also want to set `hfy-page-header' and `hfy-page-footer'."
2392 (let ((file (hfy-initfile))) 2390 (let ((file (hfy-initfile)))
2393 (load file 'NOERROR nil nil) )) 2391 (load file 'NOERROR nil nil) ))
2394 2392
2395;; Obsolete.
2396
2397(defun hfy-interq (set-a set-b) 2393(defun hfy-interq (set-a set-b)
2398 "Return the intersection (using `eq') of two lists SET-A and SET-B." 2394 "Return the intersection (using `eq') of two lists SET-A and SET-B."
2399 (declare (obsolete seq-intersection "28.1")) 2395 (declare (obsolete seq-intersection "28.1"))
2400 (nreverse (seq-intersection set-a set-b #'eq))) 2396 (nreverse (seq-intersection set-a set-b #'eq)))
2401 2397
2398(defconst htmlfontify-version 0.21)
2399(make-obsolete-variable 'htmlfontify-version 'emacs-version "29.1")
2400
2402(define-obsolete-function-alias 'hfy-prop-invisible-p #'invisible-p "29.1") 2401(define-obsolete-function-alias 'hfy-prop-invisible-p #'invisible-p "29.1")
2403 2402
2404(provide 'htmlfontify) 2403(provide 'htmlfontify)
diff --git a/lisp/international/characters.el b/lisp/international/characters.el
index ca28222c815..d6e83c81e74 100644
--- a/lisp/international/characters.el
+++ b/lisp/international/characters.el
@@ -1525,6 +1525,17 @@ Setup `char-width-table' appropriate for non-CJK language environment."
1525 (aset char-acronym-table (+ #xE0021 i) (format " %c TAG" (+ 33 i)))) 1525 (aset char-acronym-table (+ #xE0021 i) (format " %c TAG" (+ 33 i))))
1526(aset char-acronym-table #xE007F "->|TAG") ; CANCEL TAG 1526(aset char-acronym-table #xE007F "->|TAG") ; CANCEL TAG
1527 1527
1528(dotimes (i 256)
1529 (let* ((vs-number (1+ i))
1530 (codepoint (if (< i 16)
1531 (+ #xfe00 i)
1532 (+ #xe0100 i -16)))
1533 (delimiter (cond ((<= vs-number 9) "0")
1534 ((<= vs-number 99) "")
1535 (t " "))))
1536 (aset char-acronym-table codepoint
1537 (format "VS%s%s" delimiter vs-number))))
1538
1528;; We can't use the \N{name} things here, because this file is used 1539;; We can't use the \N{name} things here, because this file is used
1529;; too early in the build process. 1540;; too early in the build process.
1530(defvar bidi-control-characters 1541(defvar bidi-control-characters
@@ -1574,7 +1585,9 @@ option `glyphless-char-display'."
1574 #x80 #x9F method)) 1585 #x80 #x9F method))
1575 ((eq target 'variation-selectors) 1586 ((eq target 'variation-selectors)
1576 (glyphless-set-char-table-range glyphless-char-display 1587 (glyphless-set-char-table-range glyphless-char-display
1577 #xFE00 #xFE0F method)) 1588 #xFE00 #xFE0F method)
1589 (glyphless-set-char-table-range glyphless-char-display
1590 #xE0100 #xE01EF method))
1578 ((or (eq target 'format-control) 1591 ((or (eq target 'format-control)
1579 (eq target 'bidi-control)) 1592 (eq target 'bidi-control))
1580 (when unicode-category-table 1593 (when unicode-category-table
@@ -1647,10 +1660,10 @@ GROUP must be one of these symbols:
1647 that are relevant for bidirectional formatting control, 1660 that are relevant for bidirectional formatting control,
1648 like U+2069 (PDI) and U+202B (RLE). 1661 like U+2069 (PDI) and U+202B (RLE).
1649 `variation-selectors': 1662 `variation-selectors':
1650 Characters in the range U+FE00..U+FE0F, used for 1663 Characters in the range U+FE00..U+FE0F and
1651 selecting alternate glyph presentations, such as 1664 U+E0100..U+E01EF, used for selecting alternate glyph
1652 Emoji vs Text presentation, of the preceding 1665 presentations, such as Emoji vs Text presentation, of
1653 character(s). 1666 the preceding character(s).
1654 `no-font': For GUI frames, characters for which no suitable 1667 `no-font': For GUI frames, characters for which no suitable
1655 font is found; for text-mode frames, characters 1668 font is found; for text-mode frames, characters
1656 that cannot be encoded by `terminal-coding-system'. 1669 that cannot be encoded by `terminal-coding-system'.
diff --git a/lisp/leim/quail/indian.el b/lisp/leim/quail/indian.el
index e652f108dde..431d8369c1e 100644
--- a/lisp/leim/quail/indian.el
+++ b/lisp/leim/quail/indian.el
@@ -702,7 +702,7 @@ is."
702;; Probhat Input Method 702;; Probhat Input Method
703(quail-define-package 703(quail-define-package
704 "bengali-probhat" "Bengali" "BngPB" t 704 "bengali-probhat" "Bengali" "BngPB" t
705 "Probhat keyboard for Bengali/Bangla" nil t nil nil nil nil nil nil nil nil t) 705 "Probhat keyboard for Bengali/Bangla" nil t nil t t nil nil nil nil nil t)
706 706
707(quail-define-rules 707(quail-define-rules
708 ("!" ?!) 708 ("!" ?!)
diff --git a/lisp/loadup.el b/lisp/loadup.el
index 8dad382ac0d..17e82cc0c49 100644
--- a/lisp/loadup.el
+++ b/lisp/loadup.el
@@ -154,8 +154,7 @@
154;; Load-time macro-expansion can only take effect after setting 154;; Load-time macro-expansion can only take effect after setting
155;; load-source-file-function because of where it is called in lread.c. 155;; load-source-file-function because of where it is called in lread.c.
156(load "emacs-lisp/macroexp") 156(load "emacs-lisp/macroexp")
157(if (or (byte-code-function-p (symbol-function 'macroexpand-all)) 157(if (compiled-function-p (symbol-function 'macroexpand-all))
158 (subr-native-elisp-p (symbol-function 'macroexpand-all)))
159 nil 158 nil
160 ;; Since loaddefs is not yet loaded, macroexp's uses of pcase will simply 159 ;; Since loaddefs is not yet loaded, macroexp's uses of pcase will simply
161 ;; fail until pcase is explicitly loaded. This also means that we have to 160 ;; fail until pcase is explicitly loaded. This also means that we have to
diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el
index 93af525e39d..a61620b2761 100644
--- a/lisp/mh-e/mh-e.el
+++ b/lisp/mh-e/mh-e.el
@@ -388,11 +388,11 @@ gnus-version)
388 (insert "MH-E " mh-version "\n\n") 388 (insert "MH-E " mh-version "\n\n")
389 ;; MH-E compilation details. 389 ;; MH-E compilation details.
390 (insert "MH-E compilation details:\n") 390 (insert "MH-E compilation details:\n")
391 (let* ((compiled-mhe (byte-code-function-p (symbol-function 'mh-version))) 391 (let* ((compiled-mhe (compiled-function-p (symbol-function 'mh-version)))
392 (gnus-compiled-version (if compiled-mhe 392 (gnus-compiled-version (if compiled-mhe
393 (mh-macro-expansion-time-gnus-version) 393 (mh-macro-expansion-time-gnus-version)
394 "N/A"))) 394 "N/A")))
395 (insert " Byte compiled:\t\t" (if compiled-mhe "yes" "no") "\n" 395 (insert " Compiled:\t\t" (if compiled-mhe "yes" "no") "\n"
396 " Gnus (compile-time):\t" gnus-compiled-version "\n" 396 " Gnus (compile-time):\t" gnus-compiled-version "\n"
397 " Gnus (run-time):\t" (mh-run-time-gnus-version) "\n\n")) 397 " Gnus (run-time):\t" (mh-run-time-gnus-version) "\n\n"))
398 ;; Emacs version. 398 ;; Emacs version.
diff --git a/lisp/net/newst-treeview.el b/lisp/net/newst-treeview.el
index 637f53e6550..e98767ae7c7 100644
--- a/lisp/net/newst-treeview.el
+++ b/lisp/net/newst-treeview.el
@@ -361,7 +361,8 @@ AGES is the list of ages that are to be shown."
361 (mapc (lambda (feed) 361 (mapc (lambda (feed)
362 (let ((feed-name-symbol (intern (car feed)))) 362 (let ((feed-name-symbol (intern (car feed))))
363 (mapc (lambda (item) 363 (mapc (lambda (item)
364 (when (memq (newsticker--age item) ages) 364 (when (or (memq 'all ages)
365 (memq (newsticker--age item) ages))
365 (newsticker--treeview-list-add-item 366 (newsticker--treeview-list-add-item
366 item feed-name-symbol t))) 367 item feed-name-symbol t)))
367 (newsticker--treeview-list-sort-items 368 (newsticker--treeview-list-sort-items
@@ -1218,11 +1219,11 @@ Note: does not update the layout."
1218 (newsticker--treeview-list-update t) 1219 (newsticker--treeview-list-update t)
1219 (newsticker--treeview-item-update) 1220 (newsticker--treeview-item-update)
1220 (newsticker--treeview-tree-update-tags) 1221 (newsticker--treeview-tree-update-tags)
1221 (cond (newsticker--treeview-current-feed 1222 (cond (newsticker--treeview-current-vfeed
1222 (newsticker--treeview-list-items newsticker--treeview-current-feed))
1223 (newsticker--treeview-current-vfeed
1224 (newsticker--treeview-list-items-with-age 1223 (newsticker--treeview-list-items-with-age
1225 (intern newsticker--treeview-current-vfeed)))) 1224 (intern newsticker--treeview-current-vfeed)))
1225 (newsticker--treeview-current-feed
1226 (newsticker--treeview-list-items newsticker--treeview-current-feed)))
1226 (newsticker--treeview-tree-update-highlight) 1227 (newsticker--treeview-tree-update-highlight)
1227 (newsticker--treeview-list-update-highlight) 1228 (newsticker--treeview-list-update-highlight)
1228 (let ((cur-feed (or newsticker--treeview-current-feed 1229 (let ((cur-feed (or newsticker--treeview-current-feed
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index d033667e87f..170583f608c 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -324,7 +324,7 @@ arguments to pass to the OPERATION."
324 (tramp-compat-file-name-concat localname ".")) 324 (tramp-compat-file-name-concat localname "."))
325 (tramp-shell-quote-argument 325 (tramp-shell-quote-argument
326 (tramp-compat-file-name-concat localname "..")))) 326 (tramp-compat-file-name-concat localname ".."))))
327 (replace-regexp-in-region 327 (tramp-compat-replace-regexp-in-region
328 (regexp-quote 328 (regexp-quote
329 (tramp-compat-file-name-unquote 329 (tramp-compat-file-name-unquote
330 (file-name-as-directory localname))) 330 (file-name-as-directory localname)))
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index fda1441615e..548999ca1d2 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -325,7 +325,7 @@ arguments to pass to the OPERATION."
325;; Starting with Emacs 29, `tramp-archive-file-name-handler' is 325;; Starting with Emacs 29, `tramp-archive-file-name-handler' is
326;; autoloaded. But it must still be in tramp-loaddefs.el for older 326;; autoloaded. But it must still be in tramp-loaddefs.el for older
327;; Emacsen. 327;; Emacsen.
328;;;###autoload(autoload 'tramp-archive-file-name-handler "tramp-archine") 328;;;###autoload(autoload 'tramp-archive-file-name-handler "tramp-archive")
329;;;###tramp-autoload 329;;;###tramp-autoload
330(defun tramp-archive-file-name-handler (operation &rest args) 330(defun tramp-archive-file-name-handler (operation &rest args)
331 "Invoke the file archive related OPERATION. 331 "Invoke the file archive related OPERATION.
diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el
index b83f9f0724e..203d3ede98f 100644
--- a/lisp/net/tramp-compat.el
+++ b/lisp/net/tramp-compat.el
@@ -330,6 +330,29 @@ CONDITION can also be a list of error conditions."
330 (autoload 'netrc-parse "netrc") 330 (autoload 'netrc-parse "netrc")
331 (netrc-parse file)))) 331 (netrc-parse file))))
332 332
333;; Function `replace-regexp-in-region' is new in Emacs 28.1.
334(defalias 'tramp-compat-replace-regexp-in-region
335 (if (fboundp 'replace-regexp-in-region)
336 #'replace-regexp-in-region
337 (lambda (regexp replacement &optional start end)
338 (if start
339 (when (< start (point-min))
340 (error "Start before start of buffer"))
341 (setq start (point)))
342 (if end
343 (when (> end (point-max))
344 (error "End after end of buffer"))
345 (setq end (point-max)))
346 (save-excursion
347 (let ((matches 0)
348 (case-fold-search nil))
349 (goto-char start)
350 (while (re-search-forward regexp end t)
351 (replace-match replacement t)
352 (setq matches (1+ matches)))
353 (and (not (zerop matches))
354 matches))))))
355
333(dolist (elt (all-completions "tramp-compat-" obarray 'functionp)) 356(dolist (elt (all-completions "tramp-compat-" obarray 'functionp))
334 (put (intern elt) 'tramp-suppress-trace t)) 357 (put (intern elt) 'tramp-suppress-trace t))
335 358
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index 7f385292626..27b359d439b 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -426,7 +426,7 @@ Otherwise, return NAME."
426 (if (directory-name-p name) #'file-name-as-directory #'identity) 426 (if (directory-name-p name) #'file-name-as-directory #'identity)
427 (concat 427 (concat
428 dir 428 dir
429 (unless (string-equal localname "/") 429 (unless (string-match-p (rx (seq bos (opt "/") eos)) localname)
430 (with-tramp-file-property 430 (with-tramp-file-property
431 crypt-vec localname (concat (symbol-name op) "-file-name") 431 crypt-vec localname (concat (symbol-name op) "-file-name")
432 (unless (tramp-crypt-send-command 432 (unless (tramp-crypt-send-command
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 0b40ff867f2..ca5e959bea5 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -1055,9 +1055,10 @@ file names."
1055 ;; code in case of direct copy/move. Apply 1055 ;; code in case of direct copy/move. Apply
1056 ;; sanity checks. 1056 ;; sanity checks.
1057 (or (not equal-remote) 1057 (or (not equal-remote)
1058 (tramp-gvfs-info newname) 1058 (and
1059 (eq op 'copy) 1059 (tramp-gvfs-info newname)
1060 (not (tramp-gvfs-info filename)))) 1060 (or (eq op 'copy)
1061 (not (tramp-gvfs-info filename))))))
1061 1062
1062 (if (or (not equal-remote) 1063 (if (or (not equal-remote)
1063 (and equal-remote 1064 (and equal-remote
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index a2b675cf885..f2e3c48235a 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -4205,14 +4205,17 @@ file exists and nonzero exit status otherwise."
4205 ;; by some sh implementations (eg, bash when called as sh) on 4205 ;; by some sh implementations (eg, bash when called as sh) on
4206 ;; startup; this way, we avoid the startup file clobbering $PS1. 4206 ;; startup; this way, we avoid the startup file clobbering $PS1.
4207 ;; $PROMPT_COMMAND is another way to set the prompt in /bin/bash, 4207 ;; $PROMPT_COMMAND is another way to set the prompt in /bin/bash,
4208 ;; it must be discarded as well. $HISTFILE is set according to 4208 ;; it must be discarded as well. Some ssh daemons (for example,
4209 ;; `tramp-histfile-override'. $TERM and $INSIDE_EMACS set here to 4209 ;; on Android devices) do not acknowledge the $PS1 setting in
4210 ;; ensure they have the correct values when the shell starts, not 4210 ;; that call, so we make a further sanity check. (Bug#57044)
4211 ;; just processes run within the shell. (Which processes include 4211 ;; $HISTFILE is set according to `tramp-histfile-override'. $TERM
4212 ;; our initial probes to ensure the remote shell is usable.) 4212 ;; and $INSIDE_EMACS set here to ensure they have the correct
4213 ;; For the time being, we assume that all shells interpret -i as 4213 ;; values when the shell starts, not just processes run within the
4214 ;; interactive shell. Must be the last argument, because (for 4214 ;; shell. (Which processes include our initial probes to ensure
4215 ;; example) bash expects long options first. 4215 ;; the remote shell is usable.) For the time being, we assume
4216 ;; that all shells interpret -i as interactive shell. Must be the
4217 ;; last argument, because (for example) bash expects long options
4218 ;; first.
4216 (tramp-send-command 4219 (tramp-send-command
4217 vec (format 4220 vec (format
4218 (concat 4221 (concat
@@ -4228,7 +4231,21 @@ file exists and nonzero exit status otherwise."
4228 "")) 4231 ""))
4229 (tramp-shell-quote-argument tramp-end-of-output) 4232 (tramp-shell-quote-argument tramp-end-of-output)
4230 shell (or (tramp-get-sh-extra-args shell) "")) 4233 shell (or (tramp-get-sh-extra-args shell) ""))
4231 t) 4234 t t)
4235
4236 ;; Sanity check.
4237 (tramp-barf-if-no-shell-prompt
4238 (tramp-get-connection-process vec) 10
4239 "Couldn't find remote shell prompt for %s" shell)
4240 (unless
4241 (tramp-check-for-regexp
4242 (tramp-get-connection-process vec) (regexp-quote tramp-end-of-output))
4243 (tramp-message vec 5 "Setting shell prompt")
4244 (tramp-send-command
4245 vec (format "PS1=%s PS2='' PS3='' PROMPT_COMMAND=''"
4246 (tramp-shell-quote-argument tramp-end-of-output))
4247 t))
4248
4232 ;; Check proper HISTFILE setting. We give up when not working. 4249 ;; Check proper HISTFILE setting. We give up when not working.
4233 (when (and (stringp tramp-histfile-override) 4250 (when (and (stringp tramp-histfile-override)
4234 (file-name-directory tramp-histfile-override)) 4251 (file-name-directory tramp-histfile-override))
@@ -5524,10 +5541,14 @@ Nonexistent directories are removed from spec."
5524 ;; "--color=never" argument (for example on FreeBSD). 5541 ;; "--color=never" argument (for example on FreeBSD).
5525 (when (tramp-send-command-and-check 5542 (when (tramp-send-command-and-check
5526 vec (format "%s -lnd /" result)) 5543 vec (format "%s -lnd /" result))
5527 (when (tramp-send-command-and-check 5544 (when (and (tramp-send-command-and-check
5528 vec (format 5545 vec (format
5529 "%s --color=never -al %s" 5546 "%s --color=never -al %s"
5530 result (tramp-get-remote-null-device vec))) 5547 result (tramp-get-remote-null-device vec)))
5548 (not (string-match-p
5549 (regexp-quote "\e")
5550 (tramp-get-buffer-string
5551 (tramp-get-buffer vec)))))
5531 (setq result (concat result " --color=never"))) 5552 (setq result (concat result " --color=never")))
5532 (throw 'ls-found result)) 5553 (throw 'ls-found result))
5533 (setq dl (cdr dl)))))) 5554 (setq dl (cdr dl))))))
diff --git a/lisp/org/org.el b/lisp/org/org.el
index 68f522b060a..df708a2159d 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -3807,10 +3807,6 @@ This is needed for font-lock setup.")
3807(declare-function dired-get-filename 3807(declare-function dired-get-filename
3808 "dired" 3808 "dired"
3809 (&optional localp no-error-if-not-filep)) 3809 (&optional localp no-error-if-not-filep))
3810(declare-function iswitchb-read-buffer
3811 "iswitchb"
3812 (prompt &optional
3813 default require-match _predicate start matches-set))
3814(declare-function org-agenda-change-all-lines 3810(declare-function org-agenda-change-all-lines
3815 "org-agenda" 3811 "org-agenda"
3816 (newhead hdmarker &optional fixface just-this)) 3812 (newhead hdmarker &optional fixface just-this))
@@ -3844,7 +3840,6 @@ This is needed for font-lock setup.")
3844(defvar calc-embedded-open-formula) 3840(defvar calc-embedded-open-formula)
3845(defvar calc-embedded-open-mode) 3841(defvar calc-embedded-open-mode)
3846(defvar font-lock-unfontify-region-function) 3842(defvar font-lock-unfontify-region-function)
3847(defvar iswitchb-temp-buflist)
3848(defvar org-agenda-tags-todo-honor-ignore-options) 3843(defvar org-agenda-tags-todo-honor-ignore-options)
3849(defvar remember-data-file) 3844(defvar remember-data-file)
3850(defvar texmathp-why) 3845(defvar texmathp-why)
diff --git a/lisp/outline.el b/lisp/outline.el
index 35524a79a90..3250b62f1e7 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -281,7 +281,7 @@ This option is only in effect when `outline-minor-mode-cycle' is non-nil."
281 [outline-1 outline-2 outline-3 outline-4 281 [outline-1 outline-2 outline-3 outline-4
282 outline-5 outline-6 outline-7 outline-8]) 282 outline-5 outline-6 outline-7 outline-8])
283 283
284(defcustom outline-minor-mode-use-buttons '(derived-mode . special-mode) 284(defcustom outline-minor-mode-use-buttons '(derived-mode . help-mode)
285 "Whether to display clickable buttons on the headings. 285 "Whether to display clickable buttons on the headings.
286The value should be a `buffer-match-p' condition. 286The value should be a `buffer-match-p' condition.
287 287
@@ -294,16 +294,16 @@ buffers (yet) -- that will be amended in a future version."
294 :version "29.1") 294 :version "29.1")
295 295
296(define-icon outline-open button 296(define-icon outline-open button
297 '((emoji "▶️") 297 '((emoji "🔽")
298 (symbol " ") 298 (symbol " ")
299 (text " open ")) 299 (text " open "))
300 "Icon used for buttons for opening a section in outline buffers." 300 "Icon used for buttons for opening a section in outline buffers."
301 :version "29.1" 301 :version "29.1"
302 :help-echo "Open this section") 302 :help-echo "Open this section")
303 303
304(define-icon outline-close button 304(define-icon outline-close button
305 '((emoji "🔽") 305 '((emoji "▶️")
306 (symbol " ") 306 (symbol " ")
307 (text " close ")) 307 (text " close "))
308 "Icon used for buttons for closing a section in outline buffers." 308 "Icon used for buttons for closing a section in outline buffers."
309 :version "29.1" 309 :version "29.1"
diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el
index 8fe72ddf593..fb944f4d76a 100644
--- a/lisp/play/5x5.el
+++ b/lisp/play/5x5.el
@@ -82,13 +82,6 @@
82 82
83;; Non-customize variables. 83;; Non-customize variables.
84 84
85(defmacro 5x5-defvar-local (var value doc)
86 "Define VAR to VALUE with documentation DOC and make it buffer local."
87 (declare (obsolete defvar-local "28.1"))
88 `(progn
89 (defvar ,var ,value ,doc)
90 (make-variable-buffer-local (quote ,var))))
91
92(defvar-local 5x5-grid nil 85(defvar-local 5x5-grid nil
93 "5x5 grid contents.") 86 "5x5 grid contents.")
94 87
@@ -930,14 +923,15 @@ lest."
930 923
931;; Support functions 924;; Support functions
932 925
933(define-obsolete-function-alias '5x5-xor 'xor "27.1")
934
935(defun 5x5-y-or-n-p (prompt) 926(defun 5x5-y-or-n-p (prompt)
936 "5x5 wrapper for `y-or-n-p' which respects the `5x5-hassle-me' setting." 927 "5x5 wrapper for `y-or-n-p' which respects the `5x5-hassle-me' setting."
937 (if 5x5-hassle-me 928 (if 5x5-hassle-me
938 (y-or-n-p prompt) 929 (y-or-n-p prompt)
939 t)) 930 t))
940 931
932(define-obsolete-function-alias '5x5-xor #'xor "27.1")
933(define-obsolete-function-alias '5x5-defvar-local #'defvar-local "28.1")
934
941(provide '5x5) 935(provide '5x5)
942 936
943;;; 5x5.el ends here 937;;; 5x5.el ends here
diff --git a/lisp/printing.el b/lisp/printing.el
index 83c9ffc9cbd..534b45c772b 100644
--- a/lisp/printing.el
+++ b/lisp/printing.el
@@ -4,16 +4,9 @@
4 4
5;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com> 5;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
6;; Keywords: wp, print, PostScript 6;; Keywords: wp, print, PostScript
7;; Version: 6.9.3 7;; Old-Version: 6.9.3
8;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre 8;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
9 9
10(defconst pr-version "6.9.3"
11 "printing.el, v 6.9.3 <2007/12/09 vinicius>
12
13Please send all bug fixes and enhancements to
14 bug-gnu-emacs@gnu.org and Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
15")
16
17;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
18 11
19;; GNU Emacs is free software: you can redistribute it and/or modify 12;; GNU Emacs is free software: you can redistribute it and/or modify
@@ -63,10 +56,6 @@ Please send all bug fixes and enhancements to
63;; spool and to despool PostScript buffer. So, `printing' provides an 56;; spool and to despool PostScript buffer. So, `printing' provides an
64;; interface to ps-print package and it also provides some extra stuff. 57;; interface to ps-print package and it also provides some extra stuff.
65;; 58;;
66;; To download the latest ps-print package see
67;; `https://www.emacswiki.org/cgi-bin/wiki/PsPrintPackage'.
68;; Please, see README file for ps-print installation instructions.
69;;
70;; `printing' was inspired by: 59;; `printing' was inspired by:
71;; 60;;
72;; print-nt.el Frederic Corne <frederic.corne@erli.fr> 61;; print-nt.el Frederic Corne <frederic.corne@erli.fr>
@@ -942,11 +931,6 @@ Please send all bug fixes and enhancements to
942;; 931;;
943;; Below are some URL where you can find good utilities. 932;; Below are some URL where you can find good utilities.
944;; 933;;
945;; * For `printing' package:
946;;
947;; printing `https://www.emacswiki.org/cgi-bin/emacs/download/printing.el'
948;; ps-print `https://www.emacswiki.org/cgi-bin/wiki/PsPrintPackage'
949;;
950;; * For GNU or Unix system: 934;; * For GNU or Unix system:
951;; 935;;
952;; gs, gv `https://www.gnu.org/software/ghostscript/ghostscript.html' 936;; gs, gv `https://www.gnu.org/software/ghostscript/ghostscript.html'
@@ -1015,10 +999,6 @@ Please send all bug fixes and enhancements to
1015(require 'lpr) 999(require 'lpr)
1016(require 'ps-print) 1000(require 'ps-print)
1017 1001
1018(and (string< ps-print-version "6.6.4")
1019 (error "`printing' requires `ps-print' package version 6.6.4 or later"))
1020
1021
1022(defconst pr-cygwin-system 1002(defconst pr-cygwin-system
1023 (and lpr-windows-system (getenv "OSTYPE") 1003 (and lpr-windows-system (getenv "OSTYPE")
1024 (string-match "cygwin" (getenv "OSTYPE")))) 1004 (string-match "cygwin" (getenv "OSTYPE"))))
@@ -3007,9 +2987,7 @@ Calls `pr-update-menus' to adjust menus."
3007 2987
3008 2988
3009(defconst pr-help-message 2989(defconst pr-help-message
3010 (concat "printing.el version " pr-version 2990 "\
3011 " ps-print.el version " ps-print-version
3012 "\n\n
3013Menu Layout 2991Menu Layout
3014----------- 2992-----------
3015 2993
@@ -3215,14 +3193,12 @@ VI. Customization:
3215 23. Show current settings for `printing', `ps-print' or `lpr'. 3193 23. Show current settings for `printing', `ps-print' or `lpr'.
3216 3194
3217 24. Quick help for printing menu layout. 3195 24. Quick help for printing menu layout.
3218") 3196"
3219 "Printing help message.") 3197 "Printing help message.")
3220 3198
3221 3199
3222(defconst pr-interface-help-message 3200(defconst pr-interface-help-message
3223 (concat "printing.el version " pr-version 3201 "\
3224 " ps-print.el version " ps-print-version
3225 "\n\n
3226The printing interface buffer has the same functionality as the printing menu. 3202The printing interface buffer has the same functionality as the printing menu.
3227The major difference is that the states (like sending PostScript generated to a 3203The major difference is that the states (like sending PostScript generated to a
3228file, n-up printing, etc.) are set and saved between printing buffer 3204file, n-up printing, etc.) are set and saved between printing buffer
@@ -3449,7 +3425,7 @@ The printing interface buffer has the following sections:
3449 3425
3450 Quick help for printing interface buffer and printing menu layout. You can 3426 Quick help for printing interface buffer and printing menu layout. You can
3451 also quit the printing interface buffer or kill all printing help buffer. 3427 also quit the printing interface buffer or kill all printing help buffer.
3452") 3428"
3453 "Printing buffer interface help message.") 3429 "Printing buffer interface help message.")
3454 3430
3455 3431
@@ -4402,7 +4378,6 @@ Or choose the menu option Printing/Show Settings/printing."
4402 (mapconcat 4378 (mapconcat
4403 #'ps-print-quote 4379 #'ps-print-quote
4404 (list 4380 (list
4405 (concat "\n;;; printing.el version " pr-version "\n")
4406 ";; internal vars" 4381 ";; internal vars"
4407 (ps-comment-string "emacs-version " emacs-version) 4382 (ps-comment-string "emacs-version " emacs-version)
4408 (ps-comment-string "pr-txt-command " pr-txt-command) 4383 (ps-comment-string "pr-txt-command " pr-txt-command)
@@ -5597,9 +5572,6 @@ COMMAND.exe, COMMAND.bat and COMMAND.com in this order."
5597 (switch-to-buffer (get-buffer-create pr-buffer-name)) 5572 (switch-to-buffer (get-buffer-create pr-buffer-name))
5598 5573
5599 ;; header 5574 ;; header
5600 (let ((versions (concat "printing v" pr-version
5601 " ps-print v" ps-print-version)))
5602 (widget-insert (make-string (- 79 (length versions)) ?\ ) versions))
5603 (pr-insert-italic "\nCurrent Directory : " 1) 5575 (pr-insert-italic "\nCurrent Directory : " 1)
5604 (pr-insert-italic default-directory) 5576 (pr-insert-italic default-directory)
5605 5577
@@ -6213,6 +6185,12 @@ COMMAND.exe, COMMAND.bat and COMMAND.com in this order."
6213 6185
6214;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6186;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6215 6187
6188(defconst pr-version "6.9.3"
6189 "printing.el, v 6.9.3 <2007/12/09 vinicius>
6190
6191Please send all bug fixes and enhancements to
6192 bug-gnu-emacs@gnu.org and Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>")
6193(make-obsolete-variable 'pr-version 'emacs-version "29.1")
6216 6194
6217(provide 'printing) 6195(provide 'printing)
6218 6196
diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el
index e19726a7eab..6e42da2d54f 100644
--- a/lisp/progmodes/ebnf2ps.el
+++ b/lisp/progmodes/ebnf2ps.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com> 5;; Author: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
6;; Keywords: wp, ebnf, PostScript 6;; Keywords: wp, ebnf, PostScript
7;; Version: 4.4 7;; Old-Version: 4.4
8;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre 8;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -22,16 +22,6 @@
22;; You should have received a copy of the GNU General Public License 22;; You should have received a copy of the GNU General Public License
23;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 23;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
24 24
25(defconst ebnf-version "4.4"
26 "ebnf2ps.el, v 4.4 <2007/02/12 vinicius>
27
28Vinicius's last change version. When reporting bugs, please also
29report the version of Emacs, if any, that ebnf2ps was running with.
30
31Please send all bug fixes and enhancements to
32 Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>.")
33
34
35;;; Commentary: 25;;; Commentary:
36 26
37;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 27;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -45,20 +35,12 @@ Please send all bug fixes and enhancements to
45;; 35;;
46;; (require 'ebnf2ps) 36;; (require 'ebnf2ps)
47;; 37;;
48;; ebnf2ps uses ps-print package (version 5.2.3 or later), so see ps-print to 38;; ebnf2ps uses ps-print package (bundled with Emacs), so see ps-print to
49;; know how to set options like landscape printing, page headings, margins, 39;; know how to set options like landscape printing, page headings, margins,
50;; etc. 40;; etc.
51;; 41;;
52;; NOTE: ps-print zebra stripes and line number options doesn't have effect on 42;; NOTE: ps-print zebra stripes and line number options don't have an
53;; ebnf2ps, they behave as it's turned off. 43;; effect on ebnf2ps, they behave as if it's turned off.
54;;
55;; For good performance, be sure to byte-compile ebnf2ps.el, e.g.
56;;
57;; M-x byte-compile-file <give the path to ebnf2ps.el when prompted>
58;;
59;; This will generate ebnf2ps.elc, which will be loaded instead of ebnf2ps.el.
60;;
61;; ebnf2ps was tested with GNU Emacs 20.4.1.
62;; 44;;
63;; 45;;
64;; Using ebnf2ps 46;; Using ebnf2ps
@@ -1154,9 +1136,6 @@ Please send all bug fixes and enhancements to
1154(require 'ps-print) 1136(require 'ps-print)
1155(eval-when-compile (require 'cl-lib)) 1137(eval-when-compile (require 'cl-lib))
1156 1138
1157(and (string< ps-print-version "5.2.3")
1158 (error "`ebnf2ps' requires `ps-print' package version 5.2.3 or later"))
1159
1160 1139
1161;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1162;; User Variables: 1141;; User Variables:
@@ -2455,8 +2434,6 @@ See also `ebnf-syntax-buffer'."
2455 "Return the current ebnf2ps setup." 2434 "Return the current ebnf2ps setup."
2456 (format 2435 (format
2457 " 2436 "
2458;;; ebnf2ps.el version %s
2459
2460;;; Emacs version %S 2437;;; Emacs version %S
2461 2438
2462\(setq ebnf-special-show-delimiter %S 2439\(setq ebnf-special-show-delimiter %S
@@ -2525,7 +2502,6 @@ See also `ebnf-syntax-buffer'."
2525 2502
2526;;; ebnf2ps.el - end of settings 2503;;; ebnf2ps.el - end of settings
2527" 2504"
2528 ebnf-version
2529 emacs-version 2505 emacs-version
2530 ebnf-special-show-delimiter 2506 ebnf-special-show-delimiter
2531 (ps-print-quote ebnf-special-font) 2507 (ps-print-quote ebnf-special-font)
@@ -2958,7 +2934,7 @@ See section \"Actions in Comments\" in ebnf2ps documentation.")
2958 2934
2959 2935
2960(defvar ebnf-eps-file-alist nil 2936(defvar ebnf-eps-file-alist nil
2961"Alist associating file name with EPS header and footer. 2937 "Alist associating file name with EPS header and footer.
2962 2938
2963Each element has the following form: 2939Each element has the following form:
2964 2940
@@ -5242,11 +5218,7 @@ killed after process termination."
5242 (not (search-forward "& ebnf2ps v" 5218 (not (search-forward "& ebnf2ps v"
5243 (line-end-position) 5219 (line-end-position)
5244 t)) 5220 t))
5245 (progn 5221 (progn
5246 ;; adjust creator comment
5247 (end-of-line)
5248 ;; (backward-char)
5249 (insert " & ebnf2ps v" ebnf-version)
5250 ;; insert ebnf settings & engine 5222 ;; insert ebnf settings & engine
5251 (goto-char (point-max)) 5223 (goto-char (point-max))
5252 (search-backward "\n%%EndProlog\n") 5224 (search-backward "\n%%EndProlog\n")
@@ -5272,7 +5244,7 @@ killed after process termination."
5272 (format "%d %d" (1+ ebnf-eps-upper-x) (1+ ebnf-eps-upper-y)) 5244 (format "%d %d" (1+ ebnf-eps-upper-x) (1+ ebnf-eps-upper-y))
5273 "\n%%Title: " filename 5245 "\n%%Title: " filename
5274 "\n%%CreationDate: " (format-time-string "%T %b %d %Y") 5246 "\n%%CreationDate: " (format-time-string "%T %b %d %Y")
5275 "\n%%Creator: " (user-full-name) " (using ebnf2ps v" ebnf-version ")" 5247 "\n%%Creator: " (user-full-name) " (using GNU Emacs " emacs-version ")"
5276 "\n%%DocumentNeededResources: font " 5248 "\n%%DocumentNeededResources: font "
5277 (or ebnf-fonts-required 5249 (or ebnf-fonts-required
5278 (setq ebnf-fonts-required 5250 (setq ebnf-fonts-required
@@ -6350,6 +6322,15 @@ killed after process termination."
6350 6322
6351;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 6323;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
6352 6324
6325(defconst ebnf-version "4.4"
6326 "ebnf2ps.el, v 4.4 <2007/02/12 vinicius>
6327
6328Vinicius's last change version. When reporting bugs, please also
6329report the version of Emacs, if any, that ebnf2ps was running with.
6330
6331Please send all bug fixes and enhancements to
6332 bug-gnu-emacs@gnu.org and Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>.")
6333(make-obsolete-variable 'ebnf-version 'emacs-version "29.1")
6353 6334
6354(provide 'ebnf2ps) 6335(provide 'ebnf2ps)
6355 6336
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el
index dcd74f0369c..443281c4f07 100644
--- a/lisp/progmodes/f90.el
+++ b/lisp/progmodes/f90.el
@@ -116,12 +116,11 @@
116;; non-nil, the line numbers are never touched. 116;; non-nil, the line numbers are never touched.
117;; 2) Multi-; statements like "do i=1,20 ; j=j+i ; end do" are not handled 117;; 2) Multi-; statements like "do i=1,20 ; j=j+i ; end do" are not handled
118;; correctly, but I imagine them to be rare. 118;; correctly, but I imagine them to be rare.
119;; 3) Regexps for hilit19 are no longer supported. 119;; 3) For FIXED FORMAT code, use fortran mode.
120;; 4) For FIXED FORMAT code, use fortran mode. 120;; 4) Preprocessor directives, i.e., lines starting with # are left-justified
121;; 5) Preprocessor directives, i.e., lines starting with # are left-justified
122;; and are untouched by all case-changing commands. There is, at present, no 121;; and are untouched by all case-changing commands. There is, at present, no
123;; mechanism for treating multi-line directives (continued by \ ). 122;; mechanism for treating multi-line directives (continued by \ ).
124;; 6) f77 do-loops do 10 i=.. ; ; 10 continue are not correctly indented. 123;; 5) f77 do-loops do 10 i=.. ; ; 10 continue are not correctly indented.
125;; You are urged to use f90-do loops (with labels if you wish). 124;; You are urged to use f90-do loops (with labels if you wish).
126 125
127;; List of user commands 126;; List of user commands
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 9c2c6405253..c256198b3c1 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -92,6 +92,7 @@
92(require 'cl-seq) 92(require 'cl-seq)
93(require 'bindat) 93(require 'bindat)
94(eval-when-compile (require 'pcase)) 94(eval-when-compile (require 'pcase))
95(require 'subr-x) ; `string-pad'
95 96
96(declare-function speedbar-change-initial-expansion-list 97(declare-function speedbar-change-initial-expansion-list
97 "speedbar" (new-default)) 98 "speedbar" (new-default))
@@ -2511,9 +2512,8 @@ means to decode using the coding-system set for the GDB process."
2511 ;; Record transactions if logging is enabled. 2512 ;; Record transactions if logging is enabled.
2512 (when gdb-enable-debug 2513 (when gdb-enable-debug
2513 (push (cons 'recv string) gdb-debug-log) 2514 (push (cons 'recv string) gdb-debug-log)
2514 (if (and gdb-debug-log-max 2515 (when gdb-debug-log-max
2515 (> (length gdb-debug-log) gdb-debug-log-max)) 2516 (setq gdb-debug-log (ntake gdb-debug-log-max gdb-debug-log))))
2516 (setcdr (nthcdr (1- gdb-debug-log-max) gdb-debug-log) nil)))
2517 2517
2518 ;; Recall the left over gud-marker-acc from last time. 2518 ;; Recall the left over gud-marker-acc from last time.
2519 (setq gud-marker-acc (concat gud-marker-acc string)) 2519 (setq gud-marker-acc (concat gud-marker-acc string))
@@ -2943,7 +2943,8 @@ Return position where LINE begins."
2943 start-posn))) 2943 start-posn)))
2944 2944
2945(defun gdb-pad-string (string padding) 2945(defun gdb-pad-string (string padding)
2946 (format (concat "%" (number-to-string padding) "s") string)) 2946 (declare (obsolete string-pad "29.1"))
2947 (string-pad string padding nil t))
2947 2948
2948;; gdb-table struct is a way to programmatically construct simple 2949;; gdb-table struct is a way to programmatically construct simple
2949;; tables. It help to reliably align columns of data in GDB buffers 2950;; tables. It help to reliably align columns of data in GDB buffers
@@ -2985,13 +2986,13 @@ calling `gdb-table-string'."
2985 "Return TABLE as a string with columns separated with SEP." 2986 "Return TABLE as a string with columns separated with SEP."
2986 (let ((column-sizes (gdb-table-column-sizes table))) 2987 (let ((column-sizes (gdb-table-column-sizes table)))
2987 (mapconcat 2988 (mapconcat
2988 'identity 2989 #'identity
2989 (cl-mapcar 2990 (cl-mapcar
2990 (lambda (row properties) 2991 (lambda (row properties)
2991 (apply 'propertize 2992 (apply #'propertize
2992 (mapconcat 'identity 2993 (mapconcat #'identity
2993 (cl-mapcar (lambda (s x) (gdb-pad-string s x)) 2994 (cl-mapcar (lambda (s x) (string-pad s x nil t))
2994 row column-sizes) 2995 row column-sizes)
2995 sep) 2996 sep)
2996 properties)) 2997 properties))
2997 (gdb-table-rows table) 2998 (gdb-table-rows table)
@@ -3688,10 +3689,11 @@ in `gdb-memory-format'."
3688 (dolist (row memory) 3689 (dolist (row memory)
3689 (insert (concat (gdb-mi--field row 'addr) ":")) 3690 (insert (concat (gdb-mi--field row 'addr) ":"))
3690 (dolist (column (gdb-mi--field row 'data)) 3691 (dolist (column (gdb-mi--field row 'data))
3691 (insert (gdb-pad-string column 3692 (insert (string-pad column
3692 (+ 2 (gdb-memory-column-width 3693 (+ 2 (gdb-memory-column-width
3693 gdb-memory-unit 3694 gdb-memory-unit
3694 gdb-memory-format))))) 3695 gdb-memory-format))
3696 nil t)))
3695 (newline))) 3697 (newline)))
3696 ;; Show last page instead of empty buffer when out of bounds 3698 ;; Show last page instead of empty buffer when out of bounds
3697 (when gdb-memory-last-address 3699 (when gdb-memory-last-address
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index be43effed7d..ccc57205757 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -1577,16 +1577,17 @@ into one that invokes an Emacs-enabled debugging session.
1577 (seen-e nil) 1577 (seen-e nil)
1578 (shift (lambda () (push (pop args) new-args)))) 1578 (shift (lambda () (push (pop args) new-args))))
1579 1579
1580 ;; Pass all switches and -e scripts through. 1580 ;; Pass all switches and -E/-e scripts through.
1581 (while (and args 1581 (while (and args
1582 (string-match "^-" (car args)) 1582 (string-match "^-" (car args))
1583 (not (equal "-" (car args))) 1583 (not (equal "-" (car args)))
1584 (not (equal "--" (car args)))) 1584 (not (equal "--" (car args))))
1585 (when (equal "-e" (car args)) 1585 (when (or (equal "-E" (car args)) (equal "-e" (car args)))
1586 ;; -e goes with the next arg, so shift one extra. 1586 ;; -e goes with the next arg, so shift one extra.
1587 (or (funcall shift) 1587 (funcall shift)
1588 ;; -e as the last arg is an error in Perl. 1588 (or args
1589 (error "No code specified for -e")) 1589 ;; -E (or -e) as the last arg is an error in Perl.
1590 (error "No code specified for %s" (car new-args)))
1590 (setq seen-e t)) 1591 (setq seen-e t))
1591 (funcall shift)) 1592 (funcall shift))
1592 1593
@@ -1697,7 +1698,7 @@ The directory containing the perl program becomes the initial
1697working directory and source-file directory for your debugger." 1698working directory and source-file directory for your debugger."
1698 (interactive 1699 (interactive
1699 (list (gud-query-cmdline 'perldb 1700 (list (gud-query-cmdline 'perldb
1700 (concat (or (buffer-file-name) "-e 0") " ")))) 1701 (concat (or (buffer-file-name) "-E 0") " "))))
1701 1702
1702 (gud-common-init command-line 'gud-perldb-massage-args 1703 (gud-common-init command-line 'gud-perldb-massage-args
1703 'gud-perldb-marker-filter) 1704 'gud-perldb-marker-filter)
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index d2c24a75810..efad3b52aa9 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3490,9 +3490,10 @@ This function is intended for use in `after-change-functions'."
3490 3490
3491;;;###autoload 3491;;;###autoload
3492(define-derived-mode js-json-mode js-mode "JSON" 3492(define-derived-mode js-json-mode js-mode "JSON"
3493 ;; JSON files can be big. Speed up syntax-ppss. 3493 (setq-local js-enabled-frameworks nil)
3494 (setq-local syntax-propertize-function nil) 3494 ;; Speed up `syntax-ppss': JSON files can be big but can't hold
3495 (setq-local js-enabled-frameworks nil)) 3495 ;; regexp matchers nor #! thingies (and `js-enabled-frameworks' is nil).
3496 (setq-local syntax-propertize-function #'ignore))
3496 3497
3497;; Since we made JSX support available and automatically-enabled in 3498;; Since we made JSX support available and automatically-enabled in
3498;; the base `js-mode' (for ease of use), now `js-jsx-mode' simply 3499;; the base `js-mode' (for ease of use), now `js-jsx-mode' simply
diff --git a/lisp/progmodes/ps-mode.el b/lisp/progmodes/ps-mode.el
index 7c9aee2b2a8..89482d86ce2 100644
--- a/lisp/progmodes/ps-mode.el
+++ b/lisp/progmodes/ps-mode.el
@@ -34,7 +34,6 @@
34 34
35;;; Code: 35;;; Code:
36 36
37(defconst ps-mode-version "1.1i, 17 May 2008")
38(defconst ps-mode-maintainer-address 37(defconst ps-mode-maintainer-address
39 "Peter Kleiweg <p.c.j.kleiweg@rug.nl>, bug-gnu-emacs@gnu.org") 38 "Peter Kleiweg <p.c.j.kleiweg@rug.nl>, bug-gnu-emacs@gnu.org")
40 39
@@ -519,7 +518,7 @@ Typing \\<ps-run-mode-map>\\[ps-run-goto-error] when the cursor is at the number
519(defun ps-mode-show-version () 518(defun ps-mode-show-version ()
520 "Show current version of PostScript mode." 519 "Show current version of PostScript mode."
521 (interactive) 520 (interactive)
522 (message " *** PostScript Mode (ps-mode) Version %s *** " ps-mode-version)) 521 (message " *** PostScript Mode (ps-mode) in GNU Emacs %s *** " emacs-version))
523 522
524;; From reporter.el 523;; From reporter.el
525(defvar reporter-prompt-for-summary-p) 524(defvar reporter-prompt-for-summary-p)
@@ -534,7 +533,7 @@ Typing \\<ps-run-mode-map>\\[ps-run-goto-error] when the cursor is at the number
534 ps-run-font-lock-keywords-2))) 533 ps-run-font-lock-keywords-2)))
535 (reporter-submit-bug-report 534 (reporter-submit-bug-report
536 ps-mode-maintainer-address 535 ps-mode-maintainer-address
537 (format "ps-mode.el %s [%s]" ps-mode-version system-type) 536 (format "ps-mode.el %s [%s]" emacs-version system-type)
538 '(ps-mode-tab 537 '(ps-mode-tab
539 ps-mode-paper-size 538 ps-mode-paper-size
540 ps-mode-print-function 539 ps-mode-print-function
@@ -1094,6 +1093,9 @@ Use line numbers if `ps-run-error-line-numbers' is not nil."
1094;; 1093;;
1095(add-hook 'kill-emacs-hook #'ps-run-cleanup) 1094(add-hook 'kill-emacs-hook #'ps-run-cleanup)
1096 1095
1096(defconst ps-mode-version "1.1i, 17 May 2008")
1097(make-obsolete-variable 'ps-mode-version 'emacs-version "29.1")
1098
1097(provide 'ps-mode) 1099(provide 'ps-mode)
1098 1100
1099;;; ps-mode.el ends here 1101;;; ps-mode.el ends here
diff --git a/lisp/ps-print.el b/lisp/ps-print.el
index dad4c8ffbac..d67c34e11ab 100644
--- a/lisp/ps-print.el
+++ b/lisp/ps-print.el
@@ -8,21 +8,9 @@
8;; Kenichi Handa <handa@gnu.org> (multi-byte characters) 8;; Kenichi Handa <handa@gnu.org> (multi-byte characters)
9;; Maintainer: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com> 9;; Maintainer: Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
10;; Keywords: wp, print, PostScript 10;; Keywords: wp, print, PostScript
11;; Version: 7.3.5 11;; Old-Version: 7.3.5
12;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre 12;; URL: https://www.emacswiki.org/cgi-bin/wiki/ViniciusJoseLatorre
13 13
14(eval-when-compile (require 'cl-lib))
15
16(defconst ps-print-version "7.3.5"
17 "ps-print.el, v 7.3.5 <2009/12/23 vinicius>
18
19Vinicius's last change version -- this file may have been edited as part of
20Emacs without changes to the version number. When reporting bugs, please also
21report the version of Emacs, if any, that ps-print was distributed with.
22
23Please send all bug fixes and enhancements to
24 bug-gnu-emacs@gnu.org and Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>.")
25
26;; This file is part of GNU Emacs. 14;; This file is part of GNU Emacs.
27 15
28;; GNU Emacs is free software: you can redistribute it and/or modify 16;; GNU Emacs is free software: you can redistribute it and/or modify
@@ -1320,11 +1308,11 @@ Please send all bug fixes and enhancements to
1320;; Known bugs and limitations of ps-print 1308;; Known bugs and limitations of ps-print
1321;; -------------------------------------- 1309;; --------------------------------------
1322;; 1310;;
1323;; Automatic font-attribute detection doesn't work well, especially with 1311;; Automatic font-attribute detection doesn't work well. Users having
1324;; hilit19 and older versions of get-create-face. Users having problems with 1312;; problems with auto-font detection should use the lists
1325;; auto-font detection should use the lists `ps-italic-faces', `ps-bold-faces' 1313;; `ps-italic-faces', `ps-bold-faces' and `ps-underlined-faces' and/or
1326;; and `ps-underlined-faces' and/or turn off automatic detection by setting 1314;; turn off automatic detection by setting `ps-auto-font-detect' to
1327;; `ps-auto-font-detect' to nil. 1315;; nil.
1328;; 1316;;
1329;; Still too slow; could use some hand-optimization. 1317;; Still too slow; could use some hand-optimization.
1330;; 1318;;
@@ -1451,6 +1439,7 @@ Please send all bug fixes and enhancements to
1451;;; Code: 1439;;; Code:
1452 1440
1453(require 'lpr) 1441(require 'lpr)
1442(eval-when-compile (require 'cl-lib))
1454 1443
1455;; autoloads for secondary file 1444;; autoloads for secondary file
1456(require 'ps-print-loaddefs) 1445(require 'ps-print-loaddefs)
@@ -3596,7 +3585,6 @@ The table depends on the current ps-print setup."
3596 (mapconcat 3585 (mapconcat
3597 #'ps-print-quote 3586 #'ps-print-quote
3598 (list 3587 (list
3599 (concat "\n;;; (Emacs) ps-print version " ps-print-version "\n")
3600 ";; internal vars" 3588 ";; internal vars"
3601 (ps-comment-string "emacs-version " emacs-version) 3589 (ps-comment-string "emacs-version " emacs-version)
3602 (ps-comment-string "lpr-windows-system" lpr-windows-system) 3590 (ps-comment-string "lpr-windows-system" lpr-windows-system)
@@ -5347,7 +5335,7 @@ XSTART YSTART are the relative position for the first page in a sheet.")
5347 ps-adobe-tag 5335 ps-adobe-tag
5348 "%%Title: " (buffer-name) ; Take job name from name of 5336 "%%Title: " (buffer-name) ; Take job name from name of
5349 ; first buffer printed 5337 ; first buffer printed
5350 "\n%%Creator: ps-print v" ps-print-version 5338 "\n%%Creator: GNU Emacs " emacs-version
5351 "\n%%For: " (user-full-name) ;FIXME: may need encoding! 5339 "\n%%For: " (user-full-name) ;FIXME: may need encoding!
5352 "\n%%CreationDate: " (format-time-string "%T %b %d %Y") ;FIXME: encoding! 5340 "\n%%CreationDate: " (format-time-string "%T %b %d %Y") ;FIXME: encoding!
5353 "\n%%Orientation: " 5341 "\n%%Orientation: "
@@ -6548,6 +6536,17 @@ If FACE is not a valid face name, use default face."
6548(unless noninteractive 6536(unless noninteractive
6549 (add-hook 'kill-emacs-query-functions #'ps-kill-emacs-check)) 6537 (add-hook 'kill-emacs-query-functions #'ps-kill-emacs-check))
6550 6538
6539(defconst ps-print-version "7.3.5"
6540 "ps-print.el, v 7.3.5 <2009/12/23 vinicius>
6541
6542Vinicius's last change version -- this file may have been edited as part of
6543Emacs without changes to the version number. When reporting bugs, please also
6544report the version of Emacs, if any, that ps-print was distributed with.
6545
6546Please send all bug fixes and enhancements to
6547 bug-gnu-emacs@gnu.org and Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>.")
6548(make-obsolete-variable 'ps-print-version 'emacs-version "29.1")
6549
6551(define-obsolete-function-alias 'ps-print-ensure-fontified #'font-lock-ensure "29.1") 6550(define-obsolete-function-alias 'ps-print-ensure-fontified #'font-lock-ensure "29.1")
6552 6551
6553(provide 'ps-print) 6552(provide 'ps-print)
diff --git a/lisp/select.el b/lisp/select.el
index e407c224367..5b9cca80a38 100644
--- a/lisp/select.el
+++ b/lisp/select.el
@@ -673,9 +673,12 @@ two markers or an overlay. Otherwise, it is nil."
673 (let ((str (cond ((stringp value) value) 673 (let ((str (cond ((stringp value) value)
674 ((setq value (xselect--selection-bounds value)) 674 ((setq value (xselect--selection-bounds value))
675 (with-current-buffer (nth 2 value) 675 (with-current-buffer (nth 2 value)
676 (buffer-substring (nth 0 value) 676 (when (and (>= (nth 0 value) (point-min))
677 (nth 1 value))))))) 677 (<= (nth 1 value) (point-max)))
678 (xselect--encode-string type str t))) 678 (buffer-substring (nth 0 value)
679 (nth 1 value))))))))
680 (when str
681 (xselect--encode-string type str t))))
679 682
680(defun xselect-convert-to-length (_selection _type value) 683(defun xselect-convert-to-length (_selection _type value)
681 (let ((len (cond ((stringp value) 684 (let ((len (cond ((stringp value)
diff --git a/lisp/simple.el b/lisp/simple.el
index a4ea345ca5f..1e6e5e11e00 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -6731,7 +6731,8 @@ If Transient Mark mode is disabled, this function normally does
6731nothing; but if FORCE is non-nil, it deactivates the mark anyway. 6731nothing; but if FORCE is non-nil, it deactivates the mark anyway.
6732 6732
6733Deactivating the mark sets `mark-active' to nil, updates the 6733Deactivating the mark sets `mark-active' to nil, updates the
6734primary selection according to `select-active-regions', and runs 6734primary selection according to `select-active-regions' (unless
6735`deactivate-mark' is `dont-save'), and runs
6735`deactivate-mark-hook'. 6736`deactivate-mark-hook'.
6736 6737
6737If Transient Mark mode was temporarily enabled, reset the value 6738If Transient Mark mode was temporarily enabled, reset the value
@@ -6742,6 +6743,7 @@ run `deactivate-mark-hook'."
6742 (when (and (if (eq select-active-regions 'only) 6743 (when (and (if (eq select-active-regions 'only)
6743 (eq (car-safe transient-mark-mode) 'only) 6744 (eq (car-safe transient-mark-mode) 'only)
6744 select-active-regions) 6745 select-active-regions)
6746 (not (eq deactivate-mark 'dont-save))
6745 (region-active-p) 6747 (region-active-p)
6746 (display-selections-p)) 6748 (display-selections-p))
6747 ;; The var `saved-region-selection', if non-nil, is the text in 6749 ;; The var `saved-region-selection', if non-nil, is the text in
@@ -7690,11 +7692,33 @@ not vscroll."
7690 ;; But don't vscroll in a keyboard macro. 7692 ;; But don't vscroll in a keyboard macro.
7691 (not defining-kbd-macro) 7693 (not defining-kbd-macro)
7692 (not executing-kbd-macro) 7694 (not executing-kbd-macro)
7695 ;; Lines are not truncated...
7696 (not
7697 (and
7698 (or truncate-lines
7699 (and (integerp truncate-partial-width-windows)
7700 (< (window-total-width)
7701 truncate-partial-width-windows))
7702 (and truncate-partial-width-windows
7703 (not (integerp truncate-partial-width-windows))
7704 (not (window-full-width-p))))
7705 ;; ...or if lines are truncated, this buffer
7706 ;; doesn't have very long lines.
7707 (long-line-optimizations-p)))
7693 (line-move-partial arg noerror)) 7708 (line-move-partial arg noerror))
7694 (set-window-vscroll nil 0 t) 7709 (set-window-vscroll nil 0 t)
7695 (if (and line-move-visual 7710 (if (and line-move-visual
7696 ;; Display-based column are incompatible with goal-column. 7711 ;; Display-based column are incompatible with goal-column.
7697 (not goal-column) 7712 (not goal-column)
7713 ;; Lines aren't truncated.
7714 (not
7715 (or truncate-lines
7716 (and (integerp truncate-partial-width-windows)
7717 (< (window-width)
7718 truncate-partial-width-windows))
7719 (and truncate-partial-width-windows
7720 (not (integerp truncate-partial-width-windows))
7721 (not (window-full-width-p)))))
7698 ;; When the text in the window is scrolled to the left, 7722 ;; When the text in the window is scrolled to the left,
7699 ;; display-based motion doesn't make sense (because each 7723 ;; display-based motion doesn't make sense (because each
7700 ;; logical line occupies exactly one screen line). 7724 ;; logical line occupies exactly one screen line).
@@ -8131,10 +8155,11 @@ For motion by visual lines, see `beginning-of-visual-line'."
8131 (line-move (1- arg) t))) 8155 (line-move (1- arg) t)))
8132 8156
8133 ;; Move to beginning-of-line, ignoring fields and invisible text. 8157 ;; Move to beginning-of-line, ignoring fields and invisible text.
8134 (skip-chars-backward "^\n") 8158 (let ((inhibit-field-text-motion t))
8135 (while (and (not (bobp)) (invisible-p (1- (point)))) 8159 (goto-char (line-beginning-position))
8136 (goto-char (previous-char-property-change (point))) 8160 (while (and (not (bobp)) (invisible-p (1- (point))))
8137 (skip-chars-backward "^\n")) 8161 (goto-char (previous-char-property-change (point)))
8162 (goto-char (line-beginning-position))))
8138 8163
8139 ;; Now find first visible char in the line. 8164 ;; Now find first visible char in the line.
8140 (while (and (< (point) orig) (invisible-p (point))) 8165 (while (and (< (point) orig) (invisible-p (point)))
diff --git a/lisp/subr.el b/lisp/subr.el
index 4b1fc832da1..42ce9148a90 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -4077,6 +4077,12 @@ Otherwise, return nil."
4077 (or (eq 'macro (car def)) 4077 (or (eq 'macro (car def))
4078 (and (autoloadp def) (memq (nth 4 def) '(macro t))))))) 4078 (and (autoloadp def) (memq (nth 4 def) '(macro t)))))))
4079 4079
4080(defun compiled-function-p (object)
4081 "Return non-nil if OBJECT is a function that has been compiled.
4082Does not distinguish between functions implemented in machine code
4083or byte-code."
4084 (or (subrp object) (byte-code-function-p object)))
4085
4080(defun field-at-pos (pos) 4086(defun field-at-pos (pos)
4081 "Return the field at position POS, taking stickiness etc into account." 4087 "Return the field at position POS, taking stickiness etc into account."
4082 (let ((raw-field (get-char-property (field-beginning pos) 'field))) 4088 (let ((raw-field (get-char-property (field-beginning pos) 'field)))
diff --git a/lisp/textmodes/emacs-authors-mode.el b/lisp/textmodes/emacs-authors-mode.el
new file mode 100644
index 00000000000..af78ab605e9
--- /dev/null
+++ b/lisp/textmodes/emacs-authors-mode.el
@@ -0,0 +1,145 @@
1;;; emacs-authors-mode.el --- font-locking for etc/AUTHORS -*- lexical-binding: t -*-
2
3;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
4
5;; Author: Stefan Kangas <stefan@marxist.se>
6;; Keywords: internal
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
22
23;;; Commentary:
24
25;; Major mode to display the etc/AUTHORS file from the Emacs
26;; distribution. Provides some basic font locking and not much else.
27
28;;; Code:
29
30(require 'subr-x) ; `emacs-etc--hide-local-variables'
31
32(defgroup emacs-authors-mode nil
33 "Display the \"etc/AUTHORS\" file from the Emacs distribution."
34 :version "29.1"
35 :group 'internal)
36
37(defface emacs-authors-default
38 '((t :inherit variable-pitch))
39 "Default face used to display the \"etc/AUTHORS\" file.
40See also `emacs-authors-mode'."
41 :version "29.1")
42
43(defface emacs-authors-author
44 '((((class color) (min-colors 88) (background light))
45 :foreground "midnight blue"
46 :weight bold :height 1.05
47 :inherit variable-pitch)
48 (((class color) (min-colors 88) (background dark))
49 :foreground "cyan"
50 :weight bold :height 1.05
51 :inherit variable-pitch)
52 (((supports :weight bold) (supports :height 1.05))
53 :weight bold :height 1.05
54 :inherit variable-pitch)
55 (((supports :weight bold))
56 :weight bold :inherit variable-pitch)
57 (t :inherit variable-pitch))
58 "Face used for the author in the \"etc/AUTHORS\" file.
59See also `emacs-authors-mode'."
60 :version "29.1")
61
62(defface emacs-authors-descriptor
63 '((((class color) (min-colors 88) (background light))
64 :foreground "sienna" :inherit variable-pitch)
65 (((class color) (min-colors 88) (background dark))
66 :foreground "peru" :inherit variable-pitch)
67 (t :inherit variable-pitch))
68 "Face used for the description text in the \"etc/AUTHORS\" file.
69See also `emacs-authors-mode'."
70 :version "29.1")
71
72(defface emacs-authors-other-files
73 '((t :inherit emacs-authors-descriptor))
74 "Face used for the \"other files\" text in the \"etc/AUTHORS\" file.
75See also `emacs-authors-mode'."
76 :version "29.1")
77
78(defconst emacs-authors--author-re
79 (rx bol (group (not (any blank "\n")) (+? (not (any ":" "\n")))) ":")
80 "Regexp matching an author in \"etc/AUTHORS\".")
81
82(defvar emacs-authors-mode-font-lock-keywords
83 `((,emacs-authors--author-re
84 1 'emacs-authors-author)
85 (,(rx (or "wrote"
86 (seq (? "and ") (or "co-wrote" "changed"))))
87 0 'emacs-authors-descriptor)
88 (,(rx "and " (+ digit) " other files")
89 0 'emacs-authors-other-files)
90 (,(rx bol (not space) (+ not-newline) eol)
91 0 'emacs-authors-default)))
92
93(defun emacs-authors-next-author (&optional arg)
94 "Move point to the next author in \"etc/AUTHORS\".
95With a prefix arg ARG, move point that many authors forward."
96 (interactive "p" emacs-authors-mode)
97 (if (< 0 arg)
98 (progn
99 (when (looking-at emacs-authors--author-re)
100 (forward-line 1))
101 (re-search-forward emacs-authors--author-re nil t arg))
102 (when (looking-at emacs-authors--author-re)
103 (forward-line -1))
104 (re-search-backward emacs-authors--author-re nil t (abs arg)))
105 (goto-char (line-beginning-position)))
106
107(defun emacs-authors-prev-author (&optional arg)
108 "Move point to the previous author in \"etc/AUTHORS\".
109With a prefix arg ARG, move point that many authors backward."
110 (interactive "p" emacs-authors-mode)
111 (emacs-authors-next-author (- arg)))
112
113(defvar emacs-authors-imenu-generic-expression
114 `((nil ,(rx bol (group (+ (not ":"))) ": "
115 (or "wrote" "co-wrote" "changed")
116 " ")
117 1)))
118
119(define-obsolete-variable-alias 'etc-authors-mode-map 'emacs-authors-mode-map "29.1")
120(defvar-keymap emacs-authors-mode-map
121 :doc "Keymap for `emacs-authors-mode'."
122 "n" #'emacs-authors-next-author
123 "p" #'emacs-authors-prev-author)
124
125;;;###autoload
126(define-derived-mode emacs-authors-mode special-mode "Authors View"
127 "Major mode for viewing \"etc/AUTHORS\" from the Emacs distribution.
128Provides some basic font locking and not much else."
129 (setq-local font-lock-defaults
130 '(emacs-authors-mode-font-lock-keywords nil nil ((?_ . "w"))))
131 (setq font-lock-multiline nil)
132 (setq imenu-generic-expression emacs-authors-imenu-generic-expression)
133 (emacs-etc--hide-local-variables))
134
135(define-obsolete-face-alias 'etc-authors-default 'emacs-authors-default "29.1")
136(define-obsolete-face-alias 'etc-authors-author 'emacs-authors-author "29.1")
137(define-obsolete-face-alias 'etc-authors-descriptor 'emacs-authors-descriptor "29.1")
138(define-obsolete-face-alias 'etc-authors-other-files 'emacs-authors-other-files "29.1")
139(define-obsolete-function-alias 'etc-authors-next-author #'emacs-authors-next-author "29.1")
140(define-obsolete-function-alias 'etc-authors-prev-author #'emacs-authors-prev-author "29.1")
141;;;###autoload
142(define-obsolete-function-alias 'etc-authors-mode #'emacs-authors-mode "29.1")
143
144(provide 'emacs-authors-mode)
145;;; emacs-authors-mode.el ends here
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index e6e1f037284..022e17c9343 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -25,6 +25,7 @@
25 25
26(eval-when-compile (require 'cl-lib)) 26(eval-when-compile (require 'cl-lib))
27(require 'outline) 27(require 'outline)
28(require 'subr-x) ; `emacs-etc--hide-local-variables'
28 29
29(defgroup emacs-news-mode nil 30(defgroup emacs-news-mode nil
30 "Major mode for editing and viewing the Emacs NEWS file." 31 "Major mode for editing and viewing the Emacs NEWS file."
@@ -59,9 +60,12 @@
59 "C-x C-q" #'emacs-news-view-mode 60 "C-x C-q" #'emacs-news-view-mode
60 "<remap> <open-line>" #'emacs-news-open-line) 61 "<remap> <open-line>" #'emacs-news-open-line)
61 62
62(defvar-keymap emacs-news-view-mode-map 63(defvar emacs-news-view-mode-map
63 :parent emacs-news-common-map 64 ;; This is defined this way instead of inheriting because we're
64 "C-x C-q" #'emacs-news-mode) 65 ;; deriving the mode from `special-mode' and want the keys from there.
66 (let ((map (copy-keymap emacs-news-common-map)))
67 (keymap-set map "C-x C-q" #'emacs-news-mode)
68 map))
65 69
66(defvar emacs-news-mode-font-lock-keywords 70(defvar emacs-news-mode-font-lock-keywords
67 `(("^---$" 0 'emacs-news-does-not-need-documentation) 71 `(("^---$" 0 'emacs-news-does-not-need-documentation)
@@ -73,7 +77,8 @@
73 outline-minor-mode-cycle t 77 outline-minor-mode-cycle t
74 outline-level (lambda () (length (match-string 2))) 78 outline-level (lambda () (length (match-string 2)))
75 outline-minor-mode-highlight 'append) 79 outline-minor-mode-highlight 'append)
76 (outline-minor-mode)) 80 (outline-minor-mode)
81 (emacs-etc--hide-local-variables))
77 82
78;;;###autoload 83;;;###autoload
79(define-derived-mode emacs-news-mode text-mode "NEWS" 84(define-derived-mode emacs-news-mode text-mode "NEWS"
diff --git a/lisp/textmodes/etc-authors-mode.el b/lisp/textmodes/etc-authors-mode.el
deleted file mode 100644
index 7eabdd4c2b8..00000000000
--- a/lisp/textmodes/etc-authors-mode.el
+++ /dev/null
@@ -1,133 +0,0 @@
1;;; etc-authors-mode.el --- font-locking for etc/AUTHORS -*- lexical-binding: t -*-
2
3;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
4
5;; Author: Stefan Kangas <stefan@marxist.se>
6;; Keywords: internal
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
22
23;;; Commentary:
24
25;; Major mode to display the etc/AUTHORS file from the Emacs
26;; distribution. Provides some basic font locking and not much else.
27
28;;; Code:
29
30(defgroup etc-authors-mode nil
31 "Display the \"etc/AUTHORS\" file from the Emacs distribution."
32 :version "28.1"
33 :group 'internal)
34
35(defface etc-authors-default '((t :inherit variable-pitch))
36 "Default face used to display the \"etc/AUTHORS\" file.
37See also `etc-authors-mode'."
38 :version "28.1")
39
40(defface etc-authors-author '((((class color) (min-colors 88) (background light))
41 :foreground "midnight blue"
42 :weight bold :height 1.05
43 :inherit variable-pitch)
44 (((class color) (min-colors 88) (background dark))
45 :foreground "cyan"
46 :weight bold :height 1.05
47 :inherit variable-pitch)
48 (((supports :weight bold) (supports :height 1.05))
49 :weight bold :height 1.05
50 :inherit variable-pitch)
51 (((supports :weight bold))
52 :weight bold :inherit variable-pitch)
53 (t :inherit variable-pitch))
54 "Face used for the author in the \"etc/AUTHORS\" file.
55See also `etc-authors-mode'."
56 :version "28.1")
57
58(defface etc-authors-descriptor '((((class color) (min-colors 88) (background light))
59 :foreground "sienna" :inherit variable-pitch)
60 (((class color) (min-colors 88) (background dark))
61 :foreground "peru" :inherit variable-pitch)
62 (t :inherit variable-pitch))
63 "Face used for the description text in the \"etc/AUTHORS\" file.
64See also `etc-authors-mode'."
65 :version "28.1")
66
67(defface etc-authors-other-files '((t :inherit etc-authors-descriptor))
68 "Face used for the \"other files\" text in the \"etc/AUTHORS\" file.
69See also `etc-authors-mode'."
70 :version "28.1")
71
72(defconst etc-authors--author-re
73 (rx bol (group (not (any blank "\n")) (+? (not (any ":" "\n")))) ":")
74 "Regexp matching an author in \"etc/AUTHORS\".")
75
76(defvar etc-authors-mode-font-lock-keywords
77 `((,etc-authors--author-re
78 1 'etc-authors-author)
79 (,(rx (or "wrote"
80 (seq (? "and ") (or "co-wrote" "changed"))))
81 0 'etc-authors-descriptor)
82 (,(rx "and " (+ digit) " other files")
83 0 'etc-authors-other-files)
84 (,(rx bol (not space) (+ not-newline) eol)
85 0 'etc-authors-default)))
86
87(defun etc-authors-mode--hide-local-variables ()
88 "Hide local variables in \"etc/AUTHORS\". Used by `etc-authors-mode'."
89 (narrow-to-region (point-min)
90 (save-excursion
91 (goto-char (point-min))
92 ;; Obfuscate to avoid this being interpreted
93 ;; as a local variable section itself.
94 (if (re-search-forward "^Local\sVariables:$" nil t)
95 (progn (forward-line -1) (point))
96 (point-max)))))
97
98(defun etc-authors-next-author (&optional arg)
99 "Move point to the next author in \"etc/AUTHORS\".
100With a prefix arg ARG, move point that many authors forward."
101 (interactive "p" etc-authors-mode)
102 (if (< 0 arg)
103 (progn
104 (when (looking-at etc-authors--author-re)
105 (forward-line 1))
106 (re-search-forward etc-authors--author-re nil t arg))
107 (when (looking-at etc-authors--author-re)
108 (forward-line -1))
109 (re-search-backward etc-authors--author-re nil t (abs arg)))
110 (goto-char (line-beginning-position)))
111
112(defun etc-authors-prev-author (&optional arg)
113 "Move point to the previous author in \"etc/AUTHORS\".
114With a prefix arg ARG, move point that many authors backward."
115 (interactive "p" etc-authors-mode)
116 (etc-authors-next-author (- arg)))
117
118(defvar-keymap etc-authors-mode-map
119 :doc "Keymap for `etc-authors-mode'."
120 "n" #'etc-authors-next-author
121 "p" #'etc-authors-prev-author)
122
123;;;###autoload
124(define-derived-mode etc-authors-mode special-mode "Authors View"
125 "Major mode for viewing \"etc/AUTHORS\" from the Emacs distribution.
126Provides some basic font locking and not much else."
127 (setq-local font-lock-defaults
128 '(etc-authors-mode-font-lock-keywords nil nil ((?_ . "w"))))
129 (setq font-lock-multiline nil)
130 (etc-authors-mode--hide-local-variables))
131
132(provide 'etc-authors-mode)
133;;; etc-authors-mode.el ends here
diff --git a/lisp/thingatpt.el b/lisp/thingatpt.el
index a7c86fb24f0..462f87d3c1a 100644
--- a/lisp/thingatpt.el
+++ b/lisp/thingatpt.el
@@ -74,7 +74,7 @@ question.
74 74
75\"things\" include `symbol', `list', `sexp', `defun', `filename', 75\"things\" include `symbol', `list', `sexp', `defun', `filename',
76`existing-filename', `url', `email', `uuid', `word', `sentence', 76`existing-filename', `url', `email', `uuid', `word', `sentence',
77`whitespace', `line', and `page'.") 77`whitespace', `line', `face' and `page'.")
78 78
79;; Basic movement 79;; Basic movement
80 80
@@ -166,7 +166,7 @@ positions of the thing found."
166THING should be a symbol specifying a type of syntactic entity. 166THING should be a symbol specifying a type of syntactic entity.
167Possibilities include `symbol', `list', `sexp', `defun', 167Possibilities include `symbol', `list', `sexp', `defun',
168`filename', `existing-filename', `url', `email', `uuid', `word', 168`filename', `existing-filename', `url', `email', `uuid', `word',
169`sentence', `whitespace', `line', `number', and `page'. 169`sentence', `whitespace', `line', `number', `face' and `page'.
170 170
171When the optional argument NO-PROPERTIES is non-nil, 171When the optional argument NO-PROPERTIES is non-nil,
172strip text properties from the return value. 172strip text properties from the return value.
@@ -361,6 +361,15 @@ E.g.:
361 361
362(put 'existing-filename 'thing-at-point 'thing-at-point-file-at-point) 362(put 'existing-filename 'thing-at-point 'thing-at-point-file-at-point)
363 363
364;; Faces
365
366(defun thing-at-point-face-at-point (&optional _lax _bounds)
367 "Return the name of the face at point as a symbol."
368 (when-let ((face (thing-at-point 'symbol)))
369 (and (facep face) (intern face))))
370
371(put 'face 'thing-at-point 'thing-at-point-face-at-point)
372
364;; URIs 373;; URIs
365 374
366(defvar thing-at-point-beginning-of-url-regexp nil 375(defvar thing-at-point-beginning-of-url-regexp nil
diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el
index e02d84f1f56..d710578ffff 100644
--- a/lisp/vc/add-log.el
+++ b/lisp/vc/add-log.el
@@ -568,14 +568,12 @@ Compatibility function for \\[next-error] invocations."
568 ;; Select window displaying source file. 568 ;; Select window displaying source file.
569 (select-window change-log-find-window))))) 569 (select-window change-log-find-window)))))
570 570
571(defvar change-log-mode-map 571(defvar-keymap change-log-mode-map
572 (let ((map (make-sparse-keymap))) 572 :doc "Keymap for Change Log major mode."
573 (define-key map [?\C-c ?\C-p] #'add-log-edit-prev-comment) 573 "C-c C-p" #'add-log-edit-prev-comment
574 (define-key map [?\C-c ?\C-n] #'add-log-edit-next-comment) 574 "C-c C-n" #'add-log-edit-next-comment
575 (define-key map [?\C-c ?\C-f] #'change-log-find-file) 575 "C-c C-f" #'change-log-find-file
576 (define-key map [?\C-c ?\C-c] #'change-log-goto-source) 576 "C-c C-c" #'change-log-goto-source)
577 map)
578 "Keymap for Change Log major mode.")
579 577
580(easy-menu-define change-log-mode-menu change-log-mode-map 578(easy-menu-define change-log-mode-menu change-log-mode-map
581 "Menu for Change Log major mode." 579 "Menu for Change Log major mode."
diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el
index aa426446d73..e4a1996c1bb 100644
--- a/lisp/vc/diff-mode.el
+++ b/lisp/vc/diff-mode.el
@@ -27,8 +27,8 @@
27;; to the corresponding source file. 27;; to the corresponding source file.
28 28
29;; Inspired by Pavel Machek's patch-mode.el (<pavel@@atrey.karlin.mff.cuni.cz>) 29;; Inspired by Pavel Machek's patch-mode.el (<pavel@@atrey.karlin.mff.cuni.cz>)
30;; Some efforts were spent to have it somewhat compatible with XEmacs's 30;; Some efforts were spent to have it somewhat compatible with
31;; diff-mode as well as with compilation-minor-mode 31;; `compilation-minor-mode'.
32 32
33;; Bugs: 33;; Bugs:
34 34
diff --git a/lisp/vc/ediff-mult.el b/lisp/vc/ediff-mult.el
index 7e15060f8c4..52e356d8e9b 100644
--- a/lisp/vc/ediff-mult.el
+++ b/lisp/vc/ediff-mult.el
@@ -144,20 +144,18 @@ Useful commands (type ? to hide them and free up screen):
144 144
145(ediff-defvar-local ediff-meta-buffer-map nil 145(ediff-defvar-local ediff-meta-buffer-map nil
146 "The keymap for the meta buffer.") 146 "The keymap for the meta buffer.")
147(defvar ediff-dir-diffs-buffer-map 147(defvar-keymap ediff-dir-diffs-buffer-map
148 (let ((map (make-sparse-keymap))) 148 :doc "Keymap for buffer showing differences between directories."
149 (suppress-keymap map) 149 :suppress t
150 (define-key map "q" #'ediff-bury-dir-diffs-buffer) 150 "q" #'ediff-bury-dir-diffs-buffer
151 (define-key map " " #'next-line) 151 "SPC" #'next-line
152 (define-key map "n" #'next-line) 152 "n" #'next-line
153 (define-key map "\C-?" #'previous-line) 153 "DEL" #'previous-line
154 (define-key map "p" #'previous-line) 154 "p" #'previous-line
155 (define-key map "C" #'ediff-dir-diff-copy-file) 155 "C" #'ediff-dir-diff-copy-file
156 (define-key map [mouse-2] #'ediff-dir-diff-copy-file) 156 "<mouse-2>" #'ediff-dir-diff-copy-file
157 (define-key map [delete] #'previous-line) 157 "<delete>" #'previous-line
158 (define-key map [backspace] #'previous-line) 158 "<backspace>" #'previous-line)
159 map)
160 "Keymap for buffer showing differences between directories.")
161 159
162;; Variable specifying the action to take when the use invokes ediff in the 160;; Variable specifying the action to take when the use invokes ediff in the
163;; meta buffer. This is usually ediff-registry-action or ediff-filegroup-action 161;; meta buffer. This is usually ediff-registry-action or ediff-filegroup-action
diff --git a/lisp/vc/ediff.el b/lisp/vc/ediff.el
index 84ad5cef90f..94e3fc6d7fe 100644
--- a/lisp/vc/ediff.el
+++ b/lisp/vc/ediff.el
@@ -89,12 +89,11 @@
89;; underlining. However, if the region is already underlined by some other 89;; underlining. However, if the region is already underlined by some other
90;; overlays, there is no simple way to temporarily remove that residual 90;; overlays, there is no simple way to temporarily remove that residual
91;; underlining. This problem occurs when a buffer is highlighted with 91;; underlining. This problem occurs when a buffer is highlighted with
92;; hilit19.el or font-lock.el packages. If this residual highlighting gets 92;; font-lock.el packages. If this residual highlighting gets in the way, you
93;; in the way, you can do the following. Both font-lock.el and hilit19.el 93;; can do the following. font-lock.el provides commands for unhighlighting
94;; provide commands for unhighlighting buffers. You can either place these 94;; buffers. You can either place these commands in `ediff-prepare-buffer-hook'
95;; commands in `ediff-prepare-buffer-hook' (which will unhighlight every 95;; (which will unhighlight every buffer used by Ediff) or you can execute
96;; buffer used by Ediff) or you can execute them interactively, at any time 96;; them interactively, at any time and in any buffer.
97;; and on any buffer.
98 97
99 98
100;;; Acknowledgments: 99;;; Acknowledgments:
diff --git a/lisp/vc/emerge.el b/lisp/vc/emerge.el
index 422ed5c0a4d..de09be80e7c 100644
--- a/lisp/vc/emerge.el
+++ b/lisp/vc/emerge.el
@@ -2942,6 +2942,7 @@ If some prefix of KEY has a non-prefix definition, it is redefined."
2942 2942
2943;; Define a key if it (or a prefix) is not already defined in the map. 2943;; Define a key if it (or a prefix) is not already defined in the map.
2944(defun emerge-define-key-if-possible (keymap key definition) 2944(defun emerge-define-key-if-possible (keymap key definition)
2945 (declare (obsolete keymap-set "29.1"))
2945 ;; look up the present definition of the key 2946 ;; look up the present definition of the key
2946 (let ((present (lookup-key keymap key))) 2947 (let ((present (lookup-key keymap key)))
2947 (if (integerp present) 2948 (if (integerp present)
@@ -2959,6 +2960,7 @@ If some prefix of KEY has a non-prefix definition, it is redefined."
2959If the name won't fit on one line, the minibuffer is expanded to hold it, 2960If the name won't fit on one line, the minibuffer is expanded to hold it,
2960and the command waits for a keystroke from the user. If the keystroke is 2961and the command waits for a keystroke from the user. If the keystroke is
2961SPC, it is ignored; if it is anything else, it is processed as a command." 2962SPC, it is ignored; if it is anything else, it is processed as a command."
2963 (declare (obsolete nil "29.1"))
2962 (interactive) 2964 (interactive)
2963 (let ((name (buffer-file-name))) 2965 (let ((name (buffer-file-name)))
2964 (or name 2966 (or name
diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el
index 1f19c4cfe26..a15cf417de3 100644
--- a/lisp/vc/vc-annotate.el
+++ b/lisp/vc/vc-annotate.el
@@ -162,22 +162,20 @@ List of factors, used to expand/compress the time scale. See `vc-annotate'."
162 :type '(repeat number) 162 :type '(repeat number)
163 :group 'vc) 163 :group 'vc)
164 164
165(defvar vc-annotate-mode-map 165(defvar-keymap vc-annotate-mode-map
166 (let ((m (make-sparse-keymap))) 166 :doc "Local keymap used for VC-Annotate mode."
167 (define-key m "a" #'vc-annotate-revision-previous-to-line) 167 "a" #'vc-annotate-revision-previous-to-line
168 (define-key m "d" #'vc-annotate-show-diff-revision-at-line) 168 "d" #'vc-annotate-show-diff-revision-at-line
169 (define-key m "=" #'vc-annotate-show-diff-revision-at-line) 169 "=" #'vc-annotate-show-diff-revision-at-line
170 (define-key m "D" #'vc-annotate-show-changeset-diff-revision-at-line) 170 "D" #'vc-annotate-show-changeset-diff-revision-at-line
171 (define-key m "f" #'vc-annotate-find-revision-at-line) 171 "f" #'vc-annotate-find-revision-at-line
172 (define-key m "j" #'vc-annotate-revision-at-line) 172 "j" #'vc-annotate-revision-at-line
173 (define-key m "l" #'vc-annotate-show-log-revision-at-line) 173 "l" #'vc-annotate-show-log-revision-at-line
174 (define-key m "n" #'vc-annotate-next-revision) 174 "n" #'vc-annotate-next-revision
175 (define-key m "p" #'vc-annotate-prev-revision) 175 "p" #'vc-annotate-prev-revision
176 (define-key m "w" #'vc-annotate-working-revision) 176 "w" #'vc-annotate-working-revision
177 (define-key m "v" #'vc-annotate-toggle-annotation-visibility) 177 "v" #'vc-annotate-toggle-annotation-visibility
178 (define-key m "\C-m" #'vc-annotate-goto-line) 178 "RET" #'vc-annotate-goto-line)
179 m)
180 "Local keymap used for VC-Annotate mode.")
181 179
182;;; Annotate functionality 180;;; Annotate functionality
183 181
diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el
index 072bd72b441..f6b17d4ce09 100644
--- a/lisp/vc/vc-bzr.el
+++ b/lisp/vc/vc-bzr.el
@@ -1008,19 +1008,17 @@ stream. Standard error output is discarded."
1008 ;; frob the results accordingly. 1008 ;; frob the results accordingly.
1009 (file-relative-name dir (vc-bzr-root dir))))) 1009 (file-relative-name dir (vc-bzr-root dir)))))
1010 1010
1011(defvar vc-bzr-shelve-map 1011(defvar-keymap vc-bzr-shelve-map
1012 (let ((map (make-sparse-keymap))) 1012 ;; Turn off vc-dir marking
1013 ;; Turn off vc-dir marking 1013 "<mouse-2>" #'ignore
1014 (define-key map [mouse-2] #'ignore) 1014
1015 1015 "<down-mouse-3>" #'vc-bzr-shelve-menu
1016 (define-key map [down-mouse-3] #'vc-bzr-shelve-menu) 1016 "C-k" #'vc-bzr-shelve-delete-at-point
1017 (define-key map "\C-k" #'vc-bzr-shelve-delete-at-point) 1017 "=" #'vc-bzr-shelve-show-at-point
1018 (define-key map "=" #'vc-bzr-shelve-show-at-point) 1018 "RET" #'vc-bzr-shelve-show-at-point
1019 (define-key map "\C-m" #'vc-bzr-shelve-show-at-point) 1019 "A" #'vc-bzr-shelve-apply-and-keep-at-point
1020 (define-key map "A" #'vc-bzr-shelve-apply-and-keep-at-point) 1020 "P" #'vc-bzr-shelve-apply-at-point
1021 (define-key map "P" #'vc-bzr-shelve-apply-at-point) 1021 "S" #'vc-bzr-shelve-snapshot)
1022 (define-key map "S" #'vc-bzr-shelve-snapshot)
1023 map))
1024 1022
1025(defvar vc-bzr-shelve-menu-map 1023(defvar vc-bzr-shelve-menu-map
1026 (let ((map (make-sparse-keymap "Bzr Shelve"))) 1024 (let ((map (make-sparse-keymap "Bzr Shelve")))
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el
index 9335da10065..068a66b25b8 100644
--- a/lisp/vc/vc-dir.el
+++ b/lisp/vc/vc-dir.el
@@ -1467,17 +1467,13 @@ These are the commands available for use in the file status buffer:
1467 (propertize "Please add backend specific headers here. It's easy!" 1467 (propertize "Please add backend specific headers here. It's easy!"
1468 'face 'vc-dir-status-warning))) 1468 'face 'vc-dir-status-warning)))
1469 1469
1470(defvar vc-dir-status-mouse-map 1470(defvar-keymap vc-dir-status-mouse-map
1471 (let ((map (make-sparse-keymap))) 1471 :doc "Local keymap for toggling mark."
1472 (define-key map [mouse-2] #'vc-dir-toggle-mark) 1472 "<mouse-2>" #'vc-dir-toggle-mark)
1473 map)
1474 "Local keymap for toggling mark.")
1475 1473
1476(defvar vc-dir-filename-mouse-map 1474(defvar-keymap vc-dir-filename-mouse-map
1477 (let ((map (make-sparse-keymap))) 1475 :doc "Local keymap for visiting a file."
1478 (define-key map [mouse-2] #'vc-dir-find-file-other-window) 1476 "<mouse-2>" #'vc-dir-find-file-other-window)
1479 map)
1480 "Local keymap for visiting a file.")
1481 1477
1482(defun vc-default-dir-printer (_backend fileentry) 1478(defun vc-default-dir-printer (_backend fileentry)
1483 "Pretty print FILEENTRY." 1479 "Pretty print FILEENTRY."
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 8937454d111..46a486a46c3 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -664,32 +664,26 @@ or an empty string if none."
664 :files files 664 :files files
665 :update-function update-function))) 665 :update-function update-function)))
666 666
667(defvar vc-git-stash-shared-map 667(defvar-keymap vc-git-stash-shared-map
668 (let ((map (make-sparse-keymap))) 668 "S" #'vc-git-stash-snapshot
669 (define-key map "S" #'vc-git-stash-snapshot) 669 "C" #'vc-git-stash)
670 (define-key map "C" #'vc-git-stash) 670
671 map)) 671(defvar-keymap vc-git-stash-map
672 672 :parent vc-git-stash-shared-map
673(defvar vc-git-stash-map 673 ;; Turn off vc-dir marking
674 (let ((map (make-sparse-keymap))) 674 "<mouse-2>" #'ignore
675 (set-keymap-parent map vc-git-stash-shared-map) 675
676 ;; Turn off vc-dir marking 676 "<down-mouse-3>" #'vc-git-stash-menu
677 (define-key map [mouse-2] #'ignore) 677 "C-k" #'vc-git-stash-delete-at-point
678 678 "=" #'vc-git-stash-show-at-point
679 (define-key map [down-mouse-3] #'vc-git-stash-menu) 679 "RET" #'vc-git-stash-show-at-point
680 (define-key map "\C-k" #'vc-git-stash-delete-at-point) 680 "A" #'vc-git-stash-apply-at-point
681 (define-key map "=" #'vc-git-stash-show-at-point) 681 "P" #'vc-git-stash-pop-at-point)
682 (define-key map "\C-m" #'vc-git-stash-show-at-point) 682
683 (define-key map "A" #'vc-git-stash-apply-at-point) 683(defvar-keymap vc-git-stash-button-map
684 (define-key map "P" #'vc-git-stash-pop-at-point) 684 :parent vc-git-stash-shared-map
685 map)) 685 "<mouse-2>" #'push-button
686 686 "RET" #'push-button)
687(defvar vc-git-stash-button-map
688 (let ((map (make-sparse-keymap)))
689 (set-keymap-parent map vc-git-stash-shared-map)
690 (define-key map [mouse-2] #'push-button)
691 (define-key map "\C-m" #'push-button)
692 map))
693 687
694(defconst vc-git-stash-shared-help 688(defconst vc-git-stash-shared-help
695 "\\<vc-git-stash-shared-map>\\[vc-git-stash]: Create named stash\n\\[vc-git-stash-snapshot]: Snapshot stash") 689 "\\<vc-git-stash-shared-map>\\[vc-git-stash]: Create named stash\n\\[vc-git-stash-snapshot]: Snapshot stash")
@@ -910,12 +904,11 @@ If toggling on, also insert its message into the buffer."
910 standard-output 1 nil 904 standard-output 1 nil
911 "log" "--max-count=1" "--pretty=format:%B" "HEAD"))))) 905 "log" "--max-count=1" "--pretty=format:%B" "HEAD")))))
912 906
913(defvar vc-git-log-edit-mode-map 907(defvar-keymap vc-git-log-edit-mode-map
914 (let ((map (make-sparse-keymap "Git-Log-Edit"))) 908 :name "Git-Log-Edit"
915 (define-key map "\C-c\C-s" #'vc-git-log-edit-toggle-signoff) 909 "C-c C-s" #'vc-git-log-edit-toggle-signoff
916 (define-key map "\C-c\C-n" #'vc-git-log-edit-toggle-no-verify) 910 "C-c C-n" #'vc-git-log-edit-toggle-no-verify
917 (define-key map "\C-c\C-e" #'vc-git-log-edit-toggle-amend) 911 "C-c C-e" #'vc-git-log-edit-toggle-amend)
918 map))
919 912
920(define-derived-mode vc-git-log-edit-mode log-edit-mode "Log-Edit/git" 913(define-derived-mode vc-git-log-edit-mode log-edit-mode "Log-Edit/git"
921 "Major mode for editing Git log messages. 914 "Major mode for editing Git log messages.
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el
index 5fba2b3908a..61976288e35 100644
--- a/lisp/vc/vc-hg.el
+++ b/lisp/vc/vc-hg.el
@@ -1177,10 +1177,9 @@ If toggling on, also insert its message into the buffer."
1177 standard-output 1 nil 1177 standard-output 1 nil
1178 "log" "--limit=1" "--template" "{desc}"))))) 1178 "log" "--limit=1" "--template" "{desc}")))))
1179 1179
1180(defvar vc-hg-log-edit-mode-map 1180(defvar-keymap vc-hg-log-edit-mode-map
1181 (let ((map (make-sparse-keymap "Hg-Log-Edit"))) 1181 :name "Hg-Log-Edit"
1182 (define-key map "\C-c\C-e" #'vc-hg-log-edit-toggle-amend) 1182 "C-c C-e" #'vc-hg-log-edit-toggle-amend)
1183 map))
1184 1183
1185(define-derived-mode vc-hg-log-edit-mode log-edit-mode "Log-Edit/hg" 1184(define-derived-mode vc-hg-log-edit-mode log-edit-mode "Log-Edit/hg"
1186 "Major mode for editing Hg log messages. 1185 "Major mode for editing Hg log messages.
@@ -1262,9 +1261,7 @@ REV is the revision to check out into WORKFILE."
1262 1261
1263;;; Hg specific functionality. 1262;;; Hg specific functionality.
1264 1263
1265(defvar vc-hg-extra-menu-map 1264(defvar-keymap vc-hg-extra-menu-map)
1266 (let ((map (make-sparse-keymap)))
1267 map))
1268 1265
1269(defun vc-hg-extra-menu () vc-hg-extra-menu-map) 1266(defun vc-hg-extra-menu () vc-hg-extra-menu-map)
1270 1267
diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el
index 405c9bc2ca4..1f0eeb7e18a 100644
--- a/lisp/vc/vc-hooks.el
+++ b/lisp/vc/vc-hooks.el
@@ -855,38 +855,37 @@ In the latter case, VC mode is deactivated for this buffer."
855;; Autoloading works fine, but it prevents shortcuts from appearing 855;; Autoloading works fine, but it prevents shortcuts from appearing
856;; in the menu because they don't exist yet when the menu is built. 856;; in the menu because they don't exist yet when the menu is built.
857;; (autoload 'vc-prefix-map "vc" nil nil 'keymap) 857;; (autoload 'vc-prefix-map "vc" nil nil 'keymap)
858(defvar vc-prefix-map 858(defvar-keymap vc-prefix-map
859 (let ((map (make-sparse-keymap))) 859 "a" #'vc-update-change-log
860 (define-key map "a" #'vc-update-change-log) 860 "d" #'vc-dir
861 (with-suppressed-warnings ((obsolete vc-switch-backend)) 861 "g" #'vc-annotate
862 (define-key map "b" #'vc-switch-backend)) 862 "G" #'vc-ignore
863 (define-key map "d" #'vc-dir) 863 "h" #'vc-region-history
864 (define-key map "g" #'vc-annotate) 864 "i" #'vc-register
865 (define-key map "G" #'vc-ignore) 865 "l" #'vc-print-log
866 (define-key map "h" #'vc-region-history) 866 "L" #'vc-print-root-log
867 (define-key map "i" #'vc-register) 867 "I" #'vc-log-incoming
868 (define-key map "l" #'vc-print-log) 868 "O" #'vc-log-outgoing
869 (define-key map "L" #'vc-print-root-log) 869 "M L" #'vc-log-mergebase
870 (define-key map "I" #'vc-log-incoming) 870 "M D" #'vc-diff-mergebase
871 (define-key map "O" #'vc-log-outgoing) 871 "m" #'vc-merge
872 (define-key map "ML" #'vc-log-mergebase) 872 "r" #'vc-retrieve-tag
873 (define-key map "MD" #'vc-diff-mergebase) 873 "s" #'vc-create-tag
874 (define-key map "m" #'vc-merge) 874 "u" #'vc-revert
875 (define-key map "r" #'vc-retrieve-tag) 875 "v" #'vc-next-action
876 (define-key map "s" #'vc-create-tag) 876 "+" #'vc-update
877 (define-key map "u" #'vc-revert) 877 ;; I'd prefer some kind of symmetry with vc-update:
878 (define-key map "v" #'vc-next-action) 878 "P" #'vc-push
879 (define-key map "+" #'vc-update) 879 "=" #'vc-diff
880 ;; I'd prefer some kind of symmetry with vc-update: 880 "D" #'vc-root-diff
881 (define-key map "P" #'vc-push) 881 "~" #'vc-revision-other-window
882 (define-key map "=" #'vc-diff) 882 "x" #'vc-delete-file)
883 (define-key map "D" #'vc-root-diff)
884 (define-key map "~" #'vc-revision-other-window)
885 (define-key map "x" #'vc-delete-file)
886 map))
887(fset 'vc-prefix-map vc-prefix-map) 883(fset 'vc-prefix-map vc-prefix-map)
888(define-key ctl-x-map "v" 'vc-prefix-map) 884(define-key ctl-x-map "v" 'vc-prefix-map)
889 885
886(with-suppressed-warnings ((obsolete vc-switch-backend))
887 (keymap-set vc-prefix-map "b" #'vc-switch-backend))
888
890(defvar vc-menu-map 889(defvar vc-menu-map
891 (let ((map (make-sparse-keymap "Version Control"))) 890 (let ((map (make-sparse-keymap "Version Control")))
892 ;;(define-key map [show-files] 891 ;;(define-key map [show-files]
diff --git a/src/Makefile.in b/src/Makefile.in
index 92a8790efdc..a7024bda461 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -845,7 +845,6 @@ ifeq ($(HAVE_NATIVE_COMP):$(NATIVE_DISABLED),yes:)
845## List of *.eln files we need to produce in addition to the preloaded 845## List of *.eln files we need to produce in addition to the preloaded
846## ones in $(lisp). 846## ones in $(lisp).
847elnlisp := \ 847elnlisp := \
848 emacs-lisp/autoload.eln \
849 emacs-lisp/byte-opt.eln \ 848 emacs-lisp/byte-opt.eln \
850 emacs-lisp/bytecomp.eln \ 849 emacs-lisp/bytecomp.eln \
851 emacs-lisp/cconv.eln \ 850 emacs-lisp/cconv.eln \
diff --git a/src/buffer.c b/src/buffer.c
index e5601af5051..98066a2eb60 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1160,7 +1160,8 @@ is first appended to NAME, to speed up finding a non-existent buffer. */)
1160 genbase = name; 1160 genbase = name;
1161 else 1161 else
1162 { 1162 {
1163 char number[sizeof "-999999"]; 1163 enum { bug_52711 = true }; /* https://bugs.gnu.org/57211 */
1164 char number[bug_52711 ? INT_BUFSIZE_BOUND (int) + 1 : sizeof "-999999"];
1164 EMACS_INT r = get_random (); 1165 EMACS_INT r = get_random ();
1165 eassume (0 <= r); 1166 eassume (0 <= r);
1166 int i = r % 1000000; 1167 int i = r % 1000000;
@@ -6442,6 +6443,24 @@ If nil, these display shortcuts will always remain disabled.
6442There is no reason to change that value except for debugging purposes. */); 6443There is no reason to change that value except for debugging purposes. */);
6443 XSETFASTINT (Vlong_line_threshold, 10000); 6444 XSETFASTINT (Vlong_line_threshold, 10000);
6444 6445
6446 DEFVAR_INT ("large-hscroll-threshold", large_hscroll_threshold,
6447 doc: /* Horizontal scroll of truncated lines above which to use redisplay shortcuts.
6448
6449The value should be a positive integer.
6450
6451Shortcuts in the display code intended to speed up redisplay for long
6452and truncated lines will automatically be enabled when a line's
6453horizontal scroll amount is or about to become larger than the value
6454of this variable.
6455
6456This variable has effect only in buffers which contain one or more
6457lines whose length is above `long-line-threshold', which see.
6458To disable redisplay shortcuts for long truncated line, set this
6459variable to `most-positive-fixnum'.
6460
6461There is no reason to change that value except for debugging purposes. */);
6462 large_hscroll_threshold = 10000;
6463
6445 defsubr (&Sbuffer_live_p); 6464 defsubr (&Sbuffer_live_p);
6446 defsubr (&Sbuffer_list); 6465 defsubr (&Sbuffer_list);
6447 defsubr (&Sget_buffer); 6466 defsubr (&Sget_buffer);
diff --git a/src/eval.c b/src/eval.c
index d82d05797b2..56b42966623 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -57,6 +57,12 @@ Lisp_Object Vrun_hooks;
57/* FIXME: We should probably get rid of this! */ 57/* FIXME: We should probably get rid of this! */
58Lisp_Object Vsignaling_function; 58Lisp_Object Vsignaling_function;
59 59
60/* The handler structure which will catch errors in Lisp hooks called
61 from redisplay. We do not use it for this; we compare it with the
62 handler which is about to be used in signal_or_quit, and if it
63 matches, cause a backtrace to be generated. */
64static struct handler *redisplay_deep_handler;
65
60/* These would ordinarily be static, but they need to be visible to GDB. */ 66/* These would ordinarily be static, but they need to be visible to GDB. */
61bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE; 67bool backtrace_p (union specbinding *) EXTERNALLY_VISIBLE;
62Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE; 68Lisp_Object *backtrace_args (union specbinding *) EXTERNALLY_VISIBLE;
@@ -246,6 +252,7 @@ init_eval (void)
246 lisp_eval_depth = 0; 252 lisp_eval_depth = 0;
247 /* This is less than the initial value of num_nonmacro_input_events. */ 253 /* This is less than the initial value of num_nonmacro_input_events. */
248 when_entered_debugger = -1; 254 when_entered_debugger = -1;
255 redisplay_deep_handler = NULL;
249} 256}
250 257
251/* Ensure that *M is at least A + B if possible, or is its maximum 258/* Ensure that *M is at least A + B if possible, or is its maximum
@@ -333,7 +340,8 @@ call_debugger (Lisp_Object arg)
333 /* Interrupting redisplay and resuming it later is not safe under 340 /* Interrupting redisplay and resuming it later is not safe under
334 all circumstances. So, when the debugger returns, abort the 341 all circumstances. So, when the debugger returns, abort the
335 interrupted redisplay by going back to the top-level. */ 342 interrupted redisplay by going back to the top-level. */
336 if (debug_while_redisplaying) 343 if (debug_while_redisplaying
344 && !EQ (Vdebugger, Qdebug_early))
337 Ftop_level (); 345 Ftop_level ();
338 346
339 return unbind_to (count, val); 347 return unbind_to (count, val);
@@ -1556,12 +1564,16 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
1556 ptrdiff_t nargs, 1564 ptrdiff_t nargs,
1557 Lisp_Object *args)) 1565 Lisp_Object *args))
1558{ 1566{
1567 struct handler *old_deep = redisplay_deep_handler;
1559 struct handler *c = push_handler (handlers, CONDITION_CASE); 1568 struct handler *c = push_handler (handlers, CONDITION_CASE);
1569 if (redisplaying_p)
1570 redisplay_deep_handler = c;
1560 if (sys_setjmp (c->jmp)) 1571 if (sys_setjmp (c->jmp))
1561 { 1572 {
1562 Lisp_Object val = handlerlist->val; 1573 Lisp_Object val = handlerlist->val;
1563 clobbered_eassert (handlerlist == c); 1574 clobbered_eassert (handlerlist == c);
1564 handlerlist = handlerlist->next; 1575 handlerlist = handlerlist->next;
1576 redisplay_deep_handler = old_deep;
1565 return hfun (val, nargs, args); 1577 return hfun (val, nargs, args);
1566 } 1578 }
1567 else 1579 else
@@ -1569,6 +1581,7 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *),
1569 Lisp_Object val = bfun (nargs, args); 1581 Lisp_Object val = bfun (nargs, args);
1570 eassert (handlerlist == c); 1582 eassert (handlerlist == c);
1571 handlerlist = c->next; 1583 handlerlist = c->next;
1584 redisplay_deep_handler = old_deep;
1572 return val; 1585 return val;
1573 } 1586 }
1574} 1587}
@@ -1701,6 +1714,11 @@ quit (void)
1701 return signal_or_quit (Qquit, Qnil, true); 1714 return signal_or_quit (Qquit, Qnil, true);
1702} 1715}
1703 1716
1717/* Has an error in redisplay giving rise to a backtrace occurred as
1718 yet in the current command? This gets reset in the command
1719 loop. */
1720bool backtrace_yet = false;
1721
1704/* Signal an error, or quit. ERROR_SYMBOL and DATA are as with Fsignal. 1722/* Signal an error, or quit. ERROR_SYMBOL and DATA are as with Fsignal.
1705 If KEYBOARD_QUIT, this is a quit; ERROR_SYMBOL should be 1723 If KEYBOARD_QUIT, this is a quit; ERROR_SYMBOL should be
1706 Qquit and DATA should be Qnil, and this function may return. 1724 Qquit and DATA should be Qnil, and this function may return.
@@ -1816,6 +1834,40 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool keyboard_quit)
1816 unbind_to (count, Qnil); 1834 unbind_to (count, Qnil);
1817 } 1835 }
1818 1836
1837 /* If an error is signalled during a Lisp hook in redisplay, write a
1838 backtrace into the buffer *Redisplay-trace*. */
1839 if (!debugger_called && !NILP (error_symbol)
1840 && backtrace_on_redisplay_error
1841 && (NILP (clause) || h == redisplay_deep_handler)
1842 && NILP (Vinhibit_debugger)
1843 && !NILP (Ffboundp (Qdebug_early)))
1844 {
1845 max_ensure_room (&max_lisp_eval_depth, lisp_eval_depth, 100);
1846 specpdl_ref count = SPECPDL_INDEX ();
1847 ptrdiff_t counti = specpdl_ref_to_count (count);
1848 AUTO_STRING (redisplay_trace, "*Redisplay_trace*");
1849 Lisp_Object redisplay_trace_buffer;
1850 AUTO_STRING (gap, "\n\n\n\n"); /* Separates things in *Redisplay-trace* */
1851 Lisp_Object delayed_warning;
1852 max_ensure_room (&max_specpdl_size, counti, 200);
1853 redisplay_trace_buffer = Fget_buffer_create (redisplay_trace, Qnil);
1854 current_buffer = XBUFFER (redisplay_trace_buffer);
1855 if (!backtrace_yet) /* Are we on the first backtrace of the command? */
1856 Ferase_buffer ();
1857 else
1858 Finsert (1, &gap);
1859 backtrace_yet = true;
1860 specbind (Qstandard_output, redisplay_trace_buffer);
1861 specbind (Qdebugger, Qdebug_early);
1862 call_debugger (list2 (Qerror, Fcons (error_symbol, data)));
1863 unbind_to (count, Qnil);
1864 delayed_warning = make_string
1865 ("Error in a redisplay Lisp hook. See buffer *Redisplay_trace*", 61);
1866
1867 Vdelayed_warnings_list = Fcons (list2 (Qerror, delayed_warning),
1868 Vdelayed_warnings_list);
1869 }
1870
1819 if (!NILP (clause)) 1871 if (!NILP (clause))
1820 { 1872 {
1821 Lisp_Object unwind_data 1873 Lisp_Object unwind_data
@@ -4278,6 +4330,11 @@ Does not apply if quit is handled by a `condition-case'. */);
4278 DEFVAR_BOOL ("debug-on-next-call", debug_on_next_call, 4330 DEFVAR_BOOL ("debug-on-next-call", debug_on_next_call,
4279 doc: /* Non-nil means enter debugger before next `eval', `apply' or `funcall'. */); 4331 doc: /* Non-nil means enter debugger before next `eval', `apply' or `funcall'. */);
4280 4332
4333 DEFVAR_BOOL ("backtrace-on-redisplay-error", backtrace_on_redisplay_error,
4334 doc: /* Non-nil means create a backtrace if a lisp error occurs in redisplay.
4335The backtrace is written to buffer *Redisplay-trace*. */);
4336 backtrace_on_redisplay_error = false;
4337
4281 DEFVAR_BOOL ("debugger-may-continue", debugger_may_continue, 4338 DEFVAR_BOOL ("debugger-may-continue", debugger_may_continue,
4282 doc: /* Non-nil means debugger may continue execution. 4339 doc: /* Non-nil means debugger may continue execution.
4283This is nil when the debugger is called under circumstances where it 4340This is nil when the debugger is called under circumstances where it
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 119ec284094..e089f9dea85 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -677,7 +677,11 @@ ftcrhbfont_begin_hb_font (struct font *font, double *position_unit)
677 677
678 ftcrfont_info->ft_size = ft_face->size; 678 ftcrfont_info->ft_size = ft_face->size;
679 hb_font_t *hb_font = fthbfont_begin_hb_font (font, position_unit); 679 hb_font_t *hb_font = fthbfont_begin_hb_font (font, position_unit);
680 if (ftcrfont_info->bitmap_position_unit) 680 /* HarfBuzz 5 correctly scales bitmap-only fonts without position
681 unit adjustment.
682 (https://github.com/harfbuzz/harfbuzz/issues/489) */
683 if (!hb_version_atleast (5, 0, 0)
684 && ftcrfont_info->bitmap_position_unit)
681 *position_unit = ftcrfont_info->bitmap_position_unit; 685 *position_unit = ftcrfont_info->bitmap_position_unit;
682 686
683 return hb_font; 687 return hb_font;
diff --git a/src/indent.c b/src/indent.c
index d2dfaee254e..cb368024d97 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -306,8 +306,8 @@ and point (e.g., control characters will have a width of 2 or 4, tabs
306will have a variable width). 306will have a variable width).
307Ignores finite width of frame, which means that this function may return 307Ignores finite width of frame, which means that this function may return
308values greater than (frame-width). 308values greater than (frame-width).
309In a buffer with very long lines, the value can be zero, because calculating 309In a buffer with very long lines, the value will be an approximation,
310the exact number is very expensive. 310because calculating the exact number is very expensive.
311Whether the line is visible (if `selective-display' is t) has no effect; 311Whether the line is visible (if `selective-display' is t) has no effect;
312however, ^M is treated as end of line when `selective-display' is t. 312however, ^M is treated as end of line when `selective-display' is t.
313Text that has an invisible property is considered as having width 0, unless 313Text that has an invisible property is considered as having width 0, unless
@@ -316,8 +316,6 @@ Text that has an invisible property is considered as having width 0, unless
316{ 316{
317 Lisp_Object temp; 317 Lisp_Object temp;
318 318
319 if (current_buffer->long_line_optimizations_p)
320 return make_fixnum (0);
321 XSETFASTINT (temp, current_column ()); 319 XSETFASTINT (temp, current_column ());
322 return temp; 320 return temp;
323} 321}
@@ -346,6 +344,14 @@ current_column (void)
346 && MODIFF == last_known_column_modified) 344 && MODIFF == last_known_column_modified)
347 return last_known_column; 345 return last_known_column;
348 346
347 ptrdiff_t line_beg = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1,
348 NULL, NULL, 1);
349
350 /* Avoid becoming abysmally slow for very long lines. */
351 if (current_buffer->long_line_optimizations_p
352 && !NILP (Vlong_line_threshold)
353 && PT - line_beg > XFIXNUM (Vlong_line_threshold))
354 return PT - line_beg; /* this is an approximation! */
349 /* If the buffer has overlays, text properties, 355 /* If the buffer has overlays, text properties,
350 or multibyte characters, use a more general algorithm. */ 356 or multibyte characters, use a more general algorithm. */
351 if (buffer_intervals (current_buffer) 357 if (buffer_intervals (current_buffer)
@@ -561,13 +567,53 @@ scan_for_column (ptrdiff_t *endpos, EMACS_INT *goalcol,
561 ptrdiff_t scan, scan_byte, next_boundary, prev_pos, prev_bpos; 567 ptrdiff_t scan, scan_byte, next_boundary, prev_pos, prev_bpos;
562 568
563 scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1); 569 scan = find_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -1, NULL, &scan_byte, 1);
564 next_boundary = scan;
565 prev_pos = scan;
566 prev_bpos = scan_byte;
567 570
568 window = Fget_buffer_window (Fcurrent_buffer (), Qnil); 571 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
569 w = ! NILP (window) ? XWINDOW (window) : NULL; 572 w = ! NILP (window) ? XWINDOW (window) : NULL;
570 573
574 if (current_buffer->long_line_optimizations_p)
575 {
576 bool lines_truncated = false;
577
578 if (!NILP (BVAR (current_buffer, truncate_lines)))
579 lines_truncated = true;
580 else if (w && FIXNUMP (Vtruncate_partial_width_windows))
581 lines_truncated =
582 w->total_cols < XFIXNAT (Vtruncate_partial_width_windows);
583 else if (w && !NILP (Vtruncate_partial_width_windows))
584 lines_truncated =
585 w->total_cols < FRAME_COLS (XFRAME (WINDOW_FRAME (w)));
586 /* Special optimization for buffers with long and truncated
587 lines: assumes that each character is a single column. */
588 if (lines_truncated)
589 {
590 ptrdiff_t bolpos = scan;
591 /* The newline which ends this line or ZV. */
592 ptrdiff_t eolpos =
593 find_newline (PT, PT_BYTE, ZV, ZV_BYTE, 1, NULL, NULL, 1);
594
595 scan = bolpos + goal;
596 if (scan > end)
597 scan = end;
598 if (scan > eolpos)
599 scan = (eolpos == ZV ? ZV : eolpos - 1);
600 col = scan - bolpos;
601 if (col > large_hscroll_threshold)
602 {
603 prev_col = col - 1;
604 prev_pos = scan - 1;
605 prev_bpos = CHAR_TO_BYTE (scan);
606 goto endloop;
607 }
608 /* Restore the values we've overwritten above. */
609 scan = bolpos;
610 col = 0;
611 }
612 }
613 next_boundary = scan;
614 prev_pos = scan;
615 prev_bpos = scan_byte;
616
571 memset (&cmp_it, 0, sizeof cmp_it); 617 memset (&cmp_it, 0, sizeof cmp_it);
572 cmp_it.id = -1; 618 cmp_it.id = -1;
573 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil); 619 composition_compute_stop_pos (&cmp_it, scan, scan_byte, end, Qnil);
diff --git a/src/keyboard.c b/src/keyboard.c
index 4ad6e4e6bd1..8a2b7d58c4b 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1331,6 +1331,7 @@ command_loop_1 (void)
1331 display_malloc_warning (); 1331 display_malloc_warning ();
1332 1332
1333 Vdeactivate_mark = Qnil; 1333 Vdeactivate_mark = Qnil;
1334 backtrace_yet = false;
1334 1335
1335 /* Don't ignore mouse movements for more than a single command 1336 /* Don't ignore mouse movements for more than a single command
1336 loop. (This flag is set in xdisp.c whenever the tool bar is 1337 loop. (This flag is set in xdisp.c whenever the tool bar is
@@ -1841,7 +1842,7 @@ safe_run_hooks_1 (ptrdiff_t nargs, Lisp_Object *args)
1841static Lisp_Object 1842static Lisp_Object
1842safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) 1843safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args)
1843{ 1844{
1844 eassert (nargs == 2); 1845 eassert (nargs >= 2 && nargs <= 4);
1845 AUTO_STRING (format, "Error in %s (%S): %S"); 1846 AUTO_STRING (format, "Error in %s (%S): %S");
1846 Lisp_Object hook = args[0]; 1847 Lisp_Object hook = args[0];
1847 Lisp_Object fun = args[1]; 1848 Lisp_Object fun = args[1];
@@ -1915,6 +1916,17 @@ safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
1915 unbind_to (count, Qnil); 1916 unbind_to (count, Qnil);
1916} 1917}
1917 1918
1919void
1920safe_run_hooks_2 (Lisp_Object hook, Lisp_Object arg1, Lisp_Object arg2)
1921{
1922 specpdl_ref count = SPECPDL_INDEX ();
1923
1924 specbind (Qinhibit_quit, Qt);
1925 run_hook_with_args (4, ((Lisp_Object []) {hook, hook, arg1, arg2}),
1926 safe_run_hook_funcall);
1927 unbind_to (count, Qnil);
1928}
1929
1918 1930
1919/* Nonzero means polling for input is temporarily suppressed. */ 1931/* Nonzero means polling for input is temporarily suppressed. */
1920 1932
@@ -12638,10 +12650,17 @@ cancels any modification. */);
12638 12650
12639 DEFSYM (Qdeactivate_mark, "deactivate-mark"); 12651 DEFSYM (Qdeactivate_mark, "deactivate-mark");
12640 DEFVAR_LISP ("deactivate-mark", Vdeactivate_mark, 12652 DEFVAR_LISP ("deactivate-mark", Vdeactivate_mark,
12641 doc: /* If an editing command sets this to t, deactivate the mark afterward. 12653 doc: /* Whether to deactivate the mark after an editing command.
12642The command loop sets this to nil before each command, 12654The command loop sets this to nil before each command,
12643and tests the value when the command returns. 12655and tests the value when the command returns.
12644Buffer modification stores t in this variable. */); 12656If an editing command sets this non-nil, deactivate the mark after
12657the command returns.
12658
12659Buffer modifications store t in this variable.
12660
12661By default, deactivating the mark will save the contents of the region
12662according to `select-active-regions', unless this is set to the symbol
12663`dont-save'. */);
12645 Vdeactivate_mark = Qnil; 12664 Vdeactivate_mark = Qnil;
12646 Fmake_variable_buffer_local (Qdeactivate_mark); 12665 Fmake_variable_buffer_local (Qdeactivate_mark);
12647 12666
diff --git a/src/lisp.h b/src/lisp.h
index fe6e98843d1..2f73ba4c617 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4530,6 +4530,7 @@ extern Lisp_Object Vrun_hooks;
4530extern Lisp_Object Vsignaling_function; 4530extern Lisp_Object Vsignaling_function;
4531extern Lisp_Object inhibit_lisp_code; 4531extern Lisp_Object inhibit_lisp_code;
4532extern bool signal_quit_p (Lisp_Object); 4532extern bool signal_quit_p (Lisp_Object);
4533extern bool backtrace_yet;
4533 4534
4534/* To run a normal hook, use the appropriate function from the list below. 4535/* To run a normal hook, use the appropriate function from the list below.
4535 The calling convention: 4536 The calling convention:
@@ -4831,6 +4832,7 @@ extern bool detect_input_pending_ignore_squeezables (void);
4831extern bool detect_input_pending_run_timers (bool); 4832extern bool detect_input_pending_run_timers (bool);
4832extern void safe_run_hooks (Lisp_Object); 4833extern void safe_run_hooks (Lisp_Object);
4833extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *); 4834extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
4835extern void safe_run_hooks_2 (Lisp_Object, Lisp_Object, Lisp_Object);
4834extern void cmd_error_internal (Lisp_Object, const char *); 4836extern void cmd_error_internal (Lisp_Object, const char *);
4835extern Lisp_Object command_loop_2 (Lisp_Object); 4837extern Lisp_Object command_loop_2 (Lisp_Object);
4836extern Lisp_Object read_menu_command (void); 4838extern Lisp_Object read_menu_command (void);
diff --git a/src/timefns.c b/src/timefns.c
index 1112f174763..eed2edf1cc0 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -401,6 +401,10 @@ decode_float_time (double t, struct lisp_time *result)
401 else 401 else
402 { 402 {
403 int scale = double_integer_scale (t); 403 int scale = double_integer_scale (t);
404 /* FIXME: `double_integer_scale` often returns values that are
405 "pessimistic" (i.e. larger than necessary), so 3.5 gets converted
406 to (7881299347898368 . 2251799813685248) rather than (7 . 2).
407 On 64bit systems, this should not matter very much, tho. */
404 eassume (scale < flt_radix_power_size); 408 eassume (scale < flt_radix_power_size);
405 409
406 if (scale < 0) 410 if (scale < 0)
@@ -818,17 +822,6 @@ decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only,
818 822
819 if (NILP (specified_time)) 823 if (NILP (specified_time))
820 form = TIMEFORM_NIL; 824 form = TIMEFORM_NIL;
821 else if (FLOATP (specified_time))
822 {
823 double d = XFLOAT_DATA (specified_time);
824 if (!isfinite (d))
825 time_error (isnan (d) ? EDOM : EOVERFLOW);
826 if (result)
827 decode_float_time (d, result);
828 else
829 *dresult = d;
830 return TIMEFORM_FLOAT;
831 }
832 else if (CONSP (specified_time)) 825 else if (CONSP (specified_time))
833 { 826 {
834 high = XCAR (specified_time); 827 high = XCAR (specified_time);
@@ -868,6 +861,22 @@ decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only,
868 if (! INTEGERP (low)) 861 if (! INTEGERP (low))
869 form = TIMEFORM_INVALID; 862 form = TIMEFORM_INVALID;
870 } 863 }
864 else if (FASTER_TIMEFNS && INTEGERP (specified_time))
865 {
866 decode_ticks_hz (specified_time, make_fixnum (1), result, dresult);
867 return form;
868 }
869 else if (FLOATP (specified_time))
870 {
871 double d = XFLOAT_DATA (specified_time);
872 if (!isfinite (d))
873 time_error (isnan (d) ? EDOM : EOVERFLOW);
874 if (result)
875 decode_float_time (d, result);
876 else
877 *dresult = d;
878 return TIMEFORM_FLOAT;
879 }
871 880
872 int err = decode_time_components (form, high, low, usec, psec, 881 int err = decode_time_components (form, high, low, usec, psec,
873 result, dresult); 882 result, dresult);
@@ -1202,10 +1211,16 @@ time_cmp (Lisp_Object a, Lisp_Object b)
1202 return 0; 1211 return 0;
1203 1212
1204 /* Compare (X . Z) to (Y . Z) quickly if X and Y are fixnums. 1213 /* Compare (X . Z) to (Y . Z) quickly if X and Y are fixnums.
1205 Do not inspect Z, as it is OK to not signal if A and B are invalid. */ 1214 Do not inspect Z, as it is OK to not signal if A and B are invalid.
1206 if (FASTER_TIMEFNS && CONSP (a) && CONSP (b) && BASE_EQ (XCDR (a), XCDR (b)) 1215 Also, compare X to Y quickly if X and Y are fixnums. */
1207 && FIXNUMP (XCAR (a)) && FIXNUMP (XCAR (b))) 1216 if (FASTER_TIMEFNS)
1208 return XFIXNUM (XCAR (a)) - XFIXNUM (XCAR (b)); 1217 {
1218 Lisp_Object x = a, y = b;
1219 if (CONSP (a) && CONSP (b) && BASE_EQ (XCDR (a), XCDR (b)))
1220 x = XCAR (a), y = XCAR (b);
1221 if (FIXNUMP (x) && FIXNUMP (y))
1222 return XFIXNUM (x) - XFIXNUM (y);
1223 }
1209 1224
1210 /* Compare (ATICKS . AZ) to (BTICKS . BHZ) by comparing 1225 /* Compare (ATICKS . AZ) to (BTICKS . BHZ) by comparing
1211 ATICKS * BHZ to BTICKS * AHZ. */ 1226 ATICKS * BHZ to BTICKS * AHZ. */
@@ -1714,21 +1729,29 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
1714} 1729}
1715 1730
1716DEFUN ("time-convert", Ftime_convert, Stime_convert, 1, 2, 0, 1731DEFUN ("time-convert", Ftime_convert, Stime_convert, 1, 2, 0,
1717 doc: /* Convert TIME value to a Lisp timestamp. 1732 doc: /* Convert TIME value to a Lisp timestamp of the given FORM.
1718With optional FORM, convert to that timestamp form.
1719Truncate the returned value toward minus infinity. 1733Truncate the returned value toward minus infinity.
1720 1734
1721If FORM is nil (the default), return the same form as `current-time'.
1722If FORM is a positive integer, return a pair of integers (TICKS . FORM), 1735If FORM is a positive integer, return a pair of integers (TICKS . FORM),
1723where TICKS is the number of clock ticks and FORM is the clock frequency 1736where TICKS is the number of clock ticks and FORM is the clock frequency
1724in ticks per second. If FORM is t, return (TICKS . PHZ), where 1737in ticks per second.
1725PHZ is a suitable clock frequency in ticks per second. If FORM is 1738
1726`integer', return an integer count of seconds. If FORM is `list', 1739If FORM is t, return (TICKS . PHZ), where PHZ is a suitable clock
1727return an integer list (HIGH LOW USEC PSEC), where HIGH has the most 1740frequency in ticks per second.
1728significant bits of the seconds, LOW has the least significant 16 1741
1729bits, and USEC and PSEC are the microsecond and picosecond counts. */) 1742If FORM is `integer', return an integer count of seconds.
1743
1744If FORM is `list', return an integer list (HIGH LOW USEC PSEC), where
1745HIGH has the most significant bits of the seconds, LOW has the least
1746significant 16 bits, and USEC and PSEC are the microsecond and
1747picosecond counts.
1748
1749If FORM is nil, the behavior depends on `current-time-list',
1750but new code should not rely on it. */)
1730 (Lisp_Object time, Lisp_Object form) 1751 (Lisp_Object time, Lisp_Object form)
1731{ 1752{
1753 /* FIXME: Any reason why we don't offer a `float` output format option as
1754 well, since we accept it as input? */
1732 struct lisp_time t; 1755 struct lisp_time t;
1733 enum timeform input_form = decode_lisp_time (time, false, &t, 0); 1756 enum timeform input_form = decode_lisp_time (time, false, &t, 0);
1734 if (NILP (form)) 1757 if (NILP (form))
diff --git a/src/window.c b/src/window.c
index afb8f75537b..c8fcb3a607f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6575,9 +6575,12 @@ and redisplay normally--don't erase and redraw the frame. */)
6575 in case scroll_margin is buffer-local. */ 6575 in case scroll_margin is buffer-local. */
6576 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES); 6576 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_LINES);
6577 6577
6578 /* Don't use redisplay code for initial frames, as the necessary 6578 /* Don't use the display code for initial frames, as the necessary
6579 data structures might not be set up yet then. */ 6579 data structures might not be set up yet then. Also don't use it
6580 if (!FRAME_INITIAL_P (XFRAME (w->frame))) 6580 for buffers with very long lines, as it tremdously slows down
6581 redisplay, especially when lines are truncated. */
6582 if (!FRAME_INITIAL_P (XFRAME (w->frame))
6583 && !current_buffer->long_line_optimizations_p)
6581 { 6584 {
6582 specpdl_ref count = SPECPDL_INDEX (); 6585 specpdl_ref count = SPECPDL_INDEX ();
6583 6586
diff --git a/src/xdisp.c b/src/xdisp.c
index 1fcff2c2e3b..1e8f70b2db9 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11040,6 +11040,15 @@ move_it_by_lines (struct it *it, ptrdiff_t dvpos)
11040int 11040int
11041partial_line_height (struct it *it_origin) 11041partial_line_height (struct it *it_origin)
11042{ 11042{
11043 /* In a buffer with very long and truncated lines, we ignore the
11044 possibly-partial height of the last line in the window: it is too
11045 expensive to compute that (since in most cases that involves
11046 going all the way to ZV), and the effect of ignoring it is
11047 relatively minor. */
11048 if (XBUFFER (it_origin->w->contents)->long_line_optimizations_p
11049 && it_origin->line_wrap == TRUNCATE)
11050 return 0;
11051
11043 int partial_height; 11052 int partial_height;
11044 void *it_data = NULL; 11053 void *it_data = NULL;
11045 struct it it; 11054 struct it it;
@@ -11063,6 +11072,51 @@ partial_line_height (struct it *it_origin)
11063 return partial_height; 11072 return partial_height;
11064} 11073}
11065 11074
11075/* Approximate move_it_in_display_line_to for very long and truncated
11076 display lines, when moving horizontally. This is used when the
11077 buffer's long_line_optimizations_p flag is set. It ignores various
11078 complications, like different font sizes, invisible text, display
11079 and overlay strings, and, to some degree, bidirectional text. So
11080 caveat emptor!
11081
11082 Starting from IT's position, reseat IT after skipping NCHARS
11083 characters or to the next newline/ZV, whichever comes first. Return
11084 what move_it_in_display_line_to would have returned in this case. */
11085
11086static enum move_it_result
11087fast_move_it_horizontally (struct it *it, ptrdiff_t nchars)
11088{
11089 ptrdiff_t nl_bytepos;
11090 ptrdiff_t nl_pos = find_newline_no_quit (IT_CHARPOS (*it), IT_BYTEPOS (*it),
11091 1, &nl_bytepos);
11092 struct text_pos new_pos;
11093 enum move_it_result move_result;
11094
11095 if (nl_pos - IT_CHARPOS (*it) > nchars)
11096 {
11097 SET_TEXT_POS (new_pos,
11098 IT_CHARPOS (*it) + nchars,
11099 CHAR_TO_BYTE (IT_CHARPOS (*it) + nchars));
11100 move_result = MOVE_X_REACHED;
11101 }
11102 else
11103 {
11104 if (nl_bytepos < ZV_BYTE
11105 || (nl_bytepos > BEGV_BYTE
11106 && FETCH_BYTE (nl_bytepos - 1) == '\n'))
11107 {
11108 nl_pos--;
11109 nl_bytepos--;
11110 move_result = MOVE_NEWLINE_OR_CR;
11111 }
11112 else
11113 move_result = MOVE_POS_MATCH_OR_ZV;
11114 SET_TEXT_POS (new_pos, nl_pos, nl_bytepos);
11115 }
11116 reseat (it, new_pos, false);
11117 return move_result;
11118}
11119
11066/* Return true if IT points into the middle of a display vector. */ 11120/* Return true if IT points into the middle of a display vector. */
11067 11121
11068bool 11122bool
@@ -13106,8 +13160,7 @@ mode_line_update_needed (struct window *w)
13106{ 13160{
13107 return (w->column_number_displayed != -1 13161 return (w->column_number_displayed != -1
13108 && !(PT == w->last_point && !window_outdated (w)) 13162 && !(PT == w->last_point && !window_outdated (w))
13109 && (!current_buffer->long_line_optimizations_p 13163 && (w->column_number_displayed != current_column ()));
13110 && w->column_number_displayed != current_column ()));
13111} 13164}
13112 13165
13113/* True if window start of W is frozen and may not be changed during 13166/* True if window start of W is frozen and may not be changed during
@@ -15776,7 +15829,20 @@ hscroll_window_tree (Lisp_Object window)
15776 it.first_visible_x = window_hscroll_limited (w, it.f) 15829 it.first_visible_x = window_hscroll_limited (w, it.f)
15777 * FRAME_COLUMN_WIDTH (it.f); 15830 * FRAME_COLUMN_WIDTH (it.f);
15778 it.last_visible_x = DISP_INFINITY; 15831 it.last_visible_x = DISP_INFINITY;
15779 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS); 15832
15833 ptrdiff_t nchars = pt - IT_CHARPOS (it);
15834 if (current_buffer->long_line_optimizations_p
15835 && nchars > large_hscroll_threshold)
15836 {
15837 /* Special optimization for very long and truncated
15838 lines which need to be hscrolled far to the left:
15839 jump directly to the (approximate) first position
15840 that is visible, instead of slowly walking there. */
15841 fast_move_it_horizontally (&it, nchars);
15842 it.current_x += nchars * FRAME_COLUMN_WIDTH (it.f);
15843 }
15844 else
15845 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
15780 /* If the line ends in an overlay string with a newline, 15846 /* If the line ends in an overlay string with a newline,
15781 we might infloop, because displaying the window will 15847 we might infloop, because displaying the window will
15782 want to put the cursor after the overlay, i.e. at X 15848 want to put the cursor after the overlay, i.e. at X
@@ -15789,7 +15855,14 @@ hscroll_window_tree (Lisp_Object window)
15789 if (hscl) 15855 if (hscl)
15790 it.first_visible_x = (window_hscroll_limited (w, it.f) 15856 it.first_visible_x = (window_hscroll_limited (w, it.f)
15791 * FRAME_COLUMN_WIDTH (it.f)); 15857 * FRAME_COLUMN_WIDTH (it.f));
15792 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS); 15858 if (current_buffer->long_line_optimizations_p
15859 && nchars > large_hscroll_threshold)
15860 {
15861 fast_move_it_horizontally (&it, nchars - 1);
15862 it.current_x += (nchars - 1) * FRAME_COLUMN_WIDTH (it.f);
15863 }
15864 else
15865 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS);
15793 } 15866 }
15794 current_buffer = saved_current_buffer; 15867 current_buffer = saved_current_buffer;
15795 15868
@@ -16727,9 +16800,23 @@ redisplay_internal (void)
16727 it.current_y = this_line_y; 16800 it.current_y = this_line_y;
16728 it.vpos = this_line_vpos; 16801 it.vpos = this_line_vpos;
16729 16802
16730 /* The call to move_it_to stops in front of PT, but 16803 if (current_buffer->long_line_optimizations_p
16731 moves over before-strings. */ 16804 && it.line_wrap == TRUNCATE
16732 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); 16805 && PT - CHARPOS (tlbufpos) > large_hscroll_threshold)
16806 {
16807 /* When lines are very long and truncated, jumping to
16808 the next visible line is much faster than slowly
16809 iterating there. */
16810 reseat_at_next_visible_line_start (&it, false);
16811 if (IT_CHARPOS (it) <= PT) /* point moved off this line */
16812 it.vpos = this_line_vpos + 1;
16813 }
16814 else
16815 {
16816 /* The call to move_it_to stops in front of PT, but
16817 moves over before-strings. */
16818 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
16819 }
16733 16820
16734 if (it.vpos == this_line_vpos 16821 if (it.vpos == this_line_vpos
16735 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos), 16822 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
@@ -18119,8 +18206,8 @@ run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
18119 { 18206 {
18120 specpdl_ref count = SPECPDL_INDEX (); 18207 specpdl_ref count = SPECPDL_INDEX ();
18121 specbind (Qinhibit_quit, Qt); 18208 specbind (Qinhibit_quit, Qt);
18122 run_hook_with_args_2 (Qwindow_scroll_functions, window, 18209 safe_run_hooks_2
18123 make_fixnum (CHARPOS (startp))); 18210 (Qwindow_scroll_functions, window, make_fixnum (CHARPOS (startp)));
18124 unbind_to (count, Qnil); 18211 unbind_to (count, Qnil);
18125 SET_TEXT_POS_FROM_MARKER (startp, w->start); 18212 SET_TEXT_POS_FROM_MARKER (startp, w->start);
18126 /* In case the hook functions switch buffers. */ 18213 /* In case the hook functions switch buffers. */
@@ -19229,6 +19316,16 @@ window_start_acceptable_p (Lisp_Object window, ptrdiff_t startp)
19229 return true; 19316 return true;
19230} 19317}
19231 19318
19319DEFUN ("long-line-optimizations-p", Flong_line_optimizations_p, Slong_line_optimizations_p,
19320 0, 0, 0,
19321 doc: /* Return non-nil if long-line optimizations are in effect in current buffer.
19322See `long-line-threshold' and `large-hscroll-threshold' for what these
19323optimizations mean and when they are in effect. */)
19324 (void)
19325{
19326 return current_buffer->long_line_optimizations_p ? Qt : Qnil;
19327}
19328
19232/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only 19329/* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
19233 selected_window is redisplayed. 19330 selected_window is redisplayed.
19234 19331
@@ -19504,33 +19601,36 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
19504 ptrdiff_t it_charpos; 19601 ptrdiff_t it_charpos;
19505 19602
19506 w->optional_new_start = false; 19603 w->optional_new_start = false;
19507 start_display (&it, w, startp); 19604 if (!w->force_start)
19508 move_it_to (&it, PT, 0, it.last_visible_y, -1, 19605 {
19509 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); 19606 start_display (&it, w, startp);
19510 /* Record IT's position now, since line_bottom_y might change 19607 move_it_to (&it, PT, 0, it.last_visible_y, -1,
19511 that. */ 19608 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
19512 it_charpos = IT_CHARPOS (it); 19609 /* Record IT's position now, since line_bottom_y might
19513 /* Make sure we set the force_start flag only if the cursor row 19610 change that. */
19514 will be fully visible. Otherwise, the code under force_start 19611 it_charpos = IT_CHARPOS (it);
19515 label below will try to move point back into view, which is 19612 /* Make sure we set the force_start flag only if the cursor
19516 not what the code which sets optional_new_start wants. */ 19613 row will be fully visible. Otherwise, the code under
19517 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y) 19614 force_start label below will try to move point back into
19518 && !w->force_start) 19615 view, which is not what the code which sets
19519 { 19616 optional_new_start wants. */
19520 if (it_charpos == PT) 19617 if (it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
19521 w->force_start = true; 19618 {
19522 /* IT may overshoot PT if text at PT is invisible. */ 19619 if (it_charpos == PT)
19523 else if (it_charpos > PT && CHARPOS (startp) <= PT) 19620 w->force_start = true;
19524 w->force_start = true; 19621 /* IT may overshoot PT if text at PT is invisible. */
19622 else if (it_charpos > PT && CHARPOS (startp) <= PT)
19623 w->force_start = true;
19525#ifdef GLYPH_DEBUG 19624#ifdef GLYPH_DEBUG
19526 if (w->force_start) 19625 if (w->force_start)
19527 { 19626 {
19528 if (window_frozen_p (w)) 19627 if (window_frozen_p (w))
19529 debug_method_add (w, "set force_start from frozen window start"); 19628 debug_method_add (w, "set force_start from frozen window start");
19530 else 19629 else
19531 debug_method_add (w, "set force_start from optional_new_start"); 19630 debug_method_add (w, "set force_start from optional_new_start");
19532 } 19631 }
19533#endif 19632#endif
19633 }
19534 } 19634 }
19535 } 19635 }
19536 19636
@@ -20256,7 +20356,6 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
20256 || w->base_line_pos > 0 20356 || w->base_line_pos > 0
20257 /* Column number is displayed and different from the one displayed. */ 20357 /* Column number is displayed and different from the one displayed. */
20258 || (w->column_number_displayed != -1 20358 || (w->column_number_displayed != -1
20259 && !current_buffer->long_line_optimizations_p
20260 && (w->column_number_displayed != current_column ()))) 20359 && (w->column_number_displayed != current_column ())))
20261 /* This means that the window has a mode line. */ 20360 /* This means that the window has a mode line. */
20262 && (window_wants_mode_line (w) 20361 && (window_wants_mode_line (w)
@@ -24496,8 +24595,26 @@ display_line (struct it *it, int cursor_vpos)
24496 it->first_visible_x += x_incr; 24595 it->first_visible_x += x_incr;
24497 it->last_visible_x += x_incr; 24596 it->last_visible_x += x_incr;
24498 } 24597 }
24499 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x, 24598 if (current_buffer->long_line_optimizations_p
24500 MOVE_TO_POS | MOVE_TO_X); 24599 && it->line_wrap == TRUNCATE
24600 && window_hscroll_limited (it->w, it->f) > large_hscroll_threshold)
24601 {
24602 /* Special optimization for very long and truncated lines
24603 which are hscrolled far to the left: jump directly to the
24604 (approximate) position that is visible, instead of slowly
24605 walking there. */
24606 ptrdiff_t chars_to_skip =
24607 it->first_visible_x / FRAME_COLUMN_WIDTH (it->f);
24608 move_result = fast_move_it_horizontally (it, chars_to_skip);
24609
24610 if (move_result == MOVE_X_REACHED)
24611 it->current_x = it->first_visible_x;
24612 else /* use arbitrary value < first_visible_x */
24613 it->current_x = it->first_visible_x - FRAME_COLUMN_WIDTH (it->f);
24614 }
24615 else
24616 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
24617 MOVE_TO_POS | MOVE_TO_X);
24501 /* If we are under a large hscroll, move_it_in_display_line_to 24618 /* If we are under a large hscroll, move_it_in_display_line_to
24502 could hit the end of the line without reaching 24619 could hit the end of the line without reaching
24503 first_visible_x. Pretend that we did reach it. This is 24620 first_visible_x. Pretend that we did reach it. This is
@@ -27758,17 +27875,6 @@ decode_mode_spec (struct window *w, register int c, int field_width,
27758 even crash emacs.) */ 27875 even crash emacs.) */
27759 if (mode_line_target == MODE_LINE_TITLE) 27876 if (mode_line_target == MODE_LINE_TITLE)
27760 return ""; 27877 return "";
27761 else if (b->long_line_optimizations_p)
27762 {
27763 char *p = decode_mode_spec_buf;
27764 int pad = width - 2;
27765 while (pad-- > 0)
27766 *p++ = ' ';
27767 *p++ = '?';
27768 *p++ = '?';
27769 *p = '\0';
27770 return decode_mode_spec_buf;
27771 }
27772 else 27878 else
27773 { 27879 {
27774 ptrdiff_t col = current_column (); 27880 ptrdiff_t col = current_column ();
@@ -36112,6 +36218,7 @@ be let-bound around code that needs to disable messages temporarily. */);
36112 defsubr (&Sbidi_find_overridden_directionality); 36218 defsubr (&Sbidi_find_overridden_directionality);
36113 defsubr (&Sdisplay__line_is_continued_p); 36219 defsubr (&Sdisplay__line_is_continued_p);
36114 defsubr (&Sget_display_property); 36220 defsubr (&Sget_display_property);
36221 defsubr (&Slong_line_optimizations_p);
36115 36222
36116 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook"); 36223 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
36117 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map"); 36224 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
diff --git a/src/xfns.c b/src/xfns.c
index 2845ecca6a9..6ed93ee42ca 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -6851,17 +6851,16 @@ The coordinates X and Y are interpreted in pixels relative to a position
6851#ifdef HAVE_XINPUT2 6851#ifdef HAVE_XINPUT2
6852 int deviceid; 6852 int deviceid;
6853 6853
6854 if (FRAME_DISPLAY_INFO (f)->supports_xi2) 6854 deviceid = FRAME_DISPLAY_INFO (f)->client_pointer_device;
6855
6856 if (FRAME_DISPLAY_INFO (f)->supports_xi2
6857 && deviceid != -1)
6855 { 6858 {
6856 XGrabServer (FRAME_X_DISPLAY (f)); 6859 x_catch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
6857 if (XIGetClientPointer (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), 6860 XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None,
6858 &deviceid)) 6861 FRAME_DISPLAY_INFO (f)->root_window,
6859 { 6862 0, 0, 0, 0, xval, yval);
6860 XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None, 6863 x_uncatch_errors_for_lisp (FRAME_DISPLAY_INFO (f));
6861 FRAME_DISPLAY_INFO (f)->root_window,
6862 0, 0, 0, 0, xval, yval);
6863 }
6864 XUngrabServer (FRAME_X_DISPLAY (f));
6865 } 6864 }
6866 else 6865 else
6867#endif 6866#endif
diff --git a/src/xterm.c b/src/xterm.c
index ab43a8ec517..5047f3066be 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1398,6 +1398,15 @@ static int x_dnd_last_tooltip_x, x_dnd_last_tooltip_y;
1398/* Whether or not those values are actually known yet. */ 1398/* Whether or not those values are actually known yet. */
1399static bool x_dnd_last_tooltip_valid; 1399static bool x_dnd_last_tooltip_valid;
1400 1400
1401#ifdef HAVE_XINPUT2
1402/* The master pointer device being used for the drag-and-drop
1403 operation. */
1404static int x_dnd_pointer_device;
1405
1406/* The keyboard device attached to that pointer device. */
1407static int x_dnd_keyboard_device;
1408#endif
1409
1401/* Structure describing a single window that can be the target of 1410/* Structure describing a single window that can be the target of
1402 drag-and-drop operations. */ 1411 drag-and-drop operations. */
1403struct x_client_list_window 1412struct x_client_list_window
@@ -4705,6 +4714,67 @@ x_restore_events_after_dnd (struct frame *f, XWindowAttributes *wa)
4705 dpyinfo->Xatom_XdndTypeList); 4714 dpyinfo->Xatom_XdndTypeList);
4706} 4715}
4707 4716
4717#ifdef HAVE_XINPUT2
4718
4719/* Cancel the current drag-and-drop operation, sending leave messages
4720 to any relevant toplevels. This is called from the event loop when
4721 an event is received telling Emacs to gracefully cancel the
4722 drag-and-drop operation. */
4723
4724static void
4725x_dnd_cancel_dnd_early (void)
4726{
4727 struct frame *f;
4728 xm_drop_start_message dmsg;
4729
4730 eassert (x_dnd_frame && x_dnd_in_progress);
4731
4732 f = x_dnd_frame;
4733
4734 if (x_dnd_last_seen_window != None
4735 && x_dnd_last_protocol_version != -1)
4736 x_dnd_send_leave (x_dnd_frame,
4737 x_dnd_last_seen_window);
4738 else if (x_dnd_last_seen_window != None
4739 && !XM_DRAG_STYLE_IS_DROP_ONLY (x_dnd_last_motif_style)
4740 && x_dnd_last_motif_style != XM_DRAG_STYLE_NONE
4741 && x_dnd_motif_setup_p)
4742 {
4743 dmsg.reason = XM_DRAG_REASON (XM_DRAG_ORIGINATOR_INITIATOR,
4744 XM_DRAG_REASON_DROP_START);
4745 dmsg.byte_order = XM_BYTE_ORDER_CUR_FIRST;
4746 dmsg.timestamp = FRAME_DISPLAY_INFO (f)->last_user_time;
4747 dmsg.side_effects
4748 = XM_DRAG_SIDE_EFFECT (xm_side_effect_from_action (FRAME_DISPLAY_INFO (f),
4749 x_dnd_wanted_action),
4750 XM_DROP_SITE_VALID, x_dnd_motif_operations,
4751 XM_DROP_ACTION_DROP_CANCEL);
4752 dmsg.x = 0;
4753 dmsg.y = 0;
4754 dmsg.index_atom = x_dnd_motif_atom;
4755 dmsg.source_window = FRAME_X_WINDOW (f);
4756
4757 x_dnd_send_xm_leave_for_drop (FRAME_DISPLAY_INFO (f), f,
4758 x_dnd_last_seen_window,
4759 FRAME_DISPLAY_INFO (f)->last_user_time);
4760 xm_send_drop_message (FRAME_DISPLAY_INFO (f), FRAME_X_WINDOW (f),
4761 x_dnd_last_seen_window, &dmsg);
4762 }
4763
4764 x_dnd_last_seen_window = None;
4765 x_dnd_last_seen_toplevel = None;
4766 x_dnd_in_progress = false;
4767 x_dnd_waiting_for_finish = false;
4768 x_dnd_return_frame_object = NULL;
4769 x_dnd_movement_frame = NULL;
4770 x_dnd_wheel_frame = NULL;
4771 x_dnd_frame = NULL;
4772 x_dnd_action = None;
4773 x_dnd_action_symbol = Qnil;
4774}
4775
4776#endif
4777
4708static void 4778static void
4709x_dnd_cleanup_drag_and_drop (void *frame) 4779x_dnd_cleanup_drag_and_drop (void *frame)
4710{ 4780{
@@ -11909,6 +11979,9 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
11909 struct x_display_info *event_display; 11979 struct x_display_info *event_display;
11910#endif 11980#endif
11911 unsigned int additional_mask; 11981 unsigned int additional_mask;
11982#ifdef HAVE_XINPUT2
11983 struct xi_device_t *device;
11984#endif
11912 11985
11913 base = SPECPDL_INDEX (); 11986 base = SPECPDL_INDEX ();
11914 11987
@@ -12089,6 +12162,33 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
12089 x_dnd_wheel_frame = NULL; 12162 x_dnd_wheel_frame = NULL;
12090 x_dnd_init_type_lists = false; 12163 x_dnd_init_type_lists = false;
12091 x_dnd_need_send_drop = false; 12164 x_dnd_need_send_drop = false;
12165
12166#ifdef HAVE_XINPUT2
12167
12168 if (FRAME_DISPLAY_INFO (f)->supports_xi2)
12169 {
12170 /* Only accept input from the last master pointer to have interacted
12171 with Emacs. This prevents another pointer device getting our
12172 idea of the button state messed up. */
12173 if (FRAME_DISPLAY_INFO (f)->client_pointer_device != -1)
12174 x_dnd_pointer_device
12175 = FRAME_DISPLAY_INFO (f)->client_pointer_device;
12176 else
12177 /* This returns Bool but cannot actually fail. */
12178 XIGetClientPointer (FRAME_X_DISPLAY (f), None,
12179 &x_dnd_pointer_device);
12180
12181 x_dnd_keyboard_device = -1;
12182
12183 device = xi_device_from_id (FRAME_DISPLAY_INFO (f),
12184 x_dnd_pointer_device);
12185
12186 if (device)
12187 x_dnd_keyboard_device = device->attachment;
12188 }
12189
12190#endif
12191
12092#ifdef HAVE_XKB 12192#ifdef HAVE_XKB
12093 x_dnd_keyboard_state = 0; 12193 x_dnd_keyboard_state = 0;
12094 12194
@@ -12882,6 +12982,13 @@ xi_disable_devices (struct x_display_info *dpyinfo,
12882 { 12982 {
12883 if (to_disable[j] == dpyinfo->devices[i].device_id) 12983 if (to_disable[j] == dpyinfo->devices[i].device_id)
12884 { 12984 {
12985 if (x_dnd_in_progress
12986 /* If the drag-and-drop pointer device is being
12987 disabled, then cancel the drag and drop
12988 operation. */
12989 && to_disable[j] == x_dnd_pointer_device)
12990 x_dnd_cancel_dnd_early ();
12991
12885 /* Free any scroll valuators that might be on this 12992 /* Free any scroll valuators that might be on this
12886 device. */ 12993 device. */
12887#ifdef HAVE_XINPUT2_1 12994#ifdef HAVE_XINPUT2_1
@@ -14164,11 +14271,13 @@ x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
14164 ev->window = FRAME_X_WINDOW (f); 14271 ev->window = FRAME_X_WINDOW (f);
14165 ev->format = 32; 14272 ev->format = 32;
14166 14273
14167 /* A 32-bit X client on a 64-bit X server can pass a window pointer 14274 /* A 32-bit X client can pass a window pointer through the X server
14168 as-is. A 64-bit client on a 32-bit X server is in trouble 14275 as-is.
14169 because a pointer does not fit and would be truncated while 14276
14170 passing through the server. So use two slots and hope that X12 14277 A 64-bit client is in trouble because a pointer does not fit in
14171 will resolve such issues someday. */ 14278 the 32 bits given for ClientMessage data and will be truncated by
14279 Xlib. So use two slots and hope that X12 will resolve such
14280 issues someday. */
14172 ev->data.l[0] = iw >> 31 >> 1; 14281 ev->data.l[0] = iw >> 31 >> 1;
14173 ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift; 14282 ev->data.l[1] = sign_shift <= 0 ? iw : iw << sign_shift >> sign_shift;
14174 ev->data.l[2] = part; 14283 ev->data.l[2] = part;
@@ -17316,6 +17425,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
17316 union buffered_input_event inev; 17425 union buffered_input_event inev;
17317 int count = 0; 17426 int count = 0;
17318 int do_help = 0; 17427 int do_help = 0;
17428#ifdef HAVE_XINPUT2
17429 struct xi_device_t *gen_help_device;
17430 Time gen_help_time;
17431#endif
17319 ptrdiff_t nbytes = 0; 17432 ptrdiff_t nbytes = 0;
17320 struct frame *any, *f = NULL; 17433 struct frame *any, *f = NULL;
17321 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight; 17434 Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
@@ -17345,6 +17458,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
17345 EVENT_INIT (inev.ie); 17458 EVENT_INIT (inev.ie);
17346 inev.ie.kind = NO_EVENT; 17459 inev.ie.kind = NO_EVENT;
17347 inev.ie.arg = Qnil; 17460 inev.ie.arg = Qnil;
17461#ifdef HAVE_XINPUT2
17462 gen_help_device = NULL;
17463#endif
17348 17464
17349 /* Ignore events coming from various extensions, such as XFIXES and 17465 /* Ignore events coming from various extensions, such as XFIXES and
17350 XKB. */ 17466 XKB. */
@@ -17870,6 +17986,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
17870 if (!x_window_to_frame (dpyinfo, event->xselection.requestor)) 17986 if (!x_window_to_frame (dpyinfo, event->xselection.requestor))
17871 goto OTHER; 17987 goto OTHER;
17872#endif /* not USE_X_TOOLKIT and not USE_GTK */ 17988#endif /* not USE_X_TOOLKIT and not USE_GTK */
17989#ifdef HAVE_GTK3
17990 /* GTK 3 apparently chokes on these events since they have no
17991 associated device. (bug#56869, another bug as well that I
17992 can't find) */
17993 *finish = X_EVENT_DROP;
17994#endif
17873 x_handle_selection_notify (&event->xselection); 17995 x_handle_selection_notify (&event->xselection);
17874 break; 17996 break;
17875 17997
@@ -17878,6 +18000,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
17878 if (!x_window_to_frame (dpyinfo, event->xselectionclear.window)) 18000 if (!x_window_to_frame (dpyinfo, event->xselectionclear.window))
17879 goto OTHER; 18001 goto OTHER;
17880#endif /* not USE_X_TOOLKIT and not USE_GTK */ 18002#endif /* not USE_X_TOOLKIT and not USE_GTK */
18003#ifdef HAVE_GTK3
18004 *finish = X_EVENT_DROP;
18005#endif
17881 { 18006 {
17882 const XSelectionClearEvent *eventp = &event->xselectionclear; 18007 const XSelectionClearEvent *eventp = &event->xselectionclear;
17883 18008
@@ -17904,6 +18029,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
17904 if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner)) 18029 if (!x_window_to_frame (dpyinfo, event->xselectionrequest.owner))
17905 goto OTHER; 18030 goto OTHER;
17906#endif /* USE_X_TOOLKIT */ 18031#endif /* USE_X_TOOLKIT */
18032#ifdef HAVE_GTK3
18033 *finish = X_EVENT_DROP;
18034#endif
17907 { 18035 {
17908 const XSelectionRequestEvent *eventp = &event->xselectionrequest; 18036 const XSelectionRequestEvent *eventp = &event->xselectionrequest;
17909 18037
@@ -18446,6 +18574,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
18446#endif 18574#endif
18447 18575
18448 if (x_dnd_in_progress 18576 if (x_dnd_in_progress
18577 /* When _NET_WM_CLIENT_LIST stacking is being used, changes
18578 in that property are watched for, and it's not necessary
18579 to update the state in response to ordinary window
18580 substructure events. */
18581 && !x_dnd_use_toplevels
18449 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) 18582 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
18450 x_dnd_update_state (dpyinfo, dpyinfo->last_user_time); 18583 x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
18451 18584
@@ -20280,6 +20413,11 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20280 20413
20281 case CirculateNotify: 20414 case CirculateNotify:
20282 if (x_dnd_in_progress 20415 if (x_dnd_in_progress
20416 /* When _NET_WM_CLIENT_LIST stacking is being used, changes
20417 in that property are watched for, and it's not necessary
20418 to update the state in response to ordinary window
20419 substructure events. */
20420 && !x_dnd_use_toplevels
20283 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) 20421 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
20284 x_dnd_update_state (dpyinfo, dpyinfo->last_user_time); 20422 x_dnd_update_state (dpyinfo, dpyinfo->last_user_time);
20285 goto OTHER; 20423 goto OTHER;
@@ -20876,6 +21014,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20876 operation, don't send an event. We only have 21014 operation, don't send an event. We only have
20877 to set the user time. */ 21015 to set the user time. */
20878 if (x_dnd_in_progress 21016 if (x_dnd_in_progress
21017 /* If another master device moved the
21018 pointer, we should put a wheel event on
21019 the keyboard buffer as usual. It will be
21020 run once the drag-and-drop operation
21021 completes. */
21022 && xev->deviceid == x_dnd_pointer_device
20879 && (command_loop_level + minibuf_level 21023 && (command_loop_level + minibuf_level
20880 <= x_dnd_recursion_depth) 21024 <= x_dnd_recursion_depth)
20881 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) 21025 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
@@ -20968,6 +21112,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
20968 `x-dnd-movement-function`. */ 21112 `x-dnd-movement-function`. */
20969 && (command_loop_level + minibuf_level 21113 && (command_loop_level + minibuf_level
20970 <= x_dnd_recursion_depth) 21114 <= x_dnd_recursion_depth)
21115 && xev->deviceid == x_dnd_pointer_device
20971 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) 21116 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
20972 { 21117 {
20973 Window target, toplevel; 21118 Window target, toplevel;
@@ -21270,7 +21415,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21270 has changed, generate a HELP_EVENT. */ 21415 has changed, generate a HELP_EVENT. */
21271 if (!NILP (help_echo_string) 21416 if (!NILP (help_echo_string)
21272 || !NILP (previous_help_echo_string)) 21417 || !NILP (previous_help_echo_string))
21273 do_help = 1; 21418 {
21419 /* Also allow the focus and client pointer to be
21420 adjusted accordingly, in case a help tooltip is
21421 shown. */
21422 gen_help_device = device;
21423 gen_help_time = xev->time;
21424
21425 do_help = 1;
21426 }
21274 goto XI_OTHER; 21427 goto XI_OTHER;
21275 } 21428 }
21276 21429
@@ -21294,6 +21447,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21294 if (x_dnd_in_progress 21447 if (x_dnd_in_progress
21295 && (command_loop_level + minibuf_level 21448 && (command_loop_level + minibuf_level
21296 <= x_dnd_recursion_depth) 21449 <= x_dnd_recursion_depth)
21450 && xev->deviceid == x_dnd_pointer_device
21297 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)) 21451 && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
21298 { 21452 {
21299 f = mouse_or_wdesc_frame (dpyinfo, xev->event); 21453 f = mouse_or_wdesc_frame (dpyinfo, xev->event);
@@ -21333,6 +21487,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21333 } 21487 }
21334#endif 21488#endif
21335 21489
21490 if (f && device)
21491 xi_handle_interaction (dpyinfo, f, device,
21492 xev->time);
21493
21336 if (xev->evtype == XI_ButtonPress 21494 if (xev->evtype == XI_ButtonPress
21337 && x_dnd_last_seen_window != None) 21495 && x_dnd_last_seen_window != None)
21338 { 21496 {
@@ -21579,11 +21737,19 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21579 xev->send_event); 21737 xev->send_event);
21580 21738
21581 source = xi_device_from_id (dpyinfo, xev->sourceid); 21739 source = xi_device_from_id (dpyinfo, xev->sourceid);
21740 device = xi_device_from_id (dpyinfo, xev->deviceid);
21582 21741
21583#ifdef HAVE_XWIDGETS 21742#ifdef HAVE_XWIDGETS
21584 xvw = xwidget_view_from_window (xev->event); 21743 xvw = xwidget_view_from_window (xev->event);
21585 if (xvw) 21744 if (xvw)
21586 { 21745 {
21746 /* If the user interacts with a frame that's focused
21747 on another device, but not the current focus
21748 frame, make it the focus frame. */
21749 if (device)
21750 xi_handle_interaction (dpyinfo, xvw->frame,
21751 device, xev->time);
21752
21587 xwidget_button (xvw, xev->evtype == XI_ButtonPress, 21753 xwidget_button (xvw, xev->evtype == XI_ButtonPress,
21588 lrint (xev->event_x), lrint (xev->event_y), 21754 lrint (xev->event_x), lrint (xev->event_y),
21589 xev->detail, xi_convert_event_state (xev), 21755 xev->detail, xi_convert_event_state (xev),
@@ -21603,8 +21769,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
21603 } 21769 }
21604#endif 21770#endif
21605 21771
21606 device = xi_device_from_id (dpyinfo, xev->deviceid);
21607
21608 if (!device) 21772 if (!device)
21609 goto XI_OTHER; 21773 goto XI_OTHER;
21610 21774
@@ -22162,7 +22326,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22162 inev.ie.modifiers = x_x_to_emacs_modifiers (dpyinfo, state); 22326 inev.ie.modifiers = x_x_to_emacs_modifiers (dpyinfo, state);
22163 22327
22164#ifdef XK_F1 22328#ifdef XK_F1
22165 if (x_dnd_in_progress && keysym == XK_F1) 22329 if (x_dnd_in_progress
22330 && xev->deviceid == x_dnd_keyboard_device
22331 && keysym == XK_F1)
22166 { 22332 {
22167 x_dnd_xm_use_help = true; 22333 x_dnd_xm_use_help = true;
22168 goto xi_done_keysym; 22334 goto xi_done_keysym;
@@ -22426,11 +22592,14 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22426 22592
22427 case XI_HierarchyChanged: 22593 case XI_HierarchyChanged:
22428 { 22594 {
22429 XIHierarchyEvent *hev = (XIHierarchyEvent *) xi_event; 22595 XIHierarchyEvent *hev;
22430 XIDeviceInfo *info; 22596 XIDeviceInfo *info;
22431 int i, ndevices, n_disabled, *disabled; 22597 int i, ndevices, n_disabled, *disabled;
22432 struct xi_device_t *device; 22598 struct xi_device_t *device;
22599 bool any_changed;
22433 22600
22601 any_changed = false;
22602 hev = (XIHierarchyEvent *) xi_event;
22434 disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info); 22603 disabled = SAFE_ALLOCA (sizeof *disabled * hev->num_info);
22435 n_disabled = 0; 22604 n_disabled = 0;
22436 22605
@@ -22440,8 +22609,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22440 { 22609 {
22441 /* Handle all disabled devices now, to prevent 22610 /* Handle all disabled devices now, to prevent
22442 things happening out-of-order later. */ 22611 things happening out-of-order later. */
22443 xi_disable_devices (dpyinfo, disabled, n_disabled); 22612
22444 n_disabled = 0; 22613 if (ndevices)
22614 {
22615 xi_disable_devices (dpyinfo, disabled, n_disabled);
22616 n_disabled = 0;
22617
22618 /* This flag really just means that disabled
22619 devices were handled early and should be
22620 used in conjunction with n_disabled. */
22621 any_changed = true;
22622 }
22445 22623
22446 x_catch_errors (dpyinfo->display); 22624 x_catch_errors (dpyinfo->display);
22447 info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid, 22625 info = XIQueryDevice (dpyinfo->display, hev->info[i].deviceid,
@@ -22492,9 +22670,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22492 event. */ 22670 event. */
22493 xi_disable_devices (dpyinfo, disabled, n_disabled); 22671 xi_disable_devices (dpyinfo, disabled, n_disabled);
22494 22672
22495 /* Now that the device hierarchy has been changed, 22673 /* If the device hierarchy has been changed, recompute
22496 recompute focus. */ 22674 focus. This might seem like a micro-optimization but
22497 xi_handle_focus_change (dpyinfo); 22675 it actually keeps the focus from changing in some
22676 cases where it would be undesierable. */
22677 if (any_changed || n_disabled)
22678 xi_handle_focus_change (dpyinfo);
22498 22679
22499 goto XI_OTHER; 22680 goto XI_OTHER;
22500 } 22681 }
@@ -23182,6 +23363,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
23182 if (do_help > 0) 23363 if (do_help > 0)
23183 { 23364 {
23184 any_help_event_p = true; 23365 any_help_event_p = true;
23366#ifdef HAVE_XINPUT2
23367 if (gen_help_device)
23368 xi_handle_interaction (dpyinfo, f,
23369 gen_help_device,
23370 gen_help_time);
23371#endif
23185 gen_help_event (help_echo_string, frame, help_echo_window, 23372 gen_help_event (help_echo_string, frame, help_echo_window,
23186 help_echo_object, help_echo_pos); 23373 help_echo_object, help_echo_pos);
23187 } 23374 }
@@ -25947,27 +26134,25 @@ x_set_window_size (struct frame *f, bool change_gravity,
25947void 26134void
25948frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y) 26135frame_set_mouse_pixel_position (struct frame *f, int pix_x, int pix_y)
25949{ 26136{
25950 block_input ();
25951#ifdef HAVE_XINPUT2 26137#ifdef HAVE_XINPUT2
25952 int deviceid; 26138 int deviceid;
25953 26139
25954 if (FRAME_DISPLAY_INFO (f)->supports_xi2) 26140 deviceid = FRAME_DISPLAY_INFO (f)->client_pointer_device;
26141
26142 if (FRAME_DISPLAY_INFO (f)->supports_xi2
26143 && deviceid != -1)
25955 { 26144 {
25956 if (XIGetClientPointer (FRAME_X_DISPLAY (f), 26145 block_input ();
25957 FRAME_X_WINDOW (f), 26146 x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f));
25958 &deviceid)) 26147 XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None,
25959 { 26148 FRAME_X_WINDOW (f), 0, 0, 0, 0, pix_x, pix_y);
25960 x_ignore_errors_for_next_request (FRAME_DISPLAY_INFO (f)); 26149 x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
25961 XIWarpPointer (FRAME_X_DISPLAY (f), deviceid, None, 26150 unblock_input ();
25962 FRAME_X_WINDOW (f), 0, 0, 0, 0, pix_x, pix_y);
25963 x_stop_ignoring_errors (FRAME_DISPLAY_INFO (f));
25964 }
25965 } 26151 }
25966 else 26152 else
25967#endif 26153#endif
25968 XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f), 26154 XWarpPointer (FRAME_X_DISPLAY (f), None, FRAME_X_WINDOW (f),
25969 0, 0, 0, 0, pix_x, pix_y); 26155 0, 0, 0, 0, pix_x, pix_y);
25970 unblock_input ();
25971} 26156}
25972 26157
25973/* Raise frame F. */ 26158/* Raise frame F. */
@@ -28955,7 +29140,7 @@ void
28955x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost, 29140x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
28956 Lisp_Object current_owner) 29141 Lisp_Object current_owner)
28957{ 29142{
28958 Lisp_Object tail, frame, new_owner, tem; 29143 Lisp_Object tail, frame, new_owner;
28959 Time timestamp; 29144 Time timestamp;
28960 Window *owners; 29145 Window *owners;
28961 Atom *names; 29146 Atom *names;
@@ -28985,7 +29170,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
28985 29170
28986 FOR_EACH_TAIL_SAFE (tail) 29171 FOR_EACH_TAIL_SAFE (tail)
28987 { 29172 {
28988 tem = XCAR (tail); 29173 Lisp_Object tem = XCAR (tail);
28989 ++nowners; 29174 ++nowners;
28990 29175
28991 /* The selection is really lost (since we cannot find a new 29176 /* The selection is really lost (since we cannot find a new
@@ -29019,7 +29204,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
29019 29204
29020 FOR_EACH_TAIL_SAFE (tail) 29205 FOR_EACH_TAIL_SAFE (tail)
29021 { 29206 {
29022 tem = XCAR (tail); 29207 Lisp_Object tem = XCAR (tail);
29023 29208
29024 /* Now check if we still don't own that selection, which can 29209 /* Now check if we still don't own that selection, which can
29025 happen if another program set itself as the owner. */ 29210 happen if another program set itself as the owner. */
@@ -29039,9 +29224,10 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
29039 29224
29040 FOR_EACH_TAIL_SAFE (tail) 29225 FOR_EACH_TAIL_SAFE (tail)
29041 { 29226 {
29227 Lisp_Object tem = XCAR (tail);
29228
29042 reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection, 29229 reply = xcb_get_selection_owner_reply (dpyinfo->xcb_connection,
29043 cookies[nowners++], &error); 29230 cookies[nowners++], &error);
29044
29045 if (reply) 29231 if (reply)
29046 owners[nowners - 1] = reply->owner; 29232 owners[nowners - 1] = reply->owner;
29047 else 29233 else
@@ -29071,7 +29257,7 @@ x_preserve_selections (struct x_display_info *dpyinfo, Lisp_Object lost,
29071 29257
29072 FOR_EACH_TAIL_SAFE (tail) 29258 FOR_EACH_TAIL_SAFE (tail)
29073 { 29259 {
29074 tem = XCAR (tail); 29260 Lisp_Object tem = XCAR (tail);
29075 29261
29076 /* If the selection isn't owned by us anymore, note that the 29262 /* If the selection isn't owned by us anymore, note that the
29077 selection was lost. */ 29263 selection was lost. */
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index a655377e6cc..1a27467d292 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -570,7 +570,12 @@ Evaluate BODY for each created sequence.
570 (substring "2") 570 (substring "2")
571 (substring "1")))) 571 (substring "1"))))
572 (should (equal (seq-uniq list) '("1" "2" "3"))) 572 (should (equal (seq-uniq list) '("1" "2" "3")))
573 (should (equal (seq-uniq list #'eq) '("1" "2" "3" "2" "1"))))) 573 (should (equal (seq-uniq list #'eq) '("1" "2" "3" "2" "1"))))
574 ;; Long lists have a different code path.
575 (let ((list (seq-map-indexed (lambda (_ i) i)
576 (make-list 10000 nil))))
577 (should (= (length list) 10000))
578 (should (= (length (seq-uniq (append list list))) 10000))))
574 579
575(provide 'seq-tests) 580(provide 'seq-tests)
576;;; seq-tests.el ends here 581;;; seq-tests.el ends here
diff --git a/test/lisp/eshell/esh-cmd-tests.el b/test/lisp/eshell/esh-cmd-tests.el
new file mode 100644
index 00000000000..e86985ec717
--- /dev/null
+++ b/test/lisp/eshell/esh-cmd-tests.el
@@ -0,0 +1,283 @@
1;;; esh-cmd-tests.el --- esh-cmd test suite -*- lexical-binding:t -*-
2
3;; Copyright (C) 2022 Free Software Foundation, Inc.
4
5;; This file is part of GNU Emacs.
6
7;; GNU Emacs is free software: you can redistribute it and/or modify
8;; it under the terms of the GNU General Public License as published by
9;; the Free Software Foundation, either version 3 of the License, or
10;; (at your option) any later version.
11
12;; GNU Emacs is distributed in the hope that it will be useful,
13;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15;; GNU General Public License for more details.
16
17;; You should have received a copy of the GNU General Public License
18;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
19
20;;; Commentary:
21
22;; Tests for Eshell's command invocation.
23
24;;; Code:
25
26(require 'ert)
27(require 'esh-mode)
28(require 'eshell)
29
30(require 'eshell-tests-helpers
31 (expand-file-name "eshell-tests-helpers"
32 (file-name-directory (or load-file-name
33 default-directory))))
34
35(defvar eshell-test-value nil)
36
37;;; Tests:
38
39
40;; Command invocation
41
42(ert-deftest esh-cmd-test/simple-command-result ()
43 "Test invocation with a simple command."
44 (should (equal (eshell-test-command-result "+ 1 2") 3)))
45
46(ert-deftest esh-cmd-test/lisp-command ()
47 "Test invocation with an elisp command."
48 (should (equal (eshell-test-command-result "(+ 1 2)") 3)))
49
50(ert-deftest esh-cmd-test/lisp-command-with-quote ()
51 "Test invocation with an elisp command containing a quote."
52 (should (equal (eshell-test-command-result "(eq 'foo nil)") nil)))
53
54(ert-deftest esh-cmd-test/lisp-command-args ()
55 "Test invocation with elisp and trailing args.
56Test that trailing arguments outside the S-expression are
57ignored. e.g. \"(+ 1 2) 3\" => 3"
58 (should (equal (eshell-test-command-result "(+ 1 2) 3") 3)))
59
60(ert-deftest esh-cmd-test/subcommand ()
61 "Test invocation with a simple subcommand."
62 (should (equal (eshell-test-command-result "{+ 1 2}") 3)))
63
64(ert-deftest esh-cmd-test/subcommand-args ()
65 "Test invocation with a subcommand and trailing args.
66Test that trailing arguments outside the subcommand are ignored.
67e.g. \"{+ 1 2} 3\" => 3"
68 (should (equal (eshell-test-command-result "{+ 1 2} 3") 3)))
69
70(ert-deftest esh-cmd-test/subcommand-lisp ()
71 "Test invocation with an elisp subcommand and trailing args.
72Test that trailing arguments outside the subcommand are ignored.
73e.g. \"{(+ 1 2)} 3\" => 3"
74 (should (equal (eshell-test-command-result "{(+ 1 2)} 3") 3)))
75
76
77;; Logical operators
78
79(ert-deftest esh-cmd-test/and-operator ()
80 "Test logical && operator."
81 (skip-unless (executable-find "["))
82 (with-temp-eshell
83 (eshell-command-result-p "[ foo = foo ] && echo hi"
84 "hi\n")
85 (eshell-command-result-p "[ foo = bar ] && echo hi"
86 "\\`\\'")))
87
88(ert-deftest esh-cmd-test/or-operator ()
89 "Test logical || operator."
90 (skip-unless (executable-find "["))
91 (with-temp-eshell
92 (eshell-command-result-p "[ foo = foo ] || echo hi"
93 "\\`\\'")
94 (eshell-command-result-p "[ foo = bar ] || echo hi"
95 "hi\n")))
96
97
98;; Control flow statements
99
100(ert-deftest esh-cmd-test/for-loop ()
101 "Test invocation of a for loop."
102 (with-temp-eshell
103 (eshell-command-result-p "for i in 5 { echo $i }"
104 "5\n")))
105
106(ert-deftest esh-cmd-test/for-loop-list ()
107 "Test invocation of a for loop iterating over a list."
108 (with-temp-eshell
109 (eshell-command-result-p "for i in (list 1 2 (list 3 4)) { echo $i }"
110 "1\n2\n(3 4)\n")))
111
112(ert-deftest esh-cmd-test/for-loop-multiple-args ()
113 "Test invocation of a for loop iterating over multiple arguments."
114 (with-temp-eshell
115 (eshell-command-result-p "for i in 1 2 (list 3 4) { echo $i }"
116 "1\n2\n3\n4\n")))
117
118(ert-deftest esh-cmd-test/for-name-loop () ; bug#15231
119 "Test invocation of a for loop using `name'."
120 (let ((process-environment (cons "name" process-environment)))
121 (should (equal (eshell-test-command-result
122 "for name in 3 { echo $name }")
123 3))))
124
125(ert-deftest esh-cmd-test/for-name-shadow-loop () ; bug#15372
126 "Test invocation of a for loop using an env-var."
127 (let ((process-environment (cons "name=env-value" process-environment)))
128 (with-temp-eshell
129 (eshell-command-result-p
130 "echo $name; for name in 3 { echo $name }; echo $name"
131 "env-value\n3\nenv-value\n"))))
132
133(ert-deftest esh-cmd-test/while-loop ()
134 "Test invocation of a while loop."
135 (with-temp-eshell
136 (let ((eshell-test-value '(0 1 2)))
137 (eshell-command-result-p
138 (concat "while $eshell-test-value "
139 "{ setq eshell-test-value (cdr eshell-test-value) }")
140 "(1 2)\n(2)\n"))))
141
142(ert-deftest esh-cmd-test/while-loop-lisp-form ()
143 "Test invocation of a while loop using a Lisp form."
144 (with-temp-eshell
145 (let ((eshell-test-value 0))
146 (eshell-command-result-p
147 (concat "while (/= eshell-test-value 3) "
148 "{ setq eshell-test-value (1+ eshell-test-value) }")
149 "1\n2\n3\n"))))
150
151(ert-deftest esh-cmd-test/while-loop-ext-cmd ()
152 "Test invocation of a while loop using an external command."
153 (skip-unless (executable-find "["))
154 (with-temp-eshell
155 (let ((eshell-test-value 0))
156 (eshell-command-result-p
157 (concat "while {[ $eshell-test-value -ne 3 ]} "
158 "{ setq eshell-test-value (1+ eshell-test-value) }")
159 "1\n2\n3\n"))))
160
161(ert-deftest esh-cmd-test/until-loop ()
162 "Test invocation of an until loop."
163 (with-temp-eshell
164 (let ((eshell-test-value nil))
165 (eshell-command-result-p
166 (concat "until $eshell-test-value "
167 "{ setq eshell-test-value t }")
168 "t\n"))))
169
170(ert-deftest esh-cmd-test/until-loop-lisp-form ()
171 "Test invocation of an until loop using a Lisp form."
172 (skip-unless (executable-find "["))
173 (with-temp-eshell
174 (let ((eshell-test-value 0))
175 (eshell-command-result-p
176 (concat "until (= eshell-test-value 3) "
177 "{ setq eshell-test-value (1+ eshell-test-value) }")
178 "1\n2\n3\n"))))
179
180(ert-deftest esh-cmd-test/until-loop-ext-cmd ()
181 "Test invocation of an until loop using an external command."
182 (skip-unless (executable-find "["))
183 (with-temp-eshell
184 (let ((eshell-test-value 0))
185 (eshell-command-result-p
186 (concat "until {[ $eshell-test-value -eq 3 ]} "
187 "{ setq eshell-test-value (1+ eshell-test-value) }")
188 "1\n2\n3\n"))))
189
190(ert-deftest esh-cmd-test/if-statement ()
191 "Test invocation of an if statement."
192 (with-temp-eshell
193 (let ((eshell-test-value t))
194 (eshell-command-result-p "if $eshell-test-value {echo yes}"
195 "yes\n"))
196 (let ((eshell-test-value nil))
197 (eshell-command-result-p "if $eshell-test-value {echo yes}"
198 "\\`\\'"))))
199
200(ert-deftest esh-cmd-test/if-else-statement ()
201 "Test invocation of an if/else statement."
202 (with-temp-eshell
203 (let ((eshell-test-value t))
204 (eshell-command-result-p "if $eshell-test-value {echo yes} {echo no}"
205 "yes\n"))
206 (let ((eshell-test-value nil))
207 (eshell-command-result-p "if $eshell-test-value {echo yes} {echo no}"
208 "no\n"))))
209
210(ert-deftest esh-cmd-test/if-else-statement-lisp-form ()
211 "Test invocation of an if/else statement using a Lisp form."
212 (with-temp-eshell
213 (eshell-command-result-p "if (zerop 0) {echo yes} {echo no}"
214 "yes\n")
215 (eshell-command-result-p "if (zerop 1) {echo yes} {echo no}"
216 "no\n")
217 (let ((debug-on-error nil))
218 (eshell-command-result-p "if (zerop \"foo\") {echo yes} {echo no}"
219 "no\n"))))
220
221(ert-deftest esh-cmd-test/if-else-statement-lisp-form-2 ()
222 "Test invocation of an if/else statement using a Lisp form.
223This tests when `eshell-lisp-form-nil-is-failure' is nil."
224 (let ((eshell-lisp-form-nil-is-failure nil))
225 (with-temp-eshell
226 (eshell-command-result-p "if (zerop 0) {echo yes} {echo no}"
227 "yes\n")
228 (eshell-command-result-p "if (zerop 1) {echo yes} {echo no}"
229 "yes\n")
230 (let ((debug-on-error nil))
231 (eshell-command-result-p "if (zerop \"foo\") {echo yes} {echo no}"
232 "no\n")))))
233
234(ert-deftest esh-cmd-test/if-else-statement-ext-cmd ()
235 "Test invocation of an if/else statement using an external command."
236 (skip-unless (executable-find "["))
237 (with-temp-eshell
238 (eshell-command-result-p "if {[ foo = foo ]} {echo yes} {echo no}"
239 "yes\n")
240 (eshell-command-result-p "if {[ foo = bar ]} {echo yes} {echo no}"
241 "no\n")))
242
243(ert-deftest esh-cmd-test/unless-statement ()
244 "Test invocation of an unless statement."
245 (with-temp-eshell
246 (let ((eshell-test-value t))
247 (eshell-command-result-p "unless $eshell-test-value {echo no}"
248 "\\`\\'"))
249 (let ((eshell-test-value nil))
250 (eshell-command-result-p "unless $eshell-test-value {echo no}"
251 "no\n"))))
252
253(ert-deftest esh-cmd-test/unless-else-statement ()
254 "Test invocation of an unless/else statement."
255 (with-temp-eshell
256 (let ((eshell-test-value t))
257 (eshell-command-result-p "unless $eshell-test-value {echo no} {echo yes}"
258 "yes\n"))
259 (let ((eshell-test-value nil))
260 (eshell-command-result-p "unless $eshell-test-value {echo no} {echo yes}"
261 "no\n"))))
262
263(ert-deftest esh-cmd-test/unless-else-statement-lisp-form ()
264 "Test invocation of an unless/else statement using a Lisp form."
265 (with-temp-eshell
266 (eshell-command-result-p "unless (zerop 0) {echo no} {echo yes}"
267 "yes\n")
268 (eshell-command-result-p "unless (zerop 1) {echo no} {echo yes}"
269 "no\n")
270 (let ((debug-on-error nil))
271 (eshell-command-result-p "unless (zerop \"foo\") {echo no} {echo yes}"
272 "no\n"))))
273
274(ert-deftest esh-cmd-test/unless-else-statement-ext-cmd ()
275 "Test invocation of an unless/else statement using an external command."
276 (skip-unless (executable-find "["))
277 (with-temp-eshell
278 (eshell-command-result-p "unless {[ foo = foo ]} {echo no} {echo yes}"
279 "yes\n")
280 (eshell-command-result-p "unless {[ foo = bar ]} {echo no} {echo yes}"
281 "no\n")))
282
283;; esh-cmd-tests.el ends here
diff --git a/test/lisp/eshell/esh-var-tests.el b/test/lisp/eshell/esh-var-tests.el
index 54e701a6aab..0c094ee5a79 100644
--- a/test/lisp/eshell/esh-var-tests.el
+++ b/test/lisp/eshell/esh-var-tests.el
@@ -500,18 +500,75 @@ inside double-quotes"
500 (eshell-command-result-p "echo $INSIDE_EMACS[, 1]" 500 (eshell-command-result-p "echo $INSIDE_EMACS[, 1]"
501 "eshell"))) 501 "eshell")))
502 502
503(ert-deftest esh-var-test/last-status-var-lisp-command ()
504 "Test using the \"last exit status\" ($?) variable with a Lisp command"
505 (with-temp-eshell
506 (eshell-command-result-p "zerop 0; echo $?"
507 "t\n0\n")
508 (eshell-command-result-p "zerop 1; echo $?"
509 "0\n")
510 (let ((debug-on-error nil))
511 (eshell-command-result-p "zerop foo; echo $?"
512 "1\n"))))
513
514(ert-deftest esh-var-test/last-status-var-lisp-form ()
515 "Test using the \"last exit status\" ($?) variable with a Lisp form"
516 (let ((eshell-lisp-form-nil-is-failure t))
517 (with-temp-eshell
518 (eshell-command-result-p "(zerop 0); echo $?"
519 "t\n0\n")
520 (eshell-command-result-p "(zerop 1); echo $?"
521 "2\n")
522 (let ((debug-on-error nil))
523 (eshell-command-result-p "(zerop \"foo\"); echo $?"
524 "1\n")))))
525
526(ert-deftest esh-var-test/last-status-var-lisp-form-2 ()
527 "Test using the \"last exit status\" ($?) variable with a Lisp form.
528This tests when `eshell-lisp-form-nil-is-failure' is nil."
529 (let ((eshell-lisp-form-nil-is-failure nil))
530 (with-temp-eshell
531 (eshell-command-result-p "(zerop 0); echo $?"
532 "0\n")
533 (eshell-command-result-p "(zerop 0); echo $?"
534 "0\n")
535 (let ((debug-on-error nil))
536 (eshell-command-result-p "(zerop \"foo\"); echo $?"
537 "1\n")))))
538
539(ert-deftest esh-var-test/last-status-var-ext-cmd ()
540 "Test using the \"last exit status\" ($?) variable with an external command"
541 (skip-unless (executable-find "["))
542 (with-temp-eshell
543 (eshell-command-result-p "[ foo = foo ]; echo $?"
544 "0\n")
545 (eshell-command-result-p "[ foo = bar ]; echo $?"
546 "1\n")))
547
503(ert-deftest esh-var-test/last-result-var () 548(ert-deftest esh-var-test/last-result-var ()
504 "Test using the \"last result\" ($$) variable" 549 "Test using the \"last result\" ($$) variable"
505 (with-temp-eshell 550 (with-temp-eshell
506 (eshell-command-result-p "+ 1 2; + $$ 2" 551 (eshell-command-result-p "+ 1 2; + $$ 2"
507 "3\n5\n"))) 552 "3\n5\n")))
508 553
509(ert-deftest esh-var-test/last-result-var2 () 554(ert-deftest esh-var-test/last-result-var-twice ()
510 "Test using the \"last result\" ($$) variable twice" 555 "Test using the \"last result\" ($$) variable twice"
511 (with-temp-eshell 556 (with-temp-eshell
512 (eshell-command-result-p "+ 1 2; + $$ $$" 557 (eshell-command-result-p "+ 1 2; + $$ $$"
513 "3\n6\n"))) 558 "3\n6\n")))
514 559
560(ert-deftest esh-var-test/last-result-var-ext-cmd ()
561 "Test using the \"last result\" ($$) variable with an external command"
562 (skip-unless (executable-find "["))
563 (with-temp-eshell
564 ;; MS-DOS/MS-Windows have an external command 'format', which we
565 ;; don't want here.
566 (let ((eshell-prefer-lisp-functions t))
567 (eshell-command-result-p "[ foo = foo ]; format \"%s\" $$"
568 "t\n")
569 (eshell-command-result-p "[ foo = bar ]; format \"%s\" $$"
570 "nil\n"))))
571
515(ert-deftest esh-var-test/last-result-var-split-indices () 572(ert-deftest esh-var-test/last-result-var-split-indices ()
516 "Test using the \"last result\" ($$) variable with split indices" 573 "Test using the \"last result\" ($$) variable with split indices"
517 (with-temp-eshell 574 (with-temp-eshell
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index 5dc18775485..8423500ea7d 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -36,59 +36,6 @@
36 36
37;;; Tests: 37;;; Tests:
38 38
39(ert-deftest eshell-test/simple-command-result ()
40 "Test `eshell-command-result' with a simple command."
41 (should (equal (eshell-test-command-result "+ 1 2") 3)))
42
43(ert-deftest eshell-test/lisp-command ()
44 "Test `eshell-command-result' with an elisp command."
45 (should (equal (eshell-test-command-result "(+ 1 2)") 3)))
46
47(ert-deftest eshell-test/lisp-command-with-quote ()
48 "Test `eshell-command-result' with an elisp command containing a quote."
49 (should (equal (eshell-test-command-result "(eq 'foo nil)") nil)))
50
51(ert-deftest eshell-test/for-loop ()
52 "Test `eshell-command-result' with a for loop.."
53 (let ((process-environment (cons "foo" process-environment)))
54 (should (equal (eshell-test-command-result
55 "for foo in 5 { echo $foo }") 5))))
56
57(ert-deftest eshell-test/for-name-loop () ;Bug#15231
58 "Test `eshell-command-result' with a for loop using `name'."
59 (let ((process-environment (cons "name" process-environment)))
60 (should (equal (eshell-test-command-result
61 "for name in 3 { echo $name }") 3))))
62
63(ert-deftest eshell-test/for-name-shadow-loop () ; bug#15372
64 "Test `eshell-command-result' with a for loop using an env-var."
65 (let ((process-environment (cons "name=env-value" process-environment)))
66 (with-temp-eshell
67 (eshell-command-result-p "echo $name; for name in 3 { echo $name }; echo $name"
68 "env-value\n3\nenv-value\n"))))
69
70(ert-deftest eshell-test/lisp-command-args ()
71 "Test `eshell-command-result' with elisp and trailing args.
72Test that trailing arguments outside the S-expression are
73ignored. e.g. \"(+ 1 2) 3\" => 3"
74 (should (equal (eshell-test-command-result "(+ 1 2) 3") 3)))
75
76(ert-deftest eshell-test/subcommand ()
77 "Test `eshell-command-result' with a simple subcommand."
78 (should (equal (eshell-test-command-result "{+ 1 2}") 3)))
79
80(ert-deftest eshell-test/subcommand-args ()
81 "Test `eshell-command-result' with a subcommand and trailing args.
82Test that trailing arguments outside the subcommand are ignored.
83e.g. \"{+ 1 2} 3\" => 3"
84 (should (equal (eshell-test-command-result "{+ 1 2} 3") 3)))
85
86(ert-deftest eshell-test/subcommand-lisp ()
87 "Test `eshell-command-result' with an elisp subcommand and trailing args.
88Test that trailing arguments outside the subcommand are ignored.
89e.g. \"{(+ 1 2)} 3\" => 3"
90 (should (equal (eshell-test-command-result "{(+ 1 2)} 3") 3)))
91
92(ert-deftest eshell-test/pipe-headproc () 39(ert-deftest eshell-test/pipe-headproc ()
93 "Check that piping a non-process to a process command waits for the process" 40 "Check that piping a non-process to a process command waits for the process"
94 (skip-unless (executable-find "cat")) 41 (skip-unless (executable-find "cat"))
diff --git a/test/lisp/international/ucs-normalize-tests.el b/test/lisp/international/ucs-normalize-tests.el
index 27a4e70c78e..774a3ea7ec9 100644
--- a/test/lisp/international/ucs-normalize-tests.el
+++ b/test/lisp/international/ucs-normalize-tests.el
@@ -246,7 +246,7 @@ must be true for all conformant implementations:
246 ucs-normalize-tests--rule1-failing-for-partX 246 ucs-normalize-tests--rule1-failing-for-partX
247 ucs-normalize-tests--rule1-holds-p 247 ucs-normalize-tests--rule1-holds-p
248 ucs-normalize-tests--rule2-holds-p)) 248 ucs-normalize-tests--rule2-holds-p))
249 (or (byte-code-function-p (symbol-function fun)) 249 (or (compiled-function-p (symbol-function fun))
250 (byte-compile fun))) 250 (byte-compile fun)))
251 (let ((ucs-normalize-tests--chars-part1 (make-char-table 'ucs-normalize-tests t))) 251 (let ((ucs-normalize-tests--chars-part1 (make-char-table 'ucs-normalize-tests t)))
252 (setq ucs-normalize-tests--part1-rule1-failed-lines 252 (setq ucs-normalize-tests--part1-rule1-failed-lines
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index ad81d0c09ea..4dcf671f51f 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -7052,7 +7052,8 @@ This requires restrictions of file name syntax."
7052 "银河系漫游指南系列" 7052 "银河系漫游指南系列"
7053 "Автостопом по гала́ктике" 7053 "Автостопом по гала́ктике"
7054 ;; Use codepoints without a name. See Bug#31272. 7054 ;; Use codepoints without a name. See Bug#31272.
7055 "™›šbung" 7055 ;; Works on some Android systems only.
7056 (unless (tramp--test-adb-p) "™›šbung")
7056 ;; Use codepoints from Supplementary Multilingual Plane (U+10000 7057 ;; Use codepoints from Supplementary Multilingual Plane (U+10000
7057 ;; to U+1FFFF). 7058 ;; to U+1FFFF).
7058 "🌈🍒👋") 7059 "🌈🍒👋")