diff --git a/ChangeLog.5 b/ChangeLog.5 index c74daeb3aed..4f27baa2d22 100644 --- a/ChangeLog.5 +++ b/ChangeLog.5 @@ -1,3 +1,306 @@ +2025-08-14 Eli Zaretskii + + * Version 30.2 released. + +2025-08-14 Eli Zaretskii + + * README: + * configure.ac: + * exec/configure.ac: + * java/AndroidManifest.xml.in (Version-code): + * nt/README.W32: + * msdos/sed2v2.inp: Bump Emacs version to 30.2. + + * ChangeLog.5: + * etc/AUTHORS: + * etc/HISTORY: Update for Emacs 30.2. + + * admin/admin.el (set-version): Fix handling of official releases. + +2025-08-07 Vinícius Moraes (tiny change) + + Handle remote file names in cmuscheme.el + + * lisp/cmuscheme.el (scheme-load-file, scheme-compile-file): Use + 'file-local-name' to handle file names on remote systems. + (Bug#79163) + +2025-08-06 Sean Whitton + + * lisp/vc/vc.el (vc-register): Fix interactive spec (bug#79183). + +2025-07-31 James Thomas + + * doc/misc/gnus.texi (Category Syntax): Update gnus-agent-predicate. + + This updates the Gnus manual due to recent code change (bug#79123). + +2025-07-28 Robert Pluim + + Prefer "tls" to "ssl" in documentation + + * doc/misc/gnus.texi (NNTP): Refer to 'nntp-open-tls-stream'. + (Direct Functions, Customizing the IMAP Connection): Add + commentary about desirability of STARTTLS. Correct + documentation about use of GnuTLS. Use 'tls in example. + * lisp/gnus/nnimap.el (nnimap-server-port): Mention 'tls in + preference to 'ssl. + * lisp/gnus/nntp.el (nntp-open-connection-function) + (nntp-never-echoes-commands): Document 'nntp-open-tls-stream' as + preferred to 'nntp-open-ssl-stream'. + +2025-07-26 Sean Whitton + + loaddefs-generate--rubric: Note about committing ldefs-boot.el + + * lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate--rubric): + Note that ldefs-boot.el should be committed on its own. + +2025-07-21 Jim Porter + + Fix Eshell call to 'string-suffix-p' when checking for trailing newline + + * lisp/eshell/esh-io.el (eshell--output-maybe-n): Fix call. + + * test/lisp/eshell/esh-io-tests.el + (esh-io-test/output-newline/add-newline) + (esh-io-test/output-newline/no-newline) + (esh-io-test/output-newline/no-extra-newline): New tests (bug#79063). + +2025-07-21 Robert Pluim + + * etc/PROBLEMS: Describe how to work around screen reader TAB issue + +2025-07-21 Sean Whitton + + (gnus)Scoring Tips: New tip regarding header continuation lines + + * doc/misc/gnus.texi (Scoring Tips): New "Continuation lines + when scoring on other headers" tip. + +2025-07-16 Ken Mankoff + + Fix :box attribute of faces in Leuven themes. + + * etc/themes/leuven-dark-theme.el: + * etc/themes/leuven-theme.el: Fix 'lui-highlight-face' face. + (Bug#79029) + +2025-07-09 Andrea Corallo + + Nativecomp don't error with undeclared types (bug#6573) (don't merge) + + Backporting f38e969e472 from trunk to emacs-30 + + * test/src/comp-resources/comp-test-funcs.el (comp-test-76573-1-f): New + function. + * lisp/emacs-lisp/comp-cstr.el (comp-supertypes): Don't error if 'type' + is unknown. + +2025-07-06 Eli Zaretskii + + Fix 'kill-ring-deindent-mode' + + * lisp/indent-aux.el + (kill-ring-deindent-buffer-substring-function): Fix deindenting + for modes which set 'indent-tab-mode' to nil. (Bug#77981) + + (cherry picked from commit 1c7fe501fedb41aaf5b22d82dab5a365f86e4c85) + +2025-07-04 Yuan Fu + + Handle ts_node_type return NULL (bug#78938) + + * src/treesit.c (treesit_traverse_match_predicate): Handle the + case when ts_node_type returns NULL. + (Ftreesit_node_type): Add some comment. + +2025-07-04 Eli Zaretskii + + Improve documentation of 'warning-display-at-bottom' + + * lisp/emacs-lisp/warnings.el (warning-display-at-bottom): + * doc/lispref/display.texi (Warning Options): + * doc/emacs/windows.texi (Temporary Displays): + * etc/NEWS: Improve documentation of 'warning-display-at-bottom'. + See https://lists.gnu.org/archive/html/emacs-devel/2025-07/msg00024.html + for more details. + +2025-07-04 Yuan Fu + + Handle the case when ts_node_type returns NULL (bug#78938) + + * src/treesit.c (Ftreesit_node_type): Handle NULL. + +2025-06-29 Jim Porter + + Populate the ':title' in EWW when defaulting to readable mode + + Do not merge to master. + + * lisp/net/eww.el (eww-display-document): Always render the full + document first to populate ':title' (bug#77299). + +2025-06-28 Liam Hupfer + + bug#78901: [PATCH] js-ts-mode: Fix auto-mode-alist regexp + + Align the js-ts-mode entry with the javascript-mode entries in the + default auto-mode-alist value in lisp/files.el. Otherwise, js-ts-mode is + not associated with .js files. + + * lisp/progmodes/js.el (js-ts-mode): Fix auto-mode-alist regexp. + + Fixes: 2023-01-20 6b2f85caa6ca "Make tree-sitter based modes optional" + +2025-06-25 Eli Zaretskii + + Fix 'insert-directory' in Turkish language-environment + + * lisp/files.el (insert-directory-clean, insert-directory): Use + case-sensitive search for "//DIRED//" and similar strings. + (Bug#78894) + +2025-06-25 Michael Albinus + + Fix job control in remote shell + + * lisp/net/tramp-sh.el (tramp-methods) : + Adapt `tramp-direct-async' argument. (Bug#71050, Bug#71259) + +2025-06-21 Eli Zaretskii + + Workaround for "M-x man" on macOS 15 and later + + * lisp/man.el (Man-init-defvars): Workaround for macOS Sed. Do + not merge to master. (Bug#77944) + +2025-06-11 Sean Whitton + + Insert missing step to make use of directory tracking OSC codes + + * doc/emacs/misc.texi (Interactive Shell): Say to add + comint-osc-process-output to comint-output-filter-function. + +2025-06-11 Robert Pluim + + * lisp/keymap.el (keymap-set): Refer to 'key-description'. (Bug#78714) + +2025-06-11 Yuan Fu + + Support new tree-sitter grammar filename format (bug#78754) + + Previously Emacs only looks for filenames like + libtree-sitter-json.so.0.0. Now Emacs also look for filenames + like libtree-sitter-json.so.15.0. + + * src/treesit.c: + (treesit_load_language_push_for_each_suffix): Add versioned + candidate to candidate list too. + +2025-06-10 Pip Cet + + Fix crash when evaluating "(signal nil 5)" (bug#78738) + + The docstring already warns against calling signal with a nil + error symbol, which is for internal use only, but we can avoid crashing + in this case. + + * src/eval.c (Fsignal): Produce a "peculiar error" for more arguments + involving non-lists. + +2025-06-08 Michael Albinus + + Adapt emba integration (don't merge) + + * test/infra/Dockerfile.emba (emacs-inotify): Don't install clangd. + + * test/infra/gitlab-ci.yml (.job-template): Make actions in + after_script more robust. + +2025-06-03 Xiyue Deng + + Make xoauth2 auth fail when a smtp server replies 334 (Bug#78366) + + * lisp/mail/smtpmail.el (smtpmail-try-auth-method): Throw error 535 + when receiving a "334 server challenge" reply. + + (cherry picked from commit 53371c959462a677a29ee869b3b6627facf3ed79) + +2025-05-31 Eli Zaretskii + + Revert "; * lisp/subr.el (setq-local): Doc fix (bug#78644)." + + This reverts commit cb9556d669c037c4e2f1a9c80adacad55948c706. + Some of its parts were not supposed to be installed. + +2025-05-28 Stephen Berman + + Fix bug in 'todo-jump-to-category' (bug#78608) + + * lisp/calendar/todo-mode.el (todo-jump-to-category): Eliminate + comparison of the number of Todo categories before and after + specifying the category to jump to and replace it by a check of + whether there are any items in the category, since an existing + category should always have at least one item (perhaps done or + archived). + +2025-05-27 Michael Albinus + + Fix gitlab-ci.yml (don't merge to master) + + * test/infra/gitlab-ci.yml (.job-template): Fix config.log name. + (test-filenotify-gio, test-eglot): Fix formatting. + +2025-05-25 Konstantin Kharlamov + + typescript-ts-mode: Improve function body indentation (bug#78121) + + Older code was calculating body indentation depending on function + parameters alignment. This is incorrect, because if parameters are + misaligned, so will the function body. Instead, use offset of the + previous standalone parent. + + * lisp/progmodes/typescript-ts-mode.el: + (typescript-ts-mode--indent-rules): Stop depending on function + parameters indentation for calculating body content and the closing + `}'. + * test/lisp/progmodes/typescript-ts-mode-resources/indent.erts: + (Function body with params misindented (bug#78121)): Add new test. + +2025-05-24 Eli Zaretskii + + Fix documentation of use-package's ':hook' keyword + + * doc/misc/use-package.texi (Hooks): Document how to add several + functions to the same hook (bug#77609). + +2025-05-22 Michael Albinus + + * test/infra/gitlab-ci.yml (.job-template): Make it more robust. + +2025-05-20 Stephen Berman + + Fix todo-mode item insertion bug (bug#78506) + + * lisp/calendar/todo-mode.el (todo-insert-item--next-param): Unset + transient keymap on completing default or copy item insertion + command, to ensure that the next Todo mode key is recognized. + +2025-05-19 Jostein Kjønigsen + + Add support for Pyrefly LSP for Python + + * lisp/progmodes/eglot.el (eglot-server-programs): Add config + for Pyrefly. (Bug#78492) + +2025-05-18 Michael Albinus + + Adapt Tramp version in customize-package-emacs-version-alist + + * lisp/net/trampver.el (customize-package-emacs-version-alist): + Add Tramp version integrated in Emacs 30.1. + 2025-05-17 Eli Zaretskii Fix saving abbrevs by 'abbrev-edit-save-buffer' @@ -1157,7 +1460,7 @@ This file records repository revisions from commit 1cda0967b4d3c815fc610794ad6a8fc2b913a3c5 (exclusive) to -commit 299d3a440121ff6692a85615ff97e6ad4dde91db (inclusive). +commit 49d64bfb1a4ca5fc8b3a4d215fb6cabbb9780f9b (inclusive). See ChangeLog.4 for earlier changes. ;; Local Variables: diff --git a/admin/MAINTAINERS b/admin/MAINTAINERS index 945e69fc690..c8388f74577 100644 --- a/admin/MAINTAINERS +++ b/admin/MAINTAINERS @@ -96,6 +96,10 @@ Dmitry Gutov test/indent/ruby.rb lisp/progmodes/xref.el lisp/progmodes/project.el + lisp/thread.el + src/thread.c + + Thread-related code in src/process.c Ulf Jasper Newsticker @@ -323,12 +327,14 @@ Michael Albinus lisp/autorevert.el lisp/eshell/em-tramp.el lisp/files.el (file-name-non-special) + lisp/files-x.el (connection-local variables) lisp/net/ange-ftp.el lisp/notifications.el lisp/shadowfile.el test/infra/* test/lisp/autorevert-tests.el test/lisp/files-tests.el (file-name-non-special) + test/lisp/files-x-tests.el (connection-local variables) test/lisp/shadowfile-tests.el test/src/inotify-test.el @@ -381,6 +387,10 @@ Harald Jörg Spencer Baugh lisp/progmodes/flymake.el + lisp/thread.el + src/thread.c + + Thread-related code in src/process.c Yuan Fu lisp/progmodes/c-ts-mode.el diff --git a/admin/admin.el b/admin/admin.el index 542556a65e0..7e761c3f1f4 100644 --- a/admin/admin.el +++ b/admin/admin.el @@ -128,8 +128,13 @@ Root must be the root of an Emacs source tree." (submatch (1+ (in "0-9.")))))) (set-version-in-file root "java/AndroidManifest.xml.in" (apply #'format "%02d%02d%02d000" - (mapcar #'string-to-number - (split-string version "\\."))) + (let ((ver-list + (mapcar #'string-to-number + (split-string version "\\.")))) + ;; Official releases are XX.YY, not XX.YY.ZZ + (if (= 2 (length ver-list)) + (setq ver-list (append ver-list '(0)))) + ver-list)) admin-android-version-code-regexp) (set-version-in-file root "nt/README.W32" version (rx (and "version" (1+ space) diff --git a/admin/authors.el b/admin/authors.el index b9f5f170fc0..66346b46091 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -187,6 +187,7 @@ files.") ("Mark D. Baushke" "Mark D Baushke") ("Mark E. Shoulson" "Mark Shoulson") ("Marko Kohtala" "Kohtala Marko") + ("Mattias Roux" "mattias@kojin\\.tech") ("Maxim Nikulin" "Max Nikulin") ("Agustín Martín" "Agustin Martin" "Agustín Martín Domingo") ("Martin Lorentzon" "Martin Lorentzson") diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt index 22e76a0ac2e..61d19e54b8e 100644 --- a/admin/make-tarball.txt +++ b/admin/make-tarball.txt @@ -388,9 +388,9 @@ add the new NEWS file as news/NEWS.xx.y Copy new etc/MACHINES to MACHINES and CONTRIBUTE to CONTRIBUTE For every new release, a banner is displayed on top of the emacs.html -page. Uncomment and the release banner in emacs.html. Keep it on the -page for about a month, then comment it again. The new release banner -looks like this: +page. Uncomment the release banner in emacs.html. Keep it on the page +for about a month, then comment it again. The new release banner looks +like this:
@@ -398,6 +398,16 @@ looks like this:
+Add the information about the new release in the "Releases" section of +emacs.html, which begins like this: + +
+
+ + + +

+ Also, make sure the copyright years at the bottom of emacs.html are up-to-date. diff --git a/admin/nt/dist-build/emacs.nsi b/admin/nt/dist-build/emacs.nsi index 9239eb07ec7..13278749871 100644 --- a/admin/nt/dist-build/emacs.nsi +++ b/admin/nt/dist-build/emacs.nsi @@ -70,6 +70,9 @@ Section # create uninstaller WriteUninstaller "$UninstallerPath" + # request to set x64 registry keys + SetRegView 64 + # add registry key to enable uninstall from control panel WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "GNU Emacs ${VERSION_BRANCH}" WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$\"$UninstallerPath$\"" diff --git a/admin/tree-sitter/treesit-admin.el b/admin/tree-sitter/treesit-admin.el index 2be6fe42f27..2e85d6b0d8c 100644 --- a/admin/tree-sitter/treesit-admin.el +++ b/admin/tree-sitter/treesit-admin.el @@ -83,6 +83,7 @@ go-ts-mode heex-ts-mode html-ts-mode + mhtml-ts-mode java-ts-mode js-ts-mode json-ts-mode @@ -107,6 +108,7 @@ go-ts-mode heex-ts-mode html-ts-mode + mhtml-ts-mode java-ts-mode js json-ts-mode diff --git a/configure.ac b/configure.ac index 84bd5d51351..ed69d9cd024 100644 --- a/configure.ac +++ b/configure.ac @@ -2247,9 +2247,9 @@ AC_CACHE_CHECK([for flag to work around GCC union bugs], [/* Work around GCC bugs 117423 and 119085 re holes in unions: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117423 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119085 - These are fixed in GCC 15.2. + These are fixed in GCC 14.4 and 15.2. - Working wround them also works around GCC bug 58416 + Working around them also works around GCC bug 58416 with double in unions on x86, where the generated insns copy non-floating-point data via fldl/fstpl instruction pairs. This can misbehave if the data's bit pattern looks like a NaN. diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 602c8e5bfb2..e49823384ce 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -702,14 +702,14 @@ the directory. @kindex touchscreen-hold @r{(Dired)} @findex dired-click-to-select-mode @findex dired-enable-click-to-select-mode -Enter a ``click to select'' mode, where using the mouse button -@kbd{mouse-2} on a file name will cause its mark to be toggled. This -mode is useful when performing file management using a touch screen -device. +Enter a ``click to select'' mode (@code{dired-click-to-select-mode}), +where using the mouse button @kbd{mouse-2} on a file name will cause its +mark to be toggled. This mode is useful when performing file management +using a touch screen device. -It is enabled when a ``hold'' gesture (@pxref{Touchscreens}) is -detected over a file name, and is automatically disabled once a Dired -command operates on the marked files. +It is enabled when a ``hold'' gesture (@pxref{Touchscreens}) is detected +over a file name, and is automatically disabled once a Dired command +that operates on the marked files finishes. @end table @node Operating on Files diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index ffa3b7f2a58..3de00fe8684 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1070,11 +1070,18 @@ non-@code{nil}, @kbd{C-x v I} becomes a prefix key, and @code{vc-log-incoming} becomes bound to @kbd{C-x v I L}. @item M-x vc-root-diff-incoming -Display a diff of the changes that a pull operation will retrieve. +Display a diff of all changes that a pull operation will retrieve. If you customize @code{vc-use-incoming-outgoing-prefixes} to non-@code{nil}, this command becomes available on @kbd{C-x v I D}. +@item M-x vc-diff-incoming +Display a diff of changes that a pull operation will retrieve, but +limited to the current fileset. + +If you customize @code{vc-use-incoming-outgoing-prefixes} to +non-@code{nil}, this command becomes available on @kbd{C-x v I =}. + @item C-x v O Display log entries for the changes that will be sent by the next ``push'' operation (@code{vc-log-outgoing}). @@ -1084,12 +1091,19 @@ non-@code{nil}, @kbd{C-x v O} becomes a prefix key, and @code{vc-log-outgoing} becomes bound to @kbd{C-x v O L}. @item M-x vc-root-diff-outgoing -Display a diff of the changes that will be sent by the next push +Display a diff of all changes that will be sent by the next push operation. If you customize @code{vc-use-incoming-outgoing-prefixes} to non-@code{nil}, this command is bound to @kbd{C-x v O D}. +@item M-x vc-diff-outgoing +Display a diff of changes that will be sent by the next push operation, +but limited to the current fileset. + +If you customize @code{vc-use-incoming-outgoing-prefixes} to +non-@code{nil}, this command becomes available on @kbd{C-x v O =}. + @item C-x v h Display the history of changes made in the region of file visited by the current buffer (@code{vc-region-history}). @@ -1176,13 +1190,21 @@ version control system can be a branch name. @findex vc-root-diff-outgoing The closely related commands @code{vc-root-diff-incoming} and @code{vc-root-diff-outgoing} are the diff analogues of -@code{vc-log-incoming} and @code{vc-log-outgoing}. These display a diff -buffer reporting the changes that would be pulled or pushed. You can +@code{vc-log-incoming} and @code{vc-log-outgoing}. These display diff +buffers reporting the changes that would be pulled or pushed. You can use a prefix argument here too to specify a particular remote location. @code{vc-root-diff-outgoing} is useful as a way to preview your push and quickly check that all and only the changes you intended to include were committed and will be pushed. +@findex vc-diff-incoming +@findex vc-diff-outgoing + The commands @code{vc-diff-incoming} and @code{vc-diff-outgoing} are +very similar. They also display changes that would be pulled or pushed. +The difference is that the diffs reported are limited to the current +fileset. Don't forget that actual pull and push operations always +affect the whole working tree, not just the current fileset. + @cindex VC log buffer, commands in @cindex vc-log buffer In the @file{*vc-change-log*} buffer, you can use the following keys diff --git a/doc/emacs/vc1-xtra.texi b/doc/emacs/vc1-xtra.texi index c768910349f..72e660a2def 100644 --- a/doc/emacs/vc1-xtra.texi +++ b/doc/emacs/vc1-xtra.texi @@ -285,7 +285,11 @@ tree. Add a new working tree. @item C-x v w w -Visit this file in another working tree. +Visit this file or directory in another working tree. + +@item C-x v w s +Invoke @kbd{C-x p p} (@code{project-switch-project}) but limited to +other working trees. @item C-x v w x Delete a working tree you no longer need. @@ -313,12 +317,24 @@ new working tree. @findex vc-switch-working-tree Once your repository has other working trees, you can use the command @kbd{C-x v w w} (@code{vc-switch-working-tree}) to switch between them. -It tries to find the analogue of the current buffer's file -under another working tree. Typically the sets of workfiles -under different working trees differ more in file contents than in which -files do and do not exist. In other words, the file the -current buffer visits probably exists in other working trees too, and -this command lets you switch to those versions of the file. +It tries to find the analogue of the current buffer's file or directory +under another working tree. Typically the sets of workfiles under +different working trees differ more in file contents than in which files +do and do not exist. In other words, the file or directory the current +buffer visits probably exists in other working trees too, and this +command lets you switch to those versions of the file. + +@kindex C-x v w s +@findex vc-working-tree-switch-project +An alternative way to switch between working trees is @kbd{C-x v w s} +(@code{vc-working-tree-switch-project}). This prompts you to select a +working tree, and then displays a menu of commands to operate on it. +This is in fact just @kbd{C-x p p} (@code{project-switch-project}) +(@pxref{Switching Projects}) but with the selection of projects limited +to other working trees. The main difference between @kbd{C-x v w w} and +@kbd{C-x v w s} is that the former looks for an analogue of the current +buffer in the other working tree while the latter considers the other +working tree as a whole, independent project. @kindex C-x v w x @kindex C-x v w R diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi index 9473f189c25..4f04dc542eb 100644 --- a/doc/emacs/windows.texi +++ b/doc/emacs/windows.texi @@ -158,6 +158,8 @@ this option is @code{nil}. @table @kbd @item C-x o Select another window (@code{other-window}). +@item C-x O +Select another window, backwards (@code{other-window-backward}). @item C-M-v Scroll the next window upward (@code{scroll-other-window}). @item C-M-S-v @@ -183,7 +185,8 @@ cycle in the opposite order. When the minibuffer is active, the minibuffer window is the last window in the cycle; you can switch from the minibuffer window to one of the other windows, and later switch back and finish supplying the minibuffer argument that is requested. -@xref{Minibuffer Edit}. +@xref{Minibuffer Edit}. @kbd{C-x O} is similar, but defaults to the +opposite order. @findex next-window-any-frame The @code{other-window} command will normally only switch to the next diff --git a/doc/lispref/backups.texi b/doc/lispref/backups.texi index f3f0902f364..9e262346edb 100644 --- a/doc/lispref/backups.texi +++ b/doc/lispref/backups.texi @@ -719,7 +719,7 @@ preserved, but this is up to the specific @code{revert-buffer-function} implementation. @end deffn -@defvar revert-buffer-in-progress-p +@defvar revert-buffer-in-progress @code{revert-buffer} binds this variable to a non-@code{nil} value while it is working. @end defvar @@ -852,6 +852,13 @@ It is important to assure that point does not continuously jump around as a consequence of auto-reverting. Of course, moving point might be inevitable if the buffer radically changes. +@defvar auto-revert-buffer-in-progress +@code{auto-revert-buffer} binds this variable to a non-@code{nil} value +while it is working. This can be used by major mode +@code{revert-buffer-function} implementations to suppress messages in +Auto Revert modes, for example. +@end defvar + @defvar inhibit-auto-revert-buffers When the current buffer is member of this variable (a list of buffers), auto-reverting is suppressed for that buffer. This is useful if serious diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 4d00d27bd46..8df8cd215f5 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -1489,8 +1489,8 @@ Each clause normally has the form @w{@code{(@var{condition} @findex bind* @code{(bind* @var{bindings}@dots{})} means to bind @var{bindings} (like the bindings list in @code{let*}, @pxref{Local Variables}) for the body -of the clause. As a condition, it counts as true if the first binding's -value is non-@code{nil}. +of the clause, and all subsequent clauses. As a condition, it counts as +true if the first binding's value is non-@code{nil}. @findex match* @findex pcase* diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi index 15836591032..f16190b85c9 100644 --- a/doc/lispref/edebug.texi +++ b/doc/lispref/edebug.texi @@ -256,38 +256,47 @@ commands; all except for @kbd{S} resume execution of the program, at least for a certain distance. @table @kbd +@findex edebug-stop @item S Stop: don't execute any more of the program, but wait for more Edebug commands (@code{edebug-stop}). @c FIXME Does not work. https://debbugs.gnu.org/9764 +@findex edebug-step-mode @item @key{SPC} Step: stop at the next stop point encountered (@code{edebug-step-mode}). +@findex edebug-next-mode @item n Next: stop at the next stop point encountered after an expression (@code{edebug-next-mode}). Also see @code{edebug-forward-sexp} in @ref{Jumping}. +@findex edebug-trace-mode @item t Trace: pause (normally one second) at each Edebug stop point (@code{edebug-trace-mode}). +@findex edebug-Trace-fast-mode @item T Rapid trace: update the display at each stop point, but don't actually pause (@code{edebug-Trace-fast-mode}). +@findex edebug-go-mode @item g Go: run until the next breakpoint (@code{edebug-go-mode}). @xref{Breakpoints}. +@findex edebug-continue-mode @item c Continue: pause one second at each breakpoint, and then continue (@code{edebug-continue-mode}). +@findex edebug-Continue-fast-mode @item C Rapid continue: move point to each breakpoint, but don't pause (@code{edebug-Continue-fast-mode}). +@findex edebug-Go-nonstop-mode @item G Go non-stop: ignore breakpoints (@code{edebug-Go-nonstop-mode}). You can still stop the program by typing @kbd{S}, or any editing command. @@ -345,25 +354,30 @@ in trace mode or continue mode. The default is 1 second. The commands described in this section execute until they reach a specified location. All except @kbd{i} make a temporary breakpoint to -establish the place to stop, then switch to go mode. Any other -breakpoint reached before the intended stop point will also stop -execution. @xref{Breakpoints}, for the details on breakpoints. +establish the place to stop, then switch to go mode (@pxref{Edebug +Execution Modes}). Any other breakpoint reached before the intended +stop point will also stop execution. @xref{Breakpoints}, for the +details on breakpoints. These commands may fail to work as expected in case of nonlocal exit, as that can bypass the temporary breakpoint where you expected the program to stop. @table @kbd +@findex edebug-goto-here @item h Proceed to the stop point near where point is (@code{edebug-goto-here}). +@findex edebug-forward-sexp @item f Run the program for one expression (@code{edebug-forward-sexp}). +@findex edebug-step-out @item o Run the program until the end of the containing sexp (@code{edebug-step-out}). +@findex edebug-step-in @item i Step into the function or macro called by the form after point (@code{edebug-step-in}). @@ -397,7 +411,7 @@ containing sexp is a function definition itself, @kbd{o} continues until just before the last sexp in the definition. If that is where you are now, it returns from the function and then stops. In other words, this command does not exit the currently executing function unless you are -positioned after the last sexp. +positioned after the last sexp of that function. Normally, the @kbd{h}, @kbd{f}, and @kbd{o} commands display ``Break'' and pause for @code{edebug-sit-for-seconds} before showing the result @@ -421,14 +435,17 @@ arrange to deinstrument it. Some miscellaneous Edebug commands are described here. @table @kbd +@findex edebug-help @item ? Display the help message for Edebug (@code{edebug-help}). +@findex abort-recursive-edit @r{(Edebug)} @item a @itemx C-] Abort one level back to the previous command level -(@code{abort-recursive-edit}). +(@code{abort-recursive-edit}). @xref{Recursive Editing}. +@findex top-level @r{(Edebug)} @item q Return to the top level editor command loop (@code{top-level}). This exits all recursive editing levels, including all levels of Edebug @@ -436,14 +453,17 @@ activity. However, instrumented code protected with @code{unwind-protect} or @code{condition-case} forms may resume debugging. +@findex edebug-top-level-nonstop @item Q Like @kbd{q}, but don't stop even for protected code (@code{edebug-top-level-nonstop}). +@findex edebug-previous-result @item r Redisplay the most recently known expression result in the echo area (@code{edebug-previous-result}). +@findex edebug-pop-to-backtrace @item d Display a backtrace, excluding Edebug's own functions for clarity (@code{edebug-pop-to-backtrace}). @@ -473,9 +493,10 @@ display a backtrace of all the pending evaluations with @kbd{d}. @node Breaks @subsection Breaks -Edebug's step mode stops execution when the next stop point is reached. -There are three other ways to stop Edebug execution once it has started: -breakpoints, the global break condition, and source breakpoints. +Edebug's step mode (@pxref{Edebug Execution Modes}) stops execution when +the next stop point is reached. There are three other ways to stop +Edebug execution once it has started: breakpoints, the global break +condition, and source breakpoints. @menu * Breakpoints:: Breakpoints at stop points. @@ -495,6 +516,9 @@ the first one at or after point in the source code buffer. Here are the Edebug commands for breakpoints: @table @kbd +@findex edebug-set-breakpoint +@vindex edebug-enabled-breakpoint @r{(face)} +@vindex edebug-disabled-breakpoint @r{(face)} @item b Set a breakpoint at the stop point at or after point (@code{edebug-set-breakpoint}). If you use a prefix argument, the @@ -502,26 +526,34 @@ breakpoint is temporary---it turns off the first time it stops the program. An overlay with the @code{edebug-enabled-breakpoint} or @code{edebug-disabled-breakpoint} faces is put at the breakpoint. +@findex edebug-unset-breakpoint @item u Unset the breakpoint (if any) at the stop point at or after point (@code{edebug-unset-breakpoint}). +@findex edebug-unset-breakpoints @item U Unset any breakpoints in the current form (@code{edebug-unset-breakpoints}). +@findex edebug-toggle-disable-breakpoint @item D Toggle whether to disable the breakpoint near point (@code{edebug-toggle-disable-breakpoint}). This command is mostly useful if the breakpoint is conditional and it would take some work to recreate the condition. +@findex edebug-set-conditional-breakpoint @item x @var{condition} @key{RET} Set a conditional breakpoint which stops the program only if evaluating @var{condition} produces a non-@code{nil} value (@code{edebug-set-conditional-breakpoint}). With a prefix argument, the breakpoint is temporary. +@item X @var{condition} @key{RET} +Set @code{edebug-global-break-condition} to @var{condition}. + +@findex edebug-next-breakpoint @item B Move point to the next breakpoint in the current definition (@code{edebug-next-breakpoint}). @@ -542,6 +574,8 @@ conditional breakpoint, use @kbd{x}, and specify the condition expression in the minibuffer. Setting a conditional breakpoint at a stop point that has a previously established conditional breakpoint puts the previous condition expression in the minibuffer so you can edit it. +(You can also use @kbd{X} to set the global break condition, to be +evaluated at every stop point, @pxref{Global Break Condition}.) You can make a conditional or unconditional breakpoint @dfn{temporary} by using a prefix argument with the command to set the @@ -566,8 +600,9 @@ point in the buffer. condition is satisfied, no matter where that may occur. Edebug evaluates the global break condition at every stop point; if it evaluates to a non-@code{nil} value, then execution stops or pauses -depending on the execution mode, as if a breakpoint had been hit. If -evaluating the condition gets an error, execution does not stop. +depending on the execution mode (@pxref{Edebug Execution Modes}), as if +a breakpoint had been hit. If evaluating the condition gets an error, +execution does not stop. @findex edebug-set-global-break-condition The condition expression is stored in @@ -603,7 +638,8 @@ argument reaches zero: When the @code{fac} definition is instrumented and the function is called, the call to @code{edebug} acts as a breakpoint. Depending on -the execution mode, Edebug stops or pauses there. +the execution mode (@pxref{Edebug Execution Modes}), Edebug stops or +pauses there. If no instrumented code is being executed when @code{edebug} is called, that function calls @code{debug}. @@ -640,17 +676,20 @@ configuration is the collection of windows and contents that were in effect outside of Edebug. @table @kbd +@findex edebug-view-outside @item P @itemx v Switch to viewing the outside window configuration (@code{edebug-view-outside}). Type @kbd{C-x X w} to return to Edebug. +@findex edebug-bounce-point @item p Temporarily display the outside current buffer with point at its outside position (@code{edebug-bounce-point}), pausing for one second before returning to Edebug. With a prefix argument @var{n}, pause for @var{n} seconds instead. +@findex edebug-where @item w Move point back to the current stop point in the source code buffer (@code{edebug-where}). @@ -659,6 +698,7 @@ If you use this command in a different window displaying the same buffer, that window will be used instead to display the current definition in the future. +@findex edebug-toggle-save-windows @item W @c Its function is not simply to forget the saved configuration -- dan Toggle whether Edebug saves and restores the outside window @@ -697,6 +737,7 @@ explicitly saves and restores. @xref{The Outside Context}, for details on this process. @table @kbd +@findex edebug-eval-expression @item e @var{exp} @key{RET} Evaluate expression @var{exp} in the context outside of Edebug (@code{edebug-eval-expression}). That is, Edebug tries to minimize @@ -707,30 +748,47 @@ pretty-print the result there. By default, this command suppresses the debugger during evaluation, so that an error in the evaluated expression won't add a new error on top of the existing one. -Set the @code{debug-allow-recursive-debug} user option to a -non-@code{nil} value to override this. +Set the @code{debug-allow-recursive-debug} user option (@pxref{Error +Debugging}) to a non-@code{nil} value to override this. +@findex eval-expression @r{(Edebug)} @item M-: @var{exp} @key{RET} Evaluate expression @var{exp} in the context of Edebug itself (@code{eval-expression}). +@findex edebug-eval-last-sexp @item C-x C-e Evaluate the expression before point, in the context outside of Edebug -(@code{edebug-eval-last-sexp}). With the prefix argument of zero -(@kbd{C-u 0 C-x C-e}), don't shorten long items (like strings and -lists). Any other prefix will result in the value being -pretty-printed in a separate buffer. +(@code{edebug-eval-last-sexp}) and show the value in the minibuffer. +With the prefix argument of zero (@kbd{C-u 0 C-x C-e}), don't shorten +long items (like strings and lists) when showing the value, due to +@code{edebug-print-length} and @code{edebug-print-level} +(@pxref{Printing in Edebug}). Any other prefix will result in the value +being pretty-printed in a separate buffer instead of the minibuffer. @end table +@xref{Eval List}, for additional Edebug features related to evaluating +lists of expressions interactively. + +@cindex lexical binding (Edebug) +@findex cl-macrolet @r{(Edebug)} +@findex cl-symbol-macrolet @r{(Edebug)} + Edebug supports evaluation of expressions containing references to +lexically bound symbols created by the following constructs in +@file{cl-lib.el}: @code{cl-macrolet} and @code{cl-symbol-macrolet}. +@c FIXME? What about lexical-binding = t? + @node Eval List @subsection Evaluation List Buffer +@cindex evaluation list buffer You can use the @dfn{evaluation list buffer}, called @file{*edebug*}, to evaluate expressions interactively. You can also set up the @dfn{evaluation list} of expressions to be evaluated automatically each time Edebug updates the display. @table @kbd +@findex edebug-visit-eval-list @item E Switch to the evaluation list buffer @file{*edebug*} (@code{edebug-visit-eval-list}). @@ -741,20 +799,25 @@ Interaction mode (@pxref{Lisp Interaction,,, emacs, The GNU Emacs Manual}) as well as these special commands: @table @kbd +@findex edebug-eval-print-last-sexp @item C-j Evaluate the expression before point, in the outside context, and insert the value in the buffer (@code{edebug-eval-print-last-sexp}). With prefix argument of zero (@kbd{C-u 0 C-j}), don't shorten long -items (like strings and lists). +items (like strings and lists) due to @code{edebug-print-length} and +@code{edebug-print-level} (@pxref{Printing in Edebug}). +@findex edebug-eval-last-sexp @item C-x C-e Evaluate the expression before point, in the context outside of Edebug (@code{edebug-eval-last-sexp}). +@findex edebug-update-eval-list @item C-c C-u Build a new evaluation list from the contents of the buffer (@code{edebug-update-eval-list}). +@findex edebug-delete-eval-item @item C-c C-d Delete the evaluation list group that point is in (@code{edebug-delete-eval-item}). @@ -797,24 +860,36 @@ not interrupt your debugging. several expressions have been added to it: @smallexample +@group (current-buffer) # ;--------------------------------------------------------------- +@end group +@group (selected-window) # ;--------------------------------------------------------------- +@end group +@group (point) 196 ;--------------------------------------------------------------- +@end group +@group bad-var "Symbol's value as variable is void: bad-var" ;--------------------------------------------------------------- +@end group +@group (recursion-depth) 0 ;--------------------------------------------------------------- +@end group +@group this-command eval-last-sexp ;--------------------------------------------------------------- +@end group @end smallexample To delete a group, move point into it and type @kbd{C-c C-d}, or simply @@ -825,8 +900,9 @@ the expression at a suitable place, insert a new comment line, then type contents don't matter. After selecting @file{*edebug*}, you can return to the source code -buffer with @kbd{C-c C-w}. The @file{*edebug*} buffer is killed when -you continue execution, and recreated next time it is needed. +buffer with @kbd{C-c C-w} (@pxref{Edebug Views}). The @file{*edebug*} +buffer is killed when you continue execution, and recreated next time it +is needed. @node Printing in Edebug @subsection Printing in Edebug @@ -860,8 +936,10 @@ to a non-@code{nil} value. Here is an example of code that creates a circular structure: @example +@group (setq a (list 'x 'y)) (setcar a a) +@end group @end example @noindent @@ -883,11 +961,14 @@ printing results. The default value is @code{t}. @node Trace Buffer @subsection Trace Buffer @cindex trace buffer +@cindex Edebug trace buffer +@cindex tracing in Edebug Edebug can record an execution trace, storing it in a buffer named @file{*edebug-trace*}. This is a log of function calls and returns, showing the function names and their arguments and values. To enable -trace recording, set @code{edebug-trace} to a non-@code{nil} value. +trace recording, set @code{edebug-trace} to a non-@code{nil} value +(@pxref{Edebug Options}). Making a trace buffer is not the same thing as using trace execution mode (@pxref{Edebug Execution Modes}). @@ -918,7 +999,7 @@ value of the last form in @var{body}. @defun edebug-trace format-string &rest format-args This function inserts text in the trace buffer. It computes the text -with @code{(apply 'format @var{format-string} @var{format-args})}. +with @w{@code{(apply 'format @var{format-string} @var{format-args})}}. It also appends a newline to separate entries. @end defun @@ -945,10 +1026,10 @@ correctly; Edebug will tell you when you have tried enough different conditions that each form has returned two different values. Coverage testing makes execution slower, so it is only done if -@code{edebug-test-coverage} is non-@code{nil}. Frequency counting is -performed for all executions of an instrumented function, even if the -execution mode is Go-nonstop, and regardless of whether coverage testing -is enabled. +@code{edebug-test-coverage} is non-@code{nil} (@pxref{Edebug Options}). +Frequency counting is performed for all executions of an instrumented +function, even if the execution mode is Go-nonstop, and regardless of +whether coverage testing is enabled. @kindex C-x X = @findex edebug-temp-display-freq-count @@ -981,6 +1062,7 @@ breakpoint, and setting @code{edebug-test-coverage} to @code{t}, when the breakpoint is reached, the frequency data looks like this: @example +@group (defun fac (n) (if (= n 0) (edebug)) ;#6 1 = =5 @@ -989,7 +1071,8 @@ the breakpoint is reached, the frequency data looks like this: (* n (fac (1- n))) ;# 5 0 1)) -;# 0 +a;# 0 +@end group @end example The comment lines show that @code{fac} was called 6 times. The @@ -1030,15 +1113,19 @@ using Edebug. You can also enlarge the value of @code{edebug-max-depth} if Edebug reaches the limit of recursion depth instrumenting code that contains very large quoted lists. +@vindex executing-kbd-macro @r{(Edebug)} @item The state of keyboard macro execution is saved and restored. While Edebug is active, @code{executing-kbd-macro} is bound to @code{nil} -unless @code{edebug-continue-kbd-macro} is non-@code{nil}. +unless @code{edebug-continue-kbd-macro} is non-@code{nil} (@pxref{Edebug +Options}). @end itemize @node Edebug Display Update @subsubsection Edebug Display Update +@cindex Edebug and display updates +@cindex display updates, and Edebug @c This paragraph is not filled, because LaLiberte's conversion script @c needs an xref to be on just one line. @@ -1059,13 +1146,13 @@ following data (though some of them are deliberately not restored if an error or quit signal occurs). @itemize @bullet -@item @cindex current buffer point and mark (Edebug) +@item Which buffer is current, and the positions of point and the mark in the current buffer, are saved and restored. -@item @cindex window configuration (Edebug) +@item The outside window configuration is saved and restored if @code{edebug-save-windows} is non-@code{nil} (@pxref{Edebug Options}). If the value of @code{edebug-save-windows} is a list, only the listed @@ -1079,7 +1166,7 @@ The window start and horizontal scrolling of the source code buffer are not restored, however, so that the display remains coherent within Edebug. @cindex buffer point changed by Edebug -@cindex edebug overwrites buffer point position +@cindex Edebug overwrites buffer point position Saving and restoring the outside window configuration can sometimes change the positions of point in the buffers on which the Lisp program you are debugging operates, especially if your program moves point. @@ -1091,11 +1178,14 @@ set @code{edebug-save-windows} to @code{nil} The value of point in each displayed buffer is saved and restored if @code{edebug-save-displayed-buffer-points} is non-@code{nil}. +@vindex overlay-arrow-position @r{(Edebug)} +@vindex overlay-arrow-string @r{(Edebug)} @item The variables @code{overlay-arrow-position} and @code{overlay-arrow-string} are saved and restored, so you can safely invoke Edebug from the recursive edit elsewhere in the same buffer. +@vindex cursor-in-echo-area @r{(Edebug)} @item @code{cursor-in-echo-area} is locally bound to @code{nil} so that the cursor shows up in the window. @@ -1103,6 +1193,8 @@ the cursor shows up in the window. @node Edebug Recursive Edit @subsubsection Edebug Recursive Edit +@cindex Edebug and recursive edit +@cindex recursive edit, and Edebug When Edebug is entered and actually reads commands from the user, it saves (and later restores) these additional data: @@ -1149,6 +1241,8 @@ Edebug is active, @code{defining-kbd-macro} is bound to @node Edebug and Macros @subsection Edebug and Macros +@cindex Edebug and macros +@cindex macros, debugging with Edebug To make Edebug properly instrument expressions that call macros, some extra care is needed. This subsection explains the details. @@ -1172,23 +1266,26 @@ time later.) Therefore, you must define an Edebug specification for each macro that Edebug will encounter, to explain the format of calls to that -macro. To do this, add a @code{debug} declaration to the macro -definition. Here is a simple example that shows the specification for -the @code{for} example macro (@pxref{Argument Evaluation}). +macro. To do this, add a @code{debug} declaration (@pxref{Declare +Form}) to the macro definition. Here is a simple example that shows the +specification for the @code{for} example macro (@pxref{Argument +Evaluation}). @smallexample +@group (defmacro for (var from init to final do &rest body) "Execute a simple \"for\" loop. For example, (for i from 1 to 10 do (print i))." (declare (debug (symbolp "from" form "to" form "do" &rest form))) ...) +@end group @end smallexample The Edebug specification says which parts of a call to the macro are forms to be evaluated. For simple macros, the specification often looks very similar to the formal argument list of the macro definition, but specifications are much more general than macro -arguments. @xref{Defining Macros}, for more explanation of +arguments. @xref{Declare Form}, for more details about the @code{declare} form. @c See, e.g., https://debbugs.gnu.org/10577 @@ -1252,6 +1349,7 @@ are instrumented. @subsubsection Specification List @cindex Edebug specification list +@cindex specification list, Edebug A @dfn{specification list} is required for an Edebug specification if some arguments of a macro call are evaluated while others are not. Some elements in a specification list match one or more arguments, but others @@ -1358,8 +1456,8 @@ This is successful when there are no more arguments to match at the current argument list level; otherwise it fails. See sublist specifications and the backquote example. +@cindex preventing backtracking, in Edebug specification list @item gate -@cindex preventing backtracking No argument is matched but backtracking through the gate is disabled while matching the remainder of the specifications at this level. This is primarily used to generate more specific syntax error messages. @@ -1385,8 +1483,8 @@ sexps whose first element is a symbol and then lets with that head symbol according to @code{pcase--match-pat-args} and pass them to the @var{pf} it received as argument. -@item @var{other-symbol} @cindex indirect specifications +@item @var{other-symbol} Any other symbol in a specification list may be a predicate or an indirect specification. @@ -1408,8 +1506,8 @@ specification fails and the argument is not instrumented. Some suitable predicates include @code{symbolp}, @code{integerp}, @code{stringp}, @code{vectorp}, and @code{atom}. -@item [@var{elements}@dots{}] @cindex [@dots{}] (Edebug) +@item [@var{elements}@dots{}] A vector of elements groups the elements into a single @dfn{group specification}. Its meaning has nothing to do with vectors. @@ -1470,8 +1568,8 @@ The argument, a symbol, is the name of an argument of the defining form. However, lambda-list keywords (symbols starting with @samp{&}) are not allowed. -@item lambda-list @cindex lambda-list (Edebug) +@item lambda-list This matches a lambda list---the argument list of a lambda expression. @item def-body @@ -1791,6 +1889,7 @@ a breakpoint. Set to @code{nil} to prevent the pause, non-@code{nil} to allow it. @end defopt +@cindex Edebug, changing behavior with instrumented code @defopt edebug-behavior-alist By default, this alist contains one entry with the key @code{edebug} and a list of three functions, which are the default implementations @@ -1798,6 +1897,7 @@ of the functions inserted in instrumented code: @code{edebug-enter}, @code{edebug-before} and @code{edebug-after}. To change Edebug's behavior globally, modify the default entry. +@vindex edebug-behavior, symbol property Edebug's behavior may also be changed on a per-definition basis by adding an entry to this alist, with a key of your choice and three functions. Then set the @code{edebug-behavior} symbol property of an diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 6d3b0945a88..84d6299b018 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -149,9 +149,10 @@ The function returns an existing buffer if there is one; otherwise it creates a new buffer and reads the file into it. When @code{find-file-noselect} uses an existing buffer, it first verifies that the file has not changed since it was last visited or saved in -that buffer. If the file has changed, this function asks the user -whether to reread the changed file. If the user says @samp{yes}, any -edits previously made in the buffer are lost. +that buffer (unless @var{nowarn} is non-@code{nil}, see below). If the +file has changed, this function asks the user whether to reread the +changed file. If the user says @samp{yes}, any edits previously made in +the buffer are lost. Reading the file involves decoding the file's contents (@pxref{Coding Systems}), including end-of-line conversion, and format conversion @@ -163,7 +164,8 @@ This function displays warning or advisory messages in various peculiar cases, unless the optional argument @var{nowarn} is non-@code{nil}. For example, if it needs to create a buffer, and there is no file named @var{filename}, it displays the message @samp{(New file)} in the echo -area, and leaves the buffer empty. +area, and leaves the buffer empty. The verification of the file's last +change is also bypassed if @var{nowarn} is non-@code{nil}. The @code{find-file-noselect} function normally calls @code{after-find-file} after reading the file (@pxref{Subroutines of diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index ea6e07e05fb..1b2a21e160c 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -2742,6 +2742,14 @@ Indent calls to this function or macro according to @var{indent-spec}. This is typically used for macros, though it works for functions too. @xref{Indenting Macros}. +@cindex @code{autoload-macro} (@code{declare} spec) +@item (autoload-macro @var{value}) +This is used when defining a macro. If @var{value} is @samp{expand}, +any calls to the macro which follow an autoload comment will first be +expanded during generation of the autoloads. This declaration is used +as an alternative to hard-coding lists of macros to expand in +@code{loaddefs-generate--make-autoload}. @xref{Autoload}. + @item (interactive-only @var{value}) Set the function's @code{interactive-only} property to @var{value}. @xref{The interactive-only property}. diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi index 520b1b1d792..8ec1291b2f3 100644 --- a/doc/lispref/internals.texi +++ b/doc/lispref/internals.texi @@ -445,16 +445,17 @@ object type; space allocated to the contents of buffers does not count. The initial threshold value is @code{GC_DEFAULT_THRESHOLD}, defined in @file{alloc.c}. Since it's defined in @code{word_size} units, the -value is 400,000 for the default 32-bit configuration and 800,000 for -the 64-bit one. If you specify a larger value, garbage collection -will happen less often. This reduces the amount of time spent garbage -collecting (so Lisp programs will run faster between cycles of garbage -collection that happen more rarely), but increases total memory use. -You may want to do this when running a program that creates lots of -Lisp data, especially if you need it to run faster. However, we -recommend against increasing the threshold for prolonged periods of -time, and advise that you never set it higher than needed for the -program to run in reasonable time. Using thresholds higher than +value is 400,000 for the default 32-bit configuration, and 800,000 for +the 64-bit one and for 32-bit builds configured with the +@option{--with-wide-int} option. If you specify a larger value, garbage +collection will happen less often. This reduces the amount of time +spent garbage collecting (so Lisp programs will run faster between +cycles of garbage collection that happen more rarely), but increases +total memory use. You may want to do this when running a program that +creates lots of Lisp data, especially if you need it to run faster. +However, we recommend against increasing the threshold for prolonged +periods of time, and advise that you never set it higher than needed for +the program to run in reasonable time. Using thresholds higher than necessary could potentially cause higher system-wide memory pressure, and also make each garbage-collection cycle take much more time, and should therefore be avoided. @@ -475,6 +476,10 @@ As the heap size increases, the time to perform a garbage collection increases. Thus, it can be desirable to do them less frequently in proportion. +The initial percentage value is 0.1 in interactive sessions and while +dumping Emacs (@pxref{Building Emacs}), and 1.0 in non-interactive +(a.k.a.@: ``batch'') sessions. + As with @code{gc-cons-threshold}, do not enlarge this more than necessary, and never for prolonged periods of time. @end defopt diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 7fa64b72999..836d980ff0d 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -665,10 +665,12 @@ Building Emacs loads @file{loaddefs.el} and thus calls @code{autoload}. The same magic comment can copy any kind of form into @file{loaddefs.el}. The form following the magic comment is copied -verbatim, @emph{except} if it is one of the forms which the autoload -facility handles specially (e.g., by conversion into an -@code{autoload} call). The forms which are not copied verbatim are -the following: +verbatim, unless it is a form which the autoload facility handles +specially, by conversion directly into an @code{autoload} call, or by +recursively expanding the macro. Any macro can request expansion of +autoloads which call it during generation; @xref{autoload-macro expand}. + +The following forms are handled specially: @table @asis @item Definitions for function or function-like objects: @@ -684,8 +686,12 @@ and @code{define-overloadable-function} (see the commentary in @item Other definition types: @code{defcustom}, @code{defgroup}, @code{deftheme}, @code{defclass} -(@pxref{Top,EIEIO,,eieio,EIEIO}), and @code{define-skeleton} -(@pxref{Top,Autotyping,,autotype,Autotyping}). +(@pxref{Top,EIEIO,,eieio,EIEIO}), @code{define-skeleton} +(@pxref{Top,Autotyping,,autotype,Autotyping}), +@code{transient-define-prefix}, @code{transient-define-suffix}, +@code{transient-define-infix}, @code{transient-define-argument}, and +@code{transient-define-group} (@pxref{TOP,Transient,,transient,Transient +User and Developer Manual}). @end table You can also use a magic comment to execute a form at build time @@ -727,11 +733,50 @@ keep the line length down. @samp{(fn)} in the usage part of the documentation string is replaced with the function's name when the various help functions (@pxref{Help Functions}) display it. +@anchor{autoload-macro expand} If you write a function definition with an unusual macro that is not -one of the known and recognized function definition methods, use of an -ordinary magic autoload comment would copy the whole definition into -@code{loaddefs.el}. That is not desirable. You can put the desired -@code{autoload} call into @code{loaddefs.el} instead by writing this: +one of the known and recognized function definition methods, using an +ordinary magic autoload comment with a call to the macro would require +autoloading the macro definition itself to work. Doing so copies the +whole macro definition into the autoload file. If that is not desired, +you can use the special declare form @code{(autoload-macro expand)} in +your macro definition (@pxref{Declare Form}), instead of autoloading it. +This indicates to the autoload system that calls to your macro following +@samp{;;;###autoload} should be expanded, similar to how the special +functions listed above are handled. For example, a macro which wraps +@code{define-minor-mode} can request expansion, so that proper +@code{autoload} calls for the function it defines are generated. + +@cindex @code{:autoload-end} +The keyword symbol @code{:autoload-end} can be used in the expansion of +a macro to prevent including unwanted forms in the autoload output. Its +presence causes any further elements within the form where it appears to +be silently skipped. For example, if during autoload generation, a +macro's expansion includes: + +@example +(progn + (put my-mode 'visible-prop t) + :autoload-end + (put my-mode 'hidden-prop nil)) +@end example + +@noindent +the final form (@w{@code{(put my-mode 'hidden-prop nil)}}) will not be +copied into the autoload file. + +Note that, if a symbol in the @code{car} of an autoloaded form is found +to be undefined during autoload generation, the file in which the +associated @samp{;;;###autoload} appears will itself be loaded, to give +the macro a chance to be defined. Packages which use special loading +mechanisms, including loading their own @file{@var{package}-loaddefs.el} +file, should therefore gracefully handle load errors, since these files +may not yet exist during autoload generation. This can be done, e.g., +by setting the @var{no-error} argument of @code{require} non-@code{nil} +(@pxref{Named Features})). + +Alternatively, instead of expansion, you can put the desired +@code{autoload} call into @file{loaddefs.el} by writing this: @example ;;;###autoload (autoload 'foo "myfile") diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index ba86b2d7b13..33c02aaabe3 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -1289,10 +1289,11 @@ the Tabulated List buffer. Its value should be either a list or a function. If the value is a list, each list element corresponds to one group, and -should have the form @w{@code{(@var{group-name} @var{entries})}}, where +should have the form +@w{@code{(@var{group-name} @var{entry1} @var{entry2} @dots{})}}, where @var{group-name} is a string inserted before all group entries, and -@var{entries} have the same format as @code{tabulated-list-entries} -(see above). +@var{entry1}, @var{entry2} and so on each have the same format as an +element of @code{tabulated-list-entries} (see above). Otherwise, the value should be a function which returns a list of the above form when called with no arguments. diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi index 5588d32c5e9..2f7c6876a8f 100644 --- a/doc/lispref/sequences.texi +++ b/doc/lispref/sequences.texi @@ -1441,8 +1441,8 @@ x The @var{array} should be mutable. @xref{Mutability}. If @var{array} is a string and @var{object} is not a character, a -@code{wrong-type-argument} error results. The function converts a -unibyte string to multibyte if necessary to insert a character. +@code{wrong-type-argument} error results. For more information about +string mutation, @pxref{Modifying Strings}. @end defun @defun fillarray array object diff --git a/doc/lispref/streams.texi b/doc/lispref/streams.texi index 3fd8f038bae..f049a2d23b1 100644 --- a/doc/lispref/streams.texi +++ b/doc/lispref/streams.texi @@ -1054,7 +1054,7 @@ This overrides @code{print-escape-nonascii}. This overrides @code{print-escape-multibyte}. @item charset-text-property This overrides @code{print-charset-text-property}. -@item unreadeable-function +@item unreadable-function This overrides @code{print-unreadable-function}. @item gensym This overrides @code{print-gensym}. @@ -1066,6 +1066,8 @@ This overrides @code{print-number-table}. This overrides @code{float-output-format}. @item integers-as-characters This overrides @code{print-integers-as-characters}. +@item symbols-bare +This overrides @code{print-symbols-bare}. @end table In the future, more overrides may be offered that do not map directly diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index 93025574893..a3b335b426e 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi @@ -467,12 +467,10 @@ described in this section. @xref{Mutability}. The most basic way to alter the contents of an existing string is with @code{aset} (@pxref{Array Functions}). @w{@code{(aset @var{string} @var{idx} @var{char})}} stores @var{char} into @var{string} at character -index @var{idx}. It will automatically convert a pure-@acronym{ASCII} -@var{string} to a multibyte string (@pxref{Text Representations}) if -needed, but we recommend to always make sure @var{string} is multibyte -(e.g., by using @code{string-to-multibyte}, @pxref{Converting -Representations}), if @var{char} is a non-@acronym{ASCII} character, not -a raw byte. +index @var{idx}. When @var{string} is a unibyte string (@pxref{Text +Representations}), @var{char} must be a single byte (0--255); when +@var{string} is multibyte, both @var{char} and the previous character at +@var{idx} must be ASCII (0--127). To clear out a string that contained a password, use @code{clear-string}: diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index dc984decd6c..943d08579ed 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -4641,6 +4641,8 @@ with @var{tochar} in @var{string}. By default, substitution occurs in a copy of @var{string}, but if the optional argument @var{inplace} is non-@code{nil}, the function modifies the @var{string} itself. In any case, the function returns the resulting string. + +For restrictions when altering an existing string, @pxref{Modifying Strings}. @end defun @deffn Command translate-region start end table @@ -4716,9 +4718,9 @@ value visits file @var{filename} and goes to buffer position @var{position}. Restoring this type of position asks the user for confirmation first. -@item @code{(buffer @var{buffer-name})} -This represents a buffer; jumping to this value switches to buffer -@var{buffer-name}. +@item @code{(buffer @var{buffer})} +This represents a buffer; jumping to this value switches to that +@var{buffer}. @end table The functions in this section return unpredictable values unless @@ -6311,7 +6313,11 @@ specific parts of the text. The functions you use in these hooks should save and restore the match data if they do anything that uses regular expressions; otherwise, they will interfere in bizarre ways with the editing operations that call -them. +them. In addition, the functions in these hooks should avoid changing +buffer text, faces, properties, overlays, and other aspects of the +buffer-specific state except those that the hook functions themselves +create and manage, because other parts of Emacs might become confused by +such changes behind their back. @defvar before-change-functions This variable holds a list of functions to call when Emacs is about to diff --git a/doc/lispref/threads.texi b/doc/lispref/threads.texi index 3d9ebf08073..db6d0cf4d26 100644 --- a/doc/lispref/threads.texi +++ b/doc/lispref/threads.texi @@ -55,7 +55,7 @@ closure are shared by any threads invoking the closure. directly, but the current thread can be exited implicitly, and other threads can be signaled. -@defun make-thread function &optional name +@defun make-thread function &optional name buffer-disposition Create a new thread of execution which invokes @var{function}. When @var{function} returns, the thread exits. @@ -66,9 +66,23 @@ The new thread's current buffer is inherited from the current thread. used for debugging and informational purposes only; it has no meaning to Emacs. If @var{name} is provided, it must be a string. +@var{buffer-disposition} indicates what happens if the thread's current +buffer is about to be killed. If the value is @code{t}, killing the +buffer is not allowed. Any other value, including @code{nil} (which is +the default), means that the buffer is killed and the thread is assigned +another current buffer, and it's signaled the error +@code{thread-buffer-killed}. But if the value is the symbol +@code{silently}, the error is not signaled. + This function returns the new thread. @end defun +@findex thread-buffer-disposition +@findex thread-set-buffer-disposition +After a thread had been created, you can inspect or change its +buffer-disposition using functions @code{thread-buffer-disposition} and +@code{thread-set-buffer-disposition}. + @defun threadp object This function returns @code{t} if @var{object} represents an Emacs thread, @code{nil} otherwise. diff --git a/doc/misc/autotype.texi b/doc/misc/autotype.texi index c53be54d0af..377dcda3efd 100644 --- a/doc/misc/autotype.texi +++ b/doc/misc/autotype.texi @@ -273,13 +273,15 @@ empty file is visited. This is accomplished by putting @vindex auto-insert-alist What gets inserted, if anything, is determined by the variable -@code{auto-insert-alist}. The @sc{car} of each element of this list -is either a mode name, making the element applicable when a buffer is -in that mode, or a string, which is a regexp matched against a -buffer's file name (the latter enables you to distinguish between -different kinds of files that have the same mode in Emacs). The -@sc{car} of an element may also be a cons cell, consisting of mode -name or regexp, as above, and an additional descriptive string. +@code{auto-insert-alist}. The @sc{car} of each element of this list is +either a mode name, making the element applicable when a buffer is in +that mode, or a string, which is a regexp matched against a buffer's +file name (the latter enables you to distinguish between different kinds +of files that have the same mode in Emacs). It can also be a predicate +declared through a plist of the form @code{(predicate @var{function})}. +@var{function} should be a predicate function of no arguments. The +@sc{car} of an element may also be a cons cell, consisting of mode name +or regexp, as above, and an additional descriptive string. When a matching element is found, the @sc{cdr} says what to do. It may be a string, which is a file name, whose contents are to be inserted, if diff --git a/doc/misc/eieio.texi b/doc/misc/eieio.texi index 39225535089..bf6f2fdb430 100644 --- a/doc/misc/eieio.texi +++ b/doc/misc/eieio.texi @@ -881,7 +881,7 @@ help with this a plethora of predicates have been created. @anchor{find-class} Return the class that @var{symbol} represents. If there is no class, @code{nil} is returned if @var{errorp} is @code{nil}. -If @var{errorp} is non-@code{nil}, @code{wrong-argument-type} is signaled. +If @var{errorp} is non-@code{nil}, @code{wrong-type-argument} is signaled. @end defun @defun class-p class diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi index d6c8778d785..cc364813f8b 100644 --- a/doc/misc/flymake.texi +++ b/doc/misc/flymake.texi @@ -316,10 +316,8 @@ reported. The indicator type which Flymake should use to indicate lines with errors or warnings. Depending on your preference, this can either use @code{fringes} or -@code{margins} for indicating errors. -If set to @code{fringes} (the default), it will automatically fall back -to using margins in windows or frames without fringes, such as text -terminals. +@code{margins} for indicating errors. On text terminals, only +@code{margins} is available. @item flymake-error-bitmap A bitmap used in the fringe to mark lines for which an error has diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index 34ecfb040ec..e0a9c54c328 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -14088,7 +14088,7 @@ indirect ones (three pre-made). Non-@code{nil} means the nntp server never echoes commands. It is reported that some nntps server doesn't echo commands. So, you may want to set this to non-@code{nil} in the method for such a server setting -@code{nntp-open-connection-function} to @code{nntp-open-ssl-stream} for +@code{nntp-open-connection-function} to @code{nntp-open-tls-stream} for example. The default value is @code{nil}. Note that the @code{nntp-open-connection-functions-never-echo-commands} variable overrides the @code{nil} value of this variable. @@ -14144,18 +14144,26 @@ functions is also affected by commonly understood variables @findex nntp-open-network-stream @item nntp-open-network-stream This is the default, and simply connects to some port or other on the -remote system. If both Emacs and the server supports it, the -connection will be upgraded to an encrypted @acronym{STARTTLS} -connection automatically. +remote system. If both Emacs and the server supports it, the connection +will be upgraded to an encrypted @acronym{STARTTLS} connection +automatically. If you want to avoid the possibility of a malicious +intermediary blocking the use of @acronym{STARTTLS}, use +@code{nntp-open-tls-stream} instead. -@item network-only -The same as the above, but don't do automatic @acronym{STARTTLS} upgrades. +@item nntp-open-plain-stream +@itemx network-only +The same as the above, but don't do automatic @acronym{STARTTLS} +upgrades. Only use this if you want anyone to be able to read your +traffic. @findex nntp-open-tls-stream @item nntp-open-tls-stream Opens a connection to a server over a @dfn{secure} channel. To use -this you must have @uref{https://www.gnu.org/software/gnutls/, GnuTLS} -installed. You then define a server as follows: +this, your Emacs must have been compiled with GnuTLS support +@uref{https://www.gnu.org/software/gnutls/, GnuTLS}. You can check this +using the @code{gnutls-available-p} command. + +You then define a server as follows: @lisp ;; @r{"nntps" is port 563 and is predefined in our @file{/etc/services}} @@ -14167,26 +14175,10 @@ installed. You then define a server as follows: (nntp-address "snews.bar.com")) @end lisp -@c FIXME openssl s_client should be deprecated in favor of gnutls. @findex nntp-open-ssl-stream @item nntp-open-ssl-stream -Opens a connection to a server over a @dfn{secure} channel. To use -this you must have @uref{https://www.openssl.org/, OpenSSL} -@ignore -@c Defunct URL, ancient package, so don't mention it. -or @uref{ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL, SSLeay} -@end ignore -installed. You then define a server as follows: - -@lisp -;; @r{"snews" is port 563 and is predefined in our @file{/etc/services}} -;; @r{however, @samp{openssl s_client -port} doesn't like named ports.} -;; -(nntp "snews.bar.com" - (nntp-open-connection-function nntp-open-ssl-stream) - (nntp-port-number 563) - (nntp-address "snews.bar.com")) -@end lisp +This is the old name for @code{nntp-open-tls-stream}, and is +completely equivalent. @findex nntp-open-netcat-stream @item nntp-open-netcat-stream @@ -14528,7 +14520,7 @@ Here's an example method that's more complex: (nnimap-inbox "INBOX") (nnimap-split-methods default) (nnimap-expunge t) - (nnimap-stream ssl)) + (nnimap-stream tls)) @end example @table @code @@ -14554,11 +14546,12 @@ How @code{nnimap} should connect to the server. Possible values are: @table @code @item undecided -This is the default, and this first tries the @code{ssl} setting, and +This is the default, and this first tries the @code{tls} setting, and then tries the @code{network} setting. -@item ssl -This uses standard @acronym{TLS}/@acronym{SSL} connections. +@item tls +This uses standard @acronym{TLS}/@acronym{SSL} connections. @code{ssl} +is an equivalent but deprecated way to specify this. @item network Non-encrypted and unsafe straight socket connection, but will upgrade @@ -18870,7 +18863,7 @@ operators sprinkled in between. Perhaps some examples are in order. -Here's a simple predicate. (It's the default predicate, in fact, used +Here's a simple predicate. (The default predicate is @code{false}, used for all groups that don't belong to any other category.) @lisp diff --git a/doc/misc/texinfo.tex b/doc/misc/texinfo.tex index 42e686ce705..64dddad8290 100644 --- a/doc/misc/texinfo.tex +++ b/doc/misc/texinfo.tex @@ -3,7 +3,7 @@ % Load plain if necessary, i.e., if running under initex. \expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi % -\def\texinfoversion{2025-07-15.21} +\def\texinfoversion{2025-07-31.19} % % Copyright 1985, 1986, 1988, 1990-2025 Free Software Foundation, Inc. % @@ -9634,7 +9634,10 @@ might help (with 'rm \jobname.?? \jobname.??s')% % Auto-number footnotes. Otherwise like plain. \gdef\footnote{% \global\advance\footnoteno by \@ne - \edef\thisfootno{$^{\the\footnoteno}$}% + % + % Output for the footnote marker. If we are immediately after another + % footnote, output a comma and small space first. + \edef\thisfootno{$^{\ifnum\lastpenalty=3 ,\mskip 1mu \fi\the\footnoteno}$}% % % In case the footnote comes at the end of a sentence, preserve the % extra spacing after we do the footnote number. @@ -9643,19 +9646,25 @@ might help (with 'rm \jobname.?? \jobname.??s')% % % Remove inadvertent blank space before typesetting the footnote number. \unskip - \thisfootno\@sf + % + % \scriptspace is 0.5pt by default and gives excessive space before the + % comma if we have multiple footnote markers in a row. + \bgroup\scriptspace=0pt + \thisfootno\@sf + \egroup \dofootnote }% -% Don't bother with the trickery in plain.tex to not require the -% footnote text as a parameter. Our footnotes don't need to be so general. -% -% Oh yes, they do; otherwise, @ifset (and anything else that uses -% \parseargline) fails inside footnotes because the tokens are fixed when -% the footnote is read. --karl, 16nov96. +% marker for immediately after a footnote marker +\gdef\footnoteendmarker{\penalty3 } + +% Do not require the footnote text as a parameter; otherwise, @ifset +% (and anything else that uses \parseargline) fails inside footnotes +% because the tokens are fixed when the footnote is read. % \gdef\dofootnote{% \insert\footins\bgroup + \aftergroup\footnoteendmarker % % Nested footnotes are not supported in TeX, that would take a lot % more work. (\startsavinginserts does not suffice.) @@ -9686,14 +9695,14 @@ might help (with 'rm \jobname.?? \jobname.??s')% % Hang the footnote text off the number. Use \everypar in case the % footnote extends for more than one paragraph. \everypar = {\hang}% - \textindent{\thisfootno}% + \textindent{$^{\the\footnoteno}$}% % % Don't crash into the line above the footnote text. Since this % expands into a box, it must come within the paragraph, lest it % provide a place where TeX can split the footnote. \footstrut % - % Invoke rest of plain TeX footnote routine. + % Eat opening brace and invoke rest of plain TeX footnote routine. \futurelet\next\fo@t } }%end \catcode `\@=11 diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 21f12a38e0b..2944978f8ee 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -169,6 +169,7 @@ How file names, directories and localnames are mangled and managed * Localname deconstruction:: Breaking a localname into its components. * External packages:: Integration with external Lisp packages. * Extension packages:: Adding new methods to @value{tramp}. +* New operations:: Handling further operations in @value{tramp}. @end detailmenu @end menu @@ -2375,9 +2376,11 @@ value is @t{"-l"}, but some shells, like @command{ksh}, prefer All @file{tramp-sh.el} based methods accept the property @t{"session-timeout"}. This is the time (in seconds) after a connection is disabled for security reasons, and must be -reestablished. A value of @code{nil} disables this feature. Most of -the methods do not set this property except the @option{sudo}, -@option{doas} and @option{run0} methods, which use predefined values. +reestablished@footnote{If there is a modified buffer, or a buffer +under @code{auto-revert}, this is suppressed.}. A value of @code{nil} +disables this feature. Most of the methods do not set this property +except the @option{sudo}, @option{doas} and @option{run0} methods, +which use predefined values. @item @t{"~"}@* @t{"~user"} @@ -3658,6 +3661,8 @@ behavior: @file{@trampfn{method,user@@host,path/to/file}}. For specifying port numbers, affix @file{#} to the host name. For example: @file{@trampfn{ssh,daniel@@melancholia#42,.emacs}}. +If the host is an IPv6 address, the port is appended like this: +@file{@trampfn{ssh,@value{ipv6prefix}::1@value{ipv6postfix}#42,.emacs}}. All method, user name, host name, port number and local name parts are optional, @xref{Default Method}, @xref{Default User}, @xref{Default Host}. @@ -5472,6 +5477,13 @@ Suppress reading the remote history file in @code{shell}. Set Disable excessive traces. Set @code{tramp-verbose} to 3 or lower, default being 3. Increase trace levels temporarily when hunting for bugs. + +@item +Use a package with @value{tramp} specific implementation of high-level +operations. For example, the GNU ELPA package @file{tramp-hlo} +implements specialized versions of @code{dir-locals--all-files}, +@code{locate-dominating-file} and @code{dir-locals-find-file} for +@value{tramp}'s @code{tramp-sh} backend (@pxref{New operations}). @end itemize @@ -6457,6 +6469,7 @@ programs. * Localname deconstruction:: Splitting a localname into its component parts. * External packages:: Integrating with external Lisp packages. * Extension packages:: Adding new methods to @value{tramp}. +* New operations:: Handling further operations in @value{tramp}. @end menu @@ -6721,15 +6734,112 @@ The trick is to wrap the function definition of @code{;;;###autoload} cookie. +@node New operations +@section Handling further operations in @value{tramp} + +By default, @value{tramp} handles the basic operations listed in +@ref{Magic File Names, , Magic File Name Operations, elisp}. +Sometimes, it is desired to support more complex operations directly, +mainly for performance reasons. + +An external package package could add an own implementation of an +operation to @value{tramp}, which avoids the performance overhead +caused by using the basic operations which are aware of remote files. +For example, it could implement this by using an own shell script +which collects the information on the remote host for this very +special purpose with one round-trip per-call. + +@defun tramp-add-external-operation operation function backend +This adds an implementation of @var{operation} to @value{tramp}'s +backend @var{backend}. @var{function} is the new implementation. + +Both @var{operation} and @var{function} shall be function symbols. +They must have the same argument list. The first argument is used to +determine, whether @value{tramp} is invoked (check for remote file +name syntax). It must be a string or nil, in the latter case +@code{default-directory} is used for the check. + +@var{backend}, also a symbol, is the feature name of a @value{tramp} +backend (except @code{tramp-ftp}). The new implementation will be +applied only for this backend. Example: + +@lisp +@group +(defun test-operation (file) + (message "Original implementation for %s" file)) +@end group + +@group +(defun handle-test-operation (file) + (message "Handler implementation for %s" file)) +@end group + +@group +(tramp-add-external-operation + #'test-operation #'handle-test-operation 'tramp-sh) +@end group +@end lisp + +Then we have the different use cases: + +@lisp +@group +;; Local file name. +(test-operation "/a/b") +@result{} "Original implementation for /a/b" +@end group + +@group +;; Remote file name, handled by `tramp-sh'. +(test-operation "/ssh::/a/b") +@result{} "Handler implementation for /ssh::/a/b" +@end group + +@group +;; Remote file name, handled by `tramp-gvfs'. +(test-operation "/sftp::/a/b") +@result{} "Original implementation for /sftp::/a/b" +@end group +@end lisp + +@var{function} is implemented like an ordinary @value{tramp} backend +handler, see the examples in @code{tramp--handle-*} and +@code{tramp-handle-*}. It can expect, that the first argument (or +@code{default-directory}, if that is @code{nil}) has remote file name +syntax. It shall use @value{tramp} internal macros and functions like +@code{with-parsed-tramp-file-name} and the different cache functions. + +If the same @var{function} shall be used for different @value{tramp} +backends, @code{tramp-add-external-operation} must be called for every +backend, respectively. +@end defun + +@defun tramp-remove-external-operation operation backend +The handler for @var{operation}, added by +@code{tramp-add-external-operation}, is removed from @var{backend}. +If there are handlers of @var{operation} for other @var{backend}s, +they are kept. Example: + +@lisp +@group +(tramp-remove-external-operation + #'test-operation 'tramp-sh) +@end group +@end lisp +@end defun + + @node Traces and Profiles @chapter How to Customize Traces @vindex tramp-verbose @vindex tramp-debug-to-file @vindex tramp-debug-command-messages +@vindex tramp-debug-buffer-limit @value{tramp} messages are raised with verbosity levels ranging from 0 to 10. @value{tramp} does not display all messages; only those with a -verbosity level less than or equal to @code{tramp-verbose}. +verbosity level less than or equal to 3, when @code{tramp-verbose} +permits. @noindent The verbosity levels are @@ -6814,6 +6924,12 @@ strings), and the entry and exit messages for the function @code{tramp-file-name-handler}. This is intended for @value{tramp} maintainers, analyzing the remote commands for performance analysis. +The debug buffer can be very large, if @code{tramp-verbose} is high, +and @value{tramp} runs for a long time. If the buffer size exceeds +@code{tramp-debug-buffer-limit} (100MB by default), a warning will be +raised. This user option can be adapted to your needs; a value of 0 +means that there is no limit (no warning). + @node GNU Free Documentation License @appendix GNU Free Documentation License @@ -6841,7 +6957,7 @@ maintainers, analyzing the remote commands for performance analysis. @bye -@c TODO +@c TODO: @c @c * Say something about the .login and .profile files of the remote @c shells. @@ -6850,3 +6966,5 @@ maintainers, analyzing the remote commands for performance analysis. @c host and then send commands to it. @c @c * Consistent small or capitalized words especially in menus. +@c +@c * Starting with Emacs 29, use 'setopt' in the examples. diff --git a/doc/misc/transient.texi b/doc/misc/transient.texi index fe7f81c7930..4aa0ebf97d6 100644 --- a/doc/misc/transient.texi +++ b/doc/misc/transient.texi @@ -31,7 +31,7 @@ General Public License for more details. @finalout @titlepage @title Transient User and Developer Manual -@subtitle for version 0.9.3 +@subtitle for version 0.9.4 @author Jonas Bernoulli @page @vskip 0pt plus 1filll @@ -53,7 +53,7 @@ resource to get over that hurdle is Psionic K's interactive tutorial, available at @uref{https://github.com/positron-solutions/transient-showcase}. @noindent -This manual is for Transient version 0.9.3. +This manual is for Transient version 0.9.4. @insertcopying @end ifnottex diff --git a/etc/AUTHORS b/etc/AUTHORS index 9d289f0edf8..ff7c2cc4ee6 100644 --- a/etc/AUTHORS +++ b/etc/AUTHORS @@ -304,7 +304,7 @@ Anders Waldenborg: changed emacsclient.c Andrea Corallo: wrote comp-common.el comp-cstr-tests.el comp-cstr.el comp-run.el comp-tests.el comp.c comp.el syncdoc-type-hierarchy.el and changed pdumper.c lread.c bytecomp.el configure.ac startup.el - loadup.el comp.h lisp.h cl-macs.el cl-preloaded.el comp-test-funcs.el + loadup.el comp.h lisp.h cl-macs.el comp-test-funcs.el cl-preloaded.el subr.el Makefile.in data.c elisp-mode.el nadvice.el alloc.c byte-run.el emacs.c lisp/Makefile.in advice.el and 101 other files @@ -1740,7 +1740,7 @@ and co-wrote help-tests.el and changed xdisp.c display.texi w32.c msdos.c simple.el w32fns.c files.el fileio.c keyboard.c configure.ac emacs.c text.texi w32term.c dispnew.c frames.texi files.texi w32proc.c xfaces.c window.c - dispextern.h lisp.h and 1407 other files + dispextern.h lisp.h and 1409 other files Eliza Velasquez: changed server.el simple.el @@ -2625,7 +2625,7 @@ James TD Smith: changed org.el org-colview.el org-clock.el org.texi James Thomas: changed eww.el nnmail.el quail/indian.el gnus-cache.el - gnus-msg.el ind-util.el info-look.el progmodes/python.el + gnus-msg.el gnus.texi ind-util.el info-look.el progmodes/python.el James Troup: changed gnus-sum.el @@ -3198,8 +3198,8 @@ Joshua Datko: changed fortune.el Joshua Varner: changed intro.texi -Jostein Kjønigsen: changed csharp-mode.el typescript-ts-mode.el js.el - eglot.el progmodes/compile.el README dotnet-appconfig.rnc +Jostein Kjønigsen: changed csharp-mode.el typescript-ts-mode.el eglot.el + js.el progmodes/compile.el README dotnet-appconfig.rnc dotnet-packages-config.rnc dotnet-packages-props.rnc dotnet-resx.rnc json-ts-mode.el msbuild.rnc nuget.rnc nuspec.rnc nxml-mode.el schemas.xml treesit.el @@ -3443,6 +3443,8 @@ and changed pgg-gpg.el pgg.el progmodes/python.el locked-encrypted.png locked-encrypted.xpm pgg-pgp.el pgg-pgp5.el unlocked-encrypted.png unlocked-encrypted.xpm README edebug.el pgg.texi tips.texi +Ken Mankoff: changed leuven-dark-theme.el leuven-theme.el + Kenneth Stailey: changed alpha.h configure.ac ns32000.h openbsd.h pmax.h sparc.h unexalpha.c unexelf.c @@ -3564,11 +3566,11 @@ Koichi Arakawa: changed tramp-sh.el w32proc.c Konrad Hinsen: wrote ol-eshell.el and changed ob-python.el -Konstantin Kharlamov: changed smerge-mode.el diff-mode.el files.el - indent.erts typescript-ts-mode.el ada-mode.el alloc.c autorevert.el - calc-aent.el calc-ext.el calc-lang.el cc-mode.el cperl-mode.el - css-mode.el cua-rect.el dnd.el ebnf-abn.el ebnf-dtd.el ebnf-ebx.el - emacs-module-tests.el epg.el and 33 other files +Konstantin Kharlamov: changed indent.erts smerge-mode.el + typescript-ts-mode.el diff-mode.el files.el ada-mode.el alloc.c + autorevert.el calc-aent.el calc-ext.el calc-lang.el cc-mode.el + cperl-mode.el css-mode.el cua-rect.el dnd.el ebnf-abn.el ebnf-dtd.el + ebnf-ebx.el emacs-module-tests.el epg.el and 33 other files Konstantin Kliakhandler: changed org-agenda.el @@ -3727,6 +3729,8 @@ Lewis Perin: changed emacs-x86.manifest Liam Healy: changed outline.el +Liam Hupfer: changed js.el + Liam Stitt: changed url-file.el url-vars.el Liang Wang: changed etags.el @@ -5058,9 +5062,9 @@ Piotr Zieliński: wrote org-mouse.el Pip Cet: wrote image-circular-tests.el and changed xdisp.c comp.c byte-opt.el fns.c pdumper.c alloc.c - display.texi ftcrfont.c image.c sfnt.c xterm.c DEBUG bytecomp-tests.el - bytecomp.el ccl-tests.el ccl.c ccl.el cl-macs.el cmds.c comint.el - comp-test-funcs.el and 34 other files + display.texi eval.c ftcrfont.c image.c sfnt.c xterm.c DEBUG + bytecomp-tests.el bytecomp.el ccl-tests.el ccl.c ccl.el cl-macs.el + cmds.c comint.el and 34 other files Platon Pronko: changed tramp.el @@ -5538,10 +5542,10 @@ Sean O'Rourke: changed complete.el comint.el dabbrev.el find-func.el Sean Sieger: changed emacs-lisp-intro.texi Sean Whitton: wrote em-elecslash.el em-extpipe-tests.el em-extpipe.el -and changed vc-git.el project.el bindings.el server.el simple.el subr.el - vc-dispatcher.el vc.el window.el eshell-tests.el eshell.texi subr-x.el - .dir-locals.el cl-macs.el eshell-tests-helpers.el files.texi ftfont.c - remember.el startup.el term.el INSTALL and 38 other files +and changed vc-git.el project.el vc.el bindings.el server.el simple.el + subr.el vc-dispatcher.el window.el eshell-tests.el eshell.texi + subr-x.el .dir-locals.el cl-macs.el eshell-tests-helpers.el files.texi + ftfont.c remember.el startup.el term.el INSTALL and 40 other files Sebastian Fieber: changed gnus-art.el mm-decode.el mm-view.el @@ -6430,6 +6434,8 @@ and changed ps-prin1.ps ps-bdf.el ps-prin0.ps blank-mode.el ps-prin3.ps easymenu.el loading.texi menu-bar.el misc.texi progmodes/compile.el ps-print-def.el ps-vars.el +Vinícius Moraes: changed cmuscheme.el + Vitalie Spinu: changed comint.el eieio-base.el message.el ob-R.el ob-core.el ob-tangle.el subr.el @@ -6593,7 +6599,7 @@ Xi Lu: changed etags.c htmlfontify.el ruby-mode.el CTAGS.good_crlf man-tests.el man.el shortdoc.el tramp-sh.el Xiyue Deng: changed emacs-lisp-intro.texi strings.texi functions.texi - symbols.texi + smtpmail.el symbols.texi Xuan Wang: changed warnings.el diff --git a/etc/DEBUG b/etc/DEBUG index 758ee51e192..9098ecb5935 100644 --- a/etc/DEBUG +++ b/etc/DEBUG @@ -211,15 +211,19 @@ the debugger, but before running it, is the most efficient way of making sure control will be returned to the debugger when you need that. -'Fsignal' is a very useful place to put a breakpoint in. All Lisp -errors go through there. If you are only interested in errors that -would fire the Lisp debugger, breaking at 'maybe_call_debugger' is -useful. +The function 'debugger-trap' is a do-nothing interactive command that +exists to give control to the debugger. It is convenient to set a +breakpoint there to give control to the debugger when the function is +called. You can invoke it interactively with "M-x debugger-trap RET". +The src/.gdbinit file in the Emacs source distribution sets a breakpoint +in this function, so if you arrange for .gdbinit to be loaded, or load +it manually in a debugging session, the breakpoint is set for you +automatically. -Another technique for getting control to the debugger is to put a -breakpoint in some rarely used function. One such convenient function -is Fredraw_display, which you can invoke at will interactively with -"M-x redraw-display RET". +'Fsignal' is another very useful place to put a breakpoint in. All Lisp +errors go through there. If you are only interested in errors that +would fire the Lisp debugger, breaking at 'maybe_call_debugger' is a +useful alternative. It is also useful to have a guaranteed way to return to the debugger at any arbitrary time. When using X, this is easy: type C-z at the diff --git a/etc/HISTORY b/etc/HISTORY index bb8155de112..5758d5853d5 100644 --- a/etc/HISTORY +++ b/etc/HISTORY @@ -241,6 +241,8 @@ GNU Emacs 29.4 (2024-06-22) emacs-29.4 GNU Emacs 30.1 (2025-02-23) emacs-30.1 +GNU Emacs 30.2 (2025-08-14) emacs-30.2 + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/etc/NEWS b/etc/NEWS index b790c7e318c..aee83c2f604 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -162,15 +162,26 @@ behavior, customize 'find-function-mode-lower-precedence' to non-nil. ** Minibuffer and Completions +++ -*** New user option 'completion-eager-display'. -This option configures whether completion commands should display the -"*Completions*" buffer immediately. When the option is set to t, all -completion commands show "*Completions*" immediately, respectively nil -disables the eager display for all commands. The default setting auto -enables eager completion only if requested by the command. -For more fine-grained control you can also toggle this feature by -category using the symbol 'eager-display' in the user option -'completion-category-overrides'. +*** Support for immediate display of the "*Completions*" buffer. +Whenever a minibuffer with completion is opened, the "*Completions*" +buffer will now be displayed immediately if the completion property +'eager-display', set by the completion table, is non-nil. This property +can be overridden for different completion categories by customizing +'completion-category-overrides'. Alternatively, the new user option +'completion-eager-display' can be set to t to force eager display of +"*Completions*" for all minibuffers, or nil to suppress this for all +minibuffers. + ++++ +*** Support for updating "*Completions*" as you type. +If the "*Completions*" buffer is displayed, it will now be updated as +you type if the completion property 'eager-update', set by the +completion table, is non-nil. This property can be overridden for +different completion categories by customizing +'completion-category-overrides'. Alternatively, the new user option +'completion-eager-update can be set to t to make "*Completions*" always +be updated as you type, or nil to suppress this always. Note that for +large or inefficient completion tables this can slow down typing. +++ *** New user option 'completion-pcm-leading-wildcard'. @@ -333,6 +344,10 @@ helps to restore window buffers across Emacs sessions. You can use this in 'display-buffer-alist' to match buffers displayed during the execution of particular commands. +*** New command 'other-window-backward' ('C-x O'). +This moves in the opposite direction of 'other-window' and is for its +default keybinding consistent with 'repeat-mode'. + ** Frames +++ @@ -427,6 +442,16 @@ This user option controls where 'tab-line-mode' should not be enabled in a buffer. The value must be a condition which is passed to 'buffer-match-p'. +--- +*** New user option 'tab-line-close-modified-button-show'. +With this user option, if non-nil (the default), the tab close button +will change its appearance if the tab buffer has been modified. + +--- +*** New user option 'tab-line-tabs-window-buffers-filter-function'. +This user option controls which buffers should appear in the tab line. +By default, this is set to not filter the buffers. + ** Project --- @@ -443,17 +468,31 @@ It is equivalent to running 'project-any-command' with The prompt now displays the chosen project on which to invoke a command. --- -*** The MAYBE-PROMPT argument of 'project-current' can be a string. -When such value is used, the 'project-prompter' is called with it as the -first argument. This is a way for the callers to indicate, for example, -the reason or the context why the project is asked for. +*** 'project-prompter' values may be called with up to three arguments. +These allow callers of the value of 'project-prompter' to specify a +prompt string; prompt the user to choose between a subset of all the +known projects; and disallow returning arbitrary directories. +See the docstring of 'project-prompter' for a full specification of +these new optional arguments. --- -*** New command 'project-find-matching-file'. +*** 'project-current' has a new optional argument, MAYBE-PROMPT. +If 'project-current' is called with this argument non-nil, then it is +passed to the 'project-prompter' to use as a prompt string. +Callers can use this to indicate the reason for which or context in +which Emacs should ask the user to select a project. + +--- +*** New command 'project-find-matching-buffer'. It can be used when switching between projects with similar file trees (such as Git worktrees of the same repository). It supports being invoked standalone or from the 'project-switch-commands' dispatch menu. +--- +*** New variable 'project-find-matching-buffer-function'. +Major modes can set this to major mode-specific functions to control how +'project-find-matching-buffer' finds matching buffers. + +++ *** New user option 'project-list-exclude'. This user option describes projects that should always be skipped by @@ -465,12 +504,13 @@ This user option controls the automatic deletion of projects from 'project-list-file' that cannot be accessed when prompting for a project. -The value can be a predicate which takes one argument and should return -non-nil if the project should be removed. If set to nil, all the -inaccessible projects will not be removed automatically. +The value must be an alist where each element must be in the form: -By default this is set to 'project-prune-zombies-default' function -which removes all non-remote projects. + (WHEN . PREDICATE) + +where WHEN specifies where the deletion will be performed, and PREDICATE +a function which takes one argument, and must return non-nil if the +project should be removed. --- *** New command 'project-save-some-buffers' bound to 'C-x p C-x s'. @@ -478,6 +518,23 @@ This is like 'C-x s', but only for this project's buffers. *** 'project-remember-project' can now be called interactively. +--- +*** 'project-shell' and 'project-eshell' support numeric prefix buffer naming. +They now accept numeric prefix arguments to select or create numbered +shell sessions. For example, 'C-2 C-x p s' switches to or creates a +buffer named "*name-of-project-shell<2>*". By comparison, a plain +universal argument as in 'C-u C-x p s' always creates a new session. + +--- +*** 'project-switch-buffer' re-uniquifies buffer names while prompting. +When 'uniquify-buffer-name-style' is non-nil, 'project-switch-buffer' +changes the buffer names to only make them unique within the given +project, during completion. That makes some items shorter. + +*** 'project-switch-buffer' uses 'project-buffer' as completion category. +The category defaults are the same as for 'buffer' but any user +customizations would need to be re-added. + ** Registers *** New functions 'buffer-to-register' and 'file-to-register'. @@ -662,6 +719,15 @@ to the value 'fill-region-as-paragraph-semlf' to enable functions like 'fill-paragraph' and 'fill-region' to fill text using "semantic linefeeds". +--- +** Temporary files are named differently when 'file-precious-flag' is set. +When the user option 'file-precious-flag' is set to a non-nil value, +Emacs now names the temporary file it creates while saving buffers using +the original file name with ".tmp" appended to it. Thus, if saving the +buffer fails for some reason, and the temporary file is not renamed back +to the original file's name, you can easily identify which file's saving +failed. + +++ ** 'C-u C-x .' clears the fill prefix. You can now use 'C-u C-x .' to clear the fill prefix, similarly to how @@ -670,6 +736,15 @@ you could already use 'C-u C-x C-n' to clear the goal column. * Changes in Specialized Modes and Packages in Emacs 31.1 +** Autoinsert + ++++ +*** New condition for 'auto-insert-alist'. +'auto-insert-alist' now also allows to have a predicate taking no +argument as conditions. These types of conditions should be declared +with '(predicate FUNCTION)'. This allows to trigger 'auto-insert' +with finer grained control. + ** Register *** The "*Register Preview*" buffer shows only suitable registers. @@ -678,6 +753,12 @@ the default UI you get, i.e., when 'register-use-preview' is 'traditional'. ** Tree-sitter +*** New user option 'treesit-enabled-modes'. +You can customize it either to t to enable all available ts-modes, +or to select a list of ts-modes to enable. Depending on customization, +it modifies the variable 'major-mode-remap-alist' from the corresponding +variable 'treesit-major-mode-remap-alist' prepared by ts-mode packages. + *** New user option 'treesit-auto-install-grammar'. It controls the automatic installation of tree-sitter grammar libraries needed for tree-sitter based modes, if these grammar libraries are not @@ -869,6 +950,13 @@ build tags for the test commands. The 'go-ts-mode-test-flags' user option is available to set a list of additional flags to pass to the go test command line. +** Lua-ts mode + +--- +*** New user option 'lua-ts-auto-close-block-comments'. +When non-nil, inserting a block comment "--[[" will close it by +inserting its respective "]]". By default, this is disabled. + ** Java-ts mode +++ @@ -885,6 +973,12 @@ option controls how much is indented for method chaining. ** PHP-ts mode +--- +*** 'php-ts-mode' now depends on 'mhtml-ts-mode'. +The direct dependency on js-ts-mode, css-ts-mode and html-ts-mode has +now been replaced by ‘mhtml-ts-mode’. Navigation, Outline and Imenu +work for all languages and code maintenance is easier. + --- *** 'php-ts-mode-run-php-webserver' can now accept a custom "php.ini" file. You can use the new optional argument CONFIG when calling @@ -893,6 +987,34 @@ the built-in Web server. Interactively, when invoked with a prefix argument, 'php-ts-mode-run-php-webserver' prompts for the config file as well as for other connection parameters. +--- +*** The option 'php-ts-mode-css-fontify-colors' has been removed. +'mhtml-ts-mode-css-fontify-colors' replaces this option. + +--- +*** New user option 'php-ts-mode-html-relative-indent'. +In buffers containing both PHP and HTML, this option allows you to +define how the PHP code should be indented relative to the position of +the HTML tags. + +--- +*** New user option 'php-ts-mode-html-indent-offset'. +Offset of PHP code block relative to HTML tags. + +--- +*** New user option 'php-ts-mode-find-sibling-rules'. +Rules for finding siblings of a PHP file. + +--- +*** New user option 'php-ts-mode-phpdoc-highlight-errors'. +When non nil, it highlights unknown PHPDOC tags using +'font-lock-warning-face' so that the user can identify them more easily. + +--- +*** New command 'php-ts-mode-show-ini'. +Show the location of the PHP ini files, if the buffer is associated to a remote +PHP file show the remote PHP ini files. + ** Rust-ts mode --- @@ -920,6 +1042,14 @@ characters in CJK texts. For example, 'A' is converted to 'A', '1' is converted to '1', etc. Companion commands 'halfwidth-region' and 'halfwidth-word' perform the opposite conversion. +** Texinfo mode + +--- +*** texinfo-mode now can auto-close the ``'' pairs. +Now inserting `` in 'texinfo-mode' will close it by inserting its +respective '', if 'electric-pair-mode' is enabled. + + ** ASM mode --- @@ -1103,6 +1233,14 @@ slot. Symbol macros are created for the accessor functions using If 'whitespace-style' includes 'missing-newline-at-eof' (which is the default), the 'whitespace-cleanup' function will now add the newline. +--- +*** 'whitespace-mode' now can prettify page delimiter characters (^L). +If 'page-delimiters' is set in 'whitespace-style', or the new minor mode +'whitespace-page-delimiters-mode' is on, the page delimiter characters +(^L) are displayed as a pretty horizontal line that spans the entire +width of the window. The new 'whitespace-page-delimiter' face can be +used to customize the appearence. + ** Bookmark --- @@ -1594,6 +1732,15 @@ This feature is experimental. --- *** Implementation of filesystem notifications for connection method "smb". ++++ +*** New functions to extend the set of operations with a remote implementation. +The new functions 'tramp-add-external-operation' and +'tramp-remove-external-operation' allow to add an implementation for +other operations but the defined set of magic file name operations. +This can be used by external ELPA packages for performance optimizations +in special cases. For more information, see "(tramp) New operations" in +the Tramp manual. + ** Diff --- @@ -1817,6 +1964,13 @@ restart Emacs. --- *** Support of 'electric-layout-mode' added. +--- +*** 'DEL' now deletes the text in the active region. +When point is between indentation, the command +'python-indent-dedent-line-backspace' (by default bound to 'DEL') now +deletes the text in the region and deactivates the mark if Transient +Mark mode is enabled, the mark is active, and prefix argument is 1. + ** Tmm Menubar --- @@ -1876,6 +2030,7 @@ other working trees: - 'C-x v w c': Add a new working tree. - 'C-x v w w': Visit this file in another working tree. +- 'C-x v w s': Like 'C-x p p' but limited to other working trees. - 'C-x v w x': Delete a working tree you no longer need. - 'C-x v w R': Relocate a working tree to another file name. @@ -1996,15 +2151,19 @@ relevant buffers before generating the contents of a VC Directory buffer (like the third-party package Magit does with its status buffer). +++ -*** New commands 'vc-root-diff-incoming' and 'vc-root-diff-outgoing'. -These commands report diffs of all the changes that would be pulled and -would be pushed, respectively. They are the diff analogues of the -existing commands 'vc-log-incoming' and 'vc-log-outgoing'. +*** New commands to report incoming and outgoing diffs. +'vc-root-diff-incoming' and 'vc-root-diff-outgoing' report diffs of all +the changes that would be pulled and would be pushed, respectively. +They are the diff analogues of the existing commands 'vc-log-incoming' +and 'vc-log-outgoing'. In particular, 'vc-root-diff-outgoing' is useful as a way to preview your push and ensure that all and only the changes you intended to include were committed and will be pushed. +'vc-diff-incoming' and 'vc-diff-outgoing' are similar but limited to the +current VC fileset. + +++ *** New user option 'vc-use-incoming-outgoing-prefixes'. If this is customized to non-nil, 'C-x v I' and 'C-x v O' become prefix @@ -2142,6 +2301,16 @@ destination window is chosen using 'display-buffer-alist'. Example: display-buffer-use-some-window) (some-window . mru)))) +** Revert + ++++ +*** Variable 'revert-buffer-in-progress' has been renamed. +The old name, 'revert-buffer-in-progress-p', is kept as obsolete +variable alias. + +Symbol names with a trailing '-p' are reserved for predicates. Calling +a variable like this was a mistake. + ** Autorevert +++ @@ -2155,6 +2324,12 @@ This macro adds the current buffer to 'inhibit-auto-revert-buffers', runs its body, and removes the current buffer from 'inhibit-auto-revert-buffers' afterwards. ++++ +*** New variable 'auto-revert-buffer-in-progress'. +'auto-revert-buffer' binds this variable to a non-nil value while it is +working. This can be used by major mode 'revert-buffer-function' +implementations to suppress messages in Auto Revert modes, for example. + ** Strokes -- @@ -2340,11 +2515,6 @@ file names in above buffers. The default is nil. --- ** Flymake -*** Windows without fringes now automatically use margin indicators. -When 'flymake-indicator-type' is set to 'fringes', as is now the default, -flymake will automatically fall back to using margin indicators in -windows without fringes, including any window on a text terminal. - *** Enhanced 'flymake-show-diagnostics-at-end-of-line' The new value 'fancy' allowed for this user option will attempt to layout diagnostics below the affected line using unicode graphics to @@ -2410,6 +2580,12 @@ modifier, it scrolls by year. The month and year navigation key bindings 'M-}', 'M-{', 'C-x ]' and 'C-x [' now have the alternative keys '}', '{', ']' and '['. +--- +*** Avoid modifying Calendar's user options. +The user options 'calendar-mark-holidays-flag' and +'calendar-mark-diary-entries-flag' are not modified anymore when +changing the marking state in the calendar buffer. + ** Calc *** New user option 'calc-string-maximum-character'. @@ -2456,10 +2632,10 @@ Use the byte-compiler instead; it provides more and more useful warnings. --- *** New user option 'newsticker-hide-old-feed-header'. It controls whether to automatically hide the header of feeds whose -items are all old or obsolete in the plainview *newsticker* buffer. +items are all old or obsolete in the plainview "*newsticker*" buffer. This is only visually interesting if the content of those feeds are also hidden (see 'newsticker-hide-old-items-in-newsticker-buffer' and -'newsticker-show-descriptions-of-new-items')." +'newsticker-show-descriptions-of-new-items'). --- *** New commands to hide and show headers of old newsticker feeds. @@ -2471,7 +2647,6 @@ or obsolete. ** CPerl mode *** Syntax of Perl up to version 5.42 is supported. - CPerl mode creates imenu entries for ":writer" generated accessors and recognizes the new functions "all" and "any". See https://perldoc.perl.org/5.42.0/perldelta for details. @@ -2505,6 +2680,21 @@ enabled for files named "go.work". * Incompatible Lisp Changes in Emacs 31.1 ++++ +** String mutation has been restricted further. +'aset' on unibyte strings now requires the new character to be a single +byte (0-255). On multibyte strings the new character and the character +being replaced must both be ASCII (0-127). + +These rules ensure that mutation will never transform a unibyte string +to multibyte, and that the size of a string in bytes (as reported by +'string-bytes') never changes. They also allow strings to be +represented more efficiently in the future. + +Other functions that use 'aset' to modify string data, such as +'subst-char-in-string' with a non-nil INPLACE argument, will signal an +error if called with arguments that would violate these rules. + ** Nested backquotes are not supported any more in Pcase patterns. --- @@ -2513,9 +2703,6 @@ enabled for files named "go.work". ** The 'rx' category name 'chinese-two-byte' must now be spelled correctly. An old alternative name (without the first 'e') has been removed. -+++ -** 'read-directory-name' now accepts an optional PREDICATE argument. - +++ ** 'text-property-default-nonsticky' is now buffer-local. This variable now becomes buffer-local when set. Use 'setq-default' in @@ -2586,6 +2773,21 @@ That is, if the PATH environment variable is unset or empty, 'exec-path' now acts as if PATH is the system default, which is "/bin:/usr/bin" on GNU/Linux systems. +--- +** New variable 'tty-cursor-movement-use-TAB-BS'. +The display optimization where the combination TAB characters + +BACKSPACE is used to move to a position on a TTY frame is now disabled +by default and controlled by this variable; it can be set to non-nil +to keep the old behavior. This change is to accomodate screen +readers. + ++++ +** A thread's current buffer can now be killed. +We introduce a new attribute for threads called buffer-disposition. +See the new argument in 'make-thread'. The default value allows the +thread's current buffer to be killed by another thread. This does not +apply to the main thread's buffer. + * Lisp Changes in Emacs 31.1 @@ -2835,6 +3037,14 @@ option, but can optionally return the equivalent of 'exec-suffixes' from a remote host. It must be used in conjunction with the function 'exec-path'. ++++ +** 'read-directory-name' now accepts an optional PREDICATE argument. + +--- +** JSON parse error line and column are now obsolete. +The column number is no longer available; the line number will be +removed in next Emacs release. + * Changes in Emacs 31.1 on Non-Free Operating Systems diff --git a/etc/NEWS.21 b/etc/NEWS.21 index ed7b69f18e6..2b6b6084c6e 100644 --- a/etc/NEWS.21 +++ b/etc/NEWS.21 @@ -1822,7 +1822,7 @@ separate Texinfo file. *** The PCL-CVS package available by either running M-x cvs-examine or by visiting a CVS administrative directory (with a prefix argument) -provides an alternative interface to VC-dired for CVS. It comes with +provides an alternative interface to VC-Dir for CVS. It comes with 'log-view-mode' to view RCS and SCCS logs and 'log-edit-mode' used to enter check-in log messages. diff --git a/etc/NEWS.30 b/etc/NEWS.30 index c52929b6d38..dfe6c5cafe6 100644 --- a/etc/NEWS.30 +++ b/etc/NEWS.30 @@ -15,32 +15,9 @@ in older Emacs versions. You can narrow news to a specific version by calling 'view-emacs-news' with a prefix argument or by typing 'C-u C-h C-n'. - -* Installation Changes in Emacs 30.2 - - -* Startup Changes in Emacs 30.2 - * Changes in Emacs 30.2 - - -* Editing Changes in Emacs 30.2 - - -* Changes in Specialized Modes and Packages in Emacs 30.2 - - -* New Modes and Packages in Emacs 30.2 - - -* Incompatible Lisp Changes in Emacs 30.2 - - -* Lisp Changes in Emacs 30.2 - - -* Changes in Emacs 30.2 on Non-Free Operating Systems +Emacs 30.2 is a bug-fix release with no new features. * Installation Changes in Emacs 30.1 diff --git a/etc/images/tabs/README b/etc/images/tabs/README index c3bab00d56c..2a68577951f 100644 --- a/etc/images/tabs/README +++ b/etc/images/tabs/README @@ -4,5 +4,9 @@ COPYRIGHT AND LICENSE INFORMATION FOR IMAGE FILES Files: close.xpm new.xpm left-arrow.xpm right-arrow.xpm Author: Juri Linkov + +Files: close-modified.xpm +Author: Elías Gabriel Pérez + Copyright (C) 2019-2025 Free Software Foundation, Inc. License: GNU General Public License version 3 or later (see COPYING) diff --git a/etc/images/tabs/close-modified.xpm b/etc/images/tabs/close-modified.xpm new file mode 100644 index 00000000000..44b45d49011 --- /dev/null +++ b/etc/images/tabs/close-modified.xpm @@ -0,0 +1,16 @@ +/* XPM */ +static char *dummy[]={ +"9 9 4 1", +". c None", +"b c #000000", +"a c #808080", +"# c #bfbfbf", +"..#####..", +".#######.", +"###aaa###", +"##abbba##", +"##abbba##", +"##abbba##", +"###aaa###", +".#######.", +"..#####.."}; diff --git a/etc/symbol-releases.eld b/etc/symbol-releases.eld index 9732f60fc16..3c666423cc0 100644 --- a/etc/symbol-releases.eld +++ b/etc/symbol-releases.eld @@ -9,6 +9,8 @@ ;; TYPE being `fun' or `var'. ( + ("30.1" fun dired-click-to-select-mode) + ("30.1" var dired-click-to-select-mode) ("29.1" fun plistp) ("29.1" fun help-key) ("28.1" fun always) diff --git a/lib/copy-file-range.c b/lib/copy-file-range.c index 8e0c644c086..2465a558028 100644 --- a/lib/copy-file-range.c +++ b/lib/copy-file-range.c @@ -21,9 +21,22 @@ #include #if defined __linux__ && HAVE_COPY_FILE_RANGE +# include # include +/* Although it can be dicey to use static checks for Linux kernel versions, + due to the dubious practice of building on newer kernels for older ones, + do it here anyway as the buggy kernels are rare (they are all EOLed) + and builders for them are unlikely to use the dubious practice. + Circa 2029 we should remove the old-kernel workarounds entirely. */ +# if LINUX_VERSION_CODE < KERNEL_VERSION (5, 3, 0) +# define CHECK_LINUX_KERNEL_VERSION true +# else +# define CHECK_LINUX_KERNEL_VERSION false +# endif #endif +#include "sys-limits.h" + ssize_t copy_file_range (int infd, off_t *pinoff, int outfd, off_t *poutoff, @@ -31,32 +44,51 @@ copy_file_range (int infd, off_t *pinoff, { #undef copy_file_range -#if defined __linux__ && HAVE_COPY_FILE_RANGE +#if HAVE_COPY_FILE_RANGE + bool ok = true; + +# if CHECK_LINUX_KERNEL_VERSION /* The implementation of copy_file_range (which first appeared in Linux kernel release 4.5) had many issues before release 5.3 , so fail with ENOSYS for Linux kernels 5.2 and earlier. - This workaround, and the configure-time check for Linux, can be - removed when such kernels (released March 2016 through September - 2019) are no longer a consideration. As of January 2021, the - furthest-future planned kernel EOL is December 2024 for kernel - release 4.19. */ + This workaround can be removed when such kernels (released March + 2016 through September 2019) are no longer a consideration. + Although all such kernels have reached EOL, some distros use + older kernels. For example, RHEL 8 uses kernel 4.18 and has an + EOL of 2029. */ - static signed char ok; + static signed char kernel_ok; + if (! kernel_ok) + { + struct utsname name; + uname (&name); + char *p = name.release; + kernel_ok = ((p[1] != '.' || '5' < p[0] + || (p[0] == '5' && (p[3] != '.' || '2' < p[2]))) + ? 1 : -1); + } - if (! ok) - { - struct utsname name; - uname (&name); - char *p = name.release; - ok = ((p[1] != '.' || '5' < p[0] - || (p[0] == '5' && (p[3] != '.' || '2' < p[2]))) - ? 1 : -1); - } + if (kernel_ok < 0) + ok = false; +# endif + + if (ok) + { +# if defined __GLIBC__ && ! (2 < __GLIBC__ + (43 <= __GLIBC_MINOR__)) + /* Work around glibc bug 33245 + . + This bug is present in glibc 2.42 (2025) and fixed in 2.43, + so this workaround, and the configure-time check for glibc, + can be removed once glibc 2.42 and earlier is no longer a + consideration. Perhaps in 2040. */ + if (SYS_BUFSIZE_MAX < length) + length = SYS_BUFSIZE_MAX; +# endif - if (0 < ok) return copy_file_range (infd, pinoff, outfd, poutoff, length, flags); + } #endif /* There is little need to emulate copy_file_range with read+write, diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index b3774a648b8..fa800300a42 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -1799,6 +1799,8 @@ ifneq (,$(GL_COND_OBJ_COPY_FILE_RANGE_CONDITION)) libgnu_a_SOURCES += copy-file-range.c endif +EXTRA_DIST += sys-limits.h + endif ## end gnulib module copy-file-range diff --git a/lib/sys-limits.h b/lib/sys-limits.h new file mode 100644 index 00000000000..a556dfeb6d5 --- /dev/null +++ b/lib/sys-limits.h @@ -0,0 +1,42 @@ +/* System call limits + + Copyright 2018-2025 Free Software Foundation, Inc. + + This file is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This file is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#ifndef _GL_SYS_LIMITS_H +#define _GL_SYS_LIMITS_H + +#include + +/* Maximum number of bytes to read or write in a single system call. + This can be useful for system calls like sendfile on GNU/Linux, + which do not handle more than MAX_RW_COUNT bytes correctly. + The Linux kernel MAX_RW_COUNT is at least INT_MAX >> 20 << 20, + where the 20 comes from the Hexagon port with 1 MiB pages; use that + as an approximation, as the exact value may not be available to us. + + Using this also works around a serious Linux bug before 2.6.16; see + . + + Using this also works around a Tru64 5.1 bug, where attempting + to read INT_MAX bytes fails with errno == EINVAL. See + . + + Using this is likely to work around similar bugs in other operating + systems. */ + +enum { SYS_BUFSIZE_MAX = INT_MAX >> 20 << 20 }; + +#endif diff --git a/lisp/Makefile.in b/lisp/Makefile.in index 17182357739..9dacf766108 100644 --- a/lisp/Makefile.in +++ b/lisp/Makefile.in @@ -212,7 +212,8 @@ autoloads-force: $(MAKE) autoloads ldefs-boot.el: autoloads-force - sed '/^;; Local Variables:/a ;; no-byte-compile: t'\ + sed '/^;; Local Variables:/a\ +;; no-byte-compile: t'\ < $(lisp)/loaddefs.el > $(lisp)/ldefs-boot.el # This is required by the bootstrap-emacs target in ../src/Makefile, so diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 10ff3871074..8f6c71a4b74 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -897,7 +897,7 @@ when parsing the archive." "Toggle alternative display. To avoid very long lines archive mode does not show all information. This function changes the set of information shown for each files." - (interactive) + (interactive nil archive-mode) (setq archive-alternate-display (not archive-alternate-display)) (setq-local archive-hidden-columns (if archive-alternate-display @@ -913,7 +913,8 @@ This function changes the set of information shown for each files." (list (intern (completing-read "Toggle visibility of: " '(Mode Ids Ratio Date&Time) - nil t)))) + nil t))) + archive-mode) (setq-local archive-hidden-columns (if (memq column archive-hidden-columns) (remove column archive-hidden-columns) @@ -1133,7 +1134,8 @@ NEW-NAME." (or (archive-get-marked ?*) (list (archive-get-descr)))))) (list names (read-file-name (format "Copy %s to: " (string-join names ", ")) - nil default-directory)))) + nil default-directory))) + archive-mode) (unless (consp files) (setq files (list files))) (when (and (> (length files) 1) @@ -1171,7 +1173,7 @@ NEW-NAME." (defun archive-extract (&optional other-window-p event) "In archive mode, extract this entry of the archive into its own buffer." - (interactive (list nil last-input-event)) + (interactive (list nil last-input-event) archive-mode) (if event (posn-set-point (event-end event))) (let* ((view-p (eq other-window-p 'view)) (descr (archive-get-descr)) @@ -1348,17 +1350,17 @@ NEW-NAME." (defun archive-extract-other-window () "In archive mode, find this member in another window." - (interactive) + (interactive nil archive-mode) (archive-extract t)) (defun archive-display-other-window () "In archive mode, display this member in another window." - (interactive) + (interactive nil archive-mode) (archive-extract 'display)) (defun archive-view () "In archive mode, view the member on this line." - (interactive) + (interactive nil archive-mode) (archive-extract 'view)) (defun archive-add-new-member (arcbuf name) @@ -1469,7 +1471,7 @@ NEW-NAME." (defun archive-flag-deleted (p &optional type) "In archive mode, mark this member to be deleted from the archive. With a prefix argument, mark that many files." - (interactive "p") + (interactive "p" archive-mode) (or type (setq type ?D)) (beginning-of-line) (let ((sign (if (>= p 0) +1 -1)) @@ -1488,18 +1490,18 @@ With a prefix argument, mark that many files." (defun archive-unflag (p) "In archive mode, un-mark this member if it is marked to be deleted. With a prefix argument, un-mark that many files forward." - (interactive "p") + (interactive "p" archive-mode) (archive-flag-deleted p ?\s)) (defun archive-unflag-backwards (p) "In archive mode, un-mark this member if it is marked to be deleted. With a prefix argument, un-mark that many members backward." - (interactive "p") + (interactive "p" archive-mode) (archive-flag-deleted (- p) ?\s)) (defun archive-unmark-all-files () "Remove all marks." - (interactive) + (interactive nil archive-mode) (let ((modified (buffer-modified-p)) (inhibit-read-only t)) (save-excursion @@ -1514,7 +1516,7 @@ With a prefix argument, un-mark that many members backward." "In archive mode, mark this member for group operations. With a prefix argument, mark that many members. Use \\[archive-unmark-all-files] to remove all marks." - (interactive "p") + (interactive "p" archive-mode) (archive-flag-deleted p ?*)) (defun archive-get-marked (mark &optional default) @@ -1532,20 +1534,20 @@ Use \\[archive-unmark-all-files] to remove all marks." ;;; Section: Operate (defun archive-next-line (p) - (interactive "p") + (interactive "p" archive-mode) (forward-line p) (or (eobp) (forward-char archive-file-name-indent))) (defun archive-previous-line (p) - (interactive "p") + (interactive "p" archive-mode) (archive-next-line (- p))) (defun archive-chmod-entry (new-mode) "Change the protection bits associated with all marked or this member. The new protection bits can either be specified as an octal number or as a relative change like \"g+rw\" as for chmod(2)." - (interactive "sNew mode (octal or symbolic): ") + (interactive "sNew mode (octal or symbolic): " archive-mode) (if archive-read-only (error "Archive is read-only")) (let ((func (archive-name "chmod-entry"))) (if (fboundp func) @@ -1556,7 +1558,7 @@ as a relative change like \"g+rw\" as for chmod(2)." (defun archive-chown-entry (new-uid) "Change the owner of all marked or this member." - (interactive "nNew uid: ") + (interactive "nNew uid: " archive-mode) (if archive-read-only (error "Archive is read-only")) (let ((func (archive-name "chown-entry"))) (if (fboundp func) @@ -1567,7 +1569,7 @@ as a relative change like \"g+rw\" as for chmod(2)." (defun archive-chgrp-entry (new-gid) "Change the group of all marked or this member." - (interactive "nNew gid: ") + (interactive "nNew gid: " archive-mode) (if archive-read-only (error "Archive is read-only")) (let ((func (archive-name "chgrp-entry"))) (if (fboundp func) @@ -1607,7 +1609,7 @@ as a relative change like \"g+rw\" as for chmod(2)." (defun archive-expunge () "Do the flagged deletions." - (interactive) + (interactive nil archive-mode) (archive--expunge-maybe-force nil)) (defun archive-*-expunge (archive files command) @@ -1616,7 +1618,7 @@ as a relative change like \"g+rw\" as for chmod(2)." (defun archive-rename-entry (newname) "Change the name associated with this entry in the archive file." - (interactive "sNew name: ") + (interactive "sNew name: " archive-mode) (if archive-read-only (error "Archive is read-only")) (if (string= newname "") (error "Archive members may not be given empty names")) @@ -1644,7 +1646,7 @@ as a relative change like \"g+rw\" as for chmod(2)." (defun archive-undo () "Undo in an archive buffer. This doesn't recover lost files, it just undoes changes in the buffer itself." - (interactive) + (interactive nil archive-mode) (let ((inhibit-read-only t)) (undo))) diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el index e7492d1b9ed..d5ccb7d1e0e 100644 --- a/lisp/autoinsert.el +++ b/lisp/autoinsert.el @@ -323,8 +323,11 @@ The document was typeset with ")) "A list specifying text to insert by default into a new file. Elements look like (CONDITION . ACTION) or ((CONDITION . DESCRIPTION) . ACTION). -CONDITION may be a regexp that must match the new file's name, or it may be -a symbol that must match the major mode for this element to apply. +CONDITION may be a regexp that must match the new file's name, or it +may be a symbol that must match the major mode for this element to apply. +CONDITION can also be a custom predicate of no arguments declared +with (predicate FUNCTION). Emacs will insert the text if the +predicate function returns non-nil. Only the first matching element is effective. Optional DESCRIPTION is a string for filling `auto-insert-prompt'. ACTION may be a skeleton to insert (see `skeleton-insert'), an absolute @@ -368,12 +371,24 @@ Matches the visited file name against the elements of `auto-insert-alist'." (pcase-lambda (`(,cond . ,action)) (if (atom cond) (setq desc cond) - (setq desc (cdr cond) - cond (car cond))) - (when (if (symbolp cond) - (derived-mode-p cond) + ;; if `cond' is a predicate, don't split it but set `desc' to a custom string + (if (and (consp cond) (equal (car cond) 'predicate)) + (setq desc "predicate") + (setq desc (cdr cond) + cond (car cond)))) + (when (cond + ;; `cond' should be a major-mode variable + ((symbolp cond) + (derived-mode-p cond)) + + ;; `cond' should be a predicate that takes no argument + ((and (consp cond) (equal (car cond) 'predicate)) + (funcall (cadr cond))) + + ;; cond should be a regexp + (t (and buffer-file-name - (string-match cond buffer-file-name))) + (string-match cond buffer-file-name)))) action)) auto-insert-alist))) (goto-char 1) diff --git a/lisp/autorevert.el b/lisp/autorevert.el index 2fae74ddc57..ccedaa759cb 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el @@ -329,6 +329,10 @@ seconds, in addition to using notification for those files." ;; Internal variables: +;;;###autoload +(defvar auto-revert-buffer-in-progress nil "\ +Non-nil if a `auto-revert-buffer' operation is in progress, nil otherwise.") + (defvar auto-revert-buffer-list () "List of buffers in Auto-Revert Mode. @@ -834,16 +838,15 @@ This is an internal function used by Auto-Revert Mode." t))))) eob eoblist) (when (timerp auto-revert--lockout-timer) - (cancel-timer auto-revert--lockout-timer)) - (setq auto-revert-notify-modified-p nil - auto-revert--last-time - (if revert (current-time) auto-revert--last-time) - auto-revert--lockout-timer nil) + (cancel-timer auto-revert--lockout-timer) + (setq auto-revert--lockout-timer nil)) (when revert (when (and auto-revert-verbose (not (eq revert 'fast))) (message "Reverting buffer `%s'" (buffer-name))) + (setq auto-revert-notify-modified-p nil + auto-revert--last-time (current-time)) ;; If point (or a window point) is at the end of the buffer, we ;; want to keep it at the end after reverting. This allows one ;; to tail a file. @@ -872,7 +875,7 @@ This is an internal function used by Auto-Revert Mode." ;; `preserve-modes' avoids changing the (minor) modes. But we do ;; want to reset the mode for VC, so we do it manually. (when (and (not auto-revert-tail-mode) (or revert auto-revert-check-vc-info)) - (let ((revert-buffer-in-progress-p t)) + (let ((revert-buffer-in-progress t)) (vc-refresh-state))))) (defun auto-revert-tail-handler (size) @@ -933,25 +936,25 @@ buffers not reverted last time due to user interruption." This is performed as specified by Auto-Revert and Global Auto-Revert Modes." - (if (not (buffer-live-p buf)) - (auto-revert-remove-current-buffer buf) - (with-current-buffer buf - ;; Test if someone has turned off Auto-Revert Mode - ;; in a non-standard way, for example by changing - ;; major mode. - (when (and (not auto-revert-mode) - (not auto-revert-tail-mode)) - (auto-revert-remove-current-buffer)) - (when (auto-revert-active-p) - ;; Enable file notification. - ;; Don't bother creating a notifier for non-file buffers - ;; unless it explicitly indicates that this works. - (when (and auto-revert-use-notify - (not auto-revert-notify-watch-descriptor) - (or buffer-file-name - buffer-auto-revert-by-notification)) - (auto-revert-notify-add-watch)) - (auto-revert-handler))))) + (let ((auto-revert-buffer-in-progress t)) + (if (not (buffer-live-p buf)) + (auto-revert-remove-current-buffer buf) + (with-current-buffer buf + ;; Test if someone has turned off Auto-Revert Mode in a + ;; non-standard way, for example by changing major mode. + (when (and (not auto-revert-mode) + (not auto-revert-tail-mode)) + (auto-revert-remove-current-buffer)) + (when (auto-revert-active-p) + ;; Enable file notification. + ;; Don't bother creating a notifier for non-file buffers + ;; unless it explicitly indicates that this works. + (when (and auto-revert-use-notify + (not auto-revert-notify-watch-descriptor) + (or buffer-file-name + buffer-auto-revert-by-notification)) + (auto-revert-notify-add-watch)) + (auto-revert-handler)))))) (defun auto-revert-buffers () "Revert buffers as specified by Auto-Revert and Global Auto-Revert Mode. diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index 917624c489e..04a42fcd38a 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -456,6 +456,12 @@ LEFT is the leftmost column associated with month segment N, FIRST and LAST are the first and last columns with day digits in, and LAST is the rightmost column.") +(defvar calendar-mark-holidays nil + "Variable version of the user option `calendar-mark-holidays-flag'.") + +(defvar calendar-mark-diary-entries nil + "Variable version of the user option `calendar-mark-diary-entries-flag'.") + (defun calendar-month-edges (segment) "Compute the month edge columns for month SEGMENT. Returns a list (LEFT FIRST LAST RIGHT), where LEFT is the @@ -1161,17 +1167,20 @@ MON defaults to `displayed-month'. YR defaults to `displayed-year'." First creates or erases BUFFER as needed. Leaves BUFFER read-only, with disabled undo. Leaves point at `point-min', displays BUFFER." (declare (indent 1) (debug t)) - `(progn - (set-buffer (get-buffer-create ,buffer)) - (or (derived-mode-p 'special-mode) (special-mode)) - (setq buffer-read-only nil - buffer-undo-list t) - (erase-buffer) - (display-buffer ,buffer) - ,@body - (goto-char (point-min)) - (set-buffer-modified-p nil) - (setq buffer-read-only t))) + (let ((window (gensym))) + `(progn + (set-buffer (get-buffer-create ,buffer)) + (or (derived-mode-p 'special-mode) (special-mode)) + (setq buffer-read-only nil + buffer-undo-list t) + (erase-buffer) + (let ((,window (display-buffer ,buffer))) + (when ,window + (with-selected-window ,window + ,@body + (goto-char (point-min))))) + (set-buffer-modified-p nil) + (setq buffer-read-only t)))) ;; The following are in-line for speed; they can be called thousands of times ;; when looking up holidays or processing the diary. Here, for example, are @@ -1433,11 +1442,11 @@ Optional integers MON and YR are used instead of today's date." ;; For a full height window or a window that is horizontally ;; combined don't fit height to that of its buffer. (set-window-vscroll nil 0))) - (and calendar-mark-holidays-flag + (and calendar-mark-holidays ;; (calendar-date-is-valid-p today) ; useful for BC dates (calendar-mark-holidays)) (unwind-protect - (if calendar-mark-diary-entries-flag (diary-mark-entries)) + (if calendar-mark-diary-entries (diary-mark-entries)) (run-hooks (if today-visible 'calendar-today-visible-hook 'calendar-today-invisible-hook))))) @@ -1830,6 +1839,9 @@ For a complete description, see the info node `Calendar/Diary'. (make-local-variable 'calendar-mark-ring) (make-local-variable 'displayed-month) ; month in middle of window (make-local-variable 'displayed-year) ; year in middle of window + ;; Init with user options. + (setq calendar-mark-holidays calendar-mark-holidays-flag + calendar-mark-diary-entries calendar-mark-diary-entries-flag) ;; Most functions only work if displayed-month and displayed-year are set, ;; so let's make sure they're always set. Most likely, this will be reset ;; soon in calendar-generate, but better safe than sorry. @@ -2428,8 +2440,8 @@ interpreted as BC; -1 being 1 BC, and so on." (defun calendar-unmark () "Delete all diary/holiday marks/highlighting from the calendar." (interactive) - (setq calendar-mark-holidays-flag nil - calendar-mark-diary-entries-flag nil) + (setq calendar-mark-holidays nil + calendar-mark-diary-entries nil) (with-current-buffer calendar-buffer (mapc #'delete-overlay (overlays-in (point-min) (point-max))))) diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el index 3d8d827417e..056360bbede 100644 --- a/lisp/calendar/diary-lib.el +++ b/lisp/calendar/diary-lib.el @@ -1395,8 +1395,8 @@ marks. This is intended to deal with deleted diary entries." ;; ii) called via calendar-redraw (since calendar has already been ;; erased). ;; Use of REDRAW handles both of these cases. - (when (and redraw calendar-mark-diary-entries-flag) - (setq calendar-mark-diary-entries-flag nil) + (when (and redraw calendar-mark-diary-entries) + (setq calendar-mark-diary-entries nil) (calendar-redraw)) (let ((diary-marking-entries-flag t) (diary-buffer (find-buffer-visiting diary-file)) @@ -1417,7 +1417,7 @@ marks. This is intended to deal with deleted diary entries." ;; If including, caller has already verified it is readable. (insert-file-contents diary-file) (if (eq major-mode (default-value 'major-mode)) (diary-mode))) - (setq calendar-mark-diary-entries-flag t) + (setq calendar-mark-diary-entries t) (setq file-glob-attrs (nth 1 (diary-pull-attrs nil '()))) (with-syntax-table diary-syntax-table (save-excursion @@ -2243,7 +2243,7 @@ Prefix argument ARG makes the entry nonmarking." (defun diary-redraw-calendar () "If `calendar-buffer' is live and diary entries are marked, redraw it." - (and calendar-mark-diary-entries-flag + (and calendar-mark-diary-entries (save-excursion (calendar-redraw))) ;; Return value suitable for `write-contents-functions'. diff --git a/lisp/calendar/holidays.el b/lisp/calendar/holidays.el index b40c56abd86..28f3a0ae7f2 100644 --- a/lisp/calendar/holidays.el +++ b/lisp/calendar/holidays.el @@ -585,7 +585,7 @@ use instead of point." (with-current-buffer (if event (calendar-event-buffer event) (current-buffer)) - (setq calendar-mark-holidays-flag t) + (setq calendar-mark-holidays t) (message "Marking holidays...") (dolist (holiday (calendar-holiday-list)) (calendar-mark-visible-date (car holiday) calendar-holiday-marker)) diff --git a/lisp/cmuscheme.el b/lisp/cmuscheme.el index 51b183de347..0d591791d73 100644 --- a/lisp/cmuscheme.el +++ b/lisp/cmuscheme.el @@ -416,7 +416,7 @@ in the next one.") (setq scheme-prev-l/c-dir/file (cons (file-name-directory file-name) (file-name-nondirectory file-name))) (comint-send-string (scheme-proc) (concat "(load \"" - file-name + (file-local-name file-name) "\")\n"))) (defun scheme-compile-file (file-name) @@ -430,7 +430,7 @@ in the next one.") (setq scheme-prev-l/c-dir/file (cons (file-name-directory file-name) (file-name-nondirectory file-name))) (comint-send-string (scheme-proc) (concat "(compile-file \"" - file-name + (file-local-name file-name) "\")\n"))) diff --git a/lisp/comint.el b/lisp/comint.el index b9c910eff43..bbb9820c16a 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -1197,7 +1197,7 @@ This function makes `comint-dynamic-list-input-ring' obsolete." (ring-elements comint-input-ring) (user-error "No history available"))) (completion-in-region-mode-predicate - (lambda () (get-buffer-window "*Completions*" 0)))) + (lambda () (minibuffer--completions-visible)))) (completion-in-region (comint-line-beginning-position) (point-max) (completion-table-with-metadata @@ -3521,7 +3521,7 @@ The optional argument COMMON-SUBSTRING, if non-nil, should be a string specifying a common substring for adding the faces `completions-first-difference' and `completions-common-part' to the completions." - (let ((window (get-buffer-window "*Completions*" 0))) + (let ((window (minibuffer--completions-visible))) (setq completions (sort completions #'string-lessp)) (if (and (eq last-command this-command) window (window-live-p window) (window-buffer window) diff --git a/lisp/completion-preview.el b/lisp/completion-preview.el index 84380ee5c54..e5953f4a513 100644 --- a/lisp/completion-preview.el +++ b/lisp/completion-preview.el @@ -521,7 +521,9 @@ candidates or if there are multiple matching completions and (run-hook-wrapped 'completion-at-point-functions #'completion-preview--capf-wrapper) - (when-let* ((suffix (car suffixes))) + (when-let* ((suffix (car suffixes)) + (inhibit-quit t)) + ;; Critical section, do not quit upon receiving input here. (set-text-properties 0 (length suffix) (list 'face (if (cdr suffixes) 'completion-preview diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 3bc296e4ad1..e49d1552c08 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -77,10 +77,10 @@ (const box) integer) (const :tag "Hollow cursor" hollow) (const :tag "Vertical bar" bar) - (cons :tag "Vertical bar with specified height" + (cons :tag "Vertical bar with specified width" (const bar) integer) (const :tag "Horizontal bar" hbar) - (cons :tag "Horizontal bar with specified width" + (cons :tag "Horizontal bar with specified height" (const hbar) integer) (const :tag "None "nil)))) (pcase-dolist diff --git a/lisp/dired-x.el b/lisp/dired-x.el index 59668f79bd7..ad602b00a3e 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el @@ -475,7 +475,9 @@ status message." nil))) (let ((omit-re (or regexp (dired-omit-regexp))) (old-modified-p (buffer-modified-p)) - (count (or init-count 0))) + (count (or init-count 0)) + (dired-omit-verbose + (and dired-omit-verbose (not auto-revert-buffer-in-progress)))) (unless (string= omit-re "") (let ((dired-marker-char dired-omit-marker-char)) (when dired-omit-verbose (message "Omitting...")) diff --git a/lisp/dired.el b/lisp/dired.el index 103c273ccfd..996ca9c23bb 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -4057,7 +4057,10 @@ non-empty directories is allowed." (message "(No deletions requested)"))))) (defun dired-post-do-command () - "Disable `dired-click-to-select-mode' after an operation." + "Disable `dired-click-to-select-mode' if enabled.. +This is called after Dired finishes an operation on marked files, and it +disables `dired-click-to-select-mode' that is automatically enabled +by the \"hold\" touch-screen gestures." (when dired-click-to-select-mode (dired-click-to-select-mode -1))) @@ -5381,12 +5384,14 @@ When this minor mode is enabled, using `mouse-2' on a file name within a Dired buffer will toggle its mark instead of going to it within another window. -Disabling this minor mode will unmark all files within the Dired -buffer. - -`dired-click-to-select-mode' is automatically disabled after any -Dired operation (command whose name starts with `dired-do') -completes." +This minor mode is intended to be used when performing file management +using a touch-screen device. The mode is automatically enabled when a +\"hold\" gesture over a file name is received, and is therefore +automatically disabled after any Dired operation on the marked +files (any command whose name starts with \"dired-do-\" and which +performs some operation on the marked files) completes. When the mode +is automatically disabled, it unmarks all the marked files in the Dired +buffer." :group 'dired :lighter " Click-To-Select" (unless (derived-mode-p '(dired-mode wdired-mode)) diff --git a/lisp/doc-view.el b/lisp/doc-view.el index b9bde21eaa8..30536cb4c6c 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el @@ -2143,7 +2143,11 @@ If FILE-NAME is nil, use the current file instead." (defun doc-view-initiate-display () ;; Switch to image display if possible. (if (doc-view-mode-p doc-view-doc-type) - (progn + ;; Inhibit the echo area display of the "Type C-c C-c..." message + ;; if the doc-view buffer is not shown in the selected window + ;; which can happen due to auto-reverting the buffer (bug#79145). + (let ((inhibit-message (not (eq (current-buffer) + (window-buffer))))) (doc-view-buffer-message) (setf (doc-view-current-page) (or (doc-view-current-page) 1)) (if (doc-view-already-converted-p) diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 6412c8cde22..49fd6084693 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -286,6 +286,12 @@ This is used by `declare'.") (list 'put (list 'quote name) ''edebug-form-spec (list 'quote spec))))) +(defalias 'byte-run--set-autoload-macro + #'(lambda (name _args spec) + (list 'function-put (list 'quote name) + ''autoload-macro (list 'quote spec))) + "Handle autoload-macro declarations") + (defalias 'byte-run--set-no-font-lock-keyword #'(lambda (name _args val) (list 'function-put (list 'quote name) @@ -365,8 +371,13 @@ This is used by `declare'.") (cons (list 'debug #'byte-run--set-debug) (cons - (list 'no-font-lock-keyword #'byte-run--set-no-font-lock-keyword) - defun-declarations-alist)) + ;; macros can declare (autoload-macro expand) to request expansion + ;; during autoload generation of forms calling them. See + ;; `loaddefs-generate--make-autoload'. + (list 'autoload-macro #'byte-run--set-autoload-macro) + (cons + (list 'no-font-lock-keyword #'byte-run--set-no-font-lock-keyword) + defun-declarations-alist))) "List associating properties of macros to their macro expansion. Each element of the list takes the form (PROP FUN) where FUN is a function. For each (PROP . VALUES) in a macro's declaration, the FUN corresponding @@ -412,6 +423,8 @@ The return value is undefined. (if declarations (cons 'prog1 (cons def (car declarations))) def)))))) +;; Expand to defalias and related forms on autoload gen +(function-put 'defmacro 'autoload-macro 'expand) ; Since we cannot `declare' it ;; Now that we defined defmacro we can use it! (defmacro defun (name arglist &rest body) @@ -424,7 +437,9 @@ INTERACTIVE is an optional `interactive' specification. The return value is undefined. \(fn NAME ARGLIST [DOCSTRING] [DECL] [INTERACTIVE] BODY...)" - (declare (doc-string 3) (indent 2)) + (declare (doc-string 3) (indent 2) + ;; Expand to defalias on autoload gen + (autoload-macro expand)) (or name (error "Cannot define '%s' as a function" name)) (if (null (and (listp arglist) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index a694bfe11d5..ca3d8654488 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -3592,6 +3592,7 @@ This assumes the function has the `important-return-value' property." (cl-nset-exclusive-or 1 2) (cl-nreconc 1) (cl-sort 1) (cl-stable-sort 1) (cl-merge 2 3) + (cl-fill 1) (cl-replace 1) ))) (dolist (entry mutating-fns) (put (car entry) 'mutates-arguments (cdr entry)))) diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 4c6c6a0007c..e821b15378b 100644 --- a/lisp/emacs-lisp/cl-generic.el +++ b/lisp/emacs-lisp/cl-generic.el @@ -230,9 +230,11 @@ SPECIALIZERS-FUNCTION takes as first argument a tag value TAG (defmacro cl-defgeneric (name args &rest options-and-methods) "Create a generic function NAME. DOC-STRING is the base documentation for this class. A generic -function has no body, as its purpose is to decide which method body -is appropriate to use. Specific methods are defined with `cl-defmethod'. -With this implementation the ARGS are currently ignored. +function usually has no body, as its purpose is to decide which +method body is appropriate to use; ARGS are currently ignored if +there's no body. If BODY is present, it provides the default +implementation. +Specific implementation methods are defined with `cl-defmethod'. OPTIONS-AND-METHODS currently understands: - (:documentation DOCSTRING) - (declare DECLARATIONS) @@ -258,7 +260,9 @@ DEFAULT-BODY, if present, is used as the body of a default method. cl--generic-edebug-make-name in:method] lambda-doc def-body)]] - def-body))) + def-body)) + ;; Expand to defun and related forms on autoload definition + (autoload-macro expand)) (let* ((doc (if (stringp (car-safe options-and-methods)) (pop options-and-methods))) (declarations nil) diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index a076012cd30..08a6cbf209d 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -396,7 +396,9 @@ more details. [&optional ("interactive" interactive)] def-body)) (doc-string 3) - (indent 2)) + (indent 2) + ;; expand to function definition on autoload gen + (autoload-macro expand)) `(defun ,name ,@(cl--transform-lambda (cons args body) name))) ;;;###autoload @@ -414,7 +416,9 @@ and BODY is implicitly surrounded by (cl-block NAME ...). [&optional ("interactive" interactive)] def-body)) (doc-string 3) - (indent 2)) + (indent 2) + ;; expand (eventually) to function definition on autoload gen + (autoload-macro expand)) (require 'generator) `(iter-defun ,name ,@(cl--transform-lambda (cons args body) name))) @@ -473,7 +477,8 @@ more details. (declare (debug (&define name cl-macro-list cl-declarations-or-string def-body)) (doc-string 3) - (indent 2)) + (indent 2) + (autoload-macro expand)) ; expand to defmacro on autoload gen `(defmacro ,name ,@(cl--transform-lambda (cons args body) name))) (def-edebug-elem-spec 'cl-lambda-expr @@ -3087,7 +3092,9 @@ To see the documentation for a defined struct type, use sexp])] [&optional stringp] ;; All the above is for the following def-form. - &rest &or symbolp (symbolp &optional def-form &rest sexp)))) + &rest &or symbolp (symbolp &optional def-form &rest sexp))) + ;; expand to function definitions and related forms on autoload gen + (autoload-macro expand)) (let* ((name (if (consp struct) (car struct) struct)) (warning nil) (opts (cdr-safe struct)) diff --git a/lisp/emacs-lisp/crm.el b/lisp/emacs-lisp/crm.el index a75ccd46f50..425a606cb12 100644 --- a/lisp/emacs-lisp/crm.el +++ b/lisp/emacs-lisp/crm.el @@ -259,6 +259,7 @@ with empty strings removed." (list minibuffer-visible-completions-map map)) map)) + (buffer (current-buffer)) input) (minibuffer-with-setup-hook (lambda () @@ -282,6 +283,8 @@ with empty strings removed." ;; see completing_read in src/minibuf.c (setq-local minibuffer-completion-confirm (unless (eq require-match t) require-match)) + (setq-local minibuffer--require-match require-match) + (setq-local minibuffer--original-buffer buffer) (setq-local crm-completion-table table)) (setq input (read-from-minibuffer (format-spec diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 46c99052090..ca921308877 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -222,10 +222,12 @@ INIT-VALUE LIGHTER KEYMAP. (indent defun) (debug (&define name string-or-null-p [&optional [¬ keywordp] sexp - &optional [¬ keywordp] sexp - &optional [¬ keywordp] sexp] + &optional [¬ keywordp] sexp + &optional [¬ keywordp] sexp] [&rest [keywordp sexp]] - def-body))) + def-body)) + ;; expand to the command definition on autoload gen + (autoload-macro expand)) (let* ((last-message (make-symbol "last-message")) (mode-name (symbol-name mode)) @@ -488,7 +490,9 @@ after running the major mode's hook. However, MODE is not turned on if the hook has explicitly disabled it. \(fn GLOBAL-MODE MODE TURN-ON [KEY VALUE]... BODY...)" - (declare (doc-string 2) (indent defun)) + (declare (doc-string 2) (indent defun) + ;; expand to the minor-mode definition on autoload gen + (autoload-macro expand)) (let* ((global-mode-name (symbol-name global-mode)) (mode-name (symbol-name mode)) (pretty-name (easy-mmode-pretty-mode-name mode)) @@ -499,8 +503,8 @@ on if the hook has explicitly disabled it. (MODE-enable-in-buffer (intern (concat global-mode-name "-enable-in-buffer"))) (minor-MODE-hook (intern (concat mode-name "-hook"))) - (MODE-set-explicitly (intern (concat mode-name "-set-explicitly"))) - (MODE-major-mode (intern (concat (symbol-name mode) "-major-mode"))) + (MODE-set-explicitly (intern (concat mode-name "--set-explicitly"))) + (MODE-major-mode (intern (concat global-mode-name "--major-mode"))) (MODE-predicate (intern (concat (replace-regexp-in-string "-mode\\'" "" global-mode-name) "-modes"))) diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index e1051eb7d4e..7f7b2adde45 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -593,7 +593,7 @@ OBJECT can be an instance or a class." (defun find-class (symbol &optional errorp) "Return the class that SYMBOL represents. If there is no class, nil is returned if ERRORP is nil. -If ERRORP is non-nil, `wrong-argument-type' is signaled." +If ERRORP is non-nil, `wrong-type-argument' is signaled." (let ((class (cl--find-class symbol))) (cond ((eieio--class-p class) class) diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index cf21af8f101..1ebddf98fe4 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -813,7 +813,7 @@ This mainly sets up debugger-related bindings." (letrec ((debugfun (lambda (err) (ert--run-test-debugger test-execution-info err debugfun)))) - (handler-bind (((error quit) debugfun)) + (handler-bind ((t debugfun)) (funcall (ert-test-body (ert--test-execution-info-test test-execution-info)))))))) (ert-pass)) diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el index 344e11e245e..c01e559fd5c 100644 --- a/lisp/emacs-lisp/generator.el +++ b/lisp/emacs-lisp/generator.el @@ -675,7 +675,8 @@ encapsulates the state of a computation that produces a sequence of values. Callers can retrieve each value using `iter-next'." (declare (indent defun) (debug (&define name lambda-list lambda-doc &rest sexp)) - (doc-string 3)) + (doc-string 3) + (autoload-macro expand)) ; expand to the defun on autoload gen (cl-assert lexical-binding) (let* ((parsed-body (macroexp-parse-body body)) (declarations (car parsed-body)) diff --git a/lisp/emacs-lisp/inline.el b/lisp/emacs-lisp/inline.el index c015e2b57d0..027c24c465b 100644 --- a/lisp/emacs-lisp/inline.el +++ b/lisp/emacs-lisp/inline.el @@ -135,7 +135,8 @@ After VARS is handled, BODY is evaluated in the new environment." This is like `defmacro', but has several advantages. See Info node `(elisp)Defining Functions' for more details." ;; FIXME: How can this work with CL arglists? - (declare (indent defun) (debug defun) (doc-string 3)) + (declare (indent defun) (debug defun) (doc-string 3) + (autoload-macro expand)) ; expand to the defun on autoload gen (let ((doc (if (stringp (car-safe body)) (list (pop body)))) (declares (if (eq (car-safe (car-safe body)) 'declare) (pop body))) (cm-name (intern (format "%s--inliner" name))) diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index a8500759cf8..9e91a11204d 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -143,12 +143,37 @@ scanning for autoloads and will be in the `load-path'." 3) form)) +;; The following macros are known to define functions, and are treated +;; specially when encountered during autoload generation, translating +;; calls to them directly into appropriate (autoload function ...) +;; forms. +;; +;; An alternative to appearing on this list is for a macro to declare +;; (autoload-macro expand), so calls to it get expanded into more basic +;; forms during generation. Macros may be removed from this list once +;; they request such expansion and produce suitable output (e.g. by +;; employing :autoload-end to omit unneeded forms). +(defconst loaddefs--defining-macros + '( define-skeleton define-derived-mode define-compilation-mode + define-generic-mode define-globalized-minor-mode define-minor-mode + cl-defun defun* cl-defmacro defmacro* define-overloadable-function + transient-define-prefix transient-define-suffix transient-define-infix + transient-define-argument transient-define-group + ;; Obsolete; keep until the alias is removed. + easy-mmode-define-global-mode + easy-mmode-define-minor-mode + define-global-minor-mode)) + +(defvar loaddefs--load-error-files nil) (defun loaddefs-generate--make-autoload (form file &optional expansion) "Turn FORM into an autoload or defvar for source file FILE. Returns nil if FORM is not a special autoload form (i.e. a function definition or macro definition or a defcustom). If EXPANSION is non-nil, we're processing the macro expansion of an -expression, in which case we want to handle forms differently." +expression, in which case we want to handle forms differently. + +Note that macros can request expansion by including `(autoload-macro +expand)' among their `declare' forms." (let ((car (car-safe form)) expand) (cond ((and expansion (eq car 'defalias)) @@ -192,42 +217,58 @@ expression, in which case we want to handle forms differently." (setq form (copy-sequence form)) (setcdr (memq :autoload-end form) nil)) (let ((exps (delq nil (mapcar (lambda (form) - (loaddefs-generate--make-autoload - form file expansion)) + (unless (eq form :autoload-end) + (loaddefs-generate--make-autoload + form file expansion))) (cdr form))))) (when exps (cons 'progn exps))))) - ;; For complex cases, try again on the macro-expansion. - ((and (memq car '( define-globalized-minor-mode defun defmacro - define-minor-mode define-inline - cl-defun cl-defmacro cl-defgeneric - cl-defstruct pcase-defmacro iter-defun cl-iter-defun - ;; Obsolete; keep until the alias is removed. - easy-mmode-define-global-mode - easy-mmode-define-minor-mode - define-global-minor-mode)) - (macrop car) - (setq expand (let ((load-true-file-name file) - (load-file-name file)) - (macroexpand form))) - (memq (car expand) '(progn prog1 defalias))) + ;; For macros which request it, try again on their expansion. + ((progn + ;; If the car is an unknown symbol, we load the file first to + ;; give packages a chance to define their macros. + (unless (or (not (symbolp car)) (fboundp car) + ;; Special cases handled below + (memq car loaddefs--defining-macros) + (memq car '(defclass defcustom deftheme defgroup nil)) + (assoc file load-history) + (member file loaddefs--load-error-files)) + (let ((load-path (cons (file-name-directory file) load-path))) + (message "loaddefs-gen: loading file %s (for %s)" file car) + (condition-case e (load file) + (error + (push file loaddefs--load-error-files) ; do not attempt again + (warn "loaddefs-gen: load error\n\t%s" e))))) + (and (macrop car) + (eq 'expand (function-get car 'autoload-macro)) + (setq expand (let ((load-true-file-name file) + (load-file-name file)) + (macroexpand form))) + (or (and + ;; Previously, macros defined in this list would not + ;; see their expansions processed in place of + ;; themselves if such an expansion did not yield a + ;; `progn', `prog1' or `defalias' form. Not + ;; reproducing these conditions results in the + ;; omission of minor mode variables and suchlike in + ;; loaddefs.el when only the defuns in the + ;; macroexpansions are autoloaded. + (not (memq car '( define-globalized-minor-mode defun defmacro + define-minor-mode define-inline + cl-defun cl-defmacro cl-defgeneric + cl-defstruct pcase-defmacro iter-defun cl-iter-defun + ;; Obsolete; keep until the alias is removed. + easy-mmode-define-global-mode + easy-mmode-define-minor-mode + define-global-minor-mode))) + (not (eq car (car expand)))) + (memq (car expand) '(progn prog1 defalias))))) ;; Recurse on the expansion. (loaddefs-generate--make-autoload expand file 'expansion)) - ;; For special function-like operators, use the `autoload' function. - ((memq car '( define-skeleton define-derived-mode - define-compilation-mode define-generic-mode - define-globalized-minor-mode - define-minor-mode - cl-defun defun* cl-defmacro defmacro* - define-overloadable-function - transient-define-prefix transient-define-suffix - transient-define-infix transient-define-argument - transient-define-group - ;; Obsolete; keep until the alias is removed. - easy-mmode-define-global-mode - easy-mmode-define-minor-mode - define-global-minor-mode)) + ;; For known special macros which define functions, use `autoload' + ;; directly. + ((memq car loaddefs--defining-macros) (let* ((macrop (memq car '(defmacro cl-defmacro defmacro*))) (name (nth 1 form)) (args (pcase car @@ -268,8 +309,8 @@ expression, in which case we want to handle forms differently." t) (and (eq (car-safe (car body)) 'interactive) ;; List of modes or just t. - (or (if (nthcdr 1 (car body)) - (list 'quote (nthcdr 1 (car body))) + (or (if (nthcdr 2 (car body)) + (list 'quote (nthcdr 2 (car body))) t)))) ,(if macrop ''macro nil))))) diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el index deeeec132cf..1e88630959d 100644 --- a/lisp/emacs-lisp/map.el +++ b/lisp/emacs-lisp/map.el @@ -350,7 +350,8 @@ The default implementation delegates to `map-apply'." (cl-defgeneric map-filter (pred map) "Return an alist of key/val pairs for which (PRED key val) is non-nil in MAP. -The default implementation delegates to `map-apply'." +The default implementation delegates to `map-apply'. +This does not modify MAP." (delq nil (map-apply (lambda (key val) (and (funcall pred key val) (cons key val))) @@ -358,7 +359,8 @@ The default implementation delegates to `map-apply'." (cl-defgeneric map-remove (pred map) "Return an alist of the key/val pairs for which (PRED key val) is nil in MAP. -The default implementation delegates to `map-filter'." +The default implementation delegates to `map-filter'. +This does not modify MAP." (map-filter (lambda (key val) (not (funcall pred key val))) map)) @@ -457,7 +459,8 @@ MAP may be of a type other than TYPE." (defun map-merge (type &rest maps) "Merge into a map of TYPE all the key/value pairs in MAPS. -See `map-into' for all supported values of TYPE." +See `map-into' for all supported values of TYPE. +This does not modify any of the MAPS." (apply #'map--merge (lambda (result key value) (setf (map-elt result key) value) @@ -469,7 +472,8 @@ See `map-into' for all supported values of TYPE." When two maps contain the same key, call FUNCTION on the two values and use the value FUNCTION returns. Each of MAPS can be an alist, plist, hash-table, or array. -See `map-into' for all supported values of TYPE." +See `map-into' for all supported values of TYPE. +This does not modify any of the MAPS." (let ((not-found (list nil))) (apply #'map--merge (lambda (result key value) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index fe6bebc67ff..ba9999c20e6 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -995,18 +995,22 @@ Newer versions are always activated, regardless of FORCE." This uses `tar-untar-buffer' from Tar mode. All files should untar into a directory named DIR; otherwise, signal an error." (tar-mode) - ;; Make sure everything extracts into DIR. - (let ((regexp (concat "\\`" (regexp-quote (expand-file-name dir)) "/")) - (case-fold-search (file-name-case-insensitive-p dir))) - (dolist (tar-data tar-parse-info) - (let ((name (expand-file-name (tar-header-name tar-data)))) - (or (string-match regexp name) - ;; Tarballs created by some utilities don't list - ;; directories with a trailing slash (Bug#13136). - (and (string-equal (expand-file-name dir) name) - (eq (tar-header-link-type tar-data) 5)) - (error "Package does not untar cleanly into directory %s/" dir))))) - (tar-untar-buffer)) + (unwind-protect + (progn + ;; Make sure everything extracts into DIR. + (let ((regexp (concat "\\`" (regexp-quote (expand-file-name dir)) "/")) + (case-fold-search (file-name-case-insensitive-p dir))) + (dolist (tar-data tar-parse-info) + (let ((name (expand-file-name (tar-header-name tar-data)))) + (or (string-match regexp name) + ;; Tarballs created by some utilities don't list + ;; directories with a trailing slash (Bug#13136). + (and (string-equal (expand-file-name dir) name) + (eq (tar-header-link-type tar-data) 5)) + (error "Package does not untar cleanly into directory %s/" + dir))))) + (tar-untar-buffer)) + (fundamental-mode))) ; free auxiliary tar-mode data (defun package--alist-to-plist-args (alist) (mapcar #'macroexp-quote @@ -2455,7 +2459,9 @@ directory." (set-visited-file-name file) (set-buffer-modified-p nil) (when (string-match "\\.tar\\'" file) (tar-mode))) - (package-install-from-buffer))) + (unwind-protect + (package-install-from-buffer) + (fundamental-mode)))) ; free auxiliary data ;;;###autoload (defun package-install-selected-packages (&optional noconfirm) diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index c68b8961ee3..cd6b5e42771 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -544,7 +544,9 @@ to this macro. By convention, DOC should use \"EXPVAL\" to stand for the result of evaluating EXP (first arg to `pcase'). \n(fn NAME ARGS [DOC] &rest BODY...)" - (declare (indent 2) (debug defun) (doc-string 3)) + (declare (indent 2) (debug defun) (doc-string 3) + ;; Expand to defun and related forms on autoload gen + (autoload-macro expand)) ;; Add the function via `fsym', so that an autoload cookie placed ;; on a pcase-defmacro will cause the macro to be loaded on demand. (let ((fsym (intern (format "%s--pcase-macroexpander" name))) diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index a7954e7614c..d8ffdb1fa20 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -274,7 +274,8 @@ Value is a sequence of the same type as SEQUENCE." (cl-defgeneric seq-sort (pred sequence) "Sort SEQUENCE using PRED as the sorting comparison function. -The result is a sequence of the same type as SEQUENCE." +The result is a sequence of the same type as SEQUENCE. The sort +operates on a copy of SEQUENCE and does not modify SEQUENCE." (let ((result (seq-sort pred (append sequence nil)))) (seq-into result (type-of sequence)))) @@ -285,7 +286,8 @@ The result is a sequence of the same type as SEQUENCE." (defun seq-sort-by (function pred sequence) "Sort SEQUENCE transformed by FUNCTION using PRED as the comparison function. Elements of SEQUENCE are transformed by FUNCTION before being -sorted. FUNCTION must be a function of one argument." +sorted. FUNCTION must be a function of one argument. The sort +operates on a copy of SEQUENCE and does not modify SEQUENCE." (seq-sort (lambda (a b) (funcall pred (funcall function a) @@ -293,7 +295,8 @@ sorted. FUNCTION must be a function of one argument." sequence)) (cl-defgeneric seq-reverse (sequence) - "Return a sequence with elements of SEQUENCE in reverse order." + "Return a sequence with elements of SEQUENCE in reverse order. +This does not modify SEQUENCE." (let ((result '())) (seq-map (lambda (elt) (push elt result)) @@ -307,6 +310,7 @@ sorted. FUNCTION must be a function of one argument." (cl-defgeneric seq-concatenate (type &rest sequences) "Concatenate SEQUENCES into a single sequence of type TYPE. TYPE must be one of following symbols: `vector', `string' or `list'. +This does not modify any of the SEQUENCES. \n(fn TYPE SEQUENCE...)" (setq sequences (mapcar #'seq-into-sequence sequences)) @@ -321,7 +325,9 @@ TYPE must be one of following symbols: `vector', `string' or `list'. The default implementation is to signal an error if SEQUENCE is not a sequence, specific functions should be implemented for new types -of sequence." +of sequence. + +This does not modify SEQUENCE." (unless (sequencep sequence) (error "Cannot convert %S into a sequence" sequence)) sequence) @@ -329,7 +335,7 @@ of sequence." (cl-defgeneric seq-into (sequence type) "Concatenate the elements of SEQUENCE into a sequence of type TYPE. TYPE can be one of the following symbols: `vector', `string' or -`list'." +`list'. This does not modify SEQUENCE." (pcase type (`vector (seq--into-vector sequence)) (`string (seq--into-string sequence)) @@ -338,7 +344,8 @@ TYPE can be one of the following symbols: `vector', `string' or ;;;###autoload (cl-defgeneric seq-filter (pred sequence) - "Return a list of all the elements in SEQUENCE for which PRED returns non-nil." + "Return a list of all the elements in SEQUENCE for which PRED returns non-nil. +This does not modify SEQUENCE." (let ((exclude (make-symbol "exclude"))) (delq exclude (seq-map (lambda (elt) (if (funcall pred elt) @@ -348,7 +355,8 @@ TYPE can be one of the following symbols: `vector', `string' or ;;;###autoload (cl-defgeneric seq-remove (pred sequence) - "Return a list of all the elements in SEQUENCE for which PRED returns nil." + "Return a list of all the elements in SEQUENCE for which PRED returns nil. +This does not modify SEQUENCE." (seq-filter (lambda (elt) (not (funcall pred elt))) sequence)) @@ -359,7 +367,8 @@ TYPE can be one of the following symbols: `vector', `string' or N is the (zero-based) index of the element that should not be in the result. -The result is a sequence of the same type as SEQUENCE." +The result is a sequence of the same type as SEQUENCE. +This does not modify SEQUENCE." (seq-concatenate (if (listp sequence) 'list (type-of sequence)) (seq-subseq sequence 0 n) @@ -376,7 +385,9 @@ third element of SEQUENCE, etc. FUNCTION will be called with INITIAL-VALUE (and then the accumulated value) as the first argument, and the elements from SEQUENCE as the second argument. -If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called." +If SEQUENCE is empty, return INITIAL-VALUE and FUNCTION is not called. + +This does not modify SEQUENCE." (if (seq-empty-p sequence) initial-value (let ((acc initial-value)) @@ -411,7 +422,9 @@ If no such element is found, return DEFAULT. Note that `seq-find' has an ambiguity if the found element is identical to DEFAULT, as in that case it is impossible to know -whether an element was found or not." +whether an element was found or not. + +This does not modify SEQUENCE." (catch 'seq--break (seq-doseq (elt sequence) (when (funcall pred elt) @@ -485,7 +498,8 @@ The result is a list of (zero-based) indices." ;;;###autoload (cl-defgeneric seq-uniq (sequence &optional testfn) "Return a list of the elements of SEQUENCE with duplicates removed. -TESTFN is used to compare elements, and defaults to `equal'." +TESTFN is used to compare elements, and defaults to `equal'. +This does not modify SEQUENCE." (let ((result '())) (seq-doseq (elt sequence) (unless (seq-contains-p result elt testfn) @@ -521,14 +535,16 @@ TESTFN is used to compare elements, and defaults to `equal'." (cl-defgeneric seq-mapcat (function sequence &optional type) "Concatenate the results of applying FUNCTION to each element of SEQUENCE. -The result is a sequence of type TYPE; TYPE defaults to `list'." +The result is a sequence of type TYPE; TYPE defaults to `list'. +This does not modify SEQUENCE." (apply #'seq-concatenate (or type 'list) (seq-map function sequence))) (cl-defgeneric seq-partition (sequence n) "Return list of elements of SEQUENCE grouped into sub-sequences of length N. The last sequence may contain less than N elements. If N is a -negative integer or 0, the function returns nil." +negative integer or 0, the function returns nil. +This does not modify SEQUENCE." (unless (< n 1) (let ((result '())) (while (not (seq-empty-p sequence)) @@ -540,7 +556,8 @@ negative integer or 0, the function returns nil." (cl-defgeneric seq-union (sequence1 sequence2 &optional testfn) "Return a list of all the elements that appear in either SEQUENCE1 or SEQUENCE2. \"Equality\" of elements is defined by the function TESTFN, which -defaults to `equal'." +defaults to `equal'. +This does not modify SEQUENCE1 or SEQUENCE2." (let* ((accum (lambda (acc elt) (if (seq-contains-p acc elt testfn) acc @@ -553,7 +570,8 @@ defaults to `equal'." (cl-defgeneric seq-intersection (sequence1 sequence2 &optional testfn) "Return a list of all the elements that appear in both SEQUENCE1 and SEQUENCE2. \"Equality\" of elements is defined by the function TESTFN, which -defaults to `equal'." +defaults to `equal'. +This does not modify SEQUENCE1 or SEQUENCE2." (seq-reduce (lambda (acc elt) (if (seq-contains-p sequence2 elt testfn) (cons elt acc) @@ -564,7 +582,8 @@ defaults to `equal'." (cl-defgeneric seq-difference (sequence1 sequence2 &optional testfn) "Return list of all the elements that appear in SEQUENCE1 but not in SEQUENCE2. \"Equality\" of elements is defined by the function TESTFN, which -defaults to `equal'." +defaults to `equal'. +This does not modify SEQUENCE1 or SEQUENCE2." (seq-reduce (lambda (acc elt) (if (seq-contains-p sequence2 elt testfn) acc @@ -576,7 +595,7 @@ defaults to `equal'." (cl-defgeneric seq-group-by (function sequence) "Apply FUNCTION to each element of SEQUENCE. Separate the elements of SEQUENCE into an alist using the results as -keys. Keys are compared using `equal'." +keys. Keys are compared using `equal'. This does not modify SEQUENCE." (seq-reduce (lambda (acc elt) (let* ((key (funcall function elt)) @@ -692,7 +711,7 @@ Signal an error if SEQUENCE is empty." (defun seq-split (sequence length) "Split SEQUENCE into a list of sub-sequences of at most LENGTH elements. All the sub-sequences will be LENGTH long, except the last one, -which may be shorter." +which may be shorter. This does not modify SEQUENCE." (when (< length 1) (error "Sub-sequence length must be larger than zero")) (let ((result nil) @@ -705,7 +724,8 @@ which may be shorter." (nreverse result))) (defun seq-keep (function sequence) - "Apply FUNCTION to SEQUENCE and return the list of all the non-nil results." + "Apply FUNCTION to SEQUENCE and return the list of all the non-nil results. +This does not modify SEQUENCE." (delq nil (seq-map function sequence))) (provide 'seq) diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 2e826399261..754b2016d9e 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -1131,6 +1131,9 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'), :eval (seq-map-indexed (lambda (a i) (cons i a)) '(a b c))) (seq-mapcat :eval (seq-mapcat #'upcase '("a" "b" "c") 'string)) + (seq-doseq + :no-eval (seq-doseq (a '("foo" "bar")) (insert a)) + :eg-result ("foo" "bar")) (seq-do :no-eval (seq-do (lambda (a) (insert a)) '("foo" "bar")) :eg-result ("foo" "bar")) diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index 40b2fb0886b..f4220501b35 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -142,13 +142,14 @@ arguments and must return a list of the above form.") (defvar-local tabulated-list-groups nil "Groups displayed in the current Tabulated List buffer. This should be either a function, or a list. -If a list, each element has the form (GROUP-NAME ENTRIES), +If a list, each element has the form (GROUP-NAME ENTRY1 ENTRY2 ...), where: - GROUP-NAME is a group name as a string, which is displayed at the top line of each group. - - ENTRIES is a list described in `tabulated-list-entries'. + - ENTRY1, ENTRY2 and so on each have the same format as an element + of `tabulated-list-entries'. If `tabulated-list-groups' is a function, it is called with no arguments and must return a list of the above form.") diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index be191d63b9e..fb5c2b1829f 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -356,7 +356,7 @@ This function is called, by name, directly by the C code." (defun run-at-time (time repeat function &rest args) "Perform an action at time TIME. Repeat the action every REPEAT seconds, if REPEAT is non-nil. -REPEAT may be an integer or floating point number. +REPEAT may be a non-negative integer or floating point number. TIME should be one of: - a string giving today's time like \"11:23pm\" @@ -386,10 +386,10 @@ This function returns a timer object which you can use in `cancel-timer'." (interactive "sRun at time: \nNRepeat interval: \naFunction: ") - (when (and repeat - (numberp repeat) - (< repeat 0)) - (error "Invalid repetition interval")) + (unless (or (null repeat) + (and (numberp repeat) + (>= repeat 0))) + (error "Invalid repetition interval: %s" repeat)) (let ((timer (timer-create))) ;; Special case: nil means "now" and is useful when repeating. @@ -433,6 +433,7 @@ This function returns a timer object which you can use in "Perform an action after a delay of SECS seconds. Repeat the action every REPEAT seconds, if REPEAT is non-nil. SECS and REPEAT may be integers or floating point numbers. +REPEAT, if non-nil, must be a non-negative number. The action is to call FUNCTION with arguments ARGS. This function returns a timer object which you can use in `cancel-timer'." diff --git a/lisp/external-completion.el b/lisp/external-completion.el index a1aa7ec9cb6..5fd29f801fe 100644 --- a/lisp/external-completion.el +++ b/lisp/external-completion.el @@ -5,6 +5,7 @@ ;; Version: 0.1 ;; Author: Stefan Monnier ;; Maintainer: João Távora +;; Package-Requires: ((emacs "26.1")) ;; Keywords: ;; This is a GNU ELPA :core package. Avoid functionality that is not @@ -117,10 +118,11 @@ EXPANDED-PATTERN." completion-category-defaults))) (let ((cache (make-hash-table :test #'equal))) (cl-flet ((lookup-internal (string point) - (let ((key (cons string point))) - (if (hash-table-contains-p key cache) - (gethash key cache) - (puthash key (funcall lookup string point) cache))))) + (let* ((key (cons string point)) + (probe (gethash key cache 'external--notfound))) + (if (eq probe 'external--notfound) + (puthash key (funcall lookup string point) cache) + probe)))) (lambda (string pred action) (pcase action (`metadata diff --git a/lisp/filenotify.el b/lisp/filenotify.el index 311da73a8ef..9e35f5413fb 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -500,7 +500,8 @@ DESCRIPTOR should be an object returned by `file-notify-add-watch'." (maphash (lambda (key _value) (file-notify-rm-watch key)) - file-notify-descriptors)) + file-notify-descriptors) + (setq file-notify-descriptors (clrhash file-notify-descriptors))) (defun file-notify-valid-p (descriptor) "Check a watch specified by its DESCRIPTOR. diff --git a/lisp/files.el b/lisp/files.el index 23a8d83ab28..3e85244e4e9 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2532,7 +2532,9 @@ be visible in the echo area." If a buffer exists visiting FILENAME, return that one, but verify that the file has not changed since visited or saved. The buffer is not selected, just returned to the caller. -Optional second arg NOWARN non-nil means suppress any warning messages. +Optional second arg NOWARN non-nil means suppress any warning messages, +and also don't verify that the file has not been changed since +last visited or saved. Optional third arg RAWFILE non-nil means the file is read literally. Optional fourth arg WILDCARDS non-nil means do wildcard processing and visit all the matching files. When wildcards are actually @@ -2885,7 +2887,7 @@ error in reading the file. WARN non-nil means warn if there exists an auto-save file more recent than the visited file. NOAUTO means don't mess with auto-save mode. Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER is ignored -\(see `revert-buffer-in-progress-p' for similar functionality). +\(see `revert-buffer-in-progress' for similar functionality). Fifth arg NOMODES non-nil means don't alter the file's modes. Finishes by calling the functions in `find-file-hook' unless NOMODES is non-nil." @@ -6243,7 +6245,13 @@ Before and after saving the buffer, this function runs ;; for saving the buffer. (setq tempname (make-temp-file - (expand-file-name "tmp" dir))) + ;; The MSDOS 8+3 restricted namespace cannot be + ;; relied upon to produce a different file name + ;; if we append ".tmp". + (if (and (eq system-type 'ms-dos) + (not (msdos-long-file-names))) + (expand-file-name "tmp" dir) + (concat buffer-file-name ".tmp")))) ;; Pass in nil&nil rather than point-min&max ;; cause we're saving the whole buffer. ;; write-region-annotate-functions may use it. @@ -7105,9 +7113,10 @@ hook functions. The function `revert-buffer--default' runs this. A customized `revert-buffer-function' need not run this hook.") -(defvar revert-buffer-in-progress-p nil +(define-obsolete-variable-alias + 'revert-buffer-in-progress-p 'revert-buffer-in-progress "31.1") +(defvar revert-buffer-in-progress nil "Non-nil if a `revert-buffer' operation is in progress, nil otherwise.") - (defvar revert-buffer-internal-hook) ;; `revert-buffer-function' was defined long ago to be a function of only @@ -7166,7 +7175,7 @@ revert buffers without querying for confirmation.) Optional third argument PRESERVE-MODES non-nil means don't alter the files modes. Normally we reinitialize them using `normal-mode'. -This function binds `revert-buffer-in-progress-p' non-nil while it operates. +This function binds `revert-buffer-in-progress' non-nil while it operates. This function calls the function that `revert-buffer-function' specifies to do the work, with arguments IGNORE-AUTO and NOCONFIRM. @@ -7187,7 +7196,7 @@ preserve markers and overlays, at the price of being slower." ;; reversal of the argument sense. So I'm just changing the user ;; interface, but leaving the programmatic interface the same. (interactive (list (not current-prefix-arg))) - (let ((revert-buffer-in-progress-p t) + (let ((revert-buffer-in-progress t) (revert-buffer-preserve-modes preserve-modes) restore-functions) (run-hook-wrapped 'revert-buffer-restore-functions diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index 30f0a4b6a62..566c3e3fba4 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -51,7 +51,7 @@ (defvoo nnimap-server-port nil "The IMAP port used. -If `nnimap-stream' is `ssl', this will default to `imaps'. If not, +If `nnimap-stream' is `tls', this will default to `imaps'. If not, it will default to `imap'.") (defvoo nnimap-use-namespaces nil @@ -63,10 +63,10 @@ names of your nnimap groups.") (defvoo nnimap-stream 'undecided "How nnimap talks to the IMAP server. -The value should be either `undecided', `ssl' or `tls', +The value should be either `undecided', `tls' or `ssl' (deprecated), `network', `starttls', `plain', or `shell'. -If the value is `undecided', nnimap tries `ssl' first, then falls +If the value is `undecided', nnimap tries `tls' first, then falls back on `network'.") (defvoo nnimap-shell-program (if (boundp 'imap-shell-program) diff --git a/lisp/gnus/nnrss.el b/lisp/gnus/nnrss.el index e166fa8424f..60282167409 100644 --- a/lisp/gnus/nnrss.el +++ b/lisp/gnus/nnrss.el @@ -496,7 +496,8 @@ which RSS 2.0 allows." (defun nnrss-read-server-data (server) (setq nnrss-server-data nil) (let ((file (nnrss-make-filename "nnrss" server)) - (file-name-coding-system nnmail-pathname-coding-system)) + (file-name-coding-system nnmail-pathname-coding-system) + (warning-inhibit-types '((files missing-lexbind-cookie)))) (when (file-exists-p file) (load file nil t t)))) @@ -505,7 +506,7 @@ which RSS 2.0 allows." (let ((coding-system-for-write nnrss-file-coding-system) (file-name-coding-system nnmail-pathname-coding-system)) (with-temp-file (nnrss-make-filename "nnrss" server) - (insert (format ";; -*- coding: %s; -*-\n" + (insert (format ";; -*- coding: %s; lexical-binding:t -*-\n" nnrss-file-coding-system)) (gnus-prin1 `(setq nnrss-group-alist ',nnrss-group-alist)) (insert "\n") @@ -520,7 +521,8 @@ which RSS 2.0 allows." (setq nnrss-group-max (or (cadr pair) 0)) (setq nnrss-group-min (+ nnrss-group-max 1))) (let ((file (nnrss-make-filename group server)) - (file-name-coding-system nnmail-pathname-coding-system)) + (file-name-coding-system nnmail-pathname-coding-system) + (warning-inhibit-types '((files missing-lexbind-cookie)))) (when (file-exists-p file) (load file nil t t) (dolist (e nnrss-group-data) @@ -535,7 +537,7 @@ which RSS 2.0 allows." (let ((coding-system-for-write nnrss-file-coding-system) (file-name-coding-system nnmail-pathname-coding-system)) (with-temp-file (nnrss-make-filename group server) - (insert (format ";; -*- coding: %s; -*-\n" + (insert (format ";; -*- coding: %s; lexical-binding:t -*-\n" nnrss-file-coding-system)) (gnus-prin1 `(setq nnrss-group-data ',nnrss-group-data))))) diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index cc68291868c..2ebbe6ee5be 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el @@ -82,8 +82,9 @@ as its single argument, or one of the following special values: upgrading to a TLS connection via STARTTLS if possible. - `nntp-open-plain-stream' specifies an unencrypted network connection (no STARTTLS upgrade is attempted). -- `nntp-open-ssl-stream' or `nntp-open-tls-stream' specify a TLS - network connection. +- `nntp-open-tls-stream' specifies a TLS network connection (the + equivalent value `nntp-open-ssl-stream' is accepted for backwards + compatibility). Apart from the above special values, valid functions are as follows; please refer to their respective doc string for more @@ -100,7 +101,7 @@ For indirect connections: "Non-nil means the nntp server never echoes commands. It is reported that some nntps server doesn't echo commands. So, you may want to set this to non-nil in the method for such a server setting -`nntp-open-connection-function' to `nntp-open-ssl-stream' for example. +`nntp-open-connection-function' to `nntp-open-tls-stream' for example. Note that the `nntp-open-connection-functions-never-echo-commands' variable overrides the nil value of this variable.") diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 9cd30107002..e9601d52e33 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -2253,13 +2253,14 @@ is enabled in the Help buffer." (describe-function major)))) (insert " mode") (when-let* ((file-name (find-lisp-object-file-name major nil))) - (insert (format " defined in %s:\n\n" + (insert (format " defined in %s" (buttonize (help-fns-short-filename file-name) (lambda (_) (help-function-def--button-function major file-name)))))) - (insert (help-split-fundoc (documentation major) nil 'doc) + (insert ":\n\n" + (help-split-fundoc (documentation major) nil 'doc) (with-current-buffer buffer (help-fns--list-local-commands))) (ensure-empty-lines 1) diff --git a/lisp/help.el b/lisp/help.el index 8b29a10e0cf..e6c5ea54812 100644 --- a/lisp/help.el +++ b/lisp/help.el @@ -2285,53 +2285,54 @@ ARGLIST can also be t or a string of the form \"(FUN ARG1 ARG2 ...)\"." "Return a formal argument list for the function DEF. If PRESERVE-NAMES is non-nil, return a formal arglist that uses the same names as used in the original source code, when possible." - ;; Handle symbols aliased to other symbols. - (if (and (symbolp def) (fboundp def)) (setq def (indirect-function def))) - ;; Advice wrappers have "catch all" args, so fetch the actual underlying - ;; function to find the real arguments. - (setq def (advice--cd*r def)) - ;; If definition is a macro, find the function inside it. - (if (eq (car-safe def) 'macro) (setq def (cdr def))) - (cond - ((and (closurep def) (listp (aref def 0))) (aref def 0)) - ((eq (car-safe def) 'lambda) (nth 1 def)) - ((and (featurep 'native-compile) - (subrp def) - (listp (subr-native-lambda-list def))) - (subr-native-lambda-list def)) - ((or (and (byte-code-function-p def) (integerp (aref def 0))) - (subrp def) (module-function-p def)) - (or (when preserve-names - (let* ((doc (condition-case nil (documentation def 'raw) (error nil))) - (docargs (if doc (car (help-split-fundoc doc nil)))) - (arglist (if docargs - (cdar (read-from-string (downcase docargs))))) - (valid t)) - ;; Check validity. - (dolist (arg arglist) - (unless (and (symbolp arg) - (let ((name (symbol-name arg))) - (if (and (> (length name) 0) (eq (aref name 0) ?&)) - (memq arg '(&rest &optional)) - (not (string-search "." name))))) - (setq valid nil))) - (when valid arglist))) - (let* ((arity (func-arity def)) - (max (cdr arity)) - (min (car arity)) - (arglist ())) - (dotimes (i min) - (push (intern (concat "arg" (number-to-string (1+ i)))) arglist)) - (when (and (integerp max) (> max min)) - (push '&optional arglist) - (dotimes (i (- max min)) - (push (intern (concat "arg" (number-to-string (+ 1 i min)))) - arglist))) - (unless (integerp max) (push '&rest arglist) (push 'rest arglist)) - (nreverse arglist)))) - ((and (autoloadp def) (not (eq (nth 4 def) 'keymap))) - "[Arg list not available until function definition is loaded.]") - (t t))) + (let ((orig-def def) + ;; Advice wrappers have "catch all" args, so fetch the actual underlying + ;; function to find the real arguments. + (def (advice--cd*r + (indirect-function def)))) ;; Follow aliases to other symbols. + ;; If definition is a macro, find the function inside it. + (if (eq (car-safe def) 'macro) (setq def (cdr def))) + (cond + ((and (closurep def) (listp (aref def 0))) (aref def 0)) + ((eq (car-safe def) 'lambda) (nth 1 def)) + ((and (featurep 'native-compile) + (subrp def) + (listp (subr-native-lambda-list def))) + (subr-native-lambda-list def)) + ((or (and (byte-code-function-p def) (integerp (aref def 0))) + (subrp def) (module-function-p def)) + (or (when preserve-names + (let* ((doc (ignore-errors (documentation orig-def 'raw))) + (docargs (if doc (car (help-split-fundoc doc nil)))) + (arglist (if docargs + (cdar (read-from-string (downcase docargs))))) + (valid t)) + ;; Check validity. + (dolist (arg arglist) + (unless (and (symbolp arg) + (let ((name (symbol-name arg))) + (if (and (> (length name) 0) + (eq (aref name 0) ?&)) + (memq arg '(&rest &optional)) + (not (string-search "." name))))) + (setq valid nil))) + (when valid arglist))) + (let* ((arity (func-arity def)) + (max (cdr arity)) + (min (car arity)) + (arglist ())) + (dotimes (i min) + (push (intern (concat "arg" (number-to-string (1+ i)))) arglist)) + (when (and (integerp max) (> max min)) + (push '&optional arglist) + (dotimes (i (- max min)) + (push (intern (concat "arg" (number-to-string (+ 1 i min)))) + arglist))) + (unless (integerp max) (push '&rest arglist) (push 'rest arglist)) + (nreverse arglist)))) + ((and (autoloadp def) (not (eq (nth 4 def) 'keymap))) + "[Arg list not available until function definition is loaded.]") + (t t)))) (defun help--make-usage (function arglist) (cons (if (symbolp function) function 'anonymous) diff --git a/lisp/hippie-exp.el b/lisp/hippie-exp.el index 3b89521e0fd..a7bb6ef92e9 100644 --- a/lisp/hippie-exp.el +++ b/lisp/hippie-exp.el @@ -334,11 +334,12 @@ undoes the expansion." (defun he-capitalize-first (str) (save-match-data - (if (string-match "\\Sw*\\(\\sw\\).*" str) - (let ((res (downcase str)) - (no (match-beginning 1))) - (aset res no (upcase (aref str no))) - res) + (if (string-match "\\Sw*\\(\\sw\\)" str) + (let ((b (match-beginning 1)) + (e (match-end 1))) + (concat (substring str 0 b) + (upcase (substring str b e)) + (downcase (substring str e)))) str))) (defun he-ordinary-case-p (str) diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 95deb2db478..ae7e8dd4117 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -2136,7 +2136,8 @@ the value of point at the beginning of the line for that buffer." `(ibuffer-title t font-lock-face ,ibuffer-title-face))) ;; Now, insert the summary columns. (goto-char (point-max)) - (if (get-text-property (1- (point-max)) 'ibuffer-summary) + (if (and (> (point-max) (point-min)) + (get-text-property (1- (point-max)) 'ibuffer-summary)) (delete-region (previous-single-property-change (point-max) 'ibuffer-summary) (point-max))) diff --git a/lisp/image.el b/lisp/image.el index b95dd230914..51a7a687961 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -419,10 +419,10 @@ be determined." ;;;###autoload (defun image-supported-file-p (file) - "Say whether Emacs has native support for displaying TYPE. -The value is a symbol specifying the image type, or nil if type -cannot be determined (or if Emacs doesn't have built-in support -for the image type)." + "Return non-nil if Emacs can display the specified image FILE. +The returned value is a symbol specifying the image type of FILE, +or nil if Emacs cannot display that image type or if the type +cannot be determined." (let ((case-fold-search t) type) (catch 'found diff --git a/lisp/indent-aux.el b/lisp/indent-aux.el index eeb8f1ee6bb..47d21f86649 100644 --- a/lisp/indent-aux.el +++ b/lisp/indent-aux.el @@ -50,13 +50,16 @@ is yanked." (delete-and-extract-region beg end) (buffer-substring beg end)))) (with-temp-buffer - ;; Indent/deindent the same as the major mode in the original - ;; buffer. - (setq indent-tabs-mode i-t-m) - (insert text) - (indent-rigidly (point-min) (point-max) - (- indentation)) - (buffer-string)))) + ;; We bind inhibit-read-only non-nil in case the copied text has + ;; read-only properties. + (let ((inhibit-read-only t)) + ;; Indent/deindent the same as the major mode in the original + ;; buffer. + (setq indent-tabs-mode i-t-m) + (insert text) + (indent-rigidly (point-min) (point-max) + (- indentation)) + (buffer-string))))) ;;;###autoload (define-minor-mode kill-ring-deindent-mode diff --git a/lisp/international/kkc.el b/lisp/international/kkc.el index 6d603cf831a..a1789bce16f 100644 --- a/lisp/international/kkc.el +++ b/lisp/international/kkc.el @@ -64,9 +64,12 @@ This string is shown at mode line when users are in KKC mode.") (not (eq kkc-init-file-flag t))) (let ((coding-system-for-write 'iso-2022-7bit) (print-length nil)) - (write-region (format "(setq kkc-lookup-cache '%S)\n" kkc-lookup-cache) - nil - kkc-init-file-name)))) + (write-region + (format + ";; -*- lexical-binding: t; -*-\n\n(setq kkc-lookup-cache '%S)\n" + kkc-lookup-cache) + nil + kkc-init-file-name)))) ;; Sequence of characters to be used for indexes for shown list. The ;; Nth character is for the Nth conversion in the list currently shown. @@ -178,7 +181,8 @@ area while indicating the current selection by `'." (add-hook 'kill-emacs-hook 'kkc-save-init-file) (if (file-readable-p kkc-init-file-name) (condition-case nil - (load-file kkc-init-file-name) + (let ((warning-inhibit-types '((files missing-lexbind-cookie)))) + (load-file kkc-init-file-name)) (kkc-error "Invalid data in %s" kkc-init-file-name)))) (or (and (nested-alist-p kkc-lookup-cache) (eq (car kkc-lookup-cache) kkc-lookup-cache-tag)) diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 20649082941..d015b73e955 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -2135,10 +2135,14 @@ minibuffer and the selected frame has no other windows)." (let ((guidance (quail-guidance))) (if (listp guidance) ;; We must replace the typed key with the specified PROMPT-KEY. - (dotimes (i (length str)) - (let ((prompt-key (cdr (assoc (aref str i) guidance)))) - (if prompt-key - (aset str i (aref prompt-key 0))))))) + (setq str (apply #'string + (mapcar + (lambda (c) + (let ((prompt-key (assq c guidance))) + (if prompt-key + (aref (cdr prompt-key) 0) + c))) + str))))) ;; Show followable keys. (if (and (> (length quail-current-key) 0) (cdr map)) diff --git a/lisp/isearch.el b/lisp/isearch.el index 68519b7a820..5a79076c63d 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -1751,7 +1751,9 @@ You can update the global isearch variables by setting new values to ;; This is so that the user can do anything without failure, ;; like switch buffers and start another isearch, and return. (condition-case nil - (isearch-done t t) + (progn + (isearch-done t t) + (isearch-clean-overlays)) (exit nil)) ; was recursive editing ;; Save old point and isearch-other-end before reading from minibuffer @@ -1824,6 +1826,7 @@ You can update the global isearch variables by setting new values to (progn ;; (sit-for 1) ;; needed if isearch-done does: (message "") (isearch-done) + (isearch-clean-overlays) ;; The search done message is confusing when the string ;; is empty, so erase it. (if (equal isearch-string "") @@ -3790,19 +3793,20 @@ Optional third argument, if t, means if fail just return nil (no error). ;; point returns to the original location which surely is not contain ;; in any of these overlays, se we are safe in this case too. (defun isearch-open-necessary-overlays (ov) - (let ((inside-overlay (and (> (point) (overlay-start ov)) - (<= (point) (overlay-end ov)))) - ;; If this exists it means that the overlay was opened using - ;; this function, not by us tweaking the overlay properties. - (fct-temp (overlay-get ov 'isearch-open-invisible-temporary))) - (when (or inside-overlay (not fct-temp)) - ;; restore the values for the `invisible' properties. - (overlay-put ov 'invisible (overlay-get ov 'isearch-invisible)) - (overlay-put ov 'isearch-invisible nil)) - (if inside-overlay - (funcall (overlay-get ov 'isearch-open-invisible) ov) - (if fct-temp - (funcall fct-temp ov t))))) + (when (overlay-buffer ov) + (let ((inside-overlay (and (> (point) (overlay-start ov)) + (<= (point) (overlay-end ov)))) + ;; If this exists it means that the overlay was opened using + ;; this function, not by us tweaking the overlay properties. + (fct-temp (overlay-get ov 'isearch-open-invisible-temporary))) + (when (or inside-overlay (not fct-temp)) + ;; restore the values for the `invisible' properties. + (overlay-put ov 'invisible (overlay-get ov 'isearch-invisible)) + (overlay-put ov 'isearch-invisible nil)) + (if inside-overlay + (funcall (overlay-get ov 'isearch-open-invisible) ov) + (if fct-temp + (funcall fct-temp ov t)))))) ;; This is called when exiting isearch. It closes the temporary ;; opened overlays, except the ones that contain the latest match. @@ -3827,16 +3831,17 @@ Optional third argument, if t, means if fail just return nil (no error). (let ((overlays isearch-opened-overlays)) (setq isearch-opened-overlays nil) (dolist (ov overlays) - (if (isearch-intersects-p beg end (overlay-start ov) (overlay-end ov)) - (push ov isearch-opened-overlays) - (let ((fct-temp (overlay-get ov 'isearch-open-invisible-temporary))) - (if fct-temp - ;; If this exists it means that the overlay was opened - ;; using this function, not by us tweaking the overlay - ;; properties. - (funcall fct-temp ov t) - (overlay-put ov 'invisible (overlay-get ov 'isearch-invisible)) - (overlay-put ov 'isearch-invisible nil))))))) + (when (overlay-buffer ov) + (if (isearch-intersects-p beg end (overlay-start ov) (overlay-end ov)) + (push ov isearch-opened-overlays) + (let ((fct-temp (overlay-get ov 'isearch-open-invisible-temporary))) + (if fct-temp + ;; If this exists it means that the overlay was opened + ;; using this function, not by us tweaking the overlay + ;; properties. + (funcall fct-temp ov t) + (overlay-put ov 'invisible (overlay-get ov 'isearch-invisible)) + (overlay-put ov 'isearch-invisible nil)))))))) (defun isearch-range-invisible (beg end) diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 10328165450..e1f62222e9a 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -6,7 +6,8 @@ ;;; Commentary: ;; This file will be copied to ldefs-boot.el and checked in -;; periodically. +;; periodically. Note: When checking in ldefs-boot.el, don't include +;; changes to any other files in the commit. ;;; Code: @@ -1563,6 +1564,8 @@ disabled. ;;; Generated autoloads from autorevert.el +(defvar auto-revert-buffer-in-progress nil "\ +Non-nil if a `auto-revert-buffer' operation is in progress, nil otherwise.") (autoload 'auto-revert-mode "autorevert" "\ Toggle reverting buffer when the file changes (Auto-Revert Mode). @@ -2982,6 +2985,7 @@ This function attempts to use file contents to determine whether the code is C or C++, and based on that chooses whether to enable `c-ts-mode' or `c++-ts-mode'." t) (make-obsolete 'c-or-c++-ts-mode 'c-or-c++-mode "30.1") +(when (treesit-available-p) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(c-mode . c-ts-mode)) (add-to-list 'treesit-major-mode-remap-alist '(c++-mode . c++-ts-mode)) (add-to-list 'treesit-major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode))) (register-definition-prefixes "c-ts-mode" '("c-ts-")) @@ -4699,6 +4703,11 @@ For use inside Lisp programs, see also `c-macro-expansion'. Major mode for editing CMake files, powered by tree-sitter. (fn)" t) +(autoload 'cmake-ts-mode-maybe "cmake-ts-mode" "\ +Enable `cmake-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode-maybe)) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(cmake-mode . cmake-ts-mode))) (register-definition-prefixes "cmake-ts-mode" '("cmake-ts-mode-")) @@ -5923,6 +5932,7 @@ Key bindings: Major mode for editing C# code. (fn)" t) +(when (treesit-available-p) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(csharp-mode . csharp-ts-mode))) (register-definition-prefixes "csharp-mode" '("codedoc-font-lock-" "csharp-")) @@ -5952,6 +5962,7 @@ can also be used to fill comments. \\{css-mode-map} (fn)" t) +(when (treesit-available-p) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(css-mode . css-ts-mode))) (autoload 'css-mode "css-mode" "\ Major mode to edit Cascading Style Sheets (CSS). \\ @@ -8385,6 +8396,11 @@ disabled. Major mode for editing Dockerfiles, powered by tree-sitter. (fn)" t) +(autoload 'dockerfile-ts-mode-maybe "dockerfile-ts-mode" "\ +Enable `dockerfile-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)\\'" . dockerfile-ts-mode-maybe)) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(dockerfile-mode . dockerfile-ts-mode))) (register-definition-prefixes "dockerfile-ts-mode" '("dockerfile-ts-mode--")) @@ -8534,6 +8550,7 @@ INIT-VALUE LIGHTER KEYMAP. (fn MODE DOC [KEYWORD VAL ... &rest BODY])" nil t) (function-put 'define-minor-mode 'doc-string-elt 2) (function-put 'define-minor-mode 'lisp-indent-function 'defun) +(function-put 'define-minor-mode 'autoload-macro 'expand) (autoload 'define-globalized-minor-mode "easy-mmode" "\ Make a global mode GLOBAL-MODE corresponding to buffer-local minor MODE. TURN-ON is a function that will be called with no args in every buffer @@ -8577,6 +8594,7 @@ on if the hook has explicitly disabled it. (fn GLOBAL-MODE MODE TURN-ON [KEY VALUE]... BODY...)" nil t) (function-put 'define-globalized-minor-mode 'doc-string-elt 2) (function-put 'define-globalized-minor-mode 'lisp-indent-function 'defun) +(function-put 'define-globalized-minor-mode 'autoload-macro 'expand) (autoload 'easy-mmode-define-keymap "easy-mmode" "\ Return a keymap built from bindings BS. BS must be a list of (KEY . BINDING) where @@ -8925,7 +8943,7 @@ A second call of this function without changing point inserts the next match. A call with prefix PREFIX reads the symbol to insert from the minibuffer with completion. -(fn PREFIX)" '("P")) +(fn PREFIX)" t) (autoload 'ebrowse-tags-loop-continue "ebrowse" "\ Repeat last operation on files in tree. FIRST-TIME non-nil means this is not a repetition, but the first time. @@ -9953,6 +9971,11 @@ mode hooks. Major mode for editing Elixir, powered by tree-sitter. (fn)" t) +(autoload 'elixir-ts-mode-maybe "elixir-ts-mode" "\ +Enable `elixir-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("\\.elixir\\'" . elixir-ts-mode-maybe)) (add-to-list 'auto-mode-alist '("\\.ex\\'" . elixir-ts-mode-maybe)) (add-to-list 'auto-mode-alist '("\\.exs\\'" . elixir-ts-mode-maybe)) (add-to-list 'auto-mode-alist '("mix\\.lock" . elixir-ts-mode-maybe)) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(elixir-mode . elixir-ts-mode))) (register-definition-prefixes "elixir-ts-mode" '("elixir-ts-")) @@ -10691,7 +10714,7 @@ ERC assigns SERVER and FULL-NAME the associated keyword values and defers to `erc-compute-port', `erc-compute-user', and `erc-compute-nick' for those respective parameters. -(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME ID)" '((let ((erc--display-context `((erc-interactive-display . erc) ,@erc--display-context))) (erc-select-read-args)))) +(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME ID)" t) (defalias 'erc-select #'erc) (autoload 'erc-tls "erc" "\ Connect to an IRC server over a TLS-encrypted connection. @@ -10714,7 +10737,7 @@ See the alternative entry-point command `erc' as well as Info node `(erc) Connecting' for a fuller description of the various parameters, like ID. -(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME CLIENT-CERTIFICATE ID)" '((let ((erc-default-port erc-default-port-tls) (erc--display-context `((erc-interactive-display . erc-tls) ,@erc--display-context))) (erc-select-read-args)))) +(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME CLIENT-CERTIFICATE ID)" t) (autoload 'erc-handle-irc-url "erc" "\ Use ERC to IRC on HOST:PORT in CHANNEL. If ERC is already connected to HOST:PORT, simply /join CHANNEL. @@ -15112,15 +15135,29 @@ Major mode for editing Go, powered by tree-sitter. \\{go-ts-mode-map} (fn)" t) +(autoload 'go-ts-mode-maybe "go-ts-mode" "\ +Enable `go-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode-maybe)) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(go-mode . go-ts-mode))) (autoload 'go-mod-ts-mode "go-ts-mode" "\ Major mode for editing go.mod files, powered by tree-sitter. (fn)" t) +(autoload 'go-mod-ts-mode-maybe "go-ts-mode" "\ +Enable `go-mod-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode-maybe)) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(go-mod-mode . go-mod-ts-mode))) (autoload 'go-work-ts-mode "go-ts-mode" "\ Major mode for editing go.work files, powered by tree-sitter. (fn)" t) -(add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)) +(autoload 'go-work-ts-mode-maybe "go-ts-mode" "\ +Enable `go-work-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode-maybe)) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(go-work-mode . go-work-ts-mode))) (register-definition-prefixes "go-ts-mode" '("go-")) @@ -15793,6 +15830,11 @@ Like `hanoi-unix', but with a 64-bit clock." t) Major mode for editing HEEx, powered by tree-sitter. (fn)" t) +(autoload 'heex-ts-mode-maybe "heex-ts-mode" "\ +Enable `heex-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("\\.[hl]?eex\\'" . heex-ts-mode-maybe)) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(heex-mode . heex-ts-mode))) (register-definition-prefixes "heex-ts-mode" '("heex-ts-")) @@ -18851,6 +18893,7 @@ See Info node `(elisp)Defining Functions' for more details. (fn NAME ARGS &rest BODY)" nil t) (function-put 'define-inline 'lisp-indent-function 'defun) (function-put 'define-inline 'doc-string-elt 3) +(function-put 'define-inline 'autoload-macro 'expand) (register-definition-prefixes "inline" '("inline-")) @@ -19295,6 +19338,7 @@ Return the string read from the minibuffer. Major mode for editing Java, powered by tree-sitter. (fn)" t) +(when (treesit-available-p) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(java-mode . java-ts-mode))) (register-definition-prefixes "java-ts-mode" '("java-ts-mode-")) @@ -19341,6 +19385,7 @@ Major mode for editing JavaScript. \\ (fn)" t) +(when (treesit-available-p) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(javascript-mode . js-ts-mode))) (autoload 'js-json-mode "js" "\ @@ -19376,6 +19421,7 @@ one of the aforementioned options instead of using this mode. Major mode for editing JSON, powered by tree-sitter. (fn)" t) +(when (treesit-available-p) (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(js-json-mode . json-ts-mode))) (register-definition-prefixes "json-ts-mode" '("json-ts-")) @@ -19874,7 +19920,7 @@ The first element on the command line should be the (main) loaddefs.el output file, and the rest are the directories to use.") (load "theme-loaddefs.el" t) -(register-definition-prefixes "loaddefs-gen" '("autoload-" "generated-autoload-" "loaddefs-generate--" "no-update-autoloads")) +(register-definition-prefixes "loaddefs-gen" '("autoload-" "generated-autoload-" "loaddefs-" "no-update-autoloads")) ;;; Generated autoloads from loadhist.el @@ -20105,6 +20151,11 @@ Major mode for editing Lua files, powered by tree-sitter. \\{lua-ts-mode-map} (fn)" t) +(autoload 'lua-ts-mode-maybe "lua-ts-mode" "\ +Enable `lua-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name.") +(when (treesit-available-p) (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-ts-mode-maybe)) (add-to-list 'interpreter-mode-alist '("\\ m m-orig) (when (yes-or-no-p "Is this bug about org-mode?") (error (substitute-command-keys "\ Not sending, use \\[org-submit-bug-report] to report an Org-mode bug."))))))) @@ -584,7 +587,7 @@ Message buffer where you can explain more about the patch." (message-goto-body) (insert "\n\n\n") (emacs-build-description) - (mml-attach-file file "text/patch" nil "attachment") + (mml-attach-file file "text/x-patch" nil "attachment") (message-goto-body) (message "Write a description of the patch and use %s to send it" (substitute-command-keys "\\[message-send-and-exit]")) diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 41b0813707f..b8aa937aec2 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -4515,6 +4515,11 @@ TEXT and INDENT are not used." ;; to "prying eyes." Obviously, this encoding isn't "real security," ;; nor is it meant to be. +(defvar rmail--remote-password-host nil + "Last recorded value of the HOST argument to `rmail-get-remote-password'.") +(defvar rmail--remote-password-user nil + "Last recorded value of the USER argument to `rmail-get-remote-password'.") + ;;;###autoload (defun rmail-set-remote-password (password) "Set PASSWORD to be used for retrieving mail from a POP or IMAP server." @@ -4535,7 +4540,12 @@ machine mymachine login myloginname password mypassword If auth-source search yields no result, prompt the user for the password." - (when (not rmail-encoded-remote-password) + (when (or (not rmail-encoded-remote-password) + (not (equal user rmail--remote-password-user)) + (not (equal host rmail--remote-password-host))) + ;; Record the values we will be using from now on. + (setq rmail--remote-password-host host + rmail--remote-password-user user) (if (not rmail-remote-password) (setq rmail-remote-password (let ((found (nth 0 (auth-source-search diff --git a/lisp/man.el b/lisp/man.el index 9e1d294b1ec..49873c5a87b 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -1123,7 +1123,14 @@ for the current invocation." (and (not (equal default-entry "")) default-entry)) #'Man-completion-table - nil nil nil 'Man-topic-history default-entry))) + nil nil nil 'Man-topic-history + `(,default-entry + ,@(when (use-region-p) + (list (string-replace + " " "-" + (buffer-substring-no-properties + (region-beginning) + (region-end))))))))) (if Man-cache-completion-results-flag (read) (let ((Man-completion-cache)) (read)))))) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 122459be062..3558b14bf78 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1064,6 +1064,24 @@ metadata." (const :tag "If requested by the completion command" auto)) :version "31.1") +(defcustom completion-eager-update 'auto + "Whether the *Completions* buffer should update as you type. + +If `t', always update as you type. + +If `auto', only update if the completion property `eager-update' is +non-nil, whether set by the completion table or by +`completion-category-overrides' or by `completion-category-defaults'. + +If nil, never update as you type. + +This only affects the *Completions* buffer if it is already +displayed." + :type '(choice (const :tag "Don't update as you type" nil) + (const :tag "Auto-update based on the category" auto) + (const :tag "Always update as you type" t)) + :version "31.1") + (defcustom completion-auto-help t "Non-nil means automatically provide help for invalid completion input. If the value is t, the *Completions* buffer is displayed whenever completion @@ -1197,6 +1215,7 @@ styles for specific categories, such as files, buffers, etc." ;; A new style that combines substring and pcm might be better, ;; e.g. one that does not anchor to bos. (project-file (styles . (substring))) + (project-buffer (styles . (basic substring))) (xref-location (styles . (substring))) (info-menu (styles . (basic substring))) (symbol-help (styles . (basic shorthand substring)))) @@ -1598,7 +1617,7 @@ when the buffer's text is already an exact match." (completed (cond ((pcase completion-auto-help - ('visible (get-buffer-window "*Completions*" 0)) + ('visible (minibuffer--completions-visible)) ('always t)) (minibuffer-completion-help beg end)) (t (minibuffer-hide-completions) @@ -2634,12 +2653,43 @@ The candidate will still be chosen by `choose-completion' unless (goto-char (or (next-single-property-change (point) 'completion--string) (point-max))))) +(defun completion--eager-update-p (start) + "Return non-nil if *Completions* should be automatically updated. + +If `completion-eager-update' is the symbol `auto', checks completion +metadata for the string from START to point." + (if (eq completion-eager-update 'auto) + (completion-metadata-get (completion--field-metadata start) 'eager-update) + completion-eager-update)) + +(defun completions--background-update () + "Try to update *Completions* without blocking input. + +This function uses `while-no-input' and sets `non-essential' to t +so that the update is less likely to interfere with user typing." + (while-no-input + (let ((non-essential t)) + (redisplay) + (cond + (completion-in-region-mode (completion-help-at-point t)) + ((completion--eager-update-p (minibuffer-prompt-end)) + (minibuffer-completion-help)))))) + +(defun completions--post-command-update () + "Update displayed *Completions* buffer after command, once." + (remove-hook 'post-command-hook #'completions--post-command-update) + (when (and completion-eager-update (minibuffer--completions-visible)) + (completions--background-update))) + (defun completions--after-change (_start _end _old-len) "Update displayed *Completions* buffer after change in buffer contents." - (when completion-auto-deselect - (when-let* ((window (get-buffer-window "*Completions*" 0))) - (with-selected-window window - (completions--deselect))))) + (when (or completion-auto-deselect completion-eager-update) + (when-let* ((window (minibuffer--completions-visible))) + (when completion-auto-deselect + (with-selected-window window + (completions--deselect))) + (when completion-eager-update + (add-hook 'post-command-hook #'completions--post-command-update))))) (defun minibuffer-completion-help (&optional start end) "Display a list of possible completions of the current minibuffer contents." @@ -2730,7 +2780,7 @@ The candidate will still be chosen by `choose-completion' unless (body-function . ,#'(lambda (window) (with-current-buffer mainbuf - (when completion-auto-deselect + (when (or completion-auto-deselect completion-eager-update) (add-hook 'after-change-functions #'completions--after-change nil t)) ;; Remove the base-size tail because `sort' requires a properly ;; nil-terminated list. @@ -2836,7 +2886,7 @@ The candidate will still be chosen by `choose-completion' unless ;; FIXME: We could/should use minibuffer-scroll-window here, but it ;; can also point to the minibuffer-parent-window, so it's a bit tricky. (interactive) - (when-let* ((win (get-buffer-window "*Completions*" 0))) + (when-let* ((win (minibuffer--completions-visible))) (with-selected-window win ;; Move point off any completions, so we don't move point there ;; again the next time `minibuffer-completion-help' is called. @@ -3119,7 +3169,7 @@ The completion method is determined by `completion-at-point-functions'." (car res))) (cdr res))))) -(defun completion-help-at-point () +(defun completion-help-at-point (&optional only-if-eager) "Display the completions on the text around point. The completion method is determined by `completion-at-point-functions'." (interactive) @@ -3146,7 +3196,8 @@ The completion method is determined by `completion-at-point-functions'." `(,start ,(copy-marker end t) ,collection ,(plist-get plist :predicate))) (completion-in-region-mode 1) - (minibuffer-completion-help start end))) + (when (or (not only-if-eager) (completion--eager-update-p start)) + (minibuffer-completion-help start end)))) (`(,hookfun . ,_) ;; The hook function already performed completion :-( ;; Not much we can do at this point. @@ -3282,18 +3333,26 @@ and `RET' accepts the input typed into the minibuffer." (defvar minibuffer-visible-completions--always-bind nil "If non-nil, force the `minibuffer-visible-completions' bindings on.") +(defun minibuffer--completions-visible () + "Return the window where the current *Completions* buffer is visible, if any." + (when-let* ((window (get-buffer-window "*Completions*" 0))) + (when (eq (buffer-local-value 'completion-reference-buffer + (window-buffer window)) + ;; If there's no active minibuffer, we call + ;; `window-buffer' on nil, assuming that completion is + ;; happening in the selected window. + (window-buffer (active-minibuffer-window))) + window))) + (defun minibuffer-visible-completions--filter (cmd) "Return CMD if `minibuffer-visible-completions' bindings should be active." (if minibuffer-visible-completions--always-bind cmd - (when-let* ((window (get-buffer-window "*Completions*" 0))) - (when (and (eq (buffer-local-value 'completion-reference-buffer - (window-buffer window)) - (window-buffer (active-minibuffer-window))) - (if (eq cmd #'minibuffer-choose-completion-or-exit) - (with-current-buffer (window-buffer window) - (get-text-property (point) 'completion--string)) - t)) + (when-let* ((window (minibuffer--completions-visible))) + (when (if (eq cmd #'minibuffer-choose-completion-or-exit) + (with-current-buffer (window-buffer window) + (get-text-property (point) 'completion--string)) + t) cmd)))) (defun minibuffer-visible-completions--bind (binding) @@ -4067,7 +4126,7 @@ style." "Split STRING into a pattern. A pattern is a list where each element is either a string or a symbol, see `completion-pcm--merge-completions'." - (if (and point (< point (length string))) + (if (and point (<= point (length string))) (let ((prefix (substring string 0 point)) (suffix (substring string point))) (append (completion-pcm--string->pattern prefix) @@ -4128,12 +4187,6 @@ or a symbol, see `completion-pcm--merge-completions'." (pcase p (`(,(or 'any 'any-delim) ,(or 'any 'point) . ,_) (setq p (cdr p))) - ;; This is not just a performance improvement: it turns a - ;; terminating `point' into an implicit `any', which affects - ;; the final position of point (because `point' gets turned - ;; into a non-greedy ".*?" regexp whereas we need it to be - ;; greedy when it's at the end, see bug#38458). - (`(point) (setq p nil)) ;Implicit terminating `any'. (_ (push (pop p) n)))) (nreverse n))) @@ -4542,38 +4595,35 @@ the same set of elements." (cond ((null (cdr strs)) (list (car strs))) (t - (let ((re (completion-pcm--pattern->regex pattern 'group)) + (let ((re (concat + (completion-pcm--pattern->regex pattern 'group) + ;; The implicit trailing `any' is greedy. + "\\([^z-a]*\\)")) (ccs ())) ;Chopped completions. - ;; First chop each string into the parts corresponding to each - ;; non-constant element of `pattern', using regexp-matching. + ;; First match each string against PATTERN as a regex and extract + ;; the text matched by each wildcard. (let ((case-fold-search completion-ignore-case)) (dolist (str strs) (unless (string-match re str) (error "Internal error: %s doesn't match %s" str re)) (let ((chopped ()) - (last 0) (i 1) next) - (while (setq next (match-end i)) - (push (substring str last next) chopped) - (setq last next) + (while (setq next (match-string i str)) + (push next chopped) (setq i (1+ i))) - ;; Add the text corresponding to the implicit trailing `any'. - (push (substring str last) chopped) (push (nreverse chopped) ccs)))) - ;; Then for each of those non-constant elements, extract the - ;; commonality between them. + ;; Then for each of those wildcards, extract the commonality between them. (let ((res ()) - (fixed "") ;; Accumulate each stretch of wildcards, and process them as a unit. (wildcards ())) ;; Make the implicit trailing `any' explicit. (dolist (elem (append pattern '(any))) (if (stringp elem) (progn - (setq fixed (concat fixed elem)) + (push elem res) (setq wildcards nil)) (let ((comps ())) (push elem wildcards) @@ -4584,10 +4634,14 @@ the same set of elements." ;; different capitalizations in different parts. ;; In practice, it doesn't seem to make any difference. (setq ccs (nreverse ccs)) - (let* ((prefix (try-completion fixed comps)) - (unique (or (and (eq prefix t) (setq prefix fixed)) + (let* ((prefix (try-completion "" comps)) + (unique (or (and (eq prefix t) (setq prefix "")) (and (stringp prefix) - (eq t (try-completion prefix comps)))))) + ;; If PREFIX is equal to all of COMPS, + ;; then PREFIX is a unique completion. + (seq-every-p + (lambda (comp) (= (length prefix) (length comp))) + comps))))) ;; If there's only one completion, `elem' is not useful ;; any more: it can only match the empty string. ;; FIXME: in some cases, it may be necessary to turn an @@ -4601,7 +4655,7 @@ the same set of elements." ;; `prefix' only wants to include the fixed part before the ;; wildcard, not the result of growing that fixed part. (when (seq-some (lambda (elem) (eq elem 'prefix)) wildcards) - (setq prefix fixed)) + (setq prefix "")) (push prefix res) ;; Push all the wildcards in this stretch, to preserve `point' and ;; `star' wildcards before ELEM. @@ -4625,8 +4679,7 @@ the same set of elements." (unless (equal suffix "") (push suffix res)))) ;; We pushed these wildcards on RES, so we're done with them. - (setq wildcards nil)) - (setq fixed ""))))) + (setq wildcards nil)))))) ;; We return it in reverse order. res))))) @@ -5063,10 +5116,10 @@ the minibuffer was activated, and execute the forms." When used in a minibuffer window, select the window with completions, and execute the forms." (declare (indent 0) (debug t)) - `(let ((window (or (get-buffer-window "*Completions*" 0) + `(let ((window (or (minibuffer--completions-visible) ;; Make sure we have a completions window. (progn (minibuffer-completion-help) - (get-buffer-window "*Completions*" 0))))) + (minibuffer--completions-visible))))) (when window (with-selected-window window (completion--lazy-insert-strings) @@ -5161,7 +5214,7 @@ inputs for the prompting command, instead of the default completion table." (user-error "No history available")))) ;; FIXME: Can we make it work for CRM? (let ((completion-in-region-mode-predicate - (lambda () (get-buffer-window "*Completions*" 0)))) + (lambda () (minibuffer--completions-visible)))) (completion-in-region (minibuffer--completion-prompt-end) (point-max) (completion-table-with-metadata @@ -5179,7 +5232,7 @@ provided by the prompting command, instead of the completion table." minibuffer-default (funcall minibuffer-default-add-function))) (let ((completions (ensure-list minibuffer-default)) (completion-in-region-mode-predicate - (lambda () (get-buffer-window "*Completions*" 0)))) + (lambda () (minibuffer--completions-visible)))) (completion-in-region (minibuffer--completion-prompt-end) (point-max) (completion-table-with-metadata diff --git a/lisp/net/eww.el b/lisp/net/eww.el index e0ec7d91090..6f06302cb3f 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -1356,7 +1356,6 @@ This consults the entries in `eww-readable-urls' (which see)." "" #'eww-forward-url :menu '("Eww" - ["Exit" quit-window t] ["Close browser" quit-window t] ["Reload" eww-reload t] ["Follow URL in new buffer" eww-open-in-new-buffer] diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 2d240e8756b..5d6c053868b 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -573,9 +573,9 @@ Emacs dired can't find files." "touch -t %s %s %s") (format-time-string "%Y-%m-%dT%H:%M:%S.%NZ" time t) nofollow quoted-name (tramp-get-remote-null-device v) - (format-time-string "%Y-%m-%dT%H:%M:%S" time t) + (format-time-string "%Y-%m-%dT%H:%M:%S" time) nofollow quoted-name (tramp-get-remote-null-device v) - (format-time-string "%Y%m%d%H%M.%S" time t) + (format-time-string "%Y%m%d%H%M.%S" time) nofollow quoted-name))))) (defun tramp-adb-handle-copy-file diff --git a/lisp/net/tramp-compat.el b/lisp/net/tramp-compat.el index 9787e3a6553..5db8f1f61da 100644 --- a/lisp/net/tramp-compat.el +++ b/lisp/net/tramp-compat.el @@ -29,7 +29,7 @@ ;;; Code: -(require 'tramp-loaddefs) +(require 'tramp-loaddefs nil t) ; guard against load during autoload gen (require 'ansi-color) (require 'auth-source) (require 'format-spec) diff --git a/lisp/net/tramp-message.el b/lisp/net/tramp-message.el index 5131e5fced9..a328183e184 100644 --- a/lisp/net/tramp-message.el +++ b/lisp/net/tramp-message.el @@ -94,6 +94,15 @@ This increases `tramp-verbose' to 6 if necessary." :type 'boolean :link '(info-link :tag "Tramp manual" "(tramp) Traces and Profiles")) +(defcustom tramp-debug-buffer-limit (* 100 1024 1024) ;100MB + "The upper limit of a Tramp debug buffer. +If the size of a debug buffer exceeds this limit, a warning is raised. +Set it to 0 if there is no limit." + :group 'tramp + :version "31.1" + :type 'natnum + :link '(info-link :tag "Tramp manual" "(tramp) Traces and Profiles")) + (defconst tramp-debug-outline-regexp (rx ;; Timestamp. (+ digit) ":" (+ digit) ":" (+ digit) "." (+ digit) blank @@ -281,7 +290,14 @@ ARGUMENTS to actually emit the message (if applicable)." (when tramp-debug-to-file (ignore-errors (write-region - point (point-max) (tramp-get-debug-file-name vec) 'append)))))))) + point (point-max) (tramp-get-debug-file-name vec) 'append)))) + (when (and (natnump tramp-debug-buffer-limit) + (not (zerop tramp-debug-buffer-limit)) + (> (point-max) tramp-debug-buffer-limit)) + (setq-local tramp-debug-buffer-limit nil) + (lwarn + 'tramp :warning + "Tramp debug buffer %S exceeds the limit" (current-buffer))))))) ;;;###tramp-autoload (defun tramp-message (vec-or-proc level fmt-string &rest arguments) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 576f09b764b..9d13cdc3a2d 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1633,7 +1633,10 @@ of." "-t %s" (format-time-string "%Y%m%d%H%M.%S" (tramp-defined-time time) t)) "") - (if (eq flag 'nofollow) "-h" "") + (if (and (eq flag 'nofollow) + (tramp-get-connection-property v "touch-h")) + "-h" + "") (tramp-shell-quote-argument localname)))))) (defun tramp-sh-handle-get-home-directory (vec &optional user) @@ -3669,6 +3672,8 @@ are \"file-exists-p\", \"file-readable-p\", \"file-directory-p\" and (defun tramp-sh-handle-vc-registered (file) "Like `vc-registered' for Tramp files." (when vc-handled-backends + ;; Starting with Emacs 31, use `revert-buffer-in-progress'. + (with-suppressed-warnings ((obsolete revert-buffer-in-progress-p)) (let ((inhibit-message (or revert-buffer-in-progress-p inhibit-message)) (temp-message (unless revert-buffer-in-progress-p ""))) (with-temp-message temp-message @@ -3728,7 +3733,7 @@ are \"file-exists-p\", \"file-readable-p\", \"file-directory-p\" and ;; Run. (tramp-with-demoted-errors v "Error in 2nd pass of `vc-registered': %s" - (tramp-run-real-handler #'vc-registered (list file)))))))))) + (tramp-run-real-handler #'vc-registered (list file))))))))))) ;;;###tramp-autoload (defun tramp-sh-file-name-handler (operation &rest args) @@ -5149,17 +5154,41 @@ Goes through the list `tramp-inline-compress-commands'." ;;;###tramp-autoload (defun tramp-timeout-session (vec) "Close the connection VEC after a session timeout. -If there is just some editing, retry it after 5 seconds." - (if (and (tramp-get-connection-property - (tramp-get-connection-process vec) "locked") - (tramp-file-name-equal-p vec (car tramp-current-connection))) - (progn - (tramp-message - vec 5 "Cannot timeout session, trying it again in %s seconds." 5) - (run-at-time 5 nil #'tramp-timeout-session vec)) +If there is just some editing, retry it after 5 seconds. +If there is a modified buffer, retry it after 60 seconds." + (cond + ;; Tramp is locked. Try it, again. + ((and (tramp-get-connection-property + (tramp-get-connection-process vec) "locked") + (tramp-file-name-equal-p vec (car tramp-current-connection))) (tramp-message - vec 3 "Timeout session %s" (tramp-make-tramp-file-name vec 'noloc)) - (tramp-cleanup-connection vec 'keep-debug nil 'keep-processes))) + vec 5 "Cannot timeout session, trying it again in %s seconds." 5) + (run-at-time 5 nil #'tramp-timeout-session vec)) + ;; There's a modified buffer. Try it, again. + ((seq-some + (lambda (buf) + (and-let* (((or (buffer-modified-p buf) + (with-current-buffer buf + ;; We don't know whether autorevert.el has + ;; been loaded alreaddy. + (tramp-compat-funcall 'auto-revert-active-p)))) + (bfn (buffer-file-name buf)) + (v (tramp-ensure-dissected-file-name bfn)) + ((tramp-file-name-equal-p vec v))))) + (tramp-list-remote-buffers)) + (tramp-message + vec 5 + (concat + "Cannot timeout session (modified buffer), " + "trying it again in %s seconds.") + (tramp-get-method-parameter vec 'tramp-session-timeout)) + (run-at-time + (tramp-get-method-parameter vec 'tramp-session-timeout) nil + #'tramp-timeout-session vec)) + ;; Do it. + (t (tramp-message + vec 3 "Timeout session %s" (tramp-make-tramp-file-name vec 'noloc)) + (tramp-cleanup-connection vec 'keep-debug nil 'keep-processes)))) (defun tramp-maybe-open-connection (vec) "Maybe open a connection VEC. @@ -5887,12 +5916,12 @@ Nonexistent directories are removed from spec." "Determine remote `touch' command." (with-tramp-connection-property vec "touch" (tramp-message vec 5 "Finding a suitable `touch' command") - (let ((result (tramp-find-executable - vec "touch" (tramp-get-remote-path vec))) - (tmpfile (tramp-make-tramp-temp-name vec))) - ;; Busyboxes do support the "-t" option only when they have been - ;; built with the DESKTOP config option. Let's check it. - (when result + (when-let* ((result (tramp-find-executable + vec "touch" (tramp-get-remote-path vec))) + (tmpfile (tramp-make-tramp-temp-name vec))) + (prog1 result + ;; Busyboxes do support the "-t" option only when they have + ;; been built with the DESKTOP config option. Let's check it. (tramp-set-connection-property vec "touch-t" (tramp-send-command-and-check @@ -5902,8 +5931,13 @@ Nonexistent directories are removed from spec." result (format-time-string "%Y%m%d%H%M.%S") (tramp-file-local-name tmpfile)))) - (delete-file tmpfile)) - result))) + ;; The touch command included in busybox (version 1.30.1-6) on + ;; OpenWrt does not have the option "-h". + (tramp-set-connection-property + vec "touch-h" + (tramp-send-command-and-check + vec (format "%s -h %s" result (tramp-file-local-name tmpfile)))) + (delete-file tmpfile))))) (defun tramp-get-remote-df (vec) "Determine remote `df' command." diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 28364de83f1..fdda945f120 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -295,7 +295,7 @@ See `tramp-actions-before-shell' for more info.") (set-file-acl . tramp-smb-handle-set-file-acl) (set-file-modes . tramp-smb-handle-set-file-modes) (set-file-selinux-context . ignore) - (set-file-times . ignore) + (set-file-times . tramp-smb-handle-set-file-times) (set-visited-file-modtime . tramp-handle-set-visited-file-modtime) (shell-command . tramp-handle-shell-command) (start-file-process . tramp-smb-handle-start-file-process) @@ -1534,6 +1534,15 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (tramp-error v 'file-error "Error while changing file's mode %s" filename)))))) +(defun tramp-smb-handle-set-file-times (filename &optional time _flag) + "Like `set-file-times' for Tramp files." + (tramp-skeleton-set-file-modes-times-uid-gid filename + (tramp-smb-send-command + v (format + "utimes %s -1 -1 %s -1" + (tramp-smb-shell-quote-localname v) + (format-time-string "%Y:%m:%d-%H:%M:%S" (tramp-defined-time time)))))) + ;; We use BUFFER also as connection buffer during setup. Because of ;; this, its original contents must be saved, and restored once ;; connection has been setup. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 2208ce880d7..e80a470957f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -103,8 +103,15 @@ (put 'tramp--startup-hook 'tramp-suppress-trace t) + ;; TODO: once (autoload-macro expand) is available in all supported + ;; Emacs versions, this can be eliminated: + ;; backward compatibility for autoload-macro declare form + (unless (assq 'autoload-macro macro-declarations-alist) + (push '(autoload-macro ignore) macro-declarations-alist)) + (defmacro tramp--with-startup (&rest body) "Schedule BODY to be executed at the end of tramp.el." + (declare (autoload-macro expand)) `(add-hook 'tramp--startup-hook (lambda () ,@body))) (eval-and-compile @@ -2380,6 +2387,9 @@ arguments to pass to the OPERATION." signal-hook-function) (apply operation args))) +(defvar tramp-file-name-for-operation-external nil + "List of operations added by external packages.") + ;; We handle here all file primitives. Most of them have the file ;; name as first parameter; nevertheless we check for them explicitly ;; in order to be signaled if a new primitive appears. This @@ -2387,6 +2397,10 @@ arguments to pass to the OPERATION." ;; syntactical means whether a foreign method must be called. It would ;; ease the life if `file-name-handler-alist' would support a decision ;; function as well but regexp only. +;; Operations added by external packages are kept in +;; `tramp-file-name-for-operation-external'. They expect the file +;; name to be checked as first argument or, if there isn't any +;; argument, `default-directory'. (defun tramp-file-name-for-operation (operation &rest args) "Return file name related to OPERATION file primitive. ARGS are the arguments OPERATION has been called with. @@ -2396,40 +2410,40 @@ first argument of `expand-file-name' is absolute and not remote. Must be handled by the callers." (cond ;; FILE resp DIRECTORY. - ((member operation - '(access-file byte-compiler-base-file-name delete-directory - delete-file diff-latest-backup-file directory-file-name - directory-files directory-files-and-attributes dired-compress-file - dired-uncache file-acl file-accessible-directory-p file-attributes - file-directory-p file-executable-p file-exists-p file-local-copy - file-locked-p file-modes file-name-as-directory - file-name-case-insensitive-p file-name-directory - file-name-nondirectory file-name-sans-versions - file-notify-add-watch file-ownership-preserved-p file-readable-p - file-regular-p file-remote-p file-selinux-context file-symlink-p - file-system-info file-truename file-writable-p - find-backup-file-name get-file-buffer - insert-directory insert-file-contents load lock-file make-directory - make-lock-file-name set-file-acl set-file-modes - set-file-selinux-context set-file-times substitute-in-file-name - unhandled-file-name-directory unlock-file vc-registered - ;; Emacs 28- only. - make-directory-internal - ;; Emacs 29+ only. - abbreviate-file-name - ;; Tramp internal magic file name function. - tramp-set-file-uid-gid)) + ((memq operation + '(access-file byte-compiler-base-file-name delete-directory + delete-file diff-latest-backup-file directory-file-name + directory-files directory-files-and-attributes dired-compress-file + dired-uncache file-acl file-accessible-directory-p file-attributes + file-directory-p file-executable-p file-exists-p file-local-copy + file-locked-p file-modes file-name-as-directory + file-name-case-insensitive-p file-name-directory + file-name-nondirectory file-name-sans-versions + file-notify-add-watch file-ownership-preserved-p file-readable-p + file-regular-p file-remote-p file-selinux-context file-symlink-p + file-system-info file-truename file-writable-p + find-backup-file-name get-file-buffer + insert-directory insert-file-contents load lock-file make-directory + make-lock-file-name set-file-acl set-file-modes + set-file-selinux-context set-file-times substitute-in-file-name + unhandled-file-name-directory unlock-file vc-registered + ;; Emacs 28- only. + make-directory-internal + ;; Emacs 29+ only. + abbreviate-file-name + ;; Tramp internal magic file name function. + tramp-set-file-uid-gid)) (if (file-name-absolute-p (nth 0 args)) (nth 0 args) default-directory)) ;; STRING FILE. ((eq operation 'make-symbolic-link) (nth 1 args)) ;; FILE DIRECTORY resp FILE1 FILE2. - ((member operation - '(add-name-to-file copy-directory copy-file - file-equal-p file-in-directory-p - file-name-all-completions file-name-completion - file-newer-than-file-p rename-file)) + ((memq operation + '(add-name-to-file copy-directory copy-file + file-equal-p file-in-directory-p + file-name-all-completions file-name-completion + file-newer-than-file-p rename-file)) (cond ((tramp-tramp-file-p (nth 0 args)) (nth 0 args)) ((file-name-absolute-p (nth 1 args)) (nth 1 args)) @@ -2446,31 +2460,39 @@ Must be handled by the callers." (nth 2 args) default-directory)) ;; BUFFER. - ((member operation - '(make-auto-save-file-name - set-visited-file-modtime verify-visited-file-modtime)) + ((memq operation + '(make-auto-save-file-name + set-visited-file-modtime verify-visited-file-modtime)) (buffer-file-name (if (bufferp (nth 0 args)) (nth 0 args) (current-buffer)))) ;; COMMAND. - ((member operation - '(exec-path make-nearby-temp-file make-process process-file - shell-command start-file-process temporary-file-directory - ;; Emacs 29+ only. - list-system-processes memory-info process-attributes - ;; Emacs 30+ only. - file-group-gid file-user-uid)) + ((memq operation + '(exec-path make-nearby-temp-file make-process process-file + shell-command start-file-process temporary-file-directory + ;; Emacs 29+ only. + list-system-processes memory-info process-attributes + ;; Emacs 30+ only. + file-group-gid file-user-uid)) default-directory) ;; PROC. - ((member operation '(file-notify-rm-watch file-notify-valid-p)) + ((memq operation '(file-notify-rm-watch file-notify-valid-p)) (when (processp (nth 0 args)) (tramp-get-default-directory (process-buffer (nth 0 args))))) ;; VEC. - ((member operation - '(tramp-get-home-directory tramp-get-remote-gid - tramp-get-remote-groups tramp-get-remote-uid)) + ((memq operation + '(tramp-get-home-directory tramp-get-remote-gid + tramp-get-remote-groups tramp-get-remote-uid)) (tramp-make-tramp-file-name (nth 0 args))) + ;; FILE resp DIRECTORY. + ((and (memq operation tramp-file-name-for-operation-external) + (or (stringp (nth 0 args)) (null (nth 0 args)))) + (if (and (stringp (nth 0 args)) (file-name-absolute-p (nth 0 args))) + (nth 0 args) + default-directory)) ;; Unknown file primitive. - (t (error "Unknown file I/O primitive: %s" operation)))) + (t (unless (member 'remote-file-error debug-ignored-errors) + (tramp-error + nil 'remote-file-error "Unknown file I/O primitive: %s" operation))))) (defun tramp-find-foreign-file-name-handler (vec &optional _operation) "Return foreign file name handler if exists." @@ -2494,6 +2516,63 @@ Must be handled by the callers." res (cdr elt)))) res))) +(defun tramp-add-external-operation (operation function backend) + "Add FUNTION to Tramp BACKEND as handler for OPERATION. +OPERATION must not be one of the magic operations listed in Info +node `(elisp) Magic File Names'. FUNCTION must have the same argument +list as OPERATION. BACKEND, a symbol, must be one of the Tramp backend +packages like `tramp-sh' (except `tramp-ftp')." + (require backend) + (when-let* ((fnha + (intern-soft + (concat (symbol-name backend) "-file-name-handler-alist"))) + ((boundp fnha))) + ;; Make BACKEND aware of the new operation. + (add-to-list fnha (cons operation function)) + (unless (memq operation tramp-file-name-for-operation-external) + ;; Make Tramp aware of the new operation. + (add-to-list 'tramp-file-name-for-operation-external operation) + (put #'tramp-file-name-handler + 'operations + (cons operation (get 'tramp-file-name-handler 'operations))) + ;; Add an advice for OPERATION, in order to invoke the handler FUNCTION. + (advice-add + operation :around + `(lambda (orig-fun &rest args) + (if-let* ((handler + (find-file-name-handler + (or (car args) default-directory) #',operation))) + (apply handler #',operation args) + (apply orig-fun args))) + `((name . ,(concat "tramp-advice-" (symbol-name operation)))))))) + +(defun tramp-remove-external-operation (operation backend) + "Remove OPERATION from Tramp BACKEND as handler for OPERATION. +OPERATION must not be one of the magic operations listed in Info +node `(elisp) Magic File Names'. BACKEND, a symbol, must be one of the +Tramp backend packages like `tramp-sh'." + ;; Remove OPERATION from BACKEND. + (when-let* ((fnha + (intern-soft + (concat (symbol-name backend) "-file-name-handler-alist"))) + ((boundp fnha))) + (setf (alist-get operation (symbol-value fnha) nil 'remove) nil)) + ;; Check, whether OPERATION is still used in any backend. + (unless (seq-some + (lambda (item) + (when-let* + ((fnha (intern-soft (concat (symbol-name (cdr item)) "-alist"))) + ((boundp fnha))) + (alist-get operation (symbol-value fnha)))) + tramp-foreign-file-name-handler-alist) + ;; Make Tramp unaware of OPERATION. + (setq tramp-file-name-for-operation-external + (delq operation tramp-file-name-for-operation-external)) + (put #'tramp-file-name-handler + 'operations (delq operation (get 'tramp-file-name-handler 'operations))) + ;; Remove the advice for OPERATION. + (advice-remove operation (concat "tramp-advice-" (symbol-name operation))))) + ;; Main function. ;;;###autoload (defun tramp-file-name-handler (operation &rest args) @@ -2900,7 +2979,7 @@ not in completion mode." BODY is the backend specific code." (declare (indent 2) (debug t)) `(ignore-error file-missing - (delete-dups (delq nil + (delete-dups (delq nil (delete "" (let* ((case-fold-search read-file-name-completion-ignore-case) (result (progn ,@body))) ;; Some storage systems do not return "." and "..". @@ -2917,7 +2996,7 @@ BODY is the backend specific code." (dolist (elt completion-regexp-list x) (unless (string-match-p elt x) (throw 'match nil)))))) result) - result)))))) + result))))))) (defvar tramp--last-hop-directory nil "Tracks the directory from which to run login programs.") diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el index d8a928b1f9f..49fc4103cc7 100644 --- a/lisp/org/org-src.el +++ b/lisp/org/org-src.el @@ -665,7 +665,8 @@ Leave point in edit buffer." "Fontify code block between START and END using LANG's syntax. This function is called by Emacs's automatic fontification, as long as `org-src-fontify-natively' is non-nil." - (let ((modified (buffer-modified-p)) native-tab-width) + (let ((modified (buffer-modified-p)) + (native-tab-width tab-width)) (remove-text-properties start end '(face nil)) (let ((lang-mode (org-src-get-lang-mode lang))) (when (fboundp lang-mode) diff --git a/lisp/pcomplete.el b/lisp/pcomplete.el index 43d149d5c90..c3b7f9d52d3 100644 --- a/lisp/pcomplete.el +++ b/lisp/pcomplete.el @@ -1150,7 +1150,7 @@ Typing SPC flushes the help buffer." ((or (eq event 'tab) ;; Needed on a terminal (eq event 9)) - (let ((win (or (get-buffer-window "*Completions*" 0) + (let ((win (or (minibuffer--completions-visible) (display-buffer "*Completions*" 'not-this-window)))) (with-selected-window win diff --git a/lisp/play/doctor.el b/lisp/play/doctor.el index b3ddabf9823..0e75bd108eb 100644 --- a/lisp/play/doctor.el +++ b/lisp/play/doctor.el @@ -589,6 +589,7 @@ reads the sentence before point, and prints the Doctor's answer." (doctor-put-meaning pc 'mach) (doctor-put-meaning gnu 'mach) (doctor-put-meaning linux 'mach) +(doctor-put-meaning llm 'mach) (doctor-put-meaning bitching 'foul) (doctor-put-meaning shit 'foul) (doctor-put-meaning bastard 'foul) diff --git a/lisp/play/zone.el b/lisp/play/zone.el index 39a33f1e2a0..5f817c10371 100644 --- a/lisp/play/zone.el +++ b/lisp/play/zone.el @@ -433,8 +433,9 @@ run a specific program. The program must be a member of (defsubst zone-replace-char (count del-count char-as-string new-value) (delete-char (or del-count (- count))) - (aset char-as-string 0 new-value) - (dotimes (_ count) (insert char-as-string))) + (let ((s (apply #'propertize (string new-value) + (text-properties-at 0 char-as-string)))) + (dotimes (_ count) (insert s)))) (defsubst zone-park/sit-for (pos seconds) (let ((p (point))) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 5155193c603..174eb47cb3a 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -65,11 +65,9 @@ ;; ;; will turn on the c++-ts-mode for C++ source files. ;; -;; - If you have both C and C++ grammars installed, add -;; -;; (load "c-ts-mode") -;; -;; to your init file. +;; - If you have both C and C++ grammars installed, customize +;; 'treesit-enabled-modes' and select 'c-ts-mode', +;; 'c++-mode', 'c-or-c++-mode'. ;; ;; You can also turn on these modes manually in a buffer. Doing so ;; will set up Emacs to use the C/C++ modes defined here for other @@ -1675,21 +1673,15 @@ the code is C or C++, and based on that chooses whether to enable 'c-ts-mode))) (funcall (major-mode-remap mode)))) -(when (treesit-ready-p 'cpp) - (setq major-mode-remap-defaults - (assq-delete-all 'c++-mode major-mode-remap-defaults)) - (add-to-list 'major-mode-remap-defaults '(c++-mode . c++-ts-mode))) - -(when (treesit-ready-p 'c) - (setq major-mode-remap-defaults - (assq-delete-all 'c-mode major-mode-remap-defaults)) - (add-to-list 'major-mode-remap-defaults '(c-mode . c-ts-mode))) - -(when (and (treesit-ready-p 'cpp) - (treesit-ready-p 'c)) - (setq major-mode-remap-defaults - (assq-delete-all 'c-or-c++-mode major-mode-remap-defaults)) - (add-to-list 'major-mode-remap-defaults '(c-or-c++-mode . c-or-c++-ts-mode))) +;;;###autoload +(when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(c-mode . c-ts-mode)) + (add-to-list 'treesit-major-mode-remap-alist + '(c++-mode . c++-ts-mode)) + (add-to-list 'treesit-major-mode-remap-alist + '(c-or-c++-mode . c-or-c++-ts-mode))) (provide 'c-ts-mode) (provide 'c++-ts-mode) diff --git a/lisp/progmodes/cmake-ts-mode.el b/lisp/progmodes/cmake-ts-mode.el index 2f2d1b6e2a0..84589b1eb73 100644 --- a/lisp/progmodes/cmake-ts-mode.el +++ b/lisp/progmodes/cmake-ts-mode.el @@ -255,9 +255,26 @@ Return nil if there is no name or if NODE is not a defun node." (derived-mode-add-parents 'cmake-ts-mode '(cmake-mode)) -(if (treesit-ready-p 'cmake) - (add-to-list 'auto-mode-alist - '("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode))) +;;;###autoload +(defun cmake-ts-mode-maybe () + "Enable `cmake-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name." + (declare-function treesit-language-available-p "treesit.c") + (if (or (treesit-language-available-p 'cmake) + (eq treesit-enabled-modes t) + (memq 'cmake-ts-mode treesit-enabled-modes)) + (cmake-ts-mode) + (fundamental-mode))) + +;;;###autoload +(when (treesit-available-p) + (add-to-list 'auto-mode-alist + '("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode-maybe)) + ;; To be able to toggle between an external package and core ts-mode: + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(cmake-mode . cmake-ts-mode))) (provide 'cmake-ts-mode) diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index 8643b69ef83..23ff955f389 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el @@ -2726,6 +2726,7 @@ PARSE-DATA is used to save status between calls in a loop." (if (listp indent) (setq indent (car indent))) (cond ((and (looking-at (rx (sequence (eval cperl--label-rx) (not (in ":"))))) + (null (get-text-property (point) 'syntax-type)) (not (looking-at (rx (eval cperl--false-label-rx))))) (and (> indent 0) (setq indent (max cperl-min-label-indent @@ -2766,7 +2767,7 @@ PARSE-DATA is used to save status between calls in a loop." START is a good place to start parsing, or equal to PARSE-START if preset. STATE is what is returned by `parse-partial-sexp'. -DEPTH is true is we are immediately after end of block +DEPTH is true if we are immediately after end of block which contains START. PRESTART is the position basing on which START was found. START-STATE should be a good guess for the start of a function." @@ -2775,7 +2776,7 @@ START-STATE should be a good guess for the start of a function." (if (and parse-start (<= parse-start start-point)) (goto-char parse-start) - (beginning-of-defun) + (beginning-of-defun-raw) (when (cperl-declaration-header-p (point)) (goto-char (cperl-beginning-of-property (point) 'syntax-type)) (beginning-of-line)) @@ -5064,7 +5065,7 @@ recursive calls in starting lines of here-documents." (cperl-postpone-fontification (- (point) 2) (- (point) 1) 'face (if (memq qtag - (append "ghijkmoqvFHIJKMORTVY" nil)) + (append "gijkmoqFIJKMOTY" nil)) 'font-lock-warning-face my-cperl-REx-0length-face)) (if (and (eq (char-after b) qtag) @@ -6374,9 +6375,7 @@ functions (which they are not). Inherits from `default'.") (sequence (eval cperl--signature-rx) (eval cperl--ws*-rx)) ;; ... or the start of a "sloppy" signature - (sequence (eval cperl--sloppy-signature-rx) - ;; arbitrarily continue "a few lines" - (repeat 0 200 (not (in "{")))) + (sequence (eval cperl--sloppy-signature-rx)) ;; make sure we have a reasonably ;; short match for an incomplete sub (not (in ";{(")) @@ -6392,7 +6391,13 @@ functions (which they are not). Inherits from `default'.") (group (eval cperl--basic-variable-rx)))) (progn (goto-char (match-beginning 2)) ; pre-match: Back to sig - (match-end 2)) + ;; While typing, forward-sexp might fail with a scan error. + ;; If so, stop looking for declarations at (match-end 2) + (condition-case nil + (save-excursion + (forward-sexp) + (point)) + (error (match-end 2)))) nil (1 font-lock-variable-name-face))) ;; -------- flow control diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index 958ccf05672..2ef97ccc687 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -1219,12 +1219,16 @@ Key bindings: "local_function_statement") eos)) - (treesit-major-mode-setup) - - (add-to-list 'auto-mode-alist '("\\.cs\\'" . csharp-ts-mode))) + (treesit-major-mode-setup)) (derived-mode-add-parents 'csharp-ts-mode '(csharp-mode)) +;;;###autoload +(when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(csharp-mode . csharp-ts-mode))) + (provide 'csharp-mode) ;;; csharp-mode.el ends here diff --git a/lisp/progmodes/dockerfile-ts-mode.el b/lisp/progmodes/dockerfile-ts-mode.el index fe0c9e23acc..40259792b52 100644 --- a/lisp/progmodes/dockerfile-ts-mode.el +++ b/lisp/progmodes/dockerfile-ts-mode.el @@ -202,11 +202,28 @@ Return nil if there is no name or if NODE is not a stage node." (derived-mode-add-parents 'dockerfile-ts-mode '(dockerfile-mode)) -(if (treesit-ready-p 'dockerfile) - (add-to-list 'auto-mode-alist - ;; NOTE: We can't use `rx' here, as it breaks bootstrap. - '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)\\'" - . dockerfile-ts-mode))) +;;;###autoload +(defun dockerfile-ts-mode-maybe () + "Enable `dockerfile-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name." + (declare-function treesit-language-available-p "treesit.c") + (if (or (treesit-language-available-p 'dockerfile) + (eq treesit-enabled-modes t) + (memq 'dockerfile-ts-mode treesit-enabled-modes)) + (dockerfile-ts-mode) + (fundamental-mode))) + +;;;###autoload +(when (treesit-available-p) + (add-to-list 'auto-mode-alist + ;; NOTE: We can't use `rx' here, as it breaks bootstrap. + '("\\(?:Dockerfile\\(?:\\..*\\)?\\|\\.[Dd]ockerfile\\)\\'" + . dockerfile-ts-mode-maybe)) + ;; To be able to toggle between an external package and core ts-mode: + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(dockerfile-mode . dockerfile-ts-mode))) (provide 'dockerfile-ts-mode) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 4a7c525003c..29e6c269fdf 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -2242,7 +2242,7 @@ Use `eglot-managed-p' to determine if current buffer is managed.") (when (and eglot-autoshutdown (null (eglot--managed-buffers server)) ;; Don't shutdown if up again soon. - (not revert-buffer-in-progress-p)) + (with-no-warnings (not revert-buffer-in-progress-p))) (eglot-shutdown server))))))) (defun eglot--managed-mode-off () diff --git a/lisp/progmodes/elixir-ts-mode.el b/lisp/progmodes/elixir-ts-mode.el index 8b43c032424..04227599630 100644 --- a/lisp/progmodes/elixir-ts-mode.el +++ b/lisp/progmodes/elixir-ts-mode.el @@ -806,12 +806,28 @@ Return nil if NODE is not a defun node or doesn't have a name." (derived-mode-add-parents 'elixir-ts-mode '(elixir-mode)) -(if (treesit-ready-p 'elixir) - (progn - (add-to-list 'auto-mode-alist '("\\.elixir\\'" . elixir-ts-mode)) - (add-to-list 'auto-mode-alist '("\\.ex\\'" . elixir-ts-mode)) - (add-to-list 'auto-mode-alist '("\\.exs\\'" . elixir-ts-mode)) - (add-to-list 'auto-mode-alist '("mix\\.lock" . elixir-ts-mode)))) +;;;###autoload +(defun elixir-ts-mode-maybe () + "Enable `elixir-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name." + (declare-function treesit-language-available-p "treesit.c") + (if (or (treesit-language-available-p 'elixir) + (eq treesit-enabled-modes t) + (memq 'elixir-ts-mode treesit-enabled-modes)) + (elixir-ts-mode) + (fundamental-mode))) + +;;;###autoload +(when (treesit-available-p) + (add-to-list 'auto-mode-alist '("\\.elixir\\'" . elixir-ts-mode-maybe)) + (add-to-list 'auto-mode-alist '("\\.ex\\'" . elixir-ts-mode-maybe)) + (add-to-list 'auto-mode-alist '("\\.exs\\'" . elixir-ts-mode-maybe)) + (add-to-list 'auto-mode-alist '("mix\\.lock" . elixir-ts-mode-maybe)) + ;; To be able to toggle between an external package and core ts-mode: + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(elixir-mode . elixir-ts-mode))) (provide 'elixir-ts-mode) diff --git a/lisp/progmodes/executable.el b/lisp/progmodes/executable.el index b003b75b0e4..aa3a74d30fa 100644 --- a/lisp/progmodes/executable.el +++ b/lisp/progmodes/executable.el @@ -180,7 +180,7 @@ command to find the next error. The buffer is also in `comint-mode' and `compilation-shell-minor-mode', so that you can answer any prompts." (interactive (list (read-string "Run script: " (or executable-command - buffer-file-name)))) + (file-local-name buffer-file-name))))) (require 'compile) (save-some-buffers (not compilation-ask-about-save)) (setq-local executable-command command) diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index e911faf603d..8b6d477c385 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -195,8 +195,6 @@ margins). Difference between fringes and margin is that fringes support displaying bitmaps on graphical displays and margins display text in a blank area from current buffer that works in both graphical and text displays. -Thus, even when `fringes' is selected, margins will still be used on -text displays and also when fringes are disabled. See Info node `Fringes' and Info node `(elisp)Display Margins'." :version "31.1" @@ -1172,6 +1170,13 @@ report applies to that region." (flymake--state-foreign-diags state)) (clrhash (flymake--state-foreign-diags state))) +(defun flymake--clear-state (state) + (cl-loop for diag in (flymake--state-diags state) + for ov = (flymake--diag-overlay diag) + when ov do (flymake--delete-overlay ov)) + (setf (flymake--state-diags state) nil) + (flymake--clear-foreign-diags state)) + (defvar-local flymake-mode nil) (defvar-local flymake--mode-line-counter-cache nil @@ -1189,7 +1194,7 @@ and other buffers." ;; (cond (;; If there is a `region' arg, only affect the diagnostics whose - ;; overlays are in a certain region. Discard "foreign" + ;; overlays are in a certain region. Ignore "foreign" ;; diagnostics. region (cl-loop for diag in (flymake--state-diags state) @@ -1202,16 +1207,9 @@ and other buffers." else collect diag into surviving finally (setf (flymake--state-diags state) surviving))) - (;; Else, if this is the first report, zero all lists and delete - ;; all associated overlays. + (;; Else, if this is the first report, fully clear this state. (not (flymake--state-reported-p state)) - (cl-loop for diag in (flymake--state-diags state) - for ov = (flymake--diag-overlay diag) - when ov do (flymake--delete-overlay ov)) - (setf (flymake--state-diags state) nil) - ;; Also clear all overlays for `foreign-diags' in all other - ;; buffers. - (flymake--clear-foreign-diags state)) + (flymake--clear-state state)) (;; If this is not the first report, do no cleanup. t)) @@ -1406,6 +1404,17 @@ Interactively, with a prefix arg, FORCE is t." (cl-reduce #'max (mapcar #'cadr flymake--recent-changes)))))) (setq flymake--recent-changes nil) + ;; Delete all overlays that didn't come from one of the + ;; current diagnostic functions. + ;; Sometimes diagnostic functions are removed from + ;; `flymake-diagnostic-functions' (e.g. by eglot). This + ;; leaves overlays in the buffer which otherwise won't be + ;; cleaned up until `flymake-mode' is restarted. + ;; See bug#78862 + (maphash (lambda (backend state) + (unless (memq backend flymake-diagnostic-functions) + (flymake--clear-state state))) + flymake--state) (run-hook-wrapped 'flymake-diagnostic-functions (lambda (backend) @@ -1485,13 +1494,6 @@ special *Flymake log* buffer." :group 'flymake :lighter (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t) (add-hook 'eldoc-documentation-functions 'flymake-eldoc-function t t) - (when (and (eq flymake-indicator-type 'fringes) - (not (cl-case flymake-fringe-indicator-position - (left-fringe (< 0 (nth 0 (window-fringes)))) - (right-fringe (< 0 (nth 1 (window-fringes))))))) - ;; There are no fringes in the buffer, fallback to margins. - (setq-local flymake-indicator-type 'margins)) - ;; AutoResize margins. (flymake--resize-margins) diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index e8e4c9af29d..e149e9230ec 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -359,10 +359,25 @@ (derived-mode-add-parents 'go-ts-mode '(go-mode)) -(if (treesit-ready-p 'go) - ;; FIXME: Should we instead put `go-mode' in `auto-mode-alist' - ;; and then use `major-mode-remap-defaults' to map it to `go-ts-mode'? - (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode))) +;;;###autoload +(defun go-ts-mode-maybe () + "Enable `go-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name." + (declare-function treesit-language-available-p "treesit.c") + (if (or (treesit-language-available-p 'go) + (eq treesit-enabled-modes t) + (memq 'go-ts-mode treesit-enabled-modes)) + (go-ts-mode) + (fundamental-mode))) + +;;;###autoload +(when (treesit-available-p) + (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode-maybe)) + ;; To be able to toggle between an external package and core ts-mode: + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(go-mode . go-ts-mode))) (defun go-ts-mode--defun-name (node &optional skip-prefix) "Return the defun name of NODE. @@ -622,8 +637,25 @@ what the parent of the node would be if it were a node." (derived-mode-add-parents 'go-mod-ts-mode '(go-mod-mode)) -(if (treesit-ready-p 'gomod t) - (add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode))) +;;;###autoload +(defun go-mod-ts-mode-maybe () + "Enable `go-mod-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name." + (declare-function treesit-language-available-p "treesit.c") + (if (or (treesit-language-available-p 'gomod) + (eq treesit-enabled-modes t) + (memq 'go-mod-ts-mode treesit-enabled-modes)) + (go-mod-ts-mode) + (fundamental-mode))) + +;;;###autoload +(when (treesit-available-p) + (add-to-list 'auto-mode-alist '("/go\\.mod\\'" . go-mod-ts-mode-maybe)) + ;; To be able to toggle between an external package and core ts-mode: + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(go-mod-mode . go-mod-ts-mode))) ;;;; go.work support. @@ -711,7 +743,24 @@ what the parent of the node would be if it were a node." (treesit-major-mode-setup))) ;;;###autoload -(add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode)) +(defun go-work-ts-mode-maybe () + "Enable `go-work-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name." + (declare-function treesit-language-available-p "treesit.c") + (if (or (treesit-language-available-p 'gowork) + (eq treesit-enabled-modes t) + (memq 'go-work-ts-mode treesit-enabled-modes)) + (go-work-ts-mode) + (fundamental-mode))) + +;;;###autoload +(when (treesit-available-p) + (add-to-list 'auto-mode-alist '("/go\\.work\\'" . go-work-ts-mode-maybe)) + ;; To be able to toggle between an external package and core ts-mode: + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(go-work-mode . go-work-ts-mode))) (provide 'go-ts-mode) diff --git a/lisp/progmodes/heex-ts-mode.el b/lisp/progmodes/heex-ts-mode.el index c478750a73e..2b8b75c444e 100644 --- a/lisp/progmodes/heex-ts-mode.el +++ b/lisp/progmodes/heex-ts-mode.el @@ -265,10 +265,27 @@ Return nil if NODE is not a defun node or doesn't have a name." (derived-mode-add-parents 'heex-ts-mode '(heex-mode)) -(if (treesit-ready-p 'heex) - ;; Both .heex and the deprecated .leex files should work - ;; with the tree-sitter-heex grammar. - (add-to-list 'auto-mode-alist '("\\.[hl]?eex\\'" . heex-ts-mode))) +;;;###autoload +(defun heex-ts-mode-maybe () + "Enable `heex-ts-mode' when its grammar is available. +Also propose to install the grammar when `treesit-enabled-modes' +is t or contains the mode name." + (declare-function treesit-language-available-p "treesit.c") + (if (or (treesit-language-available-p 'heex) + (eq treesit-enabled-modes t) + (memq 'heex-ts-mode treesit-enabled-modes)) + (heex-ts-mode) + (fundamental-mode))) + +;;;###autoload +(when (treesit-available-p) + ;; Both .heex and the deprecated .leex files should work + ;; with the tree-sitter-heex grammar. + (add-to-list 'auto-mode-alist '("\\.[hl]?eex\\'" . heex-ts-mode-maybe)) + ;; To be able to toggle between an external package and core ts-mode: + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(heex-mode . heex-ts-mode))) (provide 'heex-ts-mode) ;;; heex-ts-mode.el ends here diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index 0fe35a4df8b..979f5456c6d 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -524,8 +524,11 @@ Return nil if there is no name or if NODE is not a defun node." (derived-mode-add-parents 'java-ts-mode '(java-mode)) -(if (treesit-ready-p 'java) - (add-to-list 'auto-mode-alist '("\\.java\\'" . java-ts-mode))) +;;;###autoload +(when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(java-mode . java-ts-mode))) (provide 'java-ts-mode) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index bed2ef0616a..1e4c832254c 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -4105,13 +4105,16 @@ See `treesit-thing-settings' for more information.") ;; Outline minor mode (setq-local treesit-outline-predicate js-ts-mode--outline-predicate) - (treesit-major-mode-setup) - - (add-to-list 'auto-mode-alist - '("\\(\\.js[mx]?\\|\\.har\\)\\'" . js-ts-mode)))) + (treesit-major-mode-setup))) (derived-mode-add-parents 'js-ts-mode '(js-mode)) +;;;###autoload +(when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(javascript-mode . js-ts-mode))) + (defvar js-ts--s-p-query (when (treesit-available-p) (treesit-query-compile 'javascript @@ -4142,6 +4145,7 @@ See `treesit-thing-settings' for more information.") :syntax-table js-mode-syntax-table (js--mode-setup) ;Reuse most of `js-mode', but not as parent (bug#67463). (setq-local js-enabled-frameworks nil) + (setq-local editorconfig-indent-size-vars '(js-indent-level)) ;; Speed up `syntax-ppss': JSON files can be big but can't hold ;; regexp matchers nor #! thingies (and `js-enabled-frameworks' is nil). (setq-local syntax-propertize-function #'ignore)) diff --git a/lisp/progmodes/json-ts-mode.el b/lisp/progmodes/json-ts-mode.el index a18f3c342c0..a08e9a29fe8 100644 --- a/lisp/progmodes/json-ts-mode.el +++ b/lisp/progmodes/json-ts-mode.el @@ -181,9 +181,11 @@ Return nil if there is no name or if NODE is not a defun node." (derived-mode-add-parents 'json-ts-mode '(json-mode)) -(if (treesit-ready-p 'json) - (add-to-list 'auto-mode-alist - '("\\.json\\'" . json-ts-mode))) +;;;###autoload +(when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) + (add-to-list 'treesit-major-mode-remap-alist + '(js-json-mode . json-ts-mode))) (provide 'json-ts-mode) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index 5e58d4c071d..5089e17c287 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -74,6 +74,11 @@ :safe 'natnump :version "30.1") +(defcustom lua-ts-auto-close-block-comments nil + "If non-nil, inserting a block comment \"--[[\" will insert its respective \"]]\"." + :type 'boolean + :version "31.1") + (defcustom lua-ts-luacheck-program "luacheck" "Location of the Luacheck program." :type 'file @@ -675,6 +680,14 @@ Calls REPORT-FN directly." (setq-local comment-start-skip "--\\s-*") (setq-local comment-end "") + ;; Pairs. + (when (and lua-ts-auto-close-block-comments + (boundp 'electric-pair-pairs)) + (setq-local electric-pair-pairs + (cons + '("--\\[\\[" . "\n]") + electric-pair-pairs))) + ;; Font-lock. (setq-local treesit-font-lock-settings lua-ts--font-lock-settings) (setq-local treesit-font-lock-feature-list @@ -756,9 +769,26 @@ Calls REPORT-FN directly." (derived-mode-add-parents 'lua-ts-mode '(lua-mode)) -(when (treesit-ready-p 'lua) - (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-ts-mode)) - (add-to-list 'interpreter-mode-alist '("\\ and