commit 6df535788a20c9047d33dd8a0c62258597632647 (HEAD, refs/remotes/origin/master) Author: Jim Porter Date: Sun Dec 8 20:23:46 2024 -0800 Fix usage reporting for Eshell commands * lisp/eshell/esh-cmd.el (eshell-exec-lisp): Call 'elisp-get-fnsym-args-string'; the old function was renamed to this. diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 7a146944145..eb922b59a31 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -1501,11 +1501,13 @@ case." (when (memq eshell-in-pipeline-p '(nil last)) (eshell-set-exit-info 1)) (let ((msg (error-message-string err))) - (if (and (not form-p) - (string-match "^Wrong number of arguments" msg) - (fboundp 'eldoc-get-fnsym-args-string)) - (let ((func-doc (eldoc-get-fnsym-args-string func-or-form))) - (setq msg (format "usage: %s" func-doc)))) + (unless form-p + (let ((prog-name (string-trim-left (symbol-name func-or-form) + "eshell/"))) + (if (eq (car err) 'wrong-number-of-arguments) + (setq msg (format "%s usage: %s" prog-name + (elisp-get-fnsym-args-string func-or-form))) + (setq msg (format "%s: %s" prog-name msg))))) (funcall errprint msg)) nil))) commit b6c91cdf54168eef260e28a7866486a4d68bfc9e Author: Jim Porter Date: Sun Dec 8 20:21:31 2024 -0800 Return non-zero exit status when Eshell's "which" fails to find a command * lisp/eshell/esh-cmd.el (eshell/which): Set exit status to 1 if we couldn't find any of the commands (bug#74739). diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index c0015745ad5..7a146944145 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -1381,19 +1381,22 @@ have been replaced by constants." (defun eshell/which (command &rest names) "Identify the COMMAND, and where it is located." - (dolist (name (cons command names)) - (condition-case error - (eshell-printn - (catch 'found - (run-hook-wrapped - 'eshell-named-command-hook - (lambda (hook) - (when-let* (((symbolp hook)) - (which-func (get hook 'eshell-which-function)) - (result (funcall which-func command))) - (throw 'found result)))) - (eshell-plain-command--which name))) - (error (eshell-error (format "which: %s\n" (cadr error))))))) + (let (not-found) + (dolist (name (cons command names)) + (condition-case error + (eshell-printn + (catch 'found + (run-hook-wrapped + 'eshell-named-command-hook + (lambda (hook) + (when-let* (((symbolp hook)) + (which-func (get hook 'eshell-which-function)) + (result (funcall which-func command))) + (throw 'found result)))) + (eshell-plain-command--which name))) + (error (eshell-error (format "which: %s\n" (cadr error))) + (setq not-found t)))) + (when not-found (eshell-set-exit-info 1)))) (put 'eshell/which 'eshell-no-numeric-conversions t) commit 1098ae2896f458507c01afd04cb2e242227c6724 Author: Stefan Kangas Date: Mon Dec 9 04:14:47 2024 +0100 ; * etc/symbol-releases.eld: Add and-let*. (Bug#74712) diff --git a/etc/symbol-releases.eld b/etc/symbol-releases.eld index 3febf0a10bb..de1eaad6bd1 100644 --- a/etc/symbol-releases.eld +++ b/etc/symbol-releases.eld @@ -11,6 +11,7 @@ ( ("28.1" fun always) ("26.1" fun when-let*) + ("26.1" fun and-let*) ("26.1" fun if-let*) ("24.4" fun set-transient-map) ("22.1" fun version=) commit 9b4af418ddc3328c8756f3ca21ba25f161c65b65 Author: Stefan Kangas Date: Mon Dec 9 04:01:44 2024 +0100 Make setting tex-dvi-view-command to an sexp obsolete This is more in line with how we generally handle user options for commands to call. Later, we can get rid of the 'eval' call. * lisp/textmodes/tex-mode.el (tex-view): Warn if tex-dvi-view-command is set to an sexp instead of a string; say that this use is obsolete. (tex-dvi-view-command): Change the default value to a string. Update docstring to reflect the above obsoletion. diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 06a45112719..c82e589632e 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -199,17 +199,17 @@ use." ;;;###autoload (defcustom tex-dvi-view-command - `(cond - ((eq window-system 'x) ,(purecopy "xdvi")) - ((eq window-system 'w32) ,(purecopy "yap")) - (t ,(purecopy "dvi2tty * | cat -s"))) + (cond ((eq window-system 'x) (purecopy "xdvi")) + ((eq window-system 'w32) (purecopy "yap")) + (t (purecopy "dvi2tty * | cat -s"))) "Command used by \\[tex-view] to display a `.dvi' file. -If it is a string, that specifies the command directly. If this string contains an asterisk (`*'), that is replaced by the file name; otherwise, the file name, preceded by a space, is added at the end. -If the value is a form, it is evaluated to get the command to use." - :type '(choice (const nil) string sexp) +For backwards-compatibility, the value can also be a form, in which case +it is evaluated to get the command to use. This is now obsolete, and +will lead to a warning. Set it to a string instead." + :type '(choice (const nil) string) :risky t :group 'tex-view) @@ -2804,6 +2804,7 @@ Runs the shell command defined by `tex-alt-dvi-print-command'." (interactive) (tex-print t)) +(defvar tex-view--warned-once nil) (defun tex-view () "Preview the last `.dvi' file made by running TeX under Emacs. This means, made using \\[tex-region], \\[tex-buffer] or \\[tex-file]. @@ -2816,7 +2817,14 @@ because there is no standard value that would generally work." ;; Restart the TeX shell if necessary. (or (tex-shell-running) (tex-start-shell)) - (let ((tex-dvi-print-command (eval tex-dvi-view-command t))) + (let ((tex-dvi-print-command + (if (stringp tex-dvi-view-command) + tex-dvi-view-command + (unless tex-view--warned-once + (warn (concat "Setting `tex-dvi-view-command' to an S-expression" + " is obsolete since Emacs " "31.1")) + (setq tex-view--warned-once t)) + (eval tex-dvi-view-command t)))) (tex-print))) (defun tex-append (file-name suffix) commit 4960af1c963ada0185dd216c906ef52a6f05edab Author: Michael Albinus Date: Sun Dec 8 18:22:17 2024 +0100 Fix calling processes inside ffap * lisp/ffap.el (ffap--url-file-handler): Handle also `unhandled-file-name-directory'. (Bug#74208) diff --git a/lisp/ffap.el b/lisp/ffap.el index 6a4915fb5a3..180fe408104 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -1512,6 +1512,7 @@ which may actually result in an URL rather than a filename." ;; We mainly just want to disable these bits: (substitute-in-file-name (car args)) (expand-file-name (car args)) + (unhandled-file-name-directory temporary-file-directory) (otherwise (apply operation args))))) commit 9a0e26b88616946d2512680859166caa2675b30a Author: Eli Zaretskii Date: Sun Dec 8 14:10:33 2024 +0200 ; * doc/lispref/modes.texi (Parser-based Font Lock): Fix markup. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 43282c7cd30..4838a4d8ebb 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -4412,10 +4412,11 @@ ignored. @end defun @c FIXME: Cross-ref treesit-font-lock-level to user manual. +@vindex treesit-font-lock-level @defvar treesit-font-lock-feature-list This is a list of lists of feature symbols. Each element of the list is a list that represents a decoration level. -@var{treesit-font-lock-level} controls which levels are +The @code{treesit-font-lock-level} user option controls which levels are activated. Each element of the list is a list of the form @w{@code{(@var{feature} commit b953bcb17047998c9e41cede7c5e5ffec22209b2 Author: Yuan Fu Date: Sat Dec 7 23:18:53 2024 -0800 Allow treesit--font-lock-level-setter to be an alist * lisp/treesit.el (treesit-font-lock-level): Allow the value to be an alist mapping major modes to font lock levels. (treesit--font-lock-level-setter): Rewrite. (treesit--compute-font-lock-level): New function. (treesit-font-lock-recompute-features): Use new function. * doc/lispref/modes.texi (Parser-based Font Lock): Minor fix. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index ed7cc141cd5..43282c7cd30 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -4415,7 +4415,7 @@ ignored. @defvar treesit-font-lock-feature-list This is a list of lists of feature symbols. Each element of the list is a list that represents a decoration level. -@code{treesit-font-lock-level} controls which levels are +@var{treesit-font-lock-level} controls which levels are activated. Each element of the list is a list of the form @w{@code{(@var{feature} diff --git a/lisp/treesit.el b/lisp/treesit.el index db3a706f016..db8f7a7595d 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -898,29 +898,22 @@ t, nil, append, prepend, keep. See more in (setf (nth 1 new-setting) t) new-setting)) -;; FIXME: Rewrite this in more readable fashion. (defun treesit--font-lock-level-setter (sym val) "Custom setter for `treesit-font-lock-level'. Set the default value of SYM to VAL, recompute fontification features and refontify for every buffer where tree-sitter-based fontification is enabled." (set-default sym val) - (and (treesit-available-p) - (named-let loop ((res nil) - (buffers (buffer-list))) - (if (null buffers) - (mapc (lambda (b) - (with-current-buffer b - (setq-local treesit-font-lock-level val) - (treesit-font-lock-recompute-features) - (treesit-font-lock-fontify-region (point-min) - (point-max)))) - res) - (let ((buffer (car buffers))) - (with-current-buffer buffer - (if treesit-font-lock-settings - (loop (append res (list buffer)) (cdr buffers)) - (loop res (cdr buffers))))))))) + (when (treesit-available-p) + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + ;; FIXME: This doesn't re-run major mode hooks, meaning any + ;; customization done in major mode hooks (e.g., with + ;; `treesit-font-lock-recompute-features') is lost. + (when treesit-font-lock-settings + (treesit-font-lock-recompute-features) + (treesit-font-lock-fontify-region + (point-min) (point-max))))))) (defcustom treesit-font-lock-level 3 "Decoration level to be used by tree-sitter fontifications. @@ -937,6 +930,15 @@ Level 4 adds everything else that can be fontified: delimiters, operators, brackets, punctuation, all functions, properties, variables, etc. +The value of this variable can be either a number representing a level, +or an alist of (MAJOR-MODE . LEVEL), where MAJOR-MODE is major mode +symbols, or t (meaning the default), and LEVEL is the font-lock level +for that mode. For example, + + ((c-ts-mode . 3) (c++-ts-mode . 4) (t . 3)) + +Major mode is checked with `derived-mode-p'. + In addition to the decoration level, individual features can be turned on/off by calling `treesit-font-lock-recompute-features'. Changing the decoration level requires calling @@ -1123,6 +1125,23 @@ name, it is ignored." (defvar treesit--font-lock-verbose nil "If non-nil, print debug messages when fontifying.") +(defun treesit--compute-font-lock-level (level) + "Compute the font-lock level for the current major mode. + +LEVEL should be the value of `treesit-font-lock-level'. Return a number +representing the font-lock level for the current major mode. If there's +no match, return 3." + (if (numberp level) + level + (catch 'found + (dolist (config level) + (let ((mode (car config)) + (num (cdr config))) + (when (derived-mode-p mode) + (throw 'found num)))) + (or (alist-get t level) + 3)))) + (defun treesit-font-lock-recompute-features (&optional add-list remove-list language) "Enable/disable font-lock features. @@ -1147,7 +1166,8 @@ and leave settings for other languages unchanged." (signal 'treesit-font-lock-error (list "ADD-LIST and REMOVE-LIST contain the same feature" intersection))) - (let* ((level treesit-font-lock-level) + (let* ((level (treesit--compute-font-lock-level + treesit-font-lock-level)) (base-features (cl-loop for idx = 0 then (1+ idx) for features in treesit-font-lock-feature-list commit 6f6b641975e4828f96913b29b1476c6323c952d8 Merge: 0ece0e68ee5 4f2a21cc2a3 Author: Eli Zaretskii Date: Sat Dec 7 09:16:18 2024 -0500 Merge from origin/emacs-30 4f2a21cc2a3 Don't restrict 'lua-ts-send-file' to 'lua-ts-mode' commit 0ece0e68ee57e893ea2575d9c0fad19d7e17ae0d Merge: 284b6647d21 84fc77f34f0 Author: Eli Zaretskii Date: Sat Dec 7 09:16:18 2024 -0500 ; Merge from origin/emacs-30 The following commit was skipped: 84fc77f34f0 Remove unnecessary function call from 'php-ts-mode' commit 284b6647d215e6d0b773f5100b61849d4b80885c Merge: be5218138fc 3cf177442cc Author: Eli Zaretskii Date: Sat Dec 7 09:16:18 2024 -0500 Merge from origin/emacs-30 3cf177442cc ; * lisp/help-at-pt.el (display-local-help): Fix last cha... 02c53b9aab0 ; * lisp/help-at-pt.el (display-local-help): Doc fix. 130c2a13dc7 ; * doc/emacs/building.texi (Compilation Mode): Fix last ... df7f02a7954 Add tags to 'compilation-transform-file-match-alist' cust... 7c50e4cc8cc Improve 'compilation-transform-file-match-alist' document... a73d08bb67a Improve 'compilation-hidden-output' docstring d50293b0f10 ; Improve documentation of 'epa-mail-verify' commit be5218138fc760a4216a8badf6b67c2cc1a25fc8 Merge: 66263417b75 c7d9ffcf829 Author: Eli Zaretskii Date: Sat Dec 7 09:16:18 2024 -0500 ; Merge from origin/emacs-30 The following commit was skipped: c7d9ffcf829 Improve docstrings of functions for moving to message hea... commit 66263417b754ebf7b588ea8d1dddad584741e363 Merge: 15a4022e051 7b8d12e95de Author: Eli Zaretskii Date: Sat Dec 7 09:16:18 2024 -0500 Merge from origin/emacs-30 7b8d12e95de Fix the latest dabbrev-expand test fix commit 15a4022e051dbb9bb245e43b8c7fa292b23e9436 Merge: 3993dcca823 e618d5ae941 Author: Eli Zaretskii Date: Sat Dec 7 09:16:18 2024 -0500 ; Merge from origin/emacs-30 The following commit was skipped: e618d5ae941 Fix password prompt in comint (don't merge) commit 3993dcca823753237800dee598386ca6c14746a9 Merge: 69191aeefdb f65de1019dc Author: Eli Zaretskii Date: Sat Dec 7 09:16:18 2024 -0500 Merge from origin/emacs-30 f65de1019dc Fix the version of librsvg API change 43c4a06ffcc ; Fix grammar in Emacs user manual 6bca138d60e Fix latest test for dabbrev-expand commit 69191aeefdb0fec0722dbbe29a72ad2af9053f87 Author: Michael Albinus Date: Sat Dec 7 15:14:00 2024 +0100 * test/lisp/wdired-tests.el (wdired-test-bug34915): Fix for *BSD. (Bug#74721) diff --git a/test/lisp/wdired-tests.el b/test/lisp/wdired-tests.el index 7c7026354b8..30622700939 100644 --- a/test/lisp/wdired-tests.el +++ b/test/lisp/wdired-tests.el @@ -142,7 +142,8 @@ wdired-get-filename before and after editing." (ert-with-temp-directory test-dir (let* ((dired-listing-switches "-Fl") (dired-ls-F-marks-symlinks - (or (eq system-type 'darwin) + (or (and (memq system-type '(berkeley-unix darwin)) + (not (string= insert-directory-program "gls"))) (featurep 'ls-lisp))) (buf (find-file-noselect test-dir)) proc) commit 4f2a21cc2a369341b91bb3657e851bdc75e5e053 Author: john muhl Date: Mon Dec 2 09:20:01 2024 -0600 Don't restrict 'lua-ts-send-file' to 'lua-ts-mode' * lisp/progmodes/lua-ts-mode.el (lua-ts-send-file): Remove restriction on interactive use. Unlike related send-* commands it can be useful to send a file to the Lua interpreter outside of a 'lua-ts-mode' buffer. (Bug#74705) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index d2ac67a9230..9d06517a97d 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -694,7 +694,7 @@ Calls REPORT-FN directly." (defun lua-ts-send-file (file) "Send contents of FILE to the inferior Lua process." - (interactive "f" lua-ts-mode) + (interactive "f") (with-temp-buffer (insert-file-contents-literally file) (lua-ts-send-region (point-min) (point-max)))) commit 84fc77f34f0c942860c2fd4d3080504e9509dd2b Author: Vincenzo Pupillo Date: Wed Dec 4 15:06:54 2024 +0100 Remove unnecessary function call from 'php-ts-mode' * lisp/progmodes/php-ts-mode.el (php-ts-mode): Remove unnecessary function call 'treesit-font-lock-recompute-features'. (Bug#74688) (cherry picked from commit c87c5b95e1309b59b6cb07d07a20234a74a73f35) diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index 6052c79ccf3..975d6c89be5 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -1557,7 +1557,6 @@ Depends on `c-ts-common-comment-setup'." ;; should be the last one (setq-local treesit-primary-parser (treesit-parser-create 'php)) - (treesit-font-lock-recompute-features) (treesit-major-mode-setup) (add-hook 'flymake-diagnostic-functions #'php-ts-mode-flymake-php nil 'local))) commit c87c5b95e1309b59b6cb07d07a20234a74a73f35 Author: Vincenzo Pupillo Date: Wed Dec 4 15:06:54 2024 +0100 Remove unnecessary function call from 'php-ts-mode' * lisp/progmodes/php-ts-mode.el (php-ts-mode): Remove unnecessary function call 'treesit-font-lock-recompute-features'. (Bug#74688) diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index b6fe17f7d41..10f290d24ea 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -1557,7 +1557,6 @@ Depends on `c-ts-common-comment-setup'." ;; should be the last one (setq-local treesit-primary-parser (treesit-parser-create 'php)) - (treesit-font-lock-recompute-features) (treesit-major-mode-setup) (add-hook 'flymake-diagnostic-functions #'php-ts-mode-flymake-php nil 'local))) commit e7fdf6b68ce7aeba9f3b503a1c5b8bf1a61800c1 Author: Daniel Mendler Date: Wed Mar 1 19:27:38 2023 +0100 progmodes/js: Use 'completing-read' instead of 'ido-completing-read' * lisp/progmodes/js.el (js--read-symbol): Don't use Ido. (Bug#74615) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 57889338650..dbf721e8d0f 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -58,11 +58,8 @@ (eval-when-compile (require 'cl-lib) - (require 'ido) (require 'rx)) -(defvar ido-cur-list) -(declare-function ido-mode "ido" (&optional arg)) (declare-function treesit-parser-create "treesit.c") (declare-function treesit-induce-sparse-tree "treesit.c") (declare-function treesit-search-subtree "treesit.c") @@ -3288,11 +3285,7 @@ one from `js--get-all-known-symbols', using prompt PROMPT and initial input INITIAL-INPUT. Return a cons of (SYMBOL-NAME . LOCATION), where SYMBOL-NAME is a string and LOCATION is a marker." - (unless ido-mode - (ido-mode 1) - (ido-mode -1)) - - (let ((choice (ido-completing-read + (let ((choice (completing-read prompt (cl-loop for key being the hash-keys of symbols-table collect key) commit 8c3e10b5756a72d5d17f8166c0241f933305abe9 Author: Eli Zaretskii Date: Sat Dec 7 14:43:34 2024 +0200 ; Fix last change * lisp/progmodes/flymake-cc.el (flymake-cc-command): Fix doc string and customization tags. (Bug#74378) diff --git a/lisp/progmodes/flymake-cc.el b/lisp/progmodes/flymake-cc.el index 79557c9fbe4..0cf6b68012c 100644 --- a/lisp/progmodes/flymake-cc.el +++ b/lisp/progmodes/flymake-cc.el @@ -30,16 +30,17 @@ (defcustom flymake-cc-command #'flymake-cc-use-special-make-target "Command used by the `flymake-cc' backend. -A list of strings, or a function that produces one such list when called -with no arguments in the buffer where the variable `flymake-mode' is -active. +The value should be a list of strings, or a function that produces +such a list when called with no arguments in the buffer where `flymake-mode' +is active. The list of strings should be suitable for the `:command' +keyword of `make-process'. The command should invoke a GNU-style compiler that checks the syntax of a (Obj)C(++) program passed to it via its standard input and prints the result on its standard output." :type '(choice - (function :tag "Function") - (repeat :tag "Command(s)" string)) + (function :tag "Function to produce compilation command") + (repeat :tag "Compilation command and its options" string)) :version "27.1" :group 'flymake-cc) commit bf976ca7436b620ac33f00fa12317038ab387e00 Author: Pengji Zhang Date: Sat Nov 16 11:26:41 2024 +0800 Allow lambdas for 'flymake-cc-command' * lisp/progmodes/flymake-cc.el (flymake-cc-command): Use customization type 'function' instead of 'symbol' to allow other callable objects in addition to named functions, and update the doc string accordingly. (flymake-cc): Use 'functionp' to check if 'flymake-cc-command' is callable. (Bug#74378) diff --git a/lisp/progmodes/flymake-cc.el b/lisp/progmodes/flymake-cc.el index 60e7da5d617..79557c9fbe4 100644 --- a/lisp/progmodes/flymake-cc.el +++ b/lisp/progmodes/flymake-cc.el @@ -28,17 +28,17 @@ (require 'cl-lib) -(defcustom flymake-cc-command 'flymake-cc-use-special-make-target +(defcustom flymake-cc-command #'flymake-cc-use-special-make-target "Command used by the `flymake-cc' backend. -A list of strings, or a symbol naming a function that produces one -such list when called with no arguments in the buffer where the -variable `flymake-mode' is active. +A list of strings, or a function that produces one such list when called +with no arguments in the buffer where the variable `flymake-mode' is +active. The command should invoke a GNU-style compiler that checks the syntax of a (Obj)C(++) program passed to it via its standard input and prints the result on its standard output." :type '(choice - (symbol :tag "Function") + (function :tag "Function") (repeat :tag "Command(s)" string)) :version "27.1" :group 'flymake-cc) @@ -128,7 +128,7 @@ REPORT-FN is Flymake's callback." (make-process :name "gcc-flymake" :buffer (generate-new-buffer "*gcc-flymake*") - :command (if (symbolp flymake-cc-command) + :command (if (functionp flymake-cc-command) (funcall flymake-cc-command) flymake-cc-command) :noquery t :connection-type 'pipe commit d84c5c24b58b124f79b2a61e58e46c501d8ec52a Author: Eli Zaretskii Date: Sat Dec 7 06:50:27 2024 -0500 ; * lisp/dired-aux.el (shell-command-guess-open): Fix :type (bug#74720). diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 7fe67eed1e0..3390f9b83d1 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -1440,7 +1440,7 @@ This excludes `dired-guess-shell-alist-user' and ((executable-find "run-mailcap") "run-mailcap")) "A shell command to open a file externally." - :type 'string + :type '(choice (const :tag "None" nil) string) :group 'dired :version "30.1") commit d185d901905e11cf9120f5cea680ae04eae2809f Author: Eli Zaretskii Date: Sat Dec 7 11:04:44 2024 +0200 Update info-lookup's support for 'latex-mode' * lisp/info-look.el (latex-mode): Update URLs of LaTeX manuals and the corresponding names of the index nodes. diff --git a/lisp/info-look.el b/lisp/info-look.el index b3db9bfdecc..d51a59f7ac6 100644 --- a/lisp/info-look.el +++ b/lisp/info-look.el @@ -995,9 +995,11 @@ Return nil if there is nothing appropriate in the buffer near point." :mode 'latex-mode :regexp "\\\\\\([a-zA-Z]+\\|[^a-zA-Z]\\)" :doc-spec `((,(if (Info-find-file "latex2e" t) - ;; From http://home.gna.org/latexrefman - "(latex2e)Command Index" - "(latex)Command Index") + ;; From CTAN's https://ctan.org/pkg/latex2e-help-texinfo + ;; and https://puszcza.gnu.org.ua/projects/latexrefman/ + "(latex2e)Index" + ;; From https://savannah.nongnu.org/projects/latex-manual/ + "(latex-manual)Command Index") ;; \frac{NUM}{DEN} etc can have more than one {xx} argument. ;; \sqrt[ROOT]{num} and others can have square brackets. nil "[`'‘]" "\\({[^}]*}|\\[[^]]*\\]\\)*['’]"))) commit 9ddec89e422d0dd6e9069731b8f2dd2c90aa5607 Author: Michael Albinus Date: Fri Dec 6 11:56:05 2024 +0100 Better handling of "%" in Tramp user or host names * lisp/net/tramp.el (tramp-format-spec): New defun. (tramp-dissect-file-name, tramp-compute-multi-hops) (tramp-expand-args): * lisp/net/tramp-cmds.el (tramp-default-rename-file): Use it. diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 3a66030c9d0..d38250d4e09 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -368,7 +368,7 @@ function returns nil" (when (string-match-p (or (eval (car item) t) "") string) (setq tdra nil result - (format-spec + (tramp-format-spec (cdr item) (format-spec-make ?m method ?u user ?h host))))) result))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 12ad14e0900..c23eed0bc1b 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1826,14 +1826,9 @@ default values are used." user (tramp-find-user method user host) host (tramp-find-host method user host)) (when hop - ;; Replace placeholders. The hop could contain "%" - ;; which is not intended as format character, for - ;; example in USER%DOMAIN or POD%NAMESPACE. - (setq hop - (replace-regexp-in-string - (rx "%" (group (= 2 alnum))) "%%\\1" hop) - hop - (format-spec hop (format-spec-make ?h host ?u user)))))) + ;; Replace placeholders. + (setq + hop (tramp-format-spec hop (format-spec-make ?h host ?u user)))))) ;; Return result. (prog1 @@ -2233,6 +2228,14 @@ letter into the file name. This function removes it." (rx (regexp tramp-volume-letter-regexp) "/") "/" result)) (if quoted (file-name-quote result 'top) result)))) +(defun tramp-format-spec (format specification) + "Implement `format-spec' in Tramp. +FORMAT could contain \"%\" which is not intended as format character, +for example in USER%DOMAIN or POD%NAMESPACE." + (format-spec + (replace-regexp-in-string (rx "%" (group (= 2 alnum))) "%%\\1" format) + specification)) + ;;; Config Manipulation Functions: (defconst tramp-dns-sd-service-regexp @@ -5033,7 +5036,7 @@ Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.") (setq choices nil) ;; Replace placeholders. (setq proxy - (format-spec + (tramp-format-spec proxy (format-spec-make ?u (or (tramp-file-name-user (car target-alist)) "") @@ -5108,7 +5111,7 @@ a connection-local variable." (flatten-tree (mapcar (lambda (x) - (setq x (mapcar (lambda (y) (format-spec y spec)) x)) + (setq x (mapcar (lambda (y) (tramp-format-spec y spec)) x)) (unless (member "" x) x)) args)))) commit 61d06762975fb203ae06a57d30397d699164ebc1 Author: Juri Linkov Date: Thu Dec 5 20:15:12 2024 +0200 * lisp/emacs-lisp/lisp-mode.el (lisp-fdefs): Fix font-lock (bug#74307). Move '(not "\\")' inside the group to not exclude the last character for "\\<>" and similar constructs. diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 99980a44ddf..4b89eb91387 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -491,16 +491,16 @@ This will generate compile-time constants from BINDINGS." ;; Words inside \\[], \\<>, \\{} or \\`' tend to be for ;; `substitute-command-keys'. (,(rx "\\\\" (or (seq "[" - (group-n 1 lisp-mode-symbol) (not "\\") "]") + (group-n 1 (seq lisp-mode-symbol (not "\\"))) "]") (seq "`" (group-n 1 ;; allow multiple words, e.g. "C-x a" lisp-mode-symbol (* " " lisp-mode-symbol)) "'"))) (1 font-lock-constant-face prepend)) (,(rx "\\\\" (or (seq "<" - (group-n 1 lisp-mode-symbol) (not "\\") ">") + (group-n 1 (seq lisp-mode-symbol (not "\\"))) ">") (seq "{" - (group-n 1 lisp-mode-symbol) (not "\\") "}"))) + (group-n 1 (seq lisp-mode-symbol (not "\\"))) "}"))) (1 font-lock-variable-name-face prepend)) ;; Ineffective backslashes (typically in need of doubling). ("\\(\\\\\\)\\([^\"\\]\\)" commit 3cf177442ccd08f7b92b3e08c41899ba34699355 Author: Robert Pluim Date: Thu Dec 5 11:19:41 2024 +0100 ; * lisp/help-at-pt.el (display-local-help): Fix last change. diff --git a/lisp/help-at-pt.el b/lisp/help-at-pt.el index dcad09ef6ea..1ad353ee655 100644 --- a/lisp/help-at-pt.el +++ b/lisp/help-at-pt.el @@ -95,8 +95,8 @@ is displayed instead. The string is passed through `substitute-command-keys' before it is displayed. -If INHIBIT-WARNING is non-nil, this prevents display of the warning -message in case there is no help properties at point. +If INHIBIT-WARNING is non-nil, do not display a warning message when +there is no help property at point. If DESCRIBE-BUTTON in non-nil (interactively, the prefix arg), and there's a button/widget at point, pop up a buffer describing that commit ed9eaaa9964f46ef5f9a9c084a1cb8f1ae1926a3 Author: Yuan Fu Date: Mon Dec 2 20:47:38 2024 -0800 Validate font-lock rules when setting up tree-sitter major mode When tree-sitter grammar make breaking changes, major modes breaks completely: no highlighting is shown. This new function will run in treesit-major-mode-setup, validate each font-lock features, and disable the ones that are not compatible with the new grammar, so that the rest of the features still work. It also displays a warning explaining the situation, which looks like this: Warning (treesit-font-lock-rules-mismatch): Emacs cannot compile every font-lock rules because a mismatch between the grammar and the rules. This is most likely due to a mismatch between the font-lock rules defined by the major mode and the tree-sitter grammar. This error can be fixed by either downgrading the grammar (tree-sitter-c) on your system, or upgrading the major mode package. The following are the temporarily disabled features: - `preprocessor' for c. * lisp/treesit.el (treesit-validate-font-lock-rules): New function. (treesit-major-mode-setup): Validate font-lock rules. diff --git a/lisp/treesit.el b/lisp/treesit.el index 6bebb31ee18..db3a706f016 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -1214,6 +1214,48 @@ docstring of `treesit-font-lock-rules' for what is a feature." (append rules (nthcdr feature-idx treesit-font-lock-settings))))))) +(defun treesit-validate-font-lock-rules (settings) + "Validate font-lock rules in SETTINGS before major mode starts. + +If the tree-sitter grammar currently installed on the system is +incompatible with the major mode's font-lock rules, this procedure will +detect the problematic rule, disable it temporarily, and notify the +user." + (let ((faulty-features ())) + (dolist (setting settings) + (let* ((query (treesit-font-lock-setting-query setting)) + (lang (treesit-query-language query)) + (enabled (treesit-font-lock-setting-enable setting))) + (when (and enabled + (condition-case nil + (progn + (treesit-query-compile lang query 'eager) + nil) + (treesit-query-error t))) + (push (cons (treesit-font-lock-setting-feature setting) + lang) + faulty-features)))) + (when faulty-features + (treesit-font-lock-recompute-features + nil (mapcar #'car faulty-features)) + (let* ((languages + (string-join + (delete-dups (mapcar (lambda (feat) + (format "tree-sitter-%s" (cdr feat))) + faulty-features)) + ", ")) + (features (string-join + (mapcar + (lambda (feat) + (format "- `%s' for %s" + (car feat) (cdr feat))) + faulty-features) + ",\n"))) + (display-warning + 'treesit-font-lock-rules-mismatch + (format "Emacs cannot compile every font-lock rules because a mismatch between the grammar and the rules. This is most likely due to a mismatch between the font-lock rules defined by the major mode and the tree-sitter grammar.\n\nThis error can be fixed by either downgrading the grammar (%s) on your system, or upgrading the major mode package. The following are the temporarily disabled features:\n\n%s." + languages features)))))) + (defun treesit-fontify-with-override (start end face override &optional bound-start bound-end) "Apply FACE to the region between START and END. @@ -3142,7 +3184,8 @@ before calling this function." (add-hook 'pre-redisplay-functions #'treesit--pre-redisplay 0 t) (when treesit-primary-parser (treesit-parser-add-notifier - treesit-primary-parser #'treesit--font-lock-mark-ranges-to-fontify))) + treesit-primary-parser #'treesit--font-lock-mark-ranges-to-fontify)) + (treesit-validate-font-lock-rules treesit-font-lock-settings)) ;; Syntax (add-hook 'syntax-propertize-extend-region-functions #'treesit--pre-syntax-ppss 0 t) commit 4ecd1639b19345786020c0f7a5f3672129dae466 Author: Yuan Fu Date: Mon Dec 2 20:14:55 2024 -0800 Make treesit-query-compile compile compiled-query eagerly * src/treesit.c (treesit_ensure_query_compiled_signal): Extrat out into a function. (Ftreesit_query_compile): If EAGER is non-nil and QUERY is a lazily compiled query, compile it eagerily. diff --git a/src/treesit.c b/src/treesit.c index 2372944e166..28c94f307c0 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -1516,6 +1516,20 @@ treesit_ensure_query_compiled (Lisp_Object query, Lisp_Object *signal_symbol, return treesit_query; } +/* Bsically treesit_ensure_query_compiled but can signal. */ +static +void treesit_ensure_query_compiled_signal (Lisp_Object lisp_query) +{ + Lisp_Object signal_symbol = Qnil; + Lisp_Object signal_data = Qnil; + TSQuery *treesit_query = treesit_ensure_query_compiled (lisp_query, + &signal_symbol, + &signal_data); + + if (treesit_query == NULL) + xsignal (signal_symbol, signal_data); +} + /* Resolve language symbol LANG according to treesit-language-remap-alist. */ static @@ -3051,6 +3065,8 @@ DEFUN ("treesit-query-compile", doc: /* Compile QUERY to a compiled query. Querying with a compiled query is much faster than an uncompiled one. +So it's a good idea to use compiled query in tight loops, etc. + LANGUAGE is the language this query is for. If EAGER is non-nil, immediately load LANGUAGE and compile the query. @@ -3064,11 +3080,17 @@ You can use `treesit-query-validate' to validate and debug a query. */) if (NILP (Ftreesit_query_p (query))) wrong_type_argument (Qtreesit_query_p, query); CHECK_SYMBOL (language); - if (TS_COMPILED_QUERY_P (query)) - return query; treesit_initialize (); + if (TS_COMPILED_QUERY_P (query)) + { + if (NILP (eager)) + return query; + treesit_ensure_query_compiled_signal (query); + return query; + } + Lisp_Object lisp_query = make_treesit_query (query, language); /* Maybe actually compile. */ @@ -3076,15 +3098,7 @@ You can use `treesit-query-validate' to validate and debug a query. */) return lisp_query; else { - Lisp_Object signal_symbol = Qnil; - Lisp_Object signal_data = Qnil; - TSQuery *treesit_query = treesit_ensure_query_compiled (lisp_query, - &signal_symbol, - &signal_data); - - if (treesit_query == NULL) - xsignal (signal_symbol, signal_data); - + treesit_ensure_query_compiled_signal (lisp_query); return lisp_query; } } commit 5d535334f30b874ebb8e2c286c1e059d86ccd41f Author: Yuan Fu Date: Mon Dec 2 19:39:10 2024 -0800 ; Use cpp instead of c++ for c-ts-mode--simple-indent-rules * lisp/progmodes/c-ts-mode.el (c-ts-mode--simple-indent-rules): Use cpp to be more inline with other functions in c-ts-mode.el. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 710160ea472..dec9411b87c 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -441,7 +441,7 @@ NODE and PARENT are the same as other indent rules." "Return the indent rules for MODE and STYLE. The returned value can be set to `treesit-simple-indent-rules'. -MODE can be `c' or `c++'. STYLE can be `gnu', `k&r', `linux', `bsd'." +MODE can be `c' or `cpp'. STYLE can be `gnu', `k&r', `linux', `bsd'." (let ((rules `((c-ts-mode--for-each-tail-body-matcher prev-line c-ts-mode-indent-offset) @@ -513,7 +513,7 @@ MODE can be `c' or `c++'. STYLE can be `gnu', `k&r', `linux', `bsd'." ,@rules)))) (pcase mode ('c `((c . ,rules))) - ('c++ `((cpp . ,rules)))))) + ('cpp `((cpp . ,rules)))))) (defun c-ts-mode--parenthesized-expression-indent-rule (_node parent &rest _) "Indent rule that indents aprenthesized expression. @@ -1451,7 +1451,7 @@ recommended to enable `electric-pair-mode' with this mode." ;; Indent. (setq-local treesit-simple-indent-rules (c-ts-mode--simple-indent-rules - 'c++ c-ts-mode-indent-style)) + 'cpp c-ts-mode-indent-style)) ;; Font-lock. (setq-local treesit-font-lock-settings commit 10b4d3045e1b856009c5ac1e1a1ca257f2d4493f Author: Yuan Fu Date: Mon Dec 2 17:23:08 2024 -0800 Make tree-sitter-explorer support selecting local parser Now treesit-explore-mode will prompt the user to select a parser to explore, rather than a language. It'll also include the local parsers at point for selection. * lisp/treesit.el (treesit--explorer-language): Change to treesit--explorer-parser. (treesit--explorer--nodes-to-highlight): (treesit--explorer-refresh): Change to use parser. (treesit--explorer-generate-parser-alist): New function. (treesit-explorer-switch-parser): New command. (treesit-explore-mode): Use switch-parser to setup. * doc/lispref/parsing.texi (Language Grammar): Mention treesit-explorer-switch-parser. diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 5ef29f558ef..7fbb8e61ce1 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -240,12 +240,15 @@ which displays the syntax tree of the source in the current buffer in real time. Emacs also comes with an ``inspect mode'', which displays information of the nodes at point in the mode-line. +@findex treesit-explorer-switch-parser @deffn Command treesit-explore This command pops up a window displaying the syntax tree of the source in the current buffer. Selecting text in the source buffer highlights the corresponding nodes in the syntax tree display. Clicking on nodes in the syntax tree highlights the corresponding text in the source buffer. + +To switch to another parser, use @code{treesit-explorer-switch-parser}. @end deffn @deffn Command treesit-inspect-mode diff --git a/lisp/treesit.el b/lisp/treesit.el index 2acb46ab105..6bebb31ee18 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3347,7 +3347,7 @@ to the offending pattern and highlight the pattern." (defvar-local treesit--explorer-source-buffer nil "Source buffer corresponding to the playground buffer.") -(defvar-local treesit--explorer-language nil +(defvar-local treesit--explorer-parser nil "The language used in the playground.") (defvar-local treesit--explorer-refresh-timer nil @@ -3361,8 +3361,8 @@ to the offending pattern and highlight the pattern." (defvar treesit-explore-mode) -(defun treesit--explorer--nodes-to-highlight (language) - "Return nodes for LANGUAGE covered in region. +(defun treesit--explorer--nodes-to-highlight (parser) + "Return nodes for PARSER covered in region. This function tries to return the largest node possible. If the region covers exactly one node, that node is returned (in a list). If the region covers more than one node, two nodes are @@ -3370,7 +3370,7 @@ returned: the very first one in the region and the very last one in the region." (let* ((beg (region-beginning)) (end (region-end)) - (node (treesit-node-on beg end language)) + (node (treesit-node-on beg end parser)) (node (or (treesit-parent-while node (lambda (n) @@ -3394,7 +3394,7 @@ in the region." (when (and treesit-explore-mode (buffer-live-p treesit--explorer-buffer)) (let* ((root (treesit-node-on - (window-start) (window-end) treesit--explorer-language)) + (window-start) (window-end) treesit--explorer-parser)) ;; Only highlight the current top-level construct. ;; Highlighting the whole buffer is slow and unnecessary. ;; But if the buffer is small (ie, used in playground @@ -3411,7 +3411,7 @@ in the region." (nodes-hl (when (region-active-p) (treesit--explorer--nodes-to-highlight - treesit--explorer-language))) + treesit--explorer-parser))) ;; If we didn't edit the buffer nor change the top-level ;; node, don't redraw the whole syntax tree. (highlight-only (treesit-node-eq @@ -3589,11 +3589,56 @@ leaves point at the end of the last line of NODE." (when (buffer-live-p treesit--explorer-buffer) (kill-buffer treesit--explorer-buffer))) +(defun treesit--explorer-generate-parser-alist () + "Return an alist of (PARSER-NAME . PARSER) for relevant parsers. +Relevant parsers include all global parsers and local parsers that +covers point. PARSER-NAME are unique." + (let* ((local-parsers (treesit-parser-list nil nil 'embedded)) + (local-parsers-at-point + (treesit-local-parsers-at (point))) + res) + (dolist (parser (treesit-parser-list nil nil t)) + ;; Exclude local parsers that doesn't cover point. + (when (or (memq parser local-parsers-at-point) + (not (memq parser local-parsers))) + (push (cons (concat (format "%s" parser) + (if (treesit-parser-tag parser) + (format " tag=%s" + (treesit-parser-tag + parser)) + "") + (if (memq parser + local-parsers-at-point) + " (local)" + "") + (propertize (format " %s" (gensym)) + 'invisible t)) + parser) + res))) + (nreverse res))) + (define-derived-mode treesit--explorer-tree-mode special-mode "TS Explorer" "Mode for displaying syntax trees for `treesit-explore-mode'." nil) +(defun treesit-explorer-switch-parser (parser) + "Switch explorer to use PARSER." + (interactive + (list (let* ((parser-alist + (treesit--explorer-generate-parser-alist)) + (parser-name (completing-read + "Parser: " (mapcar #'car parser-alist)))) + (alist-get parser-name parser-alist + nil nil #'equal)))) + (unless treesit-explore-mode + (user-error "Not in `treesit-explore-mode'")) + (setq-local treesit--explorer-parser parser) + (display-buffer treesit--explorer-buffer + (cons nil '((inhibit-same-window . t)))) + (setq-local treesit--explorer-last-node nil) + (treesit--explorer-refresh)) + (define-minor-mode treesit-explore-mode "Enable exploring the current buffer's syntax tree. Pops up a window showing the syntax tree of the source in the @@ -3602,40 +3647,28 @@ the text in the active region is highlighted in the explorer window." :lighter " TSexplore" (if treesit-explore-mode - (let ((language - (intern (completing-read - "Language: " - (cl-remove-duplicates - (mapcar #'treesit-parser-language - (treesit-parser-list nil nil t))))))) - (if (not (treesit-language-available-p language)) - (user-error "Cannot find tree-sitter grammar for %s: %s" - language (cdr (treesit-language-available-p - language t))) - ;; Create explorer buffer. - (unless (buffer-live-p treesit--explorer-buffer) - (setq-local treesit--explorer-buffer - (get-buffer-create - (format "*tree-sitter explorer for %s*" - (buffer-name)))) - (setq-local treesit--explorer-language language) - (with-current-buffer treesit--explorer-buffer - (treesit--explorer-tree-mode))) - (display-buffer treesit--explorer-buffer - (cons nil '((inhibit-same-window . t)))) - (setq-local treesit--explorer-last-node nil) - (treesit--explorer-refresh) - ;; Set up variables and hooks. - (add-hook 'post-command-hook - #'treesit--explorer-post-command 0 t) - (add-hook 'kill-buffer-hook - #'treesit--explorer-kill-explorer-buffer 0 t) - ;; Tell `desktop-save' to not save explorer buffers. - (when (boundp 'desktop-modes-not-to-save) - (unless (memq 'treesit--explorer-tree-mode - desktop-modes-not-to-save) - (push 'treesit--explorer-tree-mode - desktop-modes-not-to-save))))) + (progn + ;; Create explorer buffer. + (unless (buffer-live-p treesit--explorer-buffer) + (setq-local treesit--explorer-buffer + (get-buffer-create + (format "*tree-sitter explorer for %s*" + (buffer-name)))) + (with-current-buffer treesit--explorer-buffer + (treesit--explorer-tree-mode))) + ;; Select parser. + (call-interactively #'treesit-explorer-switch-parser) + ;; Set up variables and hooks. + (add-hook 'post-command-hook + #'treesit--explorer-post-command 0 t) + (add-hook 'kill-buffer-hook + #'treesit--explorer-kill-explorer-buffer 0 t) + ;; Tell `desktop-save' to not save explorer buffers. + (when (boundp 'desktop-modes-not-to-save) + (unless (memq 'treesit--explorer-tree-mode + desktop-modes-not-to-save) + (push 'treesit--explorer-tree-mode + desktop-modes-not-to-save)))) ;; Turn off explore mode. (remove-hook 'post-command-hook #'treesit--explorer-post-command t) commit 25b4bf7fcd75564f23b2e60e29e8ff7354186371 Author: Juri Linkov Date: Wed Dec 4 20:38:41 2024 +0200 * lisp/tab-line.el (tab-line-tabs-fixed-window-buffers): More optimizations. Use :size arg of 'make-hash-table' as a hint how many buffers the table will have. Add ':in-place t' to 'sort'. diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 3c83a02739a..3bf42431ac0 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -555,12 +555,15 @@ This means that switching to a buffer previously shown in the same window will keep the same order of tabs that was before switching. And newly displayed buffers are added to the end of the tab line." (let* ((old-buffers (window-parameter nil 'tab-line-buffers)) - (buffer-positions (let ((index-table (make-hash-table :test 'eq))) + (buffer-positions (let ((index-table (make-hash-table + :size (length old-buffers) + :test #'eq))) (seq-do-indexed (lambda (buf idx) (puthash buf idx index-table)) old-buffers) index-table)) (new-buffers (sort (tab-line-tabs-window-buffers) + :in-place t :key (lambda (buffer) (gethash buffer buffer-positions most-positive-fixnum))))) commit 02c53b9aab0f255e7fac39660febbbbfbc59ba25 Author: Eli Zaretskii Date: Wed Dec 4 19:51:31 2024 +0200 ; * lisp/help-at-pt.el (display-local-help): Doc fix. diff --git a/lisp/help-at-pt.el b/lisp/help-at-pt.el index 95d0fafc544..dcad09ef6ea 100644 --- a/lisp/help-at-pt.el +++ b/lisp/help-at-pt.el @@ -86,20 +86,20 @@ If this produces no string either, return nil." ;;;###autoload (defun display-local-help (&optional inhibit-warning describe-button) - "Display local help in the echo area. -This command, by default, displays a short help message, namely -the string produced by the `kbd-help' property at point. If -`kbd-help' does not produce a string, but the `help-echo' -property does, then that string is printed instead. + "Display in the echo area `kbd-help' or `help-echo' text at point. +This command displays the help message which is the string produced +by the `kbd-help' property at point. If `kbd-help' at point does not +produce a string, but the `help-echo' property does, then that string +is displayed instead. The string is passed through `substitute-command-keys' before it is displayed. -If INHIBIT-WARNING is non-nil, this prevents display of a message -in case there is no help. +If INHIBIT-WARNING is non-nil, this prevents display of the warning +message in case there is no help properties at point. If DESCRIBE-BUTTON in non-nil (interactively, the prefix arg), and -there's a button/widget at point, pop a buffer describing that +there's a button/widget at point, pop up a buffer describing that button/widget instead." (interactive (list nil current-prefix-arg)) (let ((help (help-at-pt-kbd-string))) commit 130c2a13dc72fca1677a986d3131398e908e58df Author: Eli Zaretskii Date: Wed Dec 4 18:21:19 2024 +0200 ; * doc/emacs/building.texi (Compilation Mode): Fix last change. diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index 3a3dd1d4461..bebf410f919 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi @@ -316,7 +316,8 @@ to parse output from a @code{grep} command (@pxref{Grep Searching}). Sometimes @code{compilation-error-regexp-alist} doesn't correctly determine the filename that is the source of the error. Use user option @code{compilation-transform-file-match-alist} to make any necessary -adjustments, such as adding or changing a directory component. +adjustments, such as adding or changing a directory component, or even +considering certain compiler messages not error messages at all. @findex compilation-next-error @findex compilation-previous-error commit df7f02a7954c652896dcaae590caf9dc0c4dc6a1 Author: Robert Pluim Date: Wed Dec 4 17:00:16 2024 +0100 Add tags to 'compilation-transform-file-match-alist' custom type * lisp/progmodes/compile.el (compilation-filter-start): Add some more meaningful tags, and switch to using 'radio' instead of 'choice'. diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index ee7fc6aaecb..241b29c65b0 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -77,8 +77,10 @@ an entry matching \"\\\\=`\" and a replacement regexp of \"bar/\", i.e.: Similarly, to remove a prefix \"bar/\", use: (\"\\\\=`bar/\" \"\")" - :type '(repeat (list regexp (choice (const :tag "No replacement" nil) - string))) + :type '(repeat (list (regexp :tag "Filename that matches") + (radio :tag "Action" + (const :tag "Do not consider as error" nil) + (string :tag "Replace matched filename with")))) :version "27.1") (defvar compilation-filter-hook nil commit 7c50e4cc8cc19ad1ab10121ece894409a72a8af9 Author: Robert Pluim Date: Tue Dec 3 15:20:04 2024 +0100 Improve 'compilation-transform-file-match-alist' documentation * doc/emacs/building.texi (Compilation Mode): Document 'compilation-transform-file-match-alist'. * lisp/progmodes/compile.el (compilation-transform-file-match-alist): Expand docstring and add some examples. diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi index bb03d8cf325..3a3dd1d4461 100644 --- a/doc/emacs/building.texi +++ b/doc/emacs/building.texi @@ -310,6 +310,14 @@ error message formats and tells Emacs how to extract the locus from each. A similar variable, @code{grep-regexp-alist}, tells Emacs how to parse output from a @code{grep} command (@pxref{Grep Searching}). +@vindex compilation-transform-file-match-alist +@cindex compilation transform file +@cindex compilation find file + Sometimes @code{compilation-error-regexp-alist} doesn't correctly +determine the filename that is the source of the error. Use user option +@code{compilation-transform-file-match-alist} to make any necessary +adjustments, such as adding or changing a directory component. + @findex compilation-next-error @findex compilation-previous-error @findex compilation-next-file diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 95dce7a430f..ee7fc6aaecb 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -62,9 +62,21 @@ If nil, use Emacs default." (defcustom compilation-transform-file-match-alist '(("/bin/[a-z]*sh\\'" nil)) "Alist of regexp/replacements to alter file names in compilation errors. -If the replacement is nil, the file will not be considered an -error after all. If not nil, it should be a regexp replacement -string." +If the replacement is nil, the file will not be considered an error +after all. If not nil, it should be a regexp replacement string. + +When a replacement regexp is specified, the value of the file name used +to locate the error is changed, but the compilation buffer still +displays the original value. + +For example, to prepend a subdirectory \"bar/\" to all file names, add +an entry matching \"\\\\=`\" and a replacement regexp of \"bar/\", i.e.: + + (\"\\\\=`\" \"bar/\") + +Similarly, to remove a prefix \"bar/\", use: + + (\"\\\\=`bar/\" \"\")" :type '(repeat (list regexp (choice (const :tag "No replacement" nil) string))) :version "27.1") commit a73d08bb67a3562da42ea929df01eb1fb0c17b99 Author: Robert Pluim Date: Mon Dec 2 19:27:48 2024 +0100 Improve 'compilation-hidden-output' docstring * lisp/progmodes/compile.el (compilation-hidden-output): Escape the newline so the example value is more suitable for copying. diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index d2e74aa44a6..95dce7a430f 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -95,8 +95,8 @@ like. For instance, to hide the verbose output from recursive makefiles, you can say something like: - (setq compilation-hidden-output - \\='(\"^make[^\n]+\n\"))" + (setopt compilation-hidden-output + \\='(\"^make[^\\n]+\\n\"))" :type '(choice regexp (repeat regexp)) :version "29.1") commit d50293b0f108ff85796dc56312a1c46c8db4f8a1 Author: Eli Zaretskii Date: Wed Dec 4 15:21:13 2024 +0200 ; Improve documentation of 'epa-mail-verify' * doc/misc/epa.texi (Mail-mode integration): * lisp/epa-mail.el (epa-mail-verify): Improve documentation of 'epa-mail-verify'. (Bug#74630) diff --git a/doc/misc/epa.texi b/doc/misc/epa.texi index f450b9cbdd9..58c2a111348 100644 --- a/doc/misc/epa.texi +++ b/doc/misc/epa.texi @@ -398,7 +398,8 @@ Decrypt OpenPGP armors in the current buffer. @kindex C-c C-e C-v @kindex C-c C-e v @findex epa-mail-verify -Verify OpenPGP cleartext signed messages in the current buffer. +Verify OpenPGP cleartext signed messages in the current buffer. If +verification fails for some reason, this command signals an error. @item C-c C-e C-s and C-c C-e s @kindex C-c C-e C-s diff --git a/lisp/epa-mail.el b/lisp/epa-mail.el index 0c93b18eea1..47529b02d22 100644 --- a/lisp/epa-mail.el +++ b/lisp/epa-mail.el @@ -90,7 +90,9 @@ The buffer is expected to contain a mail message." ;;;###autoload (defun epa-mail-verify () "Verify OpenPGP cleartext signed messages in the current buffer. -The buffer is expected to contain a mail message." +The buffer is expected to contain a mail message. + +If the verification fails, signal an error." (declare (interactive-only t)) (interactive) (with-suppressed-warnings ((interactive-only epa-verify-cleartext-in-region)) commit c7d9ffcf82954027929e3ca05e2a6455a453ae60 Author: Robert Pluim Date: Tue Dec 3 15:41:48 2024 +0100 Improve docstrings of functions for moving to message headers * lisp/gnus/message.el (message-goto-to, message-goto-from, message-goto-subject, message-goto-cc, message-goto-bcc, message-goto-fcc, message-goto-reply-to, message-goto-newsgroups, message-goto-distribution, message-goto-followup-to, message-goto-mail-followup-to, message-goto-keywords, message-goto-summary): Mention that these will insert an empty header if the header is not found. (message-position-on-field): Explain that this inserts an empty header if the header is missing, and that insertion is done after the headers mentioned in AFTERS. (cherry picked from commit 9f266e2d7cde41f5872304bae0b6d2415655f1c8) diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 98f63571389..6e9a7e8f72a 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -3253,79 +3253,79 @@ Like `text-mode', but with these additional commands: ;;; Movement commands (defun message-goto-to () - "Move point to the To header." + "Move point to the To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "To")) (defun message-goto-from () - "Move point to the From header." + "Move point to the From header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "From")) (defun message-goto-subject () - "Move point to the Subject header." + "Move point to the Subject header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Subject")) (defun message-goto-cc () - "Move point to the Cc header." + "Move point to the Cc header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Cc" "To")) (defun message-goto-bcc () - "Move point to the Bcc header." + "Move point to the Bcc header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Bcc" "Cc" "To")) (defun message-goto-fcc () - "Move point to the Fcc header." + "Move point to the Fcc header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Fcc" "To" "Newsgroups")) (defun message-goto-reply-to () - "Move point to the Reply-To header." + "Move point to the Reply-To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Reply-To" "Subject")) (defun message-goto-newsgroups () - "Move point to the Newsgroups header." + "Move point to the Newsgroups header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Newsgroups")) (defun message-goto-distribution () - "Move point to the Distribution header." + "Move point to the Distribution header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Distribution")) (defun message-goto-followup-to () - "Move point to the Followup-To header." + "Move point to the Followup-To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Followup-To" "Newsgroups")) (defun message-goto-mail-followup-to () - "Move point to the Mail-Followup-To header." + "Move point to the Mail-Followup-To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Mail-Followup-To" "To")) (defun message-goto-keywords () - "Move point to the Keywords header." + "Move point to the Keywords header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Keywords" "Subject")) (defun message-goto-summary () - "Move point to the Summary header." + "Move point to the Summary header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Summary" "Subject")) @@ -4249,6 +4249,10 @@ This function strips off the signature from the original message." (newline))) (defun message-position-on-field (header &rest afters) + "Move point to header HEADER or insert it if not found. + +If HEADER is not present, insert it with an empty value, after any +headers specified in AFTERS." (let ((case-fold-search t)) (save-restriction (narrow-to-region commit d706be4b345f3e2d242c4f2ffb5e566845b2935d Author: Juri Linkov Date: Wed Dec 4 09:40:33 2024 +0200 Remove obsolete 'display-comint-buffer-action' (bug#74361) * lisp/window.el (display-comint-buffer-action): (display-tex-shell-buffer-action): Remove obsolete defcustoms. * lisp/cmuscheme.el (run-scheme, switch-to-scheme): * lisp/shell.el (shell): * lisp/eshell/eshell.el (eshell): * lisp/progmodes/inf-lisp.el (inferior-lisp): * lisp/progmodes/project.el (project-shell, project-eshell): * lisp/progmodes/sh-script.el (sh-show-shell): Replace 'display-comint-buffer-action' with a list of 'display-buffer--same-window-action' and '(category . comint)'. * lisp/org/ol-eshell.el (org-eshell-open): Add '(category . comint)'. * lisp/textmodes/tex-mode.el (tex-display-shell) (tex-recenter-output-buffer): Replace 'display-tex-shell-buffer-action' with a list of 'display-buffer-in-previous-window' and '(category . tex-shell)'. diff --git a/etc/NEWS b/etc/NEWS index 4a82cbc4dfa..3efce149dbf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -154,6 +154,12 @@ that the actual killing or burying of the buffer is done by the caller. With this option set, 'quit-restore-window' will delete its window more aggressively rather than switching to some other buffer in it. +--- +*** The user option 'display-comint-buffer-action' has been removed. +It has been obsolete since Emacs 30.1. Use '(category . comint)' instead. +Another user option 'display-tex-shell-buffer-action' has been removed too +for which you can use '(category . tex-shell)'. + ** Frames +++ diff --git a/lisp/cmuscheme.el b/lisp/cmuscheme.el index d4316fb1175..b03cf1f1840 100644 --- a/lisp/cmuscheme.el +++ b/lisp/cmuscheme.el @@ -238,8 +238,8 @@ is run). (inferior-scheme-mode))) (setq scheme-program-name cmd) (setq scheme-buffer "*scheme*") - (with-suppressed-warnings ((obsolete display-comint-buffer-action)) - (pop-to-buffer "*scheme*" display-comint-buffer-action))) + (pop-to-buffer "*scheme*" (append display-buffer--same-window-action + '((category . comint))))) (defun scheme-start-file (prog) "Return the name of the start file corresponding to PROG. @@ -359,8 +359,8 @@ With argument, position cursor at end of buffer." (interactive "P") (if (or (and scheme-buffer (get-buffer scheme-buffer)) (scheme-interactively-start-process)) - (with-suppressed-warnings ((obsolete display-comint-buffer-action)) - (pop-to-buffer scheme-buffer display-comint-buffer-action)) + (pop-to-buffer scheme-buffer (append display-buffer--same-window-action + '((category . comint)))) (error "No current process buffer. See variable `scheme-buffer'")) (when eob-p (push-mark) diff --git a/lisp/eshell/eshell.el b/lisp/eshell/eshell.el index fc08734d5f3..3def918bdd1 100644 --- a/lisp/eshell/eshell.el +++ b/lisp/eshell/eshell.el @@ -278,8 +278,8 @@ information on Eshell, see Info node `(eshell)Top'." (t (get-buffer-create eshell-buffer-name))))) (cl-assert (and buf (buffer-live-p buf))) - (with-suppressed-warnings ((obsolete display-comint-buffer-action)) - (pop-to-buffer buf display-comint-buffer-action)) + (pop-to-buffer buf (append display-buffer--same-window-action + '((category . comint)))) (unless (derived-mode-p 'eshell-mode) (eshell-mode)) buf)) diff --git a/lisp/org/ol-eshell.el b/lisp/org/ol-eshell.el index 595dd0ee0f8..e364a38c17d 100644 --- a/lisp/org/ol-eshell.el +++ b/lisp/org/ol-eshell.el @@ -51,9 +51,9 @@ followed by a colon." (if (get-buffer eshell-buffer-name) (pop-to-buffer eshell-buffer-name - (if (boundp 'display-comint-buffer-action) ; Emacs >= 29 + (if (boundp 'display-comint-buffer-action) ; Emacs >= 29, <= 30 display-comint-buffer-action - '(display-buffer-same-window (inhibit-same-window)))) + '(display-buffer-same-window (inhibit-same-window) (category . comint)))) (eshell)) (goto-char (point-max)) (eshell-kill-input) diff --git a/lisp/progmodes/inf-lisp.el b/lisp/progmodes/inf-lisp.el index 85fc6b930f5..b092b3b679c 100644 --- a/lisp/progmodes/inf-lisp.el +++ b/lisp/progmodes/inf-lisp.el @@ -308,8 +308,8 @@ quoted using shell quote syntax. "inferior-lisp" (car cmdlist) nil (cdr cmdlist))) (inferior-lisp-mode))) (setq inferior-lisp-buffer "*inferior-lisp*") - (with-suppressed-warnings ((obsolete display-comint-buffer-action)) - (pop-to-buffer "*inferior-lisp*" display-comint-buffer-action))) + (pop-to-buffer "*inferior-lisp*" (append display-buffer--same-window-action + '((category . comint))))) ;;;###autoload (defalias 'run-lisp 'inferior-lisp) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 33e8aab469b..ed6be453274 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1376,7 +1376,8 @@ if one already exists." (shell-buffer (get-buffer default-project-shell-name))) (if (and shell-buffer (not current-prefix-arg)) (if (comint-check-proc shell-buffer) - (pop-to-buffer shell-buffer (bound-and-true-p display-comint-buffer-action)) + (pop-to-buffer shell-buffer (append display-buffer--same-window-action + '((category . comint)))) (shell shell-buffer)) (shell (generate-new-buffer-name default-project-shell-name))))) @@ -1393,7 +1394,8 @@ if one already exists." (eshell-buffer-name (project-prefixed-buffer-name "eshell")) (eshell-buffer (get-buffer eshell-buffer-name))) (if (and eshell-buffer (not current-prefix-arg)) - (pop-to-buffer eshell-buffer (bound-and-true-p display-comint-buffer-action)) + (pop-to-buffer eshell-buffer (append display-buffer--same-window-action + '((category . comint)))) (eshell t)))) ;;;###autoload diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 3aa0f0919bc..15ba6e6f2a0 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1447,8 +1447,9 @@ If FORCE is non-nil and no process found, create one." (defun sh-show-shell () "Pop the shell interaction buffer." (interactive) - (with-suppressed-warnings ((obsolete display-comint-buffer-action)) - (pop-to-buffer (process-buffer (sh-shell-process t)) display-comint-buffer-action))) + (pop-to-buffer (process-buffer (sh-shell-process t)) + (append display-buffer--same-window-action + '((category . comint))))) (defun sh-send-text (text) "Send TEXT to `sh-shell-process'." diff --git a/lisp/shell.el b/lisp/shell.el index 6cfae470cd7..33d80061ada 100644 --- a/lisp/shell.el +++ b/lisp/shell.el @@ -953,8 +953,8 @@ Make the shell buffer the current buffer, and return it. (current-buffer))) ;; The buffer's window must be correctly set when we call comint ;; (so that comint sets the COLUMNS env var properly). - (with-suppressed-warnings ((obsolete display-comint-buffer-action)) - (pop-to-buffer buffer display-comint-buffer-action)) + (pop-to-buffer buffer (append display-buffer--same-window-action + '((category . comint)))) (with-connection-local-variables (when file-name diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 9cb95f59da4..06a45112719 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -2092,8 +2092,9 @@ In the tex shell buffer this command behaves like `comint-send-input'." (defun tex-display-shell () "Make the TeX shell buffer visible in a window." - (with-suppressed-warnings ((obsolete display-tex-shell-buffer-action)) - (display-buffer (tex-shell-buf) display-tex-shell-buffer-action)) + (display-buffer (tex-shell-buf) '(display-buffer-in-previous-window + (inhibit-same-window . t) + (category . tex-shell))) (tex-recenter-output-buffer nil)) (defun tex-shell-sentinel (proc _msg) @@ -2753,8 +2754,9 @@ line LINE of the window, or centered if LINE is nil." (if (null tex-shell) (message "No TeX output buffer") (when-let* ((window - (with-suppressed-warnings ((obsolete display-tex-shell-buffer-action)) - (display-buffer tex-shell display-tex-shell-buffer-action)))) + (display-buffer tex-shell '(display-buffer-in-previous-window + (inhibit-same-window . t) + (category . tex-shell))))) (with-selected-window window (bury-buffer tex-shell) (goto-char (point-max)) diff --git a/lisp/window.el b/lisp/window.el index c790118c5e0..e9d57652ec6 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -9115,35 +9115,6 @@ currently selected window; otherwise it will be displayed in another window." (pop-to-buffer buffer display-buffer--same-window-action norecord)) -(defcustom display-comint-buffer-action - (append display-buffer--same-window-action '((category . comint))) - "`display-buffer' action for displaying comint buffers." - :type display-buffer--action-custom-type - :risky t - :version "29.1" - :group 'windows - :group 'comint) - -(make-obsolete-variable - 'display-comint-buffer-action - "use a `(category . comint)' condition in `display-buffer-alist'." - "30.1") - -(defcustom display-tex-shell-buffer-action '(display-buffer-in-previous-window - (inhibit-same-window . t) - (category . tex-shell)) - "`display-buffer' action for displaying TeX shell buffers." - :type display-buffer--action-custom-type - :risky t - :version "29.1" - :group 'windows - :group 'tex-run) - -(make-obsolete-variable - 'display-tex-shell-buffer-action - "use a `(category . tex-shell)' condition in `display-buffer-alist'." - "30.1") - (defun read-buffer-to-switch (prompt) "Read the name of a buffer to switch to, prompting with PROMPT. Return the name of the buffer as a string. commit 69e1f787528eaf2f223c53a6ff518ba4f984bc17 Author: Juri Linkov Date: Tue Dec 3 20:12:03 2024 +0200 Add new keyword :continue-only to defvar-keymap for repeat-mode (bug#74140) * doc/lispref/keymaps.texi (Creating Keymaps): Add :continue-only to :repeat part of defvar-keymap. * lisp/keymap.el (defvar-keymap): Add support for new :repeat keyword :continue-only. * lisp/repeat.el (repeat-post-hook): The property 'repeat-continue-only' is handled as a list of repeat-maps. * test/lisp/repeat-tests.el (repeat-tests-repeat-map): Use new :repeat keyword :continue-only. diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 2f9529a2a18..87723720b1e 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -480,7 +480,8 @@ following values are available: This means all the commands in the keymap are repeatable, and is the most common usage. -@item (:enter (commands ...) :exit (commands ...) :hints ((command . "hint") ...)) +@item (:enter (commands ...) :exit (commands ...) +@itemx :continue-only (commands ...) :hints ((command . "hint") ...)) This specifies that the commands in the @code{:enter} list enter @code{repeat-mode}, and the commands in the @code{:exit} list exit repeat mode. @@ -495,6 +496,10 @@ If the @code{:exit} list is empty then no commands in the map exit useful if the keymap being defined contains a command that should not have the @code{repeat-map} property. +The @code{:continue-only'} list specifies the commands that should not +enter @code{repeat-mode}. These command should only continue the +already activated repeating sequence. + The @code{:hints} list can contain cons pairs where the @sc{car} is a command and the @sc{cdr} is a string that is displayed alongside of the repeatable key in the echo area. diff --git a/etc/NEWS b/etc/NEWS index 4d2a2c893d0..4a82cbc4dfa 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -946,10 +946,13 @@ provide a ':columns' spec, so that the number of columns and their widths can be determined. Columns widths can be set explicitly, or they will be calculated based on the window width. ++++ ** New symbol property 'repeat-continue-only' for 'repeat-mode'. -A command with this symbol property whose value is non-nil will not -activate the repeat map in 'repeat-mode', it will only continue the -already activated repeating sequence. +A command with this symbol property whose value is a list of repeat +maps will not activate the repeat map in 'repeat-mode'. It will only +continue the already activated repeating sequence. Also 'defvar-keymap' +supports a new keyword ':continue-only' with a list of commands that +only continue the active repeating sequence. * Changes in Emacs 31.1 on Non-Free Operating Systems diff --git a/lisp/keymap.el b/lisp/keymap.el index 9b133e1ca82..43c8d918ba7 100644 --- a/lisp/keymap.el +++ b/lisp/keymap.el @@ -687,6 +687,7 @@ value can also be a property list with properties `:enter', `:exit' and `:hints', for example: :repeat (:enter (commands ...) :exit (commands ...) + :continue-only (commands ...) :hints ((command . \"hint\") ...)) `:enter' specifies the list of additional commands that only @@ -702,6 +703,10 @@ Specifying a list of commands is useful when those commands exist in this specific map, but should not have the `repeat-map' symbol property. +`:continue-only' specifies the list of commands that should not +enter `repeat-mode'. These command should only continue the +already activated repeating sequence. + `:hints' is a list of cons pairs where car is a command and cdr is a string that is displayed alongside of the repeatable key in the echo area. @@ -740,6 +745,10 @@ in the echo area. def) (dolist (def (plist-get repeat :enter)) (push `(put ',def 'repeat-map ',variable-name) props)) + (dolist (def (plist-get repeat :continue-only)) + (push `(put ',def 'repeat-continue-only + (cons ',variable-name (get ',def 'repeat-continue-only))) + props)) (while defs (pop defs) (setq def (pop defs)) diff --git a/lisp/repeat.el b/lisp/repeat.el index 11d26a477b6..45888d9db08 100644 --- a/lisp/repeat.el +++ b/lisp/repeat.el @@ -505,8 +505,12 @@ See `describe-repeat-maps' for a list of all repeatable commands." (setq repeat-in-progress nil) (let ((map (repeat-get-map))) (when (and (repeat-check-map map) - (or (null (repeat--command-property 'repeat-continue-only)) - was-in-progress)) + (let ((continue-only (repeat--command-property 'repeat-continue-only))) + (or (null continue-only) + (and (or (not (consp continue-only)) + (memq (repeat--command-property 'repeat-map) + continue-only)) + was-in-progress)))) ;; Messaging (funcall repeat-echo-function map) diff --git a/test/lisp/repeat-tests.el b/test/lisp/repeat-tests.el index c560a283039..d69d431146a 100644 --- a/test/lisp/repeat-tests.el +++ b/test/lisp/repeat-tests.el @@ -63,17 +63,15 @@ (defvar-keymap repeat-tests-repeat-map :doc "Keymap for repeating sequences." - :repeat ( :enter (repeat-tests-call-a) - :exit (repeat-tests-call-q)) + :repeat ( :enter (repeat-tests-call-a) + :continue-only (repeat-tests-call-o) + :exit (repeat-tests-call-q)) "a" 'ignore ;; for non-nil repeat-check-key only "c" 'repeat-tests-call-c "d" 'repeat-tests-call-d "C-M-o" 'repeat-tests-call-o "q" 'repeat-tests-call-q) -;; TODO: add new keyword ':continue-only (repeat-tests-call-o)' -(put 'repeat-tests-call-o 'repeat-continue-only t) - ;; Test using a variable instead of the symbol: (put 'repeat-tests-call-b 'repeat-map repeat-tests-repeat-map) @@ -228,8 +226,7 @@ ;; :continue-only ("C-M-o" . repeat-tests-bind-call-o) :exit - ("q" . repeat-tests-bind-call-q) - ) + ("q" . repeat-tests-bind-call-q)) ;; TODO: it seems there is no :entry, so need to do explicitly: (put 'repeat-tests-bind-call-a 'repeat-map 'repeat-tests-bind-keys-repeat-map) commit 9f266e2d7cde41f5872304bae0b6d2415655f1c8 Author: Robert Pluim Date: Tue Dec 3 15:41:48 2024 +0100 Improve docstrings of functions for moving to message headers * lisp/gnus/message.el (message-goto-to, message-goto-from, message-goto-subject, message-goto-cc, message-goto-bcc, message-goto-fcc, message-goto-reply-to, message-goto-newsgroups, message-goto-distribution, message-goto-followup-to, message-goto-mail-followup-to, message-goto-keywords, message-goto-summary): Mention that these will insert an empty header if the header is not found. (message-position-on-field): Explain that this inserts an empty header if the header is missing, and that insertion is done after the headers mentioned in AFTERS. diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index b4c5a1e2436..c504742b0fe 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -3253,79 +3253,79 @@ Like `text-mode', but with these additional commands: ;;; Movement commands (defun message-goto-to () - "Move point to the To header." + "Move point to the To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "To")) (defun message-goto-from () - "Move point to the From header." + "Move point to the From header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "From")) (defun message-goto-subject () - "Move point to the Subject header." + "Move point to the Subject header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Subject")) (defun message-goto-cc () - "Move point to the Cc header." + "Move point to the Cc header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Cc" "To")) (defun message-goto-bcc () - "Move point to the Bcc header." + "Move point to the Bcc header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Bcc" "Cc" "To")) (defun message-goto-fcc () - "Move point to the Fcc header." + "Move point to the Fcc header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Fcc" "To" "Newsgroups")) (defun message-goto-reply-to () - "Move point to the Reply-To header." + "Move point to the Reply-To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Reply-To" "Subject")) (defun message-goto-newsgroups () - "Move point to the Newsgroups header." + "Move point to the Newsgroups header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Newsgroups")) (defun message-goto-distribution () - "Move point to the Distribution header." + "Move point to the Distribution header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Distribution")) (defun message-goto-followup-to () - "Move point to the Followup-To header." + "Move point to the Followup-To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Followup-To" "Newsgroups")) (defun message-goto-mail-followup-to () - "Move point to the Mail-Followup-To header." + "Move point to the Mail-Followup-To header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Mail-Followup-To" "To")) (defun message-goto-keywords () - "Move point to the Keywords header." + "Move point to the Keywords header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Keywords" "Subject")) (defun message-goto-summary () - "Move point to the Summary header." + "Move point to the Summary header or insert an empty one." (interactive nil message-mode) (push-mark) (message-position-on-field "Summary" "Subject")) @@ -4249,6 +4249,10 @@ This function strips off the signature from the original message." (newline))) (defun message-position-on-field (header &rest afters) + "Move point to header HEADER or insert it if not found. + +If HEADER is not present, insert it with an empty value, after any +headers specified in AFTERS." (let ((case-fold-search t)) (save-restriction (narrow-to-region commit 0033ce9ef8eff2c8dfef644f2f110bc0edfa22aa Author: Tomas Volf <~@wolfsden.cz> Date: Tue Dec 3 15:40:53 2024 +0100 Actually remove the Mail-Followup-To header iff empty * lisp/gnus/message.el (message-send-mail): Pass a fixed string instead of regexp to 'message-remove-header' (Bug#74658). Copyright-paperwork-exempt: yes diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index b49e3f9d9ca..b4c5a1e2436 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -4900,7 +4900,7 @@ If you always want Gnus to send messages in one piece, set message-required-mail-headers)) ;; otherwise, delete the MFT header if the field is empty (when (equal "" (mail-fetch-field "mail-followup-to")) - (message-remove-header "^Mail-Followup-To:"))) + (message-remove-header "Mail-Followup-To"))) ;; Insert some headers. (let ((message-deletable-headers (if news nil message-deletable-headers))) commit fef05ba8f409738625167991e811c2ab50f5b047 Author: Michael Albinus Date: Tue Dec 3 13:23:28 2024 +0100 ; Minor fixes in tramp-tests.el * test/lisp/net/tramp-tests.el (ert-batch-backtrace-right-margin): Set it to nil. (tramp--test-enabled): Fix regexps. diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index b28b76ac979..91d0fd82788 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -144,6 +144,7 @@ (setq auth-source-cache-expiry nil auth-source-save-behavior nil + ert-batch-backtrace-right-margin nil password-cache-expiry nil remote-file-name-inhibit-cache nil tramp-allow-unsafe-temporary-files t @@ -254,30 +255,27 @@ being the result.") (dolist (dir `(,temporary-file-directory ,tramp-compat-temporary-file-directory ,ert-remote-temporary-file-directory)) - (dolist - (file - (directory-files - dir 'full - (rx bos (? ".#") - (| (literal tramp-test-name-prefix) - (eval (if (getenv "TRAMP_TEST_CLEANUP_TEMP_FILES") - tramp-temp-name-prefix 'unmatchable)))))) + (dolist (file (directory-files + dir 'full + (rx-to-string + `(: bos (? ".#") + (| ,tramp-test-name-prefix + ,(if (getenv "TRAMP_TEST_CLEANUP_TEMP_FILES") + tramp-temp-name-prefix 'unmatchable)))))) ;; Exclude sockets and FUSE mount points. (ignore-errors (unless (or (string-prefix-p "srw" (file-attribute-modes (file-attributes file))) - (string-match-p (rx bos (literal tramp-fuse-name-prefix) - (regexp tramp-method-regexp) ".") - (file-name-nondirectory file)) ;; Prior Emacs 31.1, the FUSE mount points where - ;; "tramp-rclone.*" and "tramp-sshfs.*". We should - ;; exclude them as well, in order not to make - ;; trouble. - (string-match-p (rx bos (literal tramp-temp-name-prefix) - (| "rclone" "fuse") ".") - (file-name-nondirectory file))) + ;; "tramp.rclone.*" and "tramp.sshfs.*". We should + ;; exclude them as well, in order to avoid trouble. + (string-match-p + (rx bos (| (literal tramp-fuse-name-prefix) + (literal tramp-temp-name-prefix)) + (| "rclone" "sshfs") ".") + (file-name-nondirectory file))) (tramp--test-message "Delete %s" file) (if (file-directory-p file) (delete-directory file 'recursive) commit 7b8d12e95de6e6b5239c538ad6f5af96dc3e1c2a Author: Stephen Berman Date: Tue Dec 3 10:38:26 2024 +0100 Fix the latest dabbrev-expand test fix * test/lisp/dabbrev-tests.el (dabbrev-expand-after-killing-buffer): In batch runs of this file, the user-error message contains curved quotes, but grave quotes when running `make check' (so here was evidently not passed to `substitute-command-keys'), so use grave quotes so the test succeeds in both modes of execution. diff --git a/test/lisp/dabbrev-tests.el b/test/lisp/dabbrev-tests.el index 3e84024698f..fb8715924d1 100644 --- a/test/lisp/dabbrev-tests.el +++ b/test/lisp/dabbrev-tests.el @@ -294,9 +294,14 @@ leaving the unexpanded string in the buffer." ; See bug#74090. (should (string= (buffer-string) "abc abd")) (kill-buffer "foo") (erase-buffer) - (let ((msg (cadr (should-error (execute-kbd-macro (kbd "abc SPC ab M-/ M-/")) + ;; In batch runs of this file, the user-error message contains curved + ;; quotes, but grave quotes when running `make check' (so here was + ;; evidently not passed to `substitute-command-keys'), so use grave + ;; quotes so the test succeeds in both modes of execution. + (let* ((text-quoting-style 'grave) + (msg (cadr (should-error (execute-kbd-macro (kbd "abc SPC ab M-/ M-/")) :type 'user-error)))) (should (string= (buffer-string) "abc ab")) - (should (string= msg "No further dynamic expansion for ‘ab’ found"))))) + (should (string= msg "No further dynamic expansion for `ab' found"))))) ;;; dabbrev-tests.el ends here commit 04d035acd72823e82dd61c4894f9c09113e65dd6 Author: Andrea Corallo Date: Tue Dec 3 09:24:52 2024 +0100 * lisp/progmodes/c-ts-mode.el (treesit-node-match-p): Declare. diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 6699e4ece48..710160ea472 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -86,6 +86,7 @@ (declare-function treesit-node-first-child-for-pos "treesit.c") (declare-function treesit-node-next-sibling "treesit.c") (declare-function treesit-node-eq "treesit.c") +(declare-function treesit-node-match-p "treesit.c") (declare-function treesit-query-compile "treesit.c") ;;; Custom variables commit 8534bb2d6b55ba55639058a5637da1f28797dddb Author: Dmitry Gutov Date: Tue Dec 3 04:31:07 2024 +0200 project-try-vc--search: Fix inside recursive submodule setup * lisp/progmodes/project.el (project-try-vc--search): Loop when looking for submodule parent repository (bug#74614). diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index cf1c94a6d20..33e8aab469b 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -591,10 +591,10 @@ See `project-vc-extra-root-markers' for the marker value format.") last-matches)) vc-handled-backends)) project) - (when (and - (eq backend 'Git) - (project--vc-merge-submodules-p root) - (project--submodule-p root)) + (while (and + (eq backend 'Git) + (project--vc-merge-submodules-p root) + (project--submodule-p root)) (let* ((parent (file-name-directory (directory-file-name root)))) (setq root (vc-call-backend 'Git 'root parent)))) (when root commit f9e7f57f5710fe929fce468f8875a7310e73be05 Author: Andrea Corallo Date: Mon Dec 2 21:51:29 2024 +0100 * Declare few treesit-* function to clean-up wanrnings * lisp/progmodes/c-ts-common.el (treesit-parser-language) (treesit-node-match-p, treesit-node-child, treesit-node-eq) (treesit-parser-root-node, treesit-node-parser): Declare. diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el index ab5c01bad2d..2689cb51133 100644 --- a/lisp/progmodes/c-ts-common.el +++ b/lisp/progmodes/c-ts-common.el @@ -52,6 +52,12 @@ (declare-function treesit-node-type "treesit.c") (declare-function treesit-node-parent "treesit.c") (declare-function treesit-node-prev-sibling "treesit.c") +(declare-function treesit-parser-language "treesit.c") +(declare-function treesit-node-match-p "treesit.c") +(declare-function treesit-node-child "treesit.c") +(declare-function treesit-node-eq "treesit.c") +(declare-function treesit-parser-root-node "treesit.c") +(declare-function treesit-node-parser "treesit.c") ;;; Comment indentation and filling commit a582034dc5420ba6b8e69d29bbf706f34340825b Author: Michael Albinus Date: Mon Dec 2 19:26:06 2024 +0100 Fix password prompt in comint * lisp/comint.el (comint-password-prompt-regexp): Don't use "'s" as keyword. Add default OpenSSH format. Adapt :version. (comint-watch-for-password-prompt): Adapt prompt composition. (Bug#74626) diff --git a/lisp/comint.el b/lisp/comint.el index 4268fa8dad2..6423e695430 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -404,7 +404,7 @@ This variable is buffer-local." (regexp-opt '("Enter" "enter" "Enter same" "enter same" "Enter the" "enter the" "Current" - "Enter Auth" "enter auth" "Old" "old" "New" "new" "'s" "login" + "Enter Auth" "enter auth" "Old" "old" "New" "new" "login" "Kerberos" "CVS" "UNIX" " SMB" "LDAP" "PEM" "SUDO" "[sudo]" "doas" "Repeat" "Bad" "Retype" "Verify") t) @@ -418,11 +418,13 @@ This variable is buffer-local." ;; The ccrypt encryption dialog doesn't end with a colon, so ;; treat it specially. "\\|^Enter encryption key: (repeat) *\\'" + ;; Default openssh format: "user@host's password:". + "\\|^[^@ \t\n]+@[^@ \t\n]+'s password: *\\'" ;; openssh-8.6p1 format: "(user@host) Password:". "\\|^([^)@ \t\n]+@[^)@ \t\n]+) Password: *\\'") "Regexp matching prompts for passwords in the inferior process. This is used by `comint-watch-for-password-prompt'." - :version "29.1" + :version "31.1" :type 'regexp :group 'comint) @@ -2569,11 +2571,12 @@ to detect the need to (prompt and) send a password. Ignores any carriage returns (\\r) in STRING. This function could be in the list `comint-output-filter-functions'." - (let ((string (string-limit string comint-password-prompt-max-length t)) + (let ((string (string-limit + (string-replace "\r" "" string) + comint-password-prompt-max-length t)) prompt) (when (let ((case-fold-search t)) - (string-match comint-password-prompt-regexp - (string-replace "\r" "" string))) + (string-match comint-password-prompt-regexp string)) (setq prompt (string-trim (match-string 0 string) "[ \n\r\t\v\f\b\a]+" "\n+")) ;; Use `run-at-time' in order not to pause execution of the commit e618d5ae941d005e9da6d5d5cba68cc0ecade0e5 Author: Michael Albinus Date: Mon Dec 2 19:21:54 2024 +0100 Fix password prompt in comint (don't merge) * lisp/comint.el (comint-watch-for-password-prompt): Use whole string for setting the prompt. (Bug#74626) diff --git a/lisp/comint.el b/lisp/comint.el index 8860b3edb11..d52090911b9 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -2573,8 +2573,7 @@ This function could be in the list `comint-output-filter-functions'." (when (let ((case-fold-search t)) (string-match comint-password-prompt-regexp (string-replace "\r" "" string))) - (setq prompt (string-trim (match-string 0 string) - "[ \n\r\t\v\f\b\a]+" "\n+")) + (setq prompt (string-trim string "[ \n\r\t\v\f\b\a]+" "\n+")) ;; Use `run-at-time' in order not to pause execution of the ;; process filter with a minibuffer (run-at-time commit f65de1019dca6398097751abefcad7e1a4637551 Author: Manuel Giraud Date: Mon Dec 2 15:11:52 2024 +0100 Fix the version of librsvg API change * src/image.c (init_svg_functions, svg_load_image): The first official version that introduces 'rsvg_handle_get_pixbuf_and_error' is 2.59.0 not 2.58.0. (Bug#74606) diff --git a/src/image.c b/src/image.c index ed680be54dd..8f505026021 100644 --- a/src/image.c +++ b/src/image.c @@ -11655,7 +11655,7 @@ DEF_DLL_FN (void, rsvg_handle_get_dimensions, DEF_DLL_FN (gboolean, rsvg_handle_set_stylesheet, (RsvgHandle *, const guint8 *, gsize, GError **)); # endif -# if LIBRSVG_CHECK_VERSION (2, 58, 0) +# if LIBRSVG_CHECK_VERSION (2, 59, 0) DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf_and_error, (RsvgHandle *, GError **)); # else DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *)); @@ -11718,7 +11718,7 @@ init_svg_functions (void) #if LIBRSVG_CHECK_VERSION (2, 48, 0) LOAD_DLL_FN (library, rsvg_handle_set_stylesheet); #endif -#if LIBRSVG_CHECK_VERSION (2, 58, 0) +#if LIBRSVG_CHECK_VERSION (2, 59, 0) LOAD_DLL_FN (library, rsvg_handle_get_pixbuf_and_error); #else LOAD_DLL_FN (library, rsvg_handle_get_pixbuf); @@ -11767,7 +11767,7 @@ init_svg_functions (void) # if LIBRSVG_CHECK_VERSION (2, 48, 0) # undef rsvg_handle_set_stylesheet # endif -# if LIBRSVG_CHECK_VERSION (2, 58, 0) +# if LIBRSVG_CHECK_VERSION (2, 59, 0) # undef rsvg_handle_get_pixbuf_and_error # else # undef rsvg_handle_get_pixbuf @@ -11812,7 +11812,7 @@ init_svg_functions (void) # if LIBRSVG_CHECK_VERSION (2, 48, 0) # define rsvg_handle_set_stylesheet fn_rsvg_handle_set_stylesheet # endif -# if LIBRSVG_CHECK_VERSION (2, 58, 0) +# if LIBRSVG_CHECK_VERSION (2, 59, 0) # define rsvg_handle_get_pixbuf_and_error fn_rsvg_handle_get_pixbuf_and_error # else # define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf @@ -12321,7 +12321,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, /* We can now get a valid pixel buffer from the svg file, if all went ok. */ -#if LIBRSVG_CHECK_VERSION (2, 58, 0) +#if LIBRSVG_CHECK_VERSION (2, 59, 0) pixbuf = rsvg_handle_get_pixbuf_and_error (rsvg_handle, &err); if (err) goto rsvg_error; #else commit 43c4a06ffcc8dd39a3fb743aca5aa9a71e74189c Author: Eli Zaretskii Date: Mon Dec 2 14:33:52 2024 +0200 ; Fix grammar in Emacs user manual * doc/emacs/trouble.texi (Sending Patches): Fix wording. Reported by Daniel Martín . (Bug#74638) diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi index 2e2ee2dc961..f867943a8a0 100644 --- a/doc/emacs/trouble.texi +++ b/doc/emacs/trouble.texi @@ -1255,7 +1255,7 @@ Send them @emph{individually}. If you make two changes for separate reasons, then we might not want to install them both. We might want to install just one, or install -each one in a different versions of Emacs. If you send them all +them separately in different versions of Emacs. If you send them all jumbled together in a single set of diffs, we have to do extra work to disentangle them---to figure out which parts of the change serve which purpose. If we don't have time for this, we might have to postpone commit 6bca138d60e47d0fbab4faf8e83c5b9b319f260d Author: Stephen Berman Date: Mon Dec 2 13:13:39 2024 +0100 Fix latest test for dabbrev-expand * test/lisp/dabbrev-tests.el (dabbrev-expand-after-killing-buffer): Fix typo in a 'should' test, use part of return value of 'should-error' test, and remove mistaken and unfounded FIXME comment. diff --git a/test/lisp/dabbrev-tests.el b/test/lisp/dabbrev-tests.el index b5737373875..3e84024698f 100644 --- a/test/lisp/dabbrev-tests.el +++ b/test/lisp/dabbrev-tests.el @@ -278,12 +278,8 @@ minibuffer was entered, the replacement should found in another buffer." (ert-deftest dabbrev-expand-after-killing-buffer () "Test expansion after killing buffer containing first expansion. Finding successive expansions in another live buffer should succeed, but -after killing the buffer, expansion should fail with a user-error." - ;; FIXME? The message shown by the user-error is in *Messages* but - ;; since the test finishes on hitting the user-error, we cannot test - ;; further, either for the content of the message or the content of - ;; the current buffer, so apparently cannot reproduce what a user - ;; entering these commands manually sees. +after killing the buffer, expansion should fail with a user-error, +leaving the unexpanded string in the buffer." ; See bug#74090. (with-dabbrev-test (with-current-buffer (get-buffer-create "foo") (insert "abc abd")) @@ -298,13 +294,9 @@ after killing the buffer, expansion should fail with a user-error." (should (string= (buffer-string) "abc abd")) (kill-buffer "foo") (erase-buffer) - (should-error (execute-kbd-macro (kbd "abc SPC ab M-/ M-/")) - :type 'user-error) - ;; (should (string= (buffer-string) "abc abc")) - ;; (with-current-buffer "*Messages*" - ;; (goto-char (point-max)) - ;; (should (string= (buffer-substring (pos-bol) (pos-eol)) - ;; "No further dynamic expansion for ‘ab’ found"))) - )) + (let ((msg (cadr (should-error (execute-kbd-macro (kbd "abc SPC ab M-/ M-/")) + :type 'user-error)))) + (should (string= (buffer-string) "abc ab")) + (should (string= msg "No further dynamic expansion for ‘ab’ found"))))) ;;; dabbrev-tests.el ends here commit a79c300a88b195572e57c79fa5b23cdf0e3460d5 Author: Eli Zaretskii Date: Mon Dec 2 14:11:00 2024 +0200 ; Fix recently-updated documentation * doc/lispref/modes.texi (Parser-based Indentation): Fix markup, typos and wording. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index f32d5a89bca..ed7cc141cd5 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -5245,11 +5245,12 @@ more complex indentation engines. @defvar treesit-simple-indent-rules This local variable stores indentation rules for every language. It is an list of elements of the form @w{@code{(@var{language} -@var{rule}...)}}, where @var{language} is a language symbol, and each +@var{rule}@dots{})}}, where @var{language} is a language symbol, and each @var{rule} is either a list with elements of the form -@w{@code{(@var{matcher} @var{anchor} @var{offset})}}, or a function. Let -'s focus on the list variant first, we'll come back to the function -variant later. +@w{@code{(@var{matcher} @var{anchor} @var{offset})}}, or a function. + +Here's the description of the list variant, followed by the function +variant. First, Emacs passes the smallest tree-sitter node at the beginning of the current line to @var{matcher}; if it returns non-@code{nil}, this @@ -5280,14 +5281,13 @@ or a function that returns an integer. If it is a function, it is passed @var{node}, @var{parent}, and @var{bol}, like matchers and anchors. -Remember that @var{rule} can also be a function. This is for the -complex cases where a rule needs to consider the matching rule and -anchor together. If @var{rule} is a function, it's passed the same -argument as @var{matcher}: @var{node}, @var{parent}, and @var{bol}. If -it matches, @var{rule} should return a cons @w{@code{(@var{anchor-pos} -. @var{offset})}}, where @var{anchor-pos} is a buffer position, and -@var{offset} is the indent offset. If @var{rule} does't match, it -should return @code{nil}. +If @var{rule}is a function, it is useful for the complex cases where a +rule needs to consider the matching rule and the anchor together. The +@var{rule} function is passed the same argument as @var{matcher}: +@var{node}, @var{parent}, and @var{bol}. If it matches, @var{rule} +should return a cons @w{@code{(@var{anchor-pos} . @var{offset})}}, where +@var{anchor-pos} is a buffer position, and @var{offset} is the indent +offset. If @var{rule} doesn't match, it should return @code{nil}. @end defvar @defvar treesit-simple-indent-presets commit 8cd4ab7abde87ac04e05442196b4646ab46df9a7 Author: Manuel Giraud Date: Thu Nov 21 17:19:59 2024 +0100 Do not use libjpeg quantization (bug#74476) * src/image.c (jpeg_load_body): Remove libjpeg quantization. diff --git a/src/image.c b/src/image.c index 88b0f91413e..43220758324 100644 --- a/src/image.c +++ b/src/image.c @@ -8949,9 +8949,8 @@ jpeg_load_body (struct frame *f, struct image *img, FILE *fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; - int width, height; - int i, ir, ig, ib; - unsigned long *colors; + int width, height, ncomp; + int ir, ig, ib; Emacs_Pix_Container volatile ximg_volatile = NULL; /* Open the JPEG file. */ @@ -9049,12 +9048,17 @@ jpeg_load_body (struct frame *f, struct image *img, jpeg_read_header (&mgr->cinfo, 1); - /* Customize decompression so that color quantization will be used. - Start decompression. */ - mgr->cinfo.quantize_colors = 1; + /* Start decompression. */ jpeg_start_decompress (&mgr->cinfo); width = img->width = mgr->cinfo.output_width; height = img->height = mgr->cinfo.output_height; + ncomp = mgr->cinfo.output_components; + if (ncomp > 2) + ir = 0, ig = 1, ib = 2; + else if (ncomp > 1) + ir = 0, ig = 1, ib = 0; + else + ir = 0, ig = 0, ib = 0; if (!check_image_size (f, width, height)) { @@ -9073,55 +9077,34 @@ jpeg_load_body (struct frame *f, struct image *img, sys_longjmp (mgr->setjmp_buffer, 1); } - /* Allocate colors. When color quantization is used, - mgr->cinfo.actual_number_of_colors has been set with the number of - colors generated, and mgr->cinfo.colormap is a two-dimensional array - of color indices in the range 0..mgr->cinfo.actual_number_of_colors. - No more than 255 colors will be generated. */ - USE_SAFE_ALLOCA; - { - if (mgr->cinfo.out_color_components > 2) - ir = 0, ig = 1, ib = 2; - else if (mgr->cinfo.out_color_components > 1) - ir = 0, ig = 1, ib = 0; - else - ir = 0, ig = 0, ib = 0; - - /* Use the color table mechanism because it handles colors that - cannot be allocated nicely. Such colors will be replaced with - a default color, and we don't have to care about which colors - can be freed safely, and which can't. */ - init_color_table (); - SAFE_NALLOCA (colors, 1, mgr->cinfo.actual_number_of_colors); - - for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i) - { - /* Multiply RGB values with 255 because X expects RGB values - in the range 0..0xffff. */ - int r = mgr->cinfo.colormap[ir][i] << 8; - int g = mgr->cinfo.colormap[ig][i] << 8; - int b = mgr->cinfo.colormap[ib][i] << 8; - colors[i] = lookup_rgb_color (f, r, g, b); - } - -#ifdef COLOR_TABLE_SUPPORT - /* Remember those colors actually allocated. */ - img->colors = colors_in_color_table (&img->ncolors); - free_color_table (); -#endif /* COLOR_TABLE_SUPPORT */ - } - - /* Read pixels. */ - row_stride = width * mgr->cinfo.output_components; + /* Allocate scanlines buffer and Emacs color table. */ + row_stride = width * ncomp; buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo, JPOOL_IMAGE, row_stride, 1); + init_color_table (); + + /* Fill the X image from JPEG data. */ for (y = 0; y < height; ++y) { jpeg_read_scanlines (&mgr->cinfo, buffer, 1); - for (x = 0; x < mgr->cinfo.output_width; ++x) - PUT_PIXEL (ximg, x, y, colors[buffer[0][x]]); + for (x = 0; x < width; ++x) + { + int off = x * ncomp; + /* Multiply RGB values with 255 because X expects RGB values + in the range 0..0xffff. */ + int r = buffer[0][off + ir] << 8; + int g = buffer[0][off + ig] << 8; + int b = buffer[0][off + ib] << 8; + PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b)); + } } +#ifdef COLOR_TABLE_SUPPORT + /* Remember those colors actually allocated. */ + img->colors = colors_in_color_table (&img->ncolors); + free_color_table (); +#endif /* COLOR_TABLE_SUPPORT */ + /* Clean up. */ jpeg_finish_decompress (&mgr->cinfo); jpeg_destroy_decompress (&mgr->cinfo); @@ -9135,7 +9118,6 @@ jpeg_load_body (struct frame *f, struct image *img, /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); - SAFE_FREE (); return 1; }