From e866490a077c4c8a64550a8f85c8b9688112ed60 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 30 Jan 2023 15:42:06 +0200 Subject: [PATCH 1/4] Fix keymap inheritance in descendants of 'c-ts-base-mode' * lisp/progmodes/c-ts-mode.el (c-ts-base-mode-map): Rename from 'c-ts-mode-map'. (c-ts-base-mode): Adjust accordingly. (Bug#60983) --- lisp/progmodes/c-ts-mode.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 612c41bf073..195c23d28c9 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -697,8 +697,8 @@ the semicolon. This function skips the semicolon." ;;; Modes -(defvar-keymap c-ts-mode-map - :doc "Keymap for the C language with tree-sitter" +(defvar-keymap c-ts-base-mode-map + :doc "Keymap for C and C-like languages with tree-sitter" :parent prog-mode-map "C-c C-q" #'c-ts-mode-indent-defun "C-c ." #'c-ts-mode-set-style) @@ -707,7 +707,7 @@ the semicolon. This function skips the semicolon." (define-derived-mode c-ts-base-mode prog-mode "C" "Major mode for editing C, powered by tree-sitter. -\\{c-ts-mode-map}" +\\{c-ts-base-mode-map}" :syntax-table c-ts-mode--syntax-table ;; Navigation. From 2f3683cd4dc1e2358ae5f8c11f30a773f4540df7 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Mon, 30 Jan 2023 19:39:33 +0200 Subject: [PATCH 2/4] * lisp/isearch.el (isearch-emoji-by-name): Disable derived emoji (bug#60740). Let-bind emoji--derived to nil to avoid the subsequent selection of derived emoji that fails in transient.el. --- lisp/isearch.el | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lisp/isearch.el b/lisp/isearch.el index bb46c89ae20..22e27764127 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -2774,6 +2774,7 @@ With argument, add COUNT copies of the character." (mapconcat 'isearch-text-char-description string "")))))))) +(defvar emoji--derived) (defun isearch-emoji-by-name (&optional count) "Read an Emoji name and add it to the search string COUNT times. COUNT (interactively, the prefix argument) defaults to 1. @@ -2782,7 +2783,13 @@ The command accepts Unicode names like \"smiling face\" or (interactive "p") (with-isearch-suspended (let ((emoji (with-temp-buffer - (emoji-search) + ;; Derived emoji not supported yet (bug#60740). + ;; So first load `emoji--labels', then `emoji--init' + ;; will not fill `emoji--derived' that is set + ;; to an empty hash table below. + (ignore-errors (require 'emoji-labels)) + (let ((emoji--derived (make-hash-table :test #'equal))) + (emoji-search)) (if (and (integerp count) (> count 1)) (apply 'concat (make-list count (buffer-string))) (buffer-string))))) From 327941b211299013868469e65050d92ea513f067 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Mon, 30 Jan 2023 20:02:36 +0000 Subject: [PATCH 3/4] CC Mode: Fix a coding bug in c-make-keywords-re. This should fix bug #61135 * lisp/progmodes/cc-defs.el (c-make-keywords-re): Generate "\>" components in result regexp when argument ADORN is `appendable'. This fully fixes a bug which was half-fixed on 2019-01-22. --- lisp/progmodes/cc-defs.el | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index bdbc03e7c94..aa6f33e9cab 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el @@ -1994,7 +1994,7 @@ when it's needed. The default is the current language taken from ;; doesn't occur in any word in LIST. Append it to all ;; the alternatives where we want to add \>. Run through ;; `regexp-opt' and then replace it with \>. - (let ((unique "") pos) + (let ((unique "") (list1 (copy-tree list)) pos) (while (let (found) (setq unique (concat unique "@") pos list) @@ -2005,13 +2005,12 @@ when it's needed. The default is the current language taken from t)) (setq pos (cdr pos))) found)) - (setq pos (copy-tree list) - ) + (setq pos list1) (while pos (if (string-match "\\w\\'" (car pos)) (setcar pos (concat (car pos) unique))) (setq pos (cdr pos))) - (setq re (regexp-opt list)) + (setq re (regexp-opt list1)) (setq pos 0) (while (string-match unique re pos) (setq pos (+ (match-beginning 0) 2) From 1684e254a3b95b474753275fa9bfc2567a83b2fa Mon Sep 17 00:00:00 2001 From: Jonas Bernoulli Date: Mon, 30 Jan 2023 22:39:38 +0100 Subject: [PATCH 4/4] Update to Transient v0.3.7-196-gb91f509 --- doc/misc/transient.texi | 147 +++++++++++++++++++++++++++++----------- lisp/transient.el | 57 ++++++++++------ 2 files changed, 146 insertions(+), 58 deletions(-) diff --git a/doc/misc/transient.texi b/doc/misc/transient.texi index 2cd4e985dd2..8ac5df9904c 100644 --- a/doc/misc/transient.texi +++ b/doc/misc/transient.texi @@ -31,7 +31,7 @@ General Public License for more details. @finalout @titlepage @title Transient User and Developer Manual -@subtitle for version 0.3.7 +@subtitle for version 0.3.7.50 @author Jonas Bernoulli @page @vskip 0pt plus 1filll @@ -64,8 +64,17 @@ reading a new value in the minibuffer. Calling a suffix command usually causes the transient to be exited but suffix commands can also be configured to not exit the transient. +@quotation +The second part of this manual, which describes how to modify existing +transients and create new transients from scratch, can be hard to +digest if you are just getting started. A useful resource to get over +that hurdle is Psionic K's interactive tutorial, available at +@uref{https://github.com/positron-solutions/transient-showcase}. + +@end quotation + @noindent -This manual is for Transient version 0.3.7. +This manual is for Transient version 0.3.7.50. @insertcopying @end ifnottex @@ -447,10 +456,10 @@ session. Save the value of the active transient persistently across Emacs sessions. -@item @kbd{C-x C-k} (@code{transient-save}) +@item @kbd{C-x C-k} (@code{transient-reset}) @kindex C-x C-k -@findex transient-save -Clear the set and saved value of the active transient. +@findex transient-reset +Clear the set and saved values of the active transient. @end table @defopt transient-values-file @@ -893,7 +902,16 @@ same customization. To an extent, transients can be customized interactively, see @ref{Enabling and Disabling Suffixes}. This section explains how existing -transients can be further modified non-interactively. +transients can be further modified non-interactively. Let's begin +with an example: + +@lisp +(transient-append-suffix 'magit-patch-apply "-3" + '("-R" "Apply in reverse" "--reverse")) +@end lisp + +This inserts a new infix argument to toggle the @code{--reverse} argument +after the infix argument that toggles @code{-3} in @code{magit-patch-apply}. The following functions share a few arguments: @@ -911,7 +929,6 @@ means the former. @xref{Suffix Specifications}. @var{SUFFIX} may also be a group in the same form as expected by @code{transient-define-prefix}. @xref{Group Specifications}. - @item @var{LOC} is a command, a key vector, a key description (a string as returned by @code{key-description}), or a list specifying coordinates (the @@ -1044,6 +1061,18 @@ For example, the scope of the @code{magit-branch-configure} transient is the branch whose variables are being configured. @end defmac +It is possible to define one or more groups independently of a prefix +definition, which is useful when those groups are to be used by more +than just one prefix command. + +@defmac transient-define-groups name group... +This macro defines one or more groups of infix and suffix commands +and stores them in a property of the symbol @var{NAME}. @var{GROUP} has the +same form as for @code{transient-define-prefix}. Subsequently @var{NAME} can +be used in a @var{GROUP} of @code{transient-define-prefix}, as described in the +next section. +@end defmac + @node Binding Suffix and Infix Commands @section Binding Suffix and Infix Commands @@ -1139,11 +1168,17 @@ suffixes, which assumes that a predicate like this is used: @item The value of @code{:setup-children}, if non-@code{nil}, is a function that takes -two arguments the group object itself and a list of children. -The children are given as a (potentially empty) list consisting -of either group or suffix specifications. It can make arbitrary -changes to the children including constructing new children from -scratch. Also see @code{transient-setup-children}. +one argument, a potentially list of children, and must return a list +of children or an empty list. This can either be used to somehow +transform the group's children that were defined the normal way, or +to dynamically create the children from scratch. + +The returned children must have the same form as stored in the +prefix's @code{transient--layout} property, but it is often more convenient +to use the same form as understood by @code{transient-define-prefix}, +described below. If you use the latter approach, you can use the +@code{transient-parse-child} and @code{transient-parse-children} functions to +transform them from the convenient to the expected form. @item The boolean @code{:pad-keys} argument controls whether keys of all suffixes @@ -1151,23 +1186,35 @@ contained in a group are right padded, effectively aligning the descriptions. @end itemize -The @var{ELEMENT}s are either all subgroups (vectors), or all suffixes -(lists) and strings. (At least currently no group type exists that -would allow mixing subgroups with commands at the same level, though -in principle there is nothing that prevents that.) +The @var{ELEMENT}s are either all subgroups, or all suffixes and strings. +(At least currently no group type exists that would allow mixing +subgroups with commands at the same level, though in principle there +is nothing that prevents that.) If the @var{ELEMENT}s are not subgroups, then they can be a mixture of lists -that specify commands and strings. Strings are inserted verbatim. -The empty string can be used to insert gaps between suffixes, which is -particularly useful if the suffixes are outlined as a table. +that specify commands and strings. Strings are inserted verbatim into +the buffer. The empty string can be used to insert gaps between +suffixes, which is particularly useful if the suffixes are outlined as +a table. -Variables are supported inside group specifications. For example in -place of a direct subgroup specification, a variable can be used whose -value is a vector that qualifies as a group specification. Likewise, -a variable can be used where a suffix specification is expected. -Lists of group or suffix specifications are also supported. Indirect -specifications are resolved when the transient prefix is being -defined. +Inside group specifications, including inside contained suffix +specifications, nothing has to be quoted and quoting anyway is +invalid. + +How symbols are treated, depends on context. Inside suffix +specifications they often name functions. However if they appear in +a place where a group is expected, then they are treated as indirect +group specifications. Such a symbol must have an associated group +specification, created using @code{transient-define-groups}. + +Likewise a symbol can appear in a place where a suffix specification +is expected. The value of the @code{transient--layout} property of that +symbol must be a single suffix specification or a list of such +specifications. Currently no macro exist that would create such a +symbol, and this feature should usually not be used. + +The value following a keyword, can be explicitly unquoted using @code{,}. +This feature is experimental and should be avoided as well. The form of suffix specifications is documented in the next node. @@ -1232,7 +1279,7 @@ Any command will do; it does not need to have an object associated with it (as would be the case if @code{transient-define-suffix} or @code{transient-define-infix} were used to define it). -Anonymous, dynamically defined suffix commands are also support. +Anonymous, dynamically defined suffix commands are also supported. See information about the @code{:setup-children} function in @ref{Group Specifications}. As mentioned above, the object that is associated with a command can @@ -1515,7 +1562,18 @@ Call the command without exporting variables and stay transient. @anchor{Pre-commands for Suffixes} @subheading Pre-commands for Suffixes -The default for suffixes is @code{transient--do-exit}. +By default, invoking a suffix causes the transient to be exited. + +If you want a different default behavior for a certain transient +prefix command, then set its @code{:transient-suffix} slot. The value can be +a boolean, answering the question "does the transient stay active, +when a suffix command is invoked?" @code{t} means that the transient stays +active, while @code{nil} means that invoking a suffix exits the transient. +In either case, the exact behavior depends on whether the suffix is +itself a prefix (i.e., a sub-prefix), an infix or a regular suffix. + +The behavior for an individual suffix command can be changed by +setting its @code{transient} slot to one of the following pre-commands. @defun transient--do-exit Call the command after exporting variables and exit the transient. @@ -1566,21 +1624,32 @@ be added to @code{transient-predicate-map}. @anchor{Pre-commands for Non-Suffixes} @subheading Pre-commands for Non-Suffixes -The default for non-suffixes, i.e., commands that are bound in other -keymaps beside the transient keymap, is @code{transient--do-warn}. Silently -ignoring the user-error is also an option, though probably not a good -one. +By default, non-suffixes (commands that are bound in other keymaps +beside the transient keymap) cannot be invoked. Trying to invoke +such a command results in a warning and the transient stays active. -If you want to let the user invoke non-suffix commands, then use -@code{transient--do-stay} as the value of the prefix's @code{transient-non-suffix} -slot. +If you want a different behavior, then set the @code{:transient-non-suffix} +slot of the transient prefix command. The value can be a boolean, +answering the question, "is it allowed to invoke non-suffix commands?" + +If the value is @code{t} or @code{transient--do-stay}, then non-suffixes can be +invoked, when it is @code{nil} or @code{transient--do-warn} (the default) then they +cannot be invoked. + +The only other recommended value is @code{transient--do-leave}. If that is +used, then non-suffixes can be invoked, but if one is invoked, then +that exits the transient. @defun transient--do-warn Call @code{transient-undefined} and stay transient. @end defun -@defun transient--do-noop -Call @code{transient-noop} and stay transient. +@defun transient--do-stay +Call the command without exporting variables and stay transient. +@end defun + +@defun transient--do-leave +Call the command without exporting variables and exit the transient. @end defun @anchor{Special Pre-Commands} @@ -1810,7 +1879,7 @@ indicates that all remaining arguments are files. @item Classes used for infix commands that represent variables should -derived from the abstract @code{transient-variables} class. +derived from the abstract @code{transient-variable} class. @end itemize Magit defines additional classes, which can serve as examples for the @@ -2045,7 +2114,7 @@ called with no argument and returns a string. @item @code{show-help} A function used to display help for the suffix. If -unspecified, the prefix controls how hlep is displayed for its +unspecified, the prefix controls how help is displayed for its suffixes. @end itemize diff --git a/lisp/transient.el b/lisp/transient.el index eb3c4ab6bca..cd8640a7d74 100644 --- a/lisp/transient.el +++ b/lisp/transient.el @@ -6,7 +6,7 @@ ;; URL: https://github.com/magit/transient ;; Keywords: extensions -;; Package-Version: 0.3.7 +;; Package-Version: 0.3.7.50 ;; Package-Requires: ((emacs "26.1")) ;; SPDX-License-Identifier: GPL-3.0-or-later @@ -798,8 +798,8 @@ They become the value of this argument.") (defclass transient-columns (transient-group) () "Group class that displays elements organized in columns. Direct elements have to be groups whose elements have to be -commands or string. Each subgroup represents a column. This -class takes care of inserting the subgroups' elements.") +commands or strings. Each subgroup represents a column. +This class takes care of inserting the subgroups' elements.") (defclass transient-subgroups (transient-group) () "Group class that wraps other groups. @@ -860,7 +860,7 @@ to the setup function: (indent defun) (doc-string 3)) (pcase-let ((`(,class ,slots ,suffixes ,docstr ,body) - (transient--expand-define-args args))) + (transient--expand-define-args args arglist))) `(progn (defalias ',name ,(if body @@ -913,7 +913,7 @@ ARGLIST. The infix arguments are usually accessed by using (indent defun) (doc-string 3)) (pcase-let ((`(,class ,slots ,_ ,docstr ,body) - (transient--expand-define-args args))) + (transient--expand-define-args args arglist))) `(progn (defalias ',name (lambda ,arglist ,@body)) (put ',name 'interactive-only t) @@ -921,7 +921,7 @@ ARGLIST. The infix arguments are usually accessed by using (put ',name 'transient--suffix (,(or class 'transient-suffix) :command ',name ,@slots))))) -(defmacro transient-define-infix (name _arglist &rest args) +(defmacro transient-define-infix (name arglist &rest args) "Define NAME as a transient infix command. ARGLIST is always ignored and reserved for future use. @@ -962,7 +962,7 @@ keyword. (indent defun) (doc-string 3)) (pcase-let ((`(,class ,slots ,_ ,docstr ,_) - (transient--expand-define-args args))) + (transient--expand-define-args args arglist))) `(progn (defalias ',name ,(transient--default-infix-command)) (put ',name 'interactive-only t) @@ -980,7 +980,9 @@ example, sets a variable use `transient-define-infix' instead. \(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)") -(defun transient--expand-define-args (args) +(defun transient--expand-define-args (args &optional arglist) + (unless (listp arglist) + (error "Mandatory ARGLIST is missing")) (let (class keys suffixes docstr) (when (stringp (car args)) (setq docstr (pop args))) @@ -1150,7 +1152,7 @@ example, sets a variable use `transient-define-infix' instead. PREFIX is a prefix command, a symbol. SUFFIX is a suffix command or a group specification (of the same forms as expected by `transient-define-prefix'). -Intended for use in PREFIX's `:setup-children' function." +Intended for use in a group's `:setup-children' function." (eval (car (transient--parse-child prefix suffix)))) (defun transient-parse-suffixes (prefix suffixes) @@ -1158,7 +1160,7 @@ Intended for use in PREFIX's `:setup-children' function." PREFIX is a prefix command, a symbol. SUFFIXES is a list of suffix command or a group specification (of the same forms as expected by `transient-define-prefix'). -Intended for use in PREFIX's `:setup-children' function." +Intended for use in a group's `:setup-children' function." (mapcar (apply-partially #'transient-parse-suffix prefix) suffixes)) ;;; Edit @@ -1469,14 +1471,24 @@ probably use this instead: (cl-check-type command command)) (if (or transient--prefix transient-current-prefix) - (cl-find-if (lambda (obj) - (eq (transient--suffix-command obj) + (let ((suffixes + (cl-remove-if-not + (lambda (obj) + (eq (transient--suffix-command obj) + (or command ;; When `this-command' is `transient-set-level', ;; its reader needs to know what command is being ;; configured. - (or command this-original-command))) - (or transient--suffixes - transient-current-suffixes)) + this-original-command))) + (or transient--suffixes + transient-current-suffixes)))) + (or (and (cdr suffixes) + (cl-find-if + (lambda (obj) + (equal (listify-key-sequence (transient--kbd (oref obj key))) + (listify-key-sequence (this-command-keys)))) + suffixes)) + (car suffixes))) (when-let* ((obj (get (or command this-command) 'transient--suffix)) (obj (clone obj))) ;; Cannot use and-let* because of debbugs#31840. @@ -2203,7 +2215,7 @@ value. Otherwise return CHILDREN as is." (unless abort-only (setq post-command (lambda () "@transient--delay-post-command" - (let ((act (and (not (eq (this-command-keys-vector) [])) + (let ((act (and (not (equal (this-command-keys-vector) [])) (or (eq this-command command) ;; `execute-extended-command' was ;; used to call another command @@ -2236,7 +2248,7 @@ value. Otherwise return CHILDREN as is." (transient--debug 'post-command) (transient--with-emergency-exit (cond - ((and (eq (this-command-keys-vector) []) + ((and (equal (this-command-keys-vector) []) (= (minibuffer-depth) (1+ transient--minibuffer-depth))) (transient--suspend-override) @@ -2407,6 +2419,10 @@ If there is no parent prefix, then behave like `transient--do-exit'." (transient--stack-zap) transient--exit) +(defun transient--do-leave () + "Call the command without exporting variables and exit the transient." + transient--stay) + (defun transient--do-push-button () "Call the command represented by the activated button. Use that command's pre-command to determine transient behavior." @@ -3376,7 +3392,7 @@ have a history of their own.") (insert ?\n) (insert (propertize " " 'display `(space :align-to (,(nth (1+ c) cc))))))) - (insert (make-string (- (nth c cc) (current-column)) ?\s)) + (insert (make-string (max 1 (- (nth c cc) (current-column))) ?\s)) (when-let ((cell (nth r (nth c columns)))) (insert cell)) (when (= c (1- cs)) @@ -4119,7 +4135,10 @@ we stop there." 'face 'transient-value)) (cl-defmethod transient-prompt ((obj transient-lisp-variable)) - (format "Set %s: " (oref obj variable))) + (if (and (slot-boundp obj 'prompt) + (oref obj prompt)) + (cl-call-next-method obj) + (format "Set %s: " (oref obj variable)))) (defun transient-lisp-variable--reader (prompt initial-input _history) (read--expression prompt initial-input))