commit bf652e6844601bb42daaac2ed867e047f2eb615f (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Mon Aug 18 09:49:36 2025 +0300 Silence byte-compile warnings when treesit is not available * lisp/progmodes/c-ts-mode.el: * lisp/progmodes/cmake-ts-mode.el: * lisp/progmodes/csharp-mode.el: * lisp/progmodes/dockerfile-ts-mode.el: * lisp/progmodes/elixir-ts-mode.el: * lisp/progmodes/go-ts-mode.el: * lisp/progmodes/heex-ts-mode.el: * lisp/progmodes/java-ts-mode.el: * lisp/progmodes/js.el: * lisp/progmodes/json-ts-mode.el: * lisp/progmodes/lua-ts-mode.el: * lisp/progmodes/php-ts-mode.el: * lisp/progmodes/ruby-ts-mode.el: * lisp/progmodes/rust-ts-mode.el: * lisp/progmodes/sh-script.el: * lisp/progmodes/typescript-ts-mode.el: * lisp/textmodes/css-mode.el: * lisp/textmodes/markdown-ts-mode.el: * lisp/textmodes/mhtml-ts-mode.el: * lisp/textmodes/toml-ts-mode.el: * lisp/textmodes/yaml-ts-mode.el: Declare 'treesit-major-mode-remap-alist' and 'treesit-language-available-p' to silence warnings that are false alarms. Also improve docstrings. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 55240c3869a..174eb47cb3a 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -1675,6 +1675,7 @@ the code is C or C++, and based on that chooses whether to enable ;;;###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 diff --git a/lisp/progmodes/cmake-ts-mode.el b/lisp/progmodes/cmake-ts-mode.el index 3f879e37ba2..84589b1eb73 100644 --- a/lisp/progmodes/cmake-ts-mode.el +++ b/lisp/progmodes/cmake-ts-mode.el @@ -257,7 +257,10 @@ Return nil if there is no name or if NODE is not a defun node." ;;;###autoload (defun cmake-ts-mode-maybe () - "Enable `cmake-ts-mode' when its grammar is available." + "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)) @@ -269,6 +272,7 @@ Return nil if there is no name or if NODE is not a defun node." (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))) diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el index fb05389ba91..2ef97ccc687 100644 --- a/lisp/progmodes/csharp-mode.el +++ b/lisp/progmodes/csharp-mode.el @@ -1225,6 +1225,7 @@ Key bindings: ;;;###autoload (when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(csharp-mode . csharp-ts-mode))) diff --git a/lisp/progmodes/dockerfile-ts-mode.el b/lisp/progmodes/dockerfile-ts-mode.el index 79a2197c078..40259792b52 100644 --- a/lisp/progmodes/dockerfile-ts-mode.el +++ b/lisp/progmodes/dockerfile-ts-mode.el @@ -204,7 +204,10 @@ Return nil if there is no name or if NODE is not a stage node." ;;;###autoload (defun dockerfile-ts-mode-maybe () - "Enable `dockerfile-ts-mode' when its grammar is available." + "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)) @@ -218,6 +221,7 @@ Return nil if there is no name or if NODE is not a stage node." '("\\(?: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))) diff --git a/lisp/progmodes/elixir-ts-mode.el b/lisp/progmodes/elixir-ts-mode.el index 05ad76d100f..04227599630 100644 --- a/lisp/progmodes/elixir-ts-mode.el +++ b/lisp/progmodes/elixir-ts-mode.el @@ -808,7 +808,10 @@ Return nil if NODE is not a defun node or doesn't have a name." ;;;###autoload (defun elixir-ts-mode-maybe () - "Enable `elixir-ts-mode' when its grammar is available." + "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)) @@ -822,6 +825,7 @@ Return nil if NODE is not a defun node or doesn't have a name." (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))) diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 40f3de0bc15..e149e9230ec 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -361,7 +361,10 @@ ;;;###autoload (defun go-ts-mode-maybe () - "Enable `go-ts-mode' when its grammar is available." + "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)) @@ -372,6 +375,7 @@ (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))) @@ -635,7 +639,10 @@ what the parent of the node would be if it were a node." ;;;###autoload (defun go-mod-ts-mode-maybe () - "Enable `go-mod-ts-mode' when its grammar is available." + "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)) @@ -646,6 +653,7 @@ what the parent of the node would be if it were a node." (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))) @@ -736,7 +744,10 @@ what the parent of the node would be if it were a node." ;;;###autoload (defun go-work-ts-mode-maybe () - "Enable `go-work-ts-mode' when its grammar is available." + "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)) @@ -747,6 +758,7 @@ what the parent of the node would be if it were a node." (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))) diff --git a/lisp/progmodes/heex-ts-mode.el b/lisp/progmodes/heex-ts-mode.el index 41634d0e6a4..2b8b75c444e 100644 --- a/lisp/progmodes/heex-ts-mode.el +++ b/lisp/progmodes/heex-ts-mode.el @@ -267,7 +267,10 @@ Return nil if NODE is not a defun node or doesn't have a name." ;;;###autoload (defun heex-ts-mode-maybe () - "Enable `heex-ts-mode' when its grammar is available." + "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)) @@ -280,6 +283,7 @@ Return nil if NODE is not a defun node or doesn't have a name." ;; 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))) diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el index e989d1b3f5d..979f5456c6d 100644 --- a/lisp/progmodes/java-ts-mode.el +++ b/lisp/progmodes/java-ts-mode.el @@ -526,6 +526,7 @@ Return nil if there is no name or if NODE is not a defun node." ;;;###autoload (when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(java-mode . java-ts-mode))) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index c44b2adf146..1e4c832254c 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -4111,6 +4111,7 @@ See `treesit-thing-settings' for more information.") ;;;###autoload (when (treesit-available-p) + (defvar treesit-major-mode-remap-alist) (add-to-list 'treesit-major-mode-remap-alist '(javascript-mode . js-ts-mode))) diff --git a/lisp/progmodes/json-ts-mode.el b/lisp/progmodes/json-ts-mode.el index b0db0a12210..a08e9a29fe8 100644 --- a/lisp/progmodes/json-ts-mode.el +++ b/lisp/progmodes/json-ts-mode.el @@ -183,6 +183,7 @@ Return nil if there is no name or if NODE is not a defun node." ;;;###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))) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index 07a8f0aef55..5089e17c287 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -771,7 +771,10 @@ Calls REPORT-FN directly." ;;;###autoload (defun lua-ts-mode-maybe () - "Enable `lua-ts-mode' when its grammar is available." + "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." + (declare-function treesit-language-available-p "treesit.c") (if (or (treesit-language-available-p 'lua) (eq treesit-enabled-modes t) (memq 'lua-ts-mode treesit-enabled-modes)) @@ -783,6 +786,7 @@ Calls REPORT-FN directly." (add-to-list 'auto-mode-alist '("\\.lua\\'" . lua-ts-mode-maybe)) (add-to-list 'interpreter-mode-alist '("\\ Date: Sun Aug 17 16:48:35 2025 +0200 Reject invalid error symbols (Bug#76447) * src/eval.c (signal_or_quit): Signal an error if 'signal' gets called with an invalid error symbol. diff --git a/src/eval.c b/src/eval.c index 0d4ae91136e..2dc14b6d431 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1948,6 +1948,8 @@ signal_or_quit (Lisp_Object error_symbol, Lisp_Object data, bool continuable) } conditions = Fget (real_error_symbol, Qerror_conditions); + if (NILP (conditions)) + signal_error ("Invalid error symbol", error_symbol); /* Remember from where signal was called. Skip over the frame for `signal' itself. If a frame for `error' follows, skip that, commit 1f4e2e82649bb2a122b1406caf645ea06a933dc6 Author: JD Smith <93749+jdtsmith@users.noreply.github.com> Date: Sun Aug 10 17:17:47 2025 -0400 Adapt tramp to new autoload-macro expand Bug #78995. * lisp/net/tramp-compat.el (tramp-loaddefs): suppress error on requiring tramp-loaddef. * lisp/net/tramp.el (tramp--with-startup): declare autoload-macro expand, and suppress warnings about this declare form on older versions of Emacs. 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.el b/lisp/net/tramp.el index 503b370cb3d..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 commit da3973b657db46501e650fb4af4a4f3bb07c77fd Author: Sean Whitton Date: Sun Aug 17 11:36:13 2025 +0100 VC: New commands for incoming and outgoing fileset diffs * lisp/vc/vc.el (vc-fileset-diff-incoming) (vc-fileset-diff-outgoing): New commands. (vc-root-diff-incoming): Refactor to call vc-fileset-diff-incoming. (vc-root-diff-outgoing): Refactor to call vc-fileset-diff-outgoing. * lisp/vc/vc-hooks.el (vc-incoming-prefix-map) (vc-outgoing-prefix-map): Bind the new commands. * doc/emacs/maintaining.texi (VC Change Log): * etc/NEWS: Document the new commands. diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index ffa3b7f2a58..4e531805f26 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-fileset-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-fileset-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,22 @@ 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-fileset-diff-incoming +@findex vc-fileset-diff-outgoing + The commands @code{vc-fileset-diff-incoming} and +@code{vc-fileset-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/etc/NEWS b/etc/NEWS index 4a193484591..ebf03b53e12 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2131,15 +2131,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-fileset-diff-incoming' and 'vc-fileset-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 diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index 7d46f9f0ee3..e3b2d207156 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -976,9 +976,11 @@ In the latter case, VC mode is deactivated for this buffer." (defvar-keymap vc-incoming-prefix-map "L" #'vc-log-incoming + "=" #'vc-fileset-diff-incoming "D" #'vc-root-diff-incoming) (defvar-keymap vc-outgoing-prefix-map "L" #'vc-log-outgoing + "=" #'vc-fileset-diff-outgoing "D" #'vc-root-diff-outgoing) (defcustom vc-use-incoming-outgoing-prefixes nil diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 73f4f5d6f1d..6f8985dc0c9 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2546,12 +2546,27 @@ See `vc-use-incoming-outgoing-prefixes' regarding giving this command a global binding." (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-diff" - (let ((incoming (vc--incoming-revision backend - (or remote-location "")))) - (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) - (vc-call-backend backend 'mergebase incoming) - incoming - (called-interactively-p 'interactive))))) + (vc-fileset-diff-incoming remote-location `(,backend (,rootdir))))) + +;;;###autoload +(defun vc-fileset-diff-incoming (&optional remote-location fileset) + "Report changes to VC fileset that would be pulled from REMOTE-LOCATION. +When unspecified REMOTE-LOCATION is the place \\[vc-update] would pull from. +When called interactively with a prefix argument, prompt for REMOTE-LOCATION. +In some version control systems REMOTE-LOCATION can be a remote branch name. +When called from Lisp optional argument FILESET overrides the VC fileset. + +See `vc-use-incoming-outgoing-prefixes' regarding giving this command a +global binding." + (interactive (list (vc--maybe-read-remote-location) nil)) + (let* ((fileset (or fileset (vc-deduce-fileset t))) + (backend (car fileset)) + (incoming (vc--incoming-revision backend + (or remote-location "")))) + (vc-diff-internal vc-allow-async-diff fileset + (vc-call-backend backend 'mergebase incoming) + incoming + (called-interactively-p 'interactive)))) ;;;###autoload (defun vc-root-diff-outgoing (&optional remote-location) @@ -2560,6 +2575,20 @@ When unspecified REMOTE-LOCATION is the place \\[vc-push] would push to. When called interactively with a prefix argument, prompt for REMOTE-LOCATION. In some version control systems REMOTE-LOCATION can be a remote branch name. +See `vc-use-incoming-outgoing-prefixes' regarding giving this command a +global binding." + (interactive (list (vc--maybe-read-remote-location))) + (vc--with-backend-in-rootdir "VC root-diff" + (vc-fileset-diff-outgoing remote-location `(,backend (,rootdir))))) + +;;;###autoload +(defun vc-fileset-diff-outgoing (&optional remote-location fileset) + "Report changes to VC fileset that would be pushed to REMOTE-LOCATION. +When unspecified REMOTE-LOCATION is the place \\[vc-push] would push to. +When called interactively with a prefix argument, prompt for REMOTE-LOCATION. +In some version control systems REMOTE-LOCATION can be a remote branch name. +When called from Lisp optional argument FILESET overrides the VC fileset. + See `vc-use-incoming-outgoing-prefixes' regarding giving this command a global binding." ;; For this command, for distributed VCS, we want to ignore @@ -2568,36 +2597,37 @@ global binding." ;; changes and remote committed changes. ;; (Hence why we don't call `vc-buffer-sync-fileset'.) (interactive (list (vc--maybe-read-remote-location))) - (vc--with-backend-in-rootdir "VC root-diff" - (let ((incoming (vc--incoming-revision backend - (or remote-location "")))) - (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) - (vc-call-backend backend 'mergebase incoming) - ;; FIXME: In order to exclude uncommitted - ;; changes we need to pass the most recent - ;; revision as REV2. Calling `working-revision' - ;; like this works for all the backends we have - ;; in core that implement `mergebase' and so can - ;; be used with this command (Git and Hg). - ;; However, it is not clearly permitted by the - ;; current semantics of `working-revision' to - ;; call it on a directory. - ;; - ;; A possible alternative would be something - ;; like this which effectively falls back to - ;; including uncommitted changes in the case of - ;; an older VCS or where the backend rejects our - ;; attempt to call `working-revision' on a - ;; directory: - ;; (and (eq (vc-call-backend backend - ;; 'revision-granularity) - ;; 'repository) - ;; (ignore-errors - ;; (vc-call-backend backend 'working-revision - ;; rootdir))) - (vc-call-backend backend 'working-revision - rootdir) - (called-interactively-p 'interactive))))) + (let* ((fileset (or fileset (vc-deduce-fileset t))) + (backend (car fileset)) + (incoming (vc--incoming-revision backend + (or remote-location "")))) + (vc-diff-internal vc-allow-async-diff fileset + (vc-call-backend backend 'mergebase incoming) + ;; FIXME: In order to exclude uncommitted + ;; changes we need to pass the most recent + ;; revision as REV2. Calling `working-revision' + ;; like this works for all the backends we have + ;; in core that implement `mergebase' and so can + ;; be used with this command (Git and Hg). + ;; However, it is not clearly permitted by the + ;; current semantics of `working-revision' to + ;; call it on a directory. + ;; + ;; A possible alternative would be something + ;; like this which effectively falls back to + ;; including uncommitted changes in the case of + ;; an older VCS or where the backend rejects our + ;; attempt to call `working-revision' on a + ;; directory: + ;; (and (eq (vc-call-backend backend + ;; 'revision-granularity) + ;; 'repository) + ;; (ignore-errors + ;; (vc-call-backend backend 'working-revision + ;; (car fileset))) + (vc-call-backend backend 'working-revision + (car fileset)) + (called-interactively-p 'interactive)))) (declare-function ediff-load-version-control "ediff" (&optional silent)) (declare-function ediff-vc-internal "ediff-vers" commit 70b5ad0192b2dd6232c1961b49e94a6620d02152 Author: Sean Whitton Date: Sun Aug 17 11:10:14 2025 +0100 Delete duplicate bindings of default-directory * lisp/vc/vc.el (vc-root-version-diff, vc-diff-mergebase) (vc-root-diff-incoming, vc-root-diff-outgoing, vc-root-diff): Delete duplicate bindings of default-directory. vc--with-backend-in-rootdir already establishes bindings. diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 8543b14c2a2..73f4f5d6f1d 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2456,9 +2456,8 @@ state of each file in the fileset." (when (and (not rev1) rev2) (error "Not a valid revision range")) (vc--with-backend-in-rootdir "VC root-diff" - (let ((default-directory rootdir)) - (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) rev1 rev2 - (called-interactively-p 'interactive))))) + (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) rev1 rev2 + (called-interactively-p 'interactive)))) ;;;###autoload (defun vc-diff (&optional historic not-essential fileset) @@ -2531,8 +2530,7 @@ The merge base is a common ancestor between REV1 and REV2 revisions." (when (and (not rev1) rev2) (error "Not a valid revision range")) (vc--with-backend-in-rootdir "VC root-diff" - (let ((default-directory rootdir) - (rev1 (vc-call-backend backend 'mergebase rev1 rev2))) + (let ((rev1 (vc-call-backend backend 'mergebase rev1 rev2))) (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) rev1 rev2 (called-interactively-p 'interactive))))) @@ -2548,8 +2546,7 @@ See `vc-use-incoming-outgoing-prefixes' regarding giving this command a global binding." (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-diff" - (let ((default-directory rootdir) - (incoming (vc--incoming-revision backend + (let ((incoming (vc--incoming-revision backend (or remote-location "")))) (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) (vc-call-backend backend 'mergebase incoming) @@ -2572,8 +2569,7 @@ global binding." ;; (Hence why we don't call `vc-buffer-sync-fileset'.) (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-diff" - (let ((default-directory rootdir) - (incoming (vc--incoming-revision backend + (let ((incoming (vc--incoming-revision backend (or remote-location "")))) (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) (vc-call-backend backend 'mergebase incoming) @@ -2674,8 +2670,7 @@ saving the buffer." ;; relative to it. Bind default-directory to the root directory ;; here, this way the *vc-diff* buffer is setup correctly, so ;; relative file names work. - (let ((default-directory rootdir) - (fileset `(,backend (,rootdir)))) + (let ((fileset `(,backend (,rootdir)))) (vc-buffer-sync-fileset fileset not-essential) (vc-diff-internal vc-allow-async-diff fileset nil nil (called-interactively-p 'interactive)))))) commit 6f7e795ce1e5cf4e62c6260c4bde3545fc6d0f0d Author: Sean Whitton Date: Sun Aug 17 11:06:55 2025 +0100 vc--maybe-read-remote-location: Don't return a list * lisp/vc/vc.el (vc--maybe-read-remote-location): Return an atom. (vc-root-diff-incoming, vc-root-diff-outgoing, vc-log-incoming) (vc-log-outgoing): Wrap call to 'vc--maybe-read-remote-location' in a call to 'list'. diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 5d8c3f1eeb8..8543b14c2a2 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2546,7 +2546,7 @@ In some version control systems REMOTE-LOCATION can be a remote branch name. See `vc-use-incoming-outgoing-prefixes' regarding giving this command a global binding." - (interactive (vc--maybe-read-remote-location)) + (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-diff" (let ((default-directory rootdir) (incoming (vc--incoming-revision backend @@ -2570,7 +2570,7 @@ global binding." ;; for those VCS is to make a comparison between locally committed ;; changes and remote committed changes. ;; (Hence why we don't call `vc-buffer-sync-fileset'.) - (interactive (vc--maybe-read-remote-location)) + (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-diff" (let ((default-directory rootdir) (incoming (vc--incoming-revision backend @@ -3449,8 +3449,8 @@ The command prompts for the branch whose change log to show." (defun vc--maybe-read-remote-location () (and current-prefix-arg - (list (read-string "Remote location/branch (empty for default): " - 'vc-remote-location-history)))) + (read-string "Remote location/branch (empty for default): " + 'vc-remote-location-history))) (defun vc--incoming-revision (backend remote-location) (or (vc-call-backend backend 'incoming-revision remote-location) @@ -3462,7 +3462,7 @@ The command prompts for the branch whose change log to show." When unspecified REMOTE-LOCATION is the place \\[vc-update] would pull from. When called interactively with a prefix argument, prompt for REMOTE-LOCATION. In some version control systems REMOTE-LOCATION can be a remote branch name." - (interactive (vc--maybe-read-remote-location)) + (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-log" (vc-incoming-outgoing-internal backend (or remote-location "") "*vc-incoming*" 'log-incoming))) @@ -3480,7 +3480,7 @@ In some version control systems REMOTE-LOCATION can be a remote branch name." When unspecified REMOTE-LOCATION is the place \\[vc-push] would push to. When called interactively with a prefix argument, prompt for REMOTE-LOCATION. In some version control systems REMOTE-LOCATION can be a remote branch name." - (interactive (vc--maybe-read-remote-location)) + (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-log" (vc-incoming-outgoing-internal backend (or remote-location "") "*vc-outgoing*" 'log-outgoing))) commit 6979bce0b284d62db564647a7be941f8d4828e95 Author: Michael Albinus Date: Sun Aug 17 11:19:01 2025 +0200 Suppress Tramp session timeout if buffer is modified * doc/misc/tramp.texi (Predefined connection information): A session timeout is suppressed if there is a modified buffer, or a buffer under auto-revert. (Traces and Profiles): Tramp messages are written to the *Messages* buffer when level is less than or equal to 3. * lisp/net/tramp-sh.el (tramp-timeout-session): Do not timeout when buffer is modified, or in auto-revert mode. * test/lisp/net/tramp-tests.el (tramp-test48-session-timeout): Extend test. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 1dc616918d0..182323d0f25 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2376,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"} @@ -6834,7 +6836,8 @@ they are kept. Example: @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 diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 3c1f36fa8de..9d13cdc3a2d 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -5154,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 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 3 "Timeout session %s" (tramp-make-tramp-file-name vec 'noloc)) - (tramp-cleanup-connection vec 'keep-debug nil 'keep-processes))) + 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. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 4438e0090d4..58b5083b2c0 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -8471,7 +8471,37 @@ process sentinels. They shall not disturb each other." (cl-letf (((symbol-function #'ask-user-about-lock) #'always)) (save-buffer))) (should-not - (string-match-p "File is missing:" captured-messages)))))) + (string-match-p "File is missing:" captured-messages))))) + + ;; A modified buffer suppresses session timeout. + (with-temp-buffer + (set-visited-file-name tmp-name) + (insert "foo") + (should (buffer-modified-p)) + (tramp-timeout-session tramp-test-vec) + (should + (process-live-p (tramp-get-connection-process tramp-test-vec))) + ;; Steal the file lock. + (cl-letf (((symbol-function #'ask-user-about-lock) #'always)) + (save-buffer)) + (tramp-timeout-session tramp-test-vec) + (should-not + (process-live-p (tramp-get-connection-process tramp-test-vec)))) + + ;; An auto-reverted buffer suppresses session timeout. + (with-temp-buffer + (set-visited-file-name tmp-name) + (auto-revert-mode 1) + ;; Steal the file lock. + (cl-letf (((symbol-function #'ask-user-about-lock) #'always)) + (save-buffer)) + (tramp-timeout-session tramp-test-vec) + (should + (process-live-p (tramp-get-connection-process tramp-test-vec))) + (auto-revert-mode -1) + (tramp-timeout-session tramp-test-vec) + (should-not + (process-live-p (tramp-get-connection-process tramp-test-vec))))) ;; Cleanup. (ignore-errors (delete-file tmp-name)))))) commit 23b766b503a894ff58773b40e0d185bb40b9529e Author: Sean Whitton Date: Sat Aug 16 20:42:25 2025 +0100 ; Fix last change: change `let*' to `let'. diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 6c13e555836..550d13f9adc 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -1242,36 +1242,36 @@ It is an error to supply both or neither." (write-region (car args) nil msg-file)) (when patch-file (write-region patch-string nil patch-file))) - (let* ((coding-system-for-write - ;; On MS-Windows, we must encode command-line arguments in - ;; the system codepage. - (if (eq system-type 'windows-nt) - locale-coding-system - coding-system-for-write)) - (args - (nconc (if patch-file - (list "import" "--bypass" patch-file) - (list "commit" "-A")) - (if msg-file - (cl-list* "-l" (file-local-name msg-file) (cdr args)) - (cl-list* "-m" args)))) - (post (lambda () - (when (and msg-file (file-exists-p msg-file)) - (delete-file msg-file)) - (when (and patch-file (file-exists-p patch-file)) - (delete-file patch-file)) - ;; When committing a patch we run 'hg import' and - ;; then 'hg update'. We have 'hg update' here in the - ;; always-synchronous `post' function because we - ;; assume that 'hg import' is the one that might be - ;; slow and so benefits most from `vc-async-checkin'. - ;; If in fact both the 'hg import' and the 'hg - ;; update' can be slow, then we need to make both of - ;; them part of the async command, possibly by - ;; writing out a tiny shell script (bug#79235). - (when patch-file - (vc-hg-command nil 0 nil "update" "--merge" - "--tool" "internal:local" "tip"))))) + (let ((coding-system-for-write + ;; On MS-Windows, we must encode command-line arguments in + ;; the system codepage. + (if (eq system-type 'windows-nt) + locale-coding-system + coding-system-for-write)) + (args + (nconc (if patch-file + (list "import" "--bypass" patch-file) + (list "commit" "-A")) + (if msg-file + (cl-list* "-l" (file-local-name msg-file) (cdr args)) + (cl-list* "-m" args)))) + (post (lambda () + (when (and msg-file (file-exists-p msg-file)) + (delete-file msg-file)) + (when (and patch-file (file-exists-p patch-file)) + (delete-file patch-file)) + ;; When committing a patch we run 'hg import' and + ;; then 'hg update'. We have 'hg update' here in the + ;; always-synchronous `post' function because we + ;; assume that 'hg import' is the one that might be + ;; slow and so benefits most from `vc-async-checkin'. + ;; If in fact both the 'hg import' and the 'hg + ;; update' can be slow, then we need to make both of + ;; them part of the async command, possibly by + ;; writing out a tiny shell script (bug#79235). + (when patch-file + (vc-hg-command nil 0 nil "update" "--merge" + "--tool" "internal:local" "tip"))))) (if vc-async-checkin (let ((buffer (vc-hg--async-buffer))) (vc-wait-for-process-before-save commit 72022459a90bd68bc6ea4a821ca08ff713c23dd3 Author: Sean Whitton Date: Sat Aug 16 20:40:50 2025 +0100 vc-hg-checkin-patch: Fix on MS-Windows, make 'hg import' async * lisp/vc/vc-hg.el (vc-hg--checkin): New function to do the work of vc-hg-checkin and vc-hg-checkin-patch. (vc-hg-checkin): Replace body with call to vc-hg--checkin. (vc-hg-checkin-patch): Likewise. As compared with the old implementation, this change (i) fixes encoding issues when checking in patches on MS-Windows; and (ii) when vc-async-checkin is non-nil, runs 'hg import' asynchronously instead of running 'hg update' asynchronously (bug#79235). diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index b0e5a633566..6c13e555836 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -1213,11 +1213,18 @@ It is based on `log-edit-mode', and has Hg-specific extensions.") (defalias 'vc-hg-async-checkins #'always) -(defun vc-hg-checkin (files comment &optional _rev) - "Hg-specific version of `vc-BACKEND-checkin'. -REV is ignored." +(defun vc-hg--checkin (comment &optional files patch-string) + "Workhorse routine for `vc-hg-checkin' and `vc-hg-checkin-patch'. +COMMENT is the commit message. +For a regular checkin, FILES is the list of files to check in. +To check in a patch, PATCH-STRING is the patch text. +It is an error to supply both or neither." + (unless (xor files patch-string) + (error "Invalid call to `vc-hg--checkin'")) (let* ((args (vc-hg--extract-headers comment)) - (file1 (or (car files) default-directory)) + (temps-dir (or (file-name-directory (or (car files) + default-directory)) + default-directory)) (msg-file ;; On MS-Windows, pass the commit log message through a file, ;; to work around the limitation that command-line arguments @@ -1225,30 +1232,53 @@ REV is ignored." ;; support non-ASCII characters in the log message. ;; Also handle remote files. (and (eq system-type 'windows-nt) - (let ((default-directory (or (file-name-directory file1) - default-directory))) - (make-nearby-temp-file "hg-msg"))))) - (when msg-file - (let ((coding-system-for-write 'utf-8)) - (write-region (car args) nil msg-file))) - (let ((coding-system-for-write - ;; On MS-Windows, we must encode command-line arguments in - ;; the system codepage. - (if (eq system-type 'windows-nt) - locale-coding-system - coding-system-for-write)) - (args (if msg-file - (cl-list* "commit" "-A" "-l" (file-local-name msg-file) - (cdr args)) - (cl-list* "commit" "-A" "-m" args))) - (post (lambda () - (when (and msg-file (file-exists-p msg-file)) - (delete-file msg-file))))) + (let ((default-directory temps-dir)) + (make-nearby-temp-file "hg-msg")))) + (patch-file (and patch-string + (let ((default-directory temps-dir)) + (make-nearby-temp-file "hg-patch"))))) + (let ((coding-system-for-write 'utf-8)) + (when msg-file + (write-region (car args) nil msg-file)) + (when patch-file + (write-region patch-string nil patch-file))) + (let* ((coding-system-for-write + ;; On MS-Windows, we must encode command-line arguments in + ;; the system codepage. + (if (eq system-type 'windows-nt) + locale-coding-system + coding-system-for-write)) + (args + (nconc (if patch-file + (list "import" "--bypass" patch-file) + (list "commit" "-A")) + (if msg-file + (cl-list* "-l" (file-local-name msg-file) (cdr args)) + (cl-list* "-m" args)))) + (post (lambda () + (when (and msg-file (file-exists-p msg-file)) + (delete-file msg-file)) + (when (and patch-file (file-exists-p patch-file)) + (delete-file patch-file)) + ;; When committing a patch we run 'hg import' and + ;; then 'hg update'. We have 'hg update' here in the + ;; always-synchronous `post' function because we + ;; assume that 'hg import' is the one that might be + ;; slow and so benefits most from `vc-async-checkin'. + ;; If in fact both the 'hg import' and the 'hg + ;; update' can be slow, then we need to make both of + ;; them part of the async command, possibly by + ;; writing out a tiny shell script (bug#79235). + (when patch-file + (vc-hg-command nil 0 nil "update" "--merge" + "--tool" "internal:local" "tip"))))) (if vc-async-checkin (let ((buffer (vc-hg--async-buffer))) (vc-wait-for-process-before-save (apply #'vc-hg--async-command buffer (nconc args files)) - "Finishing checking in files...") + (if patch-file + "Finishing checking in patch...." + "Finishing checking in files...")) (with-current-buffer buffer (vc-run-delayed (vc-compilation-mode 'hg) @@ -1258,31 +1288,14 @@ REV is ignored." (apply #'vc-hg-command nil 0 files args) (funcall post))))) -;; FIXME: Needs MS-Windows encoding issues handling. -;; Possibly we want fix this by merging this function into the preceeding one. -;; Figure out resolution of #79235 first. +(defun vc-hg-checkin (files comment &optional _rev) + "Hg-specific version of `vc-BACKEND-checkin'. +REV is ignored." + (vc-hg--checkin comment files nil)) + (defun vc-hg-checkin-patch (patch-string comment) - (let ((patch-file (make-nearby-temp-file "hg-patch"))) - (write-region patch-string nil patch-file) - (unwind-protect - (let ((args (list "update" - "--merge" "--tool" "internal:local" - "tip"))) - (apply #'vc-hg-command nil 0 nil - (nconc (list "import" "--bypass" patch-file "-m") - (vc-hg--extract-headers comment))) - (if vc-async-checkin - (let ((buffer (vc-hg--async-buffer))) - (vc-wait-for-process-before-save - (apply #'vc-hg--async-command buffer args) - "Finishing checking in patch....") - (with-current-buffer buffer - (vc-run-delayed - (vc-compilation-mode 'hg))) - (vc-set-async-update buffer) - (list 'async (get-buffer-process buffer))) - (apply #'vc-hg-command nil 0 nil args))) - (delete-file patch-file)))) + "Hg-specific version of `vc-BACKEND-checkin-patch'." + (vc-hg--checkin comment nil patch-string)) (defun vc-hg--extract-headers (comment) (log-edit-extract-headers `(("Author" . "--user") commit f8cb751ac0a403bc3769cac9816ad46809b7740e Author: Eli Zaretskii Date: Sat Aug 16 19:40:11 2025 +0100 vc-hg-known-other-working-trees: Fix on MS-Windows * lisp/vc/vc-hg.el (vc-hg-known-other-working-trees): Use expand-file-name to convert paths from .hg/sharedpath files. diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index e9095b72098..b0e5a633566 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -1738,7 +1738,10 @@ Intended for use via the `vc-hg--async-command' wrapper." (if (file-exists-p our-sp) (with-temp-buffer (insert-file-contents-literally our-sp) - (setq our-store (string-trim (buffer-string))) + ;; On MS-Windows, ".hg/sharedpath" gives file names with + ;; backslashes; expand-file-name normalizes that to forward + ;; slashes, needed for 'equal' comparison below. + (setq our-store (expand-file-name (string-trim (buffer-string)))) (push (abbreviate-file-name (file-name-directory our-store)) shares)) (setq our-store (expand-file-name ".hg" our-root))) @@ -1748,7 +1751,9 @@ Intended for use via the `vc-hg--async-command' wrapper." ((file-exists-p sp))) (with-temp-buffer (insert-file-contents-literally sp) - (when (equal our-store (buffer-string)) + (when (equal our-store + ;; See above why we use expand-file-name + (expand-file-name (string-trim (buffer-string)))) (push root shares))))) shares)) commit 85dcf4fe96941e00f88a68859e8b720ef6e09282 Author: João Távora Date: Sat Aug 16 18:22:47 2025 +0100 Flymake: improve previous fix (bug#78862) The previous fix for this bug is an acceptable approach, but more care must be taken when clearing a flymake--state object's diagnostics. Refactor this behaviour into a helper. * lisp/progmodes/flymake.el (flymake--clear-state): New helper. (flymake--publish-diagnostics, flymake-start): Use it. diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el index bdfcf51a5ff..c5380a9bb64 100644 --- a/lisp/progmodes/flymake.el +++ b/lisp/progmodes/flymake.el @@ -1172,6 +1172,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 +1196,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 +1209,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)) @@ -1415,16 +1415,7 @@ Interactively, with a prefix arg, FORCE is t." ;; See bug#78862 (maphash (lambda (backend state) (unless (memq backend flymake-diagnostic-functions) - ;; Delete all overlays - (dolist (diag (flymake--state-diags state)) - (let ((ov (flymake--diag-overlay diag))) - (flymake--delete-overlay ov))) - ;; Set the list of diagnostics to nil to - ;; avoid trying to delete them again. - ;; We keep the state object itself around in - ;; case there's still diagnostics in flight, - ;; so we don't break things. - (setf (flymake--state-diags state) nil))) + (flymake--clear-state state))) flymake--state) (run-hook-wrapped 'flymake-diagnostic-functions commit d4c9f08f26ebd208e1a6d102410ec93b7ff323b6 Author: Sean Whitton Date: Sat Aug 16 12:40:23 2025 +0100 vc-test--with-author-identity: Handle Mercurial * test/lisp/vc/vc-tests/vc-tests.el (vc-hg-global-switches): Declare. (vc-test--with-author-identity): Handle Mercurial. diff --git a/test/lisp/vc/vc-tests/vc-tests.el b/test/lisp/vc/vc-tests/vc-tests.el index 81789814350..02be0e722e4 100644 --- a/test/lisp/vc/vc-tests/vc-tests.el +++ b/test/lisp/vc/vc-tests/vc-tests.el @@ -584,20 +584,26 @@ This checks also `vc-backend' and `vc-responsible-backend'." (ignore-errors (run-hooks 'vc-test--cleanup-hook)))))) +(defvar vc-hg-global-switches) + (defmacro vc-test--with-author-identity (backend &rest body) (declare (indent 1) (debug t)) - `(let ((process-environment process-environment)) + `(let ((process-environment process-environment) + (vc-hg-global-switches vc-hg-global-switches)) ;; git tries various approaches to guess a user name and email, ;; which can fail depending on how the system is configured. ;; Eg if the user account has no GECOS, git commit can fail with ;; status 128 "fatal: empty ident name". (when (memq ,backend '(Bzr Git)) - (setq process-environment (cons "EMAIL=john@doe.ee" - process-environment))) + (push "EMAIL=john@doe.ee" process-environment)) (when (eq ,backend 'Git) (setq process-environment (append '("GIT_AUTHOR_NAME=A" "GIT_COMMITTER_NAME=C") process-environment))) + + ;; Mercurial fails to autodetect an identity on MS-Windows. + (when (eq ,backend 'Hg) + (push "--config=ui.username=john@doe.ee" vc-hg-global-switches)) ,@body)) (declare-function log-edit-done "vc/log-edit") commit 78d569e5245e29e271a2d443092dad8f4ccdaf51 Author: Sean Whitton Date: Thu Aug 14 13:23:24 2025 +0100 * lisp/vc/vc-hg.el (vc-hg-checkin): Fix on MS-Windows (bug#79024). diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 7b65084a108..e9095b72098 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -1216,20 +1216,51 @@ It is based on `log-edit-mode', and has Hg-specific extensions.") (defun vc-hg-checkin (files comment &optional _rev) "Hg-specific version of `vc-BACKEND-checkin'. REV is ignored." - (let ((args (nconc (list "commit" "-A" "-m") - (vc-hg--extract-headers comment)))) - (if vc-async-checkin - (let ((buffer (vc-hg--async-buffer))) - (vc-wait-for-process-before-save - (apply #'vc-hg--async-command buffer (nconc args files)) - "Finishing checking in files...") - (with-current-buffer buffer - (vc-run-delayed - (vc-compilation-mode 'hg))) - (vc-set-async-update buffer) - (list 'async (get-buffer-process buffer))) - (apply #'vc-hg-command nil 0 files args)))) - + (let* ((args (vc-hg--extract-headers comment)) + (file1 (or (car files) default-directory)) + (msg-file + ;; On MS-Windows, pass the commit log message through a file, + ;; to work around the limitation that command-line arguments + ;; must be in the system codepage, and therefore might not + ;; support non-ASCII characters in the log message. + ;; Also handle remote files. + (and (eq system-type 'windows-nt) + (let ((default-directory (or (file-name-directory file1) + default-directory))) + (make-nearby-temp-file "hg-msg"))))) + (when msg-file + (let ((coding-system-for-write 'utf-8)) + (write-region (car args) nil msg-file))) + (let ((coding-system-for-write + ;; On MS-Windows, we must encode command-line arguments in + ;; the system codepage. + (if (eq system-type 'windows-nt) + locale-coding-system + coding-system-for-write)) + (args (if msg-file + (cl-list* "commit" "-A" "-l" (file-local-name msg-file) + (cdr args)) + (cl-list* "commit" "-A" "-m" args))) + (post (lambda () + (when (and msg-file (file-exists-p msg-file)) + (delete-file msg-file))))) + (if vc-async-checkin + (let ((buffer (vc-hg--async-buffer))) + (vc-wait-for-process-before-save + (apply #'vc-hg--async-command buffer (nconc args files)) + "Finishing checking in files...") + (with-current-buffer buffer + (vc-run-delayed + (vc-compilation-mode 'hg) + (funcall post))) + (vc-set-async-update buffer) + (list 'async (get-buffer-process buffer))) + (apply #'vc-hg-command nil 0 files args) + (funcall post))))) + +;; FIXME: Needs MS-Windows encoding issues handling. +;; Possibly we want fix this by merging this function into the preceeding one. +;; Figure out resolution of #79235 first. (defun vc-hg-checkin-patch (patch-string comment) (let ((patch-file (make-nearby-temp-file "hg-patch"))) (write-region patch-string nil patch-file) commit 18b87fab35939c52df884ffe6f124f78e28b6bf9 Author: Sean Whitton Date: Sat Aug 16 12:58:18 2025 +0100 ; vc-git-command, vc-hg-command: Comments about MS-Windows encoding. diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index f01807e0113..b5da03764d1 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -2492,6 +2492,17 @@ The difference to `vc-do-command' is that this function always invokes `vc-git-program'." (let ((coding-system-for-read (or coding-system-for-read vc-git-log-output-coding-system)) + ;; Commands which pass command line arguments which might + ;; contain non-ASCII have to bind `coding-system-for-write' to + ;; `locale-coding-system' when (eq system-type 'windows-nt) + ;; because MS-Windows has the limitation that command line + ;; arguments must be in the system codepage. We do that only + ;; within the commands which must do it, instead of implementing + ;; it here, even though that means code repetition. This is + ;; because this let-binding has the disadvantage of overriding + ;; any `coding-system-for-write' explicitly selected by the user + ;; (e.g. with C-x RET c), or by enclosing function calls. So we + ;; want to do it only for commands which really require it. (coding-system-for-write (or coding-system-for-write vc-git-commits-coding-system)) (process-environment diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index 3a6580c16f4..7b65084a108 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -1638,6 +1638,18 @@ This function differs from `vc-do-command' in that - BUFFER may be nil - it invokes `vc-hg-program' and passes `vc-hg-global-switches' to it before FLAGS." + ;; Commands which pass command line arguments which might + ;; contain non-ASCII have to bind `coding-system-for-write' to + ;; `locale-coding-system' when (eq system-type 'windows-nt) + ;; because MS-Windows has the limitation that command line + ;; arguments must be in the system codepage. We do that only + ;; within the commands which must do it, instead of implementing + ;; it here, even though that means code repetition. This is + ;; because such a let-binding would have the disadvantage of + ;; overriding any `coding-system-for-write' explicitly selected + ;; by the user (e.g. with C-x RET c), or by enclosing function + ;; calls. So we want to do it only for commands which really + ;; require it. (vc-hg--command-1 #'vc-do-command (list (or buffer "*vc*") okstatus vc-hg-program file-or-list) commit eb8d0d7afe39c827cd4e35e97cd2c8bf4dbdf73e Merge: 4983985b80e 3516479b58d Author: Eli Zaretskii Date: Sat Aug 16 14:41:41 2025 +0300 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 4983985b80e853c4b85543478d1bb0eac248768f Author: Eli Zaretskii Date: Sat Aug 16 14:40:39 2025 +0300 ; Fix last change (bug#77544) * lisp/whitespace.el (whitespace-style): Bump :version. Doc fix. (whitespace-page-delimiter): Add :version. (whitespace-page-delimiters-mode): Doc fix. diff --git a/lisp/whitespace.el b/lisp/whitespace.el index 8c38b6e0868..de2551d42b0 100644 --- a/lisp/whitespace.el +++ b/lisp/whitespace.el @@ -329,7 +329,7 @@ The value is a list containing one or more of the following symbols: This has effect only if `face' (see above) is present in `whitespace-style'. - page-delimiters visualize page delimiters characters (^L) + page-delimiters visualize page-break delimiter characters (^L) as horizontal lines. This has effect only if `face' (see above) is present in `whitespace-style'. @@ -467,7 +467,8 @@ See also `whitespace-display-mappings' for documentation." (const :tag "(Face) SPACEs before TAB" space-before-tab) (const :tag "(Mark) SPACEs and HARD SPACEs" space-mark) (const :tag "(Mark) TABs" tab-mark) - (const :tag "(Mark) NEWLINEs" newline-mark))) + (const :tag "(Mark) NEWLINEs" newline-mark)) + :version "31.1") (defvar whitespace-space 'whitespace-space "Symbol face used to visualize SPACE. @@ -638,7 +639,8 @@ See `whitespace-space-after-tab-regexp'.") (((supports :strike-through t)) :height 0.1 :strike-through t :extend t :inherit shadow) (t :height 0.1 :extend t :inherit shadow :inverse-video t)) - "Face used to visualize page delimiter characters.") + "Face used to visualize page delimiter characters." + :version "31.1") (defcustom whitespace-hspace-regexp "\\(\u00A0+\\)" @@ -1006,7 +1008,7 @@ See also `whitespace-newline' and `whitespace-display-mappings'." ;;;###autoload (define-minor-mode whitespace-page-delimiters-mode - "Display page delimiters characters as horizontal lines." + "Display page-break delimiter characters as horizontal lines." :lighter " pd" :group 'whitespace (let ((whitespace-style '(face page-delimiters))) commit 3516479b58d9678def0310d951f0e3ed2acb68c6 Merge: 25380c8e145 51241572630 Author: Michael Albinus Date: Sat Aug 16 13:37:04 2025 +0200 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit 25380c8e14567894f1e847b5f2ce75f0265293d8 Merge: cb32d5ef597 964741d40e0 Author: Michael Albinus Date: Sat Aug 16 13:35:53 2025 +0200 Merge from origin/emacs-30 964741d40e0 * lisp/net/tramp-sh.el (tramp-get-remote-touch): Simplify. 6a018a2d7e4 Improve use of "touch" in Tramp commit cb32d5ef5973cefaca220d95aac34ea3e0b98190 Merge: 4cb84d3a786 4a3b6daf76c Author: Michael Albinus Date: Sat Aug 16 13:35:52 2025 +0200 ; Merge from origin/emacs-30 The following commit was skipped: 4a3b6daf76c Sync with Tramp 2.7.4-pre commit 4cb84d3a786630db4565e5f856b206fc458fe4da Merge: 8a6fdffed29 f8a206937c9 Author: Michael Albinus Date: Sat Aug 16 13:35:50 2025 +0200 Merge from origin/emacs-30 f8a206937c9 executable-interpret: Handle remote file names c17168ebed9 ; * admin/make-tarball.txt: Fix typo and add details. commit 8a6fdffed29c8db91a60ce6cb1ff6c232e1f7ec4 Merge: 8700cd24ca0 34f35407eb2 Author: Michael Albinus Date: Sat Aug 16 13:35:48 2025 +0200 ; Merge from origin/emacs-30 The following commit was skipped: 34f35407eb2 Bump Emacs version to 30.2.50 commit 8700cd24ca034327a9fb0ab7ce37acad2ac63e8d Merge: cf45a3fd79d 636f166cfc8 Author: Michael Albinus Date: Sat Aug 16 13:35:47 2025 +0200 Merge from origin/emacs-30 636f166cfc8 ; * make-dist: Include ELisp hierarchy diagram in tarball... commit cf45a3fd79d95d2fa35729b06760e29b6549f37f Merge: ea1157f68fe 1514695b7d1 Author: Michael Albinus Date: Sat Aug 16 13:35:45 2025 +0200 ; Merge from origin/emacs-30 The following commit was skipped: 1514695b7d1 ; Update lisp/ldefs-boot.el. Do not merge to master. commit ea1157f68fe249698b87c738e0548dd6ac0d313b Merge: 6d95df628ce 8960e3af819 Author: Michael Albinus Date: Sat Aug 16 13:35:43 2025 +0200 Merge from origin/emacs-30 8960e3af819 Update files for Emacs 30.2 ebeca61755e * admin/admin.el (set-version): Fix handling of official ... commit 6d95df628ceec324c6ab46eac3b1a9341a1f1a29 Merge: 839f416de7f 8ddef0ad4d6 Author: Michael Albinus Date: Sat Aug 16 13:35:42 2025 +0200 ; Merge from origin/emacs-30 The following commit was skipped: 8ddef0ad4d6 Bump Emacs version commit 839f416de7fb5e762e6f739fe943ba3aae56391a Merge: cc37d199b02 49d64bfb1a4 Author: Michael Albinus Date: Sat Aug 16 13:35:00 2025 +0200 Merge from origin/emacs-30 49d64bfb1a4 ; * etc/NEWS: Update for Emacs 30.2. 4b90b6e7ce9 ; * lisp/emacs-lisp/cl-generic.el (cl-defgeneric): Doc fi... commit 997461f48497e67ca4913ad18ae7d6d3562459d7 Author: Elías Gabriel Pérez Date: Fri Apr 4 22:17:23 2025 -0600 whitespace-mode: New style to prettify page delimiters characters. This new style for 'whitespace-style' displays the page delimiter characters "^L" as pretty horizontal lines. (Bug#77544) This also add a new minor mode to toggle these visualization. * lisp/whitespace.el (whitespace-style): Add page-delimiters option. (whitespace-page-delimiter): New face. (whitespace--page-delimiters-keyword): New variable. (whitespace-page-delimiters-mode): New minor mode. (whitespace-style-face-p, whitespace-color-on): Rework for display the page-delimiters. diff --git a/etc/NEWS b/etc/NEWS index ada8e8f8124..4a193484591 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1213,6 +1213,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 --- diff --git a/lisp/whitespace.el b/lisp/whitespace.el index 58ba0db8c90..8c38b6e0868 100644 --- a/lisp/whitespace.el +++ b/lisp/whitespace.el @@ -156,6 +156,9 @@ ;; `global-whitespace-newline-mode' ;; Toggle NEWLINE global minor mode visualization ("NL" on mode line). ;; +;; `whitespace-page-delimiters-mode' +;; Display page delimiters characters as horizontal lines ("pd" on mode line). +;; ;; `whitespace-report' ;; Report some blank problems in buffer. ;; @@ -326,6 +329,11 @@ The value is a list containing one or more of the following symbols: This has effect only if `face' (see above) is present in `whitespace-style'. + page-delimiters visualize page delimiters characters (^L) + as horizontal lines. + This has effect only if `face' (see above) + is present in `whitespace-style'. + empty visualize empty lines at beginning and/or end of buffer via faces. This has effect only if `face' (see above) @@ -440,6 +448,7 @@ See also `whitespace-display-mappings' for documentation." (const :tag "(Face) NEWLINEs" newline) (const :tag "(Face) Missing newlines at EOB" missing-newline-at-eof) + (const :tag "(Face) Page delimiters" page-delimiters) (const :tag "(Face) Empty Lines At BOB And/Or EOB" empty) (const :tag "(Face) Indentation SPACEs" indentation::tab) (const :tag "(Face) Indentation TABs" @@ -622,6 +631,14 @@ Used when `whitespace-style' includes the value `space-after-tab'.") See `whitespace-space-after-tab-regexp'.") +(defface whitespace-page-delimiter + '((((supports :underline (:color foreground-color :style double-line))) + :underline (:color foreground-color :style double-line) + :height 0.1 :extend t :inherit shadow) + (((supports :strike-through t)) + :height 0.1 :strike-through t :extend t :inherit shadow) + (t :height 0.1 :extend t :inherit shadow :inverse-video t)) + "Face used to visualize page delimiter characters.") (defcustom whitespace-hspace-regexp "\\(\u00A0+\\)" @@ -934,6 +951,17 @@ Any other value is treated as nil." (const :tag "Abort On Bogus" abort-on-bogus) (const :tag "Warn If Read-Only" warn-if-read-only))))) +(defvar whitespace--page-delimiters-keyword + `((,(lambda (bound) + (re-search-forward (concat page-delimiter "\n") bound t)) + 0 + (prog1 nil + (put-text-property (match-beginning 0) (1- (match-end 0)) 'display " ") + (add-text-properties (match-beginning 0) (match-end 0) + '( face whitespace-page-delimiter + display-line-numbers-disable t))))) + "Used to add page delimiters keywords to `whitespace-font-lock-keywords'.") + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; User commands - Local mode @@ -976,6 +1004,15 @@ See also `whitespace-newline' and `whitespace-display-mappings'." ;; sync states (running a batch job) (setq whitespace-newline-mode whitespace-mode)) +;;;###autoload +(define-minor-mode whitespace-page-delimiters-mode + "Display page delimiters characters as horizontal lines." + :lighter " pd" + :group 'whitespace + (let ((whitespace-style '(face page-delimiters))) + (whitespace-mode (if whitespace-page-delimiters-mode + 1 -1)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; User commands - Global mode @@ -1044,6 +1081,7 @@ See also `whitespace-newline' and `whitespace-display-mappings'." tabs spaces trailing + page-delimiters lines lines-tail lines-char @@ -1071,6 +1109,7 @@ See also `whitespace-newline' and `whitespace-display-mappings'." '((?f . face) (?t . tabs) (?s . spaces) + (?p . page-delimiters) (?r . trailing) (?l . lines) (?L . lines-tail) @@ -1156,6 +1195,7 @@ Interactively, it reads one of the following chars: t toggle TAB visualization s toggle SPACE and HARD SPACE visualization r toggle trailing blanks visualization + p toggle page delimiters visualization l toggle \"long lines\" visualization L toggle \"long lines\" tail visualization n toggle NEWLINE visualization @@ -1186,6 +1226,7 @@ The valid symbols are: tabs toggle TAB visualization spaces toggle SPACE and HARD SPACE visualization trailing toggle trailing blanks visualization + page-delimiters toggle page delimiters visualization lines toggle \"long lines\" visualization lines-tail toggle \"long lines\" tail visualization newline toggle NEWLINE visualization @@ -1237,6 +1278,7 @@ Interactively, it accepts one of the following chars: t toggle TAB visualization s toggle SPACE and HARD SPACE visualization r toggle trailing blanks visualization + p toggle page delimiters visualization l toggle \"long lines\" visualization L toggle \"long lines\" tail visualization C-l toggle \"long lines\" one character visualization @@ -1268,6 +1310,7 @@ The valid symbols are: tabs toggle TAB visualization spaces toggle SPACE and HARD SPACE visualization trailing toggle trailing blanks visualization + page-delimiters toggle page delimiters visualization lines toggle \"long lines\" visualization lines-tail toggle \"long lines\" tail visualization lines-char toggle \"long lines\" one character visualization @@ -2035,6 +2078,7 @@ resultant list will be returned." (memq 'lines-tail whitespace-active-style) (memq 'lines-char whitespace-active-style) (memq 'newline whitespace-active-style) + (memq 'page-delimiters whitespace-active-style) (memq 'empty whitespace-active-style) (memq 'indentation whitespace-active-style) (memq 'indentation::tab whitespace-active-style) @@ -2108,6 +2152,13 @@ resultant list will be returned." ;; first overflowing character ((memq 'lines-char whitespace-active-style) 3)) whitespace-line prepend))) + ,@(when (memq 'page-delimiters whitespace-active-style) + (unless (and (memq 'display font-lock-extra-managed-props) + (memq 'display-line-numbers-disable font-lock-extra-managed-props)) + (setq-local font-lock-extra-managed-props + `(,@font-lock-extra-managed-props display display-line-numbers-disable))) + ;; Show page delimiters characters + whitespace--page-delimiters-keyword) ,@(when (or (memq 'space-before-tab whitespace-active-style) (memq 'space-before-tab::tab whitespace-active-style) (memq 'space-before-tab::space whitespace-active-style)) commit 512415726300cba09e6b6d7f2d2387dfb3d62bf5 Author: Eli Zaretskii Date: Sat Aug 16 14:28:42 2025 +0300 ; * lisp/minibuffer.el (completion-eager-update): Doc fix. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 29d880e73c5..f0994adbb70 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1069,7 +1069,7 @@ metadata." If `t', always update as you type. -If `auto', only update if the completion property 'eager-update' is +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'. commit 4d90bdb385a23b26ddecae04b92e5557be172d27 Author: Spencer Baugh Date: Thu Apr 3 15:38:22 2025 -0400 Add support for updating *Completions* as you type Add support for updating the *Completions* buffer as you type, controlled by a new completion metadata symbol 'eager-update' and a new defcustom 'completion-eager-update'. You can configure a completion category to update *Completions* as you type by setting 'completion-category-overrides' appropriately; or set 'completion-eager-update' to t to always update *Completions* as you type. This is similar to the recently added 'completion-eager-display'. * lisp/minibuffer.el (completion-eager-update): Add new defcustom defaulting to 'auto. (Bug#77649) (completion--eager-update-p, completions--background-update) (completions--post-command-update): Add. (completions--after-change): Call 'completions--post-command-update' via 'post-command-hook'. (minibuffer-completion-help): Check 'completion-eager-update' and install 'completions--after-change'. (completion-help-at-point): Call 'completion--eager-update-p' if ONLY-IF-EAGER is non-nil. * etc/NEWS: Announce completion-eager-update. Reword the announcement of 'completion-eager-display' for consistency. diff --git a/etc/NEWS b/etc/NEWS index 5b3be259196..ada8e8f8124 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'. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 122459be062..29d880e73c5 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 @@ -2634,12 +2652,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 (get-buffer-window "*Completions*" 0)) + (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 (or completion-auto-deselect completion-eager-update) (when-let* ((window (get-buffer-window "*Completions*" 0))) - (with-selected-window window - (completions--deselect))))) + (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 +2779,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. @@ -3119,7 +3168,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 +3195,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. commit 964741d40e00334ec7b8dbe85c15c3f5af2296e7 (refs/remotes/origin/emacs-30) Author: Michael Albinus Date: Sat Aug 16 12:59:06 2025 +0200 * lisp/net/tramp-sh.el (tramp-get-remote-touch): Simplify. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 80ae71dfc64..f7dfedbd88d 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -5880,12 +5880,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 @@ -5895,16 +5895,13 @@ Nonexistent directories are removed from spec." result (format-time-string "%Y%m%d%H%M.%S") (tramp-file-local-name tmpfile)))) + ;; 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)) - result))) + vec (format "%s -h %s" result (tramp-file-local-name tmpfile)))) + (delete-file tmpfile))))) (defun tramp-get-remote-df (vec) "Determine remote `df' command." commit 6a018a2d7e4fd53e5c2340e8ba159667e4244cec Author: Toru TSUNEYOSHI Date: Sat Aug 16 12:56:09 2025 +0200 Improve use of "touch" in Tramp * lisp/net/tramp-sh.el (tramp-get-remote-touch): Set connection property "touch-h". (tramp-sh-handle-set-file-times): Use it. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 287b46fc72e..80ae71dfc64 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1601,7 +1601,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) @@ -5892,6 +5895,14 @@ Nonexistent directories are removed from spec." result (format-time-string "%Y%m%d%H%M.%S") (tramp-file-local-name tmpfile)))) + (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)) result))) commit cc37d199b029032045ccf0eb7bc83f166d33370a Author: Manuel Giraud Date: Fri Aug 8 17:53:01 2025 +0200 Handle 'lexical-binding' cookie in nnrss output * lisp/gnus/nnrss.el (nnrss-save-server-data) (nnrss-save-group-data): Add a 'lexical-binding' cookie. * lisp/gnus/nnrss.el (nnrss-read-server-data) (nnrss-read-group-data): Allow missing 'lexical-binding' cookie. (Bug#79199) 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))))) commit 034d755f2f21088b97fdb0a34d846c39fcdbf46d Author: Eli Zaretskii Date: Sat Aug 16 13:28:52 2025 +0300 ; * src/process.c (set_proc_thread): Fix assertion. diff --git a/src/process.c b/src/process.c index f8d67561f26..c8b70a4174c 100644 --- a/src/process.c +++ b/src/process.c @@ -1449,7 +1449,8 @@ See `set-process-sentinel' for more info on sentinels. */) static void set_proc_thread (struct Lisp_Process *proc, struct thread_state *thrd) { - eassert (THREADP (proc->thread) && XTHREAD (proc->thread) == thrd); + eassert ((NILP (proc->thread) && !thrd) + || (THREADP (proc->thread) && XTHREAD (proc->thread) == thrd)); eassert (proc->infd < FD_SETSIZE); if (proc->infd >= 0) fd_callback_info[proc->infd].thread = thrd; commit 4a3b6daf76c385fc58759d57aeb4d34e8acc31e5 Author: Michael Albinus Date: Sat Aug 16 12:26:19 2025 +0200 Sync with Tramp 2.7.4-pre * doc/misc/trampver.texi: * lisp/net/trampver.el (tramp-version): Adapt Tramp versions. * lisp/net/tramp-cmds.el (tramp-cleanup-connection): Use read syntax #' for `tramp-timeout-session', * lisp/net/tramp-gvfs.el (tramp-gvfs-maybe-open-connection): * lisp/net/tramp-rclone.el (tramp-rclone-maybe-open-connection): Set "connected" property in time. * lisp/net/tramp-sh.el (tramp-timeout-session): Add ;;;###tramp-autoload cookie. * lisp/net/tramp.el (tramp-barf-if-file-missing): Do not raise an error when not connected. (Bug#78572) (tramp-file-name-handler): Do not force the backtrace. (tramp-connectable-p): Check also, whether initial handshake is finished. (tramp-skeleton-directory-files) (tramp-skeleton-directory-files-and-attributes) (tramp-skeleton-set-file-modes-times-uid-gid): Rearrange sending `file-missing' error. (tramp-handle-access-file, tramp-handle-unlock-file): Use `tramp-connectable-p'. (tramp-skeleton-file-name-all-completions): Filter out "" hits. (Bug#79173) * test/lisp/net/tramp-tests.el (project-mode-line-format) (project-mode-line): Declare. (tramp-test48-session-timeout): New test. (tramp-test49-auto-load, tramp-test49-delay-load) (tramp-test49-recursive-load, tramp-test49-remote-load-path) (tramp-test50-without-remote-files, tramp-test51-unload): Rename. diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi index aa76672ea59..8fe3b9bb0a8 100644 --- a/doc/misc/trampver.texi +++ b/doc/misc/trampver.texi @@ -7,7 +7,7 @@ @c In the Tramp GIT, the version number and the bug report address @c are auto-frobbed from configure.ac. -@set trampver 2.7.3.30.2 +@set trampver 2.7.4-pre @set trampurl https://www.gnu.org/software/tramp/ @set tramp-bug-report-address tramp-devel@@gnu.org @set emacsver 27.1 diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index f03fa5cf404..18f5d12277e 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -122,7 +122,7 @@ When called interactively, a Tramp connection has to be selected." ;; Cancel timer. (dolist (timer timer-list) - (when (and (eq (timer--function timer) 'tramp-timeout-session) + (when (and (eq (timer--function timer) #'tramp-timeout-session) (tramp-file-name-equal-p vec (car (timer--args timer)))) (cancel-timer timer))) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 9530aa3733a..efbf9935573 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -2345,11 +2345,11 @@ connection if a previous connection has died for some reason." ;; Save the password. (ignore-errors (and (functionp tramp-password-save-function) - (funcall tramp-password-save-function))) + (funcall tramp-password-save-function)))))) - ;; Mark it as connected. - (tramp-set-connection-property - (tramp-get-connection-process vec) "connected" t)))))) + ;; Mark it as connected. + (tramp-set-connection-property + (tramp-get-connection-process vec) "connected" t))) (defun tramp-gvfs-gio-tool-p (vec) "Check, whether the gio tool is available." diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index 07dd80deb9a..17ae36f94e8 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -411,11 +411,11 @@ connection if a previous connection has died for some reason." (tramp-get-method-parameter vec 'tramp-mount-args)) (while (not (file-exists-p (tramp-make-tramp-file-name vec 'noloc))) (tramp-cleanup-connection vec 'keep-debug 'keep-password)) + (add-to-list 'tramp-fuse-mount-points (tramp-file-name-unify vec))) - ;; Mark it as connected. - (add-to-list 'tramp-fuse-mount-points (tramp-file-name-unify vec)) - (tramp-set-connection-property - (tramp-get-connection-process vec) "connected" t)))) + ;; Mark it as connected. + (tramp-set-connection-property + (tramp-get-connection-process vec) "connected" t))) ;; In `tramp-check-cached-permissions', the connection properties ;; "{uid,gid}-{integer,string}" are used. We set them to proper values. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index cae6d52f14c..287b46fc72e 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -5128,6 +5128,7 @@ Goes through the list `tramp-inline-compress-commands'." (t "-3"))) +;;;###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." @@ -5147,6 +5148,7 @@ If there is just some editing, retry it after 5 seconds." Does not do anything if a connection is already open, but re-opens the connection if a previous connection has died for some reason." ;; During completion, don't reopen a new connection. + ;; Same for slide-in timer or process-{filter,sentinel}. (unless (tramp-connectable-p vec) (throw 'non-essential 'non-essential)) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index e0e080021c7..c72ccc1738f 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2098,10 +2098,11 @@ does not exist, otherwise propagate the error." (declare (indent 2) (debug (symbolp form body))) (let ((err (make-symbol "err"))) `(condition-case ,err - (progn ,@body) + (let (signal-hook-function) ,@body) (error (if (not (or (file-exists-p ,filename) (file-symlink-p ,filename))) - (tramp-error ,vec 'file-missing ,filename) + (when (tramp-connectable-p ,vec) + (tramp-error ,vec 'file-missing ,filename)) (signal (car ,err) (cdr ,err))))))) ;; This function provides traces in case of errors not triggered by @@ -2542,7 +2543,7 @@ Fall back to normal file name handler if no Tramp file name handler exists." (tramp-message v 5 "Non-essential received in operation %s" (cons operation args)) - (let ((tramp-verbose 10)) (tramp-backtrace v)) + (tramp-backtrace v) (tramp-run-real-handler operation args)) ((eq result 'suppress) (let ((inhibit-message t)) @@ -2759,13 +2760,15 @@ They are completed by `M-x TAB' only if the current buffer is remote." "Check if it is possible to connect the remote host without side-effects. This is true, if either the remote host is already connected, or if we are not in completion mode." - (let ((tramp-verbose 0) - (vec (tramp-ensure-dissected-file-name vec-or-filename))) - (or ;; We check this for the process related to - ;; `tramp-buffer-name'; otherwise `make-process' wouldn't run - ;; ever when `non-essential' is non-nil. - (process-live-p (tramp-get-process vec)) - (not non-essential)))) + (or (not non-essential) + ;; We check this for the process related to `tramp-buffer-name'; + ;; otherwise `make-process' wouldn't run ever when + ;; `non-essential' is non-nil. + (and-let* ((tramp-verbose 0) + (vec (tramp-ensure-dissected-file-name vec-or-filename)) + (p (tramp-get-process vec)) + ((process-live-p p)) + ((tramp-get-connection-property p "connected")))))) (defun tramp-completion-handle-expand-file-name (filename &optional directory) "Like `expand-file-name' for partial Tramp files." @@ -2863,7 +2866,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 "..". @@ -2880,7 +2883,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.") @@ -3434,79 +3437,69 @@ BODY is the backend specific code." "Skeleton for `tramp-*-handle-directory-files'. BODY is the backend specific code." (declare (indent 5) (debug t)) - `(or - (with-parsed-tramp-file-name (expand-file-name ,directory) nil - (tramp-barf-if-file-missing v ,directory - (when (file-directory-p ,directory) - (setf ,directory - (file-name-as-directory (expand-file-name ,directory))) - (let ((temp - (with-tramp-file-property v localname "directory-files" ,@body)) - result item) - (while temp - (setq item (directory-file-name (pop temp))) - (when (or (null ,match) (string-match-p ,match item)) - (push (if ,full (concat ,directory item) item) - result))) - (unless ,nosort - (setq result (sort result #'string<))) - (when (and (natnump ,count) (> ,count 0)) - (setq result (tramp-compat-ntake ,count result))) - result)))) - - ;; Error handling. - (if (not (file-exists-p ,directory)) - (tramp-error - (tramp-dissect-file-name ,directory) 'file-missing ,directory) - nil))) + `(with-parsed-tramp-file-name (expand-file-name ,directory) nil + (tramp-barf-if-file-missing v ,directory + (if (not (file-directory-p ,directory)) + ;; Trigger the `file-missing' error. + (signal 'error nil) + (setf ,directory + (file-name-as-directory (expand-file-name ,directory))) + (let ((temp + (with-tramp-file-property v localname "directory-files" ,@body)) + result item) + (while temp + (setq item (directory-file-name (pop temp))) + (when (or (null ,match) (string-match-p ,match item)) + (push (if ,full (concat ,directory item) item) + result))) + (unless ,nosort + (setq result (sort result #'string<))) + (when (and (natnump ,count) (> ,count 0)) + (setq result (tramp-compat-ntake ,count result))) + result))))) (defmacro tramp-skeleton-directory-files-and-attributes (directory &optional full match nosort id-format count &rest body) "Skeleton for `tramp-*-handle-directory-files-and-attributes'. BODY is the backend specific code." (declare (indent 6) (debug t)) - `(or - (with-parsed-tramp-file-name (expand-file-name ,directory) nil - (tramp-barf-if-file-missing v ,directory - (when (file-directory-p ,directory) - (let ((temp - (copy-tree - (mapcar - (lambda (x) - (cons - (car x) - (tramp-convert-file-attributes - v (expand-file-name (car x) localname) - ,id-format (cdr x)))) - (with-tramp-file-property - v localname "directory-files-and-attributes" - ,@body)))) - result item) - - (while temp - (setq item (pop temp)) - (when (or (null ,match) (string-match-p ,match (car item))) - (when ,full - (setcar item (expand-file-name (car item) ,directory))) - (push item result))) - - (unless ,nosort - (setq result - (sort result (lambda (x y) (string< (car x) (car y)))))) - - (when (and (natnump ,count) (> ,count 0)) - (setq result (tramp-compat-ntake ,count result))) - - (or result - ;; The scripts could fail, for example with huge file size. - (tramp-handle-directory-files-and-attributes - ,directory ,full ,match ,nosort ,id-format ,count)))))) - - ;; Error handling. - (if (not (file-exists-p ,directory)) - (tramp-error - (tramp-dissect-file-name ,directory) 'file-missing ,directory) - nil))) + `(with-parsed-tramp-file-name (expand-file-name ,directory) nil + (tramp-barf-if-file-missing v ,directory + (if (not (file-directory-p ,directory)) + ;; Trigger the `file-missing' error. + (signal 'error nil) + (let ((temp + (copy-tree + (mapcar + (lambda (x) + (cons + (car x) + (tramp-convert-file-attributes + v (expand-file-name (car x) localname) + ,id-format (cdr x)))) + (with-tramp-file-property + v localname "directory-files-and-attributes" + ,@body)))) + result item) + + (while temp + (setq item (pop temp)) + (when (or (null ,match) (string-match-p ,match (car item))) + (when ,full + (setcar item (expand-file-name (car item) ,directory))) + (push item result))) + + (unless ,nosort + (setq result + (sort result (lambda (x y) (string< (car x) (car y)))))) + + (when (and (natnump ,count) (> ,count 0)) + (setq result (tramp-compat-ntake ,count result))) + + (or result + ;; The scripts could fail, for example with huge file size. + (tramp-handle-directory-files-and-attributes + ,directory ,full ,match ,nosort ,id-format ,count))))))) (defcustom tramp-use-file-attributes t "Whether to use \"file-attributes\" connection property for check. @@ -3810,20 +3803,23 @@ BODY is the backend specific code." BODY is the backend specific code." (declare (indent 1) (debug t)) `(with-parsed-tramp-file-name (expand-file-name ,filename) nil - (when (not (file-exists-p ,filename)) - (tramp-error v 'file-missing ,filename)) - (with-tramp-saved-file-properties - v localname - ;; We cannot add "file-attributes", "file-executable-p", - ;; "file-ownership-preserved-p", "file-readable-p", - ;; "file-writable-p". - '("file-directory-p" "file-exists-p" "file-symlink-p" "file-truename") - (tramp-flush-file-properties v localname)) - (condition-case err - (progn ,@body) - (error (if tramp-inhibit-errors-if-setting-file-attributes-fail - (display-warning 'tramp (error-message-string err)) - (signal (car err) (cdr err))))))) + (tramp-barf-if-file-missing v ,filename + (if (not (file-exists-p ,filename)) + ;; Trigger the `file-missing' error. + (signal 'error nil) + (with-tramp-saved-file-properties + v localname + ;; We cannot add "file-attributes", "file-executable-p", + ;; "file-ownership-preserved-p", "file-readable-p", + ;; "file-writable-p". + '("file-directory-p" "file-exists-p" + "file-symlink-p" "file-truename") + (tramp-flush-file-properties v localname)) + (condition-case err + (progn ,@body) + (error (if tramp-inhibit-errors-if-setting-file-attributes-fail + (display-warning 'tramp (error-message-string err)) + (signal (car err) (cdr err))))))))) (defmacro tramp-skeleton-write-region (start end filename append visit lockname mustbenew &rest body) @@ -4013,9 +4009,7 @@ Let-bind it when necessary.") (tramp-dont-suspend-timers t)) (with-tramp-timeout (timeout - (unless (and-let* ((p (tramp-get-connection-process v)) - ((process-live-p p)) - ((tramp-get-connection-property p "connected")))) + (unless (and (not non-essential) (tramp-connectable-p v)) (tramp-cleanup-connection v 'keep-debug 'keep-password)) (tramp-error v 'file-error @@ -4901,6 +4895,7 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.") ;; functions like `kill-buffer' would try to reestablish the ;; connection. See Bug#61663. (if-let* ((v (tramp-dissect-file-name file)) + ((tramp-connectable-p v)) ((process-live-p (tramp-get-process v))) (lockname (tramp-compat-make-lock-file-name file))) (delete-file lockname) diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 2b2fdf94a49..af6d52c4ae6 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el @@ -7,7 +7,7 @@ ;; Maintainer: Michael Albinus ;; Keywords: comm, processes ;; Package: tramp -;; Version: 2.7.3.30.2 +;; Version: 2.7.4-pre ;; Package-Requires: ((emacs "27.1")) ;; Package-Type: multi ;; URL: https://www.gnu.org/software/tramp/ @@ -40,7 +40,7 @@ ;; ./configure" to change them. ;;;###tramp-autoload -(defconst tramp-version "2.7.3.30.2" +(defconst tramp-version "2.7.4-pre" "This version of Tramp.") ;;;###tramp-autoload @@ -76,7 +76,7 @@ ;; Check for Emacs version. (let ((x (if (not (string-version-lessp emacs-version "27.1")) "ok" - (format "Tramp 2.7.3.30.2 is not fit for %s" + (format "Tramp 2.7.4-pre is not fit for %s" (replace-regexp-in-string "\n" "" (emacs-version)))))) (unless (string-equal "ok" x) (error "%s" x))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 4fe3fca0df8..3013a63e041 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -54,6 +54,7 @@ (require 'vc-git) (require 'vc-hg) +(declare-function project-mode-line-format "project") (declare-function tramp-check-remote-uname "tramp-sh") (declare-function tramp-find-executable "tramp-sh") (declare-function tramp-get-remote-chmod-h "tramp-sh") @@ -82,6 +83,7 @@ (defvar dired-copy-dereference) ;; Declared in Emacs 30. +(defvar project-mode-line) (defvar remote-file-name-access-timeout) (defvar remote-file-name-inhibit-delete-by-moving-to-trash) @@ -8349,8 +8351,53 @@ process sentinels. They shall not disturb each other." tramp-use-fingerprint) (should (file-exists-p ert-remote-temporary-file-directory))))) +;; This test is inspired by Bug#78572. +(ert-deftest tramp-test48-session-timeout () + "Check that Tramp handles a session timeout properly." + (skip-unless (tramp--test-enabled)) + (skip-unless + (tramp-get-method-parameter tramp-test-vec 'tramp-session-timeout)) + + ;; We want to see the timeout message. + (tramp--test-instrument-test-case 3 + (let ((remote-file-name-inhibit-cache t) + (tmp-name (tramp--test-make-temp-name))) + (unwind-protect + (progn + (should-not (file-exists-p tmp-name)) + (write-region "foo" nil tmp-name) + (should (file-exists-p tmp-name)) + + (tramp-timeout-session tramp-test-vec) + (should (file-exists-p tmp-name)) + (should (directory-files (file-name-directory tmp-name))) + + ;; `project-mode-line' was introduced in Emacs 30.1. + (when (boundp 'project-mode-line) + (require 'project) + (ert-with-message-capture captured-messages + (let ((project-mode-line t)) + (with-temp-buffer + (set-visited-file-name tmp-name) + (insert "foo") + (should (buffer-modified-p)) + (tramp-timeout-session tramp-test-vec) + ;; This calls `file-directory-p' and + ;; `directory-files'. Shouldn't raise an error when + ;; not connected. + (project-mode-line-format) + ;; Steal the file lock. + (cl-letf (((symbol-function #'ask-user-about-lock) + #'tramp-compat-always)) + (save-buffer))) + (should-not + (string-match-p "File is missing:" captured-messages)))))) + + ;; Cleanup. + (ignore-errors (delete-file tmp-name)))))) + ;; This test is inspired by Bug#29163. -(ert-deftest tramp-test48-auto-load () +(ert-deftest tramp-test49-auto-load () "Check that Tramp autoloads properly." ;; If we use another syntax but `default', Tramp is already loaded ;; due to the `tramp-change-syntax' call. @@ -8375,7 +8422,7 @@ process sentinels. They shall not disturb each other." (mapconcat #'shell-quote-argument load-path " -L ") (shell-quote-argument code))))))) -(ert-deftest tramp-test48-delay-load () +(ert-deftest tramp-test49-delay-load () "Check that Tramp is loaded lazily, only when needed." ;; Tramp is neither loaded at Emacs startup, nor when completing a ;; non-Tramp file name like "/foo". Completing a Tramp-alike file @@ -8405,7 +8452,7 @@ process sentinels. They shall not disturb each other." (mapconcat #'shell-quote-argument load-path " -L ") (shell-quote-argument (format code tm))))))))) -(ert-deftest tramp-test48-recursive-load () +(ert-deftest tramp-test49-recursive-load () "Check that Tramp does not fail due to recursive load." (skip-unless (tramp--test-enabled)) @@ -8429,7 +8476,7 @@ process sentinels. They shall not disturb each other." (mapconcat #'shell-quote-argument load-path " -L ") (shell-quote-argument code)))))))) -(ert-deftest tramp-test48-remote-load-path () +(ert-deftest tramp-test49-remote-load-path () "Check that Tramp autoloads its packages with remote `load-path'." ;; `tramp-cleanup-all-connections' is autoloaded from tramp-cmds.el. ;; It shall still work, when a remote file name is in the @@ -8454,7 +8501,7 @@ process sentinels. They shall not disturb each other." (mapconcat #'shell-quote-argument load-path " -L ") (shell-quote-argument code))))))) -(ert-deftest tramp-test49-without-remote-files () +(ert-deftest tramp-test50-without-remote-files () "Check that Tramp can be suppressed." (skip-unless (tramp--test-enabled)) @@ -8469,7 +8516,7 @@ process sentinels. They shall not disturb each other." (setq tramp-mode t) (should (file-remote-p ert-remote-temporary-file-directory))) -(ert-deftest tramp-test50-unload () +(ert-deftest tramp-test51-unload () "Check that Tramp and its subpackages unload completely. Since it unloads Tramp, it shall be the last test to run." :tags '(:expensive-test) commit 9985e71eb79624a0722b00bb2108d90b6e7ab50e Author: Eli Zaretskii Date: Sat Aug 16 13:11:19 2025 +0300 ; Stabilize a Windows-specific process-test * test/src/process-tests.el (process-sentinel-interrupt-event): Improve stability of results, and show all of the results. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 641766ca7a9..5f84d9acc6d 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -1026,7 +1026,7 @@ Return nil if FILENAME doesn't exist." (with-temp-buffer (let* ((proc-buf (current-buffer)) ;; Start a new emacs process to wait idly until interrupted. - (cmd "emacs -batch --eval=\"(sit-for 50000)\"") + (cmd "emacs -Q -batch --eval=\"(sit-for 50000)\"") (proc (start-file-process-shell-command "test/process-sentinel-signal-event" proc-buf cmd)) (events '())) @@ -1040,12 +1040,12 @@ Return nil if FILENAME doesn't exist." (should (equal 'run (process-status proc))) ;; Interrupt the sub-process and wait for it to die. (interrupt-process proc) - (sleep-for 2) + (sleep-for 3) ;; Should have received SIGINT... - (should (equal 'signal (process-status proc))) - (should (equal 2 (process-exit-status proc))) - ;; ...and the change description should be "interrupt". - (should (equal '("interrupt\n") events))))) + (should (equal '(signal 2 ("interrupt\n")) + (list (process-status proc) + (process-exit-status proc) + events)))))) (ert-deftest process-num-processors () "Sanity checks for num-processors." commit c93be71e45d4cebeb017c813426228e579e9381d Author: Eli Zaretskii Date: Sat Aug 16 13:01:01 2025 +0300 Make sure 'make-process' locks the process to the current thread * src/process.c (set_proc_thread): New function. (Fset_process_thread, create_process): Use it. diff --git a/src/process.c b/src/process.c index ccad26b5339..f8d67561f26 100644 --- a/src/process.c +++ b/src/process.c @@ -1446,6 +1446,18 @@ See `set-process-sentinel' for more info on sentinels. */) return XPROCESS (process)->sentinel; } +static void +set_proc_thread (struct Lisp_Process *proc, struct thread_state *thrd) +{ + eassert (THREADP (proc->thread) && XTHREAD (proc->thread) == thrd); + eassert (proc->infd < FD_SETSIZE); + if (proc->infd >= 0) + fd_callback_info[proc->infd].thread = thrd; + eassert (proc->outfd < FD_SETSIZE); + if (proc->outfd >= 0) + fd_callback_info[proc->outfd].thread = thrd; +} + DEFUN ("set-process-thread", Fset_process_thread, Sset_process_thread, 2, 2, 0, doc: /* Set the locking thread of PROCESS to be THREAD. @@ -1466,12 +1478,7 @@ If THREAD is nil, the process is unlocked. */) proc = XPROCESS (process); pset_thread (proc, thread); - eassert (proc->infd < FD_SETSIZE); - if (proc->infd >= 0) - fd_callback_info[proc->infd].thread = tstate; - eassert (proc->outfd < FD_SETSIZE); - if (proc->outfd >= 0) - fd_callback_info[proc->outfd].thread = tstate; + set_proc_thread (proc, tstate); return thread; } @@ -2261,6 +2268,8 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) && !EQ (p->filter, Qt)) add_process_read_fd (inchannel); + set_proc_thread (p, current_thread); + specpdl_ref count = SPECPDL_INDEX (); /* This may signal an error. */ commit 37325ed5a9c7f62c35b368d9530496ed31404940 Author: Spencer Baugh Date: Thu Aug 14 12:17:23 2025 -0400 Zero fd_callback_info when deleting an fd .waiting_thread and .thread could be left set to non-NULL values in a deleted fd_callback_info entry. These would never be cleared by e.g. clear_waiting_thread_info since that only clears fd_callback_info entries up to max_desc. Clear fd_callback_info entirely when deleting an entry. * src/process.c (clear_fd_callback_data): Add. (delete_write_fd, delete_keyboard_wait_descriptor): Call clear_fd_callback_data. (bug#79201) (delete_read_fd): Remove duplicated clearing code. (deactivate_process): Remove duplicate recompute_max_desc. diff --git a/src/process.c b/src/process.c index e61ec425f7e..ccad26b5339 100644 --- a/src/process.c +++ b/src/process.c @@ -466,6 +466,16 @@ static struct fd_callback_data struct thread_state *waiting_thread; } fd_callback_info[FD_SETSIZE]; +static void +clear_fd_callback_data(struct fd_callback_data* elem) +{ + elem->func = NULL; + elem->data = NULL; + elem->flags = 0; + elem->thread = NULL; + elem->waiting_thread = NULL; +} + /* Add a file descriptor FD to be monitored for when read is possible. When read is possible, call FUNC with argument DATA. */ @@ -507,13 +517,6 @@ void delete_read_fd (int fd) { delete_keyboard_wait_descriptor (fd); - - eassert (0 <= fd && fd < FD_SETSIZE); - if (fd_callback_info[fd].flags == 0) - { - fd_callback_info[fd].func = 0; - fd_callback_info[fd].data = 0; - } } /* Add a file descriptor FD to be monitored for when write is possible. @@ -574,8 +577,7 @@ delete_write_fd (int fd) fd_callback_info[fd].flags &= ~(FOR_WRITE | NON_BLOCKING_CONNECT_FD); if (fd_callback_info[fd].flags == 0) { - fd_callback_info[fd].func = 0; - fd_callback_info[fd].data = 0; + clear_fd_callback_data(&fd_callback_info[fd]); if (fd == max_desc) recompute_max_desc (); @@ -4839,8 +4841,6 @@ deactivate_process (Lisp_Object proc) delete_read_fd (inchannel); if ((fd_callback_info[inchannel].flags & NON_BLOCKING_CONNECT_FD) != 0) delete_write_fd (inchannel); - if (inchannel == max_desc) - recompute_max_desc (); } } @@ -8312,7 +8312,7 @@ delete_keyboard_wait_descriptor (int desc) #ifdef subprocesses eassert (desc >= 0 && desc < FD_SETSIZE); - fd_callback_info[desc].flags &= ~(FOR_READ | KEYBOARD_FD | PROCESS_FD); + clear_fd_callback_data(&fd_callback_info[desc]); if (desc == max_desc) recompute_max_desc (); commit 406140df33f9da3ac592a9a1d214d9c0bbce08c1 Author: Eli Zaretskii Date: Sat Aug 16 12:04:59 2025 +0300 ; Skip a process-test that is unreliable on MS-Windows * test/src/process-tests.el (process-tests/multiple-threads-waiting): Skip on MS-Windows. diff --git a/test/src/process-tests.el b/test/src/process-tests.el index 0693bbe8924..641766ca7a9 100644 --- a/test/src/process-tests.el +++ b/test/src/process-tests.el @@ -927,6 +927,9 @@ have written output." (ert-deftest process-tests/multiple-threads-waiting () :tags (if (getenv "EMACS_EMBA_CI") '(:unstable)) + ;; This test assumes too much of Posix functionality, and thus is + ;; unreliable on MS-Windows. + (skip-when (eq system-type 'windows-nt)) (skip-unless (fboundp 'make-thread)) (with-timeout (60 (ert-fail "Test timed out")) (process-tests--with-processes processes commit ff05a689e3d6e13a1d4287270af5700ff6a919d6 Author: john muhl Date: Mon Aug 11 17:43:20 2025 -0500 (diff--font-lock-prettify): Fix fringe width test * lisp/vc/diff-mode.el (diff--font-lock-prettify): Use 'window-fringes' instead of the 'left-fringe' frame parameter since the former returns an integer on both GUI and TTY frames. diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 31a505f19be..965ab861e05 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -1600,7 +1600,7 @@ else cover the whole buffer." (remove-overlays nil nil 'diff-mode 'syntax) (when font-lock-mode (make-local-variable 'font-lock-extra-managed-props) - ;; Added when diff--font-lock-prettify is non-nil! + ;; Added when diff-font-lock-prettify is non-nil! (cl-pushnew 'display font-lock-extra-managed-props))) (defvar-local diff-mode-read-only nil @@ -2949,7 +2949,10 @@ fixed, visit it in a buffer." (defun diff--font-lock-prettify (limit) (when diff-font-lock-prettify - (when (> (frame-parameter nil 'left-fringe) 0) + ;; FIXME: `window-fringes` uselessly allocates 4 cons cells, + ;; but the previous use of `frame-paramter' ended up internally + ;; calling `frame-parameters' making it even worse! + (when (> (car (window-fringes)) 0) (save-excursion ;; FIXME: Include the first space for context-style hunks! (while (re-search-forward "^[-+! ]" limit t) @@ -2965,7 +2968,7 @@ fixed, visit it in a buffer." (?! . (left-fringe diff-fringe-rep diff-indicator-changed)) (?\s . (left-fringe diff-fringe-nul fringe))))))))) ;; Mimics the output of Magit's diff. - ;; FIXME: This has only been tested with Git's diff output. + ;; FIXME: This has been tested only with Git's diff output. ;; FIXME: Add support for Git's "rename from/to"? (while (re-search-forward "^diff " limit t) ;; We split the regexp match into a search plus a looking-at because commit 01e351de60d402875216161ef2460b42297337db Author: Eli Zaretskii Date: Sat Aug 16 10:53:12 2025 +0300 Reject non-nil non-number REPEAT in 'run-with-timer' * lisp/emacs-lisp/timer.el (run-at-time, run-with-timer): Reject non-nil REPEAT if it is not a non-negative number. (Bug#79227) Doc fixes. * test/lisp/emacs-lisp/timer-tests.el (timer-test-repeat-arg): New test. 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/test/lisp/emacs-lisp/timer-tests.el b/test/lisp/emacs-lisp/timer-tests.el index 8de3d7f0503..ac8ae7c4a21 100644 --- a/test/lisp/emacs-lisp/timer-tests.el +++ b/test/lisp/emacs-lisp/timer-tests.el @@ -65,4 +65,24 @@ (let ((nt (timer-next-integral-multiple-of-time '(32770 . 65539) 0.5))) (should (time-equal-p 1 nt)))) +(ert-deftest timer-test-repeat-arg () + "Test bug#79227." + (should (run-at-time nil nil 'ignore)) + (should (run-at-time nil 0 'ignore)) + (should (run-at-time nil 1.5 'ignore)) + ;; Test REPEAT that is neither nil nor a non-negative number. + (let ((err (should-error (run-at-time nil t 'ignore)))) + (should (equal err '(error . ("Invalid repetition interval: t")))) + ;; Test REPEAT that is a negative number. + (setq err (should-error (run-at-time nil -1.5 'ignore))) + (should (equal err '(error . ("Invalid repetition interval: -1.5"))))) + ;; Same tests for run-with-timer. + (should (run-with-timer 0 nil 'ignore)) + (should (run-with-timer 0 0 'ignore)) + (should (run-with-timer 0 1.5 'ignore)) + (let ((err (should-error (run-with-timer 0 t 'ignore)))) + (should (equal err '(error . ("Invalid repetition interval: t")))) + (setq err (should-error (run-with-timer 0 -1.5 'ignore))) + (should (equal err '(error . ("Invalid repetition interval: -1.5")))))) + ;;; timer-tests.el ends here commit f8a206937c9f548bd810153bf29f4f4a32d84c95 Author: Zhengyi Fu Date: Thu Aug 14 17:08:36 2025 +0200 executable-interpret: Handle remote file names * lisp/progmodes/executable.el (executable-interpret): Use `file-local-name' to get the local file name component from `buffer-file-name'. (Bug#79233) Copyright-paperwork-exempt: yes 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) commit c17168ebed9b0ace53235aa34fff4e53ca8543d3 Author: Eli Zaretskii Date: Thu Aug 14 15:13:07 2025 +0300 ; * admin/make-tarball.txt: Fix typo and add details. 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. commit 34f35407eb2d6d5f977ae671058eb17aa80dd58b Author: Eli Zaretskii Date: Thu Aug 14 06:46:32 2025 -0400 Bump Emacs version to 30.2.50 * README: * configure.ac: * exec/configure.ac: * java/AndroidManifest.xml.in (Version-code): * nt/README.W32: * msdos/sed2v2.inp: Bump Emacs version to 30.2.50. * etc/NEWS: Add headers for Emacs 30.2. diff --git a/README b/README index 9f7008748ac..7032fadf713 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Copyright (C) 2001-2025 Free Software Foundation, Inc. See the end of the file for license conditions. -This directory tree holds version 30.2 of GNU Emacs, the extensible, +This directory tree holds version 30.2.50 of GNU Emacs, the extensible, customizable, self-documenting real-time display editor. The file INSTALL in this directory says how to build and install GNU diff --git a/configure.ac b/configure.ac index aedf5de759f..d91395e9163 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see . AC_PREREQ([2.65]) dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el. -AC_INIT([GNU Emacs], [30.2], [bug-gnu-emacs@gnu.org], [], +AC_INIT([GNU Emacs], [30.2.50], [bug-gnu-emacs@gnu.org], [], [https://www.gnu.org/software/emacs/]) if test "$XCONFIGURE" = "android"; then diff --git a/etc/NEWS b/etc/NEWS index dfe6c5cafe6..56f0953cd3e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -15,6 +15,33 @@ 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.3 + + +* Startup Changes in Emacs 30.3 + + +* Changes in Emacs 30.3 + + +* Editing Changes in Emacs 30.3 + + +* Changes in Specialized Modes and Packages in Emacs 30.3 + + +* New Modes and Packages in Emacs 30.3 + + +* Incompatible Lisp Changes in Emacs 30.3 + + +* Lisp Changes in Emacs 30.3 + + +* Changes in Emacs 30.3 on Non-Free Operating Systems + * Changes in Emacs 30.2 Emacs 30.2 is a bug-fix release with no new features. diff --git a/exec/configure.ac b/exec/configure.ac index 40df33d5cfc..54875f1868f 100644 --- a/exec/configure.ac +++ b/exec/configure.ac @@ -22,7 +22,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with GNU Emacs. If not, see . AC_PREREQ([2.65]) -AC_INIT([libexec], [30.2], [bug-gnu-emacs@gnu.org], [], +AC_INIT([libexec], [30.2.50], [bug-gnu-emacs@gnu.org], [], [https://www.gnu.org/software/emacs/]) AH_TOP([/* Copyright (C) 2024-2025 Free Software Foundation, Inc. diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in index afc38bbb6b0..dceddcdcff9 100644 --- a/java/AndroidManifest.xml.in +++ b/java/AndroidManifest.xml.in @@ -350,6 +350,6 @@ repositories require an incrementing numeric version code to detect upgrades, which is provided here and is altered by admin/admin.el. Refer to e.g. https://forum.f-droid.org/t/emacs-packaging/30424/25. -Version-code: 300200000 +Version-code: 300250000 --> diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index e487e169f54..0757727c2c0 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -67,7 +67,7 @@ /^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/ /^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/ /^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/ -/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "30.2"/ +/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "30.2.50"/ /^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/ /^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/ /^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/ diff --git a/nt/README.W32 b/nt/README.W32 index 4a588d7b4a8..ede1632dfdd 100644 --- a/nt/README.W32 +++ b/nt/README.W32 @@ -1,7 +1,7 @@ Copyright (C) 2001-2025 Free Software Foundation, Inc. See the end of the file for license conditions. - Emacs version 30.2 for MS-Windows + Emacs version 30.2.50 for MS-Windows This README file describes how to set up and run a precompiled distribution of the latest version of GNU Emacs for MS-Windows. You commit 636f166cfc86aa90d63f592fd99f3fdd9ef95ebd (tag: refs/tags/emacs-30.2) Author: Eli Zaretskii Date: Thu Aug 14 05:04:03 2025 -0400 ; * make-dist: Include ELisp hierarchy diagram in tarballs (bug#76441). diff --git a/make-dist b/make-dist index ba82b261743..2b287284a3a 100755 --- a/make-dist +++ b/make-dist @@ -369,7 +369,7 @@ possibly_non_vc_files=" ) || exit if [ $with_info = yes ]; then - info_files="info/dir $(echo info/*.info)" || exit + info_files="info/dir $(echo info/*.info info/*.txt info/*.jpg)" || exit else info_files= fi commit 1514695b7d10f67279aeaa14e1cc398d8a07cf08 Author: Eli Zaretskii Date: Thu Aug 14 04:24:11 2025 -0400 ; Update lisp/ldefs-boot.el. Do not merge to master. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 57790632047..6a56cb08a43 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: @@ -7556,8 +7557,9 @@ Also see the `diff-entire-buffers' variable. (autoload 'diff-mode "diff-mode" "\ Major mode for viewing/editing context diffs. -Supports unified and context diffs as well as (to a lesser extent) -normal diffs. +Supports unified and context diffs as well as, to a lesser extent, diffs +in the old \"normal\" format. (Unified diffs have become the standard, +most commonly encountered format.) When the buffer is read-only, the ESC prefix is not necessary. If you edit the buffer manually, `diff-mode' will try to update the hunk @@ -8439,8 +8441,8 @@ switch on the minor mode in all major modes), nil (meaning don't switch on in any major mode), a list of modes (meaning switch on only in those modes and their descendants), or a list (not MODES...), meaning switch on in any major mode except MODES. The value can also -mix all of these forms, see the info node `Defining Minor Modes' for -details. The :predicate key causes the macro to create a user option +mix all of these forms, see the Info node `(elisp)Defining Minor Modes' +for details. The :predicate key causes the macro to create a user option named the same as MODE, but ending with \"-modes\" instead of \"-mode\". That user option can then be used to customize in which modes this globalized minor mode will be switched on. @@ -12903,7 +12905,7 @@ is non-nil, signal an error instead. (fn FUNCTION &optional LISP-ONLY)") (autoload 'find-function "find-func" "\ -Find the definition of the FUNCTION near point. +Find the definition of the Emacs Lisp FUNCTION near point. Finds the source file containing the definition of the function near point (selected by `function-called-at-point') in a buffer and @@ -12912,6 +12914,9 @@ Set mark before moving, if the buffer already existed. See also `find-function-recenter-line' and `find-function-after-hook'. +Use \\[xref-find-definitions] to find definitions of functions and variables +that are not part of Emacs. + (fn FUNCTION)" t) (autoload 'find-function-other-window "find-func" "\ Find, in another window, the definition of FUNCTION near point. @@ -18022,8 +18027,9 @@ Toggle thumbnails in front of marked file names in the Dired buffer. If no file is marked, toggle display of thumbnail on the current file's line. ARG, if non-nil (interactively, the prefix argument), specifies the files whose thumbnail display to toggle instead of the marked files: if ARG is an -integer, use the next ARG (or previous -ARG, if ARG<0) files; any other -value of ARG means toggle thumbnail display of the current line's file. +integer, use the next ARG (or previous -ARG, if ARG<0) files; if ARG is +the symbol `marked', use only the marked files, if any; any other value of +ARG means toggle thumbnail display of the current line's file. (fn &optional ARG)" '(dired-mode)) (autoload 'image-dired-jump-thumbnail-buffer "image-dired-dired" "\ @@ -33816,7 +33822,7 @@ Add archive file name handler to `file-name-handler-alist'." (when (and tramp-ar ;;; Generated autoloads from net/trampver.el -(push (purecopy '(tramp 2 7 3 -1)) package--builtin-versions) +(push (purecopy '(tramp 2 7 3 30 2)) package--builtin-versions) (register-definition-prefixes "trampver" '("tramp-")) commit 8960e3af819f67799ef141c7b62d5abcdcdd7efc Author: Eli Zaretskii Date: Thu Aug 14 04:05:28 2025 -0400 Update files for Emacs 30.2 * ChangeLog.5: * etc/AUTHORS: * etc/HISTORY: Update for Emacs 30.2. * admin/admin.el (set-version): Fix handling of official releases. 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/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/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. commit ebeca61755e61feed530179dd538b4f0f08862bc Author: Eli Zaretskii Date: Thu Aug 14 03:54:52 2025 -0400 * admin/admin.el (set-version): Fix handling of official releases. diff --git a/admin/admin.el b/admin/admin.el index 0f02ac8d9b1..66c83225aef 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) commit 8ddef0ad4d6a7a53c84000303923b9530ab28b6c Author: Eli Zaretskii Date: Thu Aug 14 03:52:16 2025 -0400 Bump Emacs version * README: * configure.ac: * exec/configure.ac: * java/AndroidManifest.xml.in (Version-code): * nt/README.W32: * msdos/sed2v2.inp: Bump Emacs version to 30.2. diff --git a/README b/README index d0f2d580b4f..9f7008748ac 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ Copyright (C) 2001-2025 Free Software Foundation, Inc. See the end of the file for license conditions. -This directory tree holds version 30.1.90 of GNU Emacs, the extensible, +This directory tree holds version 30.2 of GNU Emacs, the extensible, customizable, self-documenting real-time display editor. The file INSTALL in this directory says how to build and install GNU diff --git a/configure.ac b/configure.ac index e57cf55fe86..aedf5de759f 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see . AC_PREREQ([2.65]) dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el. -AC_INIT([GNU Emacs], [30.1.90], [bug-gnu-emacs@gnu.org], [], +AC_INIT([GNU Emacs], [30.2], [bug-gnu-emacs@gnu.org], [], [https://www.gnu.org/software/emacs/]) if test "$XCONFIGURE" = "android"; then diff --git a/exec/configure.ac b/exec/configure.ac index c66c7276d8c..40df33d5cfc 100644 --- a/exec/configure.ac +++ b/exec/configure.ac @@ -22,7 +22,7 @@ dnl You should have received a copy of the GNU General Public License dnl along with GNU Emacs. If not, see . AC_PREREQ([2.65]) -AC_INIT([libexec], [30.1.90], [bug-gnu-emacs@gnu.org], [], +AC_INIT([libexec], [30.2], [bug-gnu-emacs@gnu.org], [], [https://www.gnu.org/software/emacs/]) AH_TOP([/* Copyright (C) 2024-2025 Free Software Foundation, Inc. diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in index 711d34cff30..afc38bbb6b0 100644 --- a/java/AndroidManifest.xml.in +++ b/java/AndroidManifest.xml.in @@ -350,6 +350,6 @@ repositories require an incrementing numeric version code to detect upgrades, which is provided here and is altered by admin/admin.el. Refer to e.g. https://forum.f-droid.org/t/emacs-packaging/30424/25. -Version-code: 300190000 +Version-code: 300200000 --> diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp index f9b5af84e25..e487e169f54 100644 --- a/msdos/sed2v2.inp +++ b/msdos/sed2v2.inp @@ -67,7 +67,7 @@ /^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/ /^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/ /^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/ -/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "30.1.90"/ +/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "30.2"/ /^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/ /^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/ /^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/ diff --git a/nt/README.W32 b/nt/README.W32 index bdd726f038d..4a588d7b4a8 100644 --- a/nt/README.W32 +++ b/nt/README.W32 @@ -1,7 +1,7 @@ Copyright (C) 2001-2025 Free Software Foundation, Inc. See the end of the file for license conditions. - Emacs version 30.1.90 for MS-Windows + Emacs version 30.2 for MS-Windows This README file describes how to set up and run a precompiled distribution of the latest version of GNU Emacs for MS-Windows. You commit 49d64bfb1a4ca5fc8b3a4d215fb6cabbb9780f9b Author: Eli Zaretskii Date: Thu Aug 14 03:03:07 2025 -0400 ; * etc/NEWS: Update for Emacs 30.2. diff --git a/etc/NEWS b/etc/NEWS index c52929b6d38..dfe6c5cafe6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -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 commit 4b90b6e7ce9be06087e727f7c6305a2a545660fc Author: Eli Zaretskii Date: Sun Aug 10 11:45:31 2025 +0300 ; * lisp/emacs-lisp/cl-generic.el (cl-defgeneric): Doc fix (bug#79206). diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el index 3aa26fba3c3..7e0f115ebcb 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)