commit d967cf5117019190fc8aadba22e039efcc8e77a5 (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Sat Nov 8 09:04:32 2025 +0200 ; * etc/TODO: Add an item about @math images in Info buffers. diff --git a/etc/TODO b/etc/TODO index 0700452b757..40cfbbb85d7 100644 --- a/etc/TODO +++ b/etc/TODO @@ -547,6 +547,34 @@ One way of doing this is to start with fx's dynamic loading, and use it to implement things like auto-loaded buffer parsers and database access in cases which need more than Lisp. +** In Info, support image files generated from @math expressions +See this discussion on the Texinfo mailing list for the details: + + https://lists.gnu.org/archive/html/bug-texinfo/2024-12/msg00061.html + https://lists.gnu.org/archive/html/bug-texinfo/2025-01/msg00004.html + https://lists.gnu.org/archive/html/bug-texinfo/2025-11/msg00002.html + +The job here is to figure out the image attributes that will produce +good-looking display of math formulas in images created by LaTeX from +Texinfo @math elements. The above discussion concluded that just +showing these images as any other image sometimes produces misaligned +display and sometimes the size of the image needs tweaking to make it +similar to the default face's font used for showing the text in Info +buffers. The assumption is that using some non-default attributes of +image specs, like :ascent, :margin, and :height, and perhaps also using +:scale with the value 'auto', should be able to improve the display. +The conclusions should be communicated to the Texinfo developers, so +that 'makeinfo' could embed the necessary image attributes in the Info +output it produces from @math. + +The function in info.el which handles image display is +'Info-display-images-node'. + +The message below in Texinfo mailing list archives includes files that +could be used to work in this feature: + + https://lists.gnu.org/archive/html/bug-texinfo/2025-11/msg00012.html + ** Imenu could be extended into a file-structure browsing mechanism This could use code like that of customize-groups. commit 3cc34865e85328b9f2eeb998662fb2635c281add Author: Eli Zaretskii Date: Fri Nov 7 18:44:49 2025 +0200 ; * lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate): Fix typo. diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index 6a40b3d84b0..fcec04115e4 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -663,11 +663,12 @@ instead of just updating them with the new/changed autoloads." ;; If we're scanning for package versions, we want to look ;; at the file even if it's excluded. (let* ((excluded - ;; FIXME: In out-of-tree builds (bug#79694) `excluded.files' + ;; FIXME: In out-of-tree builds (bug#79694) `excluded-files' ;; (derived via `lisp-directory' from `invocation-directory') ;; may end up using names which don't quite match those of - ;; `file' (derived from the command line arguments), w.r.t - ;; "c:" vs "C:", so use a test more lax than `member'. + ;; `file' (derived from the command line arguments), w.r.t. + ;; "c:/" vs "C:/" on MS-Windows, so use a test more lax + ;; than `member'. (let ((x (member-ignore-case file excluded-files))) (and x (file-equal-p file (car x))))) (package-data commit f356dca70b4d6a884c82ad6a29d2de7a91c54a7a Author: Stefan Monnier Date: Fri Nov 7 11:34:32 2025 -0500 lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate): Fix bug#79694 diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index d4c0a87e6f9..6a40b3d84b0 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -662,7 +662,14 @@ instead of just updating them with the new/changed autoloads." (file-attributes file)))) ;; If we're scanning for package versions, we want to look ;; at the file even if it's excluded. - (let* ((excluded (member file excluded-files)) + (let* ((excluded + ;; FIXME: In out-of-tree builds (bug#79694) `excluded.files' + ;; (derived via `lisp-directory' from `invocation-directory') + ;; may end up using names which don't quite match those of + ;; `file' (derived from the command line arguments), w.r.t + ;; "c:" vs "C:", so use a test more lax than `member'. + (let ((x (member-ignore-case file excluded-files))) + (and x (file-equal-p file (car x))))) (package-data (and include-package-version (if excluded 'only t)))) (when (or package-data (not excluded)) commit 5c18d23d66832c27632ffcb843770ca4b5c67897 Author: Stefan Monnier Date: Tue Nov 4 15:41:58 2025 -0500 (diff-refine-threshold): New custom var (bug#79546) Avoid getting stuck waiting for `diff` to refine big hunks. * lisp/vc/diff-mode.el (diff-refine-threshold): New custom var. (diff--refine-hunk): Add arg `skip-if-large` and use that new var if the arg says so. (diff-refine-hunk): Add arg `skip-if-large`. (diff-auto-refine-mode, diff-next/prevhunk, diff--font-lock-refined): Use it. diff --git a/etc/NEWS b/etc/NEWS index b3f8061f742..5c72fb469d7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1986,6 +1986,10 @@ the Tramp manual. ** Diff +--- +*** 'diff-mode' now refrains from automatically refining big hunks. +What is big is defined by the new 'diff-refine-threshold' variable. + --- *** New command 'diff-kill-ring-save'. This command copies to the 'kill-ring' a region of text modified diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index c6c6233485f..5c6db195807 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -113,6 +113,17 @@ You can always manually refine a hunk with `diff-refine-hunk'." (const :tag "Refine hunks during font-lock" font-lock) (const :tag "Refine hunks during navigation" navigation))) +(defcustom diff-refine-threshold 30000 ;FIXME: Arbitrary choice. + ;; FIXME: A better way to handle this would be to do the refinement + ;; asynchronously, so pathological cases just delay the refinement's display + ;; but don't freeze Emacs. + "Maximum size of diff hunk that can be automatically refined. +If a hunk is larger than that limit, measured in characters, `diff-refine' +is not automatically applied, to avoid pathological cases taking too long. +Does not affect the `diff-refine-hunk' interactive command." + :version "31.1" + :type 'integer) + (defcustom diff-font-lock-prettify nil "If non-nil, font-lock will try and make the format prettier. @@ -322,7 +333,8 @@ well." (if diff-auto-refine-mode (progn (customize-set-variable 'diff-refine 'navigation) - (condition-case-unless-debug nil (diff-refine-hunk) (error nil))) + (condition-case-unless-debug nil (diff-refine-hunk 'skip-if-large) + (error nil))) (customize-set-variable 'diff-refine nil)))) (make-obsolete 'diff-auto-refine-mode "set `diff-refine' instead." "27.1") (make-obsolete-variable 'diff-auto-refine-mode @@ -805,7 +817,7 @@ next hunk if TRY-HARDER is non-nil; otherwise signal an error." (with-current-buffer buffer (save-excursion (goto-char point) - (diff-refine-hunk)))))))))))) + (diff-refine-hunk 'skip-if-large)))))))))))) (easy-mmode-define-navigation diff-file diff-file-header-re "file" diff-end-of-file) @@ -2508,8 +2520,9 @@ Return new point, if it was moved." (setq pt (point))) pt)) -(defun diff-refine-hunk () - "Highlight changes of hunk at point at a finer granularity." +(defun diff-refine-hunk (&optional skip-if-large) + "Highlight changes of hunk at point at a finer granularity. +If SKIP-IF-LARGE is non-nil, obey `diff-refine-threshold'." (interactive) (when (diff--some-hunks-p) (save-excursion @@ -2517,7 +2530,7 @@ Return new point, if it was moved." ;; Be careful to start from the hunk header so diff-end-of-hunk ;; gets to read the hunk header's line info. (end (progn (diff-end-of-hunk) (point)))) - (diff--refine-hunk beg end))))) + (diff--refine-hunk beg end skip-if-large))))) (defun diff--refine-propertize (beg end face) (let ((ol (make-overlay beg end))) @@ -2537,7 +2550,7 @@ by `diff-refine-hunk'." :version "30.1" :type 'boolean) -(defun diff--refine-hunk (start end) +(defun diff--refine-hunk (start end &optional skip-if-large) (require 'smerge-mode) (goto-char start) (let* ((style (diff-hunk-style)) ;Skips the hunk header as well. @@ -2550,6 +2563,17 @@ by `diff-refine-hunk'." (goto-char beg) (pcase style + ((guard (and skip-if-large + ;; FIXME: Maybe instead of testing the hunk size, we + ;; should test the size of each individual "delete+insert" + ;; pairs, since a big hunk with many small del+ins pairs + ;; should not suffer from the usual pathological + ;; complexity problems. + ;; Or maybe even push the test down into + ;; `smerge-refine-regions' where `smerge-mode' could + ;; also use it? + (> (- end beg) diff-refine-threshold))) + nil) ('unified (while (re-search-forward "^[-+]" end t) (let ((beg-del (progn (beginning-of-line) (point))) @@ -2669,7 +2693,7 @@ Call FUN with two args (BEG and END) for each hunk." max (lambda (beg end) (unless (get-char-property beg 'diff--font-lock-refined) - (diff--refine-hunk beg end) + (diff--refine-hunk beg end 'skip-if-large) (let ((ol (make-overlay beg end))) (overlay-put ol 'diff--font-lock-refined t) (overlay-put ol 'diff-mode 'fine) commit 7557dcbabf5dd2dcd8e40a7f0d92db842b677ed9 Author: Sean Whitton Date: Thu Oct 30 21:21:53 2025 +0000 New tests for vc-exec-after * test/lisp/vc/vc-tests/vc-test-misc.el (vc-test--exec-after-wait): New macro. (vc-test-exec-after-1, vc-test-exec-after-2) (vc-test-exec-after-3, vc-test-exec-after-4) (vc-test-exec-after-5): New tests. diff --git a/test/lisp/vc/vc-tests/vc-test-misc.el b/test/lisp/vc/vc-tests/vc-test-misc.el index 22015358972..33aebbdb895 100644 --- a/test/lisp/vc/vc-tests/vc-test-misc.el +++ b/test/lisp/vc/vc-tests/vc-test-misc.el @@ -63,5 +63,93 @@ (should (equal (test-it `(Git ("missing" ,temp "present"))) missing+present)))))) +(defmacro vc-test--exec-after-wait () + '(progn + (while (process-live-p proc) + (when (input-pending-p) + (discard-input)) + (should-not success) + (sit-for 0.05)) + (sit-for 0.05))) + +(ert-deftest vc-test-exec-after-1 () + "Test `vc-exec-after' adding a sentinel." + (with-temp-buffer + (let ((proc (start-process-shell-command "test" (current-buffer) + "sleep 0.2; echo hello")) + success) + (vc-exec-after (lambda () (setq success t))) + (should-not (eq (process-sentinel proc) + #'internal-default-process-sentinel)) + (vc-test--exec-after-wait) + (should success)))) + +(ert-deftest vc-test-exec-after-2 () + "Test `vc-exec-after' executing the code immediately." + (with-temp-buffer + (let ((proc (start-process-shell-command "test" (current-buffer) + "sleep 0.2; echo hello")) + success) + (vc-test--exec-after-wait) + (vc-exec-after (lambda () (setq success t))) + (should (eq (process-sentinel proc) + #'internal-default-process-sentinel)) + (should success)))) + +(ert-deftest vc-test-exec-after-3 () + "Test SUCCESS argument to `vc-exec-after'." + (with-temp-buffer + (let ((proc (start-process-shell-command "test" (current-buffer) + "sleep 0.2; echo hello")) + (passes (start-process "test2" nil "true")) + success) + (vc-exec-after (lambda () (setq success t)) passes) + (vc-test--exec-after-wait) + (should success))) + + (with-temp-buffer + (let ((proc (start-process-shell-command "test" (current-buffer) + "sleep 0.2; echo hello")) + (fails (start-process "test2" nil "false")) + success) + (vc-exec-after (lambda () (setq success t)) fails) + (vc-test--exec-after-wait) + (should-not success)))) + +(ert-deftest vc-test-exec-after-4 () + "Test `vc-exec-after' handling the process mark." + (with-temp-buffer + (let ((proc (start-process-shell-command "test" (current-buffer) + "echo hello there; sleep 0.2")) + success) + ;; Disable the default output, which further moves point. + (set-process-sentinel proc #'ignore) + + (vc-exec-after (lambda () + (goto-char (point-min)) + (should (looking-at "hello")))) + (vc-exec-after (lambda () + (forward-word 1) + (should (looking-at " there")))) + (accept-process-output proc) + (let ((opoint (point))) + (vc-test--exec-after-wait) + (should (eq (point) opoint)))))) + +(ert-deftest vc-test-exec-after-5 () + "Test `vc-exec-after' with `vc-sentinel-movepoint' variable." + (with-temp-buffer + (let ((proc (start-process-shell-command "test" (current-buffer) + "echo hello there; sleep 0.2")) + success) + ;; Disable the default output, which further moves point. + (set-process-sentinel proc #'ignore) + + (vc-exec-after (lambda () (setq vc-sentinel-movepoint (point-min)))) + (accept-process-output proc) + (should-not (eq (point) (point-min))) + (vc-test--exec-after-wait) + (should (eq (point) (point-min)))))) + (provide 'vc-test-misc) ;;; vc-test-misc.el ends here commit 4eb36ad44d1c179a0ef912053fb78e71dc4d2193 Author: Sean Whitton Date: Thu Oct 30 20:45:31 2025 +0000 vc-exec-after: Pass zero timeout to accept-process-output * lisp/vc/vc-dispatcher.el (vc-exec-after): Pass zero timeout to accept-process-output. Fix due to Spencer Baugh . diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index c8e1ead318a..14b57f23864 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -280,7 +280,10 @@ Only run CODE if the SUCCESS process has a zero exit code." ;; lost. Terminated processes get deleted automatically ;; anyway. -- cyd ((or (null proc) (eq (process-status proc) 'exit)) - (when proc (accept-process-output proc)) + (when proc + ;; Nonblocking call in case we are ourselves called from a + ;; process sentinel (GNU ELPA's diff-hl does this). + (accept-process-output proc 0)) (funcall eval-code)) ((eq (process-status proc) 'run) (when (buffer-live-p buf) commit 4fbc6088f2690145c18567b82d554cf72d27c6a4 Author: Sean Whitton Date: Wed Oct 29 18:20:30 2025 +0000 Replace recursive calls of vc-exec-after * lisp/vc/vc-dispatcher.el (vc-exec-after): Refactor so as to no longer repeatedly add and remove the sentinel. Don't have two different ways to set mode-line-process. Don't call accept-process-output from the sentinel, because Emacs always reads all available process output before calling sentinels. diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index aeea56fde3e..c8e1ead318a 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -232,21 +232,25 @@ CODE. Otherwise, add CODE to the process's sentinel. If SUCCESS, it should be a process object. Only run CODE if the SUCCESS process has a zero exit code." (unless proc (setq proc (get-buffer-process (current-buffer)))) - (letrec ((buf (and proc (process-buffer proc))) + (letrec ((eval-code + (lambda () + (when (or (not success) + (zerop (process-exit-status success))) + (if (functionp code) (funcall code) (eval code t))))) + (buf (and proc (process-buffer proc))) (fun (lambda (proc _msg) ;; In the unlikely event of `set-buffer-process'. (setq buf (process-buffer proc)) - (remove-function (process-sentinel proc) fun) - ;; Impatient users sometime kill "slow" buffers; check liveness - ;; to avoid "error in process sentinel: Selecting deleted buffer". - (when (buffer-live-p buf) + (cond + ;; Impatient users sometime kill "slow" buffers; check + ;; liveness to avoid "error in process sentinel: + ;; Selecting deleted buffer". + ((not (buffer-live-p buf)) + (remove-function (process-sentinel proc) fun)) + ((eq (process-status proc) 'exit) (with-current-buffer buf - (setq mode-line-process - (let ((status (process-status proc))) - ;; Leave mode-line uncluttered, normally. - (and (not (eq 'exit status)) - (format " (%s)" status)))) + (setq mode-line-process nil) (let (vc-sentinel-movepoint (m (process-mark proc))) ;; Normally, we want async code such as sentinels to @@ -258,14 +262,17 @@ Only run CODE if the SUCCESS process has a zero exit code." ;; Handling this up here, instead of requiring ;; CODE to handle it, means CODE can be written ;; for both sync and async processes. - (vc-exec-after code success) + (funcall eval-code) (move-marker m (point))) ;; But sometimes the sentinels really want to move point. (when vc-sentinel-movepoint (if-let* ((win (get-buffer-window (current-buffer) 0))) (with-selected-window win (goto-char vc-sentinel-movepoint)) - (goto-char vc-sentinel-movepoint))))))))) + (goto-char vc-sentinel-movepoint)))))) + ((not (eq (process-status proc) 'run)) + (remove-function (process-sentinel proc) fun) + (error "Unexpected process state")))))) (cond ;; If there's no background process, just execute the code. ;; We used to explicitly call delete-process on exited processes, @@ -274,9 +281,7 @@ Only run CODE if the SUCCESS process has a zero exit code." ;; anyway. -- cyd ((or (null proc) (eq (process-status proc) 'exit)) (when proc (accept-process-output proc)) - (when (or (not success) - (zerop (process-exit-status success))) - (if (functionp code) (funcall code) (eval code t)))) + (funcall eval-code)) ((eq (process-status proc) 'run) (when (buffer-live-p buf) (with-current-buffer buf commit bdaf49fd0c9cee84d32e4631c44a827c08daed87 Author: Sean Whitton Date: Wed Oct 29 17:57:11 2025 +0000 Merge vc--process-sentinel into vc-exec-after * lisp/vc/vc-dispatcher.el (vc--process-sentinel, vc-exec-after): Merge vc--process-sentinel into vc-exec-after. Tidy up. This should not involve any functional changes; those are to follow. diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index 4b893169a33..aeea56fde3e 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -210,38 +210,7 @@ Another is that undo information is not kept." (inhibit-read-only t)) (erase-buffer)))) -(defvar vc-sentinel-movepoint) ;Dynamically scoped. - -(defun vc--process-sentinel (p code &optional success) - (let ((buf (process-buffer p))) - ;; Impatient users sometime kill "slow" buffers; check liveness - ;; to avoid "error in process sentinel: Selecting deleted buffer". - (when (buffer-live-p buf) - (with-current-buffer buf - (setq mode-line-process - (let ((status (process-status p))) - ;; Leave mode-line uncluttered, normally. - (unless (eq 'exit status) - (format " (%s)" status)))) - (let (vc-sentinel-movepoint - (m (process-mark p))) - ;; Normally, we want async code such as sentinels to not move point. - (save-excursion - (goto-char m) - ;; Each sentinel may move point and the next one should be run - ;; at that new point. We could get the same result by having - ;; each sentinel read&set process-mark, but since `cmd' needs - ;; to work both for async and sync processes, this would be - ;; difficult to achieve. - (vc-exec-after code success) - (move-marker m (point))) - ;; But sometimes the sentinels really want to move point. - (when vc-sentinel-movepoint - (let ((win (get-buffer-window (current-buffer) 0))) - (if (not win) - (goto-char vc-sentinel-movepoint) - (with-selected-window win - (goto-char vc-sentinel-movepoint)))))))))) +(defvar vc-sentinel-movepoint) (defun vc-set-mode-line-busy-indicator () (setq mode-line-process @@ -253,6 +222,7 @@ Another is that undo information is not kept." (defun vc-exec-after (code &optional success proc) "Execute CODE when PROC, or the current buffer's process, is done. CODE should be a function of no arguments. +CODE a bare form to pass to `eval' is also supported for compatibility. The optional PROC argument specifies the process Emacs should wait for before executing CODE. It defaults to the current buffer's process. @@ -261,7 +231,41 @@ CODE. Otherwise, add CODE to the process's sentinel. If SUCCESS, it should be a process object. Only run CODE if the SUCCESS process has a zero exit code." - (let ((proc (or proc (get-buffer-process (current-buffer))))) + (unless proc (setq proc (get-buffer-process (current-buffer)))) + (letrec ((buf (and proc (process-buffer proc))) + (fun + (lambda (proc _msg) + ;; In the unlikely event of `set-buffer-process'. + (setq buf (process-buffer proc)) + (remove-function (process-sentinel proc) fun) + ;; Impatient users sometime kill "slow" buffers; check liveness + ;; to avoid "error in process sentinel: Selecting deleted buffer". + (when (buffer-live-p buf) + (with-current-buffer buf + (setq mode-line-process + (let ((status (process-status proc))) + ;; Leave mode-line uncluttered, normally. + (and (not (eq 'exit status)) + (format " (%s)" status)))) + (let (vc-sentinel-movepoint + (m (process-mark proc))) + ;; Normally, we want async code such as sentinels to + ;; not move point. + (save-excursion + (goto-char m) + ;; Each sentinel may move point and the next one + ;; should be run from that new position. + ;; Handling this up here, instead of requiring + ;; CODE to handle it, means CODE can be written + ;; for both sync and async processes. + (vc-exec-after code success) + (move-marker m (point))) + ;; But sometimes the sentinels really want to move point. + (when vc-sentinel-movepoint + (if-let* ((win (get-buffer-window (current-buffer) 0))) + (with-selected-window win + (goto-char vc-sentinel-movepoint)) + (goto-char vc-sentinel-movepoint))))))))) (cond ;; If there's no background process, just execute the code. ;; We used to explicitly call delete-process on exited processes, @@ -269,21 +273,15 @@ Only run CODE if the SUCCESS process has a zero exit code." ;; lost. Terminated processes get deleted automatically ;; anyway. -- cyd ((or (null proc) (eq (process-status proc) 'exit)) - ;; Make sure we've read the process's output before going further. (when proc (accept-process-output proc)) (when (or (not success) (zerop (process-exit-status success))) (if (functionp code) (funcall code) (eval code t)))) - ;; If a process is running, add CODE to the sentinel ((eq (process-status proc) 'run) - (let ((buf (process-buffer proc))) - (when (buffer-live-p buf) - (with-current-buffer buf - (vc-set-mode-line-busy-indicator)))) - (letrec ((fun (lambda (p _msg) - (remove-function (process-sentinel p) fun) - (vc--process-sentinel p code success)))) - (add-function :after (process-sentinel proc) fun))) + (when (buffer-live-p buf) + (with-current-buffer buf + (vc-set-mode-line-busy-indicator))) + (add-function :after (process-sentinel proc) fun)) (t (error "Unexpected process state")))) nil) commit 645e8ca311a479b7aade0dcc233ecaf2198e38f8 Author: Sean Whitton Date: Fri Nov 7 15:33:04 2025 +0000 server-eval-at: End request in trailing space This is for consistency with how emacsclient behaves. * lisp/server.el (server--process-filter-1): Improve assertion. (server-eval-at): End request with trailing space. diff --git a/lisp/server.el b/lisp/server.el index bf3430b48d7..ca6f9e2448b 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1268,7 +1268,7 @@ The following commands are accepted by the client: ;; Remove this line from STRING. (setq string (substring string (match-end 0))) (cl-assert (equal (substring request -1) " ") - nil "emacsclient request did not end in SPC") + nil "emacsclient request did not end in SPC: %S" request) (setq args-left (mapcar #'server-unquote-arg (nbutlast (split-string request " ")))) (while args-left @@ -2091,7 +2091,7 @@ something that cannot be printed readably." (process-send-string process (concat "-eval " (server-quote-arg (format "%S" form)) - "\n")) + " \n")) (while (memq (process-status process) '(open run)) (accept-process-output process 0.01)) (goto-char (point-min)) commit 99a787a45146e6e4b80c8c9e79fdfc71a95dc383 Author: Dominik Schrempf Date: Wed Oct 29 16:21:37 2025 +0100 ; Fix description of use-package :custom keyword Copyright-paperwork-exempt: yes diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 65b9485b4e3..96b7a61edc9 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -1888,7 +1888,7 @@ Usage: :load-path Add to the `load-path' before attempting to load the package. :diminish Support for diminish.el (if installed). :delight Support for delight.el (if installed). -:custom Call `Custom-set' or `set-default' with each variable +:custom Call `customize-set-variable' on each variable definition without modifying the Emacs `custom-file'. (compare with `custom-set-variables'). :custom-face Call `face-spec-set' with each face definition. commit c1e8fc3069ca43a34ee5af845e47bc9cfbf8a877 Author: Jacob S. Gordon Date: Wed Oct 8 14:55:36 2025 -0400 ; Add missing defcustom types in eshell and eww (bug#79607) * lisp/eshell/esh-mode.el (eshell-scroll-to-bottom-on-input) (eshell-scroll-to-bottom-on-output): Add t as a choice. * lisp/net/eww.el (eww-restore-desktop): Add 'auto' as a choice. diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index 15dfd90dd8a..b41f7aa9055 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -128,7 +128,10 @@ buffer. If `this', scroll only the selected window. See `eshell-preinput-scroll-to-bottom'." :type '(radio (const :tag "Do not scroll Eshell windows" nil) - (const :tag "Scroll all windows showing the buffer" all) + (choice :tag "Scroll all windows showing the buffer" + :value all + (const t) + (const all)) (const :tag "Scroll only the selected window" this))) (defcustom eshell-scroll-to-bottom-on-output nil @@ -140,7 +143,10 @@ scroll only those that are not the selected window. See variable `eshell-scroll-show-maximum-output' and function `eshell-postoutput-scroll-to-bottom'." :type '(radio (const :tag "Do not scroll Eshell windows" nil) - (const :tag "Scroll all windows showing the buffer" all) + (choice :tag "Scroll all windows showing the buffer" + :value all + (const t) + (const all)) (const :tag "Scroll only the selected window" this) (const :tag "Scroll all windows other than selected" others))) diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 666a5025c2c..7d7373b275e 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -148,7 +148,9 @@ If nil, buffers will require manual reload, and will contain the text specified in `eww-restore-reload-prompt' instead of the actual Web page contents." :version "25.1" - :type '(choice (const :tag "Restore all automatically" t) + :type '(choice (choice :tag "Restore all automatically" :value t + (const t) + (const auto)) (const :tag "Require manual reload" nil))) (defcustom eww-restore-reload-prompt commit 816830d92191e3c73b785e60e15d28c40c88ea2c Author: Sean Whitton Date: Fri Nov 7 12:46:55 2025 +0000 vc-start-logentry: Disable log-edit-hook when finishing immediately * lisp/vc/vc-dispatcher.el (log-edit-hook): Declare. (vc-start-logentry): Bind log-edit-hook to nil when finishing the log edit immediately with a caller-supplied message. diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index dbf5b28fc04..4b893169a33 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -834,6 +834,8 @@ NOT-ESSENTIAL means it is okay to continue if the user says not to save." (set-buffer-modified-p nil) (setq buffer-file-name nil)) +(defvar log-edit-hook) + (defun vc-start-logentry (files comment initial-contents msg logbuf mode action &optional after-hook backend patch-string diff-function) "Accept a comment for an operation on FILES. If COMMENT is nil, pop up a LOGBUF buffer, emit MSG, and set the @@ -852,7 +854,8 @@ DIFF-FUNCTION is `log-edit-diff-function' for the Log Edit buffer." (let ((parent (or (and (length= files 1) (not (vc-dispatcher-browsing)) (get-file-buffer (car files))) - (current-buffer)))) + (current-buffer))) + (immediate (and comment (not initial-contents)))) (if (and comment (not initial-contents)) (set-buffer (get-buffer-create logbuf)) (pop-to-buffer (get-buffer-create logbuf))) @@ -861,7 +864,12 @@ DIFF-FUNCTION is `log-edit-diff-function' for the Log Edit buffer." (concat " from " (buffer-name vc-parent-buffer))) (when patch-string (setq-local vc-patch-string patch-string)) - (vc-log-edit files mode backend diff-function) + (let (;; `log-edit-hook' is usually for things like + ;; `log-edit-show-files' and `log-edit-maybe-show-diff' which + ;; don't make sense if the user is not going to do any + ;; editing, and can cause unexpected window layout changes. + (log-edit-hook (and (not immediate) log-edit-hook))) + (vc-log-edit files mode backend diff-function)) (make-local-variable 'vc-log-after-operation-hook) (when after-hook (setq vc-log-after-operation-hook after-hook)) @@ -869,11 +877,11 @@ DIFF-FUNCTION is `log-edit-diff-function' for the Log Edit buffer." (when comment (erase-buffer) (when (stringp comment) (insert comment))) - (if (or (not comment) initial-contents) - (message (substitute-command-keys + (if immediate + (vc-finish-logentry (eq comment t)) + (message (substitute-command-keys "%s Type \\\\[log-edit-done] when done") - msg) - (vc-finish-logentry (eq comment t))))) + msg)))) (defvar log-edit-vc-backend) (declare-function vc-buffer-sync-fileset "vc") commit 68e337e630f8d0960cf971f066c27f315634bc39 Author: Sean Whitton Date: Fri Nov 7 12:33:21 2025 +0000 Don't discard empty string arguments from emacsclient * lisp/server.el (server--process-filter-1): Don't discard empty string arguments from emacsclient. (server-eval-args-left): * doc/emacs/misc.texi (emacsclient Options): * etc/NEWS: Document the change. diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 2c2c710eea4..6c700869182 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -2024,8 +2024,8 @@ server file, as the default @code{server-auth-dir} is hard-coded in relative filenames. @node Invoking emacsclient -@subsection Invoking @code{emacsclient} -@cindex @code{emacsclient} invocation +@subsection Invoking @command{emacsclient} +@cindex @command{emacsclient} invocation The simplest way to use the @command{emacsclient} program is to run the shell command @samp{emacsclient @var{file}}, where @var{file} is a @@ -2193,8 +2193,9 @@ option sometimes requires elaborate escaping of characters special to the shell. To avoid this, you can pass arguments to Lisp functions in your expression as additional separate arguments to @command{emacsclient}, and use @var{server-eval-args-left} in the -expression to access those arguments. Be careful to have your -expression remove the processed arguments from +expression to access those arguments. If empty string arguments are +passed to @command{emacsclient}, those are included as well. Be careful +to have your expression remove the processed arguments from @var{server-eval-args-left} regardless of whether your code succeeds, for example by using @code{pop}, otherwise Emacs will attempt to evaluate those arguments as separate Lisp expressions. diff --git a/etc/NEWS b/etc/NEWS index 0dbe168d8c1..b3f8061f742 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -715,6 +715,12 @@ debugger and show the backtrace. If 'debug-on-error' is nil, these errors will be sent to 'emacsclient', as before, and will be displayed on the terminal from which 'emacsclient' was invoked. ++++ +** Empty string arguments to emacsclient are no longer ignored. +Emacs previously discarded arguments to emacsclient of zero length, such +as in 'emacsclient --eval "(length (pop server-eval-args-left))" ""'. +These are no longer discarded. + * Editing Changes in Emacs 31.1 diff --git a/lisp/server.el b/lisp/server.el index 4390562a580..bf3430b48d7 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1267,8 +1267,10 @@ The following commands are accepted by the client: args-left) ;; Remove this line from STRING. (setq string (substring string (match-end 0))) - (setq args-left - (mapcar #'server-unquote-arg (split-string request " " t))) + (cl-assert (equal (substring request -1) " ") + nil "emacsclient request did not end in SPC") + (setq args-left (mapcar #'server-unquote-arg + (nbutlast (split-string request " ")))) (while args-left (pcase (pop args-left) ;; -version CLIENT-VERSION: obsolete at birth. @@ -1481,6 +1483,9 @@ Adding or removing strings from this variable while the Emacs server is processing a series of eval requests will affect what Emacs evaluates. +This list includes empty strings if empty string arguments were passed +when invoking emacsclient. + See also `argv' for a similar variable which works for invocations of \"emacs\".")