commit bfa0cb81ddae6ce3e37f4cc4da4725a2f396d784 (HEAD, refs/remotes/origin/master) Author: Elías Gabriel Pérez Date: Tue Nov 18 11:02:24 2025 -0600 hideshow: Fix regressions. (Bug#79857) * lisp/progmodes/hideshow.el (hs-block-positions): Exit the function if 'hs-forward-sexp' fails. (hs-hide-level-recursive): Fix infloop. * test/lisp/progmodes/hideshow-tests.el (hideshow-hide-level-1): (hideshow-hide-level-2): Update tests. diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el index 62bbbe40164..78990993449 100644 --- a/lisp/progmodes/hideshow.el +++ b/lisp/progmodes/hideshow.el @@ -794,34 +794,39 @@ to call with the newly initialized overlay." This returns a list with the current code block beginning and end positions. This does nothing if there is not a code block at current point." - (save-match-data - (save-excursion - (when (funcall hs-looking-at-block-start-predicate) - (let ((mdata (match-data t)) - (header-end (match-end 0)) - block-beg block-end) - ;; `block-start' is the point at the end of the block - ;; beginning, which may need to be adjusted - (save-excursion - (when hs-adjust-block-beginning-function - (goto-char (funcall hs-adjust-block-beginning-function header-end))) - (setq block-beg (line-end-position))) - ;; `block-end' is the point at the end of the block - (hs-forward-sexp mdata 1) - (setq block-end - (cond ((and (stringp hs-block-end-regexp) - (looking-back hs-block-end-regexp nil)) - (match-beginning 0)) - ((functionp hs-block-end-regexp) - (funcall hs-block-end-regexp) - (match-beginning 0)) - (t (point)))) - ;; adjust block end (if needed) - (when hs-adjust-block-end-function + ;; `catch' is used here if the search fails due unbalanced parentheses + ;; or any other unknown error caused in `hs-forward-sexp'. + (catch 'hs-sexp-error + (save-match-data + (save-excursion + (when (funcall hs-looking-at-block-start-predicate) + (let ((mdata (match-data t)) + (header-end (match-end 0)) + block-beg block-end) + ;; `block-start' is the point at the end of the block + ;; beginning, which may need to be adjusted + (save-excursion + (when hs-adjust-block-beginning-function + (goto-char (funcall hs-adjust-block-beginning-function header-end))) + (setq block-beg (line-end-position))) + ;; `block-end' is the point at the end of the block + (condition-case _ + (hs-forward-sexp mdata 1) + (scan-error (throw 'hs-sexp-error nil))) (setq block-end - (or (funcall hs-adjust-block-end-function block-beg) - block-end))) - (list block-beg block-end)))))) + (cond ((and (stringp hs-block-end-regexp) + (looking-back hs-block-end-regexp nil)) + (match-beginning 0)) + ((functionp hs-block-end-regexp) + (funcall hs-block-end-regexp) + (match-beginning 0)) + (t (point)))) + ;; adjust block end (if needed) + (when hs-adjust-block-end-function + (setq block-end + (or (funcall hs-adjust-block-end-function block-beg) + block-end))) + (list block-beg block-end))))))) (defun hs--make-indicators-overlays (beg) "Helper function to make the indicators overlays." @@ -1177,8 +1182,11 @@ region (point MAXP)." (not (nth 8 (syntax-ppss)))) ; not inside comments or strings (if (> arg 1) (hs-hide-level-recursive (1- arg) minp maxp) - (goto-char (match-beginning hs-block-start-mdata-select)) - (hs-hide-block-at-point t)))) + ;; `hs-hide-block-at-point' already moves the cursor, but if it + ;; fails, return to the previous position where we were. + (unless (and (goto-char (match-beginning hs-block-start-mdata-select)) + (hs-hide-block-at-point t)) + (goto-char (match-end hs-block-start-mdata-select)))))) (goto-char maxp)) (defmacro hs-life-goes-on (&rest body) diff --git a/test/lisp/progmodes/hideshow-tests.el b/test/lisp/progmodes/hideshow-tests.el index a6b3ecfbd3d..9cf60c1ec84 100644 --- a/test/lisp/progmodes/hideshow-tests.el +++ b/test/lisp/progmodes/hideshow-tests.el @@ -254,6 +254,8 @@ sub() Comments */ +\"String\" + int main(int argc, char **argv) { @@ -270,6 +272,8 @@ main(int argc, char **argv) Comments */ +\"String\" + int main(int argc, char **argv) {} @@ -284,6 +288,8 @@ main(int argc, char **argv) Comments */ +\"String\" + int main(int argc, char **argv) { @@ -300,6 +306,8 @@ main(int argc, char **argv) Comments */ +\"String\" + int main(int argc, char **argv) { commit 4532f5ae8f690f1e663706aea265461061f6b522 Author: Stefan Monnier Date: Tue Nov 18 17:33:11 2025 -0500 (loaddefs-generate--emacs-batch): Fix bug#79821 again Hopefully, this one is for good. Use `file-truename` on all the input file/dir names to try and make sure we don't get bitten any more by symlinks or driver letter capitalization. * lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate): Revert last change. (loaddefs-generate--excluded-files): Remove test that's not needed any more now that we use all relative names. (loaddefs-generate--emacs-batch): Apply truename to all input files/dirs. diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index 44f370bdff9..a6430cc8f55 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -91,7 +91,7 @@ follows: The autoload file is assumed to contain a trailer starting with a FormFeed character.") ;;;###autoload -(put 'generated-autoload-file 'safe-local-variable 'stringp) +(put 'generated-autoload-file 'safe-local-variable #'stringp) (defvar generated-autoload-load-name nil "Load name for `autoload' statements generated from autoload cookies. @@ -100,7 +100,7 @@ Typically, you need to set this when the directory containing the file is not in `load-path'. This also affects the generated cus-load.el file.") ;;;###autoload -(put 'generated-autoload-load-name 'safe-local-variable 'stringp) +(put 'generated-autoload-load-name 'safe-local-variable #'stringp) (defun loaddefs-generate--file-load-name (file outfile) "Compute the name that will be used to load FILE. @@ -406,7 +406,7 @@ expand)' among their `declare' forms." nil)))) prefixes))) `(register-definition-prefixes ,file ',(sort (delq nil strings) - 'string<)))))) + #'string<)))))) (defun loaddefs-generate--parse-file (file main-outfile &optional package-data) "Examining FILE for ;;;###autoload statements. @@ -662,15 +662,7 @@ instead of just updating them with the new/changed autoloads." (file-attributes file)))) ;; If we're scanning for package versions, we want to look ;; at the file even if it's excluded. - (let* ((excluded - ;; FIXME: In out-of-tree builds (bug#79694) `excluded-files' - ;; (derived via `lisp-directory' from `invocation-directory') - ;; may end up using names which don't quite match those of - ;; `file' (derived from the command line arguments), w.r.t. - ;; "c:/" vs "C:/" on MS-Windows, so use a test more lax - ;; than `member'. - (let ((x (member-ignore-case file excluded-files))) - (and x (file-equal-p file (car x))))) + (let* ((excluded (member file excluded-files)) (package-data (and include-package-version (if excluded 'only t)))) (when (or package-data (not excluded)) @@ -789,8 +781,6 @@ instead of just updating them with the new/changed autoloads." ;; Exclude those files that are preloaded on ALL platforms. ;; These are the ones in loadup.el where "(load" is at the start ;; of the line (crude, but it works). - (unless (equal default-directory (file-name-as-directory lisp-directory)) - (error "PWD is not set as expected: %S" default-directory)) (let ((excludes nil)) (with-temp-buffer (insert-file-contents "loadup.el") @@ -821,11 +811,11 @@ use." "Generate the loaddefs for the Emacs build. This is like `loaddefs-generate-batch', but has some specific rules for built-in packages and excluded files." - (let* ((args (mapcar #'expand-file-name command-line-args-left)) + (let* ((args (mapcar #'file-truename command-line-args-left)) ;; We're run from $BUILDDIR/lisp but all the .el(c) files reside ;; (and are generated) in `lisp-directory' which is in $SRCDIR, ;; so go there and don't look back. - (default-directory lisp-directory) + (default-directory (file-truename lisp-directory)) (output-file (expand-file-name "loaddefs.el"))) (setq command-line-args-left nil) (loaddefs-generate commit be2b38ce14118a2ff312926602e64dc504b3bf71 Author: Stefan Monnier Date: Tue Nov 18 17:23:11 2025 -0500 (lisp-indent-function): Auto-load macros to get the indent info Rather than preload the `lisp-indent-function` property for autoloaded macros, auto-load them to fetch their property. In terms of cost, this slightly reduces the heap size at startup, while tending to increase the heap size while editing ELisp code since more packages will be (auto)loaded. The benefit is elsewhere: by loading the definition the macro we will also load other (non-autoloaded) definitions, so we get better behavior for things like `ert.el` and `inline.el` where only some of the macros are autoloaded, because there's a good chance that we'll end up loading them to indent the autoloaded macro, after which indentation of the other macros will be performed correctly (bug#68818). * lisp/emacs-lisp/byte-run.el (byte-run--dont-autoload): New function. (macro-declarations-alist): Use it to override `byte-run--set-indent`. * lisp/emacs-lisp/lisp-mode.el (lisp-indent-function): Auto-load macros if needed to get the indent info. diff --git a/lisp/emacs-lisp/byte-run.el b/lisp/emacs-lisp/byte-run.el index 05ee0615fec..47bafbde03e 100644 --- a/lisp/emacs-lisp/byte-run.el +++ b/lisp/emacs-lisp/byte-run.el @@ -246,6 +246,12 @@ declaration" f2 f)) (list 'function-put (list 'quote f) ''function-type (list 'quote val)))) +(defalias 'byte-run--dont-autoload + #'(lambda (fn) + #'(lambda (&rest args) + (let ((code (apply fn args))) + (list 'progn ':autoload-end code))))) + ;; Add any new entries to info node `(elisp)Declare Form'. (defvar defun-declarations-alist (list @@ -368,16 +374,18 @@ This is used by `declare'.") (cons actions cl-decls)))) (defvar macro-declarations-alist - (cons - (list 'debug #'byte-run--set-debug) - (cons + (nconc + (list + (list 'debug #'byte-run--set-debug) ;; macros can declare (autoload-macro expand) to request expansion ;; during autoload generation of forms calling them. See ;; `loaddefs-generate--make-autoload'. (list 'autoload-macro #'byte-run--set-autoload-macro) - (cons - (list 'no-font-lock-keyword #'byte-run--set-no-font-lock-keyword) - defun-declarations-alist))) + ;; Override the entry from `defun-declarations-alist', because we + ;; prefer to autoload the macro when trying to indent it (bug#68818). + (list 'indent (byte-run--dont-autoload #'byte-run--set-indent)) + (list 'no-font-lock-keyword #'byte-run--set-no-font-lock-keyword)) + defun-declarations-alist) "List associating properties of macros to their macro expansion. Each element of the list takes the form (PROP FUN) where FUN is a function. For each (PROP . VALUES) in a macro's declaration, the FUN corresponding diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 0756c0f908f..e91587b5b23 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -861,7 +861,7 @@ or to switch back to an existing one." :type '(choice (const nil) integer) :safe (lambda (x) (or (null x) (integerp x)))) -(defcustom lisp-indent-function 'lisp-indent-function +(defcustom lisp-indent-function #'lisp-indent-function "A function to be called by `calculate-lisp-indent'. It indents the arguments of a Lisp function call. This function should accept two arguments: the indent-point, and the @@ -1256,7 +1256,7 @@ Lisp function does not specify a special indentation." (progn (forward-sexp 1) (point)))) method) (setq method (or (function-get (intern-soft function) - 'lisp-indent-function) + 'lisp-indent-function 'macro) (get (intern-soft function) 'lisp-indent-hook))) (cond ((or (eq method 'defun) ;; Check whether we are in flet-like form. commit 6b389a61c151e3b37eba4557bbb071682e0e4ac3 Author: Anatolii Smolianinov Date: Tue Nov 18 20:52:30 2025 +0000 Eglot: use symbol at point as default in eglot-rename (bug#79757) * lisp/progmodes/eglot.el (eglot-rename): Tweak. Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 2e46e3fe766..f46d6b2ee76 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -4075,12 +4075,10 @@ edit proposed by the server." (defun eglot-rename (newname) "Rename the current symbol to NEWNAME." (interactive - (list (read-from-minibuffer - (eglot--format "Rename `%s' to: " - (or (thing-at-point 'symbol t) - "unknown symbol")) - nil nil nil nil - (symbol-name (symbol-at-point))))) + (let ((tap (thing-at-point 'symbol t))) + (list (read-from-minibuffer + (format "Rename `%s' to: " (or tap "unknown symbol")) + tap nil nil nil tap)))) (eglot-server-capable-or-lose :renameProvider) (eglot--apply-workspace-edit (eglot--request (eglot--current-server-or-lose) commit 6b0cf8ab8721d8136b32a879f4d1de3173627133 Author: Juri Linkov Date: Tue Nov 18 19:57:04 2025 +0200 Display daemon startup warnings on the first client frame (bug#79783) * lisp/emacs-lisp/warnings.el (display-warning): For warnings/errors on the initial daemon frame use 'after-make-frame-functions' to postpone their display until the first client frame is created. (warning--display-buffer): New internal function refactored out of 'display-warning'. diff --git a/lisp/emacs-lisp/warnings.el b/lisp/emacs-lisp/warnings.el index 40fa98b24eb..62ab3f47214 100644 --- a/lisp/emacs-lisp/warnings.el +++ b/lisp/emacs-lisp/warnings.el @@ -372,7 +372,14 @@ entirely by setting `warning-suppress-types' or (if (bolp) (forward-char -1)) (message "%s" (buffer-substring start (point)))))) - ((and (daemonp) (null after-init-time)) + ((and (daemonp) (eq (selected-frame) terminal-frame)) + ;; Display daemon startup warnings on the first client frame. + (letrec ((afterfun + (lambda (frame) + (remove-hook 'after-make-frame-functions afterfun) + (with-selected-frame frame + (warning--display-buffer buffer))))) + (add-hook 'after-make-frame-functions afterfun)) ;; Warnings assigned during daemon initialization go into ;; the messages buffer. (message "%s" @@ -388,23 +395,27 @@ entirely by setting `warning-suppress-types' or (or (< (warning-numeric-level level) (warning-numeric-level warning-minimum-level)) (warning-suppress-p type warning-suppress-types) - (let ((window (display-buffer - buffer - (when warning-display-at-bottom - `(display-buffer--maybe-at-bottom - (window-height - . ,(lambda (window) - (fit-window-to-buffer window 10))) - (category . warning)))))) - (when (and window (markerp warning-series) - (eq (marker-buffer warning-series) buffer)) - (set-window-start window warning-series)) - (when (and window warning-display-at-bottom) - (with-selected-window window - (goto-char (point-max)) - (forward-line -1) - (recenter -1))) - (sit-for 0))))))))) + (warning--display-buffer buffer)))))))) + +(defun warning--display-buffer (buffer) + (let ((window (display-buffer + buffer + (when warning-display-at-bottom + `(display-buffer--maybe-at-bottom + (window-height + . ,(lambda (window) + (fit-window-to-buffer window 10))) + (category . warning)))))) + (when (and window (markerp warning-series) + (eq (marker-buffer warning-series) buffer)) + (set-window-start window warning-series)) + (when (and window warning-display-at-bottom) + (with-selected-window window + (goto-char (point-max)) + (forward-line -1) + (recenter -1))) + (sit-for 0))) + ;; Use \\ so that help-enable-autoload can do its thing. ;; Any keymap that is defined will do. commit 6415fc5e0484410d165c8f78e356d944a68c9353 Author: Jonas Bernoulli Date: Tue Nov 18 17:55:10 2025 +0100 Update to Transient v0.11.0-10-g6637364e diff --git a/doc/misc/transient.texi b/doc/misc/transient.texi index 71f35011496..d55244d0579 100644 --- a/doc/misc/transient.texi +++ b/doc/misc/transient.texi @@ -25,13 +25,13 @@ General Public License for more details. @dircategory Emacs misc features @direntry -* Transient: (transient). Transient Commands. +* Transient: (transient). Transient Commands. @end direntry @finalout @titlepage @title Transient User and Developer Manual -@subtitle for version 0.10.1 +@subtitle for version 0.11.0 @author Jonas Bernoulli @page @vskip 0pt plus 1filll @@ -53,7 +53,7 @@ resource to get over that hurdle is Psionic K's interactive tutorial, available at @uref{https://github.com/positron-solutions/transient-showcase}. @noindent -This manual is for Transient version 0.10.1. +This manual is for Transient version 0.11.0. @insertcopying @end ifnottex @@ -385,7 +385,7 @@ than outlined above and even customizable.} If the user does not save the value and just exits using a regular suffix command, then the value is merely saved to the transient's history. That value won't be used when the transient is next invoked, -but it is easily accessible (@pxref{Using History}). +but it is easily accessible (see @ref{Using History}). Option @code{transient-common-command-prefix} controls the prefix key used in the following bindings. For simplicity's sake the default, @kbd{C-x}, @@ -454,8 +454,8 @@ previously used values. Usually the same keys as those mentioned above are bound to those commands. Authors of transients should arrange for different infix commands that -read the same kind of value to also use the same history key -(@pxref{Suffix Slots}). +read the same kind of value to also use the same history key (see +@ref{Suffix Slots}). Both kinds of history are saved to a file when Emacs is exited. @@ -785,7 +785,7 @@ menu buffer. The menu buffer is displayed in a window using The value of this option has the form @code{(@var{FUNCTION} . @var{ALIST})}, where @var{FUNCTION} is a function or a list of functions. Each such function should accept two arguments: a buffer to display and an -alist of the same form as @var{ALIST}. @xref{Choosing Window,,,elisp,}, +alist of the same form as @var{ALIST}. See @ref{Choosing Window,,,elisp,}, for details. The default is: @@ -799,7 +799,7 @@ The default is: This displays the window at the bottom of the selected frame. For alternatives see @ref{Buffer Display Action Functions,,,elisp,}, -and @xref{Buffer Display Action Alists,,,elisp,}. +and @ref{Buffer Display Action Alists,,,elisp,}. When you switch to a different ACTION, you should keep the ALIST entries for @code{dedicated} and @code{inhibit-same-window} in most cases. @@ -861,7 +861,7 @@ used to draw the line. This user option may be overridden if @code{:mode-line-format} is passed when creating a new prefix with @code{transient-define-prefix}. -Otherwise this can be any mode-line format. @xref{Mode Line Format,,,elisp,}, for details. +Otherwise this can be any mode-line format. See @ref{Mode Line Format,,,elisp,}, for details. @end defopt @defopt transient-semantic-coloring @@ -879,6 +879,9 @@ This option controls whether key bindings of infix commands that do not match the respective command-line argument should be highlighted. For other infix commands this option has no effect. +This is mostly indended for autors of transient menus and disabled +by default. + When this option is non-@code{nil}, the key binding for an infix argument is highlighted when only a long argument (e.g., @code{--verbose}) is specified but no shorthand (e.g., @code{-v}). In the rare case that a @@ -1026,10 +1029,10 @@ which can be included in multiple prefixes. See TODO@. as expected by @code{transient-define-prefix}. Note that an infix is a special kind of suffix. Depending on context ``suffixes'' means ``suffixes (including infixes)'' or ``non-infix suffixes''. Here it -means the former. @xref{Suffix Specifications}. +means the former. See @ref{Suffix Specifications}. @var{SUFFIX} may also be a group in the same form as expected by -@code{transient-define-prefix}. @xref{Group Specifications}. +@code{transient-define-prefix}. See @ref{Group Specifications}. @item @var{LOC} is a key description (a string as returned by @code{key-description} @@ -1053,11 +1056,11 @@ the function @code{transient--get-layout}. These functions operate on the information stored in the @code{transient--layout} property of the @var{PREFIX} symbol. Elements in that tree are not objects but have the form @code{(@var{CLASS} @var{PLIST}) for suffixes} and -[CLASS PLIST CHILDREN] for groups. At the root of the tree is an -element [N nil CHILDREN], where N is the version of the layout format, +@code{[CLASS PLIST CHILDREN]} for groups. At the root of the tree is an +element @code{[N Nil CHILDREN]}, where @code{N} is the version of the layout format, currently and hopefully for a long time 2. While that element looks like a group vector, that element does not count when identifying a -group using a coordinate vector, i.e., [0] is its first child, not the +group using a coordinate vector, i.e., @code{[0]} is its first child, not the root element itself. @defun transient-insert-suffix prefix loc suffix &optional keep-other @@ -1202,14 +1205,14 @@ enabled. One benefit of the Transient interface is that it remembers history not only on a global level (``this command was invoked using these arguments, and previously it was invoked using those other arguments''), but also remembers the values of individual arguments -independently. @xref{Using History}. +independently. See @ref{Using History}. After a transient prefix command is invoked, @kbd{C-h @var{KEY}} can be used to show the documentation for the infix or suffix command that @kbd{@var{KEY}} is bound to (see @ref{Getting Help for Suffix Commands}), and infixes and suffixes can be removed from the transient using @kbd{C-x l @var{KEY}}. Infixes and suffixes that are disabled by default can be enabled the same way. -@xref{Enabling and Disabling Suffixes}. +See @ref{Enabling and Disabling Suffixes}. Transient ships with support for a few different types of specialized infix commands. A command that sets a command line option, for example, @@ -1260,7 +1263,7 @@ explicitly. @var{GROUP}s add key bindings for infix and suffix commands and specify how these bindings are presented in the menu buffer. At least one -@var{GROUP} has to be specified. @xref{Binding Suffix and Infix Commands}. +@var{GROUP} has to be specified. See @ref{Binding Suffix and Infix Commands}. The @var{BODY} is optional. If it is omitted, then @var{ARGLIST} is ignored and the function definition becomes: @@ -1311,13 +1314,11 @@ GROUPs have the same form as for @code{transient-define-prefix}. @section Binding Suffix and Infix Commands The macro @code{transient-define-prefix} is used to define a transient. -This defines the actual transient prefix command (@pxref{Defining -Transients}) and adds the transient's infix and suffix bindings, as +This defines the actual transient prefix command (see @ref{Defining Transients}) and adds the transient's infix and suffix bindings, as described below. Users and third-party packages can add additional bindings using -functions such as @code{transient-insert-suffix} (@pxref{Modifying Existing Transients}). -These functions take a ``suffix specification'' as one of +functions such as @code{transient-insert-suffix} (see @ref{Modifying Existing Transients}). These functions take a ``suffix specification'' as one of their arguments, which has the same form as the specifications used in @code{transient-define-prefix}. @@ -1343,13 +1344,10 @@ brackets to do the latter. Group specifications then have this form: @lisp -[@{@var{LEVEL}@} @{@var{DESCRIPTION}@} - @{@var{KEYWORD} @var{VALUE}@}... - @var{ELEMENT}...] +[@{LEVEL@} @{DESCRIPTION@} @{KEYWORD VALUE@}... ELEMENT...] @end lisp -The @var{LEVEL} is optional and defaults to 4. @xref{Enabling and -Disabling Suffixes}. +The @var{LEVEL} is optional and defaults to 4. See @ref{Enabling and Disabling Suffixes}. The @var{DESCRIPTION} is optional. If present, it is used as the heading of the group. @@ -1500,9 +1498,7 @@ suffixes''. Here it means the former. Suffix specifications have this form: @lisp -([@var{LEVEL}] - [@var{KEY} [@var{DESCRIPTION}]] - @var{COMMAND}|@var{ARGUMENT} [@var{KEYWORD} @var{VALUE}]...) +([LEVEL] [KEY [DESCRIPTION]] COMMAND|ARGUMENT [KEYWORD VALUE]...) @end lisp @var{LEVEL}, @var{KEY} and @var{DESCRIPTION} can also be specified using the @var{KEYWORD}s @@ -1513,8 +1509,8 @@ the object's values just for the binding inside this transient. @itemize @item -@var{LEVEL} is the suffix level, an integer between 1 and 7. -@xref{Enabling and Disabling Suffixes}. +@var{LEVEL} is the suffix level, an integer between 1 and 7. See +@ref{Enabling and Disabling Suffixes}. @item KEY is the key binding, a string in the format returned by @@ -1588,7 +1584,7 @@ guessed based on the long argument. If the argument ends with @samp{=} Finally, details can be specified using optional @var{KEYWORD}-@var{VALUE} pairs. Each keyword has to be a keyword symbol, either @code{:class} or a keyword -argument supported by the constructor of that class. @xref{Suffix Slots}. +argument supported by the constructor of that class. See @ref{Suffix Slots}. If a keyword argument accepts a function as value, you an use a @code{lambda} expression. As a special case, the @code{##} macro (which returns a @code{lambda} @@ -1742,16 +1738,16 @@ its value can be accessed using @code{transient-args}. This function returns the scope of the active or current transient prefix command. -If optional PREFIXES and CLASSES are both nil, return the scope of +If optional PREFIXES and CLASSES are both @code{nil}, return the scope of the prefix currently being setup, making this variation useful, e.g., in @code{:if*} predicates. If no prefix is being setup, but the current command was invoked from some prefix, then return the scope of that. -If PREFIXES is non-nil, it must be a prefix command or a list of such -commands. If CLASSES is non-nil, it must be a prefix class or a list +If PREFIXES is non-@code{nil}, it must be a prefix command or a list of such +commands. If CLASSES is non-@code{nil}, it must be a prefix class or a list of such classes. When this function is called from the body or the @code{interactive} form of a suffix command, PREFIXES and/or CLASSES should -be non-nil. If either is non-nil, try the following in order: +be non-@code{nil}. If either is non-@code{nil}, try the following in order: @itemize @item @@ -1777,7 +1773,7 @@ PREFIXES@. This only works if that slot is set in the respective class definition or using its `transient-init-scope' method. @end itemize -If no prefix matches, return nil. +If no prefix matches, return @code{nil}. @end defun @node Current Suffix Command @@ -1938,8 +1934,8 @@ means that all outer prefixes are exited at once. @item The behavior for non-suffixes can be set for a particular prefix, by the prefix's @code{transient-non-suffix} slot to a boolean, a suitable -pre-command function, or a shorthand for such a function. -@xref{Pre-commands for Non-Suffixes}. +pre-command function, or a shorthand for such a function. See +@ref{Pre-commands for Non-Suffixes}. @item The common behavior for the suffixes of a particular prefix can be @@ -2279,7 +2275,7 @@ object should not affect later invocations. @item All suffix and infix classes derive from @code{transient-suffix}, which in turn derives from @code{transient-child}, from which @code{transient-group} also -derives (@pxref{Group Classes}). +derives (see @ref{Group Classes}). @item All infix classes derive from the abstract @code{transient-infix} class, @@ -2293,7 +2289,7 @@ that does not do so. If you do that then you get to implement many methods. Also, infixes and non-infix suffixes are usually defined using -different macros (@pxref{Defining Suffix and Infix Commands}). +different macros (see @ref{Defining Suffix and Infix Commands}). @item Classes used for infix commands that represent arguments should @@ -2703,7 +2699,7 @@ secondary value, called a ``scope''. See @code{transient-define-prefix}. @code{transient-suffix}, @code{transient-non-suffix} and @code{transient-switch-frame} play a part when determining whether the currently active transient prefix command remains active/transient when a suffix or arbitrary -non-suffix command is invoked. @xref{Transient State}. +non-suffix command is invoked. See @ref{Transient State}. @item @code{refresh-suffixes} Normally suffix objects and keymaps are only setup @@ -2785,7 +2781,7 @@ of the same symbol. @item @code{level} The level of the prefix commands. The suffix commands whose -layer is equal or lower are displayed. @pxref{Enabling and Disabling Suffixes}. +layer is equal or lower are displayed. See @ref{Enabling and Disabling Suffixes}. @item @code{value} The likely outdated value of the prefix. Instead of accessing @@ -2843,7 +2839,7 @@ which is useful for alignment purposes. @code{command} The command, a symbol. @item -@code{transient} Whether to stay transient. @xref{Transient State}. +@code{transient} Whether to stay transient. See @ref{Transient State}. @item @code{format} The format used to display the suffix in the menu buffer. @@ -2886,7 +2882,7 @@ defining a command using @code{transient-define-suffix}. The following two slots are experimental. They can also be set for a group, in which case they apply to all suffixes in that group, except -for suffixes that set the same slot to a non-nil value. +for suffixes that set the same slot to a non-@code{nil} value. @itemize @item @@ -2897,7 +2893,7 @@ advice. @item @code{advice*} A function used to advise the command. Unlike @code{advice}, this advises not only the command body but also its @code{interactive} spec. If -both slots are non-nil, @code{advice} is used for the body and @code{advice*} is +both slots are non-@code{nil}, @code{advice} is used for the body and @code{advice*} is used for the @code{interactive} form. When advising the @code{interactive} spec, called using @code{(funcall advice #'advice-eval-interactive-spec spec)}. @end itemize @@ -3067,14 +3063,14 @@ currently cannot be invoked. By default these predicates run when the prefix command is invoked, but this can be changes, using the @code{refresh-suffixes} prefix slot. -@xref{Prefix Slots}. +See @ref{Prefix Slots}. One more slot is shared between group and suffix classes, @code{level}. Like the slots documented above, it is a predicate, but it is used for a different purpose. The value has to be an integer between 1 and 7. @code{level} controls whether a suffix or a group should be available depending on user preference. -@xref{Enabling and Disabling Suffixes}. +See @ref{Enabling and Disabling Suffixes}. @node FAQ @appendix FAQ diff --git a/lisp/transient.el b/lisp/transient.el index 520270972e8..0ca60c4ceea 100644 --- a/lisp/transient.el +++ b/lisp/transient.el @@ -5,7 +5,7 @@ ;; Author: Jonas Bernoulli ;; URL: https://github.com/magit/transient ;; Keywords: extensions -;; Version: 0.10.1 +;; Version: 0.11.0 ;; SPDX-License-Identifier: GPL-3.0-or-later @@ -33,7 +33,7 @@ ;;; Code: ;;;; Frontmatter -(defconst transient-version "v0.10.1-8-g188ec9a1-builtin") +(defconst transient-version "v0.11.0-10-g6637364e-builtin") (require 'cl-lib) (require 'eieio) @@ -52,22 +52,6 @@ (defvar Man-notify-method) -(static-if (< emacs-major-version 30) - (progn - (defun internal--build-binding@backport-e680827e814 (fn binding prev-var) - "Backport not warning about `_' not being left unused. -Backport fix for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69108, -from Emacs commit e680827e814e155cf79175d87ff7c6ee3a08b69a." - (let ((binding (funcall fn binding prev-var))) - (if (eq (car binding) '_) - (cons (make-symbol "s") (cdr binding)) - binding))) - (advice-add 'internal--build-binding :around - #'internal--build-binding@backport-e680827e814))) - -(make-obsolete-variable 'transient-hide-during-minibuffer-read - 'transient-show-during-minibuffer-read "0.8.0") - (defvar transient-common-command-prefix) (defmacro transient--with-emergency-exit (id &rest body) @@ -94,9 +78,10 @@ from Emacs commit e680827e814e155cf79175d87ff7c6ee3a08b69a." (defcustom transient-show-popup t "Whether and when to show transient's menu in a buffer. -\\ -- If t, then show the buffer as soon as a transient prefix command - is invoked. + +\\\ +- If t (the default), then show the buffer as soon as a transient + prefix command is invoked. - If nil, then do not show the buffer unless the user explicitly requests it, by pressing \\[transient-show] or a prefix key. @@ -118,8 +103,8 @@ from Emacs commit e680827e814e155cf79175d87ff7c6ee3a08b69a." (defcustom transient-enable-popup-navigation 'verbose "Whether navigation commands are enabled in the menu buffer. -If the value is `verbose', additionally show brief documentation -about the command under point in the echo area. +If the value is `verbose' (the default), additionally show brief +documentation about the command under point in the echo area. While a transient is active transient's menu buffer is not the current buffer, making it necessary to use dedicated commands to @@ -208,6 +193,7 @@ want to change the value of `transient-mode-line-format'." (defcustom transient-minimal-frame-width 83 "Minimal width of dedicated frame used to display transient menu. + This is only used if the transient menu is actually displayed in a dedicated frame (see `transient-display-buffer-action'). The value is in characters." @@ -329,12 +315,15 @@ This command is not bound by default, see its docstring for instructions." (defcustom transient-highlight-mismatched-keys nil "Whether to highlight keys that do not match their argument. -This only affects infix arguments that represent command-line -arguments. When this option is non-nil, then the key binding -for infix argument are highlighted when only a long argument -\(e.g., \"--verbose\") is specified but no shorthand (e.g., \"-v\"). -In the rare case that a short-hand is specified but does not -match the key binding, then it is highlighted differently. +This is mostly intended for authors of transient menus and disabled by +default. + +This only affects infix arguments that represent command-line arguments. +When this option is non-nil, then the key binding for infix argument are +highlighted when only a long argument \(e.g., \"--verbose\") is specified +but no shorthand (e.g., \"-v\"). In the rare case that a short-hand is +specified but does not match the key binding, then it is highlighted +differently. The highlighting is done using `transient-mismatched-key' and `transient-nonstandard-key'." @@ -577,10 +566,9 @@ See info node `(transient)Enabling and Disabling Suffixes'." :group 'transient-faces) (defface transient-higher-level - `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1) - :color ,(let ((color (face-attribute 'shadow :foreground t t))) - (or (and (not (eq color 'unspecified)) color) - "grey60"))))) + (let* ((color (face-attribute 'shadow :foreground t t)) + (color (if (eq color 'unspecified) "grey60" color))) + `((t :box (:line-width (-1 . -1) :color ,color)))) "Face optionally used to highlight suffixes on higher levels. See also option `transient-highlight-higher-levels'." :group 'transient-faces) @@ -661,15 +649,13 @@ character used to separate possible values from each other." :group 'transient-faces) (defface transient-nonstandard-key - `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1) - :color "cyan"))) + `((t :box (:line-width (-1 . -1) :color "cyan"))) "Face optionally used to highlight keys conflicting with short-argument. See also option `transient-highlight-mismatched-keys'." :group 'transient-faces) (defface transient-mismatched-key - `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1) - :color "magenta"))) + `((t :box (:line-width (-1 . -1) :color "magenta"))) "Face optionally used to highlight keys without a short-argument. See also option `transient-highlight-mismatched-keys'." :group 'transient-faces) @@ -1397,12 +1383,13 @@ commands are aliases for." (_ (use key val))))) (when spec (error "Need keyword, got %S" (car spec))) - (if-let* ((key (plist-get args :key))) - (when (string-match "\\`\\({p}\\)" key) - (use :key - (replace-match transient-common-command-prefix t t key 1))) - (when-let* ((shortarg (plist-get args :shortarg))) - (use :key shortarg)))) + (cond* + ((bind-and* (key (plist-get args :key))) + (when (string-match "\\`\\({p}\\)" key) + (use :key + (replace-match transient-common-command-prefix t t key 1)))) + ((bind-and* (shortarg (plist-get args :shortarg))) + (use :key shortarg)))) (list 'cons (macroexp-quote (or class 'transient-suffix)) (cons 'list args)))) @@ -1427,8 +1414,7 @@ See also `transient-command-completion-not-suffix-only-p'. Only use this alias as the value of the `completion-predicate' symbol property.") -(when (and (boundp 'read-extended-command-predicate) ; since Emacs 28.1 - (not read-extended-command-predicate)) +(unless read-extended-command-predicate (setq read-extended-command-predicate #'transient-command-completion-not-suffix-only-p)) @@ -1436,50 +1422,52 @@ symbol property.") (put prefix 'transient--layout (vector 2 nil layout))) (defun transient--get-layout (prefix) - (if-let* - ((layout - (or (get prefix 'transient--layout) - ;; Migrate unparsed legacy group definition. - (condition-case-unless-debug err - (and-let* ((value (symbol-value prefix))) - (transient--set-layout - prefix - (if (and (listp value) - (or (listp (car value)) - (vectorp (car value)))) - (transient-parse-suffixes prefix value) - (list (transient-parse-suffix prefix value))))) - (error - (message "Not a legacy group definition: %s: %S" prefix err) - nil))))) - (if (vectorp layout) - (let ((version (aref layout 0))) - (if (= version 2) - layout - (error "Unsupported layout version %s for %s" version prefix))) - ;; Upgrade from version 1. - (cl-labels - ((upgrade (spec) - (cond - ((vectorp spec) - (pcase-let ((`[,level ,class ,args ,children] spec)) - (when level - (setq args (plist-put args :level level))) - (vector class args (mapcar #'upgrade children)))) - ((and (listp spec) - (length= spec 3) - (or (null (car spec)) - (natnump (car spec))) - (symbolp (cadr spec))) - (pcase-let ((`(,level ,class ,args) spec)) - (when level - (setq args (plist-put args :level level))) - (cons class args))) - ((listp spec) - (mapcar #'upgrade spec)) - (t spec)))) - (transient--set-layout prefix (upgrade layout)))) - (error "Not a transient prefix command or group definition: %s" prefix))) + (cond* + ((bind* + (layout + (or (get prefix 'transient--layout) + ;; Migrate unparsed legacy group definition. + (condition-case-unless-debug err + (and-let* ((value (symbol-value prefix))) + (transient--set-layout + prefix + (if (and (listp value) + (or (listp (car value)) + (vectorp (car value)))) + (transient-parse-suffixes prefix value) + (list (transient-parse-suffix prefix value))))) + (error + (message "Not a legacy group definition: %s: %S" prefix err) + nil)))))) + ((not layout) + (error "Not a transient prefix command or group definition: %s" prefix)) + ((vectorp layout) + (let ((version (aref layout 0))) + (if (= version 2) + layout + (error "Unsupported layout version %s for %s" version prefix)))) + (t + ;; Upgrade from version 1. + (transient--set-layout + prefix + (named-let upgrade ((spec layout)) + (cond ((vectorp spec) + (pcase-let ((`[,level ,class ,args ,children] spec)) + (when level + (setq args (plist-put args :level level))) + (vector class args (mapcar #'upgrade children)))) + ((and (listp spec) + (length= spec 3) + (or (null (car spec)) + (natnump (car spec))) + (symbolp (cadr spec))) + (pcase-let ((`(,level ,class ,args) spec)) + (when level + (setq args (plist-put args :level level))) + (cons class args))) + ((listp spec) + (mapcar #'upgrade spec)) + (t spec))))))) (defun transient--get-children (prefix) (aref (transient--get-layout prefix) 2)) @@ -1674,11 +1662,12 @@ See info node `(transient)Modifying Existing Transients'." (defun transient--match-child (group loc child) (cl-etypecase child (string nil) - (symbol (if (symbolp loc) - (and (eq child loc) - (list child group)) - (and-let* ((include (transient--get-layout child))) - (transient--locate-child include loc)))) + (symbol (cond* + ((symbolp loc) + (and (eq child loc) + (list child group))) + ((bind-and* (include (transient--get-layout child))) + (transient--locate-child include loc)))) (vector (seq-some (lambda (subgroup) (transient--locate-child subgroup loc)) (aref group 2))) @@ -1924,47 +1913,46 @@ probably use this instead: (get COMMAND \\='transient--suffix)" (when command (cl-check-type command command)) - (cond - (transient--pending-suffix) - (transient--current-suffix) - ((or transient--prefix - transient-current-prefix) - (let ((suffixes - (cl-remove-if-not - (lambda (obj) - (eq (oref obj command) - (or command - (if (eq this-command 'transient-set-level) - ;; This is how it can look up for which - ;; command it is setting the level. - this-original-command - this-command)))) - (or transient--suffixes - transient-current-suffixes)))) - (cond - ((length= suffixes 1) - (car suffixes)) - ((cl-find-if (lambda (obj) - (equal (listify-key-sequence (kbd (oref obj key))) - (listify-key-sequence (this-command-keys)))) - suffixes)) - ;; COMMAND is only provided if `this-command' is meaningless, in - ;; which case `this-command-keys' is also meaningless, making it - ;; impossible to disambiguate bindings for the same command. - (command (car suffixes)) - ;; If COMMAND is nil, then failure to disambiguate likely means - ;; that there is a bug somewhere. - ((length> suffixes 1) - (error "BUG: Cannot unambiguously determine suffix object")) - ;; It is legimate to use this function as a predicate of sorts. - ;; `transient--pre-command' and `transient-help' are examples. - (t nil)))) - ((and-let* ((obj (transient--suffix-prototype (or command this-command))) - (obj (clone obj))) - (progn - (transient-init-scope obj) - (transient-init-value obj) - obj))))) + (cond* + (transient--pending-suffix) + (transient--current-suffix) + ((or transient--prefix + transient-current-prefix) + (let ((suffixes + (cl-remove-if-not + (lambda (obj) + (eq (oref obj command) + (or command + (if (eq this-command 'transient-set-level) + ;; This is how it can look up for which + ;; command it is setting the level. + this-original-command + this-command)))) + (or transient--suffixes + transient-current-suffixes)))) + (cond + ((length= suffixes 1) + (car suffixes)) + ((cl-find-if (lambda (obj) + (equal (listify-key-sequence (kbd (oref obj key))) + (listify-key-sequence (this-command-keys)))) + suffixes)) + ;; COMMAND is only provided if `this-command' is meaningless, in + ;; which case `this-command-keys' is also meaningless, making it + ;; impossible to disambiguate bindings for the same command. + (command (car suffixes)) + ;; If COMMAND is nil, then failure to disambiguate likely means + ;; that there is a bug somewhere. + ((length> suffixes 1) + (error "BUG: Cannot unambiguously determine suffix object")) + ;; It is legimate to use this function as a predicate of sorts. + ;; `transient--pre-command' and `transient-help' are examples. + (t nil)))) + ((bind-and* (obj (transient--suffix-prototype (or command this-command))) + (obj (clone obj))) + (transient-init-scope obj) + (transient-init-value obj) + obj))) (defun transient--suffix-prototype (command) (or (get command 'transient--suffix) @@ -1997,25 +1985,22 @@ to `transient-predicate-map'." "" #'transient-scroll-up "" #'transient-scroll-down) -(defvar transient-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map transient-base-map) - (keymap-set map "C-u" #'universal-argument) - (keymap-set map "C--" #'negative-argument) - (keymap-set map "C-t" #'transient-show) - (keymap-set map "?" #'transient-help) - (keymap-set map "C-h" #'transient-help) - ;; Next two have additional bindings in transient-common-commands. - (keymap-set map "C-M-p" #'transient-history-prev) - (keymap-set map "C-M-n" #'transient-history-next) - (when (fboundp 'other-frame-prefix) ;Emacs >= 28.1 - (keymap-set map "C-x 5 5" 'other-frame-prefix) - (keymap-set map "C-x 4 4" 'other-window-prefix)) - map) - "Top-level keymap used by all transients. +(defvar-keymap transient-map + :doc "Top-level keymap used by all transients. If you add a new command here, then you must also add a binding -to `transient-predicate-map'. See also `transient-base-map'.") +to `transient-predicate-map'. See also `transient-base-map'." + :parent transient-base-map + "C-u" #'universal-argument + "C--" #'negative-argument + "C-t" #'transient-show + "?" #'transient-help + "C-h" #'transient-help + "C-x 5 5" #'other-frame-prefix + "C-x 4 4" #'other-window-prefix + ;; These have additional bindings in transient-common-commands. + "C-M-p" #'transient-history-prev + "C-M-n" #'transient-history-next) (defvar-keymap transient-edit-map :doc "Keymap that is active while a transient in is in \"edit mode\"." @@ -2449,16 +2434,14 @@ value. Otherwise return CHILDREN as is.") (transient--get-children 'transient-common-commands)))))) (defun transient--flatten-suffixes (layout) - (cl-labels ((s (def) - (cond - ((stringp def) nil) - ((cl-typep def 'transient-information) nil) - ((listp def) (mapcan #'s def)) - ((cl-typep def 'transient-group) - (mapcan #'s (oref def suffixes))) - ((cl-typep def 'transient-suffix) - (list def))))) - (mapcan #'s layout))) + (named-let flatten ((def layout)) + (cond ((stringp def) nil) + ((cl-typep def 'transient-information) nil) + ((listp def) (mapcan #'flatten def)) + ((cl-typep def 'transient-group) + (mapcan #'flatten (oref def suffixes))) + ((cl-typep def 'transient-suffix) + (list def))))) (defun transient--init-child (levels spec parent) (cl-etypecase spec @@ -3825,20 +3808,22 @@ command-line option) or \": \". Finally fall through to using \"(BUG: no prompt): \" as the prompt." - (if-let* ((prompt (oref obj prompt))) - (let ((prompt (if (functionp prompt) - (funcall prompt obj) - prompt))) - (if (stringp prompt) - prompt - "[BUG: invalid prompt]: ")) - (if-let* ((name (or (and (slot-boundp obj 'argument) (oref obj argument)) - (and (slot-boundp obj 'variable) (oref obj variable))))) - (if (and (stringp name) - (string-suffix-p "=" name)) - name - (format "%s: " name)) - "[BUG: no prompt]: "))) + (cond* + ((bind-and* (prompt (oref obj prompt))) + (let ((prompt (if (functionp prompt) + (funcall prompt obj) + prompt))) + (if (stringp prompt) + prompt + "[BUG: invalid prompt]: "))) + ((bind-and* + (name (or (and (slot-boundp obj 'argument) (oref obj argument)) + (and (slot-boundp obj 'variable) (oref obj variable))))) + (if (and (stringp name) + (string-suffix-p "=" name)) + name + (format "%s: " name))) + ("[BUG: no prompt]: "))) ;;;; Set @@ -4415,8 +4400,7 @@ have a history of their own.") (height (cond ((not window-system) nil) ((natnump format) format) ((eq format 'line) 1))) - (face `(,@(and (>= emacs-major-version 27) '(:extend t)) - :background ,(transient--prefix-color)))) + (face `(:background ,(transient--prefix-color) :extend t))) (concat (propertize "__" 'face face 'display `(space :height (,height))) (propertize "\n" 'face face 'line-height t)))) @@ -4699,9 +4683,9 @@ apply the face `transient-unreachable' to the complete string." (when-let* ((face (transient--get-face obj 'face))) (setq desc (transient--add-face desc face t))) (setq desc (propertize "(BUG: no description)" 'face 'error))) - (when (if transient--all-levels-p - (> (oref obj level) transient--default-prefix-level) - (and transient-highlight-higher-levels + (when (cond (transient--all-levels-p + (> (oref obj level) transient--default-prefix-level)) + (transient-highlight-higher-levels (> (max (oref obj level) transient--max-group-level) transient--default-prefix-level))) (setq desc (transient--add-face desc 'transient-higher-level))) @@ -4887,28 +4871,28 @@ if non-nil, else show the `man-page' if non-nil, else use Also used to dispatch showing documentation for the current prefix. If the suffix is a sub-prefix, then also call the prefix method." - (cond - ((eq this-command 'transient-help) - (transient-show-help transient--prefix)) - ((let ((prefix (get (oref obj command) - 'transient--prefix))) - (and prefix (not (eq (oref transient--prefix command) this-command)) - (prog1 t (transient-show-help prefix))))) - ((if-let* ((show-help (oref obj show-help))) - (funcall show-help obj) - (transient--describe-function this-command))))) + (cond* + ((eq this-command 'transient-help) + (transient-show-help transient--prefix)) + ((bind-and* (prefix (get (oref obj command) 'transient--prefix)) + (n/a (not (eq (oref transient--prefix command) this-command)))) + (transient-show-help prefix)) + ((bind-and* (show-help (oref obj show-help))) + (funcall show-help obj)) + ((transient--describe-function this-command)))) (cl-defmethod transient-show-help ((obj transient-infix)) "Call `show-help' if non-nil, else show the `man-page' if non-nil, else use `describe-function'. When showing the manpage, then try to jump to the correct location." - (if-let* ((show-help (oref obj show-help))) - (funcall show-help obj) - (if-let* ((man-page (oref transient--prefix man-page)) - (argument (and (slot-boundp obj 'argument) - (oref obj argument)))) - (transient--show-manpage man-page argument) - (transient--describe-function this-command)))) + (cond* + ((bind-and* (show-help (oref obj show-help))) + (funcall show-help obj)) + ((bind-and* (man-page (oref transient--prefix man-page)) + (argument (and (slot-boundp obj 'argument) + (oref obj argument)))) + (transient--show-manpage man-page argument)) + ((transient--describe-function this-command)))) ;; `cl-generic-generalizers' doesn't support `command' et al. (cl-defmethod transient-show-help (cmd) @@ -5159,6 +5143,7 @@ See `forward-button' for information about N." (defvar-keymap transient--isearch-mode-map :parent isearch-mode-map + "" #'transient-isearch-exit " " #'transient-isearch-exit " " #'transient-isearch-cancel " " #'transient-isearch-abort) commit ce5d8ddb325f67d452b33165bc0359697aa8b574 Author: Eshel Yaron Date: Tue Nov 18 16:08:05 2025 +0100 ; Mention LSP semantic highlighting in the Emacs manual * doc/emacs/display.texi (Semantic Font Lock): Mention LSP-based semantic highlighting, refer to the Eglot manual. diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 3f72a9416c1..dd898e0cf88 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -1234,18 +1234,23 @@ occur, such as Lisp and Prolog. In such languages, syntactic analysis alone misses a lot of important information that coders need to reason about their programs. +Some language servers provide semantic highlighting information, which +Emacs can leverage via its LSP client, Eglot. @xref{Eglot Features,,, +eglot, Eglot: The Emacs LSP Client}. + @vindex elisp-fontify-semantically -Emacs implements semantic highlighting for Emacs Lisp as an optional -feature of @code{emacs-lisp-mode} (@pxref{Executing Lisp}). To enable -it, customize the option @code{elisp-fontify-semantically} to a -non-@code{nil} value. - -When this option is enabled, @code{emacs-lisp-mode} analyzes your code -and highlights symbols according to their semantic roles, as part of the -mode's usual Font Lock highlighting (@pxref{Font Lock}). It doesn't -affect the highlighting of strings, comments and other syntactic -elements such as brackets; @code{elisp-fontify-semantically} only -affects highlighting of symbols. +Additionally, Emacs implements semantic highlighting for Emacs Lisp as +an optional feature of @code{emacs-lisp-mode} (@pxref{Executing Lisp}). +To enable it, customize the option @code{elisp-fontify-semantically} to +a non-@code{nil} value. The rest of this subsection describes the use +of this Emacs Lisp-specific semantic highlighting support. + +When @code{elisp-fontify-semantically} is enabled, +@code{emacs-lisp-mode} analyzes your code and highlights symbols +according to their semantic roles, as part of the mode's usual Font Lock +highlighting (@pxref{Font Lock}). It doesn't affect the highlighting of +strings, comments and other syntactic elements such as brackets; +@code{elisp-fontify-semantically} only affects highlighting of symbols. @cindex symbol role, in semantic analysis The semantic analysis assigns to each symbol a @dfn{symbol role}, such commit 0026445dd6f4fb0dad763a1bead0d23c8d27137e Author: Eli Zaretskii Date: Tue Nov 18 16:19:20 2025 +0200 Fix MinGW build broken by integration of 'stdio-consolesafe' * src/conf_post.h: Avoid redirecting '*printf' functions if 'OMIT_CONSOLESAFE' is defined to 1. * nt/cmdproxy.c: * nt/ddeclient.c: Define 'OMIT_CONSOLESAFE' to 1 to avoid redirecting '*printf functions' to stdio-consolesafe replacements. * nt/Makefile.in (LIBS_ADDPM): Add -lgnu to link 'addpm' against Gnulib. (Bug#79855) diff --git a/nt/Makefile.in b/nt/Makefile.in index f9662183065..71d590b2c15 100644 --- a/nt/Makefile.in +++ b/nt/Makefile.in @@ -139,7 +139,7 @@ EMACS_MANIFEST = @EMACS_MANIFEST@ WINDRES = @WINDRES@ ## Extra libraries to use when linking addpm. -LIBS_ADDPM = -lole32 -luuid +LIBS_ADDPM = -L../lib -lgnu -lole32 -luuid ## Compilation and linking flags BASE_CFLAGS = $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) \ diff --git a/nt/cmdproxy.c b/nt/cmdproxy.c index 8f4333e6139..8b2f18feade 100644 --- a/nt/cmdproxy.c +++ b/nt/cmdproxy.c @@ -28,6 +28,10 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ #define DEFER_MS_W32_H +/* We don't want to use the stdio-consolesafe redefinitions of *printf + functions, since (a) that pulls in stdio, which we don't want, see + below; and (b) we have our own implementations of *printf here. */ +#define OMIT_CONSOLESAFE 1 #include #include diff --git a/nt/ddeclient.c b/nt/ddeclient.c index 11dcfb5a3c5..52cfbde21eb 100644 --- a/nt/ddeclient.c +++ b/nt/ddeclient.c @@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License along with GNU Emacs. If not, see . */ #define DEFER_MS_W32_H +/* We only ever use fprintf for a fixed usage message below, so the + stdio-consolesafe module is overkill. */ +#define OMIT_CONSOLESAFE 1 #include #include diff --git a/src/conf_post.h b/src/conf_post.h index e946f6fc90b..99400d76210 100644 --- a/src/conf_post.h +++ b/src/conf_post.h @@ -397,7 +397,7 @@ extern int emacs_setenv_TZ (char const *); : S_ISSOCK (mode) ? DT_SOCK : DT_UNKNOWN) #endif /* MSDOS */ -#if defined WINDOWSNT +#if defined WINDOWSNT && !(defined OMIT_CONSOLESAFE && OMIT_CONSOLESAFE == 1) # if !defined _UCRT # include # include commit 3ae79b7c05b7360e7b7c319941ed3d25174eba01 Author: Sean Whitton Date: Tue Nov 18 12:56:25 2025 +0000 diff-apply-hunk: Avoid display-buffer-overriding-action * lisp/vc/diff-mode.el (diff-apply-hunk): Use ACTION argument to display-buffer instead of display-buffer-overriding-action. diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 07c2e013419..d58d221a658 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2187,7 +2187,8 @@ With a prefix argument, REVERSE the hunk." "Hunk has already been applied; undo it? "))))) (message "(Nothing done)")) ((and deletion (not switched)) - (when (y-or-n-p (format-message "Delete file `%s'?" (buffer-file-name buf))) + (when (y-or-n-p (format-message "Delete file `%s'?" + (buffer-file-name buf))) (delete-file (buffer-file-name buf) delete-by-moving-to-trash) (kill-buffer buf))) (t @@ -2197,9 +2198,8 @@ With a prefix argument, REVERSE the hunk." (delete-region (car pos) (cdr pos)) (insert (car new))) ;; Display BUF in a window - (let ((display-buffer-overriding-action - '(nil (inhibit-same-window . t)))) - (set-window-point (display-buffer buf) (+ (car pos) (cdr new)))) + (set-window-point (display-buffer buf '(nil (inhibit-same-window . t))) + (+ (car pos) (cdr new))) (diff-hunk-status-msg line-offset (xor switched reverse) nil) (when diff-advance-after-apply-hunk (diff-hunk-next))))))