Function: transient--parse-suffix

transient--parse-suffix is a byte-compiled function defined in transient.el.

Signature

(transient--parse-suffix PREFIX SPEC)

Source Code

;; Defined in ~/.emacs.d/elpa/transient-20260414.1009/transient.el
(defun transient--parse-suffix (prefix spec)
  (let (class args)
    (cl-flet ((use (prop value)
                (setq args (plist-put args prop value))))
      (pcase (car spec)
        ((cl-type integer)
         (use :level (pop spec))))
      (pcase (car spec)
        ((cl-type (or string vector))
         (use :key (pop spec))))
      (pcase (car spec)
        ((guard (or (stringp (car spec))
                    (and (eq (car-safe (car spec)) 'lambda)
                         (not (commandp (car spec))))))
         (use :description (pop spec)))
        ((and (cl-type (and symbol (not keyword) (not command)))
              (guard (commandp (cadr spec))))
         (use :description (macroexp-quote (pop spec)))))
      (pcase (car spec)
        ((or :info :info* :cons))
        ((and (cl-type keyword) invalid)
         (error "Need command, argument, `:info', `:info*' or `:cons'; got `%s'"
                invalid))
        ((cl-type symbol)
         (use :command (macroexp-quote (pop spec))))
        ;; During macro-expansion this is expected to be a `lambda'
        ;; expression (i.e., source code).  When this is called from a
        ;; `:setup-children' function, it may also be a function object
        ;; (a.k.a a function value).  However, we never treat a string
        ;; as a command, so we have to check for that explicitly.
        ((cl-type (and command (not string)))
         (let ((cmd (pop spec))
               (sym (intern
                     (format
                      "transient:%s:%s:%d" prefix
                      (replace-regexp-in-string (plist-get args :key) " " "")
                      (prog1 gensym-counter (cl-incf gensym-counter))))))
           (use :command
                `(prog1 ',sym
                   (put ',sym 'interactive-only t)
                   (put ',sym 'completion-predicate #'transient--suffix-only)
                   (defalias ',sym ,cmd)))))
        ((cl-type (or string (and list (not null))))
         (let ((arg (pop spec)))
           (cl-typecase arg
             (list
              (use :shortarg (car arg))
              (use :argument (cadr arg))
              (setq arg (cadr arg)))
             (string
              (when-let ((shortarg (transient--derive-shortarg arg)))
                (use :shortarg shortarg))
              (use :argument arg)))
           (use :command
                (let ((sym (intern (format "transient:%s:%s" prefix arg))))
                  `(prog1 ',sym
                     (put ',sym 'interactive-only t)
                     (put ',sym 'completion-predicate #'transient--suffix-only)
                     (defalias ',sym #'transient--default-infix-command))))
           (pcase (car spec)
             ((cl-type (and (not null) (not keyword)))
              (setq class 'transient-option)
              (use :reader (macroexp-quote (pop spec))))
             ((guard (string-suffix-p "=" arg))
              (setq class 'transient-option))
             (_ (setq class 'transient-switch)))))
        (invalid
         (error "Need command, argument, `:info' or `:info*'; got %s" invalid)))
      (while (keywordp (car spec))
        (let* ((key (pop spec))
               (val (if spec (pop spec) (error "No value for `%s'" key))))
          (pcase key
            (:class (setq class val))
            (:info  (setq class 'transient-information)
                    (use :description val))
            (:info* (setq class 'transient-information*)
                    (use :description val))
            (:cons
             (setq class 'transient-cons-option)
             (use :command
                  (let ((sym (intern (format "transient:%s:%s" prefix val))))
                    `(prog1 ',sym
                       (put ',sym 'interactive-only t)
                       (put ',sym 'completion-predicate #'transient--suffix-only)
                       (defalias ',sym #'transient--default-infix-command))))
             (use :argument val))
            ((guard (eq (car-safe val) '\,))
             (use key (cadr val)))
            ((guard (or (symbolp val)
                        (and (listp val)
                             (not (memq (car val) (list 'lambda (intern "")))))))
             (use key (macroexp-quote val)))
            (_ (use key val)))))
      (when spec
        (error "Need keyword, got %S" (car spec)))
      (cond-let
        ([key (plist-get args :key)]
         (when (string-match "\\`\\({p}\\)" key)
           (use :key
                (replace-match transient-common-command-prefix t t key 1))))
        ([shortarg (plist-get args :shortarg)]
         (use :key shortarg))))
    (list 'cons
          (macroexp-quote (or class 'transient-suffix))
          (cons 'list args))))