]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update transient
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Fri, 31 Jan 2020 16:35:38 +0000 (17:35 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Fri, 31 Jan 2020 17:13:05 +0000 (18:13 +0100)
elpa/transient-20191017.1115/dir [deleted file]
elpa/transient-20191017.1115/transient-autoloads.el [deleted file]
elpa/transient-20191017.1115/transient-pkg.el [deleted file]
elpa/transient-20191017.1115/transient.el [deleted file]
elpa/transient-20191017.1115/transient.info [deleted file]
elpa/transient-20200125.1308/dir [new file with mode: 0644]
elpa/transient-20200125.1308/transient-autoloads.el [new file with mode: 0644]
elpa/transient-20200125.1308/transient-pkg.el [new file with mode: 0644]
elpa/transient-20200125.1308/transient.el [new file with mode: 0644]
elpa/transient-20200125.1308/transient.info [new file with mode: 0644]

diff --git a/elpa/transient-20191017.1115/dir b/elpa/transient-20191017.1115/dir
deleted file mode 100644 (file)
index 4d6ad7f..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-\1f
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "H" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Emacs
-* Transient: (transient).       Transient Commands.
diff --git a/elpa/transient-20191017.1115/transient-autoloads.el b/elpa/transient-20191017.1115/transient-autoloads.el
deleted file mode 100644 (file)
index c49f3fe..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-;;; transient-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
-\f
-;;;### (autoloads nil nil ("transient-pkg.el" "transient.el") (23993
-;;;;;;  53925 817643 925000))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; End:
-;;; transient-autoloads.el ends here
diff --git a/elpa/transient-20191017.1115/transient-pkg.el b/elpa/transient-20191017.1115/transient-pkg.el
deleted file mode 100644 (file)
index c0ca5d3..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-(define-package "transient" "20191017.1115" "Transient commands"
-  '((emacs "25.1")
-    (dash "2.15.0"))
-  :keywords
-  '("bindings")
-  :authors
-  '(("Jonas Bernoulli" . "jonasNOSPAMbernoul.li"))
-  :maintainer
-  '("Jonas Bernoulli" . "jonasNOSPAMbernoul.li")
-  :url "https://github.com/magit/transient")
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/transient-20191017.1115/transient.el b/elpa/transient-20191017.1115/transient.el
deleted file mode 100644 (file)
index 731fe6a..0000000
+++ /dev/null
@@ -1,3092 +0,0 @@
-;;; transient.el --- Transient commands          -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2019  Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
-;; Homepage: https://github.com/magit/transient
-;; Package-Requires: ((emacs "25.1") (dash "2.15.0"))
-;; Keywords: bindings
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published
-;; by the Free Software Foundation; either version 3 of the License,
-;; or (at your option) any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; For a full copy of the GNU GPL see http://www.gnu.org/licenses.
-
-;;; Commentary:
-
-;; Taking inspiration from prefix keys and prefix arguments, Transient
-;; implements a similar abstraction involving a prefix command, infix
-;; arguments and suffix commands.  We could call this abstraction a
-;; "transient command", but because it always involves at least two
-;; commands (a prefix and a suffix) we prefer to call it just a
-;; "transient".
-
-;; When the user calls a transient prefix command, then a transient
-;; (temporary) keymap is activated, which binds the transient's infix
-;; and suffix commands, and functions that control the transient state
-;; are added to `pre-command-hook' and `post-command-hook'.  The
-;; available suffix and infix commands and their state are shown in
-;; the echo area until the transient is exited by invoking a suffix
-;; command.
-
-;; Calling an infix command causes its value to be changed, possibly
-;; by 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 state.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'dash)
-(require 'eieio)
-(require 'format-spec)
-
-(eval-when-compile
-  (require 'subr-x))
-
-(declare-function info 'info)
-(declare-function Man-find-section 'man)
-(declare-function Man-next-section 'man)
-(declare-function Man-getpage-in-background 'man)
-
-(defvar Man-notify-method)
-
-;;; Options
-
-(defgroup transient nil
-  "Transient commands."
-  :group 'bindings)
-
-(defcustom transient-show-popup t
-  "Whether to show the current transient in a popup buffer.
-
-- If t, then show the popup as soon as a transient prefix command
-  is invoked.
-
-- If nil, then do not show the popup unless the user explicitly
-  requests it, by pressing an incomplete prefix key sequence.
-
-- If a number, then delay displaying the popup and instead show
-  a brief one-line summary.  If zero or negative, then suppress
-  even showing that summary and display the pressed key only.
-
-  Show the popup when the user explicitly requests it by pressing
-  an incomplete prefix key sequence.  Unless zero, then also show
-  the popup after that many seconds of inactivity (using the
-  absolute value)."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type '(choice (const  :tag "instantly" t)
-                 (const  :tag "on demand" nil)
-                 (const  :tag "on demand (no summary)" 0)
-                 (number :tag "after delay" 1)))
-
-(defcustom transient-enable-popup-navigation nil
-  "Whether navigation commands are enabled in the transient popup.
-
-While a transient is active the transient popup buffer is not the
-current buffer, making it necesary to use dedicated commands to
-act on that buffer itself.  If this non-nil, then the following
-features are available:
-
-- \"<up>\" moves the cursor to the previous suffix.
-  \"<down>\" moves the cursor to the next suffix.
-  \"RET\" invokes the suffix the cursor is on.
-- \"<mouse-1>\" invokes the clicked on suffix.
-- \"C-s\" and \"C-r\" start isearch in the popup buffer."
-  :package-version '(transient . "0.2.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-display-buffer-action
-  '(display-buffer-in-side-window (side . bottom))
-  "The action used to display the transient popup buffer.
-
-The transient popup buffer is displayed in a window using
-
-  \(display-buffer buf transient-display-buffer-action)
-
-The value of this option has the form (FUNCTION . ALIST),
-where 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 ALIST.  See `display-buffer' for
-details.
-
-The default is (display-buffer-in-side-window (side . bottom)).
-This displays the window at the bottom of the selected frame.
-Another useful value is (display-buffer-below-selected).  This
-is what `magit-popup' used by default.  For more alternatives
-see info node `(elisp)Display Action Functions'.
-
-It may be possible to display the window in another frame, but
-whether that works in practice depends on the window-manager.
-If the window manager selects the new window (Emacs frame),
-then it doesn't work.
-
-If you change the value of this option, then you might also
-want to change the value of `transient-mode-line-format'."
-  :package-version '(transient . "0.2.0")
-  :group 'transient
-  :type '(cons (choice function (repeat :tag "Functions" function))
-               alist))
-
-(defcustom transient-mode-line-format (and window-system 'line)
-  "The mode-line format for the transient popup buffer.
-
-If nil, then the buffer has no mode-line.  If the buffer is not
-displayed right above the echo area, then this probably is not
-a good value.
-
-If `line' (the default), then the buffer also has no mode-line,
-but a thin line is drawn instead, using the background color of
-the face `transient-separator'.
-
-Otherwise this can be any mode-line format.
-See `mode-line-format' for details."
-  :package-version '(transient . "0.2.0")
-  :group 'transient
-  :type '(choice (const :tag "hide mode-line" nil)
-                 (const :tag "substitute thin line" line)
-                 (const :tag "name of prefix command"
-                        ("%e" mode-line-front-space
-                         mode-line-buffer-identification))
-                 (sexp  :tag "custom mode-line format")))
-
-(defcustom transient-show-common-commands nil
-  "Whether to show common transient suffixes in the popup buffer.
-
-These commands are always shown after typing the prefix key
-\"C-x\" when a transient command is active.  To toggle the value
-of this variable use \"C-x t\" when a transient is active."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-read-with-initial-input t
-  "Whether to use the last history element as initial minibuffer input."
-  :package-version '(transient . "0.2.0")
-  :group 'transient
-  :type 'boolean)
-
-(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 shor-thand (e.g \"-v\").
-In the rare case that a short-hand is specified but does not
-match the key binding, then it is highlighed differently.
-
-The highlighting is done using using `transient-mismatched-key'
-and `transient-nonstandard-key'."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-substitute-key-function nil
-  "Function used to modify key bindings.
-
-This function is called with one argument, the prefix object,
-and must return a key binding description, either the existing
-key description it finds in the `key' slot, or a substitution.
-
-This is intended to let users replace certain prefix keys.  It
-could also be used to make other substitutions, but that is
-discouraged.
-
-For example, \"=\" is hard to reach using my custom keyboard
-layout, so I substitute \"(\" for that, which is easy to reach
-using a layout optimized for lisp.
-
-  (setq transient-substitute-key-function
-        (lambda (obj)
-          (let ((key (oref obj key)))
-            (if (string-match \"\\\\`\\\\(=\\\\)[a-zA-Z]\" key)
-                (replace-match \"(\" t t key 1)
-              key)))))"
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type '(choice (const :tag "Transform no keys (nil)" nil) function))
-
-(defcustom transient-detect-key-conflicts nil
-  "Whether to detect key binding conflicts.
-
-Conflicts are detected when a transient prefix command is invoked
-and results in an error, which prevents the transient from being
-used."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-default-level 4
-  "Control what suffix levels are made available by default.
-
-Each suffix command is placed on a level and each prefix command
-has a level, which controls which suffix commands are available.
-Integers between 1 and 7 (inclusive) are valid levels.
-
-The levels of individual transients and/or their individual
-suffixes can be changed individually, by invoking the prefix and
-then pressing \"C-x l\".
-
-The default level for both transients and their suffixes is 4.
-This option only controls the default for transients.  The default
-suffix level is always 4.  The author of a transient should place
-certain suffixes on a higher level if they expect that it won't be
-of use to most users, and they should place very important suffixes
-on a lower level so that the remain available even if the user
-lowers the transient level.
-
-\(Magit currently places nearly all suffixes on level 4 and lower
-levels are not used at all yet.  So for the time being you should
-not set a lower level here and using a higher level might not
-give you as many additional suffixes as you hoped.)"
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type '(choice (const :tag "1 - fewest suffixes" 1)
-                 (const 2)
-                 (const 3)
-                 (const :tag "4 - default" 4)
-                 (const 5)
-                 (const 6)
-                 (const :tag "7 - most suffixes" 7)))
-
-(defcustom transient-levels-file
-  (locate-user-emacs-file (convert-standard-filename "transient/levels.el"))
-  "File used to save levels of transients and their suffixes."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'file)
-
-(defcustom transient-values-file
-  (locate-user-emacs-file (convert-standard-filename "transient/values.el"))
-  "File used to save values of transients."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'file)
-
-(defcustom transient-history-file
-  (locate-user-emacs-file (convert-standard-filename "transient/history.el"))
-  "File used to save history of transients and their infixes."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'file)
-
-(defcustom transient-history-limit 10
-  "Number of history elements to keep when saving to file."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'integer)
-
-(defcustom transient-save-history t
-  "Whether to save history of transient commands when exiting Emacs."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'boolean)
-
-;;; Faces
-
-(defgroup transient-faces nil
-  "Faces used by Transient."
-  :group 'transient)
-
-(defface transient-heading '((t :inherit font-lock-keyword-face))
-  "Face used for headings."
-  :group 'transient-faces)
-
-(defface transient-key '((t :inherit font-lock-builtin-face))
-  "Face used for keys."
-  :group 'transient-faces)
-
-(defface transient-argument '((t :inherit font-lock-warning-face))
-  "Face used for enabled arguments."
-  :group 'transient-faces)
-
-(defface transient-value '((t :inherit font-lock-string-face))
-  "Face used for values."
-  :group 'transient-faces)
-
-(defface transient-inactive-argument '((t :inherit shadow))
-  "Face used for inactive arguments."
-  :group 'transient-faces)
-
-(defface transient-inactive-value '((t :inherit shadow))
-  "Face used for inactive values."
-  :group 'transient-faces)
-
-(defface transient-unreachable '((t :inherit shadow))
-  "Face used for suffixes unreachable from the current prefix sequence."
-  :group 'transient-faces)
-
-(defface transient-active-infix '((t :inherit secondary-selection))
-  "Face used for the infix for which the value is being read."
-  :group 'transient-faces)
-
-(defface transient-unreachable-key '((t :inherit shadow))
-  "Face used for keys unreachable from the current prefix sequence."
-  :group 'transient-faces)
-
-(defface transient-nonstandard-key '((t :underline t))
-  "Face optionally used to highlight keys conflicting with short-argument.
-Also see option `transient-highlight-mismatched-keys'."
-  :group 'transient-faces)
-
-(defface transient-mismatched-key '((t :underline t))
-  "Face optionally used to highlight keys without a short-argument.
-Also see option `transient-highlight-mismatched-keys'."
-  :group 'transient-faces)
-
-(defface transient-enabled-suffix
-  '((t :background "green" :foreground "black" :weight bold))
-  "Face used for enabled levels while editing suffix levels.
-See info node `(transient)Enabling and Disabling Suffixes'."
-  :group 'transient-faces)
-
-(defface transient-disabled-suffix
-  '((t :background "red" :foreground "black" :weight bold))
-  "Face used for disabled levels while editing suffix levels.
-See info node `(transient)Enabling and Disabling Suffixes'."
-  :group 'transient-faces)
-
-(defface transient-separator
-  '((((class color) (background light)) :background "grey80")
-    (((class color) (background  dark)) :background "grey30"))
-  "Face used to draw line below transient popup window.
-This is only used if `transient-mode-line-format' is `line'.
-Only the background color is significant."
-  :group 'transient-faces)
-
-;;; Persistence
-
-(defun transient--read-file-contents (file)
-  (with-demoted-errors "Transient error: %S"
-    (and (file-exists-p file)
-         (with-temp-buffer file
-           (insert-file-contents file)
-           (read (current-buffer))))))
-
-(defun transient--pp-to-file (object file)
-  (make-directory (file-name-directory file) t)
-  (setq object (cl-sort object #'string< :key #'car))
-  (with-temp-file file
-    (let ((print-level nil)
-          (print-length nil))
-      (pp object (current-buffer)))))
-
-(defvar transient-values
-  (transient--read-file-contents transient-values-file)
-  "Values of transient commands.
-The value of this variable persists between Emacs sessions
-and you usually should not change it manually.")
-
-(defun transient-save-values ()
-  (transient--pp-to-file transient-values transient-values-file))
-
-(defvar transient-levels
-  (transient--read-file-contents transient-levels-file)
-  "Levels of transient commands.
-The value of this variable persists between Emacs sessions
-and you usually should not change it manually.")
-
-(defun transient-save-levels ()
-  (transient--pp-to-file transient-levels transient-levels-file))
-
-(defvar transient-history
-  (transient--read-file-contents transient-history-file)
-  "History of transient commands and infix arguments.
-The value of this variable persists between Emacs sessions
-\(unless `transient-save-history' is nil) and you usually
-should not change it manually.")
-
-(defun transient-save-history ()
-  (setq transient-history
-        (cl-sort (mapcar (pcase-lambda (`(,key . ,val))
-                           (cons key (-take transient-history-limit
-                                            (delete-dups val))))
-                         transient-history)
-                 #'string< :key #'car))
-  (transient--pp-to-file transient-history transient-history-file))
-
-(defun transient-maybe-save-history ()
-  "Save the value of `transient-history'.
-If `transient-save-history' is nil, then do nothing."
-  (when transient-save-history
-    (transient-save-history)))
-
-(unless noninteractive
-  (add-hook 'kill-emacs-hook 'transient-maybe-save-history))
-
-;;; Classes
-;;;; Prefix
-
-(defclass transient-prefix ()
-  ((prototype   :initarg :prototype)
-   (command     :initarg :command)
-   (level       :initarg :level)
-   (variable    :initarg :variable    :initform nil)
-   (value       :initarg :value)
-   (scope       :initarg :scope       :initform nil)
-   (history     :initarg :history     :initform nil)
-   (history-pos :initarg :history-pos :initform 0)
-   (history-key :initarg :history-key :initform nil)
-   (man-page    :initarg :man-page    :initform nil)
-   (info-manual :initarg :info-manual :initform nil)
-   (transient-suffix     :initarg :transient-suffix     :initform nil)
-   (transient-non-suffix :initarg :transient-non-suffix :initform nil)
-   (incompatible         :initarg :incompatible         :initform nil))
-  "Transient prefix command.
-
-Each transient prefix command consists of a command, which is
-stored in a symbol's function slot and an object, which is
-stored in the `transient--prefix' property of the same symbol.
-
-When a transient prefix command is invoked, then a clone of that
-object is stored in the global variable `transient--prefix' and
-the prototype is stored in the clone's `prototype' slot.")
-
-;;;; Suffix
-
-(defclass transient-child ()
-  ((level
-    :initarg :level
-    :initform 1
-    :documentation "Enable if level of prefix is equal or greater.")
-   (if
-    :initarg :if
-    :initform nil
-    :documentation "Enable if predicate returns non-nil.")
-   (if-not
-    :initarg :if-not
-    :initform nil
-    :documentation "Enable if predicate returns nil.")
-   (if-non-nil
-    :initarg :if-non-nil
-    :initform nil
-    :documentation "Enable if variable's value is non-nil.")
-   (if-nil
-    :initarg :if-nil
-    :initform nil
-    :documentation "Enable if variable's value is nil.")
-   (if-mode
-    :initarg :if-mode
-    :initform nil
-    :documentation "Enable if major-mode matches value.")
-   (if-not-mode
-    :initarg :if-not-mode
-    :initform nil
-    :documentation "Enable if major-mode does not match value.")
-   (if-derived
-    :initarg :if-derived
-    :initform nil
-    :documentation "Enable if major-mode derives from value.")
-   (if-not-derived
-    :initarg :if-not-derived
-    :initform nil
-    :documentation "Enable if major-mode does not derive from value."))
-  "Abstract superclass for group and and suffix classes.
-
-It is undefined what happens if more than one `if*' predicate
-slot is non-nil."
-  :abstract t)
-
-(defclass transient-suffix (transient-child)
-  ((key         :initarg :key)
-   (command     :initarg :command)
-   (transient   :initarg :transient)
-   (format      :initarg :format      :initform " %k %d")
-   (description :initarg :description :initform nil))
-  "Superclass for suffix command.")
-
-(defclass transient-infix (transient-suffix)
-  ((transient                         :initform t)
-   (argument    :initarg :argument)
-   (shortarg    :initarg :shortarg)
-   (value                             :initform nil)
-   (multi-value :initarg :multi-value :initform nil)
-   (allow-empty :initarg :allow-empty :initform nil)
-   (history-key :initarg :history-key :initform nil)
-   (reader      :initarg :reader      :initform nil)
-   (prompt      :initarg :prompt      :initform nil)
-   (choices     :initarg :choices     :initform nil)
-   (format                            :initform " %k %d (%v)"))
-  "Transient infix command."
-  :abstract t)
-
-(defclass transient-argument (transient-infix) ()
-  "Abstract superclass for infix arguments."
-  :abstract t)
-
-(defclass transient-switch (transient-argument) ()
-  "Class used for command-line argument that can be turned on and off.")
-
-(defclass transient-option (transient-argument) ()
-  "Class used for command-line argument that can take a value.")
-
-(defclass transient-variable (transient-infix)
-  ((variable    :initarg :variable)
-   (format                            :initform " %k %d %v"))
-  "Abstract superclass for infix commands that set a variable."
-  :abstract t)
-
-(defclass transient-switches (transient-argument)
-  ((argument-format  :initarg :argument-format)
-   (argument-regexp  :initarg :argument-regexp))
-  "Class used for sets of mutually exclusive command-line switches.")
-
-(defclass transient-files (transient-infix) ()
-  "Class used for the \"--\" argument.
-All remaining arguments are treated as files.
-They become the value of this this argument.")
-
-;;;; Group
-
-(defclass transient-group (transient-child)
-  ((suffixes    :initarg :suffixes    :initform nil)
-   (hide        :initarg :hide        :initform nil)
-   (description :initarg :description :initform nil))
-  "Abstract superclass of all group classes."
-  :abstract t)
-
-(defclass transient-column (transient-group) ()
-  "Group class that displays each element on a separate line.")
-
-(defclass transient-row (transient-group) ()
-  "Group class that displays all elements on a single line.")
-
-(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.")
-
-(defclass transient-subgroups (transient-group) ()
-  "Group class that wraps other groups.
-
-Direct elements have to be groups whose elements have to be
-commands or strings.  This group inserts an empty line between
-subgroups.  The subgroups are responsible for displaying their
-elements themselves.")
-
-;;; Define
-
-(defmacro define-transient-command (name arglist &rest args)
-  "Define NAME as a transient prefix command.
-
-ARGLIST are the arguments that command takes.
-DOCSTRING is the documentation string and is optional.
-
-These arguments can optionally be followed by key-value pairs.
-Each key has to be a keyword symbol, either `:class' or a keyword
-argument supported by the constructor of that class.  The
-`transient-prefix' class is used if the class is not specified
-explicitly.
-
-GROUPs add key bindings for infix and suffix commands and specify
-how these bindings are presented in the popup buffer.  At least
-one GROUP has to be specified.  See info node `(transient)Binding
-Suffix and Infix Commands'.
-
-The BODY is optional.  If it is omitted, then ARGLIST is also
-ignored and the function definition becomes:
-
-  (lambda ()
-    (interactive)
-    (transient-setup \\='NAME))
-
-If BODY is specified, then it must begin with an `interactive'
-form that matches ARGLIST, and it must call `transient-setup'.
-It may however call that function only when some condition is
-satisfied; that is one of the reason why you might want to use
-an explicit BODY.
-
-All transients have a (possibly nil) value, which is exported
-when suffix commands are called, so that they can consume that
-value.  For some transients it might be necessary to have a sort
-of secondary value, called a scope.  Such a scope would usually
-be set in the commands `interactive' form and has to be passed
-to the setup function:
-
-  (transient-setup \\='NAME nil nil :scope SCOPE)
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... GROUP... [BODY...])"
-  (declare (debug (&define name lambda-list
-                           [&optional lambda-doc]
-                           [&rest keywordp sexp]
-                           [&rest vectorp]
-                           [&optional ("interactive" interactive) def-body])))
-  (pcase-let ((`(,class ,slots ,suffixes ,docstr ,body)
-               (transient--expand-define-args args)))
-    `(progn
-       (defalias ',name
-         ,(if body
-              `(lambda ,arglist ,@body)
-            `(lambda ()
-               (interactive)
-               (transient-setup ',name))))
-       (put ',name 'interactive-only t)
-       (put ',name 'function-documentation ,docstr)
-       (put ',name 'transient--prefix
-            (,(or class 'transient-prefix) :command ',name ,@slots))
-       (put ',name 'transient--layout
-            ',(cl-mapcan (lambda (s) (transient--parse-child name s))
-                         suffixes)))))
-
-(defmacro define-suffix-command (name arglist &rest args)
-  "Define NAME as a transient suffix command.
-
-ARGLIST are the arguments that the command takes.
-DOCSTRING is the documentation string and is optional.
-
-These arguments can optionally be followed by key-value pairs.
-Each key has to be a keyword symbol, either `:class' or a
-keyword argument supported by the constructor of that class.
-The `transient-suffix' class is used if the class is not
-specified explicitly.
-
-The BODY must begin with an `interactive' form that matches
-ARGLIST.  The infix arguments are usually accessed by using
-`transient-args' inside `interactive'.
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... BODY...)"
-  (declare (debug (&define name lambda-list
-                           [&optional lambda-doc]
-                           [&rest keywordp sexp]
-                           ("interactive" interactive)
-                           def-body)))
-  (pcase-let ((`(,class ,slots ,_ ,docstr ,body)
-               (transient--expand-define-args args)))
-    `(progn
-       (defalias ',name (lambda ,arglist ,@body))
-       (put ',name 'interactive-only t)
-       (put ',name 'function-documentation ,docstr)
-       (put ',name 'transient--suffix
-            (,(or class 'transient-suffix) :command ',name ,@slots)))))
-
-(defmacro define-infix-command (name _arglist &rest args)
-  "Define NAME as a transient infix command.
-
-ARGLIST is always ignored and reserved for future use.
-DOCSTRING is the documentation string and is optional.
-
-The key-value pairs are mandatory.  All transient infix commands
-are equal to each other (but not eq), so it is meaningless to
-define an infix command without also setting at least `:class'
-and one other keyword (which it is depends on the used class,
-usually `:argument' or `:variable').
-
-Each key has to be a keyword symbol, either `:class' or a keyword
-argument supported by the constructor of that class.  The
-`transient-switch' class is used if the class is not specified
-explicitly.
-
-The function definitions is always:
-
-   (lambda ()
-     (interactive)
-     (let ((obj (transient-suffix-object)))
-       (transient-infix-set obj (transient-infix-read obj)))
-     (transient--show))
-
-`transient-infix-read' and `transient-infix-set' are generic
-functions.  Different infix commands behave differently because
-the concrete methods are different for different infix command
-classes.  In rare case the above command function might not be
-suitable, even if you define your own infix command class.  In
-that case you have to use `transient-suffix-command' to define
-the infix command and use t as the value of the `:transient'
-keyword.
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)"
-  (declare (debug (&define name lambda-list
-                           [&optional lambda-doc]
-                           [&rest keywordp sexp])))
-  (pcase-let ((`(,class ,slots ,_ ,docstr ,_)
-               (transient--expand-define-args args)))
-    `(progn
-       (defalias ',name ,(transient--default-infix-command))
-       (put ',name 'interactive-only t)
-       (put ',name 'function-documentation ,docstr)
-       (put ',name 'transient--suffix
-            (,(or class 'transient-switch) :command ',name ,@slots)))))
-
-(defalias 'define-infix-argument 'define-infix-command
-  "Define NAME as a transient infix command.
-
-Only use this alias to define an infix command that actually
-sets an infix argument.  To define a infix command that, for
-example, sets a variable use `define-infix-command' instead.
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)")
-
-(defun transient--expand-define-args (args)
-  (let (class keys suffixes docstr)
-    (when (stringp (car args))
-      (setq docstr (pop args)))
-    (while (keywordp (car args))
-      (let ((k (pop args))
-            (v (pop args)))
-        (if (eq k :class)
-            (setq class v)
-          (push k keys)
-          (push v keys))))
-    (while (vectorp (car args))
-      (push (pop args) suffixes))
-    (list (if (eq (car-safe class) 'quote)
-              (cadr class)
-            class)
-          (nreverse keys)
-          (nreverse suffixes)
-          docstr
-          args)))
-
-(defun transient--parse-child (prefix spec)
-  (cl-etypecase spec
-    (vector  (when-let ((c (transient--parse-group  prefix spec))) (list c)))
-    (list    (when-let ((c (transient--parse-suffix prefix spec))) (list c)))
-    (string  (list spec))))
-
-(defun transient--parse-group (prefix spec)
-  (setq spec (append spec nil))
-  (cl-symbol-macrolet
-      ((car (car spec))
-       (pop (pop spec)))
-    (let (level class args)
-      (when (integerp car)
-        (setq level pop))
-      (when (stringp car)
-        (setq args (plist-put args :description pop)))
-      (while (keywordp car)
-        (let ((k pop))
-          (if (eq k :class)
-              (setq class pop)
-            (setq args (plist-put args k pop)))))
-      (vector (or level (oref-default 'transient-child level))
-              (or class
-                  (if (vectorp car)
-                      'transient-columns
-                    'transient-column))
-              args
-              (cl-mapcan (lambda (s) (transient--parse-child prefix s)) spec)))))
-
-(defun transient--parse-suffix (prefix spec)
-  (let (level class args)
-    (cl-symbol-macrolet
-        ((car (car spec))
-         (pop (pop spec)))
-      (when (integerp car)
-        (setq level pop))
-      (when (or (stringp car)
-                (vectorp car))
-        (setq args (plist-put args :key pop)))
-      (when (or (stringp car)
-                (eq (car-safe car) 'lambda)
-                (and (symbolp car)
-                     (not (commandp car))
-                     (commandp (cadr spec))))
-        (setq args (plist-put args :description pop)))
-      (cond
-        ((keywordp car)
-         (error "Need command, got %S" car))
-        ((symbolp car)
-         (setq args (plist-put args :command pop)))
-        ((or (stringp car)
-             (and car (listp car)))
-         (let ((arg pop))
-           (cl-typecase arg
-             (list
-              (setq args (plist-put args :shortarg (car  arg)))
-              (setq args (plist-put args :argument (cadr arg)))
-              (setq arg  (cadr arg)))
-             (string
-              (when-let ((shortarg (transient--derive-shortarg arg)))
-                (setq args (plist-put args :shortarg shortarg)))
-              (setq args (plist-put args :argument arg))))
-           (setq args (plist-put args :command
-                                 (intern (format "transient:%s:%s"
-                                                 prefix arg))))
-           (cond ((and car (not (keywordp car)))
-                  (setq class 'transient-option)
-                  (setq args (plist-put args :reader pop)))
-                 ((not (string-suffix-p "=" arg))
-                  (setq class 'transient-switch))
-                 (t
-                  (setq class 'transient-option)
-                  (setq args (plist-put args :reader 'read-string))))))
-        (t
-         (error "Needed command or argument, got %S" car)))
-      (while (keywordp car)
-        (let ((k pop))
-          (cl-case k
-            (:class (setq class pop))
-            (:level (setq level pop))
-            (t (setq args (plist-put args k pop)))))))
-    (unless (plist-get args :key)
-      (when-let ((shortarg (plist-get args :shortarg)))
-        (setq args (plist-put args :key shortarg))))
-    (list (or level (oref-default 'transient-child level))
-          (or class 'transient-suffix)
-          args)))
-
-(defun transient--default-infix-command ()
-  (cons 'lambda '(()
-             (interactive)
-             (let ((obj (transient-suffix-object)))
-               (transient-infix-set obj (transient-infix-read obj)))
-             (transient--show))))
-
-(defun transient--ensure-infix-command (obj)
-  (let ((cmd (oref obj command)))
-    (unless (or (commandp cmd)
-                (get cmd 'transient--infix-command))
-      (if (or (cl-typep obj 'transient-switch)
-              (cl-typep obj 'transient-option))
-          (put cmd 'transient--infix-command
-               (transient--default-infix-command))
-        ;; This is not an anonymous infix argument.
-        (error "Suffix %s is not defined or autoloaded as a command" cmd)))))
-
-(defun transient--derive-shortarg (arg)
-  (save-match-data
-    (and (string-match "\\`\\(-[a-zA-Z]\\)\\(\\'\\|=\\)" arg)
-         (match-string 1 arg))))
-
-;;; Edit
-
-(defun transient--insert-suffix (prefix loc suffix action)
-  (let* ((suf (cl-etypecase suffix
-                (vector (transient--parse-group  prefix suffix))
-                (list   (transient--parse-suffix prefix suffix))
-                (string suffix)))
-         (mem (transient--layout-member loc prefix))
-         (elt (car mem)))
-    (cond
-     ((not mem)
-      (message "Cannot insert %S into %s; %s not found"
-               suffix prefix loc))
-     ((or (and (vectorp suffix) (not (vectorp elt)))
-          (and (listp   suffix) (vectorp elt))
-          (and (stringp suffix) (vectorp elt)))
-      (message "Cannot place %S into %s at %s; %s"
-               suffix prefix loc
-               "suffixes and groups cannot be siblings"))
-     (t
-      (when (and (listp suffix)
-                 (listp elt))
-        (let ((key (or (plist-get elt :key)
-                       (transient--command-key (plist-get elt :command)))))
-          (if (equal (transient--kbd key)
-                     (transient--kbd (plist-get (nth 2 elt) :key)))
-              (setq action 'replace)
-            (transient-remove-suffix prefix key))))
-      (cl-ecase action
-        (insert  (setcdr mem (cons elt (cdr mem)))
-                 (setcar mem suf))
-        (append  (setcdr mem (cons suf (cdr mem))))
-        (replace (setcar mem suf)))))))
-
-(defun transient-insert-suffix (prefix loc suffix)
-  "Insert a SUFFIX into PREFIX before LOC.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
-  the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
-  as returned by `key-description'), or a coordination list
-  (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
-  (declare (indent defun))
-  (transient--insert-suffix prefix loc suffix 'insert))
-
-(defun transient-append-suffix (prefix loc suffix)
-  "Insert a SUFFIX into PREFIX after LOC.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
-  the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
-  as returned by `key-description'), or a coordination list
-  (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
-  (declare (indent defun))
-  (transient--insert-suffix prefix loc suffix 'append))
-
-(defun transient-replace-suffix (prefix loc suffix)
-  "Replace the suffix at LOC in PREFIX with SUFFIX.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
-  the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
-  as returned by `key-description'), or a coordination list
-  (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
-  (declare (indent defun))
-  (transient--insert-suffix prefix loc suffix 'replace))
-
-(defun transient-remove-suffix (prefix loc)
-  "Remove the suffix or group at LOC in PREFIX.
-PREFIX is a prefix command, a symbol.
-LOC is a command, a key vector, a key description (a string
-  as returned by `key-description'), or a coordination list
-  (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
-  (declare (indent defun))
-  (transient--layout-member loc prefix 'remove))
-
-(defun transient-get-suffix (prefix loc)
-  "Return the suffix or group at LOC in PREFIX.
-PREFIX is a prefix command, a symbol.
-LOC is a command, a key vector, a key description (a string
-  as returned by `key-description'), or a coordination list
-  (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
-  (if-let ((mem (transient--layout-member loc prefix)))
-      (car mem)
-    (error "%s not found in %s" loc prefix)))
-
-(defun transient-suffix-put (prefix loc prop value)
-  "Edit the suffix at LOC in PREFIX, setting PROP to VALUE.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
-  the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
-  as returned by `key-description'), or a coordination list
-  (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
-  (let ((suf (transient-get-suffix prefix loc)))
-    (setf (elt suf 2)
-          (plist-put (elt suf 2) prop value))))
-
-(defun transient--layout-member (loc prefix &optional remove)
-  (let ((val (or (get prefix 'transient--layout)
-                 (error "%s is not a transient command" prefix))))
-    (when (listp loc)
-      (while (integerp (car loc))
-        (let* ((children (if (vectorp val) (aref val 3) val))
-               (mem (transient--nthcdr (pop loc) children)))
-          (if (and remove (not loc))
-              (let ((rest (delq (car mem) children)))
-                (if (vectorp val)
-                    (aset val 3 rest)
-                  (put prefix 'transient--layout rest))
-                (setq val nil))
-            (setq val (if loc (car mem) mem)))))
-      (setq loc (car loc)))
-    (if loc
-        (transient--layout-member-1 (transient--kbd loc) val remove)
-      val)))
-
-(defun transient--layout-member-1 (loc layout remove)
-  (cond ((listp layout)
-         (--any (transient--layout-member-1 loc it remove) layout))
-        ((vectorp (car (aref layout 3)))
-         (--any (transient--layout-member-1 loc it remove) (aref layout 3)))
-        (remove
-         (aset layout 3
-               (delq (car (transient--group-member loc layout))
-                     (aref layout 3)))
-         nil)
-        (t (transient--group-member loc layout))))
-
-(defun transient--group-member (loc group)
-  (cl-member-if (lambda (suffix)
-                  (and (listp suffix)
-                       (let* ((def (nth 2 suffix))
-                              (cmd (plist-get def :command)))
-                         (if (symbolp loc)
-                             (eq cmd loc)
-                           (equal (transient--kbd
-                                   (or (plist-get def :key)
-                                       (transient--command-key cmd)))
-                                  loc)))))
-                (aref group 3)))
-
-(defun transient--kbd (keys)
-  (when (vectorp keys)
-    (setq keys (key-description keys)))
-  (when (stringp keys)
-    (setq keys (kbd keys)))
-  keys)
-
-(defun transient--command-key (cmd)
-  (when-let ((obj (get cmd 'transient--suffix)))
-    (cond ((slot-boundp obj 'key)
-           (oref obj key))
-          ((slot-exists-p obj 'shortarg)
-           (if (slot-boundp obj 'shortarg)
-               (oref obj shortarg)
-             (transient--derive-shortarg (oref obj argument)))))))
-
-(defun transient--nthcdr (n list)
-  (nthcdr (if (< n 0) (- (length list) (abs n)) n) list))
-
-;;; Variables
-
-(defvar current-transient-prefix nil
-  "The transient from which this suffix command was invoked.
-This is an object representing that transient, use
-`current-transient-command' to get the respective command.")
-
-(defvar current-transient-command nil
-  "The transient from which this suffix command was invoked.
-This is a symbol representing that transient, use
-`current-transient-object' to get the respective object.")
-
-(defvar current-transient-suffixes nil
-  "The suffixes of the transient from which this suffix command was invoked.
-This is a list of objects.  Usually it is sufficient to instead
-use the function `transient-args', which returns a list of
-values.  In complex cases it might be necessary to use this
-variable instead.")
-
-(defvar post-transient-hook nil
-  "Hook run after exiting a transient.")
-
-(defvar transient--prefix nil)
-(defvar transient--layout nil)
-(defvar transient--suffixes nil)
-
-(defconst transient--stay t   "Do not exist the transient.")
-(defconst transient--exit nil "Do exit the transient.")
-
-(defvar transient--exitp nil "Whether to exit the transient.")
-(defvar transient--showp nil "Whether the transient is show in a popup buffer.")
-(defvar transient--helpp nil "Whether help-mode is active.")
-(defvar transient--editp nil "Whether edit-mode is active.")
-
-(defvar transient--active-infix nil "The active infix awaiting user input.")
-
-(defvar transient--timer nil)
-
-(defvar transient--stack nil)
-
-(defvar transient--buffer-name " *transient*"
-  "Name of the transient buffer.")
-
-(defvar transient--window nil
-  "The window used to display the transient popup.")
-
-(defvar transient--original-window nil
-  "The window that was selected before the transient was invoked.
-Usually it remains selected while the transient is active.")
-
-(define-obsolete-variable-alias 'transient--source-buffer
-  'transient--original-buffer "Transient 0.2.0")
-
-(defvar transient--original-buffer nil
-  "The buffer that was current before the transient was invoked.
-Usually it remains current while the transient is active.")
-
-(defvar transient--debug nil "Whether put debug information into *Messages*.")
-
-(defvar transient--history nil)
-
-;;; Identities
-
-(defun transient-suffix-object (&optional command)
-  "Return the object associated with the current suffix command.
-
-Each suffix commands is associated with an object, which holds
-additional information about the suffix, such as its value (in
-the case of an infix command, which is a kind of suffix command).
-
-This function is intended to be called by infix commands, whose
-command definition usually (at least when defined using
-`define-infix-command') is this:
-
-   (lambda ()
-     (interactive)
-     (let ((obj (transient-suffix-object)))
-       (transient-infix-set obj (transient-infix-read obj)))
-     (transient--show))
-
-\(User input is read outside of `interactive' to prevent the
-command from being added to `command-history'.  See #23.)
-
-Such commands need to be able to access their associated object
-to guide how `transient-infix-read' reads the new value and to
-store the read value.  Other suffix commands (including non-infix
-commands) may also need the object to guide their behavior.
-
-This function attempts to return the object associated with the
-current suffix command even if the suffix command was not invoked
-from a transient.  (For some suffix command that is a valid thing
-to do, for others it is not.)  In that case nil may be returned
-if the command was not defined using one of the macros intended
-to define such commands.
-
-The optional argument COMMAND is intended for internal use.  If
-you are contemplating using it in your own code, then you should
-probably use this instead:
-
-  (get COMMAND 'transient--suffix)"
-  (if transient--prefix
-      (cl-find-if (lambda (obj)
-                    (eq (transient--suffix-command obj)
-                        (or command this-original-command)))
-                  transient--suffixes)
-    (when-let ((obj (get (or command this-command) 'transient--suffix))
-               (obj (clone obj)))
-      (transient-init-scope obj)
-      (transient-init-value obj)
-      obj)))
-
-(defun transient--suffix-command (arg)
-  "Return the command specified by ARG.
-
-Given a suffix specified by ARG, this function returns the
-respective command or a symbol that represents it.  It could
-therefore be considered the inverse of `transient-suffix-object'.
-
-Unlike that function it is only intended for internal use though,
-and it is more complicated to describe because of some internal
-tricks it has to account for.  You do not actually have to know
-any of this.
-
-ARG can be a `transient-suffix' object, a symbol representing a
-command, or a command (which can be either a fbound symbol or a
-lambda expression).
-
-If it is an object, then the value of its `command' slot is used
-as follows.  If ARG satisfies `commandp', then that is returned.
-Otherwise it is assumed to be a symbol that merely represents the
-command.  In that case the lambda expression that is stored in
-the symbols `transient--infix-command' property is returned.
-
-Therefore, if ARG is an object, then this function always returns
-something that is callable as a command.
-
-ARG can also be something that is callable as a function.  If it
-is a symbol, then that is returned.  Otherwise it is a lambda
-expression and a symbol that merely representing that command is
-returned.
-
-Therefore, if ARG is something that is callable as a command,
-then this function always returns a symbol that is, or merely
-represents that command.
-
-The reason that there are \"symbols that merely represent a
-command\" is that by avoiding binding a symbol as a command we
-can prevent it from being offered as a completion candidate for
-`execute-extended-command'.  That is useful for infix arguments,
-which usually do not work correctly unless called from a
-transient.  Unfortunately this only works for infix arguments
-that are defined inline in the definition of a transient prefix
-command; explicitly defined infix arguments continue to pollute
-the command namespace.  It would be better if all this were made
-unnecessary by a `execute-extended-command-ignore' symbol property
-but unfortunately that does not exist (yet?)."
-  (if (transient-suffix--eieio-childp arg)
-      (let ((sym (oref arg command)))
-        (if (commandp sym)
-            sym
-          (get sym 'transient--infix-command)))
-    (if (symbolp arg)
-        arg
-      ;; ARG is an interactive lambda.  The symbol returned by this
-      ;; is not actually a command, just a symbol representing it
-      ;; for purposes other than invoking it as a command.
-      (oref (transient-suffix-object) command))))
-
-;;; Keymaps
-
-(defvar transient-base-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "ESC ESC ESC") 'transient-quit-all)
-    (define-key map (kbd "C-g") 'transient-quit-one)
-    (define-key map (kbd "C-q") 'transient-quit-all)
-    (define-key map (kbd "C-z") 'transient-suspend)
-    (define-key map (kbd "C-v") 'transient-scroll-up)
-    (define-key map (kbd "M-v") 'transient-scroll-down)
-    (define-key map [next]      'transient-scroll-up)
-    (define-key map [prior]     'transient-scroll-down)
-    map)
-  "Parent of other keymaps used by Transient.
-
-This is the parent keymap of all the keymaps that are used in
-all transients: `transient-map' (which in turn is the parent
-of the transient-specific keymaps), `transient-edit-map' and
-`transient-sticky-map'.
-
-If you change a binding here, then you might also have to edit
-`transient-sticky-map' and `transient-common-commands'.  While
-the latter isn't a proper transient prefix command, it can be
-edited using the same functions as used for transients.")
-
-(defvar transient-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map transient-base-map)
-    (define-key map (kbd "C-p") 'universal-argument)
-    (define-key map (kbd "C--") 'negative-argument)
-    (define-key map (kbd "C-t") 'transient-show)
-    (define-key map (kbd "?")   'transient-help)
-    (define-key map (kbd "C-h") 'transient-help)
-    (define-key map (kbd "M-p") 'transient-history-prev)
-    (define-key map (kbd "M-n") 'transient-history-next)
-    map)
-  "Top-level keymap used by all transients.")
-
-(defvar transient-edit-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map transient-base-map)
-    (define-key map (kbd "?")     'transient-help)
-    (define-key map (kbd "C-h")   'transient-help)
-    (define-key map (kbd "C-x l") 'transient-set-level)
-    map)
-  "Keymap that is active while a transient in is in \"edit mode\".")
-
-(defvar transient-sticky-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map transient-base-map)
-    (define-key map (kbd "C-g") 'transient-quit-seq)
-    map)
-  "Keymap that is active while an incomplete key sequence is active.")
-
-(defvar transient--common-command-prefixes '(?\C-x))
-
-(put 'transient-common-commands
-     'transient--layout
-     (cl-mapcan
-      (lambda (s) (transient--parse-child 'transient-common-commands s))
-      '([:hide (lambda ()
-                 (and (not (memq (car transient--redisplay-key)
-                                 transient--common-command-prefixes))
-                      (not transient-show-common-commands)))
-         ["Value commands"
-          ("C-x s  " "Set"            transient-set)
-          ("C-x C-s" "Save"           transient-save)
-          ("M-p    " "Previous value" transient-history-prev)
-          ("M-n    " "Next value"     transient-history-next)]
-         ["Sticky commands"
-          ;; Like `transient-sticky-map' except that
-          ;; "C-g" has to be bound to a different command.
-          ("C-g" "Quit prefix or transient" transient-quit-one)
-          ("C-q" "Quit transient stack"     transient-quit-all)
-          ("C-z" "Suspend transient stack"  transient-suspend)]
-         ["Customize"
-          ("C-x t" transient-toggle-common
-           :description (lambda ()
-                          (if transient-show-common-commands
-                              "Hide common commands"
-                            "Show common permanently")))
-          ("C-x l" "Show/hide suffixes" transient-set-level)]])))
-
-(defvar transient-predicate-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map [handle-switch-frame]     'transient--do-suspend)
-    (define-key map [transient-suspend]       'transient--do-suspend)
-    (define-key map [transient-help]          'transient--do-stay)
-    (define-key map [transient-set-level]     'transient--do-stay)
-    (define-key map [transient-history-prev]  'transient--do-stay)
-    (define-key map [transient-history-next]  'transient--do-stay)
-    (define-key map [universal-argument]      'transient--do-stay)
-    (define-key map [negative-argument]       'transient--do-stay)
-    (define-key map [digit-argument]          'transient--do-stay)
-    (define-key map [transient-quit-all]      'transient--do-quit-all)
-    (define-key map [transient-quit-one]      'transient--do-quit-one)
-    (define-key map [transient-quit-seq]      'transient--do-stay)
-    (define-key map [transient-show]          'transient--do-stay)
-    (define-key map [transient-update]        'transient--do-stay)
-    (define-key map [transient-toggle-common] 'transient--do-stay)
-    (define-key map [transient-set]           'transient--do-call)
-    (define-key map [transient-save]          'transient--do-call)
-    (define-key map [describe-key-briefly]    'transient--do-stay)
-    (define-key map [describe-key]            'transient--do-stay)
-    (define-key map [transient-scroll-up]     'transient--do-stay)
-    (define-key map [transient-scroll-down]   'transient--do-stay)
-    (define-key map [mwheel-scroll]           'transient--do-stay)
-    (define-key map [transient-noop]              'transient--do-noop)
-    (define-key map [transient-mouse-push-button] 'transient--do-move)
-    (define-key map [transient-push-button]       'transient--do-move)
-    (define-key map [transient-backward-button]   'transient--do-move)
-    (define-key map [transient-forward-button]    'transient--do-move)
-    (define-key map [transient-isearch-backward]  'transient--do-move)
-    (define-key map [transient-isearch-forward]   'transient--do-move)
-    map)
-  "Base keymap used to map common commands to their transient behavior.
-
-The \"transient behavior\" of a command controls, among other
-things, whether invoking the command causes the transient to be
-exited or not and whether infix arguments are exported before
-doing so.
-
-Each \"key\" is a command that is common to all transients and
-that is bound in `transient-map', `transient-edit-map',
-`transient-sticky-map' and/or `transient-common-command'.
-
-Each binding is a \"pre-command\", a function that controls the
-transient behavior of the respective command.
-
-For transient commands that are bound in individual transients,
-the transient behavior is specified using the `:transient' slot
-of the corresponding object.")
-
-(defvar transient-popup-navigation-map)
-
-(defvar transient--transient-map nil)
-(defvar transient--predicate-map nil)
-(defvar transient--redisplay-map nil)
-(defvar transient--redisplay-key nil)
-
-(defun transient--push-keymap (map)
-  (transient--debug "   push %s%s" map (if (symbol-value map) "" " VOID"))
-  (with-demoted-errors "transient--push-keymap: %S"
-    (internal-push-keymap (symbol-value map) 'overriding-terminal-local-map)))
-
-(defun transient--pop-keymap (map)
-  (transient--debug "   pop  %s%s" map (if (symbol-value map) "" " VOID"))
-  (with-demoted-errors "transient--pop-keymap: %S"
-    (internal-pop-keymap (symbol-value map) 'overriding-terminal-local-map)))
-
-(defun transient--make-transient-map ()
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map (if transient--editp
-                               transient-edit-map
-                             transient-map))
-    (dolist (obj transient--suffixes)
-      (let ((key (oref obj key)))
-        (when (vectorp key)
-          (setq key (key-description key))
-          (oset obj key key))
-        (when transient-substitute-key-function
-          (setq key (save-match-data
-                      (funcall transient-substitute-key-function obj)))
-          (oset obj key key))
-        (let ((kbd (kbd key))
-              (cmd (transient--suffix-command obj)))
-          (when-let ((conflict (and transient-detect-key-conflicts
-                                    (transient--lookup-key map kbd))))
-            (unless (eq cmd conflict)
-              (error "Cannot bind %S to %s and also %s"
-                     (string-trim key)
-                     cmd conflict)))
-          (define-key map kbd cmd))))
-    (when transient-enable-popup-navigation
-      (setq map
-            (make-composed-keymap (list map transient-popup-navigation-map))))
-    map))
-
-(defun transient--make-predicate-map ()
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map transient-predicate-map)
-    (dolist (obj transient--suffixes)
-      (let* ((cmd (transient--suffix-command obj))
-             (sub-prefix (and (symbolp cmd) (get cmd 'transient--prefix))))
-        (if (slot-boundp obj 'transient)
-            (define-key map (vector cmd)
-              (let ((do (oref obj transient)))
-                (pcase do
-                  (`t (if sub-prefix
-                          'transient--do-replace
-                        'transient--do-stay))
-                  (`nil 'transient--do-exit)
-                  (_ do))))
-          (unless (lookup-key transient-predicate-map (vector cmd))
-            (define-key map (vector cmd)
-              (if sub-prefix
-                  'transient--do-replace
-                (or (oref transient--prefix transient-suffix)
-                    'transient--do-exit)))))))
-    map))
-
-(defun transient--make-redisplay-map ()
-  (setq transient--redisplay-key
-        (cl-case this-command
-          (transient-update
-           (setq transient--showp t)
-           (setq unread-command-events
-                 (listify-key-sequence (this-single-command-raw-keys))))
-          (transient-quit-seq
-           (setq unread-command-events
-                 (butlast (listify-key-sequence
-                           (this-single-command-raw-keys))
-                          2))
-           (butlast transient--redisplay-key))
-          (t nil)))
-  (let ((topmap (make-sparse-keymap))
-        (submap (make-sparse-keymap)))
-    (when transient--redisplay-key
-      (define-key topmap (vconcat transient--redisplay-key) submap)
-      (set-keymap-parent submap transient-sticky-map))
-    (map-keymap-internal
-     (lambda (key def)
-       (when (and (not (eq key ?\e))
-                  (listp def)
-                  (keymapp def))
-         (define-key topmap (vconcat transient--redisplay-key (list key))
-           'transient-update)))
-     (if transient--redisplay-key
-         (lookup-key transient--transient-map (vconcat transient--redisplay-key))
-       transient--transient-map))
-    topmap))
-
-;;; Setup
-
-(defun transient-setup (&optional name layout edit &rest params)
-  "Setup the transient specified by NAME.
-
-This function is called by transient prefix commands to setup the
-transient.  In that case NAME is mandatory, LAYOUT and EDIT must
-be nil and PARAMS may be (but usually is not) used to set e.g. the
-\"scope\" of the transient (see `transient-define-prefix').
-
-This function is also called internally in which case LAYOUT and
-EDIT may be non-nil."
-  (transient--debug 'setup)
-  (cond
-   ((not name)
-    ;; Switching between regular and edit mode.
-    (transient--pop-keymap 'transient--transient-map)
-    (transient--pop-keymap 'transient--redisplay-map)
-    (setq name (oref transient--prefix command))
-    (setq params (list :scope (oref transient--prefix scope))))
-   ((not (or layout                      ; resuming parent/suspended prefix
-             current-transient-command)) ; entering child prefix
-    (transient--stack-zap))              ; replace suspended prefix, if any
-   (edit
-    ;; Returning from help to edit.
-    (setq transient--editp t)))
-  (transient--init-objects name layout params)
-  (transient--history-init transient--prefix)
-  (setq transient--predicate-map (transient--make-predicate-map))
-  (setq transient--transient-map (transient--make-transient-map))
-  (setq transient--redisplay-map (transient--make-redisplay-map))
-  (setq transient--original-window (selected-window))
-  (setq transient--original-buffer (current-buffer))
-  (transient--redisplay)
-  (transient--init-transient)
-  (transient--suspend-which-key-mode))
-
-(defun transient--init-objects (name layout params)
-  (setq transient--prefix
-        (let ((proto (get name 'transient--prefix)))
-          (apply #'clone proto
-                 :prototype proto
-                 :level (or (alist-get
-                             t (alist-get name transient-levels))
-                            transient-default-level)
-                 params)))
-  (transient-init-value transient--prefix)
-  (setq transient--layout
-        (or layout
-            (let ((levels (alist-get name transient-levels)))
-              (cl-mapcan (lambda (c) (transient--init-child levels c))
-                         (append (get name 'transient--layout)
-                                 (and (not transient--editp)
-                                      (get 'transient-common-commands
-                                           'transient--layout)))))))
-  (setq transient--suffixes
-        (cl-labels ((s (def)
-                       (cond
-                        ((stringp def) nil)
-                        ((listp def) (cl-mapcan #'s def))
-                        ((transient-group--eieio-childp def)
-                         (cl-mapcan #'s (oref def suffixes)))
-                        ((transient-suffix--eieio-childp def)
-                         (list def)))))
-          (cl-mapcan #'s transient--layout))))
-
-(defun transient--init-child (levels spec)
-  (cl-etypecase spec
-    (vector  (transient--init-group  levels spec))
-    (list    (transient--init-suffix levels spec))
-    (string  (list spec))))
-
-(defun transient--init-group (levels spec)
-  (pcase-let ((`(,level ,class ,args ,children) (append spec nil)))
-    (when (transient--use-level-p level)
-      (let ((obj (apply class :level level args)))
-        (when (transient--use-suffix-p obj)
-          (when-let ((suffixes
-                      (cl-mapcan (lambda (c) (transient--init-child levels c))
-                                 children)))
-            (oset obj suffixes suffixes)
-            (list obj)))))))
-
-(defun transient--init-suffix (levels spec)
-  (pcase-let* ((`(,level ,class ,args) spec)
-               (cmd (plist-get args :command))
-               (level (or (alist-get (transient--suffix-command cmd) levels)
-                          level)))
-    (let ((fn (and (symbolp cmd)
-                   (symbol-function cmd))))
-      (when (autoloadp fn)
-        (transient--debug "   autoload %s" cmd)
-        (autoload-do-load fn)))
-    (when (transient--use-level-p level)
-      (let ((obj (if-let ((proto (and cmd
-                                      (symbolp cmd)
-                                      (get cmd 'transient--suffix))))
-                     (apply #'clone proto :level level args)
-                   (apply class :level level args))))
-        (transient--init-suffix-key obj)
-        (transient--ensure-infix-command obj)
-        (when (transient--use-suffix-p obj)
-          (transient-init-scope obj)
-          (transient-init-value obj)
-          (list obj))))))
-
-(cl-defmethod transient--init-suffix-key ((obj transient-suffix))
-  (unless (slot-boundp obj 'key)
-    (error "No key for %s" (oref obj command))))
-
-(cl-defmethod transient--init-suffix-key ((obj transient-argument))
-  (if (transient-switches--eieio-childp obj)
-      (cl-call-next-method obj)
-    (unless (slot-boundp obj 'shortarg)
-      (when-let ((shortarg (transient--derive-shortarg (oref obj argument))))
-        (oset obj shortarg shortarg)))
-    (unless (slot-boundp obj 'key)
-      (if (slot-boundp obj 'shortarg)
-          (oset obj key (oref obj shortarg))
-        (error "No key for %s" (oref obj command))))))
-
-(defun transient--use-level-p (level &optional edit)
-  (or (and transient--editp (not edit))
-      (and (>= level 1)
-           (<= level (oref transient--prefix level)))))
-
-(defun transient--use-suffix-p (obj)
-  (with-slots
-      (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived)
-      obj
-    (cond
-     (if                  (funcall if))
-     (if-not         (not (funcall if-not)))
-     (if-non-nil          (symbol-value if-non-nil))
-     (if-nil         (not (symbol-value if-nil)))
-     (if-mode             (if (atom if-mode)
-                              (eq major-mode if-mode)
-                            (memq major-mode if-mode)))
-     (if-not-mode    (not (if (atom if-not-mode)
-                              (eq major-mode if-not-mode)
-                            (memq major-mode if-not-mode))))
-     (if-derived          (if (atom if-derived)
-                              (derived-mode-p if-derived)
-                            (apply #'derived-mode-p if-derived)))
-     (if-not-derived (not (if (atom if-not-derived)
-                              (derived-mode-p if-not-derived)
-                            (apply #'derived-mode-p if-not-derived))))
-     (t))))
-
-;;; Flow-Control
-
-(defun transient--init-transient ()
-  (transient--debug 'init-transient)
-  (transient--push-keymap 'transient--transient-map)
-  (transient--push-keymap 'transient--redisplay-map)
-  (add-hook 'pre-command-hook      #'transient--pre-command)
-  (add-hook 'minibuffer-setup-hook #'transient--minibuffer-setup)
-  (add-hook 'minibuffer-exit-hook  #'transient--minibuffer-exit)
-  (add-hook 'post-command-hook     #'transient--post-command)
-  (advice-add 'abort-recursive-edit :after #'transient--minibuffer-exit)
-  (when transient--exitp
-    ;; This prefix command was invoked as the suffix of another.
-    ;; Prevent `transient--post-command' from removing the hooks
-    ;; that we just added.
-    (setq transient--exitp 'replace)))
-
-(defun transient--pre-command ()
-  (transient--debug 'pre-command)
-  (cond
-   ((memq this-command '(transient-update transient-quit-seq))
-    (transient--pop-keymap 'transient--redisplay-map))
-   ((and transient--helpp
-         (not (memq this-command '(transient-quit-one
-                                   transient-quit-all))))
-    (cond
-     ((transient-help)
-      (transient--do-suspend)
-      (setq this-command 'transient-suspend)
-      (transient--pre-exit))
-     (t
-      (setq this-command 'transient-undefined))))
-   ((and transient--editp
-         (transient-suffix-object)
-         (not (memq this-command '(transient-quit-one
-                                   transient-quit-all
-                                   transient-help))))
-    (setq this-command 'transient-set-level))
-   (t
-    (setq transient--exitp nil)
-    (when (eq (if-let ((fn (or (lookup-key transient--predicate-map
-                                           (vector this-original-command))
-                               (oref transient--prefix transient-non-suffix))))
-                  (let ((action (funcall fn)))
-                    (when (eq action transient--exit)
-                      (setq transient--exitp (or transient--exitp t)))
-                    action)
-                (setq this-command
-                      (let ((keys (this-command-keys-vector)))
-                        (if (eq (aref keys (1- (length keys))) ?\C-g)
-                            'transient-noop
-                          'transient-undefined)))
-                transient--stay)
-              transient--exit)
-      (transient--pre-exit)))))
-
-(defun transient--pre-exit ()
-  (transient--debug 'pre-exit)
-  (transient--delete-window)
-  (transient--timer-cancel)
-  (transient--pop-keymap 'transient--transient-map)
-  (transient--pop-keymap 'transient--redisplay-map)
-  (remove-hook 'pre-command-hook #'transient--pre-command)
-  (unless transient--showp
-    (message ""))
-  (setq transient--transient-map nil)
-  (setq transient--predicate-map nil)
-  (setq transient--redisplay-map nil)
-  (setq transient--redisplay-key nil)
-  (setq transient--showp nil)
-  (setq transient--helpp nil)
-  (setq transient--editp nil)
-  (setq transient--prefix nil)
-  (setq transient--layout nil)
-  (setq transient--suffixes nil)
-  (setq transient--original-window nil)
-  (setq transient--original-buffer nil)
-  (setq transient--window nil))
-
-(defun transient--delete-window ()
-  (when (window-live-p transient--window)
-    (let ((buf (window-buffer transient--window)))
-      (with-demoted-errors "Error while exiting transient: %S"
-        (delete-window transient--window))
-      (kill-buffer buf))))
-
-(defun transient--export ()
-  (setq current-transient-prefix transient--prefix)
-  (setq current-transient-command (oref transient--prefix command))
-  (setq current-transient-suffixes transient--suffixes)
-  (transient--history-push transient--prefix))
-
-(defun transient--minibuffer-setup ()
-  (transient--debug 'minibuffer-setup)
-  (unless (> (minibuffer-depth) 1)
-    (unless transient--exitp
-      (transient--pop-keymap 'transient--transient-map)
-      (transient--pop-keymap 'transient--redisplay-map)
-      (remove-hook 'pre-command-hook #'transient--pre-command))
-    (remove-hook 'post-command-hook #'transient--post-command)))
-
-(defun transient--minibuffer-exit ()
-  (transient--debug 'minibuffer-exit)
-  (unless (> (minibuffer-depth) 1)
-    (unless transient--exitp
-      (transient--push-keymap 'transient--transient-map)
-      (transient--push-keymap 'transient--redisplay-map)
-      (add-hook 'pre-command-hook #'transient--pre-command))
-    (add-hook 'post-command-hook #'transient--post-command)))
-
-(defun transient--post-command ()
-  (transient--debug 'post-command)
-  (if transient--exitp
-      (progn
-        (unless (and (eq transient--exitp 'replace)
-                     (or transient--prefix
-                         ;; The current command could act as a prefix,
-                         ;; but decided not to call `transient-setup'.
-                         (prog1 nil (transient--stack-zap))))
-          (remove-hook   'minibuffer-setup-hook #'transient--minibuffer-setup)
-          (remove-hook   'minibuffer-exit-hook  #'transient--minibuffer-exit)
-          (advice-remove 'abort-recursive-edit  #'transient--minibuffer-exit)
-          (remove-hook   'post-command-hook     #'transient--post-command))
-        (setq current-transient-prefix nil)
-        (setq current-transient-command nil)
-        (setq current-transient-suffixes nil)
-        (let ((resume (and transient--stack
-                           (not (memq transient--exitp '(replace suspend))))))
-          (setq transient--exitp nil)
-          (setq transient--helpp nil)
-          (setq transient--editp nil)
-          (run-hooks 'post-transient-hook)
-          (when resume
-            (transient--stack-pop))))
-    (transient--pop-keymap 'transient--redisplay-map)
-    (setq transient--redisplay-map (transient--make-redisplay-map))
-    (transient--push-keymap 'transient--redisplay-map)
-    (unless (eq this-command (oref transient--prefix command))
-      (transient--redisplay))))
-
-(defun transient--stack-push ()
-  (transient--debug 'stack-push)
-  (push (list (oref transient--prefix command)
-              transient--layout
-              transient--editp
-              :scope (oref transient--prefix scope))
-        transient--stack))
-
-(defun transient--stack-pop ()
-  (transient--debug 'stack-pop)
-  (and transient--stack
-       (prog1 t (apply #'transient-setup (pop transient--stack)))))
-
-(defun transient--stack-zap ()
-  (transient--debug 'stack-zap)
-  (setq transient--stack nil))
-
-(defun transient--redisplay ()
-  (if (or (eq transient-show-popup t)
-          transient--showp)
-      (unless (memq this-command '(transient-scroll-up
-                                   transient-scroll-down
-                                   mwheel-scroll))
-        (transient--show))
-    (when (and (numberp transient-show-popup)
-               (not (zerop transient-show-popup))
-               (not transient--timer))
-      (transient--timer-start))
-    (transient--show-brief)))
-
-(defun transient--timer-start ()
-  (setq transient--timer
-        (run-at-time (abs transient-show-popup) nil
-                     (lambda ()
-                       (transient--timer-cancel)
-                       (transient--show)
-                       (let ((message-log-max nil))
-                         (message ""))))))
-
-(defun transient--timer-cancel ()
-  (when transient--timer
-    (cancel-timer transient--timer)
-    (setq transient--timer nil)))
-
-(defun transient--debug (arg &rest args)
-  (when transient--debug
-    (if (symbolp arg)
-        (message "-- %-16s (cmd: %s, exit: %s)"
-                 arg this-command transient--exitp)
-    (apply #'message arg args))))
-
-(defun transient--emergency-exit ()
-  "Exit the current transient command after an error occured.
-Beside being used with `condition-case', this function also has
-to be a member of `debugger-mode-hook', else the debugger would
-be unusable and exiting it by pressing \"q\" would fail because
-the transient command would still be active and that key would
-either be unbound or do something else."
-  (when transient--prefix
-    (setq transient--stack nil)
-    (setq transient--exitp t)
-    (transient--pre-exit)
-    (transient--post-command)))
-
-(add-hook 'debugger-mode-hook 'transient--emergency-exit)
-
-(defmacro transient--with-emergency-exit (&rest body)
-  (declare (indent defun))
-  `(condition-case nil
-       ,(macroexp-progn body)
-     (error (transient--emergency-exit))))
-
-;;; Pre-Commands
-
-(defun transient--do-stay ()
-  "Call the command without exporting variables and stay transient."
-  transient--stay)
-
-(defun transient--do-noop ()
-  "Call `transient-noop' and stay transient."
-  (setq this-command 'transient-noop)
-  transient--stay)
-
-(defun transient--do-warn ()
-  "Call `transient-undefined' and stay transient."
-  (setq this-command 'transient-undefined)
-  transient--stay)
-
-(defun transient--do-call ()
-  "Call the command after exporting variables and stay transient."
-  (transient--export)
-  transient--stay)
-
-(defun transient--do-exit ()
-  "Call the command after exporting variables and exit the transient."
-  (transient--export)
-  (transient--stack-zap)
-  transient--exit)
-
-(defun transient--do-replace ()
-  "Call the transient prefix command, replacing the active transient."
-  (transient--export)
-  (transient--stack-push)
-  (setq transient--exitp 'replace)
-  transient--exit)
-
-(defun transient--do-suspend ()
-  "Suspend the active transient, saving the transient stack."
-  (transient--stack-push)
-  (setq transient--exitp 'suspend)
-  transient--exit)
-
-(defun transient--do-quit-one ()
-  "If active, quit help or edit mode, else exit the active transient."
-  (cond (transient--helpp
-         (setq transient--helpp nil)
-         transient--stay)
-        (transient--editp
-         (setq transient--editp nil)
-         (transient-setup)
-         transient--stay)
-        (t transient--exit)))
-
-(defun transient--do-quit-all ()
-  "Exit all transients without saving the transient stack."
-  (transient--stack-zap)
-  transient--exit)
-
-(defun transient--do-move ()
-  "Call the command if `transient-enable-popup-navigation' is non-nil.
-In that case behave like `transient--do-stay', otherwise similar
-to `transient--do-warn'."
-  (unless transient-enable-popup-navigation
-    (setq this-command 'transient-popup-navigation-help))
-  transient--stay)
-
-;;; Commands
-
-(defun transient-noop ()
-  "Do nothing at all."
-  (interactive))
-
-(defun transient-undefined ()
-  "Warn the user that the pressed key is not bound to any suffix."
-  (interactive)
-  (ding)
-  (message "Unbound suffix: `%s' (Use `%s' to abort, `%s' for help)"
-           (propertize (key-description (this-single-command-keys))
-                       'face 'font-lock-warning-face)
-           (propertize "C-g" 'face 'transient-key)
-           (propertize "?"   'face 'transient-key)))
-
-(defun transient-toggle-common ()
-  "Toggle whether common commands are always shown."
-  (interactive)
-  (setq transient-show-common-commands (not transient-show-common-commands)))
-
-(defun transient-suspend ()
-  "Suspend the current transient.
-It can later be resumed using `transient-resume' while no other
-transient is active."
-  (interactive))
-
-(defun transient-quit-all ()
-  "Exit all transients without saving the transient stack."
-  (interactive))
-
-(defun transient-quit-one ()
-  "Exit the current transients, possibly returning to the previous."
-  (interactive))
-
-(defun transient-quit-seq ()
-  "Abort the current incomplete key sequence."
-  (interactive))
-
-(defun transient-update ()
-  "Redraw the transient's state in the popup buffer."
-  (interactive))
-
-(defun transient-show ()
-  "Show the transient's state in the popup buffer."
-  (interactive)
-  (setq transient--showp t))
-
-(defvar-local transient--restore-winconf nil)
-
-(defvar transient-resume-mode)
-
-(defun transient-help ()
-  "Show help for the active transient or one of its suffixes."
-  (interactive)
-  (if (called-interactively-p 'any)
-      (setq transient--helpp t)
-    (with-demoted-errors "transient-help: %S"
-      (when (lookup-key transient--transient-map
-                        (this-single-command-raw-keys))
-        (setq transient--helpp nil)
-        (let ((winconf (current-window-configuration)))
-          (transient-show-help
-           (if (eq this-original-command 'transient-help)
-               transient--prefix
-             (or (transient-suffix-object)
-                 this-original-command)))
-          (setq transient--restore-winconf winconf))
-        (fit-window-to-buffer nil (frame-height) (window-height))
-        (transient-resume-mode)
-        (message "Type \"q\" to resume transient command.")
-        t))))
-
-(defun transient-set-level (&optional command level)
-  "Set the level of the transient or one of its suffix commands."
-  (interactive
-   (let ((command this-original-command)
-         (prefix (oref transient--prefix command)))
-     (and (or (not (eq command 'transient-set-level))
-              (and transient--editp
-                   (setq command prefix)))
-          (list command
-                (let ((keys (this-single-command-raw-keys)))
-                  (and (lookup-key transient--transient-map keys)
-                       (string-to-number
-                        (transient--read-number-N
-                         (format "Set level for `%s': "
-                                 (transient--suffix-command command))
-                         nil nil (not (eq command prefix))))))))))
-  (cond
-   ((not command)
-    (setq transient--editp t)
-    (transient-setup))
-   (level
-    (let* ((prefix (oref transient--prefix command))
-           (alist (alist-get prefix transient-levels))
-           (key (transient--suffix-command command)))
-      (if (eq command prefix)
-          (progn (oset transient--prefix level level)
-                 (setq key t))
-        (oset (transient-suffix-object command) level level))
-      (setf (alist-get key alist) level)
-      (setf (alist-get prefix transient-levels) alist))
-    (transient-save-levels))
-   (t
-    (transient-undefined))))
-
-(defun transient-set ()
-  "Save the value of the active transient for this Emacs session."
-  (interactive)
-  (transient-set-value (or transient--prefix current-transient-prefix)))
-
-(defun transient-save ()
-  "Save the value of the active transient persistenly across Emacs sessions."
-  (interactive)
-  (transient-save-value (or transient--prefix current-transient-prefix)))
-
-(defun transient-history-next ()
-  "Switch to the next value used for the active transient."
-  (interactive)
-  (let* ((obj transient--prefix)
-         (pos (1- (oref obj history-pos)))
-         (hst (oref obj history)))
-    (if (< pos 0)
-        (user-error "End of history")
-      (oset obj history-pos pos)
-      (oset obj value (nth pos hst))
-      (mapc #'transient-init-value transient--suffixes))))
-
-(defun transient-history-prev ()
-  "Switch to the previous value used for the active transient."
-  (interactive)
-  (let* ((obj transient--prefix)
-         (pos (1+ (oref obj history-pos)))
-         (hst (oref obj history))
-         (len (length hst)))
-    (if (> pos (1- len))
-        (user-error "End of history")
-      (oset obj history-pos pos)
-      (oset obj value (nth pos hst))
-      (mapc #'transient-init-value transient--suffixes))))
-
-(defun transient-scroll-up (&optional arg)
-  "Scroll text of transient popup window upward ARG lines.
-If ARG is nil scroll near full screen.  This is a wrapper
-around `scroll-up-command' (which see)."
-  (interactive "^P")
-  (with-selected-window transient--window
-    (scroll-up-command arg)))
-
-(defun transient-scroll-down (&optional arg)
-  "Scroll text of transient popup window down ARG lines.
-If ARG is nil scroll near full screen.  This is a wrapper
-around `scroll-down-command' (which see)."
-  (interactive "^P")
-  (with-selected-window transient--window
-    (scroll-down-command arg)))
-
-(defun transient-resume ()
-  "Resume a previously suspended stack of transients."
-  (interactive)
-  (cond (transient--stack
-         (let ((winconf transient--restore-winconf))
-           (kill-local-variable 'transient--restore-winconf)
-           (when transient-resume-mode
-             (transient-resume-mode -1)
-             (quit-window))
-           (when winconf
-             (set-window-configuration winconf)))
-         (transient--stack-pop))
-        (transient-resume-mode
-         (kill-local-variable 'transient--restore-winconf)
-         (transient-resume-mode -1)
-         (quit-window))
-        (t
-         (message "No suspended transient command"))))
-
-;;; Value
-;;;; Init
-
-(cl-defgeneric transient-init-scope (obj)
-  "Set the scope of the suffix object OBJ.
-
-The scope is actually a property of the transient prefix, not of
-individual suffixes.  However it is possible to invoke a suffix
-command directly instead of from a transient.  In that case, if
-the suffix expects a scope, then it has to determine that itself
-and store it in its `scope' slot.
-
-This function is called for all suffix commands, but unless a
-concrete method is implemented this falls through to the default
-implementation, which is a noop.")
-
-(cl-defmethod transient-init-scope ((_   transient-suffix))
-  "Noop." nil)
-
-(cl-defgeneric transient-init-value (_)
-  "Set the initial value of the object OBJ.
-
-This function is called for all prefix and suffix commands.
-
-For suffix commands (including infix argument commands) the
-default implementation is a noop.  Classes derived from the
-abstract `transient-infix' class must implement this function.
-Non-infix suffix commands usually don't have a value."
-  nil)
-
-(cl-defmethod transient-init-value ((obj transient-prefix))
-  (if (slot-boundp obj 'value)
-      (let ((value (oref obj value)))
-        (when (functionp value)
-          (oset obj value (funcall value))))
-    (oset obj value
-          (if-let ((saved (assq (oref obj command) transient-values)))
-              (cdr saved)
-            nil))))
-
-(cl-defmethod transient-init-value ((obj transient-switch))
-  (oset obj value
-        (car (member (oref obj argument)
-                     (oref transient--prefix value)))))
-
-(cl-defmethod transient-init-value ((obj transient-option))
-  (oset obj value
-        (transient--value-match (format "\\`%s\\(.*\\)" (oref obj argument)))))
-
-(cl-defmethod transient-init-value ((obj transient-switches))
-  (oset obj value
-        (transient--value-match (oref obj argument-regexp))))
-
-(defun transient--value-match (re)
-  (when-let ((match (cl-find-if (lambda (v)
-                                  (and (stringp v)
-                                       (string-match re v)))
-                                (oref transient--prefix value))))
-    (match-string 1 match)))
-
-(cl-defmethod transient-init-value ((obj transient-files))
-  (oset obj value
-        (cdr (assoc "--" (oref transient--prefix value)))))
-
-;;;; Read
-
-(cl-defgeneric transient-infix-read (obj)
-  "Determine the new value of the infix object OBJ.
-
-This function merely determines the value; `transient-infix-set'
-is used to actually store the new value in the object.
-
-For most infix classes this is done by reading a value from the
-user using the reader specified by the `reader' slot (using the
-`transient-infix' method described below).
-
-For some infix classes the value is changed without reading
-anything in the minibuffer, i.e. the mere act of invoking the
-infix command determines what the new value should be, based
-on the previous value.")
-
-(cl-defmethod transient-infix-read :around ((obj transient-infix))
-  "Highlight the infix in the popup buffer.
-
-Also arrange for the transient to be exited in case of an error
-because otherwise Emacs would get stuck in an inconsistent state,
-which might make it necessary to kill it from the outside."
-  (let ((transient--active-infix obj))
-    (transient--show))
-  (transient--with-emergency-exit
-    (cl-call-next-method obj)))
-
-(cl-defmethod transient-infix-read ((obj transient-infix))
-  "Read a value while taking care of history.
-
-This method is suitable for a wide variety of infix commands,
-including but not limitted to inline arguments and variables.
-
-If you do not use this method for your own infix class, then
-you should likely replicate a lot of the behavior of this
-method.  If you fail to do so, then users might not appreciate
-the lack of history, for example.
-
-Only for very simple classes that toggle or cycle through a very
-limited number of possible values should you replace this with a
-simple method that does not handle history.  (E.g. for a command
-line switch the only possible values are \"use it\" and \"don't use
-it\", in which case it is pointless to preserve history.)"
-  (with-slots (value multi-value allow-empty choices) obj
-    (if (and value
-             (not multi-value)
-             transient--prefix)
-        (oset obj value nil)
-      (let* ((overriding-terminal-local-map nil)
-             (reader (oref obj reader))
-             (prompt (transient-prompt obj))
-             (value (if multi-value (mapconcat #'identity value ",") value))
-             (history-key (or (oref obj history-key)
-                              (oref obj command)))
-             (transient--history (alist-get history-key transient-history))
-             (transient--history (if (or (null value)
-                                         (eq value (car transient--history)))
-                                     transient--history
-                                   (cons value transient--history)))
-             (initial-input (and transient-read-with-initial-input
-                                 (car transient--history)))
-             (history (cons 'transient--history (if initial-input 1 0)))
-             (value
-              (cond
-               (reader (funcall reader prompt initial-input history))
-               (multi-value
-                (completing-read-multiple prompt choices nil nil
-                                          initial-input history))
-               (choices
-                (completing-read prompt choices nil t initial-input history))
-               (t (read-string prompt initial-input history)))))
-        (cond ((and (equal value "") (not allow-empty))
-               (setq value nil))
-              ((and (equal value "\"\"") allow-empty)
-               (setq value "")))
-        (when value
-          (setf (alist-get history-key transient-history)
-                (delete-dups transient--history)))
-        value))))
-
-(cl-defmethod transient-infix-read ((obj transient-switch))
-  "Toggle the switch on or off."
-  (if (oref obj value) nil (oref obj argument)))
-
-(cl-defmethod transient-infix-read ((obj transient-switches))
-  "Cycle through the mutually exclusive switches.
-The last value is \"don't use any of these switches\"."
-  (let ((choices (mapcar (apply-partially #'format (oref obj argument-format))
-                         (oref obj choices))))
-    (if-let ((value (oref obj value)))
-        (cadr (member value choices))
-      (car choices))))
-
-;;;; Readers
-
-(defun transient-read-directory (prompt _initial-input _history)
-  "Read a directory."
-  (expand-file-name (read-directory-name prompt)))
-
-(defun transient-read-existing-directory (prompt _initial-input _history)
-  "Read an existing directory."
-  (expand-file-name (read-directory-name prompt nil nil t)))
-
-(defun transient-read-number-N0 (prompt initial-input history)
-  "Read a natural number (including zero) and return it as a string."
-  (transient--read-number-N prompt initial-input history t))
-
-(defun transient-read-number-N+ (prompt initial-input history)
-  "Read a natural number (excluding zero) and return it as a string."
-  (transient--read-number-N prompt initial-input history nil))
-
-(defun transient--read-number-N (prompt initial-input history include-zero)
-  (save-match-data
-    (cl-block nil
-      (while t
-        (let ((str (read-from-minibuffer prompt initial-input nil nil history)))
-          (cond ((string-equal str "")
-                 (cl-return nil))
-                ((string-match-p (if include-zero
-                                     "\\`\\(0\\|[1-9][0-9]*\\)\\'"
-                                   "\\`[1-9][0-9]*\\'")
-                                 str)
-                 (cl-return str))))
-        (message "Please enter a natural number (%s zero)."
-                 (if include-zero "including" "excluding"))
-        (sit-for 1)))))
-
-(defun transient-read-date (prompt default-time _history)
-  "Read a date using `org-read-date' (which see)."
-  (require 'org)
-  (when (fboundp 'org-read-date)
-    (org-read-date 'with-time nil nil prompt default-time)))
-
-;;;; Prompt
-
-(cl-defgeneric transient-prompt (obj)
-  "Return the prompt to be used to read infix object OBJ's value.")
-
-(cl-defmethod transient-prompt ((obj transient-infix))
-  "Return the prompt to be used to read infix object OBJ's value.
-
-This implementation should be suitable for almost all infix
-commands.
-
-If the value of OBJ's `prompt' slot is non-nil, then it must be
-a string or a function.  If it is a string, then use that.  If
-it is a function, then call that with OBJ as the only argument.
-That function must return a string, which is then used as the
-prompt.
-
-Otherwise, if the value of either the `argument' or `variable'
-slot of OBJ is a string, then base the prompt on that (prefering
-the former), appending either \"=\" (if it appears to be a
-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: no prompt): "))
-    (or (when-let ((arg (and (slot-boundp obj 'argument) (oref obj argument))))
-          (if (and (stringp arg) (string-suffix-p "=" arg))
-              arg
-            (concat arg ": ")))
-        (when-let ((var (and (slot-boundp obj 'variable) (oref obj variable))))
-          (and (stringp var)
-               (concat var ": ")))
-        "(BUG: no prompt): ")))
-
-;;;; Set
-
-(defvar transient--unset-incompatible t)
-
-(cl-defgeneric transient-infix-set (obj value)
-  "Set the value of infix object OBJ to value.")
-
-(cl-defmethod transient-infix-set ((obj transient-infix) value)
-  "Set the value of infix object OBJ to value.
-
-This implementation should be suitable for almost all infix
-commands."
-  (oset obj value value))
-
-(cl-defmethod transient-infix-set :around ((obj transient-argument) value)
-  "Unset incompatible infix arguments."
-  (let ((arg (if (slot-boundp obj 'argument)
-                 (oref obj argument)
-               (oref obj argument-regexp))))
-    (if-let ((sic (and value arg transient--unset-incompatible))
-             (spec (oref transient--prefix incompatible))
-             (incomp (remove arg (cl-find-if (lambda (elt) (member arg elt)) spec))))
-        (progn
-          (cl-call-next-method obj value)
-          (dolist (arg incomp)
-            (when-let ((obj (cl-find-if (lambda (obj)
-                                          (and (slot-boundp obj 'argument)
-                                               (equal (oref obj argument) arg)))
-                                        transient--suffixes)))
-              (let ((transient--unset-incompatible nil))
-                (transient-infix-set obj nil)))))
-      (cl-call-next-method obj value))))
-
-(cl-defmethod transient-set-value ((obj transient-prefix))
-  (oset (oref obj prototype) value (transient-get-value))
-  (transient--history-push obj))
-
-;;;; Save
-
-(cl-defmethod transient-save-value ((obj transient-prefix))
-  (let ((value (transient-get-value)))
-    (oset (oref obj prototype) value value)
-    (setf (alist-get (oref obj command) transient-values) value)
-    (transient-save-values))
-  (transient--history-push obj))
-
-;;;; Get
-
-(defun transient-args (prefix)
-  "Return the value of the transient prefix command PREFIX.
-If the current command was invoked from the transient prefix
-command PREFIX, then return the active infix arguments.  If
-the current command was not invoked from PREFIX, then return
-the set, saved or default value for PREFIX."
-  (if (eq current-transient-command prefix)
-      (delq nil (mapcar 'transient-infix-value current-transient-suffixes))
-    (let ((transient--prefix nil)
-          (transient--layout nil)
-          (transient--suffixes nil))
-      (transient--init-objects prefix nil nil)
-      (delq nil (mapcar 'transient-infix-value transient--suffixes)))))
-
-(defun transient-get-value ()
-  (delq nil (mapcar 'transient-infix-value current-transient-suffixes)))
-
-(cl-defgeneric transient-infix-value (obj)
-  "Return the value of the suffix object OBJ.
-
-This function is called by `transient-args' (which see), meaning
-this function is how the value of a transient is determined so
-that the invoked suffix command can use it.
-
-Currently most values are strings, but that is not set in stone.
-Nil is not a value, it means \"no value\".
-
-Usually only infixes have a value, but see the method for
-`transient-suffix'.")
-
-(cl-defmethod transient-infix-value ((_   transient-suffix))
-  "Return nil, which means \"no value\".
-
-Infix arguments contribute the the transient's value while suffix
-commands consume it.  This function is called for suffixes anyway
-because a command that both contributes to the transient's value
-and also consumes it is not completely unconceivable.
-
-If you define such a command, then you must define a derived
-class and implement this function because this default method
-does nothing." nil)
-
-(cl-defmethod transient-infix-value ((obj transient-infix))
-  "Return the value of OBJ's `value' slot."
-  (oref obj value))
-
-(cl-defmethod transient-infix-value ((obj transient-option))
-  "Return (concat ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil.  VALUE may be the empty string,
-which is not the same as nil."
-  (when-let ((value (oref obj value)))
-    (concat (oref obj argument) value)))
-
-(cl-defmethod transient-infix-value ((_   transient-variable))
-  "Return nil, which means \"no value\".
-
-Setting the value of a variable is done by, well, setting the
-value of the variable.  I.e. this is a side-effect and does not
-contribute to the value of the transient."
-  nil)
-
-(cl-defmethod transient-infix-value ((obj transient-files))
-  "Return (concat ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil.  VALUE may be the empty string,
-which is not the same as nil."
-  (when-let ((value (oref obj value)))
-    (cons (oref obj argument) value)))
-
-;;; History
-
-(cl-defgeneric transient--history-key (obj)
-  "Return OBJ's history key.
-If the value of the `history-key' slot is non-nil, then return
-that.  Otherwise return the value of the `command' slot."
-  (or (oref obj history-key)
-      (oref obj command)))
-
-(cl-defgeneric transient--history-push (obj)
-  "Push the current value of OBJ to its entry in `transient-history'."
-  (let ((key (transient--history-key obj)))
-    (setf (alist-get key transient-history)
-          (let ((args (transient-get-value)))
-            (cons args (delete args (alist-get key transient-history)))))))
-
-(cl-defgeneric transient--history-init (obj)
-  "Initialize OBJ's `history' slot.
-This is the transient-wide history; many individual infixes also
-have a history of their own.")
-
-(cl-defmethod transient--history-init ((obj transient-prefix))
-  "Initialize OBJ's `history' slot from the variable `transient-history'."
-  (let ((val (oref obj value)))
-    (oset obj history
-          (cons val (delete val (alist-get (transient--history-key obj)
-                                           transient-history))))))
-
-;;; Draw
-
-(defun transient--show-brief ()
-  (let ((message-log-max nil))
-    (if (and transient-show-popup (<= transient-show-popup 0))
-        (message "%s-" (key-description (this-command-keys)))
-      (message
-       "%s- [%s] %s"
-       (key-description (this-command-keys))
-       (oref transient--prefix command)
-       (mapconcat
-        #'identity
-        (sort
-         (cl-mapcan
-          (lambda (suffix)
-            (let ((key (kbd (oref suffix key))))
-              ;; Don't list any common commands.
-              (and (not (memq (oref suffix command)
-                              `(,(lookup-key transient-map key)
-                                ,(lookup-key transient-sticky-map key)
-                                ;; From transient-common-commands:
-                                transient-set
-                                transient-save
-                                transient-history-prev
-                                transient-history-next
-                                transient-quit-one
-                                transient-toggle-common
-                                transient-set-level)))
-                   (list (propertize (oref suffix key) 'face 'transient-key)))))
-          transient--suffixes)
-         #'string<)
-        (propertize "|" 'face 'transient-unreachable-key))))))
-
-(defun transient--show ()
-  (transient--timer-cancel)
-  (setq transient--showp t)
-  (let ((buf (get-buffer-create transient--buffer-name))
-        (focus nil))
-    (unless (window-live-p transient--window)
-      (setq transient--window
-            (display-buffer buf transient-display-buffer-action)))
-    (with-selected-window transient--window
-      (when transient-enable-popup-navigation
-        (setq focus (button-get (point) 'command)))
-      (erase-buffer)
-      (set-window-hscroll transient--window 0)
-      (set-window-dedicated-p transient--window t)
-      (set-window-parameter transient--window 'no-other-window t)
-      (setq window-size-fixed t)
-      (when (bound-and-true-p tab-line-format)
-        (setq tab-line-format nil))
-      (setq mode-line-format (if (eq transient-mode-line-format 'line)
-                                 nil
-                               transient-mode-line-format))
-      (setq mode-line-buffer-identification
-            (symbol-name (oref transient--prefix command)))
-      (if transient-enable-popup-navigation
-          (setq-local cursor-in-non-selected-windows 'box)
-        (setq cursor-type nil))
-      (setq display-line-numbers nil)
-      (setq show-trailing-whitespace nil)
-      (transient--insert-groups)
-      (when (or transient--helpp transient--editp)
-        (transient--insert-help))
-      (when (eq transient-mode-line-format 'line)
-        (insert (propertize "__" 'face 'transient-separator
-                            'display '(space :height (1))))
-        (insert (propertize "\n" 'face 'transient-separator 'line-height t)))
-      (let ((window-resize-pixelwise t)
-            (window-size-fixed nil))
-        (fit-window-to-buffer nil nil 1))
-      (goto-char (point-min))
-      (when transient-enable-popup-navigation
-        (transient--goto-button focus)))))
-
-(defun transient--insert-groups ()
-  (let ((groups (cl-mapcan (lambda (group)
-                             (let ((hide (oref group hide)))
-                               (and (not (and (functionp hide)
-                                              (funcall   hide)))
-                                    (list group))))
-                           transient--layout))
-        group)
-    (while (setq group (pop groups))
-      (transient--insert-group group)
-      (when groups
-        (insert ?\n)))))
-
-(cl-defgeneric transient--insert-group (group)
-  "Format GROUP and its elements and insert the result.")
-
-(cl-defmethod transient--insert-group :before ((group transient-group))
-  "Insert GROUP's description, if any."
-  (when-let ((desc (transient-format-description group)))
-    (insert desc ?\n)))
-
-(cl-defmethod transient--insert-group ((group transient-row))
-  (dolist (suffix (oref group suffixes))
-    (insert (transient-format suffix))
-    (insert "   "))
-  (insert ?\n))
-
-(cl-defmethod transient--insert-group ((group transient-column))
-  (dolist (suffix (oref group suffixes))
-    (let ((str (transient-format suffix)))
-      (insert str)
-      (unless (string-match-p ".\n\\'" str)
-        (insert ?\n)))))
-
-(cl-defmethod transient--insert-group ((group transient-columns))
-  (let* ((columns
-          (mapcar
-           (lambda (column)
-             (let ((rows (mapcar 'transient-format (oref column suffixes))))
-               (when-let ((desc (transient-format-description column)))
-                 (push desc rows))
-               rows))
-           (oref group suffixes)))
-         (rs (apply #'max (mapcar #'length columns)))
-         (cs (length columns))
-         (cw (--map (apply #'max (mapcar #'length it)) columns))
-         (cc (-reductions-from (apply-partially #'+ 3) 0 cw)))
-    (dotimes (r rs)
-      (dotimes (c cs)
-        (insert (make-string (- (nth c cc) (current-column)) ?\s))
-        (when-let ((cell (nth r (nth c columns))))
-          (insert cell))
-        (when (= c (1- cs))
-          (insert ?\n))))))
-
-(cl-defmethod transient--insert-group ((group transient-subgroups))
-  (let* ((subgroups (oref group suffixes))
-         (n (length subgroups)))
-    (dotimes (s n)
-      (transient--insert-group (nth s subgroups))
-      (when (< s (1- n))
-        (insert ?\n)))))
-
-(cl-defgeneric transient-format (obj)
-  "Format and return OBJ for display.
-
-When this function is called, then the current buffer is some
-temporary buffer.  If you need the buffer from which the prefix
-command was invoked to be current, then do so by temporarily
-making `transient--original-buffer' current.")
-
-(cl-defmethod transient-format ((arg string))
-  "Return the string ARG after applying the `transient-heading' face."
-  (propertize arg 'face 'transient-heading))
-
-(cl-defmethod transient-format ((_   null))
-  "Return a string containing just the newline character."
-  "\n")
-
-(cl-defmethod transient-format ((arg integer))
-  "Return a string containing just the ARG character."
-  (char-to-string arg))
-
-(cl-defmethod transient-format :around ((obj transient-infix))
-  "When reading user input for this infix, then highlight it."
-  (let ((str (cl-call-next-method obj)))
-    (when (eq obj transient--active-infix)
-      (setq str (concat str "\n"))
-      (add-face-text-property 0 (length str)
-                              'transient-active-infix nil str))
-    str))
-
-(cl-defmethod transient-format :around ((obj transient-suffix))
-  "When edit-mode is enabled, then prepend the level information.
-Optional support for popup buttons is also implemented here."
-  (let ((str (concat
-              (and transient--editp
-                   (let ((level (oref obj level)))
-                     (propertize (format " %s " level)
-                                 'face (if (transient--use-level-p level t)
-                                           'transient-enabled-suffix
-                                         'transient-disabled-suffix))))
-              (cl-call-next-method obj))))
-    (if transient-enable-popup-navigation
-        (make-text-button str nil
-                          'type 'transient-button
-                          'command (transient--suffix-command obj))
-      str)))
-
-(cl-defmethod transient-format ((obj transient-infix))
-  "Return a string generated using OBJ's `format'.
-%k is formatted using `transient-format-key'.
-%d is formatted using `transient-format-description'.
-%f is formatted using `transient-format-value'."
-  (format-spec (oref obj format)
-               `((?k . ,(transient-format-key obj))
-                 (?d . ,(transient-format-description obj))
-                 (?v . ,(transient-format-value obj)))))
-
-(cl-defmethod transient-format ((obj transient-suffix))
-  "Return a string generated using OBJ's `format'.
-%k is formatted using `transient-format-key'.
-%d is formatted using `transient-format-description'."
-  (format-spec (oref obj format)
-               `((?k . ,(transient-format-key obj))
-                 (?d . ,(transient-format-description obj)))))
-
-(cl-defgeneric transient-format-key (obj)
-  "Format OBJ's `key' for display and return the result.")
-
-(cl-defmethod transient-format-key ((obj transient-suffix))
-  "Format OBJ's `key' for display and return the result."
-  (let ((key (oref obj key)))
-    (if transient--redisplay-key
-        (let ((len (length transient--redisplay-key))
-              (seq (cl-coerce (edmacro-parse-keys key t) 'list)))
-          (cond
-           ((equal (-take len seq) transient--redisplay-key)
-            (let ((pre (key-description (vconcat (-take len seq))))
-                  (suf (key-description (vconcat (-drop len seq)))))
-              (setq pre (replace-regexp-in-string "RET" "C-m" pre t))
-              (setq pre (replace-regexp-in-string "TAB" "C-i" pre t))
-              (setq suf (replace-regexp-in-string "RET" "C-m" suf t))
-              (setq suf (replace-regexp-in-string "TAB" "C-i" suf t))
-              ;; We use e.g. "-k" instead of the more correct "- k",
-              ;; because the former is prettier.  If we did that in
-              ;; the definition, then we want to drop the space that
-              ;; is reinserted above.  False-positives are possible
-              ;; for silly bindings like "-C-c C-c".
-              (unless (string-match-p " " key)
-                (setq pre (replace-regexp-in-string " " "" pre))
-                (setq suf (replace-regexp-in-string " " "" suf)))
-              (concat (propertize pre 'face 'default)
-                      (and (string-prefix-p (concat pre " ") key) " ")
-                      (propertize suf 'face 'transient-key)
-                      (save-excursion
-                        (when (string-match " +\\'" key)
-                          (match-string 0 key))))))
-           ((transient--lookup-key transient-sticky-map (kbd key))
-            (propertize key 'face 'transient-key))
-           (t
-            (propertize key 'face 'transient-unreachable-key))))
-      (propertize key 'face 'transient-key))))
-
-(cl-defmethod transient-format-key :around ((obj transient-argument))
-  (let ((key (cl-call-next-method obj)))
-    (cond ((not transient-highlight-mismatched-keys))
-          ((not (slot-boundp obj 'shortarg))
-           (add-face-text-property
-            0 (length key) 'transient-nonstandard-key nil key))
-          ((not (string-equal key (oref obj shortarg)))
-           (add-face-text-property
-            0 (length key) 'transient-mismatched-key nil key)))
-    key))
-
-(cl-defgeneric transient-format-description (obj)
-  "Format OBJ's `description' for display and return the result.")
-
-(cl-defmethod transient-format-description ((obj transient-child))
-  "The `description' slot may be a function, in which case that is
-called inside the correct buffer (see `transient-insert-group')
-and its value is returned to the caller."
-  (when-let ((desc (oref obj description)))
-    (if (functionp desc)
-        (with-current-buffer transient--original-buffer
-          (funcall desc))
-      desc)))
-
-(cl-defmethod transient-format-description ((obj transient-group))
-  "Format the description by calling the next method.  If the result
-doesn't use the `face' property at all, then apply the face
-`transient-heading' to the complete string."
-  (when-let ((desc (cl-call-next-method obj)))
-    (if (text-property-not-all 0 (length desc) 'face nil desc)
-        desc
-      (propertize desc 'face 'transient-heading))))
-
-(cl-defmethod transient-format-description :around ((obj transient-suffix))
-  "Format the description by calling the next method.  If the result
-is nil, then use \"(BUG: no description)\" as the description.
-If the OBJ's `key' is currently unreachable, then apply the face
-`transient-unreachable' to the complete string."
-  (let ((desc (or (cl-call-next-method obj)
-                  (propertize "(BUG: no description)" 'face 'error))))
-    (if (transient--key-unreachable-p obj)
-        (propertize desc 'face 'transient-unreachable)
-      desc)))
-
-(cl-defgeneric transient-format-value (obj)
-  "Format OBJ's value for display and return the result.")
-
-(cl-defmethod transient-format-value ((obj transient-suffix))
-  (propertize (oref obj argument)
-              'face (if (oref obj value)
-                        'transient-argument
-                      'transient-inactive-argument)))
-
-(cl-defmethod transient-format-value ((obj transient-option))
-  (let ((value (oref obj value)))
-    (propertize (concat (oref obj argument) value)
-                'face (if value
-                          'transient-value
-                        'transient-inactive-value))))
-
-(cl-defmethod transient-format-value ((obj transient-switches))
-  (with-slots (value argument-format choices) obj
-    (format (propertize argument-format
-                        'face (if value
-                                  'transient-value
-                                'transient-inactive-value))
-            (concat
-             (propertize "[" 'face 'transient-inactive-value)
-             (mapconcat
-              (lambda (choice)
-                (propertize choice 'face
-                            (if (equal (format argument-format choice) value)
-                                'transient-value
-                              'transient-inactive-value)))
-              choices
-              (propertize "|" 'face 'transient-inactive-value))
-             (propertize "]" 'face 'transient-inactive-value)))))
-
-(cl-defmethod transient-format-value ((obj transient-files))
-  (let ((argument (oref obj argument)))
-    (if-let ((value (oref obj value)))
-        (propertize (concat argument " "
-                            (mapconcat (lambda (f) (format "%S" f))
-                                       (oref obj value) " "))
-                    'face 'transient-argument)
-    (propertize argument 'face 'transient-inactive-argument))))
-
-(defun transient--key-unreachable-p (obj)
-  (and transient--redisplay-key
-       (let ((key (oref obj key)))
-         (not (or (equal (-take (length transient--redisplay-key)
-                                (cl-coerce (edmacro-parse-keys key t) 'list))
-                         transient--redisplay-key)
-                  (transient--lookup-key transient-sticky-map (kbd key)))))))
-
-(defun transient--lookup-key (keymap key)
-  (let ((val (lookup-key keymap key)))
-    (and val (not (integerp val)) val)))
-
-;;; Help
-
-(cl-defgeneric transient-show-help (obj)
-  "Show help for OBJ's command.")
-
-(cl-defmethod transient-show-help ((obj transient-prefix))
-  "Show the info manual, manpage or command doc-string.
-Show the first one that is specified."
-  (if-let ((manual (oref obj info-manual)))
-      (info manual)
-    (if-let ((manpage (oref obj man-page)))
-        (transient--show-manpage manpage)
-      (transient--describe-function (oref obj command)))))
-
-(cl-defmethod transient-show-help ((_   transient-suffix))
-  "Show the command doc-string."
-  (if (eq this-original-command 'transient-help)
-      (if-let ((manpage (oref transient--prefix man-page)))
-          (transient--show-manpage manpage)
-        (transient--describe-function (oref transient--prefix command)))
-    (transient--describe-function this-original-command)))
-
-(cl-defmethod transient-show-help ((obj transient-infix))
-  "Show the manpage if defined or the command doc-string.
-If the manpage is specified, then try to jump to the correct
-location."
-  (if-let ((manpage (oref transient--prefix man-page)))
-      (transient--show-manpage manpage (ignore-errors (oref obj argument)))
-    (transient--describe-function this-original-command)))
-
-;; `cl-generic-generalizers' doesn't support `command' et al.
-(cl-defmethod transient-show-help (cmd)
-  "Show the command doc-string."
-  (transient--describe-function cmd))
-
-(defun transient--show-manpage (manpage &optional argument)
-  (require 'man)
-  (let* ((Man-notify-method 'meek)
-         (buf (Man-getpage-in-background manpage))
-         (proc (get-buffer-process buf)))
-    (while (and proc (eq (process-status proc) 'run))
-      (accept-process-output proc))
-    (switch-to-buffer buf)
-    (when argument
-      (transient--goto-argument-description argument))))
-
-(defun transient--describe-function (fn)
-  (describe-function fn)
-  (select-window (get-buffer-window (help-buffer))))
-
-(defun transient--goto-argument-description (arg)
-  (goto-char (point-min))
-  (let ((case-fold-search nil)
-        ;; This matches preceding/proceeding options.  Options
-        ;; such as "-a", "-S[<keyid>]", and "--grep=<pattern>"
-        ;; are matched by this regex without the shy group.
-        ;; The ". " in the shy group is for options such as
-        ;; "-m parent-number", and the "-[^[:space:]]+ " is
-        ;; for options such as "--mainline parent-number"
-        (others "-\\(?:. \\|-[^[:space:]]+ \\)?[^[:space:]]+"))
-    (when (re-search-forward
-           (if (equal arg "--")
-               ;; Special case.
-               "^[\t\s]+\\(--\\(?: \\|$\\)\\|\\[--\\]\\)"
-             ;; Should start with whitespace and may have
-             ;; any number of options before and/or after.
-             (format
-              "^[\t\s]+\\(?:%s, \\)*?\\(?1:%s\\)%s\\(?:, %s\\)*$"
-              others
-              ;; Options don't necessarily end in an "="
-              ;; (e.g., "--gpg-sign[=<keyid>]")
-              (string-remove-suffix "=" arg)
-              ;; Simple options don't end in an "=".  Splitting this
-              ;; into 2 cases should make getting false positives
-              ;; less likely.
-              (if (string-suffix-p "=" arg)
-                  ;; "[^[:space:]]*[^.[:space:]]" matches the option
-                  ;; value, which is usually after the option name
-                  ;; and either '=' or '[='.  The value can't end in
-                  ;; a period, as that means it's being used at the
-                  ;; end of a sentence.  The space is for options
-                  ;; such as '--mainline parent-number'.
-                  "\\(?: \\|\\[?=\\)[^[:space:]]*[^.[:space:]]"
-                ;; Either this doesn't match anything (e.g., "-a"),
-                ;; or the option is followed by a value delimited
-                ;; by a "[", "<", or ":".  A space might appear
-                ;; before this value, as in "-f <file>".  The
-                ;; space alternative is for options such as
-                ;; "-m parent-number".
-                "\\(?:\\(?: \\| ?[\\[<:]\\)[^[:space:]]*[^.[:space:]]\\)?")
-              others))
-           nil t)
-      (goto-char (match-beginning 1)))))
-
-(defun transient--insert-help ()
-  (unless (looking-back "\n\n" 2)
-    (insert "\n"))
-  (when transient--helpp
-    (insert
-     (format (propertize "\
-Type a %s to show help for that suffix command, or %s to show manual.
-Type %s to exit help.\n"
-                         'face 'transient-heading)
-             (propertize "<KEY>" 'face 'transient-key)
-             (propertize "?"     'face 'transient-key)
-             (propertize "C-g"   'face 'transient-key))))
-  (when transient--editp
-    (unless transient--helpp
-      (insert
-       (format (propertize "\
-Type a %s to set level for that suffix command.
-Type %s to set what levels are available for this prefix command.\n"
-                           'face 'transient-heading)
-               (propertize "<KEY>"   'face 'transient-key)
-               (propertize "C-x l" 'face 'transient-key))))
-    (with-slots (level) transient--prefix
-      (insert
-       (format (propertize "
-Suffixes on levels %s are available.
-Suffixes on levels %s and %s are unavailable.\n"
-                           'face 'transient-heading)
-               (propertize (format "1-%s" level)
-                           'face 'transient-enabled-suffix)
-               (propertize " 0 "
-                           'face 'transient-disabled-suffix)
-               (propertize (format ">=%s" (1+ level))
-                           'face 'transient-disabled-suffix))))))
-
-(defvar transient-resume-mode-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map [remap Man-quit]    'transient-resume)
-    (define-key map [remap Info-exit]   'transient-resume)
-    (define-key map [remap quit-window] 'transient-resume)
-    map)
-  "Keymap for `transient-resume-mode'.
-
-This keymap remaps every command that would usually just quit the
-documentation buffer to `transient-resume', which additionally
-resumes the suspended transient.")
-
-(define-minor-mode transient-resume-mode
-  "Auxiliary minor-mode used to resume a transient after viewing help.")
-
-;;; Compatibility
-;;;; Popup Navigation
-
-(defun transient-popup-navigation-help ()
-  "Inform the user how to enable popup navigation commands."
-  (interactive)
-  (message "This command is only available if `%s' is non-nil"
-           'transient-enable-popup-navigation))
-
-(define-button-type 'transient-button
-  'face nil
-  'action (lambda (button)
-            (let ((command (button-get button 'command)))
-              ;; Yes, I know that this is wrong(tm).
-              ;; Unfortunately it is also necessary.
-              (setq this-original-command command)
-              (call-interactively command))))
-
-(defvar transient-popup-navigation-map
-  (let ((map (make-sparse-keymap)))
-    (define-key map (kbd "<down-mouse-1>") 'transient-noop)
-    (define-key map (kbd "<mouse-1>") 'transient-mouse-push-button)
-    (define-key map (kbd "RET")       'transient-push-button)
-    (define-key map (kbd "<up>")      'transient-backward-button)
-    (define-key map (kbd "C-p")       'transient-backward-button)
-    (define-key map (kbd "<down>")    'transient-forward-button)
-    (define-key map (kbd "C-n")       'transient-forward-button)
-    (define-key map (kbd "C-r")       'transient-isearch-backward)
-    (define-key map (kbd "C-s")       'transient-isearch-forward)
-    map))
-
-(defun transient-mouse-push-button (&optional pos)
-  "Invoke the suffix the user clicks on."
-  (interactive (list last-command-event))
-  (push-button pos))
-
-(defun transient-push-button ()
-  "Invoke the selected suffix command."
-  (interactive)
-  (with-selected-window transient--window
-    (push-button)))
-
-(defun transient-backward-button (n)
-  "Move to the previous button in the transient popup buffer.
-See `backward-button' for information about N."
-  (interactive "p")
-  (with-selected-window transient--window
-    (backward-button n t)))
-
-(defun transient-forward-button (n)
-  "Move to the next button in the transient popup buffer.
-See `forward-button' for information about N."
-  (interactive "p")
-  (with-selected-window transient--window
-    (forward-button n t)))
-
-(defun transient--goto-button (command)
-  (if (not command)
-      (forward-button 1)
-    (while (and (ignore-errors (forward-button 1))
-                (not (eq (button-get (button-at (point)) 'command) command))))
-    (unless (eq (button-get (button-at (point)) 'command) command)
-      (goto-char (point-min))
-      (forward-button 1))))
-
-;;;; Popup Isearch
-
-(defvar transient--isearch-mode-map
-  (let ((map (make-sparse-keymap)))
-    (set-keymap-parent map isearch-mode-map)
-    (define-key map [remap isearch-exit]   'transient-isearch-exit)
-    (define-key map [remap isearch-cancel] 'transient-isearch-cancel)
-    (define-key map [remap isearch-abort]  'transient-isearch-abort)
-    map))
-
-(defun transient-isearch-backward (&optional regexp-p)
-  "Do incremental search backward.
-With a prefix argument, do an incremental regular expression
-search instead."
-  (interactive "P")
-  (transient--isearch-setup)
-  (let ((isearch-mode-map transient--isearch-mode-map))
-    (isearch-mode nil regexp-p)))
-
-(defun transient-isearch-forward (&optional regexp-p)
-  "Do incremental search forward.
-With a prefix argument, do an incremental regular expression
-search instead."
-  (interactive "P")
-  (transient--isearch-setup)
-  (let ((isearch-mode-map transient--isearch-mode-map))
-    (isearch-mode t regexp-p)))
-
-(defun transient-isearch-exit ()
-  "Like `isearch-exit' but adapted for `transient'."
-  (interactive)
-  (isearch-exit)
-  (transient--isearch-exit))
-
-(defun transient-isearch-cancel ()
-  "Like `isearch-cancel' but adapted for `transient'."
-  (interactive)
-  (condition-case nil (isearch-cancel) (quit))
-  (transient--isearch-exit))
-
-(defun transient-isearch-abort ()
-  "Like `isearch-abort' but adapted for `transient'."
-  (interactive)
-  (condition-case nil (isearch-abort) (quit))
-  (transient--isearch-exit))
-
-(defun transient--isearch-setup ()
-  (select-window transient--window)
-  (transient--pop-keymap 'transient--transient-map)
-  (transient--pop-keymap 'transient--redisplay-map)
-  (remove-hook 'pre-command-hook #'transient--pre-command)
-  (remove-hook 'post-command-hook #'transient--post-command))
-
-(defun transient--isearch-exit ()
-  (select-window transient--original-window)
-  (transient--push-keymap 'transient--transient-map)
-  (transient--push-keymap 'transient--redisplay-map)
-  (add-hook 'pre-command-hook #'transient--pre-command)
-  (add-hook 'post-command-hook #'transient--post-command))
-
-;;;; Other Packages
-
-(declare-function which-key-mode "which-key" (&optional arg))
-
-(defun transient--suspend-which-key-mode ()
-  (when (bound-and-true-p which-key-mode)
-    (which-key-mode -1)
-    (add-hook 'post-transient-hook 'transient--resume-which-key-mode)))
-
-(defun transient--resume-which-key-mode ()
-  (unless transient--prefix
-    (which-key-mode 1)
-    (remove-hook 'post-transient-hook 'transient--resume-which-key-mode)))
-
-(defun transient-bind-q-to-quit ()
-  "Modify some keymaps to bind \"q\" to the appropriate quit command.
-
-\"C-g\" is the default binding for such commands now, but Transient's
-predecessor Magit-Popup used \"q\" instead.  If you would like to get
-that binding back, then call this function in your init file like so:
-
-  (with-eval-after-load \\='transient
-    (transient-bind-q-to-quit))
-
-Individual transients may already bind \"q\" to something else
-and such a binding would shadow the quit binding.  If that is the
-case then \"Q\" is bound to whatever \"q\" would have been bound
-to by setting `transient-substitute-key-function' to a function
-that does that.  Of course \"Q\" may already be bound to something
-else, so that function binds \"M-q\" to that command instead.
-Of course \"M-q\" may already be bound to something else, but
-we stop there."
-  (define-key transient-base-map   "q" 'transient-quit-one)
-  (define-key transient-sticky-map "q" 'transient-quit-seq)
-  (setq transient-substitute-key-function
-        'transient-rebind-quit-commands))
-
-(defun transient-rebind-quit-commands (obj)
-  "See `transient-bind-q-to-quit'."
-  (let ((key (oref obj key)))
-    (cond ((string-equal key "q") "Q")
-          ((string-equal key "Q") "M-q")
-          (t key))))
-
-;;; Font-Lock
-
-(defconst transient-font-lock-keywords
-  (eval-when-compile
-    `((,(concat "("
-                (regexp-opt (list "define-transient-command"
-                                  "define-infix-command"
-                                  "define-infix-argument"
-                                  "define-suffix-command")
-                            t)
-                "\\_>[ \t'\(]*"
-                "\\(\\(?:\\sw\\|\\s_\\)+\\)?")
-       (1 'font-lock-keyword-face)
-       (2 'font-lock-function-name-face nil t)))))
-
-(font-lock-add-keywords 'emacs-lisp-mode transient-font-lock-keywords)
-
-;;; _
-(provide 'transient)
-;; Local Variables:
-;; indent-tabs-mode: nil
-;; End:
-;;; transient.el ends here
diff --git a/elpa/transient-20191017.1115/transient.info b/elpa/transient-20191017.1115/transient.info
deleted file mode 100644 (file)
index 522975c..0000000
+++ /dev/null
@@ -1,2431 +0,0 @@
-This is transient.info, produced by makeinfo version 6.5 from
-transient.texi.
-
-     Copyright (C) 2018-2019 Jonas Bernoulli <jonasNOSPAMbernoul.li>
-
-     You can redistribute this document and/or modify it under the terms
-     of the GNU General Public License as published by the Free Software
-     Foundation, either version 3 of the License, or (at your option)
-     any later version.
-
-     This document is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Transient: (transient). Transient Commands.
-END-INFO-DIR-ENTRY
-
-\1f
-File: transient.info,  Node: Top,  Next: Introduction,  Up: (dir)
-
-Transient User and Developer Manual
-***********************************
-
-Taking inspiration from prefix keys and prefix arguments, Transient
-implements a similar abstraction involving a prefix command, infix
-arguments and suffix commands.  We could call this abstraction a
-"transient command", but because it always involves at least two
-commands (a prefix and a suffix) we prefer to call it just a
-"transient".
-
-   When the user calls a transient prefix command, then a transient
-(temporary) keymap is activated, which binds the transient’s infix and
-suffix commands, and functions that control the transient state are
-added to ‘pre-command-hook’ and ‘post-command-hook’.  The available
-suffix and infix commands and their state are shown in a popup buffer
-until the transient is exited by invoking a suffix command.
-
-   Calling an infix command causes its value to be changed, possibly by
-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.
-
-This manual is for Transient version 0.1.0 (v0.1.0-106-g0d9a1b5+1).
-
-     Copyright (C) 2018-2019 Jonas Bernoulli <jonasNOSPAMbernoul.li>
-
-     You can redistribute this document and/or modify it under the terms
-     of the GNU General Public License as published by the Free Software
-     Foundation, either version 3 of the License, or (at your option)
-     any later version.
-
-     This document is distributed in the hope that it will be useful,
-     but WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-* Menu:
-
-* Introduction::
-* Usage::
-* Other Options::
-* Modifying Existing Transients::
-* Defining New Commands::
-* Classes and Methods::
-* Related Abstractions and Packages::
-* FAQ::
-* Keystroke Index::
-* Command Index::
-* Function Index::
-* Variable Index::
-
-— The Detailed Node Listing —
-
-Usage
-
-* Invoking Transients::
-* Aborting and Resuming Transients::
-* Common Suffix Commands::
-* Saving Values::
-* Using History::
-* Getting Help for Suffix Commands::
-* Enabling and Disabling Suffixes::
-* Other Commands::
-
-Defining New Commands
-
-* Defining Transients::
-* Binding Suffix and Infix Commands::
-* Defining Suffix and Infix Commands::
-* Using Infix Arguments::
-* Transient State::
-
-Binding Suffix and Infix Commands
-
-* Group Specifications::
-* Suffix Specifications::
-
-
-Classes and Methods
-
-* Group Classes::
-* Group Methods::
-* Prefix Classes::
-* Suffix Classes::
-* Suffix Methods::
-* Prefix Slots::
-* Suffix Slots::
-* Predicate Slots::
-
-Suffix Methods
-
-* Suffix Value Methods::
-* Suffix Format Methods::
-
-
-Related Abstractions and Packages
-
-* Comparison With Prefix Keys and Prefix Arguments::
-* Comparison With Other Packages::
-
-
-\1f
-File: transient.info,  Node: Introduction,  Next: Usage,  Prev: Top,  Up: Top
-
-1 Introduction
-**************
-
-Taking inspiration from prefix keys and prefix arguments, Transient
-implements a similar abstraction involving a prefix command, infix
-arguments and suffix commands.  We could call this abstraction a
-"transient command", but because it always involves at least two
-commands (a prefix and a suffix) we prefer to call it just a
-"transient".
-
-     Transient keymaps are a feature provided by Emacs.  Transients as
-     implemented by this package involve the use of transient keymaps.
-
-     Emacs provides a feature that it calls "prefix commands".  When we
-     talk about "prefix commands" in this manual, then we mean our own
-     kind of "prefix commands", unless specified otherwise.  To avoid
-     ambiguity we sometimes use the terms "transient prefix command" for
-     our kind and "regular prefix command" for Emacs’ kind.
-
-   When the user calls a transient prefix command, then a transient
-(temporary) keymap is activated, which binds the transient’s infix and
-suffix commands, and functions that control the transient state are
-added to ‘pre-command-hook’ and ‘post-command-hook’.  The available
-suffix and infix commands and their state are shown in a popup buffer
-until the transient state is exited by invoking a suffix command.
-
-   Calling an infix command causes its value to be changed.  How that is
-done depends on the type of the infix command.  The simplest case is an
-infix command that represents a command-line argument that does not take
-a value.  Invoking such an infix command causes the switch to be toggled
-on or off.  More complex infix commands may read a value from the user,
-using the minibuffer.
-
-   Calling a suffix command usually causes the transient to be exited;
-the transient keymaps and hook functions are removed, the popup buffer
-no longer shows information about the (no longer bound) suffix commands,
-the values of some public global variables are set, while some internal
-global variables are unset, and finally the command is actually called.
-Suffix commands can also be configured to not exit the transient.
-
-   A suffix command can, but does not have to, use the infix arguments
-in much the same way it can choose to use or ignore the prefix
-arguments.  For a suffix command that was invoked from a transient the
-variable ‘current-transient-suffixes’ and the function ‘transient-args’
-serve about the same purpose as the variables ‘prefix-arg’ and
-‘current-prefix-arg’ do for any command that was called after the prefix
-arguments have been set using a command such as ‘universal-argument’.
-
-   The information shown in the popup buffer while a transient is active
-looks a bit like this:
-
-     ,-----------------------------------------
-     |Arguments
-     | -f Force (--force)
-     | -a Annotate (--annotate)
-     |
-     |Create
-     | t tag
-     | r telease
-     `-----------------------------------------
-
-     This is a simplified version of ‘magit-tag’.  Info manuals do not
-     support images or colored text, so the above "screenshot" lacks
-     some information; in practice you would be able to tell whether the
-     arguments ‘--force’ and ‘--annotate’ are enabled or not based on
-     their color.
-
-   Transient can be used to implement simple "command dispatchers".  The
-main benefit then is that the user can see all the available commands in
-a popup buffer.  That is useful by itself because it frees the user from
-having to remember all the keys that are valid after a certain prefix
-key or command.  Magit’s ‘magit-dispatch’ command is an example of using
-Transient to merely implement a command dispatcher.
-
-   In addition to that, Transient also allows users to interactively
-pass arguments to commands.  These arguments can be much more complex
-than what is reasonable when using prefix arguments.  There is a limit
-to how many aspects of a command can be controlled using prefix
-arguments.  Furthermore what a certain prefix argument means for
-different commands can be completely different, and users have to read
-documentation to learn and then commit to memory what a certain prefix
-argument means to a certain command.
-
-   Transient suffix commands on the other hand can accept dozens of
-different arguments without the user having to remember anything.  When
-using Transient, then one can call a command with arguments that are
-just as complex as when calling the same function non-interactively
-using code.
-
-   Invoking a transient command with arguments is similar to invoking a
-command in a shell with command-line completion and history 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.  See *note
-Using History::.
-
-   After a transient prefix command is invoked ‘C-h <key>’ can be used
-to show the documentation for the infix or suffix command that ‘<key>’
-is bound to (see *note Getting Help for Suffix Commands::) and infixes
-and suffixes can be removed from the transient using ‘C-x l <key>’.
-Infixes and suffixes that are disabled by default can be enabled the
-same way.  See *note 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
-has different needs than a command that merely toggles a boolean flag.
-Additionally Transient provides abstractions for defining new types,
-which the author of Transient did not anticipate (or didn’t get around
-to implementing yet).
-
-\1f
-File: transient.info,  Node: Usage,  Next: Other Options,  Prev: Introduction,  Up: Top
-
-2 Usage
-*******
-
-* Menu:
-
-* Invoking Transients::
-* Aborting and Resuming Transients::
-* Common Suffix Commands::
-* Saving Values::
-* Using History::
-* Getting Help for Suffix Commands::
-* Enabling and Disabling Suffixes::
-* Other Commands::
-
-\1f
-File: transient.info,  Node: Invoking Transients,  Next: Aborting and Resuming Transients,  Up: Usage
-
-2.1 Invoking Transients
-=======================
-
-A transient prefix command is invoked like any other command by pressing
-the key that is bound to that command.  The main difference to other
-commands is that a transient prefix command activates a transient
-keymap, which temporarily binds the transient’s infix and suffix
-commands.  Bindings from other keymaps may, or may not, be disabled
-while the transient state is in effect.
-
-   There are two kinds of commands that are available after invoking a
-transient prefix command; infix and suffix commands.  Infix commands set
-some value (which is then shown in a popup buffer), without leaving the
-transient.  Suffix commands on the other hand usually quit the transient
-and they may use the values set by the infix commands, i.e.  the infix
-*arguments*.
-
-   Instead of setting arguments to be used by a suffix command, infix
-commands may also set some value by side-effect.
-
-\1f
-File: transient.info,  Node: Aborting and Resuming Transients,  Next: Common Suffix Commands,  Prev: Invoking Transients,  Up: Usage
-
-2.2 Aborting and Resuming Transients
-====================================
-
-To quit the transient without invoking a suffix command press ‘C-g’.
-
-   Key bindings in transient keymaps may be longer than a single event.
-After pressing a valid prefix key, all commands whose bindings do not
-begin with that prefix key are temporarily unavailable and grayed out.
-To abort the prefix key press ‘C-g’ (which in this case only quits the
-prefix key, but not the complete transient).
-
-   A transient prefix command can be bound as a suffix of another
-transient.  Invoking such a suffix replaces the current transient state
-with a new transient state, i.e.  the available bindings change and the
-information displayed in the popup buffer is updated accordingly.
-Pressing ‘C-g’ while a nested transient is active only quits the
-innermost transient, causing a return to the previous transient.
-
-   ‘C-q’ or ‘C-z’ on the other hand always exits all transients.  If you
-use the latter, then you can later resume the stack of transients using
-‘M-x transient-resume’.
-
-‘C-g’     (‘transient-quit-seq’)
-‘C-g’     (‘transient-quit-one’)
-
-     This key quits the currently active incomplete key sequence, if
-     any, or else the current transient.  When quitting the current
-     transient, then it returns to the previous transient, if any.
-
-   Transient’s predecessor bound ‘q’ instead of ‘C-g’ to the quit
-command.  To learn how to get that binding back see
-‘transient-bind-q-to-quit’’s doc string.
-
-‘C-q’     (‘transient-quit-all’)
-
-     This command quits the currently active incomplete key sequence, if
-     any, and all transients, including the active transient and all
-     suspended transients, if any.
-
-‘C-z’     (‘transient-suspend’)
-
-     Like ‘transient-quit-all’, this command quits an incomplete key
-     sequence, if any, and all transients.  Additionally it saves the
-     stack of transients so that it can easily be resumed (which is
-     particularly useful if you quickly need to do "something else" and
-     the stack is deeper than a single transient and/or you have already
-     changed the values of some infix arguments).
-
-     Note that only a single stack of transients can be saved at a time.
-     If another stack is already saved, then saving a new stack discards
-     the previous stack.
-
-‘M-x transient-resume’     (‘transient-resume’)
-
-     This command resumes the previously suspended stack of transients,
-     if any.
-
-\1f
-File: transient.info,  Node: Common Suffix Commands,  Next: Saving Values,  Prev: Aborting and Resuming Transients,  Up: Usage
-
-2.3 Common Suffix Commands
-==========================
-
-A few shared suffix commands are available in all transients.  These
-suffix commands are not shown in the popup buffer by default.
-
-   Most of these commands are bound to ‘C-x <key>’ and after pressing
-‘C-x’ a section featuring all common commands is temporarily shown in
-the popup buffer.  After invoking one of these commands, that section
-disappears again.  Note however that one of these commands is described
-as "Show common permanently"; invoke that if you want the common
-commands to always be shown for all transients.
-
-‘C-x t’     (‘transient-toggle-common’)
-
-     This command toggles whether the generic commands that are common
-     to all transients are always displayed or only after typing the
-     incomplete prefix key sequence ‘C-x’.  This only affects the
-     current Emacs session.
-
- -- User Option: transient-show-common-commands
-
-     This option controls whether shared suffix commands are shown
-     alongside the transient-specific infix and suffix commands.  By
-     default the shared commands are not shown to avoid overwhelming the
-     user with to many options.
-
-     While a transient is active, pressing ‘C-x’ always shows the common
-     command.  The value of this option can be changed for the current
-     Emacs session by typing ‘C-x t’ while a transient is active.
-
-   The other common commands are described in either the previous node
-or in one of the following nodes.
-
-   Some of Transient’s key bindings differ from the respective bindings
-of Magit-Popup; see *note FAQ:: for more information.
-
-\1f
-File: transient.info,  Node: Saving Values,  Next: Using History,  Prev: Common Suffix Commands,  Up: Usage
-
-2.4 Saving Values
-=================
-
-After setting the infix arguments in a transient, the user can save
-those arguments for future invocations.
-
-   Most transients will start out with the saved arguments when they are
-invoked.  There are a few exceptions though.  Some transients are
-designed so that the value that they use is stored externally as the
-buffer-local value of some variable.  Invoking such a transient again
-uses the buffer-local value.  (1)
-
-   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 (see *note Using History::).
-
-‘C-x s’     (‘transient-set’)
-
-     This command saves the value of the active transient for this Emacs
-     session.
-
-‘C-x C-s’     (‘transient-save’)
-
-     Save the value of the active transient persistently across Emacs
-     sessions.
-
- -- User Option: transient-values-file
-
-     This file is used to persist the values of transients between Emacs
-     sessions.
-
-   ---------- Footnotes ----------
-
-   (1) ‘magit-diff’ and ‘magit-log’ are two prominent examples, and
-their handling of buffer-local values is actually a bit more complicated
-than outlined above and even customizable.  This is something I am
-rethinking, but I don’t want to rush any changes.)
-
-\1f
-File: transient.info,  Node: Using History,  Next: Getting Help for Suffix Commands,  Prev: Saving Values,  Up: Usage
-
-2.5 Using History
-=================
-
-Every time the user invokes a suffix command the transient’s current
-value is saved to its history.  These values can be cycled through the
-same way one can cycle through the history of commands that read
-user-input in the minibuffer.
-
-‘M-p’     (‘transient-history-prev’)
-
-     This command switches to the previous value used for the active
-     transient.
-
-‘M-n’     (‘transient-history-next’)
-
-     This command switches to the next value used for the active
-     transient.
-
-   In addition to the transient-wide history, Transient of course
-supports per-infix history.  When an infix reads user-input using the
-minibuffer, then the user can use the regular minibuffer history
-commands to cycle through 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 (see
-*note Suffix Slots::).
-
-   Both kinds of history are saved to a file when Emacs is exited.
-
- -- User Option: transient-history-file
-
-     This file is used to persist the history of transients and their
-     infixes between Emacs sessions.
-
- -- User Option: transient-history-limit
-
-     This option controls how many history elements are kept at the time
-     the history is saved in ‘transient-history-file’.
-
-\1f
-File: transient.info,  Node: Getting Help for Suffix Commands,  Next: Enabling and Disabling Suffixes,  Prev: Using History,  Up: Usage
-
-2.6 Getting Help for Suffix Commands
-====================================
-
-Transients can have many suffixes and infixes that the user might not be
-familiar with.  To make it trivial to get help for these, Transient
-provides access to the documentation directly from the active transient.
-
-‘C-h’     (‘transient-help’)
-
-     This command enters help mode.  When help mode is active, then
-     typing ‘<key>’ shows information about the suffix command that
-     ‘<key>’ normally is bound to (instead of invoking it).  Pressing
-     ‘C-h’ a second time shows information about the _prefix_ command.
-
-     After typing ‘<key>’ the stack of transient states is suspended and
-     information about the suffix command is shown instead.  Typing ‘q’
-     in the help buffer buries that buffer and resumes the transient
-     state.
-
-   What sort of documentation is shown depends on how the transient was
-defined.  For infix commands that represent command-line arguments this
-ideally shows the appropriate manpage.  ‘transient-help’ then tries to
-jump to the correct location within that.  Info manuals are also
-supported.  The fallback is to show the command’s doc string, for
-non-infix suffixes this is usually appropriate.
-
-\1f
-File: transient.info,  Node: Enabling and Disabling Suffixes,  Next: Other Commands,  Prev: Getting Help for Suffix Commands,  Up: Usage
-
-2.7 Enabling and Disabling Suffixes
-===================================
-
-The user base of a package that uses transients can be very diverse.
-This is certainly the case for Magit; some users have been using it and
-Git for a decade, while others are just getting started now.
-
-   For that reason a mechanism is needed that authors can use to
-classify a transient’s infixes and suffixes along the
-essentials...everything spectrum.  We use the term "levels" to describe
-that mechanism.
-
-   Each suffix command is placed on a level and each transient has a
-level (called transient-level), which controls which suffix commands are
-available.  Integers between 1 and 7 (inclusive) are valid levels.  For
-suffixes, 0 is also valid; it means that the suffix is not displayed at
-any level.
-
-   The levels of individual transients and/or their individual suffixes
-can be changed interactively, by invoking the transient and then
-pressing ‘C-x l’ to enter the "edit" mode, see below.
-
-   The default level for both transients and their suffixes is 4.  The
-‘transient-default-level’ option only controls the default for
-transients.  The default suffix level is always 4.  The authors of
-transients should place certain suffixes on a higher level, if they
-expect that it won’t be of use to most users, and they should place very
-important suffixes on a lower level, so that they remain available even
-if the user lowers the transient level.
-
-   (Magit currently places nearly all suffixes on level 4 and lower
-levels are not used at all yet.  So for the time being you should not
-set a lower default level and using a higher level might not give you as
-many additional suffixes as you hoped.)
-
- -- User Option: transient-default-level
-
-     This option controls which suffix levels are made available by
-     default.  It sets the transient-level for transients for which the
-     user has not set that individually.
-
- -- User Option: transient-levels-file
-
-     This file is used to persist the levels of transients and their
-     suffixes between Emacs sessions.
-
-‘C-x l’     (‘transient-set-level’)
-
-     This command enters edit mode.  When edit mode is active, then all
-     infixes and suffixes that are currently usable are displayed along
-     with their levels.  The colors of the levels indicate whether they
-     are enabled or not.  The level of the transient is also displayed
-     along with some usage information.
-
-     In edit mode, pressing the key that would usually invoke a certain
-     suffix instead prompts the user for the level that suffix should be
-     placed on.
-
-     Help mode is available in edit mode.
-
-     To change the transient level press ‘C-x l’ again.
-
-     To exit edit mode press ‘C-g’.
-
-     Note that edit mode does not display any suffixes that are not
-     currently usable.  ‘magit-rebase’ for example shows different
-     suffixes depending on whether a rebase is already in progress or
-     not.  The predicates also apply in edit mode.
-
-     Therefore, to control which suffixes are available given a certain
-     state, you have to make sure that that state is currently active.
-
-\1f
-File: transient.info,  Node: Other Commands,  Prev: Enabling and Disabling Suffixes,  Up: Usage
-
-2.8 Other Commands
-==================
-
-When invoking a transient in a small frame, the transient window may not
-show the complete buffer, making it necessary to scroll, using the
-following commands.  These commands are never shown in the transient
-window, and the key bindings are the same as for ‘scroll-up-command’ and
-‘scroll-down-command’ in other buffers.
-
- -- Command: transient-scroll-up arg
-
-     This command scrolls text of transient popup window upward ARG
-     lines.  If ARG is ‘nil’, then it scrolls near full screen.  This is
-     a wrapper around ‘scroll-up-command’ (which see).
-
- -- Command: transient-scroll-down arg
-
-     This command scrolls text of transient popup window down ARG lines.
-     If ARG is ‘nil’, then it scrolls near full screen.  This is a
-     wrapper around ‘scroll-down-command’ (which see).
-
-\1f
-File: transient.info,  Node: Other Options,  Next: Modifying Existing Transients,  Prev: Usage,  Up: Top
-
-3 Other Options
-***************
-
- -- User Option: transient-show-popup
-
-     This option controls whether the current transient’s infix and
-     suffix commands are shown in the popup buffer.
-
-        • If ‘t’ (the default) then the popup buffer is shown as soon as
-          a transient prefix command is invoked.
-
-        • If ‘nil’, then the popup buffer is not shown unless the user
-          explicitly requests it, by pressing an incomplete prefix key
-          sequence.
-
-        • If a number, then the a brief one-line summary is shown
-          instead of the popup buffer.  If zero or negative, then not
-          even that summary is shown; only the pressed key itself is
-          shown.
-
-          The popup is shown when the user explicitly requests it by
-          pressing an incomplete prefix key sequence.  Unless this is
-          zero, then the popup is shown after that many seconds of
-          inactivity (using the absolute value).
-
- -- User Option: transient-enable-popup-navigation
-
-     This option controls whether navigation commands are enabled in the
-     transient popup.
-
-     While a transient is active the transient popup buffer is not the
-     current buffer, making it necesary to use dedicated commands to act
-     on that buffer itself.  This is disabled by default.  If this
-     option is non-nil, then the following features are available:
-
-        • ‘<up>’ moves the cursor to the previous suffix.  ‘<down>’
-          moves the cursor to the next suffix.  ‘RET’ invokes the suffix
-          the cursor is on.
-
-        • ‘<mouse-1>’ invokes the clicked on suffix.
-
-        • ‘C-s’ and ‘C-r’ start isearch in the popup buffer.
-
- -- User Option: transient-display-buffer-action
-
-     This option specifies the action used to display the transient
-     popup buffer.  The transient popup buffer is displayed in a window
-     using ‘(display-buffer buf transient-display-buffer-action)’.
-
-     The value of this option has the form ‘(FUNCTION . ALIST)’, where
-     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 ALIST.  See *note (elisp)Choosing Window::.
-
-     The default is ‘(display-buffer-in-side-window (side . bottom))’.
-     This displays the window at the bottom of the selected frame.
-     Another useful value is ‘(display-buffer-below-selected)’.  This is
-     what ‘magit-popup’ used by default.  For more alternatives see
-     *note (elisp)Display Action Functions::.
-
-     It may be possible to display the window in another frame, but
-     whether that works in practice depends on the window-manager.  If
-     the window manager selects the new window (Emacs frame), then it
-     doesn’t work.
-
-     If you change the value of this option, then you might also want to
-     change the value of ‘transient-mode-line-format’.
-
- -- User Option: transient-mode-line-format
-
-     This option controls whether the transient popup buffer has a
-     mode-line, separator line, or neither.
-
-     If ‘nil’, then the buffer has no mode-line.  If the buffer is not
-     displayed right above the echo area, then this probably is not a
-     good value.
-
-     If ‘line’ (the default), then the buffer also has no mode-line, but
-     a thin line is drawn instead, using the background color of the
-     face ‘transient-separator’.
-
-     Otherwise this can be any mode-line format.  See *note (elisp)Mode
-     Line Format:: for details.
-
- -- User Option: transient-read-with-initial-input
-
-     This option controls whether the last history element is used as
-     the initial minibuffer input when reading the value of an infix
-     argument from the user.  If ‘nil’, then there is no initial input
-     and the first element has to be accessed the same way as the older
-     elements.
-
- -- User Option: transient-highlight-mismatched-keys
-
-     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.
-
-     When this option is non-nil, then the key binding for an infix
-     argument is highlighted when only a long argument (e.g.
-     ‘--verbose’) is specified but no shorthand (e.g ‘-v’).  In the rare
-     case that a shorthand is specified but the key binding does not
-     match, then it is highlighted differently.
-
-     Highlighting mismatched key bindings is useful when learning the
-     arguments of the underlying command-line tool; you wouldn’t want to
-     learn any short-hands that do not actually exist.
-
-     The highlighting is done using one of the faces
-     ‘transient-mismatched-key’ and ‘transient-nonstandard-key’.
-
- -- User Option: transient-substitute-key-function
-
-     This function is used to modify key bindings.  If the value of this
-     option is nil (the default), then no substitution is performed.
-
-     This function is called with one argument, the prefix object, and
-     must return a key binding description, either the existing key
-     description it finds in the ‘key’ slot, or key description that
-     replaces the prefix key.  It could be used to make other
-     substitutions, but that is discouraged.
-
-     For example, ‘=’ is hard to reach using my custom keyboard layout,
-     so I substitute ‘(’ for that, which is easy to reach using a layout
-     optimized for lisp.
-
-          (setq transient-substitute-key-function
-                (lambda (obj)
-                  (let ((key (oref obj key)))
-                    (if (string-match "\\`\\(=\\)[a-zA-Z]" key)
-                        (replace-match "(" t t key 1)
-                      key))))
-
- -- User Option: transient-detect-key-conflicts
-
-     This option controls whether key binding conflicts should be
-     detected at the time the transient is invoked.  If so, then this
-     results in an error, which prevents the transient from being used.
-     Because of that, conflicts are ignored by default.
-
-     Conflicts cannot be determined earlier, i.e.  when the transient is
-     being defined and when new suffixes are being added, because at
-     that time there can be false-positives.  It is actually valid for
-     multiple suffixes to share a common key binding, provided the
-     predicates of those suffixes prevent that more than one of them is
-     enabled at a time.
-
-\1f
-File: transient.info,  Node: Modifying Existing Transients,  Next: Defining New Commands,  Prev: Other Options,  Up: Top
-
-4 Modifying Existing Transients
-*******************************
-
-To an extent transients can be customized interactively, see *note
-Enabling and Disabling Suffixes::.  This section explains how existing
-transients can be further modified non-interactively.
-
-   The following functions share a few arguments:
-
-   • PREFIX is a transient prefix command, a symbol.
-
-   • SUFFIX is a transient infix or suffix specification in the same
-     form as expected by ‘define-transient-command’.  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.  See *note Suffix Specifications::.
-
-     SUFFIX may also be a group in the same form as expected by
-     ‘define-transient-command’.  See *note Group Specifications::.
-
-   • LOC is a command, a key vector, a key description (a string as
-     returned by ‘key-description’), or a list specifying coordinates
-     (the last element may also be a command or key).  For example ‘(1 0
-     -1)’ identifies the last suffix (‘-1’) of the first subgroup (‘0’)
-     of the second group (‘1’).
-
-     If LOC is a list of coordinates, then it can be used to identify a
-     group, not just an individual suffix command.
-
-     The function ‘transient-get-suffix’ can be useful to determine
-     whether a certain coordination list identifies the suffix or group
-     that you expect it to identify.  In hairy cases it may be necessary
-     to look at the definition of the transient prefix command.
-
-   These functions operate on the information stored in the
-‘transient--layout’ property of the PREFIX symbol.  Suffix entries in
-that tree are not objects but have the form ‘(LEVEL CLASS PLIST)’, where
-plist should set at least ‘:key’, ‘:description’ and ‘:command’.
-
- -- Function: transient-insert-suffix prefix loc suffix
-
-     This function inserts suffix or group SUFFIX into PREFIX before
-     LOC.
-
- -- Function: transient-append-suffix prefix loc suffix
-
-     This function inserts suffix or group SUFFIX into PREFIX after LOC.
-
- -- Function: transient-replace-suffix prefix loc suffix
-
-     This function replaces the suffix or group at LOC in PREFIX with
-     suffix or group SUFFIX.
-
- -- Function: transient-remove-suffix prefix loc
-
-     This function removes the suffix or group at LOC in PREFIX.
-
- -- Function: transient-get-suffix prefix loc
-
-     This function returns the suffix or group at LOC in PREFIX.  The
-     returned value has the form mentioned above.
-
- -- Function: transient-suffix-put prefix loc prop value
-
-     This function edits the suffix or group at LOC in PREFIX, by
-     setting the PROP of its plist to VALUE.
-
-   Most of these functions do not signal an error if they cannot perform
-the requested modification.  The functions that insert new suffixes show
-a warning if LOC cannot be found in PREFIX, without signaling an error.
-The reason for doing it like this is that establishing a key binding
-(and that is what we essentially are trying to do here) should not
-prevent the rest of the configuration from loading.  Among these
-functions only ‘transient-get-suffix’ and ‘transient-suffix-put’ may
-signal an error.
-
-\1f
-File: transient.info,  Node: Defining New Commands,  Next: Classes and Methods,  Prev: Modifying Existing Transients,  Up: Top
-
-5 Defining New Commands
-***********************
-
-* Menu:
-
-* Defining Transients::
-* Binding Suffix and Infix Commands::
-* Defining Suffix and Infix Commands::
-* Using Infix Arguments::
-* Transient State::
-
-\1f
-File: transient.info,  Node: Defining Transients,  Next: Binding Suffix and Infix Commands,  Up: Defining New Commands
-
-5.1 Defining Transients
-=======================
-
-A transient consists of a prefix command and at least one suffix
-command, though usually a transient has several infix and suffix
-commands.  The below macro defines the transient prefix command *and*
-binds the transient’s infix and suffix commands.  In other words, it
-defines the complete transient, not just the transient prefix command
-that is used to invoke that transient.
-
- -- Macro: define-transient-command name arglist [docstring] [keyword
-          value]... group... [body...]
-
-     This macro defines NAME as a transient prefix command and binds the
-     transient’s infix and suffix commands.
-
-     ARGLIST are the arguments that the prefix command takes.  DOCSTRING
-     is the documentation string and is optional.
-
-     These arguments can optionally be followed by keyword-value pairs.
-     Each key has to be a keyword symbol, either ‘:class’ or a keyword
-     argument supported by the constructor of that class.  The
-     ‘transient-prefix’ class is used if the class is not specified
-     explicitly.
-
-     GROUPs add key bindings for infix and suffix commands and specify
-     how these bindings are presented in the popup buffer.  At least one
-     GROUP has to be specified.  See *note Binding Suffix and Infix
-     Commands::.
-
-     The BODY is optional.  If it is omitted, then ARGLIST is ignored
-     and the function definition becomes:
-
-          (lambda ()
-            (interactive)
-            (transient-setup 'NAME))
-
-     If BODY is specified, then it must begin with an ‘interactive’ form
-     that matches ARGLIST, and it must call ‘transient-setup’.  It may
-     however call that function only when some condition is satisfied.
-
-     All transients have a (possibly ‘nil’) value, which is exported
-     when suffix commands are called, so that they can consume that
-     value.  For some transients it might be necessary to have a sort of
-     secondary value, called a "scope".  Such a scope would usually be
-     set in the command’s ‘interactive’ form and has to be passed to the
-     setup function:
-
-          (transient-setup 'NAME nil nil :scope SCOPE)
-
-     For example, the scope of the ‘magit-branch-configure’ transient is
-     the branch whose variables are being configured.
-
-\1f
-File: transient.info,  Node: Binding Suffix and Infix Commands,  Next: Defining Suffix and Infix Commands,  Prev: Defining Transients,  Up: Defining New Commands
-
-5.2 Binding Suffix and Infix Commands
-=====================================
-
-The macro ‘define-transient-command’ is used to define a transient.
-This defines the actual transient prefix command (see *note 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 ‘transient-insert-suffix’ (See *note Modifying
-Existing Transients::).  These functions take a "suffix specification"
-as one of their arguments, which has the same form as the specifications
-used in ‘define-transient-command’.
-
-* Menu:
-
-* Group Specifications::
-* Suffix Specifications::
-
-\1f
-File: transient.info,  Node: Group Specifications,  Next: Suffix Specifications,  Up: Binding Suffix and Infix Commands
-
-5.2.1 Group Specifications
---------------------------
-
-The suffix and infix commands of a transient are organized in groups.
-The grouping controls how the descriptions of the suffixes are outlined
-visually but also makes it possible to set certain properties for a set
-of suffixes.
-
-   Several group classes exist, some of which organize suffixes in
-subgroups.  In most cases the class does not have to be specified
-explicitly, but see *note Group Classes::.
-
-   Groups are specified in the call to ‘define-transient-command’, using
-vectors.  Because groups are represented using vectors, we cannot use
-square brackets to indicate an optional element and instead use curly
-brackets to do the latter.
-
-   Group specifications then have this form:
-
-     [{LEVEL} {DESCRIPTION} {KEYWORD VALUE}... ELEMENT...]
-
-   The LEVEL is optional and defaults to 4.  See *note Enabling and
-Disabling Suffixes::.
-
-   The DESCRIPTION is optional.  If present it is used as the heading of
-the group.
-
-   The KEYWORD-VALUE pairs are optional.  Each keyword has to be a
-keyword symbol, either ‘:class’ or a keyword argument supported by the
-constructor of that class.
-
-   • One of these keywords, ‘:description’, is equivalent to specifying
-     DESCRIPTION at the very beginning of the vector.  The
-     recommendation is to use ‘:description’ if some other keyword is
-     also used, for consistency, or DESCRIPTION otherwise, because it
-     looks better.
-
-   • Likewise ‘:level’ is equivalent to LEVEL.
-
-   • Other important keywords include the ‘:if...’ keywords.  These
-     keywords control whether the group is available in a certain
-     situation.
-
-     For example, one group of the ‘magit-rebase’ transient uses ‘:if
-     magit-rebase-in-progress-p’, which contains the suffixes that are
-     useful while rebase is already in progress; and another that uses
-     ‘:if-not magit-rebase-in-progress-p’, which contains the suffixes
-     that initiate a rebase.
-
-     These predicates can also be used on individual suffixes and are
-     only documented once, see *note Predicate Slots::.
-
-   • Finally the value of ‘:hide’, if non-nil, is a predicate that
-     controls whether the group is hidden by default.  The key bindings
-     for suffixes of a hidden group should all use the same prefix key.
-     Pressing that prefix key should temporarily show the group and its
-     suffixes, which assumes that a predicate like this is used:
-
-          (lambda ()
-            (eq (car transient--redisplay-key)
-                ?\C-c)) ; the prefix key shared by all bindings
-
-   The ELEMENTs 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.)
-
-   If the ELEMENTs 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.
-
-   The form of suffix specifications is documented in the next node.
-
-\1f
-File: transient.info,  Node: Suffix Specifications,  Prev: Group Specifications,  Up: Binding Suffix and Infix Commands
-
-5.2.2 Suffix Specifications
----------------------------
-
-A transient’s suffix and infix commands are bound when the transient
-prefix command is defined using ‘define-transient-command’, see *note
-Defining Transients::.  The commands are organized into groups, see
-*note Group Specifications::.  Here we describe the form used to bind an
-individual suffix command.
-
-   The same form is also used when later binding additional commands
-using functions such as ‘transient-insert-suffix’, see *note Modifying
-Existing Transients::.
-
-   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.
-
-   Suffix specifications have this form:
-
-     ([LEVEL] [KEY] [DESCRIPTION] COMMAND|ARGUMENT [KEYWORD VALUE]...)
-
-   LEVEL, KEY and DESCRIPTION can also be specified using the KEYWORDs
-‘:level’, ‘:key’ and ‘:description’.  If the object that is associated
-with COMMAND sets these properties, then they do not have to be
-specified here.  You can however specify them here anyway, possibly
-overriding the object’s values just for the binding inside this
-transient.
-
-   • LEVEL is the suffix level, an integer between 1 and 7.  See *note
-     Enabling and Disabling Suffixes::.
-
-   • KEY is the key binding, either a vector or key description string.
-
-   • DESCRIPTION is the description, either a string or a function that
-     returns a string.  The function should be a lambda expression to
-     avoid ambiguity.  In some cases a symbol that is bound as a
-     function would also work but to be safe you should use
-     ‘:description’ in that case.
-
-   The next element is either a command or an argument.  This is the
-only argument that is mandatory in all cases.
-
-   • COMMAND is a symbol that is bound as a function, which has to be a
-     command.  Any command will do; it does not need to have an object
-     associated with it (as would be the case if ‘define-suffix-command’
-     or ‘define-infix-command’ were used to define it).
-
-     As mentioned above, the object that is associated with a command
-     can be used to set the default for certain values that otherwise
-     have to be set in the suffix specification.  Therefore if there is
-     no object, then you have to make sure to specify the KEY and the
-     DESCRIPTION.
-
-   • The mandatory argument can also be a command-line argument, a
-     string.  In that case an anonymous command is defined and bound.
-
-     Instead of a string, this can also be a list of two strings, in
-     which case the first string is used as the short argument (which
-     can also be specified using ‘:shortarg’) and the second as the long
-     argument (which can also be specified using ‘:argument’).
-
-     Only the long argument is displayed in the popup buffer.  See
-     ‘transient-detect-key-conflicts’ for how the short argument may be
-     used.
-
-     Unless the class is specified explicitly, the appropriate class is
-     guessed based on the long argument.  If the argument ends with "=​"
-     (e.g.  "–format=") then ‘transient-option’ is used, otherwise
-     ‘transient-switch’.
-
-   Finally, details can be specified using optional KEYWORD-VALUE pairs.
-Each keyword has to be a keyword symbol, either ‘:class’ or a keyword
-argument supported by the constructor of that class.  See *note Suffix
-Slots::.
-
-\1f
-File: transient.info,  Node: Defining Suffix and Infix Commands,  Next: Using Infix Arguments,  Prev: Binding Suffix and Infix Commands,  Up: Defining New Commands
-
-5.3 Defining Suffix and Infix Commands
-======================================
-
-Note that an infix is a special kind of suffix.  Depending on context
-"suffixes" means "suffixes (including infixes)" or "non-infix suffixes".
-
- -- Macro: define-suffix-command name arglist [docstring] [keyword
-          value]... body...
-
-     This macro defines NAME as a transient suffix command.
-
-     ARGLIST are the arguments that the command takes.  DOCSTRING is the
-     documentation string and is optional.
-
-     These arguments can optionally be followed by keyword-value pairs.
-     Each keyword has to be a keyword symbol, either ‘:class’ or a
-     keyword argument supported by the constructor of that class.  The
-     ‘transient-suffix’ class is used if the class is not specified
-     explicitly.
-
-     The BODY must begin with an ‘interactive’ form that matches
-     ARGLIST.  The infix arguments are usually accessed by using
-     ‘transient-args’ inside ‘interactive’.
-
- -- Macro: define-infix-command name arglist [docstring] [keyword
-          value]...
-
-     This macro defines NAME as a transient infix command.
-
-     ARGLIST is always ignored (but mandatory never-the-less) and
-     reserved for future use.  DOCSTRING is the documentation string and
-     is optional.
-
-     The keyword-value pairs are mandatory.  All transient infix
-     commands are ‘equal’ to each other (but not ‘eq’), so it is
-     meaningless to define an infix command without also setting at
-     least ‘:class’ and one other keyword (which it is depends on the
-     used class, usually ‘:argument’ or ‘:variable’).
-
-     Each keyword has to be a keyword symbol, either ‘:class’ or a
-     keyword argument supported by the constructor of that class.  The
-     ‘transient-switch’ class is used if the class is not specified
-     explicitly.
-
-     The function definition is always:
-
-          (lambda ()
-            (interactive)
-            (let ((obj (transient-suffix-object)))
-              (transient-infix-set obj (transient-infix-read obj)))
-            (transient--show))
-
-     ‘transient-infix-read’ and ‘transient-infix-set’ are generic
-     functions.  Different infix commands behave differently because the
-     concrete methods are different for different infix command classes.
-     In rare cases the above command function might not be suitable,
-     even if you define your own infix command class.  In that case you
-     have to use ‘transient-suffix-command’ to define the infix command
-     and use ‘t’ as the value of the ‘:transient’ keyword.
-
- -- Macro: define-infix-argument name arglist [docstring] [keyword
-          value]...
-
-     This macro defines NAME as a transient infix command.
-
-     It is an alias for ‘define-infix-command’.  Only use this alias to
-     define an infix command that actually sets an infix argument.  To
-     define an infix command that, for example, sets a variable, use
-     ‘define-infix-command’ instead.
-
-\1f
-File: transient.info,  Node: Using Infix Arguments,  Next: Transient State,  Prev: Defining Suffix and Infix Commands,  Up: Defining New Commands
-
-5.4 Using Infix Arguments
-=========================
-
-The function and the variables described below allow suffix commands to
-access the value of the transient from which they were invoked; which is
-the value of its infix arguments.  These variables are set when the user
-invokes a suffix command that exits the transient, but before actually
-calling the command.
-
-   When returning to the command-loop after calling the suffix command,
-the arguments are reset to ‘nil’ (which causes the function to return
-‘nil’ too).
-
-   Like for Emacs’ prefix arguments it is advisable, but not mandatory,
-to access the infix arguments inside the command’s ‘interactive’ form.
-The preferred way of doing that is to call the ‘transient-args’
-function, which for infix arguments serves about the same purpose as
-‘prefix-arg’ serves for prefix arguments.
-
- -- Function: transient-args &optional prefix
-
-     This function returns the value of the transient prefix command
-     PREFIX.
-
-     If the current command was invoked from the transient prefix
-     command PREFIX, then it returns the active infix arguments.  If the
-     current command was not invoked from PREFIX, then it returns the
-     set, saved or default value for PREFIX.
-
- -- Variable: current-transient-suffixes
-
-     The suffixes of the transient from which this suffix command was
-     invoked.  This is a list of objects.  Usually it is sufficient to
-     instead use the function ‘transient-args’, which returns a list of
-     values.  In complex cases it might be necessary to use this
-     variable instead, i.e.  if you need access to information beside
-     the value.
-
- -- Variable: current-transient-prefix
-
-     The transient from which this suffix command was invoked.  The
-     returned value is a ‘transient-prefix’ object, which holds
-     information associated with the transient prefix command.
-
- -- Variable: current-transient-command
-
-     The transient from which this suffix command was invoked.  The
-     returned value is a symbol, the transient prefix command.
-
-\1f
-File: transient.info,  Node: Transient State,  Prev: Using Infix Arguments,  Up: Defining New Commands
-
-5.5 Transient State
-===================
-
-Invoking a transient prefix command "activates" the respective
-transient, i.e.  it puts a transient keymap into effect, which binds the
-transient’s infix and suffix commands.
-
-   The default behavior while a transient is active is as follows:
-
-   • Invoking an infix command does not affect the transient state; the
-     transient remains active.
-
-   • Invoking a (non-infix) suffix command "deactivates" the transient
-     state by removing the transient keymap and performing some
-     additional cleanup.
-
-   • Invoking a command that is bound in a keymap other than the
-     transient keymap is disallowed and trying to do so results in a
-     warning.  This does not "deactivate" the transient.
-
-   But these are just the defaults.  Whether a certain command
-deactivates or "exits" the transient is configurable.  There is more
-than one way in which a command can be "transient" or "non-transient";
-the exact behavior is implemented by calling a so-called "pre-command"
-function.  Whether non-suffix commands are allowed to be called is
-configurable per transient.
-
-   • The transient-ness of suffix commands (including infix commands) is
-     controlled by the value of their ‘transient’ slot, which can be set
-     either when defining the command or when adding a binding to a
-     transient while defining the respective transient prefix command.
-
-     Valid values are booleans and the pre-commands described below.
-
-        • ‘t’ is equivalent to ‘transient--do-stay’.
-
-        • ‘nil’ is equivalent to ‘transient--do-exit’.
-
-        • If ‘transient’ is unbound (and that is actually the default
-          for non-infix suffixes) then the value of the prefix’s
-          ‘transient-suffix’ slot is used instead.  The default value of
-          that slot is ‘nil’, so the suffix’s ‘transient’ slot being
-          unbound is essentially equivalent to it being ‘nil’.
-
-   • A suffix command can be a prefix command itself, i.e.  a
-     "sub-prefix".  While a sub-prefix is active we nearly always want
-     ‘C-g’ to take the user back to the "super-prefix".  However in rare
-     cases this may not be desirable, and that makes the following
-     complication necessary:
-
-     For ‘transient-suffix’ objects the ‘transient’ slot is unbound.  We
-     can ignore that for the most part because, as stated above, ‘nil’
-     and the slot being unbound are equivalent, and mean "do exit".
-     That isn’t actually true for suffixes that are sub-prefixes though.
-     For such suffixes unbound means "do exit but allow going back",
-     which is the default, while ‘nil’ means "do exit permanently",
-     which requires that slot to be explicitly set to that value.
-
-   • The transient-ness of certain built-in suffix commands is specified
-     using ‘transient-predicate-map’.  This is a special keymap, which
-     binds commands to pre-commands (as opposed to keys to commands) and
-     takes precedence over the ‘transient’ slot.
-
-   The available pre-command functions are documented below.  They are
-called by ‘transient--pre-command’, a function on ‘pre-command-hook’ and
-the value that they return determines whether the transient is exited.
-To do so the value of one of the constants ‘transient--exit’ or
-‘transient--stay’ is used (that way we don’t have to remember if ‘t’
-means "exit" or "stay").
-
-   Additionally these functions may change the value of ‘this-command’
-(which explains why they have to be called using ‘pre-command-hook’),
-call ‘transient-export’, ‘transient--stack-zap’ or
-‘transient--stack-push’; and set the values of ‘transient--exitp’,
-‘transient--helpp’ or ‘transient--editp’.
-
-5.5.1 Pre-commands for Infixes
-------------------------------
-
-The default for infixes is ‘transient--do-stay’.  This is also the only
-function that makes sense for infixes.
-
- -- Function: transient--do-stay
-
-     Call the command without exporting variables and stay transient.
-
-5.5.2 Pre-commands for Suffixes
--------------------------------
-
-The default for suffixes is ‘transient--do-exit’.
-
- -- Function: transient--do-exit
-
-     Call the command after exporting variables and exit the transient.
-
- -- Function: transient--do-call
-
-     Call the command after exporting variables and stay transient.
-
- -- Function: transient--do-replace
-
-     Call the transient prefix command, replacing the active transient.
-
-     This is used for suffixes that are prefixes themselves, i.e.  for
-     sub-prefixes.
-
-5.5.3 Pre-commands for Non-Suffixes
------------------------------------
-
-The default for non-suffixes, i.e commands that are bound in other
-keymaps beside the transient keymap, is ‘transient--do-warn’.  Silently
-ignoring the user-error is also an option, though probably not a good
-one.
-
-   If you want to let the user invoke non-suffix commands, then use
-‘transient--do-stay’ as the value of the prefix’s ‘transient-non-suffix’
-slot.
-
- -- Function: transient--do-warn
-
-     Call ‘transient-undefined’ and stay transient.
-
- -- Function: transient--do-noop
-
-     Call ‘transient-noop’ and stay transient.
-
-5.5.4 Special Pre-Commands
---------------------------
-
- -- Function: transient--do-quit-one
-
-     If active, quit help or edit mode, else exit the active transient.
-
-     This is used when the user pressed ‘C-g’.
-
- -- Function: transient--do-quit-all
-
-     Exit all transients without saving the transient stack.
-
-     This is used when the user pressed ‘C-q’.
-
- -- Function: transient--do-suspend
-
-     Suspend the active transient, saving the transient stack.
-
-     This is used when the user pressed ‘C-z’.
-
-\1f
-File: transient.info,  Node: Classes and Methods,  Next: Related Abstractions and Packages,  Prev: Defining New Commands,  Up: Top
-
-6 Classes and Methods
-*********************
-
-Transient uses classes and generic functions to make it possible to
-define new types of suffix commands that are similar to existing types,
-but behave differently in some aspects.  It does the same for groups and
-prefix commands, though at least for prefix commands that *currently*
-appears to be less important.
-
-   Every prefix, infix and suffix command is associated with an object,
-which holds information that controls certain aspects of its behavior.
-This happens in two ways.
-
-   • Associating a command with a certain class gives the command a
-     type.  This makes it possible to use generic functions to do
-     certain things that have to be done differently depending on what
-     type of command it acts on.
-
-     That in turn makes it possible for third-parties to add new types
-     without having to convince the maintainer of Transient that that
-     new type is important enough to justify adding a special case to a
-     dozen or so functions.
-
-   • Associating a command with an object makes it possible to easily
-     store information that is specific to that particular command.
-
-     Two commands may have the same type, but obviously their key
-     bindings and descriptions still have to be different, for example.
-
-     The values of some slots are functions.  The ‘reader’ slot for
-     example holds a function that is used to read a new value for an
-     infix command.  The values of such slots are regular functions.
-
-     Generic functions are used when a function should do something
-     different based on the type of the command, i.e.  when all commands
-     of a certain type should behave the same way but different from the
-     behavior for other types.  Object slots that hold a regular
-     function as value are used when the task that they perform is
-     likely to differ even between different commands of the same type.
-
-* Menu:
-
-* Group Classes::
-* Group Methods::
-* Prefix Classes::
-* Suffix Classes::
-* Suffix Methods::
-* Prefix Slots::
-* Suffix Slots::
-* Predicate Slots::
-
-\1f
-File: transient.info,  Node: Group Classes,  Next: Group Methods,  Up: Classes and Methods
-
-6.1 Group Classes
-=================
-
-The type of a group can be specified using the ‘:class’ property at the
-beginning of the class specification, e.g.  ‘[:class transient-columns
-...]’ in a call to ‘define-transient-command’.
-
-   • The abstract ‘transient-child’ class is the base class of both
-     ‘transient-group’ (and therefore all groups) as well as of
-     ‘transient-suffix’ (and therefore all suffix and infix commands).
-
-     This class exists because the elements (aka "children") of certain
-     groups can be other groups instead of suffix and infix commands.
-
-   • The abstract ‘transient-group’ class is the superclass of all other
-     group classes.
-
-   • The ‘transient-column’ class is the simplest group.
-
-     This is the default "flat" group.  If the class is not specified
-     explicitly and the first element is not a vector (i.e.  not a
-     group), then this class is used.
-
-     This class displays each element on a separate line.
-
-   • The ‘transient-row’ class displays all elements on a single line.
-
-   • The ‘transient-columns’ class displays commands organized in
-     columns.
-
-     Direct elements have to be groups whose elements have to be
-     commands or strings.  Each subgroup represents a column.  This
-     class takes care of inserting the subgroups’ elements.
-
-     This is the default "nested" group.  If the class is not specified
-     explicitly and the first element is a vector (i.e.  a group), then
-     this class is used.
-
-   • The ‘transient-subgroups’ class wraps other groups.
-
-     Direct elements have to be groups whose elements have to be
-     commands or strings.  This group inserts an empty line between
-     subgroups.  The subgroups themselves are responsible for displaying
-     their elements.
-
-\1f
-File: transient.info,  Node: Group Methods,  Next: Prefix Classes,  Prev: Group Classes,  Up: Classes and Methods
-
-6.2 Group Methods
-=================
-
- -- Function: transient--insert-group group
-
-     This generic function formats the group and its elements and
-     inserts the result into the current buffer, which is a temporary
-     buffer.  The contents of that buffer are later inserted into the
-     popup buffer.
-
-     Functions that are called by this function may need to operate in
-     the buffer from which the transient was called.  To do so they can
-     temporally make the ‘transient--source-buffer’ the current buffer.
-
-\1f
-File: transient.info,  Node: Prefix Classes,  Next: Suffix Classes,  Prev: Group Methods,  Up: Classes and Methods
-
-6.3 Prefix Classes
-==================
-
-Currently the ‘transient-prefix’ class is being used for all prefix
-commands and there is only a single generic function that can be
-specialized based on the class of a prefix command.
-
- -- Function: transient--history-init obj
-
-     This generic function is called while setting up the transient and
-     is responsible for initializing the ‘history’ slot.  This is the
-     transient-wide history; many individual infixes also have a history
-     of their own.
-
-     The default (and currently only) method extracts the value from the
-     global variable ‘transient-history’.
-
-   A transient prefix command’s object is stored in the
-‘transient--prefix’ property of the command symbol.  While a transient
-is active, a clone of that object is stored in the variable
-‘transient--prefix’.  A clone is used because some changes that are made
-to the active transient’s object should not affect later invocations.
-
-\1f
-File: transient.info,  Node: Suffix Classes,  Next: Suffix Methods,  Prev: Prefix Classes,  Up: Classes and Methods
-
-6.4 Suffix Classes
-==================
-
-   • All suffix and infix classes derive from ‘transient-suffix’, which
-     in turn derives from ‘transient-child’, from which
-     ‘transient-group’ also derives (see *note Group Classes::).
-
-   • All infix classes derive from the abstract ‘transient-infix’ class,
-     which in turn derives from the ‘transient-suffix’ class.
-
-     Infixes are a special type of suffixes.  The primary difference is
-     that infixes always use the ‘transient--do-stay’ pre-command, while
-     non-infix suffixes use a variety of pre-commands (see *note
-     Transient State::).  Doing that is most easily achieved by using
-     this class, though theoretically it would be possible to define an
-     infix class 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 (see *note Defining Suffix and Infix Commands::).
-
-   • Classes used for infix commands that represent arguments should be
-     derived from the abstract ‘transient-argument’ class.
-
-   • The ‘transient-switch’ class (or a derived class) is used for infix
-     arguments that represent command-line switches (arguments that do
-     not take a value).
-
-   • The ‘transient-option’ class (or a derived class) is used for infix
-     arguments that represent command-line options (arguments that do
-     take a value).
-
-   • The ‘transient-switches’ class can be used for a set of mutually
-     exclusive command-line switches.
-
-   • The ‘transient-files’ class can be used for a "–" argument that
-     indicates that all remaining arguments are files.
-
-   • Classes used for infix commands that represent variables should
-     derived from the abstract ‘transient-variables’ class.
-
-   Magit defines additional classes, which can serve as examples for the
-fancy things you can do without modifying Transient.  Some of these
-classes will likely get generalized and added to Transient.  For now
-they are very much subject to change and not documented.
-
-\1f
-File: transient.info,  Node: Suffix Methods,  Next: Prefix Slots,  Prev: Suffix Classes,  Up: Classes and Methods
-
-6.5 Suffix Methods
-==================
-
-To get information about the methods implementing these generic
-functions use ‘describe-function’.
-
-* Menu:
-
-* Suffix Value Methods::
-* Suffix Format Methods::
-
-\1f
-File: transient.info,  Node: Suffix Value Methods,  Next: Suffix Format Methods,  Up: Suffix Methods
-
-6.5.1 Suffix Value Methods
---------------------------
-
- -- Function: transient-init-value obj
-
-     This generic function sets the initial value of the object OBJ.
-
-     This function is called for all suffix commands, but unless a
-     concrete method is implemented this falls through to the default
-     implementation, which is a noop.  In other words this usually only
-     does something for infix commands, but note that this is not
-     implemented for the abstract class ‘transient-infix’, so if your
-     class derives from that directly, then you must implement a method.
-
- -- Function: transient-infix-read obj
-
-     This generic function determines the new value of the infix object
-     OBJ.
-
-     This function merely determines the value; ‘transient-infix-set’ is
-     used to actually store the new value in the object.
-
-     For most infix classes this is done by reading a value from the
-     user using the reader specified by the ‘reader’ slot (using the
-     ‘transient-infix-value’ method described below).
-
-     For some infix classes the value is changed without reading
-     anything in the minibuffer, i.e.  the mere act of invoking the
-     infix command determines what the new value should be, based on the
-     previous value.
-
- -- Function: transient-prompt obj
-
-     This generic function returns the prompt to be used to read infix
-     object OBJ’s value.
-
- -- Function: transient-infix-set obj value
-
-     This generic function sets the value of infix object OBJ to VALUE.
-
- -- Function: transient-infix-value obj
-
-     This generic function returns the value of the suffix object OBJ.
-
-     This function is called by ‘transient-args’ (which see), meaning
-     this function is how the value of a transient is determined so that
-     the invoked suffix command can use it.
-
-     Currently most values are strings, but that is not set in stone.
-     ‘nil’ is not a value, it means "no value".
-
-     Usually only infixes have a value, but see the method for
-     ‘transient-suffix’.
-
- -- Function: transient-init-scope obj
-
-     This generic function sets the scope of the suffix object OBJ.
-
-     The scope is actually a property of the transient prefix, not of
-     individual suffixes.  However it is possible to invoke a suffix
-     command directly instead of from a transient.  In that case, if the
-     suffix expects a scope, then it has to determine that itself and
-     store it in its ‘scope’ slot.
-
-     This function is called for all suffix commands, but unless a
-     concrete method is implemented this falls through to the default
-     implementation, which is a noop.
-
-\1f
-File: transient.info,  Node: Suffix Format Methods,  Prev: Suffix Value Methods,  Up: Suffix Methods
-
-6.5.2 Suffix Format Methods
----------------------------
-
- -- Function: transient-format obj
-
-     This generic function formats and returns OBJ for display.
-
-     When this function is called, then the current buffer is some
-     temporary buffer.  If you need the buffer from which the prefix
-     command was invoked to be current, then do so by temporarily making
-     ‘transient--source-buffer’ current.
-
- -- Function: transient-format-key obj
-
-     This generic function formats OBJ’s ‘key’ for display and returns
-     the result.
-
- -- Function: transient-format-description obj
-
-     This generic function formats OBJ’s ‘description’ for display and
-     returns the result.
-
- -- Function: transient-format-value obj
-
-     This generic function formats OBJ’s value for display and returns
-     the result.
-
- -- Function: transient-show-help obj
-
-     Show help for the prefix, infix or suffix command represented by
-     OBJ.
-
-     For prefixes, show the info manual, if that is specified using the
-     ‘info-manual’ slot.  Otherwise show the manpage if that is
-     specified using the ‘man-page’ slot.  Otherwise show the command’s
-     doc string.
-
-     For suffixes, show the command’s doc string.
-
-     For infixes, show the manpage if that is specified.  Otherwise show
-     the command’s doc string.
-
-\1f
-File: transient.info,  Node: Prefix Slots,  Next: Suffix Slots,  Prev: Suffix Methods,  Up: Classes and Methods
-
-6.6 Prefix Slots
-================
-
-   • ‘man-page’ or ‘info-manual’ can be used to specify the
-     documentation for the prefix and its suffixes.  The command
-     ‘transient-help’ uses the method ‘transient-show-help’ (which see)
-     to lookup and use these values.
-
-   • ‘history-key’ If multiple prefix commands should share a single
-     value, then this slot has to be set to the same value for all of
-     them.  You probably don’t want that.
-
-   • ‘transient-suffix’ and ‘transient-non-suffix’ play a part when
-     determining whether the currently active transient prefix command
-     remains active/transient when a suffix or abitrary non-suffix
-     command is invoked.  See *note Transient State::.
-
-   • ‘incompatible’ A list of lists.  Each sub-list specifies a set of
-     mutually exclusive arguments.  Enabling one of these arguments
-     causes the others to be disabled.
-
-   • ‘scope’ For some transients it might be necessary to have a sort of
-     secondary value, called a "scope".  See ‘define-transient-command’.
-
-6.6.1 Internal Prefix Slots
----------------------------
-
-These slots are mostly intended for internal use.  They should not be
-set in calls to ‘define-transient-command’.
-
-   • ‘prototype’ When a transient prefix command is invoked, then a
-     clone of that object is stored in the global variable
-     ‘transient--prefix’ and the prototype is stored in the clone’s
-     ‘prototype’ slot.
-
-   • ‘command’ The command, a symbol.  Each transient prefix command
-     consists of a command, which is stored in a symbol’s function slot
-     and an object, which is stored in the ‘transient--prefix’ property
-     of the same symbol.
-
-   • ‘level’ The level of the prefix commands.  The suffix commands
-     whose layer is equal or lower are displayed.  See *note Enabling
-     and Disabling Suffixes::.
-
-   • ‘value’ The likely outdated value of the prefix.  Instead of
-     accessing this slot directly you should use the function
-     ‘transient-get-value’, which is guaranteed to return the up-to-date
-     value.
-
-   • ‘history’ and ‘history-pos’ are used to keep track of historic
-     values.  Unless you implement your own ‘transient-infix-read’
-     method you should not have to deal with these slots.
-
-\1f
-File: transient.info,  Node: Suffix Slots,  Next: Predicate Slots,  Prev: Prefix Slots,  Up: Classes and Methods
-
-6.7 Suffix Slots
-================
-
-Here we document most of the slots that are only available for suffix
-objects.  Some slots are shared by suffix and group objects, they are
-documented in *note Predicate Slots::.
-
-   Also see *note Suffix Classes::.
-
-6.7.1 Slots of ‘transient-suffix’
----------------------------------
-
-   • ‘key’ The key, a key vector or a key description string.
-
-   • ‘command’ The command, a symbol.
-
-   • ‘transient’ Whether to stay transient.  See *note Transient
-     State::.
-
-   • ‘format’ The format used to display the suffix in the popup buffer.
-     It must contain the following %-placeholders:
-
-        • ‘%k’ For the key.
-
-        • ‘%d’ For the description.
-
-        • ‘%v’ For the infix value.  Non-infix suffixes don’t have a
-          value.
-
-   • ‘description’ The description, either a string or a function that
-     is called with no argument and returns a string.
-
-6.7.2 Slots of ‘transient-infix’
---------------------------------
-
-Some of these slots are only meaningful for some of the subclasses.
-They are defined here anyway to allow sharing certain methods.
-
-   • ‘argument’ The long argument, e.g.  ‘--verbose’.
-
-   • ‘shortarg’ The short argument, e.g.  ‘-v’.
-
-   • ‘multi-value’ For options, whether the option can have multiple
-     values.  If non-nil, then default to use
-     ‘completing-read-multiple’.
-
-   • ‘allow-empty’ For options, whether the empty string is a valid
-     value.
-
-   • ‘history-key’ The key used to store the history.  This defaults to
-     the command name.  This is useful when multiple infixes should
-     share the same history because their values are of the same kind.
-
-   • ‘reader’ The function used to read the value of an infix.  Not used
-     for switches.  The function takes three arguments, PROMPT,
-     INITIAL-INPUT and HISTORY, and must return a string.
-
-   • ‘prompt’ The prompt used when reading the value, either a string or
-     a function that takes the object as the only argument and which
-     returns a prompt string.
-
-   • ‘choices’ A list of valid values.  How exactly that is used depends
-     on the class of the object.
-
-6.7.3 Slots of ‘transient-variable’
------------------------------------
-
-   • ‘variable’ The variable.
-
-6.7.4 Slots of ‘transient-switches’
------------------------------------
-
-   • ‘argument-format’ The display format.  Must contain ‘%s’, one of
-     the ‘choices’ is substituted for that.  E.g.  ‘--%s-order’.
-
-   • ‘argument-regexp’ The regexp used to match any one of the switches.
-     E.g.  ‘\\(--\\(topo\\|author-date\\|date\\)-order\\)’.
-
-\1f
-File: transient.info,  Node: Predicate Slots,  Prev: Suffix Slots,  Up: Classes and Methods
-
-6.8 Predicate Slots
-===================
-
-Suffix and group objects share some predicate slots that control whether
-a group or suffix should be available depending on some state.  Only one
-of these slots can be used at the same time.  It is undefined what
-happens if you use more than one.
-
-   • ‘if’ Enable if predicate returns non-nil.
-
-   • ‘if-not’ Enable if predicate returns nil.
-
-   • ‘if-non-nil’ Enable if variable’s value is non-nil.
-
-   • ‘if-nil’ Enable if variable’s value is nil.
-
-   • ‘if-mode’ Enable if major-mode matches value.
-
-   • ‘if-not-mode’ Enable if major-mode does not match value.
-
-   • ‘if-derived’ Enable if major-mode derives from value.
-
-   • ‘if-not-derived’ Enable if major-mode does not derive from value.
-
-   One more slot is shared between group and suffix classes, ‘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.
-‘level’ controls whether a suffix or a group should be available
-depending on user preference.  See *note Enabling and Disabling
-Suffixes::.
-
-\1f
-File: transient.info,  Node: Related Abstractions and Packages,  Next: FAQ,  Prev: Classes and Methods,  Up: Top
-
-7 Related Abstractions and Packages
-***********************************
-
-* Menu:
-
-* Comparison With Prefix Keys and Prefix Arguments::
-* Comparison With Other Packages::
-
-\1f
-File: transient.info,  Node: Comparison With Prefix Keys and Prefix Arguments,  Next: Comparison With Other Packages,  Up: Related Abstractions and Packages
-
-7.1 Comparison With Prefix Keys and Prefix Arguments
-====================================================
-
-While transient commands were inspired by regular prefix keys and prefix
-arguments, they are also quite different and much more complex.
-
-   The following diagrams illustrate some of the differences.
-
-   • ‘(c)’ represents a return to the command loop.
-
-   • ‘(+)’ represents the user’s choice to press one key or another.
-
-   • ‘{WORD}’ are possible behaviors.
-
-   • ‘{NUMBER}’ is a footnote.
-
-7.1.1 Regular Prefix Commands
------------------------------
-
-See *note (elisp)Prefix Keys::.
-
-                                       ,--> command1 --> (c)
-                                       |
-     (c)-(+)-> prefix command or key --+--> command2 --> (c)
-                                       |
-                                       `--> command3 --> (c)
-
-7.1.2 Regular Prefix Arguments
-------------------------------
-
-See *note (elisp)Prefix Command Arguments::.
-
-             ,----------------------------------,
-             |                                  |
-             v                                  |
-     (c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c)
-                    |                                        ^        |
-                    |                                        |        |
-                    `-- sets or changes --, ,-- maybe used --'        |
-                                          | |                         |
-                                          v |                         |
-                               prefix argument state                  |
-                                           ^                          |
-                                           |                          |
-                                           `-------- discards --------'
-
-7.1.3 Transients
-----------------
-
-(∩`-´)⊃━☆゚.*・。゚
-
-   This diagram ignores the infix value and external state:
-
-     (c)
-      |        ,- {stay} ------<-,-<------------<-,-<---,
-     (+)       |                 |                |     |
-      |        |                 |                |     |
-      |        |   ,--> infix1 --|                |     |
-      |        |   |             |                |     |
-      |        |   |--> infix2 --|                |     |
-      v        v   |             |                |     |
-      prefix -(c)-(+)-> infix3 --'                ^     |
-                   |                              |     |
-                   |---------------> suffix1 -->--|     |
-                   |                              |     |
-                   |---------------> suffix2 ----{1}------> {exit} --> (c)
-                   |                                    |
-                   |---------------> suffix3 -------------> {exit} --> (c)
-                   |                                    |
-                   `--> any command --{2}-> {warn} -->--|
-                                       |                |
-                                       |--> {noop} -->--|
-                                       |                |
-                                       |--> {call} -->--'
-                                       |
-                                       `------------------> {exit} --> (c)
-
-   This diagram takes the infix value into account to an extend, while
-still ignoring external state:
-
-     (c)
-      |        ,- {stay} ------<-,-<------------<-,-<---,
-     (+)       |                 |                |     |
-      |        |                 |                |     |
-      |        |   ,--> infix1 --|                |     |
-      |        |   |    |        |                |     |
-      |        |   ,--> infix2 --|                |     |
-      v        v   |    |        |                |     |
-      prefix -(c)-(+)-> infix3 --'                |     |
-                   |    |                         ^     |
-                   |    |                         |     |
-                   |---------------> suffix1 -->--|     |
-                   |    |             ^           |     |
-                   |    |             |           |     |
-                   |---------------> suffix2 ----{1}------> {exit} --> (c)
-                   |    |             ^                 |     |
-                   |    |             |                 |     v
-                   |    |             |                 |     |
-                   |---------------> suffix3 -------------> {exit} --> (c)
-                   |    |             ^                 |     |
-                   | sets             |                 |     v
-                   |    |             maybe             |     |
-                   |    |             used              |     |
-                   |    |             |                 |     |
-                   |    |     infix --'                 |     |
-                   |    `---> value                     |     |
-                   |           ^                        |     |
-                   |           |                        |     |
-                   |       hides                        |     |
-                   |           |                        |     |
-                   |           `--------------------------<---|
-                   |                                    |     |
-                   `--> any command --{2}-> {warn} -->--|     |
-                                       |                |     |
-                                       |--> {noop} -->--|     |
-                                       |                |     |
-                                       |--> {call} -->--'     ^
-                                       |                      |
-                                       `------------------> {exit} --> (c)
-
-   This diagram provides more information about the infix value and also
-takes external state into account.
-
-                                            ,----sets--- "anything"
-                                            |
-                                            v
-                           ,---------> external
-                           |           state
-                           |            | |
-                           |  initialized |                      ☉‿⚆
-                        sets         from |
-                           |            | maybe
-                           | ,----------' used
-                           | |            |
-     (c)                   | |            v
-      |        ,- {stay} --|---<-,-<------|-----<-,-<---,
-     (+)       |           | |   |        |       |     |
-      |        |           | v   |        |       |     |
-      |        |   ,--> infix1 --|        |       |     |
-      |        |   |       | |   |        |       |     |
-      |        |   |       | v   |        |       |     |
-      |        |   ,--> infix2 --|        |       |     |
-      |        |   |    | ^      |        |       |     |
-      v        v   |    | |      |        |       |     |
-      prefix -(c)-(+)-> infix3 --'        |       |     |
-                   |    | ^               |       ^     |
-                   |    | |               v       |     |
-                   |---------------> suffix1 -->--|     |
-                   |    | |           ^   |       |     |
-                   |    | |           |   v       |     |
-                   |---------------> suffix2 ----{1}------> {exit} --> (c)
-                   |    | |           ^   |             |     |
-                   |    | |           |   |             |     v
-                   |    | |           |   v             |     |
-                   |---------------> suffix3 -------------> {exit} --> (c)
-                   |    | |           ^                 |     |
-                   | sets |           |                 |     v
-                   |    | initalized  maybe             |     |
-                   |    | from        used              |     |
-                   |    | |           |                 |     |
-                   |    | `-- infix --'                 |     |
-                   |    `---> value -----------------------------> persistent
-                   |           ^ ^                      |     |    across
-                   |           | |                      |     |    invocations -,
-                   |       hides |                      |     |                 |
-                   |           | `----------------------------------------------'
-                   |           |                        |     |
-                   |           `--------------------------<---|
-                   |                                    |     |
-                   `--> any command --{2}-> {warn} -->--|     |
-                                       |                |     |
-                                       |--> {noop} -->--|     |
-                                       |                |     |
-                                       |--> {call} -->--'     ^
-                                       |                      |
-                                       `------------------> {exit} --> (c)
-
-   • ‘{1}’ Transients can be configured to be exited when a suffix
-     command is invoked.  The default is to do so for all suffixes
-     except for those that are common to all transients and which are
-     used to perform tasks such as providing help and saving the value
-     of the infix arguments for future invocations.  The behavior can
-     also be specified for individual suffix commands and may even
-     depend on state.
-
-   • ‘{2}’ Transients can be configured to allow the user to invoke
-     non-suffix commands.  The default is to not allow that and instead
-     warn the user.
-
-   Despite already being rather complex, even the last diagram leaves
-out many details.  Most importantly it implies that the decision whether
-to remain transient is made later than it actually is made (for the most
-part a function on ‘pre-command-hook’ is responsible).  But such
-implementation details are of little relevance to users and are covered
-elsewhere.
-
-\1f
-File: transient.info,  Node: Comparison With Other Packages,  Prev: Comparison With Prefix Keys and Prefix Arguments,  Up: Related Abstractions and Packages
-
-7.2 Comparison With Other Packages
-==================================
-
-7.2.1 Magit-Popup
------------------
-
-Transient is the successor to Magit-Popup (see *note
-(magit-popup)Top::).
-
-   One major difference between these two implementations of the same
-ideas is that while Transient uses transient keymaps and embraces the
-command-loop, Magit-Popup implemented an inferior mechanism that does
-not use transient keymaps and that instead of using the command-loop
-implements a naive alternative based on ‘read-char’.
-
-   Magit-Popup does not use classes and generic functions and defining a
-new command type is near impossible as it involves adding hard-coded
-special-cases to many functions.  Because of that only a single new type
-was added, which was not already part of Magit-Popup’s initial release.
-
-   A lot of things are hard-coded in Magit-Popup.  One random example is
-that the key bindings for switches must begin with "-" and those for
-options must begin with "=".
-
-7.2.2 Hydra
------------
-
-Hydra (see <https://github.com/abo-abo/hydra>) is another package that
-provides features similar to those of Transient.
-
-   Both packages use transient keymaps to make a set of commands
-temporarily available and show the available commands in a popup buffer.
-
-   A Hydra "body" is equivalent to a Transient "prefix" and a Hydra
-"head" is equivalent to a Transient "suffix".  Hydra has no equivalent
-of a Transient "infix".
-
-   Both hydras and transients can be used as simple command dispatchers.
-Used like this they are similar to regular prefix commands and prefix
-keys, except that the available commands are shown in the popup buffer.
-
-   (Another package that does this is ‘which-key’.  It does so
-automatically for any incomplete key sequence.  The advantage of that
-approach is that no additional work is necessary; the disadvantage is
-that the available commands are not organized semantically.)
-
-   Both Hydra and Transient provide features that go beyond simple
-command dispatchers:
-
-   • Invoking a command from a hydra does not necessarily exit the
-     hydra.  That makes it possible to invoke the same command again,
-     but using a shorter key sequence (i.e.  the key that was used to
-     enter the hydra does not have to be pressed again).
-
-     Transient supports that too, but for now this feature is not a
-     focus and the interface is a bit more complicated.  A very basic
-     example using the current interface:
-
-          (define-transient-command outline-navigate ()
-            :transient-suffix     'transient--do-stay
-            :transient-non-suffix 'transient--do-warn
-            [("p" "previous visible heading" outline-previous-visible-heading)
-             ("n" "next visible heading" outline-next-visible-heading)])
-
-   • Transient supports infix arguments; values that are set by infix
-     commands and then consumed by the invoked suffix command(s).
-
-     To my knowledge, Hydra does not support that.
-
-   Both packages make it possible to specify how exactly the available
-commands are outlined:
-
-   • With Hydra this is often done using an explicit format string,
-     which gives authors a lot of flexibility and makes it possible to
-     do fancy things.
-
-     The downside of this is that it becomes harder for a user to add
-     additional commands to an existing hydra and to change key
-     bindings.
-
-   • Transient allows the author of a transient to organize the commands
-     into groups and the use of generic functions allows authors of
-     transients to control exactly how a certain command type is
-     displayed.
-
-     However while Transient supports giving sections a heading it does
-     not currently support giving the displayed information more
-     structure by, for example, using box-drawing characters.
-
-     That could be implemented by defining a new group class, which lets
-     the author specify a format string.  It should be possible to
-     implement that without modifying any existing code, but it does not
-     currently exist.
-
-\1f
-File: transient.info,  Node: FAQ,  Next: Keystroke Index,  Prev: Related Abstractions and Packages,  Up: Top
-
-Appendix A FAQ
-**************
-
-A.1 Can I control how the popup buffer is displayed?
-====================================================
-
-Yes, see ‘transient-display-buffer-action’ in *note Other Options::.
-
-A.2 Why did some of the key bindings change?
-============================================
-
-You may have noticed that the bindings for some of the common commands
-do *not* have the prefix ‘C-x’ and that furthermore some of these
-commands are grayed out while others are not.  That unfortunately is a
-bit confusing if the section of common commands is not shown
-permanently, making the following explanation necessary.
-
-   The purpose of usually hiding that section but showing it after the
-user pressed the respective prefix key is to conserve space and not
-overwhelm users with too much noise, while allowing the user to quickly
-list common bindings on demand.
-
-   That however should not keep us from using the best possible key
-bindings.  The bindings that do use a prefix do so to avoid wasting too
-many non-prefix bindings, keeping them available for use in individual
-transients.  The bindings that do not use a prefix and that are *not*
-grayed out are very important bindings that are *always* available, even
-when invoking the "common command key prefix" or *any other*
-transient-specific prefix.  The non-prefix keys that *are* grayed out
-however, are not available when any incomplete prefix key sequence is
-active.  They do not use the "common command key prefix" because it is
-likely that users want to invoke them several times in a row and e.g.
-‘M-p M-p M-p’ is much more convenient than ‘C-x M-p C-x M-p C-x M-p’.
-
-   You may also have noticed that the "Set" command is bound to ‘C-x s’,
-while Magit-Popup used to bind ‘C-c C-c’ instead.  I have seen several
-users praise the latter binding (sic), so I did not change it
-willy-nilly.  The reason that I changed it is that using different
-prefix keys for different common commands, would have made the temporary
-display of the common commands even more confusing, i.e.  after pressing
-‘C-c’ all the ‘C-x ...’ bindings would be grayed out.
-
-   Using a single prefix for common commands key means that all other
-potential prefix keys can be used for transient-specific commands
-*without* the section of common commands also popping up.  ‘C-c’ in
-particular is a prefix that I want to (and already do) use for Magit,
-and also using that for a common command would prevent me from doing so.
-
-   (Also see the next question.)
-
-A.3 Why does ‘q’ not quit popups anymore?
-=========================================
-
-I agree that ‘q’ is a good binding for commands that quit something.
-This includes quitting whatever transient is currently active, but it
-also includes quitting whatever it is that some specific transient is
-controlling.  The transient ‘magit-blame’ for example binds ‘q’ to the
-command that turns ‘magit-blame-mode’ off.
-
-   So I had to decide if ‘q’ should quit the active transient (like
-Magit-Popup used to) or whether ‘C-g’ should do that instead, so that
-‘q’ could be bound in individual transient to whatever commands make
-sense for them.  Because all other letters are already reserved for use
-by individual transients, I have decided to no longer make an exception
-for ‘q’.
-
-   If you want to get ‘q’’s old binding back then you can do so.  Doing
-that is a bit more complicated than changing a single key binding, so I
-have implemented a function, ‘transient-bind-q-to-quit’ that makes the
-necessary changes.  See its doc string for more information.
-
-\1f
-File: transient.info,  Node: Keystroke Index,  Next: Command Index,  Prev: FAQ,  Up: Top
-
-Appendix B Keystroke Index
-**************************
-
-\0\b[index\0\b]
-* Menu:
-
-* C-g:                                   Aborting and Resuming Transients.
-                                                               (line 25)
-* C-g <1>:                               Aborting and Resuming Transients.
-                                                               (line 26)
-* C-h:                                   Getting Help for Suffix Commands.
-                                                               (line 10)
-* C-q:                                   Aborting and Resuming Transients.
-                                                               (line 36)
-* C-x C-s:                               Saving Values.        (line 25)
-* C-x l:                                 Enabling and Disabling Suffixes.
-                                                               (line 49)
-* C-x s:                                 Saving Values.        (line 20)
-* C-x t:                                 Common Suffix Commands.
-                                                               (line 16)
-* C-z:                                   Aborting and Resuming Transients.
-                                                               (line 42)
-* M-n:                                   Using History.        (line 16)
-* M-p:                                   Using History.        (line 11)
-* M-x transient-resume:                  Aborting and Resuming Transients.
-                                                               (line 55)
-
-\1f
-File: transient.info,  Node: Command Index,  Next: Function Index,  Prev: Keystroke Index,  Up: Top
-
-Appendix C Command Index
-************************
-
-\0\b[index\0\b]
-* Menu:
-
-* transient-help:                        Getting Help for Suffix Commands.
-                                                               (line 10)
-* transient-history-next:                Using History.        (line 16)
-* transient-history-prev:                Using History.        (line 11)
-* transient-quit-all:                    Aborting and Resuming Transients.
-                                                               (line 36)
-* transient-quit-one:                    Aborting and Resuming Transients.
-                                                               (line 26)
-* transient-quit-seq:                    Aborting and Resuming Transients.
-                                                               (line 25)
-* transient-resume:                      Aborting and Resuming Transients.
-                                                               (line 55)
-* transient-save:                        Saving Values.        (line 25)
-* transient-scroll-down arg:             Other Commands.       (line 18)
-* transient-scroll-up arg:               Other Commands.       (line 12)
-* transient-set:                         Saving Values.        (line 20)
-* transient-set-level:                   Enabling and Disabling Suffixes.
-                                                               (line 49)
-* transient-suspend:                     Aborting and Resuming Transients.
-                                                               (line 42)
-* transient-toggle-common:               Common Suffix Commands.
-                                                               (line 16)
-
-\1f
-File: transient.info,  Node: Function Index,  Next: Variable Index,  Prev: Command Index,  Up: Top
-
-Appendix D Function Index
-*************************
-
-\0\b[index\0\b]
-* Menu:
-
-* define-infix-argument:                 Defining Suffix and Infix Commands.
-                                                              (line  63)
-* define-infix-command:                  Defining Suffix and Infix Commands.
-                                                              (line  27)
-* define-suffix-command:                 Defining Suffix and Infix Commands.
-                                                              (line   9)
-* define-transient-command:              Defining Transients. (line  13)
-* transient--do-call:                    Transient State.     (line  98)
-* transient--do-exit:                    Transient State.     (line  94)
-* transient--do-noop:                    Transient State.     (line 125)
-* transient--do-quit-all:                Transient State.     (line 138)
-* transient--do-quit-one:                Transient State.     (line 132)
-* transient--do-replace:                 Transient State.     (line 102)
-* transient--do-stay:                    Transient State.     (line  85)
-* transient--do-suspend:                 Transient State.     (line 144)
-* transient--do-warn:                    Transient State.     (line 121)
-* transient--history-init:               Prefix Classes.      (line  10)
-* transient--insert-group:               Group Methods.       (line   6)
-* transient-append-suffix:               Modifying Existing Transients.
-                                                              (line  47)
-* transient-args:                        Using Infix Arguments.
-                                                              (line  22)
-* transient-format:                      Suffix Format Methods.
-                                                              (line   6)
-* transient-format-description:          Suffix Format Methods.
-                                                              (line  20)
-* transient-format-key:                  Suffix Format Methods.
-                                                              (line  15)
-* transient-format-value:                Suffix Format Methods.
-                                                              (line  25)
-* transient-get-suffix:                  Modifying Existing Transients.
-                                                              (line  60)
-* transient-infix-read:                  Suffix Value Methods.
-                                                              (line  17)
-* transient-infix-set:                   Suffix Value Methods.
-                                                              (line  39)
-* transient-infix-value:                 Suffix Value Methods.
-                                                              (line  43)
-* transient-init-scope:                  Suffix Value Methods.
-                                                              (line  57)
-* transient-init-value:                  Suffix Value Methods.
-                                                              (line   6)
-* transient-insert-suffix:               Modifying Existing Transients.
-                                                              (line  42)
-* transient-prompt:                      Suffix Value Methods.
-                                                              (line  34)
-* transient-remove-suffix:               Modifying Existing Transients.
-                                                              (line  56)
-* transient-replace-suffix:              Modifying Existing Transients.
-                                                              (line  51)
-* transient-scroll-down:                 Other Commands.      (line  18)
-* transient-scroll-up:                   Other Commands.      (line  12)
-* transient-show-help:                   Suffix Format Methods.
-                                                              (line  30)
-* transient-suffix-put:                  Modifying Existing Transients.
-                                                              (line  65)
-
-\1f
-File: transient.info,  Node: Variable Index,  Prev: Function Index,  Up: Top
-
-Appendix E Variable Index
-*************************
-
-\0\b[index\0\b]
-* Menu:
-
-* current-transient-command:             Using Infix Arguments.
-                                                              (line  47)
-* current-transient-prefix:              Using Infix Arguments.
-                                                              (line  41)
-* current-transient-suffixes:            Using Infix Arguments.
-                                                              (line  32)
-* transient-default-level:               Enabling and Disabling Suffixes.
-                                                              (line  38)
-* transient-detect-key-conflicts:        Other Options.       (line 136)
-* transient-display-buffer-action:       Other Options.       (line  46)
-* transient-enable-popup-navigation:     Other Options.       (line  28)
-* transient-highlight-mismatched-keys:   Other Options.       (line  95)
-* transient-history-file:                Using History.       (line  33)
-* transient-history-limit:               Using History.       (line  38)
-* transient-levels-file:                 Enabling and Disabling Suffixes.
-                                                              (line  44)
-* transient-mode-line-format:            Other Options.       (line  71)
-* transient-read-with-initial-input:     Other Options.       (line  87)
-* transient-show-common-commands:        Common Suffix Commands.
-                                                              (line  23)
-* transient-show-popup:                  Other Options.       (line   6)
-* transient-substitute-key-function:     Other Options.       (line 114)
-* transient-values-file:                 Saving Values.       (line  30)
-
-
-\1f
-Tag Table:
-Node: Top\7f751
-Node: Introduction\7f3675
-Node: Usage\7f9462
-Node: Invoking Transients\7f9796
-Node: Aborting and Resuming Transients\7f10828
-Node: Common Suffix Commands\7f13487
-Node: Saving Values\7f15241
-Ref: Saving Values-Footnote-1\7f16499
-Node: Using History\7f16769
-Node: Getting Help for Suffix Commands\7f18310
-Node: Enabling and Disabling Suffixes\7f19703
-Node: Other Commands\7f22993
-Node: Other Options\7f23949
-Node: Modifying Existing Transients\7f30562
-Node: Defining New Commands\7f33966
-Node: Defining Transients\7f34302
-Node: Binding Suffix and Infix Commands\7f36734
-Node: Group Specifications\7f37589
-Node: Suffix Specifications\7f40922
-Node: Defining Suffix and Infix Commands\7f44489
-Node: Using Infix Arguments\7f47674
-Node: Transient State\7f49894
-Node: Classes and Methods\7f55767
-Node: Group Classes\7f57981
-Node: Group Methods\7f59898
-Node: Prefix Classes\7f60543
-Node: Suffix Classes\7f61635
-Node: Suffix Methods\7f63879
-Node: Suffix Value Methods\7f64200
-Node: Suffix Format Methods\7f66960
-Node: Prefix Slots\7f68412
-Node: Suffix Slots\7f70889
-Node: Predicate Slots\7f73740
-Node: Related Abstractions and Packages\7f74988
-Node: Comparison With Prefix Keys and Prefix Arguments\7f75275
-Node: Comparison With Other Packages\7f85587
-Node: FAQ\7f89778
-Node: Keystroke Index\7f93512
-Node: Command Index\7f95146
-Node: Function Index\7f96933
-Node: Variable Index\7f101090
-\1f
-End Tag Table
-
-\1f
-Local Variables:
-coding: utf-8
-End:
diff --git a/elpa/transient-20200125.1308/dir b/elpa/transient-20200125.1308/dir
new file mode 100644 (file)
index 0000000..4d6ad7f
--- /dev/null
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+\1f
+File: dir,     Node: Top       This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "H" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Transient: (transient).       Transient Commands.
diff --git a/elpa/transient-20200125.1308/transient-autoloads.el b/elpa/transient-20200125.1308/transient-autoloads.el
new file mode 100644 (file)
index 0000000..3114fc1
--- /dev/null
@@ -0,0 +1,26 @@
+;;; transient-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "transient" "transient.el" (0 0 0 0))
+;;; Generated autoloads from transient.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "transient" '("transient-" "post-transient-hook" "current-transient-" "define-")))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("transient-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; transient-autoloads.el ends here
diff --git a/elpa/transient-20200125.1308/transient-pkg.el b/elpa/transient-20200125.1308/transient-pkg.el
new file mode 100644 (file)
index 0000000..ed112f1
--- /dev/null
@@ -0,0 +1,12 @@
+(define-package "transient" "20200125.1308" "Transient commands"
+  '((emacs "25.1"))
+  :keywords
+  '("bindings")
+  :authors
+  '(("Jonas Bernoulli" . "jonasNOSPAMbernoul.li"))
+  :maintainer
+  '("Jonas Bernoulli" . "jonasNOSPAMbernoul.li")
+  :url "https://github.com/magit/transient")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/transient-20200125.1308/transient.el b/elpa/transient-20200125.1308/transient.el
new file mode 100644 (file)
index 0000000..f816a20
--- /dev/null
@@ -0,0 +1,3189 @@
+;;; transient.el --- Transient commands          -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2020  Jonas Bernoulli
+
+;; Author: Jonas Bernoulli <jonasNOSPAMbernoul.li>
+;; Homepage: https://github.com/magit/transient
+;; Package-Requires: ((emacs "25.1"))
+;; Keywords: bindings
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3 of the License,
+;; or (at your option) any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; For a full copy of the GNU GPL see http://www.gnu.org/licenses.
+
+;;; Commentary:
+
+;; Taking inspiration from prefix keys and prefix arguments, Transient
+;; implements a similar abstraction involving a prefix command, infix
+;; arguments and suffix commands.  We could call this abstraction a
+;; "transient command", but because it always involves at least two
+;; commands (a prefix and a suffix) we prefer to call it just a
+;; "transient".
+
+;; When the user calls a transient prefix command, then a transient
+;; (temporary) keymap is activated, which binds the transient's infix
+;; and suffix commands, and functions that control the transient state
+;; are added to `pre-command-hook' and `post-command-hook'.  The
+;; available suffix and infix commands and their state are shown in
+;; the echo area until the transient is exited by invoking a suffix
+;; command.
+
+;; Calling an infix command causes its value to be changed, possibly
+;; by 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 state.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'eieio)
+(require 'format-spec)
+(require 'seq)
+
+(eval-when-compile
+  (require 'subr-x))
+
+(declare-function info 'info)
+(declare-function Man-find-section 'man)
+(declare-function Man-next-section 'man)
+(declare-function Man-getpage-in-background 'man)
+
+(defvar Man-notify-method)
+
+;;; Options
+
+(defgroup transient nil
+  "Transient commands."
+  :group 'extensions)
+
+(defcustom transient-show-popup t
+  "Whether to show the current transient in a popup buffer.
+
+- If t, then show the popup as soon as a transient prefix command
+  is invoked.
+
+- If nil, then do not show the popup unless the user explicitly
+  requests it, by pressing an incomplete prefix key sequence.
+
+- If a number, then delay displaying the popup and instead show
+  a brief one-line summary.  If zero or negative, then suppress
+  even showing that summary and display the pressed key only.
+
+  Show the popup when the user explicitly requests it by pressing
+  an incomplete prefix key sequence.  Unless zero, then also show
+  the popup after that many seconds of inactivity (using the
+  absolute value)."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type '(choice (const  :tag "instantly" t)
+                 (const  :tag "on demand" nil)
+                 (const  :tag "on demand (no summary)" 0)
+                 (number :tag "after delay" 1)))
+
+(defcustom transient-enable-popup-navigation nil
+  "Whether navigation commands are enabled in the transient popup.
+
+While a transient is active the transient popup buffer is not the
+current buffer, making it necessary to use dedicated commands to
+act on that buffer itself.  If this non-nil, then the following
+features are available:
+
+- \"<up>\" moves the cursor to the previous suffix.
+  \"<down>\" moves the cursor to the next suffix.
+  \"RET\" invokes the suffix the cursor is on.
+- \"<mouse-1>\" invokes the clicked on suffix.
+- \"C-s\" and \"C-r\" start isearch in the popup buffer."
+  :package-version '(transient . "0.2.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-display-buffer-action
+  '(display-buffer-in-side-window (side . bottom))
+  "The action used to display the transient popup buffer.
+
+The transient popup buffer is displayed in a window using
+
+  \(display-buffer buf transient-display-buffer-action)
+
+The value of this option has the form (FUNCTION . ALIST),
+where 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 ALIST.  See `display-buffer' for
+details.
+
+The default is (display-buffer-in-side-window (side . bottom)).
+This displays the window at the bottom of the selected frame.
+Another useful value is (display-buffer-below-selected).  This
+is what `magit-popup' used by default.  For more alternatives
+see info node `(elisp)Display Action Functions'.
+
+It may be possible to display the window in another frame, but
+whether that works in practice depends on the window-manager.
+If the window manager selects the new window (Emacs frame),
+then it doesn't work.
+
+If you change the value of this option, then you might also
+want to change the value of `transient-mode-line-format'."
+  :package-version '(transient . "0.2.0")
+  :group 'transient
+  :type '(cons (choice function (repeat :tag "Functions" function))
+               alist))
+
+(defcustom transient-mode-line-format (and window-system 'line)
+  "The mode-line format for the transient popup buffer.
+
+If nil, then the buffer has no mode-line.  If the buffer is not
+displayed right above the echo area, then this probably is not
+a good value.
+
+If `line' (the default), then the buffer also has no mode-line,
+but a thin line is drawn instead, using the background color of
+the face `transient-separator'.
+
+Otherwise this can be any mode-line format.
+See `mode-line-format' for details."
+  :package-version '(transient . "0.2.0")
+  :group 'transient
+  :type '(choice (const :tag "hide mode-line" nil)
+                 (const :tag "substitute thin line" line)
+                 (const :tag "name of prefix command"
+                        ("%e" mode-line-front-space
+                         mode-line-buffer-identification))
+                 (sexp  :tag "custom mode-line format")))
+
+(defcustom transient-show-common-commands nil
+  "Whether to show common transient suffixes in the popup buffer.
+
+These commands are always shown after typing the prefix key
+\"C-x\" when a transient command is active.  To toggle the value
+of this variable use \"C-x t\" when a transient is active."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-read-with-initial-input nil
+  "Whether to use the last history element as initial minibuffer input."
+  :package-version '(transient . "0.2.0")
+  :group 'transient
+  :type 'boolean)
+
+(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 shor-thand (e.g \"-v\").
+In the rare case that a short-hand is specified but does not
+match the key binding, then it is highlighed differently.
+
+The highlighting is done using using `transient-mismatched-key'
+and `transient-nonstandard-key'."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-substitute-key-function nil
+  "Function used to modify key bindings.
+
+This function is called with one argument, the prefix object,
+and must return a key binding description, either the existing
+key description it finds in the `key' slot, or a substitution.
+
+This is intended to let users replace certain prefix keys.  It
+could also be used to make other substitutions, but that is
+discouraged.
+
+For example, \"=\" is hard to reach using my custom keyboard
+layout, so I substitute \"(\" for that, which is easy to reach
+using a layout optimized for lisp.
+
+  (setq transient-substitute-key-function
+        (lambda (obj)
+          (let ((key (oref obj key)))
+            (if (string-match \"\\\\`\\\\(=\\\\)[a-zA-Z]\" key)
+                (replace-match \"(\" t t key 1)
+              key)))))"
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type '(choice (const :tag "Transform no keys (nil)" nil) function))
+
+(defcustom transient-detect-key-conflicts nil
+  "Whether to detect key binding conflicts.
+
+Conflicts are detected when a transient prefix command is invoked
+and results in an error, which prevents the transient from being
+used."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-force-fixed-pitch nil
+  "Whether to force used of monospaced font in popup buffer.
+
+Even if you use a proportional font for the `default' face,
+you might still want to use a monospaced font in transient's
+popup buffer.  Setting this option to t causes `default' to
+be remapped to `fixed-pitch' in that buffer."
+  :package-version '(transient . "0.2.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-default-level 4
+  "Control what suffix levels are made available by default.
+
+Each suffix command is placed on a level and each prefix command
+has a level, which controls which suffix commands are available.
+Integers between 1 and 7 (inclusive) are valid levels.
+
+The levels of individual transients and/or their individual
+suffixes can be changed individually, by invoking the prefix and
+then pressing \"C-x l\".
+
+The default level for both transients and their suffixes is 4.
+This option only controls the default for transients.  The default
+suffix level is always 4.  The author of a transient should place
+certain suffixes on a higher level if they expect that it won't be
+of use to most users, and they should place very important suffixes
+on a lower level so that they remain available even if the user
+lowers the transient level.
+
+\(Magit currently places nearly all suffixes on level 4 and lower
+levels are not used at all yet.  So for the time being you should
+not set a lower level here and using a higher level might not
+give you as many additional suffixes as you hoped.)"
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type '(choice (const :tag "1 - fewest suffixes" 1)
+                 (const 2)
+                 (const 3)
+                 (const :tag "4 - default" 4)
+                 (const 5)
+                 (const 6)
+                 (const :tag "7 - most suffixes" 7)))
+
+(defcustom transient-levels-file
+  (locate-user-emacs-file (convert-standard-filename "transient/levels.el"))
+  "File used to save levels of transients and their suffixes."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'file)
+
+(defcustom transient-values-file
+  (locate-user-emacs-file (convert-standard-filename "transient/values.el"))
+  "File used to save values of transients."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'file)
+
+(defcustom transient-history-file
+  (locate-user-emacs-file (convert-standard-filename "transient/history.el"))
+  "File used to save history of transients and their infixes."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'file)
+
+(defcustom transient-history-limit 10
+  "Number of history elements to keep when saving to file."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'integer)
+
+(defcustom transient-save-history t
+  "Whether to save history of transient commands when exiting Emacs."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'boolean)
+
+;;; Faces
+
+(defgroup transient-faces nil
+  "Faces used by Transient."
+  :group 'transient)
+
+(defface transient-heading '((t :inherit font-lock-keyword-face))
+  "Face used for headings."
+  :group 'transient-faces)
+
+(defface transient-key '((t :inherit font-lock-builtin-face))
+  "Face used for keys."
+  :group 'transient-faces)
+
+(defface transient-argument '((t :inherit font-lock-warning-face))
+  "Face used for enabled arguments."
+  :group 'transient-faces)
+
+(defface transient-value '((t :inherit font-lock-string-face))
+  "Face used for values."
+  :group 'transient-faces)
+
+(defface transient-inactive-argument '((t :inherit shadow))
+  "Face used for inactive arguments."
+  :group 'transient-faces)
+
+(defface transient-inactive-value '((t :inherit shadow))
+  "Face used for inactive values."
+  :group 'transient-faces)
+
+(defface transient-unreachable '((t :inherit shadow))
+  "Face used for suffixes unreachable from the current prefix sequence."
+  :group 'transient-faces)
+
+(defface transient-active-infix '((t :inherit secondary-selection))
+  "Face used for the infix for which the value is being read."
+  :group 'transient-faces)
+
+(defface transient-unreachable-key '((t :inherit shadow))
+  "Face used for keys unreachable from the current prefix sequence."
+  :group 'transient-faces)
+
+(defface transient-nonstandard-key '((t :underline t))
+  "Face optionally used to highlight keys conflicting with short-argument.
+Also see option `transient-highlight-mismatched-keys'."
+  :group 'transient-faces)
+
+(defface transient-mismatched-key '((t :underline t))
+  "Face optionally used to highlight keys without a short-argument.
+Also see option `transient-highlight-mismatched-keys'."
+  :group 'transient-faces)
+
+(defface transient-enabled-suffix
+  '((t :background "green" :foreground "black" :weight bold))
+  "Face used for enabled levels while editing suffix levels.
+See info node `(transient)Enabling and Disabling Suffixes'."
+  :group 'transient-faces)
+
+(defface transient-disabled-suffix
+  '((t :background "red" :foreground "black" :weight bold))
+  "Face used for disabled levels while editing suffix levels.
+See info node `(transient)Enabling and Disabling Suffixes'."
+  :group 'transient-faces)
+
+(defface transient-separator
+  `((((class color) (background light))
+     ,@(and (>= emacs-major-version 27) '(:extend t))
+     :background "grey80")
+    (((class color) (background  dark))
+     ,@(and (>= emacs-major-version 27) '(:extend t))
+     :background "grey30"))
+  "Face used to draw line below transient popup window.
+This is only used if `transient-mode-line-format' is `line'.
+Only the background color is significant."
+  :group 'transient-faces)
+
+;;; Persistence
+
+(defun transient--read-file-contents (file)
+  (with-demoted-errors "Transient error: %S"
+    (and (file-exists-p file)
+         (with-temp-buffer
+           (insert-file-contents file)
+           (read (current-buffer))))))
+
+(defun transient--pp-to-file (object file)
+  (make-directory (file-name-directory file) t)
+  (setq object (cl-sort object #'string< :key #'car))
+  (with-temp-file file
+    (let ((print-level nil)
+          (print-length nil))
+      (pp object (current-buffer)))))
+
+(defvar transient-values
+  (transient--read-file-contents transient-values-file)
+  "Values of transient commands.
+The value of this variable persists between Emacs sessions
+and you usually should not change it manually.")
+
+(defun transient-save-values ()
+  (transient--pp-to-file transient-values transient-values-file))
+
+(defvar transient-levels
+  (transient--read-file-contents transient-levels-file)
+  "Levels of transient commands.
+The value of this variable persists between Emacs sessions
+and you usually should not change it manually.")
+
+(defun transient-save-levels ()
+  (transient--pp-to-file transient-levels transient-levels-file))
+
+(defvar transient-history
+  (transient--read-file-contents transient-history-file)
+  "History of transient commands and infix arguments.
+The value of this variable persists between Emacs sessions
+\(unless `transient-save-history' is nil) and you usually
+should not change it manually.")
+
+(defun transient-save-history ()
+  (setq transient-history
+        (cl-sort (mapcar (pcase-lambda (`(,key . ,val))
+                           (cons key (seq-take (delete-dups val)
+                                               transient-history-limit)))
+                         transient-history)
+                 #'string< :key #'car))
+  (transient--pp-to-file transient-history transient-history-file))
+
+(defun transient-maybe-save-history ()
+  "Save the value of `transient-history'.
+If `transient-save-history' is nil, then do nothing."
+  (when transient-save-history
+    (transient-save-history)))
+
+(unless noninteractive
+  (add-hook 'kill-emacs-hook 'transient-maybe-save-history))
+
+;;; Classes
+;;;; Prefix
+
+(defclass transient-prefix ()
+  ((prototype   :initarg :prototype)
+   (command     :initarg :command)
+   (level       :initarg :level)
+   (variable    :initarg :variable    :initform nil)
+   (value) (default-value :initarg :value)
+   (scope       :initarg :scope       :initform nil)
+   (history     :initarg :history     :initform nil)
+   (history-pos :initarg :history-pos :initform 0)
+   (history-key :initarg :history-key :initform nil)
+   (man-page    :initarg :man-page    :initform nil)
+   (info-manual :initarg :info-manual :initform nil)
+   (transient-suffix     :initarg :transient-suffix     :initform nil)
+   (transient-non-suffix :initarg :transient-non-suffix :initform nil)
+   (incompatible         :initarg :incompatible         :initform nil))
+  "Transient prefix command.
+
+Each transient prefix command consists of a command, which is
+stored in a symbol's function slot and an object, which is
+stored in the `transient--prefix' property of the same symbol.
+
+When a transient prefix command is invoked, then a clone of that
+object is stored in the global variable `transient--prefix' and
+the prototype is stored in the clone's `prototype' slot.")
+
+;;;; Suffix
+
+(defclass transient-child ()
+  ((level
+    :initarg :level
+    :initform 1
+    :documentation "Enable if level of prefix is equal or greater.")
+   (if
+    :initarg :if
+    :initform nil
+    :documentation "Enable if predicate returns non-nil.")
+   (if-not
+    :initarg :if-not
+    :initform nil
+    :documentation "Enable if predicate returns nil.")
+   (if-non-nil
+    :initarg :if-non-nil
+    :initform nil
+    :documentation "Enable if variable's value is non-nil.")
+   (if-nil
+    :initarg :if-nil
+    :initform nil
+    :documentation "Enable if variable's value is nil.")
+   (if-mode
+    :initarg :if-mode
+    :initform nil
+    :documentation "Enable if major-mode matches value.")
+   (if-not-mode
+    :initarg :if-not-mode
+    :initform nil
+    :documentation "Enable if major-mode does not match value.")
+   (if-derived
+    :initarg :if-derived
+    :initform nil
+    :documentation "Enable if major-mode derives from value.")
+   (if-not-derived
+    :initarg :if-not-derived
+    :initform nil
+    :documentation "Enable if major-mode does not derive from value."))
+  "Abstract superclass for group and and suffix classes.
+
+It is undefined what happens if more than one `if*' predicate
+slot is non-nil."
+  :abstract t)
+
+(defclass transient-suffix (transient-child)
+  ((key         :initarg :key)
+   (command     :initarg :command)
+   (transient   :initarg :transient)
+   (format      :initarg :format      :initform " %k %d")
+   (description :initarg :description :initform nil))
+  "Superclass for suffix command.")
+
+(defclass transient-infix (transient-suffix)
+  ((transient                         :initform t)
+   (argument    :initarg :argument)
+   (shortarg    :initarg :shortarg)
+   (value                             :initform nil)
+   (multi-value :initarg :multi-value :initform nil)
+   (allow-empty :initarg :allow-empty :initform nil)
+   (history-key :initarg :history-key :initform nil)
+   (reader      :initarg :reader      :initform nil)
+   (prompt      :initarg :prompt      :initform nil)
+   (choices     :initarg :choices     :initform nil)
+   (format                            :initform " %k %d (%v)"))
+  "Transient infix command."
+  :abstract t)
+
+(defclass transient-argument (transient-infix) ()
+  "Abstract superclass for infix arguments."
+  :abstract t)
+
+(defclass transient-switch (transient-argument) ()
+  "Class used for command-line argument that can be turned on and off.")
+
+(defclass transient-option (transient-argument) ()
+  "Class used for command-line argument that can take a value.")
+
+(defclass transient-variable (transient-infix)
+  ((variable    :initarg :variable)
+   (format                            :initform " %k %d %v"))
+  "Abstract superclass for infix commands that set a variable."
+  :abstract t)
+
+(defclass transient-switches (transient-argument)
+  ((argument-format  :initarg :argument-format)
+   (argument-regexp  :initarg :argument-regexp))
+  "Class used for sets of mutually exclusive command-line switches.")
+
+(defclass transient-files (transient-infix) ()
+  "Class used for the \"--\" argument.
+All remaining arguments are treated as files.
+They become the value of this this argument.")
+
+;;;; Group
+
+(defclass transient-group (transient-child)
+  ((suffixes    :initarg :suffixes    :initform nil)
+   (hide        :initarg :hide        :initform nil)
+   (description :initarg :description :initform nil))
+  "Abstract superclass of all group classes."
+  :abstract t)
+
+(defclass transient-column (transient-group) ()
+  "Group class that displays each element on a separate line.")
+
+(defclass transient-row (transient-group) ()
+  "Group class that displays all elements on a single line.")
+
+(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.")
+
+(defclass transient-subgroups (transient-group) ()
+  "Group class that wraps other groups.
+
+Direct elements have to be groups whose elements have to be
+commands or strings.  This group inserts an empty line between
+subgroups.  The subgroups are responsible for displaying their
+elements themselves.")
+
+;;; Define
+
+(defmacro define-transient-command (name arglist &rest args)
+  "Define NAME as a transient prefix command.
+
+ARGLIST are the arguments that command takes.
+DOCSTRING is the documentation string and is optional.
+
+These arguments can optionally be followed by key-value pairs.
+Each key has to be a keyword symbol, either `:class' or a keyword
+argument supported by the constructor of that class.  The
+`transient-prefix' class is used if the class is not specified
+explicitly.
+
+GROUPs add key bindings for infix and suffix commands and specify
+how these bindings are presented in the popup buffer.  At least
+one GROUP has to be specified.  See info node `(transient)Binding
+Suffix and Infix Commands'.
+
+The BODY is optional.  If it is omitted, then ARGLIST is also
+ignored and the function definition becomes:
+
+  (lambda ()
+    (interactive)
+    (transient-setup \\='NAME))
+
+If BODY is specified, then it must begin with an `interactive'
+form that matches ARGLIST, and it must call `transient-setup'.
+It may however call that function only when some condition is
+satisfied; that is one of the reason why you might want to use
+an explicit BODY.
+
+All transients have a (possibly nil) value, which is exported
+when suffix commands are called, so that they can consume that
+value.  For some transients it might be necessary to have a sort
+of secondary value, called a scope.  Such a scope would usually
+be set in the commands `interactive' form and has to be passed
+to the setup function:
+
+  (transient-setup \\='NAME nil nil :scope SCOPE)
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... GROUP... [BODY...])"
+  (declare (debug (&define name lambda-list
+                           [&optional lambda-doc]
+                           [&rest keywordp sexp]
+                           [&rest vectorp]
+                           [&optional ("interactive" interactive) def-body]))
+           (doc-string 3))
+  (pcase-let ((`(,class ,slots ,suffixes ,docstr ,body)
+               (transient--expand-define-args args)))
+    `(progn
+       (defalias ',name
+         ,(if body
+              `(lambda ,arglist ,@body)
+            `(lambda ()
+               (interactive)
+               (transient-setup ',name))))
+       (put ',name 'interactive-only t)
+       (put ',name 'function-documentation ,docstr)
+       (put ',name 'transient--prefix
+            (,(or class 'transient-prefix) :command ',name ,@slots))
+       (put ',name 'transient--layout
+            ',(cl-mapcan (lambda (s) (transient--parse-child name s))
+                         suffixes)))))
+
+(defmacro define-suffix-command (name arglist &rest args)
+  "Define NAME as a transient suffix command.
+
+ARGLIST are the arguments that the command takes.
+DOCSTRING is the documentation string and is optional.
+
+These arguments can optionally be followed by key-value pairs.
+Each key has to be a keyword symbol, either `:class' or a
+keyword argument supported by the constructor of that class.
+The `transient-suffix' class is used if the class is not
+specified explicitly.
+
+The BODY must begin with an `interactive' form that matches
+ARGLIST.  The infix arguments are usually accessed by using
+`transient-args' inside `interactive'.
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... BODY...)"
+  (declare (debug (&define name lambda-list
+                           [&optional lambda-doc]
+                           [&rest keywordp sexp]
+                           ("interactive" interactive)
+                           def-body))
+           (doc-string 3))
+  (pcase-let ((`(,class ,slots ,_ ,docstr ,body)
+               (transient--expand-define-args args)))
+    `(progn
+       (defalias ',name (lambda ,arglist ,@body))
+       (put ',name 'interactive-only t)
+       (put ',name 'function-documentation ,docstr)
+       (put ',name 'transient--suffix
+            (,(or class 'transient-suffix) :command ',name ,@slots)))))
+
+(defmacro define-infix-command (name _arglist &rest args)
+  "Define NAME as a transient infix command.
+
+ARGLIST is always ignored and reserved for future use.
+DOCSTRING is the documentation string and is optional.
+
+The key-value pairs are mandatory.  All transient infix commands
+are equal to each other (but not eq), so it is meaningless to
+define an infix command without also setting at least `:class'
+and one other keyword (which it is depends on the used class,
+usually `:argument' or `:variable').
+
+Each key has to be a keyword symbol, either `:class' or a keyword
+argument supported by the constructor of that class.  The
+`transient-switch' class is used if the class is not specified
+explicitly.
+
+The function definitions is always:
+
+   (lambda ()
+     (interactive)
+     (let ((obj (transient-suffix-object)))
+       (transient-infix-set obj (transient-infix-read obj)))
+     (transient--show))
+
+`transient-infix-read' and `transient-infix-set' are generic
+functions.  Different infix commands behave differently because
+the concrete methods are different for different infix command
+classes.  In rare case the above command function might not be
+suitable, even if you define your own infix command class.  In
+that case you have to use `transient-suffix-command' to define
+the infix command and use t as the value of the `:transient'
+keyword.
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)"
+  (declare (debug (&define name lambda-list
+                           [&optional lambda-doc]
+                           [&rest keywordp sexp]))
+           (doc-string 3))
+  (pcase-let ((`(,class ,slots ,_ ,docstr ,_)
+               (transient--expand-define-args args)))
+    `(progn
+       (defalias ',name ,(transient--default-infix-command))
+       (put ',name 'interactive-only t)
+       (put ',name 'function-documentation ,docstr)
+       (put ',name 'transient--suffix
+            (,(or class 'transient-switch) :command ',name ,@slots)))))
+
+(defalias 'define-infix-argument 'define-infix-command
+  "Define NAME as a transient infix command.
+
+Only use this alias to define an infix command that actually
+sets an infix argument.  To define a infix command that, for
+example, sets a variable use `define-infix-command' instead.
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)")
+
+(defun transient--expand-define-args (args)
+  (let (class keys suffixes docstr)
+    (when (stringp (car args))
+      (setq docstr (pop args)))
+    (while (keywordp (car args))
+      (let ((k (pop args))
+            (v (pop args)))
+        (if (eq k :class)
+            (setq class v)
+          (push k keys)
+          (push v keys))))
+    (while (vectorp (car args))
+      (push (pop args) suffixes))
+    (list (if (eq (car-safe class) 'quote)
+              (cadr class)
+            class)
+          (nreverse keys)
+          (nreverse suffixes)
+          docstr
+          args)))
+
+(defun transient--parse-child (prefix spec)
+  (cl-etypecase spec
+    (vector  (when-let ((c (transient--parse-group  prefix spec))) (list c)))
+    (list    (when-let ((c (transient--parse-suffix prefix spec))) (list c)))
+    (string  (list spec))))
+
+(defun transient--parse-group (prefix spec)
+  (setq spec (append spec nil))
+  (cl-symbol-macrolet
+      ((car (car spec))
+       (pop (pop spec)))
+    (let (level class args)
+      (when (integerp car)
+        (setq level pop))
+      (when (stringp car)
+        (setq args (plist-put args :description pop)))
+      (while (keywordp car)
+        (let ((k pop))
+          (if (eq k :class)
+              (setq class pop)
+            (setq args (plist-put args k pop)))))
+      (vector (or level (oref-default 'transient-child level))
+              (or class
+                  (if (vectorp car)
+                      'transient-columns
+                    'transient-column))
+              args
+              (cl-mapcan (lambda (s) (transient--parse-child prefix s)) spec)))))
+
+(defun transient--parse-suffix (prefix spec)
+  (let (level class args)
+    (cl-symbol-macrolet
+        ((car (car spec))
+         (pop (pop spec)))
+      (when (integerp car)
+        (setq level pop))
+      (when (or (stringp car)
+                (vectorp car))
+        (setq args (plist-put args :key pop)))
+      (when (or (stringp car)
+                (eq (car-safe car) 'lambda)
+                (and (symbolp car)
+                     (not (commandp car))
+                     (commandp (cadr spec))))
+        (setq args (plist-put args :description pop)))
+      (cond
+       ((keywordp car)
+        (error "Need command, got %S" car))
+       ((symbolp car)
+        (setq args (plist-put args :command pop)))
+       ((or (stringp car)
+            (and car (listp car)))
+        (let ((arg pop))
+          (cl-typecase arg
+            (list
+             (setq args (plist-put args :shortarg (car  arg)))
+             (setq args (plist-put args :argument (cadr arg)))
+             (setq arg  (cadr arg)))
+            (string
+             (when-let ((shortarg (transient--derive-shortarg arg)))
+               (setq args (plist-put args :shortarg shortarg)))
+             (setq args (plist-put args :argument arg))))
+          (setq args (plist-put args :command
+                                (intern (format "transient:%s:%s"
+                                                prefix arg))))
+          (cond ((and car (not (keywordp car)))
+                 (setq class 'transient-option)
+                 (setq args (plist-put args :reader pop)))
+                ((not (string-suffix-p "=" arg))
+                 (setq class 'transient-switch))
+                (t
+                 (setq class 'transient-option)
+                 (setq args (plist-put args :reader 'read-string))))))
+       (t
+        (error "Needed command or argument, got %S" car)))
+      (while (keywordp car)
+        (let ((k pop))
+          (cl-case k
+            (:class (setq class pop))
+            (:level (setq level pop))
+            (t (setq args (plist-put args k pop)))))))
+    (unless (plist-get args :key)
+      (when-let ((shortarg (plist-get args :shortarg)))
+        (setq args (plist-put args :key shortarg))))
+    (list (or level (oref-default 'transient-child level))
+          (or class 'transient-suffix)
+          args)))
+
+(defun transient--default-infix-command ()
+  (cons 'lambda
+        '(()
+          (interactive)
+          (let ((obj (transient-suffix-object)))
+            (transient-infix-set obj (transient-infix-read obj)))
+          (transient--show))))
+
+(defun transient--ensure-infix-command (obj)
+  (let ((cmd (oref obj command)))
+    (unless (or (commandp cmd)
+                (get cmd 'transient--infix-command))
+      (if (or (cl-typep obj 'transient-switch)
+              (cl-typep obj 'transient-option))
+          (put cmd 'transient--infix-command
+               (transient--default-infix-command))
+        ;; This is not an anonymous infix argument.
+        (error "Suffix %s is not defined or autoloaded as a command" cmd)))))
+
+(defun transient--derive-shortarg (arg)
+  (save-match-data
+    (and (string-match "\\`\\(-[a-zA-Z]\\)\\(\\'\\|=\\)" arg)
+         (match-string 1 arg))))
+
+;;; Edit
+
+(defun transient--insert-suffix (prefix loc suffix action)
+  (let* ((suf (cl-etypecase suffix
+                (vector (transient--parse-group  prefix suffix))
+                (list   (transient--parse-suffix prefix suffix))
+                (string suffix)))
+         (mem (transient--layout-member loc prefix))
+         (elt (car mem)))
+    (cond
+     ((not mem)
+      (message "Cannot insert %S into %s; %s not found"
+               suffix prefix loc))
+     ((or (and (vectorp suffix) (not (vectorp elt)))
+          (and (listp   suffix) (vectorp elt))
+          (and (stringp suffix) (vectorp elt)))
+      (message "Cannot place %S into %s at %s; %s"
+               suffix prefix loc
+               "suffixes and groups cannot be siblings"))
+     (t
+      (when (and (listp suffix)
+                 (listp elt))
+        (let ((key (transient--spec-key suf)))
+          (if (equal (transient--kbd key)
+                     (transient--kbd (transient--spec-key elt)))
+              (setq action 'replace)
+            (transient-remove-suffix prefix key))))
+      (cl-ecase action
+        (insert  (setcdr mem (cons elt (cdr mem)))
+                 (setcar mem suf))
+        (append  (setcdr mem (cons suf (cdr mem))))
+        (replace (setcar mem suf)))))))
+
+(defun transient-insert-suffix (prefix loc suffix)
+  "Insert a SUFFIX into PREFIX before LOC.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+  the same forms as expected by `define-transient-command').
+LOC is a command, a key vector, a key description (a string
+  as returned by `key-description'), or a coordination list
+  (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+  (declare (indent defun))
+  (transient--insert-suffix prefix loc suffix 'insert))
+
+(defun transient-append-suffix (prefix loc suffix)
+  "Insert a SUFFIX into PREFIX after LOC.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+  the same forms as expected by `define-transient-command').
+LOC is a command, a key vector, a key description (a string
+  as returned by `key-description'), or a coordination list
+  (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+  (declare (indent defun))
+  (transient--insert-suffix prefix loc suffix 'append))
+
+(defun transient-replace-suffix (prefix loc suffix)
+  "Replace the suffix at LOC in PREFIX with SUFFIX.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+  the same forms as expected by `define-transient-command').
+LOC is a command, a key vector, a key description (a string
+  as returned by `key-description'), or a coordination list
+  (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+  (declare (indent defun))
+  (transient--insert-suffix prefix loc suffix 'replace))
+
+(defun transient-remove-suffix (prefix loc)
+  "Remove the suffix or group at LOC in PREFIX.
+PREFIX is a prefix command, a symbol.
+LOC is a command, a key vector, a key description (a string
+  as returned by `key-description'), or a coordination list
+  (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+  (declare (indent defun))
+  (transient--layout-member loc prefix 'remove))
+
+(defun transient-get-suffix (prefix loc)
+  "Return the suffix or group at LOC in PREFIX.
+PREFIX is a prefix command, a symbol.
+LOC is a command, a key vector, a key description (a string
+  as returned by `key-description'), or a coordination list
+  (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+  (if-let ((mem (transient--layout-member loc prefix)))
+      (car mem)
+    (error "%s not found in %s" loc prefix)))
+
+(defun transient-suffix-put (prefix loc prop value)
+  "Edit the suffix at LOC in PREFIX, setting PROP to VALUE.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+  the same forms as expected by `define-transient-command').
+LOC is a command, a key vector, a key description (a string
+  as returned by `key-description'), or a coordination list
+  (whose last element may also be a command or key).
+See info node `(transient)Modifying Existing Transients'."
+  (let ((suf (transient-get-suffix prefix loc)))
+    (setf (elt suf 2)
+          (plist-put (elt suf 2) prop value))))
+
+(defun transient--layout-member (loc prefix &optional remove)
+  (let ((val (or (get prefix 'transient--layout)
+                 (error "%s is not a transient command" prefix))))
+    (when (listp loc)
+      (while (integerp (car loc))
+        (let* ((children (if (vectorp val) (aref val 3) val))
+               (mem (transient--nthcdr (pop loc) children)))
+          (if (and remove (not loc))
+              (let ((rest (delq (car mem) children)))
+                (if (vectorp val)
+                    (aset val 3 rest)
+                  (put prefix 'transient--layout rest))
+                (setq val nil))
+            (setq val (if loc (car mem) mem)))))
+      (setq loc (car loc)))
+    (if loc
+        (transient--layout-member-1 (transient--kbd loc) val remove)
+      val)))
+
+(defun transient--layout-member-1 (loc layout remove)
+  (cond ((listp layout)
+         (seq-some (lambda (elt) (transient--layout-member-1 loc elt remove))
+                   layout))
+        ((vectorp (car (aref layout 3)))
+         (seq-some (lambda (elt) (transient--layout-member-1 loc elt remove))
+                   (aref layout 3)))
+        (remove
+         (aset layout 3
+               (delq (car (transient--group-member loc layout))
+                     (aref layout 3)))
+         nil)
+        (t (transient--group-member loc layout))))
+
+(defun transient--group-member (loc group)
+  (cl-member-if (lambda (suffix)
+                  (and (listp suffix)
+                       (let* ((def (nth 2 suffix))
+                              (cmd (plist-get def :command)))
+                         (if (symbolp loc)
+                             (eq cmd loc)
+                           (equal (transient--kbd
+                                   (or (plist-get def :key)
+                                       (transient--command-key cmd)))
+                                  loc)))))
+                (aref group 3)))
+
+(defun transient--kbd (keys)
+  (when (vectorp keys)
+    (setq keys (key-description keys)))
+  (when (stringp keys)
+    (setq keys (kbd keys)))
+  keys)
+
+(defun transient--spec-key (spec)
+  (let ((plist (nth 2 spec)))
+    (or (plist-get plist :key)
+        (transient--command-key
+         (plist-get plist :command)))))
+
+(defun transient--command-key (cmd)
+  (when-let ((obj (get cmd 'transient--suffix)))
+    (cond ((slot-boundp obj 'key)
+           (oref obj key))
+          ((slot-exists-p obj 'shortarg)
+           (if (slot-boundp obj 'shortarg)
+               (oref obj shortarg)
+             (transient--derive-shortarg (oref obj argument)))))))
+
+(defun transient--nthcdr (n list)
+  (nthcdr (if (< n 0) (- (length list) (abs n)) n) list))
+
+;;; Variables
+
+(defvar current-transient-prefix nil
+  "The transient from which this suffix command was invoked.
+This is an object representing that transient, use
+`current-transient-command' to get the respective command.")
+
+(defvar current-transient-command nil
+  "The transient from which this suffix command was invoked.
+This is a symbol representing that transient, use
+`current-transient-object' to get the respective object.")
+
+(defvar current-transient-suffixes nil
+  "The suffixes of the transient from which this suffix command was invoked.
+This is a list of objects.  Usually it is sufficient to instead
+use the function `transient-args', which returns a list of
+values.  In complex cases it might be necessary to use this
+variable instead.")
+
+(defvar post-transient-hook nil
+  "Hook run after exiting a transient.")
+
+(defvar transient--prefix nil)
+(defvar transient--layout nil)
+(defvar transient--suffixes nil)
+
+(defconst transient--stay t   "Do not exist the transient.")
+(defconst transient--exit nil "Do exit the transient.")
+
+(defvar transient--exitp nil "Whether to exit the transient.")
+(defvar transient--showp nil "Whether the transient is show in a popup buffer.")
+(defvar transient--helpp nil "Whether help-mode is active.")
+(defvar transient--editp nil "Whether edit-mode is active.")
+
+(defvar transient--active-infix nil "The active infix awaiting user input.")
+
+(defvar transient--timer nil)
+
+(defvar transient--stack nil)
+
+(defvar transient--buffer-name " *transient*"
+  "Name of the transient buffer.")
+
+(defvar transient--window nil
+  "The window used to display the transient popup.")
+
+(defvar transient--original-window nil
+  "The window that was selected before the transient was invoked.
+Usually it remains selected while the transient is active.")
+
+(define-obsolete-variable-alias 'transient--source-buffer
+  'transient--original-buffer "Transient 0.2.0")
+
+(defvar transient--original-buffer nil
+  "The buffer that was current before the transient was invoked.
+Usually it remains current while the transient is active.")
+
+(defvar transient--debug nil "Whether put debug information into *Messages*.")
+
+(defvar transient--history nil)
+
+;;; Identities
+
+(defun transient-suffix-object (&optional command)
+  "Return the object associated with the current suffix command.
+
+Each suffix commands is associated with an object, which holds
+additional information about the suffix, such as its value (in
+the case of an infix command, which is a kind of suffix command).
+
+This function is intended to be called by infix commands, whose
+command definition usually (at least when defined using
+`define-infix-command') is this:
+
+   (lambda ()
+     (interactive)
+     (let ((obj (transient-suffix-object)))
+       (transient-infix-set obj (transient-infix-read obj)))
+     (transient--show))
+
+\(User input is read outside of `interactive' to prevent the
+command from being added to `command-history'.  See #23.)
+
+Such commands need to be able to access their associated object
+to guide how `transient-infix-read' reads the new value and to
+store the read value.  Other suffix commands (including non-infix
+commands) may also need the object to guide their behavior.
+
+This function attempts to return the object associated with the
+current suffix command even if the suffix command was not invoked
+from a transient.  (For some suffix command that is a valid thing
+to do, for others it is not.)  In that case nil may be returned
+if the command was not defined using one of the macros intended
+to define such commands.
+
+The optional argument COMMAND is intended for internal use.  If
+you are contemplating using it in your own code, then you should
+probably use this instead:
+
+  (get COMMAND 'transient--suffix)"
+  (if transient--prefix
+      (cl-find-if (lambda (obj)
+                    (eq (transient--suffix-command obj)
+                        (or command this-original-command)))
+                  transient--suffixes)
+    (when-let ((obj (get (or command this-command) 'transient--suffix))
+               (obj (clone obj)))
+      (transient-init-scope obj)
+      (transient-init-value obj)
+      obj)))
+
+(defun transient--suffix-command (arg)
+  "Return the command specified by ARG.
+
+Given a suffix specified by ARG, this function returns the
+respective command or a symbol that represents it.  It could
+therefore be considered the inverse of `transient-suffix-object'.
+
+Unlike that function it is only intended for internal use though,
+and it is more complicated to describe because of some internal
+tricks it has to account for.  You do not actually have to know
+any of this.
+
+ARG can be a `transient-suffix' object, a symbol representing a
+command, or a command (which can be either a fbound symbol or a
+lambda expression).
+
+If it is an object, then the value of its `command' slot is used
+as follows.  If ARG satisfies `commandp', then that is returned.
+Otherwise it is assumed to be a symbol that merely represents the
+command.  In that case the lambda expression that is stored in
+the symbols `transient--infix-command' property is returned.
+
+Therefore, if ARG is an object, then this function always returns
+something that is callable as a command.
+
+ARG can also be something that is callable as a function.  If it
+is a symbol, then that is returned.  Otherwise it is a lambda
+expression and a symbol that merely representing that command is
+returned.
+
+Therefore, if ARG is something that is callable as a command,
+then this function always returns a symbol that is, or merely
+represents that command.
+
+The reason that there are \"symbols that merely represent a
+command\" is that by avoiding binding a symbol as a command we
+can prevent it from being offered as a completion candidate for
+`execute-extended-command'.  That is useful for infix arguments,
+which usually do not work correctly unless called from a
+transient.  Unfortunately this only works for infix arguments
+that are defined inline in the definition of a transient prefix
+command; explicitly defined infix arguments continue to pollute
+the command namespace.  It would be better if all this were made
+unnecessary by a `execute-extended-command-ignore' symbol property
+but unfortunately that does not exist (yet?)."
+  (if (transient-suffix--eieio-childp arg)
+      (let ((sym (oref arg command)))
+        (if (commandp sym)
+            sym
+          (get sym 'transient--infix-command)))
+    (if (symbolp arg)
+        arg
+      ;; ARG is an interactive lambda.  The symbol returned by this
+      ;; is not actually a command, just a symbol representing it
+      ;; for purposes other than invoking it as a command.
+      (oref (transient-suffix-object) command))))
+
+;;; Keymaps
+
+(defvar transient-base-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "ESC ESC ESC") 'transient-quit-all)
+    (define-key map (kbd "C-g") 'transient-quit-one)
+    (define-key map (kbd "C-q") 'transient-quit-all)
+    (define-key map (kbd "C-z") 'transient-suspend)
+    (define-key map (kbd "C-v") 'transient-scroll-up)
+    (define-key map (kbd "M-v") 'transient-scroll-down)
+    (define-key map [next]      'transient-scroll-up)
+    (define-key map [prior]     'transient-scroll-down)
+    map)
+  "Parent of other keymaps used by Transient.
+
+This is the parent keymap of all the keymaps that are used in
+all transients: `transient-map' (which in turn is the parent
+of the transient-specific keymaps), `transient-edit-map' and
+`transient-sticky-map'.
+
+If you change a binding here, then you might also have to edit
+`transient-sticky-map' and `transient-common-commands'.  While
+the latter isn't a proper transient prefix command, it can be
+edited using the same functions as used for transients.")
+
+(defvar transient-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map transient-base-map)
+    (define-key map (kbd "C-p") 'universal-argument)
+    (define-key map (kbd "C--") 'negative-argument)
+    (define-key map (kbd "C-t") 'transient-show)
+    (define-key map (kbd "?")   'transient-help)
+    (define-key map (kbd "C-h") 'transient-help)
+    (define-key map (kbd "M-p") 'transient-history-prev)
+    (define-key map (kbd "M-n") 'transient-history-next)
+    map)
+  "Top-level keymap used by all transients.")
+
+(defvar transient-edit-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map transient-base-map)
+    (define-key map (kbd "?")     'transient-help)
+    (define-key map (kbd "C-h")   'transient-help)
+    (define-key map (kbd "C-x l") 'transient-set-level)
+    map)
+  "Keymap that is active while a transient in is in \"edit mode\".")
+
+(defvar transient-sticky-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map transient-base-map)
+    (define-key map (kbd "C-g") 'transient-quit-seq)
+    map)
+  "Keymap that is active while an incomplete key sequence is active.")
+
+(defvar transient--common-command-prefixes '(?\C-x))
+
+(put 'transient-common-commands
+     'transient--layout
+     (cl-mapcan
+      (lambda (s) (transient--parse-child 'transient-common-commands s))
+      '([:hide (lambda ()
+                 (and (not (memq (car transient--redisplay-key)
+                                 transient--common-command-prefixes))
+                      (not transient-show-common-commands)))
+         ["Value commands"
+          ("C-x s  " "Set"            transient-set)
+          ("C-x C-s" "Save"           transient-save)
+          ("M-p    " "Previous value" transient-history-prev)
+          ("M-n    " "Next value"     transient-history-next)]
+         ["Sticky commands"
+          ;; Like `transient-sticky-map' except that
+          ;; "C-g" has to be bound to a different command.
+          ("C-g" "Quit prefix or transient" transient-quit-one)
+          ("C-q" "Quit transient stack"     transient-quit-all)
+          ("C-z" "Suspend transient stack"  transient-suspend)]
+         ["Customize"
+          ("C-x t" transient-toggle-common
+           :description (lambda ()
+                          (if transient-show-common-commands
+                              "Hide common commands"
+                            "Show common permanently")))
+          ("C-x l" "Show/hide suffixes" transient-set-level)]])))
+
+(defvar transient-predicate-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [handle-switch-frame]     'transient--do-suspend)
+    (define-key map [transient-suspend]       'transient--do-suspend)
+    (define-key map [transient-help]          'transient--do-stay)
+    (define-key map [transient-set-level]     'transient--do-stay)
+    (define-key map [transient-history-prev]  'transient--do-stay)
+    (define-key map [transient-history-next]  'transient--do-stay)
+    (define-key map [universal-argument]      'transient--do-stay)
+    (define-key map [negative-argument]       'transient--do-stay)
+    (define-key map [digit-argument]          'transient--do-stay)
+    (define-key map [transient-quit-all]      'transient--do-quit-all)
+    (define-key map [transient-quit-one]      'transient--do-quit-one)
+    (define-key map [transient-quit-seq]      'transient--do-stay)
+    (define-key map [transient-show]          'transient--do-stay)
+    (define-key map [transient-update]        'transient--do-stay)
+    (define-key map [transient-toggle-common] 'transient--do-stay)
+    (define-key map [transient-set]           'transient--do-call)
+    (define-key map [transient-save]          'transient--do-call)
+    (define-key map [describe-key-briefly]    'transient--do-stay)
+    (define-key map [describe-key]            'transient--do-stay)
+    (define-key map [transient-scroll-up]     'transient--do-stay)
+    (define-key map [transient-scroll-down]   'transient--do-stay)
+    (define-key map [mwheel-scroll]           'transient--do-stay)
+    (define-key map [transient-noop]              'transient--do-noop)
+    (define-key map [transient-mouse-push-button] 'transient--do-move)
+    (define-key map [transient-push-button]       'transient--do-move)
+    (define-key map [transient-backward-button]   'transient--do-move)
+    (define-key map [transient-forward-button]    'transient--do-move)
+    (define-key map [transient-isearch-backward]  'transient--do-move)
+    (define-key map [transient-isearch-forward]   'transient--do-move)
+    map)
+  "Base keymap used to map common commands to their transient behavior.
+
+The \"transient behavior\" of a command controls, among other
+things, whether invoking the command causes the transient to be
+exited or not and whether infix arguments are exported before
+doing so.
+
+Each \"key\" is a command that is common to all transients and
+that is bound in `transient-map', `transient-edit-map',
+`transient-sticky-map' and/or `transient-common-command'.
+
+Each binding is a \"pre-command\", a function that controls the
+transient behavior of the respective command.
+
+For transient commands that are bound in individual transients,
+the transient behavior is specified using the `:transient' slot
+of the corresponding object.")
+
+(defvar transient-popup-navigation-map)
+
+(defvar transient--transient-map nil)
+(defvar transient--predicate-map nil)
+(defvar transient--redisplay-map nil)
+(defvar transient--redisplay-key nil)
+
+(defun transient--push-keymap (map)
+  (transient--debug "   push %s%s" map (if (symbol-value map) "" " VOID"))
+  (with-demoted-errors "transient--push-keymap: %S"
+    (internal-push-keymap (symbol-value map) 'overriding-terminal-local-map)))
+
+(defun transient--pop-keymap (map)
+  (transient--debug "   pop  %s%s" map (if (symbol-value map) "" " VOID"))
+  (with-demoted-errors "transient--pop-keymap: %S"
+    (internal-pop-keymap (symbol-value map) 'overriding-terminal-local-map)))
+
+(defun transient--make-transient-map ()
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map (if transient--editp
+                               transient-edit-map
+                             transient-map))
+    (dolist (obj transient--suffixes)
+      (let ((key (oref obj key)))
+        (when (vectorp key)
+          (setq key (key-description key))
+          (oset obj key key))
+        (when transient-substitute-key-function
+          (setq key (save-match-data
+                      (funcall transient-substitute-key-function obj)))
+          (oset obj key key))
+        (let ((kbd (kbd key))
+              (cmd (transient--suffix-command obj)))
+          (when-let ((conflict (and transient-detect-key-conflicts
+                                    (transient--lookup-key map kbd))))
+            (unless (eq cmd conflict)
+              (transient--emergency-exit)
+              (error "Cannot bind %S to %s and also %s"
+                     (string-trim key)
+                     cmd conflict)))
+          (define-key map kbd cmd))))
+    (when transient-enable-popup-navigation
+      (setq map
+            (make-composed-keymap (list map transient-popup-navigation-map))))
+    map))
+
+(defun transient--make-predicate-map ()
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map transient-predicate-map)
+    (dolist (obj transient--suffixes)
+      (let* ((cmd (transient--suffix-command obj))
+             (sub-prefix (and (symbolp cmd) (get cmd 'transient--prefix))))
+        (if (slot-boundp obj 'transient)
+            (define-key map (vector cmd)
+              (let ((do (oref obj transient)))
+                (pcase do
+                  (`t (if sub-prefix
+                          'transient--do-replace
+                        'transient--do-stay))
+                  (`nil 'transient--do-exit)
+                  (_ do))))
+          (unless (lookup-key transient-predicate-map (vector cmd))
+            (define-key map (vector cmd)
+              (if sub-prefix
+                  'transient--do-replace
+                (or (oref transient--prefix transient-suffix)
+                    'transient--do-exit)))))))
+    map))
+
+(defun transient--make-redisplay-map ()
+  (setq transient--redisplay-key
+        (cl-case this-command
+          (transient-update
+           (setq transient--showp t)
+           (setq unread-command-events
+                 (listify-key-sequence (this-single-command-raw-keys))))
+          (transient-quit-seq
+           (setq unread-command-events
+                 (butlast (listify-key-sequence
+                           (this-single-command-raw-keys))
+                          2))
+           (butlast transient--redisplay-key))
+          (t nil)))
+  (let ((topmap (make-sparse-keymap))
+        (submap (make-sparse-keymap)))
+    (when transient--redisplay-key
+      (define-key topmap (vconcat transient--redisplay-key) submap)
+      (set-keymap-parent submap transient-sticky-map))
+    (map-keymap-internal
+     (lambda (key def)
+       (when (and (not (eq key ?\e))
+                  (listp def)
+                  (keymapp def))
+         (define-key topmap (vconcat transient--redisplay-key (list key))
+           'transient-update)))
+     (if transient--redisplay-key
+         (lookup-key transient--transient-map (vconcat transient--redisplay-key))
+       transient--transient-map))
+    topmap))
+
+;;; Setup
+
+(defun transient-setup (&optional name layout edit &rest params)
+  "Setup the transient specified by NAME.
+
+This function is called by transient prefix commands to setup the
+transient.  In that case NAME is mandatory, LAYOUT and EDIT must
+be nil and PARAMS may be (but usually is not) used to set e.g. the
+\"scope\" of the transient (see `transient-define-prefix').
+
+This function is also called internally in which case LAYOUT and
+EDIT may be non-nil."
+  (transient--debug 'setup)
+  (cond
+   ((not name)
+    ;; Switching between regular and edit mode.
+    (transient--pop-keymap 'transient--transient-map)
+    (transient--pop-keymap 'transient--redisplay-map)
+    (setq name (oref transient--prefix command))
+    (setq params (list :scope (oref transient--prefix scope))))
+   ((not (or layout                      ; resuming parent/suspended prefix
+             current-transient-command)) ; entering child prefix
+    (transient--stack-zap))              ; replace suspended prefix, if any
+   (edit
+    ;; Returning from help to edit.
+    (setq transient--editp t)))
+  (transient--init-objects name layout params)
+  (transient--history-init transient--prefix)
+  (setq transient--predicate-map (transient--make-predicate-map))
+  (setq transient--transient-map (transient--make-transient-map))
+  (setq transient--redisplay-map (transient--make-redisplay-map))
+  (setq transient--original-window (selected-window))
+  (setq transient--original-buffer (current-buffer))
+  (transient--redisplay)
+  (transient--init-transient)
+  (transient--suspend-which-key-mode))
+
+(defun transient--init-objects (name layout params)
+  (setq transient--prefix
+        (let ((proto (get name 'transient--prefix)))
+          (apply #'clone proto
+                 :prototype proto
+                 :level (or (alist-get
+                             t (alist-get name transient-levels))
+                            transient-default-level)
+                 params)))
+  (transient-init-value transient--prefix)
+  (setq transient--layout
+        (or layout
+            (let ((levels (alist-get name transient-levels)))
+              (cl-mapcan (lambda (c) (transient--init-child levels c))
+                         (append (get name 'transient--layout)
+                                 (and (not transient--editp)
+                                      (get 'transient-common-commands
+                                           'transient--layout)))))))
+  (setq transient--suffixes
+        (cl-labels ((s (def)
+                       (cond
+                        ((stringp def) nil)
+                        ((listp def) (cl-mapcan #'s def))
+                        ((transient-group--eieio-childp def)
+                         (cl-mapcan #'s (oref def suffixes)))
+                        ((transient-suffix--eieio-childp def)
+                         (list def)))))
+          (cl-mapcan #'s transient--layout))))
+
+(defun transient--init-child (levels spec)
+  (cl-etypecase spec
+    (vector  (transient--init-group  levels spec))
+    (list    (transient--init-suffix levels spec))
+    (string  (list spec))))
+
+(defun transient--init-group (levels spec)
+  (pcase-let ((`(,level ,class ,args ,children) (append spec nil)))
+    (when (transient--use-level-p level)
+      (let ((obj (apply class :level level args)))
+        (when (transient--use-suffix-p obj)
+          (when-let ((suffixes
+                      (cl-mapcan (lambda (c) (transient--init-child levels c))
+                                 children)))
+            (oset obj suffixes suffixes)
+            (list obj)))))))
+
+(defun transient--init-suffix (levels spec)
+  (pcase-let* ((`(,level ,class ,args) spec)
+               (cmd (plist-get args :command))
+               (level (or (alist-get (transient--suffix-command cmd) levels)
+                          level)))
+    (let ((fn (and (symbolp cmd)
+                   (symbol-function cmd))))
+      (when (autoloadp fn)
+        (transient--debug "   autoload %s" cmd)
+        (autoload-do-load fn)))
+    (when (transient--use-level-p level)
+      (let ((obj (if-let ((proto (and cmd
+                                      (symbolp cmd)
+                                      (get cmd 'transient--suffix))))
+                     (apply #'clone proto :level level args)
+                   (apply class :level level args))))
+        (transient--init-suffix-key obj)
+        (transient--ensure-infix-command obj)
+        (when (transient--use-suffix-p obj)
+          (transient-init-scope obj)
+          (transient-init-value obj)
+          (list obj))))))
+
+(cl-defmethod transient--init-suffix-key ((obj transient-suffix))
+  (unless (slot-boundp obj 'key)
+    (error "No key for %s" (oref obj command))))
+
+(cl-defmethod transient--init-suffix-key ((obj transient-argument))
+  (if (transient-switches--eieio-childp obj)
+      (cl-call-next-method obj)
+    (unless (slot-boundp obj 'shortarg)
+      (when-let ((shortarg (transient--derive-shortarg (oref obj argument))))
+        (oset obj shortarg shortarg)))
+    (unless (slot-boundp obj 'key)
+      (if (slot-boundp obj 'shortarg)
+          (oset obj key (oref obj shortarg))
+        (error "No key for %s" (oref obj command))))))
+
+(defun transient--use-level-p (level &optional edit)
+  (or (and transient--editp (not edit))
+      (and (>= level 1)
+           (<= level (oref transient--prefix level)))))
+
+(defun transient--use-suffix-p (obj)
+  (with-slots
+      (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived)
+      obj
+    (cond
+     (if                  (funcall if))
+     (if-not         (not (funcall if-not)))
+     (if-non-nil          (symbol-value if-non-nil))
+     (if-nil         (not (symbol-value if-nil)))
+     (if-mode             (if (atom if-mode)
+                              (eq major-mode if-mode)
+                            (memq major-mode if-mode)))
+     (if-not-mode    (not (if (atom if-not-mode)
+                              (eq major-mode if-not-mode)
+                            (memq major-mode if-not-mode))))
+     (if-derived          (if (atom if-derived)
+                              (derived-mode-p if-derived)
+                            (apply #'derived-mode-p if-derived)))
+     (if-not-derived (not (if (atom if-not-derived)
+                              (derived-mode-p if-not-derived)
+                            (apply #'derived-mode-p if-not-derived))))
+     (t))))
+
+;;; Flow-Control
+
+(defun transient--init-transient ()
+  (transient--debug 'init-transient)
+  (transient--push-keymap 'transient--transient-map)
+  (transient--push-keymap 'transient--redisplay-map)
+  (add-hook 'pre-command-hook      #'transient--pre-command)
+  (add-hook 'minibuffer-setup-hook #'transient--minibuffer-setup)
+  (add-hook 'minibuffer-exit-hook  #'transient--minibuffer-exit)
+  (add-hook 'post-command-hook     #'transient--post-command)
+  (advice-add 'abort-recursive-edit :after #'transient--minibuffer-exit)
+  (when transient--exitp
+    ;; This prefix command was invoked as the suffix of another.
+    ;; Prevent `transient--post-command' from removing the hooks
+    ;; that we just added.
+    (setq transient--exitp 'replace)))
+
+(defun transient--pre-command ()
+  (transient--debug 'pre-command)
+  (cond
+   ((memq this-command '(transient-update transient-quit-seq))
+    (transient--pop-keymap 'transient--redisplay-map))
+   ((and transient--helpp
+         (not (memq this-command '(transient-quit-one
+                                   transient-quit-all))))
+    (cond
+     ((transient-help)
+      (transient--do-suspend)
+      (setq this-command 'transient-suspend)
+      (transient--pre-exit))
+     ((not (transient--edebug-command-p))
+      (setq this-command 'transient-undefined))))
+   ((and transient--editp
+         (transient-suffix-object)
+         (not (memq this-command '(transient-quit-one
+                                   transient-quit-all
+                                   transient-help))))
+    (setq this-command 'transient-set-level))
+   (t
+    (setq transient--exitp nil)
+    (when (eq (if-let ((fn (or (lookup-key transient--predicate-map
+                                           (vector this-original-command))
+                               (oref transient--prefix transient-non-suffix))))
+                  (let ((action (funcall fn)))
+                    (when (eq action transient--exit)
+                      (setq transient--exitp (or transient--exitp t)))
+                    action)
+                (if (let ((keys (this-command-keys-vector)))
+                      (eq (aref keys (1- (length keys))) ?\C-g))
+                    (setq this-command 'transient-noop)
+                  (unless (transient--edebug-command-p)
+                    (setq this-command 'transient-undefined)))
+                transient--stay)
+              transient--exit)
+      (transient--pre-exit)))))
+
+(defun transient--pre-exit ()
+  (transient--debug 'pre-exit)
+  (transient--delete-window)
+  (transient--timer-cancel)
+  (transient--pop-keymap 'transient--transient-map)
+  (transient--pop-keymap 'transient--redisplay-map)
+  (remove-hook 'pre-command-hook #'transient--pre-command)
+  (unless transient--showp
+    (message ""))
+  (setq transient--transient-map nil)
+  (setq transient--predicate-map nil)
+  (setq transient--redisplay-map nil)
+  (setq transient--redisplay-key nil)
+  (setq transient--showp nil)
+  (setq transient--helpp nil)
+  (setq transient--editp nil)
+  (setq transient--prefix nil)
+  (setq transient--layout nil)
+  (setq transient--suffixes nil)
+  (setq transient--original-window nil)
+  (setq transient--original-buffer nil)
+  (setq transient--window nil))
+
+(defun transient--delete-window ()
+  (when (window-live-p transient--window)
+    (let ((buf (window-buffer transient--window)))
+      (with-demoted-errors "Error while exiting transient: %S"
+        (delete-window transient--window))
+      (kill-buffer buf))))
+
+(defun transient--export ()
+  (setq current-transient-prefix transient--prefix)
+  (setq current-transient-command (oref transient--prefix command))
+  (setq current-transient-suffixes transient--suffixes)
+  (transient--history-push transient--prefix))
+
+(defun transient--minibuffer-setup ()
+  (transient--debug 'minibuffer-setup)
+  (unless (> (minibuffer-depth) 1)
+    (unless transient--exitp
+      (transient--pop-keymap 'transient--transient-map)
+      (transient--pop-keymap 'transient--redisplay-map)
+      (remove-hook 'pre-command-hook #'transient--pre-command))
+    (remove-hook 'post-command-hook #'transient--post-command)))
+
+(defun transient--minibuffer-exit ()
+  (transient--debug 'minibuffer-exit)
+  (unless (> (minibuffer-depth) 1)
+    (unless transient--exitp
+      (transient--push-keymap 'transient--transient-map)
+      (transient--push-keymap 'transient--redisplay-map)
+      (add-hook 'pre-command-hook #'transient--pre-command))
+    (add-hook 'post-command-hook #'transient--post-command)))
+
+(defun transient--suspend-override (&optional minibuffer-hooks)
+  (transient--debug 'suspend-override)
+  (transient--pop-keymap 'transient--transient-map)
+  (transient--pop-keymap 'transient--redisplay-map)
+  (remove-hook 'pre-command-hook  #'transient--pre-command)
+  (remove-hook 'post-command-hook #'transient--post-command)
+  (when minibuffer-hooks
+    (remove-hook   'minibuffer-setup-hook #'transient--minibuffer-setup)
+    (remove-hook   'minibuffer-exit-hook  #'transient--minibuffer-exit)
+    (advice-remove 'abort-recursive-edit  #'transient--minibuffer-exit)))
+
+(defun transient--resume-override (&optional minibuffer-hooks)
+  (transient--debug 'resume-override)
+  (transient--push-keymap 'transient--transient-map)
+  (transient--push-keymap 'transient--redisplay-map)
+  (add-hook 'pre-command-hook  #'transient--pre-command)
+  (add-hook 'post-command-hook #'transient--post-command)
+  (when minibuffer-hooks
+    (add-hook   'minibuffer-setup-hook #'transient--minibuffer-setup)
+    (add-hook   'minibuffer-exit-hook  #'transient--minibuffer-exit)
+    (advice-add 'abort-recursive-edit :after #'transient--minibuffer-exit)))
+
+(defun transient--post-command ()
+  (transient--debug 'post-command)
+  (if transient--exitp
+      (progn
+        (unless (and (eq transient--exitp 'replace)
+                     (or transient--prefix
+                         ;; The current command could act as a prefix,
+                         ;; but decided not to call `transient-setup'.
+                         (prog1 nil (transient--stack-zap))))
+          (remove-hook   'minibuffer-setup-hook #'transient--minibuffer-setup)
+          (remove-hook   'minibuffer-exit-hook  #'transient--minibuffer-exit)
+          (advice-remove 'abort-recursive-edit  #'transient--minibuffer-exit)
+          (remove-hook   'post-command-hook     #'transient--post-command))
+        (setq current-transient-prefix nil)
+        (setq current-transient-command nil)
+        (setq current-transient-suffixes nil)
+        (let ((resume (and transient--stack
+                           (not (memq transient--exitp '(replace suspend))))))
+          (setq transient--exitp nil)
+          (setq transient--helpp nil)
+          (setq transient--editp nil)
+          (run-hooks 'post-transient-hook)
+          (when resume
+            (transient--stack-pop))))
+    (transient--pop-keymap 'transient--redisplay-map)
+    (setq transient--redisplay-map (transient--make-redisplay-map))
+    (transient--push-keymap 'transient--redisplay-map)
+    (unless (eq this-command (oref transient--prefix command))
+      (transient--redisplay))))
+
+(defun transient--stack-push ()
+  (transient--debug 'stack-push)
+  (push (list (oref transient--prefix command)
+              transient--layout
+              transient--editp
+              :scope (oref transient--prefix scope))
+        transient--stack))
+
+(defun transient--stack-pop ()
+  (transient--debug 'stack-pop)
+  (and transient--stack
+       (prog1 t (apply #'transient-setup (pop transient--stack)))))
+
+(defun transient--stack-zap ()
+  (transient--debug 'stack-zap)
+  (setq transient--stack nil))
+
+(defun transient--redisplay ()
+  (if (or (eq transient-show-popup t)
+          transient--showp)
+      (unless (memq this-command '(transient-scroll-up
+                                   transient-scroll-down
+                                   mwheel-scroll))
+        (transient--show))
+    (when (and (numberp transient-show-popup)
+               (not (zerop transient-show-popup))
+               (not transient--timer))
+      (transient--timer-start))
+    (transient--show-brief)))
+
+(defun transient--timer-start ()
+  (setq transient--timer
+        (run-at-time (abs transient-show-popup) nil
+                     (lambda ()
+                       (transient--timer-cancel)
+                       (transient--show)
+                       (let ((message-log-max nil))
+                         (message ""))))))
+
+(defun transient--timer-cancel ()
+  (when transient--timer
+    (cancel-timer transient--timer)
+    (setq transient--timer nil)))
+
+(defun transient--debug (arg &rest args)
+  (when transient--debug
+    (if (symbolp arg)
+        (message "-- %-16s (cmd: %s, exit: %s)"
+                 arg this-command transient--exitp)
+      (apply #'message arg args))))
+
+(defun transient--emergency-exit ()
+  "Exit the current transient command after an error occurred.
+
+Beside being used with `condition-case', this function also has
+to be a member of `debugger-mode-hook', else the debugger would
+be unusable and exiting it by pressing \"q\" would fail because
+the transient command would still be active and that key would
+either be unbound or do something else.
+
+When no transient is active (i.e. when `transient--prefix') is
+nil, then do nothing."
+  (when transient--prefix
+    (setq transient--stack nil)
+    (setq transient--exitp t)
+    (transient--pre-exit)
+    (transient--post-command)))
+
+(add-hook 'debugger-mode-hook 'transient--emergency-exit)
+
+(defmacro transient--with-emergency-exit (&rest body)
+  (declare (indent defun))
+  `(condition-case nil
+       ,(macroexp-progn body)
+     (error (transient--emergency-exit))))
+
+;;; Pre-Commands
+
+(defun transient--do-stay ()
+  "Call the command without exporting variables and stay transient."
+  transient--stay)
+
+(defun transient--do-noop ()
+  "Call `transient-noop' and stay transient."
+  (setq this-command 'transient-noop)
+  transient--stay)
+
+(defun transient--do-warn ()
+  "Call `transient-undefined' and stay transient."
+  (setq this-command 'transient-undefined)
+  transient--stay)
+
+(defun transient--do-call ()
+  "Call the command after exporting variables and stay transient."
+  (transient--export)
+  transient--stay)
+
+(defun transient--do-exit ()
+  "Call the command after exporting variables and exit the transient."
+  (transient--export)
+  (transient--stack-zap)
+  transient--exit)
+
+(defun transient--do-replace ()
+  "Call the transient prefix command, replacing the active transient."
+  (transient--export)
+  (transient--stack-push)
+  (setq transient--exitp 'replace)
+  transient--exit)
+
+(defun transient--do-suspend ()
+  "Suspend the active transient, saving the transient stack."
+  (transient--stack-push)
+  (setq transient--exitp 'suspend)
+  transient--exit)
+
+(defun transient--do-quit-one ()
+  "If active, quit help or edit mode, else exit the active transient."
+  (cond (transient--helpp
+         (setq transient--helpp nil)
+         transient--stay)
+        (transient--editp
+         (setq transient--editp nil)
+         (transient-setup)
+         transient--stay)
+        (t transient--exit)))
+
+(defun transient--do-quit-all ()
+  "Exit all transients without saving the transient stack."
+  (transient--stack-zap)
+  transient--exit)
+
+(defun transient--do-move ()
+  "Call the command if `transient-enable-popup-navigation' is non-nil.
+In that case behave like `transient--do-stay', otherwise similar
+to `transient--do-warn'."
+  (unless transient-enable-popup-navigation
+    (setq this-command 'transient-popup-navigation-help))
+  transient--stay)
+
+;;; Commands
+
+(defun transient-noop ()
+  "Do nothing at all."
+  (interactive))
+
+(defun transient-undefined ()
+  "Warn the user that the pressed key is not bound to any suffix."
+  (interactive)
+  (ding)
+  (message "Unbound suffix: `%s' (Use `%s' to abort, `%s' for help) [%s]"
+           (propertize (key-description (this-single-command-keys))
+                       'face 'font-lock-warning-face)
+           (propertize "C-g" 'face 'transient-key)
+           (propertize "?"   'face 'transient-key)
+           this-original-command))
+
+(defun transient-toggle-common ()
+  "Toggle whether common commands are always shown."
+  (interactive)
+  (setq transient-show-common-commands (not transient-show-common-commands)))
+
+(defun transient-suspend ()
+  "Suspend the current transient.
+It can later be resumed using `transient-resume' while no other
+transient is active."
+  (interactive))
+
+(defun transient-quit-all ()
+  "Exit all transients without saving the transient stack."
+  (interactive))
+
+(defun transient-quit-one ()
+  "Exit the current transients, possibly returning to the previous."
+  (interactive))
+
+(defun transient-quit-seq ()
+  "Abort the current incomplete key sequence."
+  (interactive))
+
+(defun transient-update ()
+  "Redraw the transient's state in the popup buffer."
+  (interactive))
+
+(defun transient-show ()
+  "Show the transient's state in the popup buffer."
+  (interactive)
+  (setq transient--showp t))
+
+(defvar-local transient--restore-winconf nil)
+
+(defvar transient-resume-mode)
+
+(defun transient-help ()
+  "Show help for the active transient or one of its suffixes."
+  (interactive)
+  (if (called-interactively-p 'any)
+      (setq transient--helpp t)
+    (with-demoted-errors "transient-help: %S"
+      (when (lookup-key transient--transient-map
+                        (this-single-command-raw-keys))
+        (setq transient--helpp nil)
+        (let ((winconf (current-window-configuration)))
+          (transient-show-help
+           (if (eq this-original-command 'transient-help)
+               transient--prefix
+             (or (transient-suffix-object)
+                 this-original-command)))
+          (setq transient--restore-winconf winconf))
+        (fit-window-to-buffer nil (frame-height) (window-height))
+        (transient-resume-mode)
+        (message "Type \"q\" to resume transient command.")
+        t))))
+
+(defun transient-set-level (&optional command level)
+  "Set the level of the transient or one of its suffix commands."
+  (interactive
+   (let ((command this-original-command)
+         (prefix (oref transient--prefix command)))
+     (and (or (not (eq command 'transient-set-level))
+              (and transient--editp
+                   (setq command prefix)))
+          (list command
+                (let ((keys (this-single-command-raw-keys)))
+                  (and (lookup-key transient--transient-map keys)
+                       (string-to-number
+                        (transient--read-number-N
+                         (format "Set level for `%s': "
+                                 (transient--suffix-command command))
+                         nil nil (not (eq command prefix))))))))))
+  (cond
+   ((not command)
+    (setq transient--editp t)
+    (transient-setup))
+   (level
+    (let* ((prefix (oref transient--prefix command))
+           (alist (alist-get prefix transient-levels))
+           (key (transient--suffix-command command)))
+      (if (eq command prefix)
+          (progn (oset transient--prefix level level)
+                 (setq key t))
+        (oset (transient-suffix-object command) level level))
+      (setf (alist-get key alist) level)
+      (setf (alist-get prefix transient-levels) alist))
+    (transient-save-levels))
+   (t
+    (transient-undefined))))
+
+(defun transient-set ()
+  "Save the value of the active transient for this Emacs session."
+  (interactive)
+  (transient-set-value (or transient--prefix current-transient-prefix)))
+
+(defun transient-save ()
+  "Save the value of the active transient persistenly across Emacs sessions."
+  (interactive)
+  (transient-save-value (or transient--prefix current-transient-prefix)))
+
+(defun transient-history-next ()
+  "Switch to the next value used for the active transient."
+  (interactive)
+  (let* ((obj transient--prefix)
+         (pos (1- (oref obj history-pos)))
+         (hst (oref obj history)))
+    (if (< pos 0)
+        (user-error "End of history")
+      (oset obj history-pos pos)
+      (oset obj value (nth pos hst))
+      (mapc #'transient-init-value transient--suffixes))))
+
+(defun transient-history-prev ()
+  "Switch to the previous value used for the active transient."
+  (interactive)
+  (let* ((obj transient--prefix)
+         (pos (1+ (oref obj history-pos)))
+         (hst (oref obj history))
+         (len (length hst)))
+    (if (> pos (1- len))
+        (user-error "End of history")
+      (oset obj history-pos pos)
+      (oset obj value (nth pos hst))
+      (mapc #'transient-init-value transient--suffixes))))
+
+(defun transient-scroll-up (&optional arg)
+  "Scroll text of transient popup window upward ARG lines.
+If ARG is nil scroll near full screen.  This is a wrapper
+around `scroll-up-command' (which see)."
+  (interactive "^P")
+  (with-selected-window transient--window
+    (scroll-up-command arg)))
+
+(defun transient-scroll-down (&optional arg)
+  "Scroll text of transient popup window down ARG lines.
+If ARG is nil scroll near full screen.  This is a wrapper
+around `scroll-down-command' (which see)."
+  (interactive "^P")
+  (with-selected-window transient--window
+    (scroll-down-command arg)))
+
+(defun transient-resume ()
+  "Resume a previously suspended stack of transients."
+  (interactive)
+  (cond (transient--stack
+         (let ((winconf transient--restore-winconf))
+           (kill-local-variable 'transient--restore-winconf)
+           (when transient-resume-mode
+             (transient-resume-mode -1)
+             (quit-window))
+           (when winconf
+             (set-window-configuration winconf)))
+         (transient--stack-pop))
+        (transient-resume-mode
+         (kill-local-variable 'transient--restore-winconf)
+         (transient-resume-mode -1)
+         (quit-window))
+        (t
+         (message "No suspended transient command"))))
+
+;;; Value
+;;;; Init
+
+(cl-defgeneric transient-init-scope (obj)
+  "Set the scope of the suffix object OBJ.
+
+The scope is actually a property of the transient prefix, not of
+individual suffixes.  However it is possible to invoke a suffix
+command directly instead of from a transient.  In that case, if
+the suffix expects a scope, then it has to determine that itself
+and store it in its `scope' slot.
+
+This function is called for all suffix commands, but unless a
+concrete method is implemented this falls through to the default
+implementation, which is a noop.")
+
+(cl-defmethod transient-init-scope ((_   transient-suffix))
+  "Noop." nil)
+
+(cl-defgeneric transient-init-value (_)
+  "Set the initial value of the object OBJ.
+
+This function is called for all prefix and suffix commands.
+
+For suffix commands (including infix argument commands) the
+default implementation is a noop.  Classes derived from the
+abstract `transient-infix' class must implement this function.
+Non-infix suffix commands usually don't have a value."
+  nil)
+
+(cl-defmethod transient-init-value ((obj transient-prefix))
+  (oset obj value
+        (if-let ((saved (assq (oref obj command) transient-values)))
+            (cdr saved)
+          (if-let ((default (and (slot-boundp obj 'default-value)
+                                 (oref obj default-value))))
+              (if (functionp default)
+                  (funcall default)
+                default)
+            nil))))
+
+(cl-defmethod transient-init-value ((obj transient-switch))
+  (oset obj value
+        (car (member (oref obj argument)
+                     (oref transient--prefix value)))))
+
+(cl-defmethod transient-init-value ((obj transient-option))
+  (oset obj value
+        (transient--value-match (format "\\`%s\\(.*\\)" (oref obj argument)))))
+
+(cl-defmethod transient-init-value ((obj transient-switches))
+  (oset obj value
+        (transient--value-match (oref obj argument-regexp))))
+
+(defun transient--value-match (re)
+  (when-let ((match (cl-find-if (lambda (v)
+                                  (and (stringp v)
+                                       (string-match re v)))
+                                (oref transient--prefix value))))
+    (match-string 1 match)))
+
+(cl-defmethod transient-init-value ((obj transient-files))
+  (oset obj value
+        (cdr (assoc "--" (oref transient--prefix value)))))
+
+;;;; Read
+
+(cl-defgeneric transient-infix-read (obj)
+  "Determine the new value of the infix object OBJ.
+
+This function merely determines the value; `transient-infix-set'
+is used to actually store the new value in the object.
+
+For most infix classes this is done by reading a value from the
+user using the reader specified by the `reader' slot (using the
+`transient-infix' method described below).
+
+For some infix classes the value is changed without reading
+anything in the minibuffer, i.e. the mere act of invoking the
+infix command determines what the new value should be, based
+on the previous value.")
+
+(cl-defmethod transient-infix-read :around ((obj transient-infix))
+  "Highlight the infix in the popup buffer.
+
+Also arrange for the transient to be exited in case of an error
+because otherwise Emacs would get stuck in an inconsistent state,
+which might make it necessary to kill it from the outside."
+  (let ((transient--active-infix obj))
+    (transient--show))
+  (transient--with-emergency-exit
+    (cl-call-next-method obj)))
+
+(cl-defmethod transient-infix-read ((obj transient-infix))
+  "Read a value while taking care of history.
+
+This method is suitable for a wide variety of infix commands,
+including but not limitted to inline arguments and variables.
+
+If you do not use this method for your own infix class, then
+you should likely replicate a lot of the behavior of this
+method.  If you fail to do so, then users might not appreciate
+the lack of history, for example.
+
+Only for very simple classes that toggle or cycle through a very
+limited number of possible values should you replace this with a
+simple method that does not handle history.  (E.g. for a command
+line switch the only possible values are \"use it\" and \"don't use
+it\", in which case it is pointless to preserve history.)"
+  (with-slots (value multi-value allow-empty choices) obj
+    (if (and value
+             (not multi-value)
+             transient--prefix)
+        (oset obj value nil)
+      (let* ((overriding-terminal-local-map nil)
+             (reader (oref obj reader))
+             (prompt (transient-prompt obj))
+             (value (if multi-value (mapconcat #'identity value ",") value))
+             (history-key (or (oref obj history-key)
+                              (oref obj command)))
+             (transient--history (alist-get history-key transient-history))
+             (transient--history (if (or (null value)
+                                         (eq value (car transient--history)))
+                                     transient--history
+                                   (cons value transient--history)))
+             (initial-input (and transient-read-with-initial-input
+                                 (car transient--history)))
+             (history (if initial-input
+                          (cons 'transient--history 1)
+                        'transient--history))
+             (value
+              (cond
+               (reader (funcall reader prompt initial-input history))
+               (multi-value
+                (completing-read-multiple prompt choices nil nil
+                                          initial-input history))
+               (choices
+                (completing-read prompt choices nil t initial-input history))
+               (t (read-string prompt initial-input history)))))
+        (cond ((and (equal value "") (not allow-empty))
+               (setq value nil))
+              ((and (equal value "\"\"") allow-empty)
+               (setq value "")))
+        (when value
+          (when (bound-and-true-p ivy-mode)
+            (set-text-properties 0 (length (car transient--history)) nil
+                                 (car transient--history)))
+          (setf (alist-get history-key transient-history)
+                (delete-dups transient--history)))
+        value))))
+
+(cl-defmethod transient-infix-read ((obj transient-switch))
+  "Toggle the switch on or off."
+  (if (oref obj value) nil (oref obj argument)))
+
+(cl-defmethod transient-infix-read ((obj transient-switches))
+  "Cycle through the mutually exclusive switches.
+The last value is \"don't use any of these switches\"."
+  (let ((choices (mapcar (apply-partially #'format (oref obj argument-format))
+                         (oref obj choices))))
+    (if-let ((value (oref obj value)))
+        (cadr (member value choices))
+      (car choices))))
+
+;;;; Readers
+
+(defun transient-read-directory (prompt _initial-input _history)
+  "Read a directory."
+  (expand-file-name (read-directory-name prompt)))
+
+(defun transient-read-existing-directory (prompt _initial-input _history)
+  "Read an existing directory."
+  (expand-file-name (read-directory-name prompt nil nil t)))
+
+(defun transient-read-number-N0 (prompt initial-input history)
+  "Read a natural number (including zero) and return it as a string."
+  (transient--read-number-N prompt initial-input history t))
+
+(defun transient-read-number-N+ (prompt initial-input history)
+  "Read a natural number (excluding zero) and return it as a string."
+  (transient--read-number-N prompt initial-input history nil))
+
+(defun transient--read-number-N (prompt initial-input history include-zero)
+  (save-match-data
+    (cl-block nil
+      (while t
+        (let ((str (read-from-minibuffer prompt initial-input nil nil history)))
+          (cond ((string-equal str "")
+                 (cl-return nil))
+                ((string-match-p (if include-zero
+                                     "\\`\\(0\\|[1-9][0-9]*\\)\\'"
+                                   "\\`[1-9][0-9]*\\'")
+                                 str)
+                 (cl-return str))))
+        (message "Please enter a natural number (%s zero)."
+                 (if include-zero "including" "excluding"))
+        (sit-for 1)))))
+
+(defun transient-read-date (prompt default-time _history)
+  "Read a date using `org-read-date' (which see)."
+  (require 'org)
+  (when (fboundp 'org-read-date)
+    (org-read-date 'with-time nil nil prompt default-time)))
+
+;;;; Prompt
+
+(cl-defgeneric transient-prompt (obj)
+  "Return the prompt to be used to read infix object OBJ's value.")
+
+(cl-defmethod transient-prompt ((obj transient-infix))
+  "Return the prompt to be used to read infix object OBJ's value.
+
+This implementation should be suitable for almost all infix
+commands.
+
+If the value of OBJ's `prompt' slot is non-nil, then it must be
+a string or a function.  If it is a string, then use that.  If
+it is a function, then call that with OBJ as the only argument.
+That function must return a string, which is then used as the
+prompt.
+
+Otherwise, if the value of either the `argument' or `variable'
+slot of OBJ is a string, then base the prompt on that (preferring
+the former), appending either \"=\" (if it appears to be a
+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: no prompt): "))
+    (or (when-let ((arg (and (slot-boundp obj 'argument) (oref obj argument))))
+          (if (and (stringp arg) (string-suffix-p "=" arg))
+              arg
+            (concat arg ": ")))
+        (when-let ((var (and (slot-boundp obj 'variable) (oref obj variable))))
+          (and (stringp var)
+               (concat var ": ")))
+        "(BUG: no prompt): ")))
+
+;;;; Set
+
+(defvar transient--unset-incompatible t)
+
+(cl-defgeneric transient-infix-set (obj value)
+  "Set the value of infix object OBJ to value.")
+
+(cl-defmethod transient-infix-set ((obj transient-infix) value)
+  "Set the value of infix object OBJ to value.
+
+This implementation should be suitable for almost all infix
+commands."
+  (oset obj value value))
+
+(cl-defmethod transient-infix-set :around ((obj transient-argument) value)
+  "Unset incompatible infix arguments."
+  (let ((arg (if (slot-boundp obj 'argument)
+                 (oref obj argument)
+               (oref obj argument-regexp))))
+    (if-let ((sic (and value arg transient--unset-incompatible))
+             (spec (oref transient--prefix incompatible))
+             (incomp (remove arg (cl-find-if (lambda (elt) (member arg elt)) spec))))
+        (progn
+          (cl-call-next-method obj value)
+          (dolist (arg incomp)
+            (when-let ((obj (cl-find-if (lambda (obj)
+                                          (and (slot-boundp obj 'argument)
+                                               (equal (oref obj argument) arg)))
+                                        transient--suffixes)))
+              (let ((transient--unset-incompatible nil))
+                (transient-infix-set obj nil)))))
+      (cl-call-next-method obj value))))
+
+(cl-defmethod transient-set-value ((obj transient-prefix))
+  (oset (oref obj prototype) value (transient-get-value))
+  (transient--history-push obj))
+
+;;;; Save
+
+(cl-defmethod transient-save-value ((obj transient-prefix))
+  (let ((value (transient-get-value)))
+    (oset (oref obj prototype) value value)
+    (setf (alist-get (oref obj command) transient-values) value)
+    (transient-save-values))
+  (transient--history-push obj))
+
+;;;; Get
+
+(defun transient-args (prefix)
+  "Return the value of the transient prefix command PREFIX.
+If the current command was invoked from the transient prefix
+command PREFIX, then return the active infix arguments.  If
+the current command was not invoked from PREFIX, then return
+the set, saved or default value for PREFIX."
+  (if (eq current-transient-command prefix)
+      (delq nil (mapcar 'transient-infix-value current-transient-suffixes))
+    (let ((transient--prefix nil)
+          (transient--layout nil)
+          (transient--suffixes nil))
+      (transient--init-objects prefix nil nil)
+      (delq nil (mapcar 'transient-infix-value transient--suffixes)))))
+
+(defun transient-get-value ()
+  (delq nil (mapcar 'transient-infix-value current-transient-suffixes)))
+
+(cl-defgeneric transient-infix-value (obj)
+  "Return the value of the suffix object OBJ.
+
+This function is called by `transient-args' (which see), meaning
+this function is how the value of a transient is determined so
+that the invoked suffix command can use it.
+
+Currently most values are strings, but that is not set in stone.
+Nil is not a value, it means \"no value\".
+
+Usually only infixes have a value, but see the method for
+`transient-suffix'.")
+
+(cl-defmethod transient-infix-value ((_   transient-suffix))
+  "Return nil, which means \"no value\".
+
+Infix arguments contribute the the transient's value while suffix
+commands consume it.  This function is called for suffixes anyway
+because a command that both contributes to the transient's value
+and also consumes it is not completely unconceivable.
+
+If you define such a command, then you must define a derived
+class and implement this function because this default method
+does nothing." nil)
+
+(cl-defmethod transient-infix-value ((obj transient-infix))
+  "Return the value of OBJ's `value' slot."
+  (oref obj value))
+
+(cl-defmethod transient-infix-value ((obj transient-option))
+  "Return (concat ARGUMENT VALUE) or nil.
+
+ARGUMENT and VALUE are the values of the respective slots of OBJ.
+If VALUE is nil, then return nil.  VALUE may be the empty string,
+which is not the same as nil."
+  (when-let ((value (oref obj value)))
+    (concat (oref obj argument) value)))
+
+(cl-defmethod transient-infix-value ((_   transient-variable))
+  "Return nil, which means \"no value\".
+
+Setting the value of a variable is done by, well, setting the
+value of the variable.  I.e. this is a side-effect and does not
+contribute to the value of the transient."
+  nil)
+
+(cl-defmethod transient-infix-value ((obj transient-files))
+  "Return (concat ARGUMENT VALUE) or nil.
+
+ARGUMENT and VALUE are the values of the respective slots of OBJ.
+If VALUE is nil, then return nil.  VALUE may be the empty string,
+which is not the same as nil."
+  (when-let ((value (oref obj value)))
+    (cons (oref obj argument) value)))
+
+;;; History
+
+(cl-defgeneric transient--history-key (obj)
+  "Return OBJ's history key.
+If the value of the `history-key' slot is non-nil, then return
+that.  Otherwise return the value of the `command' slot."
+  (or (oref obj history-key)
+      (oref obj command)))
+
+(cl-defgeneric transient--history-push (obj)
+  "Push the current value of OBJ to its entry in `transient-history'."
+  (let ((key (transient--history-key obj)))
+    (setf (alist-get key transient-history)
+          (let ((args (transient-get-value)))
+            (cons args (delete args (alist-get key transient-history)))))))
+
+(cl-defgeneric transient--history-init (obj)
+  "Initialize OBJ's `history' slot.
+This is the transient-wide history; many individual infixes also
+have a history of their own.")
+
+(cl-defmethod transient--history-init ((obj transient-prefix))
+  "Initialize OBJ's `history' slot from the variable `transient-history'."
+  (let ((val (oref obj value)))
+    (oset obj history
+          (cons val (delete val (alist-get (transient--history-key obj)
+                                           transient-history))))))
+
+;;; Draw
+
+(defun transient--show-brief ()
+  (let ((message-log-max nil))
+    (if (and transient-show-popup (<= transient-show-popup 0))
+        (message "%s-" (key-description (this-command-keys)))
+      (message
+       "%s- [%s] %s"
+       (key-description (this-command-keys))
+       (oref transient--prefix command)
+       (mapconcat
+        #'identity
+        (sort
+         (cl-mapcan
+          (lambda (suffix)
+            (let ((key (kbd (oref suffix key))))
+              ;; Don't list any common commands.
+              (and (not (memq (oref suffix command)
+                              `(,(lookup-key transient-map key)
+                                ,(lookup-key transient-sticky-map key)
+                                ;; From transient-common-commands:
+                                transient-set
+                                transient-save
+                                transient-history-prev
+                                transient-history-next
+                                transient-quit-one
+                                transient-toggle-common
+                                transient-set-level)))
+                   (list (propertize (oref suffix key) 'face 'transient-key)))))
+          transient--suffixes)
+         #'string<)
+        (propertize "|" 'face 'transient-unreachable-key))))))
+
+(defun transient--show ()
+  (transient--timer-cancel)
+  (setq transient--showp t)
+  (let ((buf (get-buffer-create transient--buffer-name))
+        (focus nil))
+    (unless (window-live-p transient--window)
+      (setq transient--window
+            (display-buffer buf transient-display-buffer-action)))
+    (with-selected-window transient--window
+      (when transient-enable-popup-navigation
+        (setq focus (button-get (point) 'command)))
+      (erase-buffer)
+      (set-window-hscroll transient--window 0)
+      (set-window-dedicated-p transient--window t)
+      (set-window-parameter transient--window 'no-other-window t)
+      (setq window-size-fixed t)
+      (when (bound-and-true-p tab-line-format)
+        (setq tab-line-format nil))
+      (setq mode-line-format (if (eq transient-mode-line-format 'line)
+                                 nil
+                               transient-mode-line-format))
+      (setq mode-line-buffer-identification
+            (symbol-name (oref transient--prefix command)))
+      (if transient-enable-popup-navigation
+          (setq-local cursor-in-non-selected-windows 'box)
+        (setq cursor-type nil))
+      (setq display-line-numbers nil)
+      (setq show-trailing-whitespace nil)
+      (transient--insert-groups)
+      (when (or transient--helpp transient--editp)
+        (transient--insert-help))
+      (when (eq transient-mode-line-format 'line)
+        (insert (propertize "__" 'face 'transient-separator
+                            'display '(space :height (1))))
+        (insert (propertize "\n" 'face 'transient-separator 'line-height t)))
+      (let ((window-resize-pixelwise t)
+            (window-size-fixed nil))
+        (fit-window-to-buffer nil nil 1))
+      (goto-char (point-min))
+      (when transient-force-fixed-pitch
+        (transient--force-fixed-pitch))
+      (when transient-enable-popup-navigation
+        (transient--goto-button focus)))))
+
+(defun transient--insert-groups ()
+  (let ((groups (cl-mapcan (lambda (group)
+                             (let ((hide (oref group hide)))
+                               (and (not (and (functionp hide)
+                                              (funcall   hide)))
+                                    (list group))))
+                           transient--layout))
+        group)
+    (while (setq group (pop groups))
+      (transient--insert-group group)
+      (when groups
+        (insert ?\n)))))
+
+(cl-defgeneric transient--insert-group (group)
+  "Format GROUP and its elements and insert the result.")
+
+(cl-defmethod transient--insert-group :before ((group transient-group))
+  "Insert GROUP's description, if any."
+  (when-let ((desc (transient-format-description group)))
+    (insert desc ?\n)))
+
+(cl-defmethod transient--insert-group ((group transient-row))
+  (dolist (suffix (oref group suffixes))
+    (insert (transient-format suffix))
+    (insert "   "))
+  (insert ?\n))
+
+(cl-defmethod transient--insert-group ((group transient-column))
+  (dolist (suffix (oref group suffixes))
+    (let ((str (transient-format suffix)))
+      (insert str)
+      (unless (string-match-p ".\n\\'" str)
+        (insert ?\n)))))
+
+(cl-defmethod transient--insert-group ((group transient-columns))
+  (let* ((columns
+          (mapcar
+           (lambda (column)
+             (let ((rows (mapcar 'transient-format (oref column suffixes))))
+               (when-let ((desc (transient-format-description column)))
+                 (push desc rows))
+               rows))
+           (oref group suffixes)))
+         (rs (apply #'max (mapcar #'length columns)))
+         (cs (length columns))
+         (cw (mapcar (lambda (col) (apply #'max (mapcar #'length col)))
+                     columns))
+         (cc (transient--seq-reductions-from (apply-partially #'+ 3) cw 0)))
+    (dotimes (r rs)
+      (dotimes (c cs)
+        (insert (make-string (- (nth c cc) (current-column)) ?\s))
+        (when-let ((cell (nth r (nth c columns))))
+          (insert cell))
+        (when (= c (1- cs))
+          (insert ?\n))))))
+
+(cl-defmethod transient--insert-group ((group transient-subgroups))
+  (let* ((subgroups (oref group suffixes))
+         (n (length subgroups)))
+    (dotimes (s n)
+      (transient--insert-group (nth s subgroups))
+      (when (< s (1- n))
+        (insert ?\n)))))
+
+(cl-defgeneric transient-format (obj)
+  "Format and return OBJ for display.
+
+When this function is called, then the current buffer is some
+temporary buffer.  If you need the buffer from which the prefix
+command was invoked to be current, then do so by temporarily
+making `transient--original-buffer' current.")
+
+(cl-defmethod transient-format ((arg string))
+  "Return the string ARG after applying the `transient-heading' face."
+  (propertize arg 'face 'transient-heading))
+
+(cl-defmethod transient-format ((_   null))
+  "Return a string containing just the newline character."
+  "\n")
+
+(cl-defmethod transient-format ((arg integer))
+  "Return a string containing just the ARG character."
+  (char-to-string arg))
+
+(cl-defmethod transient-format :around ((obj transient-infix))
+  "When reading user input for this infix, then highlight it."
+  (let ((str (cl-call-next-method obj)))
+    (when (eq obj transient--active-infix)
+      (setq str (concat str "\n"))
+      (add-face-text-property 0 (length str)
+                              'transient-active-infix nil str))
+    str))
+
+(cl-defmethod transient-format :around ((obj transient-suffix))
+  "When edit-mode is enabled, then prepend the level information.
+Optional support for popup buttons is also implemented here."
+  (let ((str (concat
+              (and transient--editp
+                   (let ((level (oref obj level)))
+                     (propertize (format " %s " level)
+                                 'face (if (transient--use-level-p level t)
+                                           'transient-enabled-suffix
+                                         'transient-disabled-suffix))))
+              (cl-call-next-method obj))))
+    (if transient-enable-popup-navigation
+        (make-text-button str nil
+                          'type 'transient-button
+                          'command (transient--suffix-command obj))
+      str)))
+
+(cl-defmethod transient-format ((obj transient-infix))
+  "Return a string generated using OBJ's `format'.
+%k is formatted using `transient-format-key'.
+%d is formatted using `transient-format-description'.
+%f is formatted using `transient-format-value'."
+  (format-spec (oref obj format)
+               `((?k . ,(transient-format-key obj))
+                 (?d . ,(transient-format-description obj))
+                 (?v . ,(transient-format-value obj)))))
+
+(cl-defmethod transient-format ((obj transient-suffix))
+  "Return a string generated using OBJ's `format'.
+%k is formatted using `transient-format-key'.
+%d is formatted using `transient-format-description'."
+  (format-spec (oref obj format)
+               `((?k . ,(transient-format-key obj))
+                 (?d . ,(transient-format-description obj)))))
+
+(cl-defgeneric transient-format-key (obj)
+  "Format OBJ's `key' for display and return the result.")
+
+(cl-defmethod transient-format-key ((obj transient-suffix))
+  "Format OBJ's `key' for display and return the result."
+  (let ((key (oref obj key)))
+    (if transient--redisplay-key
+        (let ((len (length transient--redisplay-key))
+              (seq (cl-coerce (edmacro-parse-keys key t) 'list)))
+          (cond
+           ((equal (seq-take seq len) transient--redisplay-key)
+            (let ((pre (key-description (vconcat (seq-take seq len))))
+                  (suf (key-description (vconcat (seq-drop seq len)))))
+              (setq pre (replace-regexp-in-string "RET" "C-m" pre t))
+              (setq pre (replace-regexp-in-string "TAB" "C-i" pre t))
+              (setq suf (replace-regexp-in-string "RET" "C-m" suf t))
+              (setq suf (replace-regexp-in-string "TAB" "C-i" suf t))
+              ;; We use e.g. "-k" instead of the more correct "- k",
+              ;; because the former is prettier.  If we did that in
+              ;; the definition, then we want to drop the space that
+              ;; is reinserted above.  False-positives are possible
+              ;; for silly bindings like "-C-c C-c".
+              (unless (string-match-p " " key)
+                (setq pre (replace-regexp-in-string " " "" pre))
+                (setq suf (replace-regexp-in-string " " "" suf)))
+              (concat (propertize pre 'face 'default)
+                      (and (string-prefix-p (concat pre " ") key) " ")
+                      (propertize suf 'face 'transient-key)
+                      (save-excursion
+                        (when (string-match " +\\'" key)
+                          (match-string 0 key))))))
+           ((transient--lookup-key transient-sticky-map (kbd key))
+            (propertize key 'face 'transient-key))
+           (t
+            (propertize key 'face 'transient-unreachable-key))))
+      (propertize key 'face 'transient-key))))
+
+(cl-defmethod transient-format-key :around ((obj transient-argument))
+  (let ((key (cl-call-next-method obj)))
+    (cond ((not transient-highlight-mismatched-keys))
+          ((not (slot-boundp obj 'shortarg))
+           (add-face-text-property
+            0 (length key) 'transient-nonstandard-key nil key))
+          ((not (string-equal key (oref obj shortarg)))
+           (add-face-text-property
+            0 (length key) 'transient-mismatched-key nil key)))
+    key))
+
+(cl-defgeneric transient-format-description (obj)
+  "Format OBJ's `description' for display and return the result.")
+
+(cl-defmethod transient-format-description ((obj transient-child))
+  "The `description' slot may be a function, in which case that is
+called inside the correct buffer (see `transient-insert-group')
+and its value is returned to the caller."
+  (when-let ((desc (oref obj description)))
+    (if (functionp desc)
+        (with-current-buffer transient--original-buffer
+          (funcall desc))
+      desc)))
+
+(cl-defmethod transient-format-description ((obj transient-group))
+  "Format the description by calling the next method.  If the result
+doesn't use the `face' property at all, then apply the face
+`transient-heading' to the complete string."
+  (when-let ((desc (cl-call-next-method obj)))
+    (if (text-property-not-all 0 (length desc) 'face nil desc)
+        desc
+      (propertize desc 'face 'transient-heading))))
+
+(cl-defmethod transient-format-description :around ((obj transient-suffix))
+  "Format the description by calling the next method.  If the result
+is nil, then use \"(BUG: no description)\" as the description.
+If the OBJ's `key' is currently unreachable, then apply the face
+`transient-unreachable' to the complete string."
+  (let ((desc (or (cl-call-next-method obj)
+                  (propertize "(BUG: no description)" 'face 'error))))
+    (if (transient--key-unreachable-p obj)
+        (propertize desc 'face 'transient-unreachable)
+      desc)))
+
+(cl-defgeneric transient-format-value (obj)
+  "Format OBJ's value for display and return the result.")
+
+(cl-defmethod transient-format-value ((obj transient-suffix))
+  (propertize (oref obj argument)
+              'face (if (oref obj value)
+                        'transient-argument
+                      'transient-inactive-argument)))
+
+(cl-defmethod transient-format-value ((obj transient-option))
+  (let ((value (oref obj value)))
+    (propertize (concat (oref obj argument)
+                        (if (listp value)
+                            (mapconcat #'identity value ",")
+                          value))
+                'face (if value
+                          'transient-value
+                        'transient-inactive-value))))
+
+(cl-defmethod transient-format-value ((obj transient-switches))
+  (with-slots (value argument-format choices) obj
+    (format (propertize argument-format
+                        'face (if value
+                                  'transient-value
+                                'transient-inactive-value))
+            (concat
+             (propertize "[" 'face 'transient-inactive-value)
+             (mapconcat
+              (lambda (choice)
+                (propertize choice 'face
+                            (if (equal (format argument-format choice) value)
+                                'transient-value
+                              'transient-inactive-value)))
+              choices
+              (propertize "|" 'face 'transient-inactive-value))
+             (propertize "]" 'face 'transient-inactive-value)))))
+
+(cl-defmethod transient-format-value ((obj transient-files))
+  (let ((argument (oref obj argument)))
+    (if-let ((value (oref obj value)))
+        (propertize (concat argument " "
+                            (mapconcat (lambda (f) (format "%S" f))
+                                       (oref obj value) " "))
+                    'face 'transient-argument)
+      (propertize argument 'face 'transient-inactive-argument))))
+
+(defun transient--key-unreachable-p (obj)
+  (and transient--redisplay-key
+       (let ((key (oref obj key)))
+         (not (or (equal (seq-take (cl-coerce (edmacro-parse-keys key t) 'list)
+                                   (length transient--redisplay-key))
+                         transient--redisplay-key)
+                  (transient--lookup-key transient-sticky-map (kbd key)))))))
+
+(defun transient--lookup-key (keymap key)
+  (let ((val (lookup-key keymap key)))
+    (and val (not (integerp val)) val)))
+
+;;; Help
+
+(cl-defgeneric transient-show-help (obj)
+  "Show help for OBJ's command.")
+
+(cl-defmethod transient-show-help ((obj transient-prefix))
+  "Show the info manual, manpage or command doc-string.
+Show the first one that is specified."
+  (if-let ((manual (oref obj info-manual)))
+      (info manual)
+    (if-let ((manpage (oref obj man-page)))
+        (transient--show-manpage manpage)
+      (transient--describe-function (oref obj command)))))
+
+(cl-defmethod transient-show-help ((_   transient-suffix))
+  "Show the command doc-string."
+  (if (eq this-original-command 'transient-help)
+      (if-let ((manpage (oref transient--prefix man-page)))
+          (transient--show-manpage manpage)
+        (transient--describe-function (oref transient--prefix command)))
+    (transient--describe-function this-original-command)))
+
+(cl-defmethod transient-show-help ((obj transient-infix))
+  "Show the manpage if defined or the command doc-string.
+If the manpage is specified, then try to jump to the correct
+location."
+  (if-let ((manpage (oref transient--prefix man-page)))
+      (transient--show-manpage manpage (ignore-errors (oref obj argument)))
+    (transient--describe-function this-original-command)))
+
+;; `cl-generic-generalizers' doesn't support `command' et al.
+(cl-defmethod transient-show-help (cmd)
+  "Show the command doc-string."
+  (transient--describe-function cmd))
+
+(defun transient--show-manpage (manpage &optional argument)
+  (require 'man)
+  (let* ((Man-notify-method 'meek)
+         (buf (Man-getpage-in-background manpage))
+         (proc (get-buffer-process buf)))
+    (while (and proc (eq (process-status proc) 'run))
+      (accept-process-output proc))
+    (switch-to-buffer buf)
+    (when argument
+      (transient--goto-argument-description argument))))
+
+(defun transient--describe-function (fn)
+  (describe-function fn)
+  (select-window (get-buffer-window (help-buffer))))
+
+(defun transient--goto-argument-description (arg)
+  (goto-char (point-min))
+  (let ((case-fold-search nil)
+        ;; This matches preceding/proceeding options.  Options
+        ;; such as "-a", "-S[<keyid>]", and "--grep=<pattern>"
+        ;; are matched by this regex without the shy group.
+        ;; The ". " in the shy group is for options such as
+        ;; "-m parent-number", and the "-[^[:space:]]+ " is
+        ;; for options such as "--mainline parent-number"
+        (others "-\\(?:. \\|-[^[:space:]]+ \\)?[^[:space:]]+"))
+    (when (re-search-forward
+           (if (equal arg "--")
+               ;; Special case.
+               "^[\t\s]+\\(--\\(?: \\|$\\)\\|\\[--\\]\\)"
+             ;; Should start with whitespace and may have
+             ;; any number of options before and/or after.
+             (format
+              "^[\t\s]+\\(?:%s, \\)*?\\(?1:%s\\)%s\\(?:, %s\\)*$"
+              others
+              ;; Options don't necessarily end in an "="
+              ;; (e.g., "--gpg-sign[=<keyid>]")
+              (string-remove-suffix "=" arg)
+              ;; Simple options don't end in an "=".  Splitting this
+              ;; into 2 cases should make getting false positives
+              ;; less likely.
+              (if (string-suffix-p "=" arg)
+                  ;; "[^[:space:]]*[^.[:space:]]" matches the option
+                  ;; value, which is usually after the option name
+                  ;; and either '=' or '[='.  The value can't end in
+                  ;; a period, as that means it's being used at the
+                  ;; end of a sentence.  The space is for options
+                  ;; such as '--mainline parent-number'.
+                  "\\(?: \\|\\[?=\\)[^[:space:]]*[^.[:space:]]"
+                ;; Either this doesn't match anything (e.g., "-a"),
+                ;; or the option is followed by a value delimited
+                ;; by a "[", "<", or ":".  A space might appear
+                ;; before this value, as in "-f <file>".  The
+                ;; space alternative is for options such as
+                ;; "-m parent-number".
+                "\\(?:\\(?: \\| ?[\\[<:]\\)[^[:space:]]*[^.[:space:]]\\)?")
+              others))
+           nil t)
+      (goto-char (match-beginning 1)))))
+
+(defun transient--insert-help ()
+  (unless (looking-back "\n\n" 2)
+    (insert "\n"))
+  (when transient--helpp
+    (insert
+     (format (propertize "\
+Type a %s to show help for that suffix command, or %s to show manual.
+Type %s to exit help.\n"
+                         'face 'transient-heading)
+             (propertize "<KEY>" 'face 'transient-key)
+             (propertize "?"     'face 'transient-key)
+             (propertize "C-g"   'face 'transient-key))))
+  (when transient--editp
+    (unless transient--helpp
+      (insert
+       (format (propertize "\
+Type a %s to set level for that suffix command.
+Type %s to set what levels are available for this prefix command.\n"
+                           'face 'transient-heading)
+               (propertize "<KEY>"   'face 'transient-key)
+               (propertize "C-x l" 'face 'transient-key))))
+    (with-slots (level) transient--prefix
+      (insert
+       (format (propertize "
+Suffixes on levels %s are available.
+Suffixes on levels %s and %s are unavailable.\n"
+                           'face 'transient-heading)
+               (propertize (format "1-%s" level)
+                           'face 'transient-enabled-suffix)
+               (propertize " 0 "
+                           'face 'transient-disabled-suffix)
+               (propertize (format ">=%s" (1+ level))
+                           'face 'transient-disabled-suffix))))))
+
+(defvar transient-resume-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap Man-quit]    'transient-resume)
+    (define-key map [remap Info-exit]   'transient-resume)
+    (define-key map [remap quit-window] 'transient-resume)
+    map)
+  "Keymap for `transient-resume-mode'.
+
+This keymap remaps every command that would usually just quit the
+documentation buffer to `transient-resume', which additionally
+resumes the suspended transient.")
+
+(define-minor-mode transient-resume-mode
+  "Auxiliary minor-mode used to resume a transient after viewing help.")
+
+;;; Compatibility
+;;;; Popup Navigation
+
+(defun transient-popup-navigation-help ()
+  "Inform the user how to enable popup navigation commands."
+  (interactive)
+  (message "This command is only available if `%s' is non-nil"
+           'transient-enable-popup-navigation))
+
+(define-button-type 'transient-button
+  'face nil
+  'action (lambda (button)
+            (let ((command (button-get button 'command)))
+              ;; Yes, I know that this is wrong(tm).
+              ;; Unfortunately it is also necessary.
+              (setq this-original-command command)
+              (call-interactively command))))
+
+(defvar transient-popup-navigation-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "<down-mouse-1>") 'transient-noop)
+    (define-key map (kbd "<mouse-1>") 'transient-mouse-push-button)
+    (define-key map (kbd "RET")       'transient-push-button)
+    (define-key map (kbd "<up>")      'transient-backward-button)
+    (define-key map (kbd "C-p")       'transient-backward-button)
+    (define-key map (kbd "<down>")    'transient-forward-button)
+    (define-key map (kbd "C-n")       'transient-forward-button)
+    (define-key map (kbd "C-r")       'transient-isearch-backward)
+    (define-key map (kbd "C-s")       'transient-isearch-forward)
+    map))
+
+(defun transient-mouse-push-button (&optional pos)
+  "Invoke the suffix the user clicks on."
+  (interactive (list last-command-event))
+  (push-button pos))
+
+(defun transient-push-button ()
+  "Invoke the selected suffix command."
+  (interactive)
+  (with-selected-window transient--window
+    (push-button)))
+
+(defun transient-backward-button (n)
+  "Move to the previous button in the transient popup buffer.
+See `backward-button' for information about N."
+  (interactive "p")
+  (with-selected-window transient--window
+    (backward-button n t)))
+
+(defun transient-forward-button (n)
+  "Move to the next button in the transient popup buffer.
+See `forward-button' for information about N."
+  (interactive "p")
+  (with-selected-window transient--window
+    (forward-button n t)))
+
+(defun transient--goto-button (command)
+  (if (not command)
+      (forward-button 1)
+    (while (and (ignore-errors (forward-button 1))
+                (not (eq (button-get (button-at (point)) 'command) command))))
+    (unless (eq (button-get (button-at (point)) 'command) command)
+      (goto-char (point-min))
+      (forward-button 1))))
+
+;;;; Popup Isearch
+
+(defvar transient--isearch-mode-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map isearch-mode-map)
+    (define-key map [remap isearch-exit]   'transient-isearch-exit)
+    (define-key map [remap isearch-cancel] 'transient-isearch-cancel)
+    (define-key map [remap isearch-abort]  'transient-isearch-abort)
+    map))
+
+(defun transient-isearch-backward (&optional regexp-p)
+  "Do incremental search backward.
+With a prefix argument, do an incremental regular expression
+search instead."
+  (interactive "P")
+  (transient--isearch-setup)
+  (let ((isearch-mode-map transient--isearch-mode-map))
+    (isearch-mode nil regexp-p)))
+
+(defun transient-isearch-forward (&optional regexp-p)
+  "Do incremental search forward.
+With a prefix argument, do an incremental regular expression
+search instead."
+  (interactive "P")
+  (transient--isearch-setup)
+  (let ((isearch-mode-map transient--isearch-mode-map))
+    (isearch-mode t regexp-p)))
+
+(defun transient-isearch-exit ()
+  "Like `isearch-exit' but adapted for `transient'."
+  (interactive)
+  (isearch-exit)
+  (transient--isearch-exit))
+
+(defun transient-isearch-cancel ()
+  "Like `isearch-cancel' but adapted for `transient'."
+  (interactive)
+  (condition-case nil (isearch-cancel) (quit))
+  (transient--isearch-exit))
+
+(defun transient-isearch-abort ()
+  "Like `isearch-abort' but adapted for `transient'."
+  (interactive)
+  (condition-case nil (isearch-abort) (quit))
+  (transient--isearch-exit))
+
+(defun transient--isearch-setup ()
+  (select-window transient--window)
+  (transient--suspend-override))
+
+(defun transient--isearch-exit ()
+  (select-window transient--original-window)
+  (transient--resume-override))
+
+;;;; Edebug
+
+(defun transient--edebug--recursive-edit (fn arg-mode)
+  (transient--debug 'edebug--recursive-edit)
+  (if (not transient--prefix)
+      (funcall fn arg-mode)
+    (transient--suspend-override t)
+    (funcall fn arg-mode)
+    (transient--resume-override t)))
+
+(advice-add 'edebug--recursive-edit :around 'transient--edebug--recursive-edit)
+
+(defun transient--abort-edebug ()
+  (when (bound-and-true-p edebug-active)
+    (transient--emergency-exit)))
+
+(advice-add 'abort-recursive-edit :before 'transient--abort-edebug)
+(advice-add 'top-level :before 'transient--abort-edebug)
+
+(defun transient--edebug-command-p ()
+  (and (bound-and-true-p edebug-active)
+       (or (memq this-command '(top-level abort-recursive-edit))
+           (string-prefix-p "edebug" (symbol-name this-command)))))
+
+;;;; Miscellaneous
+
+(declare-function which-key-mode "which-key" (&optional arg))
+
+(defun transient--suspend-which-key-mode ()
+  (when (bound-and-true-p which-key-mode)
+    (which-key-mode -1)
+    (add-hook 'post-transient-hook 'transient--resume-which-key-mode)))
+
+(defun transient--resume-which-key-mode ()
+  (unless transient--prefix
+    (which-key-mode 1)
+    (remove-hook 'post-transient-hook 'transient--resume-which-key-mode)))
+
+(defun transient-bind-q-to-quit ()
+  "Modify some keymaps to bind \"q\" to the appropriate quit command.
+
+\"C-g\" is the default binding for such commands now, but Transient's
+predecessor Magit-Popup used \"q\" instead.  If you would like to get
+that binding back, then call this function in your init file like so:
+
+  (with-eval-after-load \\='transient
+    (transient-bind-q-to-quit))
+
+Individual transients may already bind \"q\" to something else
+and such a binding would shadow the quit binding.  If that is the
+case then \"Q\" is bound to whatever \"q\" would have been bound
+to by setting `transient-substitute-key-function' to a function
+that does that.  Of course \"Q\" may already be bound to something
+else, so that function binds \"M-q\" to that command instead.
+Of course \"M-q\" may already be bound to something else, but
+we stop there."
+  (define-key transient-base-map   "q" 'transient-quit-one)
+  (define-key transient-sticky-map "q" 'transient-quit-seq)
+  (setq transient-substitute-key-function
+        'transient-rebind-quit-commands))
+
+(defun transient-rebind-quit-commands (obj)
+  "See `transient-bind-q-to-quit'."
+  (let ((key (oref obj key)))
+    (cond ((string-equal key "q") "Q")
+          ((string-equal key "Q") "M-q")
+          (t key))))
+
+(defun transient--force-fixed-pitch ()
+  (require 'face-remap)
+  (face-remap-reset-base 'default)
+  (face-remap-add-relative 'default 'fixed-pitch))
+
+;;;; Missing from Emacs
+
+(defun transient--seq-reductions-from (function sequence initial-value)
+  (let ((acc (list initial-value)))
+    (seq-doseq (elt sequence)
+      (push (funcall function (car acc) elt) acc))
+    (nreverse acc)))
+
+;;; Font-Lock
+
+(defconst transient-font-lock-keywords
+  (eval-when-compile
+    `((,(concat "("
+                (regexp-opt (list "define-transient-command"
+                                  "define-infix-command"
+                                  "define-infix-argument"
+                                  "define-suffix-command")
+                            t)
+                "\\_>[ \t'\(]*"
+                "\\(\\(?:\\sw\\|\\s_\\)+\\)?")
+       (1 'font-lock-keyword-face)
+       (2 'font-lock-function-name-face nil t)))))
+
+(font-lock-add-keywords 'emacs-lisp-mode transient-font-lock-keywords)
+
+;;; _
+(provide 'transient)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+;;; transient.el ends here
diff --git a/elpa/transient-20200125.1308/transient.info b/elpa/transient-20200125.1308/transient.info
new file mode 100644 (file)
index 0000000..70ec12a
--- /dev/null
@@ -0,0 +1,2440 @@
+This is transient.info, produced by makeinfo version 6.5 from
+transient.texi.
+
+     Copyright (C) 2018-2020 Jonas Bernoulli <jonasNOSPAMbernoul.li>
+
+     You can redistribute this document and/or modify it under the terms
+     of the GNU General Public License as published by the Free Software
+     Foundation, either version 3 of the License, or (at your option)
+     any later version.
+
+     This document is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Transient: (transient). Transient Commands.
+END-INFO-DIR-ENTRY
+
+\1f
+File: transient.info,  Node: Top,  Next: Introduction,  Up: (dir)
+
+Transient User and Developer Manual
+***********************************
+
+Taking inspiration from prefix keys and prefix arguments, Transient
+implements a similar abstraction involving a prefix command, infix
+arguments and suffix commands.  We could call this abstraction a
+"transient command", but because it always involves at least two
+commands (a prefix and a suffix) we prefer to call it just a
+"transient".
+
+   When the user calls a transient prefix command, then a transient
+(temporary) keymap is activated, which binds the transient’s infix and
+suffix commands, and functions that control the transient state are
+added to ‘pre-command-hook’ and ‘post-command-hook’.  The available
+suffix and infix commands and their state are shown in a popup buffer
+until the transient is exited by invoking a suffix command.
+
+   Calling an infix command causes its value to be changed, possibly by
+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.
+
+This manual is for Transient version 0.1.0 (v0.1.0-134-g83cb1e4+1).
+
+     Copyright (C) 2018-2020 Jonas Bernoulli <jonasNOSPAMbernoul.li>
+
+     You can redistribute this document and/or modify it under the terms
+     of the GNU General Public License as published by the Free Software
+     Foundation, either version 3 of the License, or (at your option)
+     any later version.
+
+     This document is distributed in the hope that it will be useful,
+     but WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+* Menu:
+
+* Introduction::
+* Usage::
+* Other Options::
+* Modifying Existing Transients::
+* Defining New Commands::
+* Classes and Methods::
+* Related Abstractions and Packages::
+* FAQ::
+* Keystroke Index::
+* Command Index::
+* Function Index::
+* Variable Index::
+
+— The Detailed Node Listing —
+
+Usage
+
+* Invoking Transients::
+* Aborting and Resuming Transients::
+* Common Suffix Commands::
+* Saving Values::
+* Using History::
+* Getting Help for Suffix Commands::
+* Enabling and Disabling Suffixes::
+* Other Commands::
+
+Defining New Commands
+
+* Defining Transients::
+* Binding Suffix and Infix Commands::
+* Defining Suffix and Infix Commands::
+* Using Infix Arguments::
+* Transient State::
+
+Binding Suffix and Infix Commands
+
+* Group Specifications::
+* Suffix Specifications::
+
+
+Classes and Methods
+
+* Group Classes::
+* Group Methods::
+* Prefix Classes::
+* Suffix Classes::
+* Suffix Methods::
+* Prefix Slots::
+* Suffix Slots::
+* Predicate Slots::
+
+Suffix Methods
+
+* Suffix Value Methods::
+* Suffix Format Methods::
+
+
+Related Abstractions and Packages
+
+* Comparison With Prefix Keys and Prefix Arguments::
+* Comparison With Other Packages::
+
+
+\1f
+File: transient.info,  Node: Introduction,  Next: Usage,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Taking inspiration from prefix keys and prefix arguments, Transient
+implements a similar abstraction involving a prefix command, infix
+arguments and suffix commands.  We could call this abstraction a
+"transient command", but because it always involves at least two
+commands (a prefix and a suffix) we prefer to call it just a
+"transient".
+
+     Transient keymaps are a feature provided by Emacs.  Transients as
+     implemented by this package involve the use of transient keymaps.
+
+     Emacs provides a feature that it calls "prefix commands".  When we
+     talk about "prefix commands" in this manual, then we mean our own
+     kind of "prefix commands", unless specified otherwise.  To avoid
+     ambiguity we sometimes use the terms "transient prefix command" for
+     our kind and "regular prefix command" for Emacs’ kind.
+
+   When the user calls a transient prefix command, then a transient
+(temporary) keymap is activated, which binds the transient’s infix and
+suffix commands, and functions that control the transient state are
+added to ‘pre-command-hook’ and ‘post-command-hook’.  The available
+suffix and infix commands and their state are shown in a popup buffer
+until the transient state is exited by invoking a suffix command.
+
+   Calling an infix command causes its value to be changed.  How that is
+done depends on the type of the infix command.  The simplest case is an
+infix command that represents a command-line argument that does not take
+a value.  Invoking such an infix command causes the switch to be toggled
+on or off.  More complex infix commands may read a value from the user,
+using the minibuffer.
+
+   Calling a suffix command usually causes the transient to be exited;
+the transient keymaps and hook functions are removed, the popup buffer
+no longer shows information about the (no longer bound) suffix commands,
+the values of some public global variables are set, while some internal
+global variables are unset, and finally the command is actually called.
+Suffix commands can also be configured to not exit the transient.
+
+   A suffix command can, but does not have to, use the infix arguments
+in much the same way it can choose to use or ignore the prefix
+arguments.  For a suffix command that was invoked from a transient the
+variable ‘current-transient-suffixes’ and the function ‘transient-args’
+serve about the same purpose as the variables ‘prefix-arg’ and
+‘current-prefix-arg’ do for any command that was called after the prefix
+arguments have been set using a command such as ‘universal-argument’.
+
+   The information shown in the popup buffer while a transient is active
+looks a bit like this:
+
+     ,-----------------------------------------
+     |Arguments
+     | -f Force (--force)
+     | -a Annotate (--annotate)
+     |
+     |Create
+     | t tag
+     | r release
+     `-----------------------------------------
+
+     This is a simplified version of ‘magit-tag’.  Info manuals do not
+     support images or colored text, so the above "screenshot" lacks
+     some information; in practice you would be able to tell whether the
+     arguments ‘--force’ and ‘--annotate’ are enabled or not based on
+     their color.
+
+   Transient can be used to implement simple "command dispatchers".  The
+main benefit then is that the user can see all the available commands in
+a popup buffer.  That is useful by itself because it frees the user from
+having to remember all the keys that are valid after a certain prefix
+key or command.  Magit’s ‘magit-dispatch’ command is an example of using
+Transient to merely implement a command dispatcher.
+
+   In addition to that, Transient also allows users to interactively
+pass arguments to commands.  These arguments can be much more complex
+than what is reasonable when using prefix arguments.  There is a limit
+to how many aspects of a command can be controlled using prefix
+arguments.  Furthermore what a certain prefix argument means for
+different commands can be completely different, and users have to read
+documentation to learn and then commit to memory what a certain prefix
+argument means to a certain command.
+
+   Transient suffix commands on the other hand can accept dozens of
+different arguments without the user having to remember anything.  When
+using Transient, then one can call a command with arguments that are
+just as complex as when calling the same function non-interactively
+using code.
+
+   Invoking a transient command with arguments is similar to invoking a
+command in a shell with command-line completion and history 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.  See *note
+Using History::.
+
+   After a transient prefix command is invoked ‘C-h <key>’ can be used
+to show the documentation for the infix or suffix command that ‘<key>’
+is bound to (see *note Getting Help for Suffix Commands::) and infixes
+and suffixes can be removed from the transient using ‘C-x l <key>’.
+Infixes and suffixes that are disabled by default can be enabled the
+same way.  See *note 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
+has different needs than a command that merely toggles a boolean flag.
+Additionally Transient provides abstractions for defining new types,
+which the author of Transient did not anticipate (or didn’t get around
+to implementing yet).
+
+\1f
+File: transient.info,  Node: Usage,  Next: Other Options,  Prev: Introduction,  Up: Top
+
+2 Usage
+*******
+
+* Menu:
+
+* Invoking Transients::
+* Aborting and Resuming Transients::
+* Common Suffix Commands::
+* Saving Values::
+* Using History::
+* Getting Help for Suffix Commands::
+* Enabling and Disabling Suffixes::
+* Other Commands::
+
+\1f
+File: transient.info,  Node: Invoking Transients,  Next: Aborting and Resuming Transients,  Up: Usage
+
+2.1 Invoking Transients
+=======================
+
+A transient prefix command is invoked like any other command by pressing
+the key that is bound to that command.  The main difference to other
+commands is that a transient prefix command activates a transient
+keymap, which temporarily binds the transient’s infix and suffix
+commands.  Bindings from other keymaps may, or may not, be disabled
+while the transient state is in effect.
+
+   There are two kinds of commands that are available after invoking a
+transient prefix command; infix and suffix commands.  Infix commands set
+some value (which is then shown in a popup buffer), without leaving the
+transient.  Suffix commands on the other hand usually quit the transient
+and they may use the values set by the infix commands, i.e.  the infix
+*arguments*.
+
+   Instead of setting arguments to be used by a suffix command, infix
+commands may also set some value by side-effect.
+
+\1f
+File: transient.info,  Node: Aborting and Resuming Transients,  Next: Common Suffix Commands,  Prev: Invoking Transients,  Up: Usage
+
+2.2 Aborting and Resuming Transients
+====================================
+
+To quit the transient without invoking a suffix command press ‘C-g’.
+
+   Key bindings in transient keymaps may be longer than a single event.
+After pressing a valid prefix key, all commands whose bindings do not
+begin with that prefix key are temporarily unavailable and grayed out.
+To abort the prefix key press ‘C-g’ (which in this case only quits the
+prefix key, but not the complete transient).
+
+   A transient prefix command can be bound as a suffix of another
+transient.  Invoking such a suffix replaces the current transient state
+with a new transient state, i.e.  the available bindings change and the
+information displayed in the popup buffer is updated accordingly.
+Pressing ‘C-g’ while a nested transient is active only quits the
+innermost transient, causing a return to the previous transient.
+
+   ‘C-q’ or ‘C-z’ on the other hand always exits all transients.  If you
+use the latter, then you can later resume the stack of transients using
+‘M-x transient-resume’.
+
+‘C-g’     (‘transient-quit-seq’)
+‘C-g’     (‘transient-quit-one’)
+
+     This key quits the currently active incomplete key sequence, if
+     any, or else the current transient.  When quitting the current
+     transient, then it returns to the previous transient, if any.
+
+   Transient’s predecessor bound ‘q’ instead of ‘C-g’ to the quit
+command.  To learn how to get that binding back see
+‘transient-bind-q-to-quit’’s doc string.
+
+‘C-q’     (‘transient-quit-all’)
+
+     This command quits the currently active incomplete key sequence, if
+     any, and all transients, including the active transient and all
+     suspended transients, if any.
+
+‘C-z’     (‘transient-suspend’)
+
+     Like ‘transient-quit-all’, this command quits an incomplete key
+     sequence, if any, and all transients.  Additionally it saves the
+     stack of transients so that it can easily be resumed (which is
+     particularly useful if you quickly need to do "something else" and
+     the stack is deeper than a single transient and/or you have already
+     changed the values of some infix arguments).
+
+     Note that only a single stack of transients can be saved at a time.
+     If another stack is already saved, then saving a new stack discards
+     the previous stack.
+
+‘M-x transient-resume’     (‘transient-resume’)
+
+     This command resumes the previously suspended stack of transients,
+     if any.
+
+\1f
+File: transient.info,  Node: Common Suffix Commands,  Next: Saving Values,  Prev: Aborting and Resuming Transients,  Up: Usage
+
+2.3 Common Suffix Commands
+==========================
+
+A few shared suffix commands are available in all transients.  These
+suffix commands are not shown in the popup buffer by default.
+
+   Most of these commands are bound to ‘C-x <key>’ and after pressing
+‘C-x’ a section featuring all common commands is temporarily shown in
+the popup buffer.  After invoking one of these commands, that section
+disappears again.  Note however that one of these commands is described
+as "Show common permanently"; invoke that if you want the common
+commands to always be shown for all transients.
+
+‘C-x t’     (‘transient-toggle-common’)
+
+     This command toggles whether the generic commands that are common
+     to all transients are always displayed or only after typing the
+     incomplete prefix key sequence ‘C-x’.  This only affects the
+     current Emacs session.
+
+ -- User Option: transient-show-common-commands
+
+     This option controls whether shared suffix commands are shown
+     alongside the transient-specific infix and suffix commands.  By
+     default the shared commands are not shown to avoid overwhelming the
+     user with to many options.
+
+     While a transient is active, pressing ‘C-x’ always shows the common
+     command.  The value of this option can be changed for the current
+     Emacs session by typing ‘C-x t’ while a transient is active.
+
+   The other common commands are described in either the previous node
+or in one of the following nodes.
+
+   Some of Transient’s key bindings differ from the respective bindings
+of Magit-Popup; see *note FAQ:: for more information.
+
+\1f
+File: transient.info,  Node: Saving Values,  Next: Using History,  Prev: Common Suffix Commands,  Up: Usage
+
+2.4 Saving Values
+=================
+
+After setting the infix arguments in a transient, the user can save
+those arguments for future invocations.
+
+   Most transients will start out with the saved arguments when they are
+invoked.  There are a few exceptions though.  Some transients are
+designed so that the value that they use is stored externally as the
+buffer-local value of some variable.  Invoking such a transient again
+uses the buffer-local value.  (1)
+
+   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 (see *note Using History::).
+
+‘C-x s’     (‘transient-set’)
+
+     This command saves the value of the active transient for this Emacs
+     session.
+
+‘C-x C-s’     (‘transient-save’)
+
+     Save the value of the active transient persistently across Emacs
+     sessions.
+
+ -- User Option: transient-values-file
+
+     This file is used to persist the values of transients between Emacs
+     sessions.
+
+   ---------- Footnotes ----------
+
+   (1) ‘magit-diff’ and ‘magit-log’ are two prominent examples, and
+their handling of buffer-local values is actually a bit more complicated
+than outlined above and even customizable.  This is something I am
+rethinking, but I don’t want to rush any changes.)
+
+\1f
+File: transient.info,  Node: Using History,  Next: Getting Help for Suffix Commands,  Prev: Saving Values,  Up: Usage
+
+2.5 Using History
+=================
+
+Every time the user invokes a suffix command the transient’s current
+value is saved to its history.  These values can be cycled through the
+same way one can cycle through the history of commands that read
+user-input in the minibuffer.
+
+‘M-p’     (‘transient-history-prev’)
+
+     This command switches to the previous value used for the active
+     transient.
+
+‘M-n’     (‘transient-history-next’)
+
+     This command switches to the next value used for the active
+     transient.
+
+   In addition to the transient-wide history, Transient of course
+supports per-infix history.  When an infix reads user-input using the
+minibuffer, then the user can use the regular minibuffer history
+commands to cycle through 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 (see
+*note Suffix Slots::).
+
+   Both kinds of history are saved to a file when Emacs is exited.
+
+ -- User Option: transient-history-file
+
+     This file is used to persist the history of transients and their
+     infixes between Emacs sessions.
+
+ -- User Option: transient-history-limit
+
+     This option controls how many history elements are kept at the time
+     the history is saved in ‘transient-history-file’.
+
+\1f
+File: transient.info,  Node: Getting Help for Suffix Commands,  Next: Enabling and Disabling Suffixes,  Prev: Using History,  Up: Usage
+
+2.6 Getting Help for Suffix Commands
+====================================
+
+Transients can have many suffixes and infixes that the user might not be
+familiar with.  To make it trivial to get help for these, Transient
+provides access to the documentation directly from the active transient.
+
+‘C-h’     (‘transient-help’)
+
+     This command enters help mode.  When help mode is active, then
+     typing ‘<key>’ shows information about the suffix command that
+     ‘<key>’ normally is bound to (instead of invoking it).  Pressing
+     ‘C-h’ a second time shows information about the _prefix_ command.
+
+     After typing ‘<key>’ the stack of transient states is suspended and
+     information about the suffix command is shown instead.  Typing ‘q’
+     in the help buffer buries that buffer and resumes the transient
+     state.
+
+   What sort of documentation is shown depends on how the transient was
+defined.  For infix commands that represent command-line arguments this
+ideally shows the appropriate manpage.  ‘transient-help’ then tries to
+jump to the correct location within that.  Info manuals are also
+supported.  The fallback is to show the command’s doc string, for
+non-infix suffixes this is usually appropriate.
+
+\1f
+File: transient.info,  Node: Enabling and Disabling Suffixes,  Next: Other Commands,  Prev: Getting Help for Suffix Commands,  Up: Usage
+
+2.7 Enabling and Disabling Suffixes
+===================================
+
+The user base of a package that uses transients can be very diverse.
+This is certainly the case for Magit; some users have been using it and
+Git for a decade, while others are just getting started now.
+
+   For that reason a mechanism is needed that authors can use to
+classify a transient’s infixes and suffixes along the
+essentials...everything spectrum.  We use the term "levels" to describe
+that mechanism.
+
+   Each suffix command is placed on a level and each transient has a
+level (called transient-level), which controls which suffix commands are
+available.  Integers between 1 and 7 (inclusive) are valid levels.  For
+suffixes, 0 is also valid; it means that the suffix is not displayed at
+any level.
+
+   The levels of individual transients and/or their individual suffixes
+can be changed interactively, by invoking the transient and then
+pressing ‘C-x l’ to enter the "edit" mode, see below.
+
+   The default level for both transients and their suffixes is 4.  The
+‘transient-default-level’ option only controls the default for
+transients.  The default suffix level is always 4.  The authors of
+transients should place certain suffixes on a higher level, if they
+expect that it won’t be of use to most users, and they should place very
+important suffixes on a lower level, so that they remain available even
+if the user lowers the transient level.
+
+   (Magit currently places nearly all suffixes on level 4 and lower
+levels are not used at all yet.  So for the time being you should not
+set a lower default level and using a higher level might not give you as
+many additional suffixes as you hoped.)
+
+ -- User Option: transient-default-level
+
+     This option controls which suffix levels are made available by
+     default.  It sets the transient-level for transients for which the
+     user has not set that individually.
+
+ -- User Option: transient-levels-file
+
+     This file is used to persist the levels of transients and their
+     suffixes between Emacs sessions.
+
+‘C-x l’     (‘transient-set-level’)
+
+     This command enters edit mode.  When edit mode is active, then all
+     infixes and suffixes that are currently usable are displayed along
+     with their levels.  The colors of the levels indicate whether they
+     are enabled or not.  The level of the transient is also displayed
+     along with some usage information.
+
+     In edit mode, pressing the key that would usually invoke a certain
+     suffix instead prompts the user for the level that suffix should be
+     placed on.
+
+     Help mode is available in edit mode.
+
+     To change the transient level press ‘C-x l’ again.
+
+     To exit edit mode press ‘C-g’.
+
+     Note that edit mode does not display any suffixes that are not
+     currently usable.  ‘magit-rebase’ for example shows different
+     suffixes depending on whether a rebase is already in progress or
+     not.  The predicates also apply in edit mode.
+
+     Therefore, to control which suffixes are available given a certain
+     state, you have to make sure that that state is currently active.
+
+\1f
+File: transient.info,  Node: Other Commands,  Prev: Enabling and Disabling Suffixes,  Up: Usage
+
+2.8 Other Commands
+==================
+
+When invoking a transient in a small frame, the transient window may not
+show the complete buffer, making it necessary to scroll, using the
+following commands.  These commands are never shown in the transient
+window, and the key bindings are the same as for ‘scroll-up-command’ and
+‘scroll-down-command’ in other buffers.
+
+ -- Command: transient-scroll-up arg
+
+     This command scrolls text of transient popup window upward ARG
+     lines.  If ARG is ‘nil’, then it scrolls near full screen.  This is
+     a wrapper around ‘scroll-up-command’ (which see).
+
+ -- Command: transient-scroll-down arg
+
+     This command scrolls text of transient popup window down ARG lines.
+     If ARG is ‘nil’, then it scrolls near full screen.  This is a
+     wrapper around ‘scroll-down-command’ (which see).
+
+\1f
+File: transient.info,  Node: Other Options,  Next: Modifying Existing Transients,  Prev: Usage,  Up: Top
+
+3 Other Options
+***************
+
+ -- User Option: transient-show-popup
+
+     This option controls whether the current transient’s infix and
+     suffix commands are shown in the popup buffer.
+
+        • If ‘t’ (the default) then the popup buffer is shown as soon as
+          a transient prefix command is invoked.
+
+        • If ‘nil’, then the popup buffer is not shown unless the user
+          explicitly requests it, by pressing an incomplete prefix key
+          sequence.
+
+        • If a number, then the a brief one-line summary is shown
+          instead of the popup buffer.  If zero or negative, then not
+          even that summary is shown; only the pressed key itself is
+          shown.
+
+          The popup is shown when the user explicitly requests it by
+          pressing an incomplete prefix key sequence.  Unless this is
+          zero, then the popup is shown after that many seconds of
+          inactivity (using the absolute value).
+
+ -- User Option: transient-enable-popup-navigation
+
+     This option controls whether navigation commands are enabled in the
+     transient popup.
+
+     While a transient is active the transient popup buffer is not the
+     current buffer, making it necessary to use dedicated commands to
+     act on that buffer itself.  This is disabled by default.  If this
+     option is non-nil, then the following features are available:
+
+        • ‘<up>’ moves the cursor to the previous suffix.  ‘<down>’
+          moves the cursor to the next suffix.  ‘RET’ invokes the suffix
+          the cursor is on.
+
+        • ‘<mouse-1>’ invokes the clicked on suffix.
+
+        • ‘C-s’ and ‘C-r’ start isearch in the popup buffer.
+
+ -- User Option: transient-display-buffer-action
+
+     This option specifies the action used to display the transient
+     popup buffer.  The transient popup buffer is displayed in a window
+     using ‘(display-buffer buf transient-display-buffer-action)’.
+
+     The value of this option has the form ‘(FUNCTION . ALIST)’, where
+     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 ALIST.  See *note (elisp)Choosing Window::.
+
+     The default is ‘(display-buffer-in-side-window (side . bottom))’.
+     This displays the window at the bottom of the selected frame.
+     Another useful value is ‘(display-buffer-below-selected)’.  This is
+     what ‘magit-popup’ used by default.  For more alternatives see
+     *note (elisp)Display Action Functions::.
+
+     It may be possible to display the window in another frame, but
+     whether that works in practice depends on the window-manager.  If
+     the window manager selects the new window (Emacs frame), then it
+     doesn’t work.
+
+     If you change the value of this option, then you might also want to
+     change the value of ‘transient-mode-line-format’.
+
+ -- User Option: transient-mode-line-format
+
+     This option controls whether the transient popup buffer has a
+     mode-line, separator line, or neither.
+
+     If ‘nil’, then the buffer has no mode-line.  If the buffer is not
+     displayed right above the echo area, then this probably is not a
+     good value.
+
+     If ‘line’ (the default), then the buffer also has no mode-line, but
+     a thin line is drawn instead, using the background color of the
+     face ‘transient-separator’.
+
+     Otherwise this can be any mode-line format.  See *note (elisp)Mode
+     Line Format:: for details.
+
+ -- User Option: transient-read-with-initial-input
+
+     This option controls whether the last history element is used as
+     the initial minibuffer input when reading the value of an infix
+     argument from the user.  If ‘nil’, then there is no initial input
+     and the first element has to be accessed the same way as the older
+     elements.
+
+ -- User Option: transient-highlight-mismatched-keys
+
+     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.
+
+     When this option is non-nil, then the key binding for an infix
+     argument is highlighted when only a long argument (e.g.
+     ‘--verbose’) is specified but no shorthand (e.g ‘-v’).  In the rare
+     case that a shorthand is specified but the key binding does not
+     match, then it is highlighted differently.
+
+     Highlighting mismatched key bindings is useful when learning the
+     arguments of the underlying command-line tool; you wouldn’t want to
+     learn any short-hands that do not actually exist.
+
+     The highlighting is done using one of the faces
+     ‘transient-mismatched-key’ and ‘transient-nonstandard-key’.
+
+ -- User Option: transient-substitute-key-function
+
+     This function is used to modify key bindings.  If the value of this
+     option is nil (the default), then no substitution is performed.
+
+     This function is called with one argument, the prefix object, and
+     must return a key binding description, either the existing key
+     description it finds in the ‘key’ slot, or key description that
+     replaces the prefix key.  It could be used to make other
+     substitutions, but that is discouraged.
+
+     For example, ‘=’ is hard to reach using my custom keyboard layout,
+     so I substitute ‘(’ for that, which is easy to reach using a layout
+     optimized for lisp.
+
+          (setq transient-substitute-key-function
+                (lambda (obj)
+                  (let ((key (oref obj key)))
+                    (if (string-match "\\`\\(=\\)[a-zA-Z]" key)
+                        (replace-match "(" t t key 1)
+                      key))))
+
+ -- User Option: transient-detect-key-conflicts
+
+     This option controls whether key binding conflicts should be
+     detected at the time the transient is invoked.  If so, then this
+     results in an error, which prevents the transient from being used.
+     Because of that, conflicts are ignored by default.
+
+     Conflicts cannot be determined earlier, i.e.  when the transient is
+     being defined and when new suffixes are being added, because at
+     that time there can be false-positives.  It is actually valid for
+     multiple suffixes to share a common key binding, provided the
+     predicates of those suffixes prevent that more than one of them is
+     enabled at a time.
+
+ -- User Option: transient-force-fixed-pitch
+
+     This option controls whether to force the use of a monospaced font
+     in popup buffer.  Even if you use a proportional font for the
+     ‘default’ face, you might still want to use a monospaced font in
+     transient’s popup buffer.  Setting this option to t causes
+     ‘default’ to be remapped to ‘fixed-pitch’ in that buffer.
+
+\1f
+File: transient.info,  Node: Modifying Existing Transients,  Next: Defining New Commands,  Prev: Other Options,  Up: Top
+
+4 Modifying Existing Transients
+*******************************
+
+To an extent transients can be customized interactively, see *note
+Enabling and Disabling Suffixes::.  This section explains how existing
+transients can be further modified non-interactively.
+
+   The following functions share a few arguments:
+
+   • PREFIX is a transient prefix command, a symbol.
+
+   • SUFFIX is a transient infix or suffix specification in the same
+     form as expected by ‘define-transient-command’.  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.  See *note Suffix Specifications::.
+
+     SUFFIX may also be a group in the same form as expected by
+     ‘define-transient-command’.  See *note Group Specifications::.
+
+   • LOC is a command, a key vector, a key description (a string as
+     returned by ‘key-description’), or a list specifying coordinates
+     (the last element may also be a command or key).  For example ‘(1 0
+     -1)’ identifies the last suffix (‘-1’) of the first subgroup (‘0’)
+     of the second group (‘1’).
+
+     If LOC is a list of coordinates, then it can be used to identify a
+     group, not just an individual suffix command.
+
+     The function ‘transient-get-suffix’ can be useful to determine
+     whether a certain coordination list identifies the suffix or group
+     that you expect it to identify.  In hairy cases it may be necessary
+     to look at the definition of the transient prefix command.
+
+   These functions operate on the information stored in the
+‘transient--layout’ property of the PREFIX symbol.  Suffix entries in
+that tree are not objects but have the form ‘(LEVEL CLASS PLIST)’, where
+plist should set at least ‘:key’, ‘:description’ and ‘:command’.
+
+ -- Function: transient-insert-suffix prefix loc suffix
+
+     This function inserts suffix or group SUFFIX into PREFIX before
+     LOC.
+
+ -- Function: transient-append-suffix prefix loc suffix
+
+     This function inserts suffix or group SUFFIX into PREFIX after LOC.
+
+ -- Function: transient-replace-suffix prefix loc suffix
+
+     This function replaces the suffix or group at LOC in PREFIX with
+     suffix or group SUFFIX.
+
+ -- Function: transient-remove-suffix prefix loc
+
+     This function removes the suffix or group at LOC in PREFIX.
+
+ -- Function: transient-get-suffix prefix loc
+
+     This function returns the suffix or group at LOC in PREFIX.  The
+     returned value has the form mentioned above.
+
+ -- Function: transient-suffix-put prefix loc prop value
+
+     This function edits the suffix or group at LOC in PREFIX, by
+     setting the PROP of its plist to VALUE.
+
+   Most of these functions do not signal an error if they cannot perform
+the requested modification.  The functions that insert new suffixes show
+a warning if LOC cannot be found in PREFIX, without signaling an error.
+The reason for doing it like this is that establishing a key binding
+(and that is what we essentially are trying to do here) should not
+prevent the rest of the configuration from loading.  Among these
+functions only ‘transient-get-suffix’ and ‘transient-suffix-put’ may
+signal an error.
+
+\1f
+File: transient.info,  Node: Defining New Commands,  Next: Classes and Methods,  Prev: Modifying Existing Transients,  Up: Top
+
+5 Defining New Commands
+***********************
+
+* Menu:
+
+* Defining Transients::
+* Binding Suffix and Infix Commands::
+* Defining Suffix and Infix Commands::
+* Using Infix Arguments::
+* Transient State::
+
+\1f
+File: transient.info,  Node: Defining Transients,  Next: Binding Suffix and Infix Commands,  Up: Defining New Commands
+
+5.1 Defining Transients
+=======================
+
+A transient consists of a prefix command and at least one suffix
+command, though usually a transient has several infix and suffix
+commands.  The below macro defines the transient prefix command *and*
+binds the transient’s infix and suffix commands.  In other words, it
+defines the complete transient, not just the transient prefix command
+that is used to invoke that transient.
+
+ -- Macro: define-transient-command name arglist [docstring] [keyword
+          value]... group... [body...]
+
+     This macro defines NAME as a transient prefix command and binds the
+     transient’s infix and suffix commands.
+
+     ARGLIST are the arguments that the prefix command takes.  DOCSTRING
+     is the documentation string and is optional.
+
+     These arguments can optionally be followed by keyword-value pairs.
+     Each key has to be a keyword symbol, either ‘:class’ or a keyword
+     argument supported by the constructor of that class.  The
+     ‘transient-prefix’ class is used if the class is not specified
+     explicitly.
+
+     GROUPs add key bindings for infix and suffix commands and specify
+     how these bindings are presented in the popup buffer.  At least one
+     GROUP has to be specified.  See *note Binding Suffix and Infix
+     Commands::.
+
+     The BODY is optional.  If it is omitted, then ARGLIST is ignored
+     and the function definition becomes:
+
+          (lambda ()
+            (interactive)
+            (transient-setup 'NAME))
+
+     If BODY is specified, then it must begin with an ‘interactive’ form
+     that matches ARGLIST, and it must call ‘transient-setup’.  It may
+     however call that function only when some condition is satisfied.
+
+     All transients have a (possibly ‘nil’) value, which is exported
+     when suffix commands are called, so that they can consume that
+     value.  For some transients it might be necessary to have a sort of
+     secondary value, called a "scope".  Such a scope would usually be
+     set in the command’s ‘interactive’ form and has to be passed to the
+     setup function:
+
+          (transient-setup 'NAME nil nil :scope SCOPE)
+
+     For example, the scope of the ‘magit-branch-configure’ transient is
+     the branch whose variables are being configured.
+
+\1f
+File: transient.info,  Node: Binding Suffix and Infix Commands,  Next: Defining Suffix and Infix Commands,  Prev: Defining Transients,  Up: Defining New Commands
+
+5.2 Binding Suffix and Infix Commands
+=====================================
+
+The macro ‘define-transient-command’ is used to define a transient.
+This defines the actual transient prefix command (see *note 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 ‘transient-insert-suffix’ (See *note Modifying
+Existing Transients::).  These functions take a "suffix specification"
+as one of their arguments, which has the same form as the specifications
+used in ‘define-transient-command’.
+
+* Menu:
+
+* Group Specifications::
+* Suffix Specifications::
+
+\1f
+File: transient.info,  Node: Group Specifications,  Next: Suffix Specifications,  Up: Binding Suffix and Infix Commands
+
+5.2.1 Group Specifications
+--------------------------
+
+The suffix and infix commands of a transient are organized in groups.
+The grouping controls how the descriptions of the suffixes are outlined
+visually but also makes it possible to set certain properties for a set
+of suffixes.
+
+   Several group classes exist, some of which organize suffixes in
+subgroups.  In most cases the class does not have to be specified
+explicitly, but see *note Group Classes::.
+
+   Groups are specified in the call to ‘define-transient-command’, using
+vectors.  Because groups are represented using vectors, we cannot use
+square brackets to indicate an optional element and instead use curly
+brackets to do the latter.
+
+   Group specifications then have this form:
+
+     [{LEVEL} {DESCRIPTION} {KEYWORD VALUE}... ELEMENT...]
+
+   The LEVEL is optional and defaults to 4.  See *note Enabling and
+Disabling Suffixes::.
+
+   The DESCRIPTION is optional.  If present it is used as the heading of
+the group.
+
+   The KEYWORD-VALUE pairs are optional.  Each keyword has to be a
+keyword symbol, either ‘:class’ or a keyword argument supported by the
+constructor of that class.
+
+   • One of these keywords, ‘:description’, is equivalent to specifying
+     DESCRIPTION at the very beginning of the vector.  The
+     recommendation is to use ‘:description’ if some other keyword is
+     also used, for consistency, or DESCRIPTION otherwise, because it
+     looks better.
+
+   • Likewise ‘:level’ is equivalent to LEVEL.
+
+   • Other important keywords include the ‘:if...’ keywords.  These
+     keywords control whether the group is available in a certain
+     situation.
+
+     For example, one group of the ‘magit-rebase’ transient uses ‘:if
+     magit-rebase-in-progress-p’, which contains the suffixes that are
+     useful while rebase is already in progress; and another that uses
+     ‘:if-not magit-rebase-in-progress-p’, which contains the suffixes
+     that initiate a rebase.
+
+     These predicates can also be used on individual suffixes and are
+     only documented once, see *note Predicate Slots::.
+
+   • Finally the value of ‘:hide’, if non-nil, is a predicate that
+     controls whether the group is hidden by default.  The key bindings
+     for suffixes of a hidden group should all use the same prefix key.
+     Pressing that prefix key should temporarily show the group and its
+     suffixes, which assumes that a predicate like this is used:
+
+          (lambda ()
+            (eq (car transient--redisplay-key)
+                ?\C-c)) ; the prefix key shared by all bindings
+
+   The ELEMENTs 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.)
+
+   If the ELEMENTs 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.
+
+   The form of suffix specifications is documented in the next node.
+
+\1f
+File: transient.info,  Node: Suffix Specifications,  Prev: Group Specifications,  Up: Binding Suffix and Infix Commands
+
+5.2.2 Suffix Specifications
+---------------------------
+
+A transient’s suffix and infix commands are bound when the transient
+prefix command is defined using ‘define-transient-command’, see *note
+Defining Transients::.  The commands are organized into groups, see
+*note Group Specifications::.  Here we describe the form used to bind an
+individual suffix command.
+
+   The same form is also used when later binding additional commands
+using functions such as ‘transient-insert-suffix’, see *note Modifying
+Existing Transients::.
+
+   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.
+
+   Suffix specifications have this form:
+
+     ([LEVEL] [KEY] [DESCRIPTION] COMMAND|ARGUMENT [KEYWORD VALUE]...)
+
+   LEVEL, KEY and DESCRIPTION can also be specified using the KEYWORDs
+‘:level’, ‘:key’ and ‘:description’.  If the object that is associated
+with COMMAND sets these properties, then they do not have to be
+specified here.  You can however specify them here anyway, possibly
+overriding the object’s values just for the binding inside this
+transient.
+
+   • LEVEL is the suffix level, an integer between 1 and 7.  See *note
+     Enabling and Disabling Suffixes::.
+
+   • KEY is the key binding, either a vector or key description string.
+
+   • DESCRIPTION is the description, either a string or a function that
+     returns a string.  The function should be a lambda expression to
+     avoid ambiguity.  In some cases a symbol that is bound as a
+     function would also work but to be safe you should use
+     ‘:description’ in that case.
+
+   The next element is either a command or an argument.  This is the
+only argument that is mandatory in all cases.
+
+   • COMMAND is a symbol that is bound as a function, which has to be a
+     command.  Any command will do; it does not need to have an object
+     associated with it (as would be the case if ‘define-suffix-command’
+     or ‘define-infix-command’ were used to define it).
+
+     As mentioned above, the object that is associated with a command
+     can be used to set the default for certain values that otherwise
+     have to be set in the suffix specification.  Therefore if there is
+     no object, then you have to make sure to specify the KEY and the
+     DESCRIPTION.
+
+   • The mandatory argument can also be a command-line argument, a
+     string.  In that case an anonymous command is defined and bound.
+
+     Instead of a string, this can also be a list of two strings, in
+     which case the first string is used as the short argument (which
+     can also be specified using ‘:shortarg’) and the second as the long
+     argument (which can also be specified using ‘:argument’).
+
+     Only the long argument is displayed in the popup buffer.  See
+     ‘transient-detect-key-conflicts’ for how the short argument may be
+     used.
+
+     Unless the class is specified explicitly, the appropriate class is
+     guessed based on the long argument.  If the argument ends with "=​"
+     (e.g.  "–format=") then ‘transient-option’ is used, otherwise
+     ‘transient-switch’.
+
+   Finally, details can be specified using optional KEYWORD-VALUE pairs.
+Each keyword has to be a keyword symbol, either ‘:class’ or a keyword
+argument supported by the constructor of that class.  See *note Suffix
+Slots::.
+
+\1f
+File: transient.info,  Node: Defining Suffix and Infix Commands,  Next: Using Infix Arguments,  Prev: Binding Suffix and Infix Commands,  Up: Defining New Commands
+
+5.3 Defining Suffix and Infix Commands
+======================================
+
+Note that an infix is a special kind of suffix.  Depending on context
+"suffixes" means "suffixes (including infixes)" or "non-infix suffixes".
+
+ -- Macro: define-suffix-command name arglist [docstring] [keyword
+          value]... body...
+
+     This macro defines NAME as a transient suffix command.
+
+     ARGLIST are the arguments that the command takes.  DOCSTRING is the
+     documentation string and is optional.
+
+     These arguments can optionally be followed by keyword-value pairs.
+     Each keyword has to be a keyword symbol, either ‘:class’ or a
+     keyword argument supported by the constructor of that class.  The
+     ‘transient-suffix’ class is used if the class is not specified
+     explicitly.
+
+     The BODY must begin with an ‘interactive’ form that matches
+     ARGLIST.  The infix arguments are usually accessed by using
+     ‘transient-args’ inside ‘interactive’.
+
+ -- Macro: define-infix-command name arglist [docstring] [keyword
+          value]...
+
+     This macro defines NAME as a transient infix command.
+
+     ARGLIST is always ignored (but mandatory never-the-less) and
+     reserved for future use.  DOCSTRING is the documentation string and
+     is optional.
+
+     The keyword-value pairs are mandatory.  All transient infix
+     commands are ‘equal’ to each other (but not ‘eq’), so it is
+     meaningless to define an infix command without also setting at
+     least ‘:class’ and one other keyword (which it is depends on the
+     used class, usually ‘:argument’ or ‘:variable’).
+
+     Each keyword has to be a keyword symbol, either ‘:class’ or a
+     keyword argument supported by the constructor of that class.  The
+     ‘transient-switch’ class is used if the class is not specified
+     explicitly.
+
+     The function definition is always:
+
+          (lambda ()
+            (interactive)
+            (let ((obj (transient-suffix-object)))
+              (transient-infix-set obj (transient-infix-read obj)))
+            (transient--show))
+
+     ‘transient-infix-read’ and ‘transient-infix-set’ are generic
+     functions.  Different infix commands behave differently because the
+     concrete methods are different for different infix command classes.
+     In rare cases the above command function might not be suitable,
+     even if you define your own infix command class.  In that case you
+     have to use ‘transient-suffix-command’ to define the infix command
+     and use ‘t’ as the value of the ‘:transient’ keyword.
+
+ -- Macro: define-infix-argument name arglist [docstring] [keyword
+          value]...
+
+     This macro defines NAME as a transient infix command.
+
+     It is an alias for ‘define-infix-command’.  Only use this alias to
+     define an infix command that actually sets an infix argument.  To
+     define an infix command that, for example, sets a variable, use
+     ‘define-infix-command’ instead.
+
+\1f
+File: transient.info,  Node: Using Infix Arguments,  Next: Transient State,  Prev: Defining Suffix and Infix Commands,  Up: Defining New Commands
+
+5.4 Using Infix Arguments
+=========================
+
+The function and the variables described below allow suffix commands to
+access the value of the transient from which they were invoked; which is
+the value of its infix arguments.  These variables are set when the user
+invokes a suffix command that exits the transient, but before actually
+calling the command.
+
+   When returning to the command-loop after calling the suffix command,
+the arguments are reset to ‘nil’ (which causes the function to return
+‘nil’ too).
+
+   Like for Emacs’ prefix arguments it is advisable, but not mandatory,
+to access the infix arguments inside the command’s ‘interactive’ form.
+The preferred way of doing that is to call the ‘transient-args’
+function, which for infix arguments serves about the same purpose as
+‘prefix-arg’ serves for prefix arguments.
+
+ -- Function: transient-args &optional prefix
+
+     This function returns the value of the transient prefix command
+     PREFIX.
+
+     If the current command was invoked from the transient prefix
+     command PREFIX, then it returns the active infix arguments.  If the
+     current command was not invoked from PREFIX, then it returns the
+     set, saved or default value for PREFIX.
+
+ -- Variable: current-transient-suffixes
+
+     The suffixes of the transient from which this suffix command was
+     invoked.  This is a list of objects.  Usually it is sufficient to
+     instead use the function ‘transient-args’, which returns a list of
+     values.  In complex cases it might be necessary to use this
+     variable instead, i.e.  if you need access to information beside
+     the value.
+
+ -- Variable: current-transient-prefix
+
+     The transient from which this suffix command was invoked.  The
+     returned value is a ‘transient-prefix’ object, which holds
+     information associated with the transient prefix command.
+
+ -- Variable: current-transient-command
+
+     The transient from which this suffix command was invoked.  The
+     returned value is a symbol, the transient prefix command.
+
+\1f
+File: transient.info,  Node: Transient State,  Prev: Using Infix Arguments,  Up: Defining New Commands
+
+5.5 Transient State
+===================
+
+Invoking a transient prefix command "activates" the respective
+transient, i.e.  it puts a transient keymap into effect, which binds the
+transient’s infix and suffix commands.
+
+   The default behavior while a transient is active is as follows:
+
+   • Invoking an infix command does not affect the transient state; the
+     transient remains active.
+
+   • Invoking a (non-infix) suffix command "deactivates" the transient
+     state by removing the transient keymap and performing some
+     additional cleanup.
+
+   • Invoking a command that is bound in a keymap other than the
+     transient keymap is disallowed and trying to do so results in a
+     warning.  This does not "deactivate" the transient.
+
+   But these are just the defaults.  Whether a certain command
+deactivates or "exits" the transient is configurable.  There is more
+than one way in which a command can be "transient" or "non-transient";
+the exact behavior is implemented by calling a so-called "pre-command"
+function.  Whether non-suffix commands are allowed to be called is
+configurable per transient.
+
+   • The transient-ness of suffix commands (including infix commands) is
+     controlled by the value of their ‘transient’ slot, which can be set
+     either when defining the command or when adding a binding to a
+     transient while defining the respective transient prefix command.
+
+     Valid values are booleans and the pre-commands described below.
+
+        • ‘t’ is equivalent to ‘transient--do-stay’.
+
+        • ‘nil’ is equivalent to ‘transient--do-exit’.
+
+        • If ‘transient’ is unbound (and that is actually the default
+          for non-infix suffixes) then the value of the prefix’s
+          ‘transient-suffix’ slot is used instead.  The default value of
+          that slot is ‘nil’, so the suffix’s ‘transient’ slot being
+          unbound is essentially equivalent to it being ‘nil’.
+
+   • A suffix command can be a prefix command itself, i.e.  a
+     "sub-prefix".  While a sub-prefix is active we nearly always want
+     ‘C-g’ to take the user back to the "super-prefix".  However in rare
+     cases this may not be desirable, and that makes the following
+     complication necessary:
+
+     For ‘transient-suffix’ objects the ‘transient’ slot is unbound.  We
+     can ignore that for the most part because, as stated above, ‘nil’
+     and the slot being unbound are equivalent, and mean "do exit".
+     That isn’t actually true for suffixes that are sub-prefixes though.
+     For such suffixes unbound means "do exit but allow going back",
+     which is the default, while ‘nil’ means "do exit permanently",
+     which requires that slot to be explicitly set to that value.
+
+   • The transient-ness of certain built-in suffix commands is specified
+     using ‘transient-predicate-map’.  This is a special keymap, which
+     binds commands to pre-commands (as opposed to keys to commands) and
+     takes precedence over the ‘transient’ slot.
+
+   The available pre-command functions are documented below.  They are
+called by ‘transient--pre-command’, a function on ‘pre-command-hook’ and
+the value that they return determines whether the transient is exited.
+To do so the value of one of the constants ‘transient--exit’ or
+‘transient--stay’ is used (that way we don’t have to remember if ‘t’
+means "exit" or "stay").
+
+   Additionally these functions may change the value of ‘this-command’
+(which explains why they have to be called using ‘pre-command-hook’),
+call ‘transient-export’, ‘transient--stack-zap’ or
+‘transient--stack-push’; and set the values of ‘transient--exitp’,
+‘transient--helpp’ or ‘transient--editp’.
+
+5.5.1 Pre-commands for Infixes
+------------------------------
+
+The default for infixes is ‘transient--do-stay’.  This is also the only
+function that makes sense for infixes.
+
+ -- Function: transient--do-stay
+
+     Call the command without exporting variables and stay transient.
+
+5.5.2 Pre-commands for Suffixes
+-------------------------------
+
+The default for suffixes is ‘transient--do-exit’.
+
+ -- Function: transient--do-exit
+
+     Call the command after exporting variables and exit the transient.
+
+ -- Function: transient--do-call
+
+     Call the command after exporting variables and stay transient.
+
+ -- Function: transient--do-replace
+
+     Call the transient prefix command, replacing the active transient.
+
+     This is used for suffixes that are prefixes themselves, i.e.  for
+     sub-prefixes.
+
+5.5.3 Pre-commands for Non-Suffixes
+-----------------------------------
+
+The default for non-suffixes, i.e commands that are bound in other
+keymaps beside the transient keymap, is ‘transient--do-warn’.  Silently
+ignoring the user-error is also an option, though probably not a good
+one.
+
+   If you want to let the user invoke non-suffix commands, then use
+‘transient--do-stay’ as the value of the prefix’s ‘transient-non-suffix’
+slot.
+
+ -- Function: transient--do-warn
+
+     Call ‘transient-undefined’ and stay transient.
+
+ -- Function: transient--do-noop
+
+     Call ‘transient-noop’ and stay transient.
+
+5.5.4 Special Pre-Commands
+--------------------------
+
+ -- Function: transient--do-quit-one
+
+     If active, quit help or edit mode, else exit the active transient.
+
+     This is used when the user pressed ‘C-g’.
+
+ -- Function: transient--do-quit-all
+
+     Exit all transients without saving the transient stack.
+
+     This is used when the user pressed ‘C-q’.
+
+ -- Function: transient--do-suspend
+
+     Suspend the active transient, saving the transient stack.
+
+     This is used when the user pressed ‘C-z’.
+
+\1f
+File: transient.info,  Node: Classes and Methods,  Next: Related Abstractions and Packages,  Prev: Defining New Commands,  Up: Top
+
+6 Classes and Methods
+*********************
+
+Transient uses classes and generic functions to make it possible to
+define new types of suffix commands that are similar to existing types,
+but behave differently in some aspects.  It does the same for groups and
+prefix commands, though at least for prefix commands that *currently*
+appears to be less important.
+
+   Every prefix, infix and suffix command is associated with an object,
+which holds information that controls certain aspects of its behavior.
+This happens in two ways.
+
+   • Associating a command with a certain class gives the command a
+     type.  This makes it possible to use generic functions to do
+     certain things that have to be done differently depending on what
+     type of command it acts on.
+
+     That in turn makes it possible for third-parties to add new types
+     without having to convince the maintainer of Transient that that
+     new type is important enough to justify adding a special case to a
+     dozen or so functions.
+
+   • Associating a command with an object makes it possible to easily
+     store information that is specific to that particular command.
+
+     Two commands may have the same type, but obviously their key
+     bindings and descriptions still have to be different, for example.
+
+     The values of some slots are functions.  The ‘reader’ slot for
+     example holds a function that is used to read a new value for an
+     infix command.  The values of such slots are regular functions.
+
+     Generic functions are used when a function should do something
+     different based on the type of the command, i.e.  when all commands
+     of a certain type should behave the same way but different from the
+     behavior for other types.  Object slots that hold a regular
+     function as value are used when the task that they perform is
+     likely to differ even between different commands of the same type.
+
+* Menu:
+
+* Group Classes::
+* Group Methods::
+* Prefix Classes::
+* Suffix Classes::
+* Suffix Methods::
+* Prefix Slots::
+* Suffix Slots::
+* Predicate Slots::
+
+\1f
+File: transient.info,  Node: Group Classes,  Next: Group Methods,  Up: Classes and Methods
+
+6.1 Group Classes
+=================
+
+The type of a group can be specified using the ‘:class’ property at the
+beginning of the class specification, e.g.  ‘[:class transient-columns
+...]’ in a call to ‘define-transient-command’.
+
+   • The abstract ‘transient-child’ class is the base class of both
+     ‘transient-group’ (and therefore all groups) as well as of
+     ‘transient-suffix’ (and therefore all suffix and infix commands).
+
+     This class exists because the elements (aka "children") of certain
+     groups can be other groups instead of suffix and infix commands.
+
+   • The abstract ‘transient-group’ class is the superclass of all other
+     group classes.
+
+   • The ‘transient-column’ class is the simplest group.
+
+     This is the default "flat" group.  If the class is not specified
+     explicitly and the first element is not a vector (i.e.  not a
+     group), then this class is used.
+
+     This class displays each element on a separate line.
+
+   • The ‘transient-row’ class displays all elements on a single line.
+
+   • The ‘transient-columns’ class displays commands organized in
+     columns.
+
+     Direct elements have to be groups whose elements have to be
+     commands or strings.  Each subgroup represents a column.  This
+     class takes care of inserting the subgroups’ elements.
+
+     This is the default "nested" group.  If the class is not specified
+     explicitly and the first element is a vector (i.e.  a group), then
+     this class is used.
+
+   • The ‘transient-subgroups’ class wraps other groups.
+
+     Direct elements have to be groups whose elements have to be
+     commands or strings.  This group inserts an empty line between
+     subgroups.  The subgroups themselves are responsible for displaying
+     their elements.
+
+\1f
+File: transient.info,  Node: Group Methods,  Next: Prefix Classes,  Prev: Group Classes,  Up: Classes and Methods
+
+6.2 Group Methods
+=================
+
+ -- Function: transient--insert-group group
+
+     This generic function formats the group and its elements and
+     inserts the result into the current buffer, which is a temporary
+     buffer.  The contents of that buffer are later inserted into the
+     popup buffer.
+
+     Functions that are called by this function may need to operate in
+     the buffer from which the transient was called.  To do so they can
+     temporally make the ‘transient--source-buffer’ the current buffer.
+
+\1f
+File: transient.info,  Node: Prefix Classes,  Next: Suffix Classes,  Prev: Group Methods,  Up: Classes and Methods
+
+6.3 Prefix Classes
+==================
+
+Currently the ‘transient-prefix’ class is being used for all prefix
+commands and there is only a single generic function that can be
+specialized based on the class of a prefix command.
+
+ -- Function: transient--history-init obj
+
+     This generic function is called while setting up the transient and
+     is responsible for initializing the ‘history’ slot.  This is the
+     transient-wide history; many individual infixes also have a history
+     of their own.
+
+     The default (and currently only) method extracts the value from the
+     global variable ‘transient-history’.
+
+   A transient prefix command’s object is stored in the
+‘transient--prefix’ property of the command symbol.  While a transient
+is active, a clone of that object is stored in the variable
+‘transient--prefix’.  A clone is used because some changes that are made
+to the active transient’s object should not affect later invocations.
+
+\1f
+File: transient.info,  Node: Suffix Classes,  Next: Suffix Methods,  Prev: Prefix Classes,  Up: Classes and Methods
+
+6.4 Suffix Classes
+==================
+
+   • All suffix and infix classes derive from ‘transient-suffix’, which
+     in turn derives from ‘transient-child’, from which
+     ‘transient-group’ also derives (see *note Group Classes::).
+
+   • All infix classes derive from the abstract ‘transient-infix’ class,
+     which in turn derives from the ‘transient-suffix’ class.
+
+     Infixes are a special type of suffixes.  The primary difference is
+     that infixes always use the ‘transient--do-stay’ pre-command, while
+     non-infix suffixes use a variety of pre-commands (see *note
+     Transient State::).  Doing that is most easily achieved by using
+     this class, though theoretically it would be possible to define an
+     infix class 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 (see *note Defining Suffix and Infix Commands::).
+
+   • Classes used for infix commands that represent arguments should be
+     derived from the abstract ‘transient-argument’ class.
+
+   • The ‘transient-switch’ class (or a derived class) is used for infix
+     arguments that represent command-line switches (arguments that do
+     not take a value).
+
+   • The ‘transient-option’ class (or a derived class) is used for infix
+     arguments that represent command-line options (arguments that do
+     take a value).
+
+   • The ‘transient-switches’ class can be used for a set of mutually
+     exclusive command-line switches.
+
+   • The ‘transient-files’ class can be used for a "–" argument that
+     indicates that all remaining arguments are files.
+
+   • Classes used for infix commands that represent variables should
+     derived from the abstract ‘transient-variables’ class.
+
+   Magit defines additional classes, which can serve as examples for the
+fancy things you can do without modifying Transient.  Some of these
+classes will likely get generalized and added to Transient.  For now
+they are very much subject to change and not documented.
+
+\1f
+File: transient.info,  Node: Suffix Methods,  Next: Prefix Slots,  Prev: Suffix Classes,  Up: Classes and Methods
+
+6.5 Suffix Methods
+==================
+
+To get information about the methods implementing these generic
+functions use ‘describe-function’.
+
+* Menu:
+
+* Suffix Value Methods::
+* Suffix Format Methods::
+
+\1f
+File: transient.info,  Node: Suffix Value Methods,  Next: Suffix Format Methods,  Up: Suffix Methods
+
+6.5.1 Suffix Value Methods
+--------------------------
+
+ -- Function: transient-init-value obj
+
+     This generic function sets the initial value of the object OBJ.
+
+     This function is called for all suffix commands, but unless a
+     concrete method is implemented this falls through to the default
+     implementation, which is a noop.  In other words this usually only
+     does something for infix commands, but note that this is not
+     implemented for the abstract class ‘transient-infix’, so if your
+     class derives from that directly, then you must implement a method.
+
+ -- Function: transient-infix-read obj
+
+     This generic function determines the new value of the infix object
+     OBJ.
+
+     This function merely determines the value; ‘transient-infix-set’ is
+     used to actually store the new value in the object.
+
+     For most infix classes this is done by reading a value from the
+     user using the reader specified by the ‘reader’ slot (using the
+     ‘transient-infix-value’ method described below).
+
+     For some infix classes the value is changed without reading
+     anything in the minibuffer, i.e.  the mere act of invoking the
+     infix command determines what the new value should be, based on the
+     previous value.
+
+ -- Function: transient-prompt obj
+
+     This generic function returns the prompt to be used to read infix
+     object OBJ’s value.
+
+ -- Function: transient-infix-set obj value
+
+     This generic function sets the value of infix object OBJ to VALUE.
+
+ -- Function: transient-infix-value obj
+
+     This generic function returns the value of the suffix object OBJ.
+
+     This function is called by ‘transient-args’ (which see), meaning
+     this function is how the value of a transient is determined so that
+     the invoked suffix command can use it.
+
+     Currently most values are strings, but that is not set in stone.
+     ‘nil’ is not a value, it means "no value".
+
+     Usually only infixes have a value, but see the method for
+     ‘transient-suffix’.
+
+ -- Function: transient-init-scope obj
+
+     This generic function sets the scope of the suffix object OBJ.
+
+     The scope is actually a property of the transient prefix, not of
+     individual suffixes.  However it is possible to invoke a suffix
+     command directly instead of from a transient.  In that case, if the
+     suffix expects a scope, then it has to determine that itself and
+     store it in its ‘scope’ slot.
+
+     This function is called for all suffix commands, but unless a
+     concrete method is implemented this falls through to the default
+     implementation, which is a noop.
+
+\1f
+File: transient.info,  Node: Suffix Format Methods,  Prev: Suffix Value Methods,  Up: Suffix Methods
+
+6.5.2 Suffix Format Methods
+---------------------------
+
+ -- Function: transient-format obj
+
+     This generic function formats and returns OBJ for display.
+
+     When this function is called, then the current buffer is some
+     temporary buffer.  If you need the buffer from which the prefix
+     command was invoked to be current, then do so by temporarily making
+     ‘transient--source-buffer’ current.
+
+ -- Function: transient-format-key obj
+
+     This generic function formats OBJ’s ‘key’ for display and returns
+     the result.
+
+ -- Function: transient-format-description obj
+
+     This generic function formats OBJ’s ‘description’ for display and
+     returns the result.
+
+ -- Function: transient-format-value obj
+
+     This generic function formats OBJ’s value for display and returns
+     the result.
+
+ -- Function: transient-show-help obj
+
+     Show help for the prefix, infix or suffix command represented by
+     OBJ.
+
+     For prefixes, show the info manual, if that is specified using the
+     ‘info-manual’ slot.  Otherwise show the manpage if that is
+     specified using the ‘man-page’ slot.  Otherwise show the command’s
+     doc string.
+
+     For suffixes, show the command’s doc string.
+
+     For infixes, show the manpage if that is specified.  Otherwise show
+     the command’s doc string.
+
+\1f
+File: transient.info,  Node: Prefix Slots,  Next: Suffix Slots,  Prev: Suffix Methods,  Up: Classes and Methods
+
+6.6 Prefix Slots
+================
+
+   • ‘man-page’ or ‘info-manual’ can be used to specify the
+     documentation for the prefix and its suffixes.  The command
+     ‘transient-help’ uses the method ‘transient-show-help’ (which see)
+     to lookup and use these values.
+
+   • ‘history-key’ If multiple prefix commands should share a single
+     value, then this slot has to be set to the same value for all of
+     them.  You probably don’t want that.
+
+   • ‘transient-suffix’ and ‘transient-non-suffix’ play a part when
+     determining whether the currently active transient prefix command
+     remains active/transient when a suffix or abitrary non-suffix
+     command is invoked.  See *note Transient State::.
+
+   • ‘incompatible’ A list of lists.  Each sub-list specifies a set of
+     mutually exclusive arguments.  Enabling one of these arguments
+     causes the others to be disabled.
+
+   • ‘scope’ For some transients it might be necessary to have a sort of
+     secondary value, called a "scope".  See ‘define-transient-command’.
+
+6.6.1 Internal Prefix Slots
+---------------------------
+
+These slots are mostly intended for internal use.  They should not be
+set in calls to ‘define-transient-command’.
+
+   • ‘prototype’ When a transient prefix command is invoked, then a
+     clone of that object is stored in the global variable
+     ‘transient--prefix’ and the prototype is stored in the clone’s
+     ‘prototype’ slot.
+
+   • ‘command’ The command, a symbol.  Each transient prefix command
+     consists of a command, which is stored in a symbol’s function slot
+     and an object, which is stored in the ‘transient--prefix’ property
+     of the same symbol.
+
+   • ‘level’ The level of the prefix commands.  The suffix commands
+     whose layer is equal or lower are displayed.  See *note Enabling
+     and Disabling Suffixes::.
+
+   • ‘value’ The likely outdated value of the prefix.  Instead of
+     accessing this slot directly you should use the function
+     ‘transient-get-value’, which is guaranteed to return the up-to-date
+     value.
+
+   • ‘history’ and ‘history-pos’ are used to keep track of historic
+     values.  Unless you implement your own ‘transient-infix-read’
+     method you should not have to deal with these slots.
+
+\1f
+File: transient.info,  Node: Suffix Slots,  Next: Predicate Slots,  Prev: Prefix Slots,  Up: Classes and Methods
+
+6.7 Suffix Slots
+================
+
+Here we document most of the slots that are only available for suffix
+objects.  Some slots are shared by suffix and group objects, they are
+documented in *note Predicate Slots::.
+
+   Also see *note Suffix Classes::.
+
+6.7.1 Slots of ‘transient-suffix’
+---------------------------------
+
+   • ‘key’ The key, a key vector or a key description string.
+
+   • ‘command’ The command, a symbol.
+
+   • ‘transient’ Whether to stay transient.  See *note Transient
+     State::.
+
+   • ‘format’ The format used to display the suffix in the popup buffer.
+     It must contain the following %-placeholders:
+
+        • ‘%k’ For the key.
+
+        • ‘%d’ For the description.
+
+        • ‘%v’ For the infix value.  Non-infix suffixes don’t have a
+          value.
+
+   • ‘description’ The description, either a string or a function that
+     is called with no argument and returns a string.
+
+6.7.2 Slots of ‘transient-infix’
+--------------------------------
+
+Some of these slots are only meaningful for some of the subclasses.
+They are defined here anyway to allow sharing certain methods.
+
+   • ‘argument’ The long argument, e.g.  ‘--verbose’.
+
+   • ‘shortarg’ The short argument, e.g.  ‘-v’.
+
+   • ‘multi-value’ For options, whether the option can have multiple
+     values.  If non-nil, then default to use
+     ‘completing-read-multiple’.
+
+   • ‘allow-empty’ For options, whether the empty string is a valid
+     value.
+
+   • ‘history-key’ The key used to store the history.  This defaults to
+     the command name.  This is useful when multiple infixes should
+     share the same history because their values are of the same kind.
+
+   • ‘reader’ The function used to read the value of an infix.  Not used
+     for switches.  The function takes three arguments, PROMPT,
+     INITIAL-INPUT and HISTORY, and must return a string.
+
+   • ‘prompt’ The prompt used when reading the value, either a string or
+     a function that takes the object as the only argument and which
+     returns a prompt string.
+
+   • ‘choices’ A list of valid values.  How exactly that is used depends
+     on the class of the object.
+
+6.7.3 Slots of ‘transient-variable’
+-----------------------------------
+
+   • ‘variable’ The variable.
+
+6.7.4 Slots of ‘transient-switches’
+-----------------------------------
+
+   • ‘argument-format’ The display format.  Must contain ‘%s’, one of
+     the ‘choices’ is substituted for that.  E.g.  ‘--%s-order’.
+
+   • ‘argument-regexp’ The regexp used to match any one of the switches.
+     E.g.  ‘\\(--\\(topo\\|author-date\\|date\\)-order\\)’.
+
+\1f
+File: transient.info,  Node: Predicate Slots,  Prev: Suffix Slots,  Up: Classes and Methods
+
+6.8 Predicate Slots
+===================
+
+Suffix and group objects share some predicate slots that control whether
+a group or suffix should be available depending on some state.  Only one
+of these slots can be used at the same time.  It is undefined what
+happens if you use more than one.
+
+   • ‘if’ Enable if predicate returns non-nil.
+
+   • ‘if-not’ Enable if predicate returns nil.
+
+   • ‘if-non-nil’ Enable if variable’s value is non-nil.
+
+   • ‘if-nil’ Enable if variable’s value is nil.
+
+   • ‘if-mode’ Enable if major-mode matches value.
+
+   • ‘if-not-mode’ Enable if major-mode does not match value.
+
+   • ‘if-derived’ Enable if major-mode derives from value.
+
+   • ‘if-not-derived’ Enable if major-mode does not derive from value.
+
+   One more slot is shared between group and suffix classes, ‘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.
+‘level’ controls whether a suffix or a group should be available
+depending on user preference.  See *note Enabling and Disabling
+Suffixes::.
+
+\1f
+File: transient.info,  Node: Related Abstractions and Packages,  Next: FAQ,  Prev: Classes and Methods,  Up: Top
+
+7 Related Abstractions and Packages
+***********************************
+
+* Menu:
+
+* Comparison With Prefix Keys and Prefix Arguments::
+* Comparison With Other Packages::
+
+\1f
+File: transient.info,  Node: Comparison With Prefix Keys and Prefix Arguments,  Next: Comparison With Other Packages,  Up: Related Abstractions and Packages
+
+7.1 Comparison With Prefix Keys and Prefix Arguments
+====================================================
+
+While transient commands were inspired by regular prefix keys and prefix
+arguments, they are also quite different and much more complex.
+
+   The following diagrams illustrate some of the differences.
+
+   • ‘(c)’ represents a return to the command loop.
+
+   • ‘(+)’ represents the user’s choice to press one key or another.
+
+   • ‘{WORD}’ are possible behaviors.
+
+   • ‘{NUMBER}’ is a footnote.
+
+7.1.1 Regular Prefix Commands
+-----------------------------
+
+See *note (elisp)Prefix Keys::.
+
+                                       ,--> command1 --> (c)
+                                       |
+     (c)-(+)-> prefix command or key --+--> command2 --> (c)
+                                       |
+                                       `--> command3 --> (c)
+
+7.1.2 Regular Prefix Arguments
+------------------------------
+
+See *note (elisp)Prefix Command Arguments::.
+
+             ,----------------------------------,
+             |                                  |
+             v                                  |
+     (c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c)
+                    |                                        ^        |
+                    |                                        |        |
+                    `-- sets or changes --, ,-- maybe used --'        |
+                                          | |                         |
+                                          v |                         |
+                               prefix argument state                  |
+                                           ^                          |
+                                           |                          |
+                                           `-------- discards --------'
+
+7.1.3 Transients
+----------------
+
+(∩`-´)⊃━☆゚.*・。゚
+
+   This diagram ignores the infix value and external state:
+
+     (c)
+      |        ,- {stay} ------<-,-<------------<-,-<---,
+     (+)       |                 |                |     |
+      |        |                 |                |     |
+      |        |   ,--> infix1 --|                |     |
+      |        |   |             |                |     |
+      |        |   |--> infix2 --|                |     |
+      v        v   |             |                |     |
+      prefix -(c)-(+)-> infix3 --'                ^     |
+                   |                              |     |
+                   |---------------> suffix1 -->--|     |
+                   |                              |     |
+                   |---------------> suffix2 ----{1}------> {exit} --> (c)
+                   |                                    |
+                   |---------------> suffix3 -------------> {exit} --> (c)
+                   |                                    |
+                   `--> any command --{2}-> {warn} -->--|
+                                       |                |
+                                       |--> {noop} -->--|
+                                       |                |
+                                       |--> {call} -->--'
+                                       |
+                                       `------------------> {exit} --> (c)
+
+   This diagram takes the infix value into account to an extend, while
+still ignoring external state:
+
+     (c)
+      |        ,- {stay} ------<-,-<------------<-,-<---,
+     (+)       |                 |                |     |
+      |        |                 |                |     |
+      |        |   ,--> infix1 --|                |     |
+      |        |   |    |        |                |     |
+      |        |   ,--> infix2 --|                |     |
+      v        v   |    |        |                |     |
+      prefix -(c)-(+)-> infix3 --'                |     |
+                   |    |                         ^     |
+                   |    |                         |     |
+                   |---------------> suffix1 -->--|     |
+                   |    |             ^           |     |
+                   |    |             |           |     |
+                   |---------------> suffix2 ----{1}------> {exit} --> (c)
+                   |    |             ^                 |     |
+                   |    |             |                 |     v
+                   |    |             |                 |     |
+                   |---------------> suffix3 -------------> {exit} --> (c)
+                   |    |             ^                 |     |
+                   | sets             |                 |     v
+                   |    |             maybe             |     |
+                   |    |             used              |     |
+                   |    |             |                 |     |
+                   |    |     infix --'                 |     |
+                   |    `---> value                     |     |
+                   |           ^                        |     |
+                   |           |                        |     |
+                   |       hides                        |     |
+                   |           |                        |     |
+                   |           `--------------------------<---|
+                   |                                    |     |
+                   `--> any command --{2}-> {warn} -->--|     |
+                                       |                |     |
+                                       |--> {noop} -->--|     |
+                                       |                |     |
+                                       |--> {call} -->--'     ^
+                                       |                      |
+                                       `------------------> {exit} --> (c)
+
+   This diagram provides more information about the infix value and also
+takes external state into account.
+
+                                            ,----sets--- "anything"
+                                            |
+                                            v
+                           ,---------> external
+                           |           state
+                           |            | |
+                           |  initialized |                      ☉‿⚆
+                        sets         from |
+                           |            | maybe
+                           | ,----------' used
+                           | |            |
+     (c)                   | |            v
+      |        ,- {stay} --|---<-,-<------|-----<-,-<---,
+     (+)       |           | |   |        |       |     |
+      |        |           | v   |        |       |     |
+      |        |   ,--> infix1 --|        |       |     |
+      |        |   |       | |   |        |       |     |
+      |        |   |       | v   |        |       |     |
+      |        |   ,--> infix2 --|        |       |     |
+      |        |   |    | ^      |        |       |     |
+      v        v   |    | |      |        |       |     |
+      prefix -(c)-(+)-> infix3 --'        |       |     |
+                   |    | ^               |       ^     |
+                   |    | |               v       |     |
+                   |---------------> suffix1 -->--|     |
+                   |    | |            ^  |       |     |
+                   |    | |            |  v       |     |
+                   |---------------> suffix2 ----{1}------> {exit} --> (c)
+                   |    | |            ^  |             |     |
+                   |    | |            |  |             |     v
+                   |    | |            |  v             |     |
+                   |---------------> suffix3 -------------> {exit} --> (c)
+                   |    | |            ^                |     |
+                   | sets |            |                |     v
+                   |    | initialized  maybe            |     |
+                   |    | from         used             |     |
+                   |    | |            |                |     |
+                   |    | `-- infix ---'                |     |
+                   |    `---> value -----------------------------> persistent
+                   |           ^ ^                      |     |    across
+                   |           | |                      |     |    invocations -,
+                   |       hides |                      |     |                 |
+                   |           | `----------------------------------------------'
+                   |           |                        |     |
+                   |           `--------------------------<---|
+                   |                                    |     |
+                   `--> any command --{2}-> {warn} -->--|     |
+                                       |                |     |
+                                       |--> {noop} -->--|     |
+                                       |                |     |
+                                       |--> {call} -->--'     ^
+                                       |                      |
+                                       `------------------> {exit} --> (c)
+
+   • ‘{1}’ Transients can be configured to be exited when a suffix
+     command is invoked.  The default is to do so for all suffixes
+     except for those that are common to all transients and which are
+     used to perform tasks such as providing help and saving the value
+     of the infix arguments for future invocations.  The behavior can
+     also be specified for individual suffix commands and may even
+     depend on state.
+
+   • ‘{2}’ Transients can be configured to allow the user to invoke
+     non-suffix commands.  The default is to not allow that and instead
+     warn the user.
+
+   Despite already being rather complex, even the last diagram leaves
+out many details.  Most importantly it implies that the decision whether
+to remain transient is made later than it actually is made (for the most
+part a function on ‘pre-command-hook’ is responsible).  But such
+implementation details are of little relevance to users and are covered
+elsewhere.
+
+\1f
+File: transient.info,  Node: Comparison With Other Packages,  Prev: Comparison With Prefix Keys and Prefix Arguments,  Up: Related Abstractions and Packages
+
+7.2 Comparison With Other Packages
+==================================
+
+7.2.1 Magit-Popup
+-----------------
+
+Transient is the successor to Magit-Popup (see *note
+(magit-popup)Top::).
+
+   One major difference between these two implementations of the same
+ideas is that while Transient uses transient keymaps and embraces the
+command-loop, Magit-Popup implemented an inferior mechanism that does
+not use transient keymaps and that instead of using the command-loop
+implements a naive alternative based on ‘read-char’.
+
+   Magit-Popup does not use classes and generic functions and defining a
+new command type is near impossible as it involves adding hard-coded
+special-cases to many functions.  Because of that only a single new type
+was added, which was not already part of Magit-Popup’s initial release.
+
+   A lot of things are hard-coded in Magit-Popup.  One random example is
+that the key bindings for switches must begin with "-" and those for
+options must begin with "=".
+
+7.2.2 Hydra
+-----------
+
+Hydra (see <https://github.com/abo-abo/hydra>) is another package that
+provides features similar to those of Transient.
+
+   Both packages use transient keymaps to make a set of commands
+temporarily available and show the available commands in a popup buffer.
+
+   A Hydra "body" is equivalent to a Transient "prefix" and a Hydra
+"head" is equivalent to a Transient "suffix".  Hydra has no equivalent
+of a Transient "infix".
+
+   Both hydras and transients can be used as simple command dispatchers.
+Used like this they are similar to regular prefix commands and prefix
+keys, except that the available commands are shown in the popup buffer.
+
+   (Another package that does this is ‘which-key’.  It does so
+automatically for any incomplete key sequence.  The advantage of that
+approach is that no additional work is necessary; the disadvantage is
+that the available commands are not organized semantically.)
+
+   Both Hydra and Transient provide features that go beyond simple
+command dispatchers:
+
+   • Invoking a command from a hydra does not necessarily exit the
+     hydra.  That makes it possible to invoke the same command again,
+     but using a shorter key sequence (i.e.  the key that was used to
+     enter the hydra does not have to be pressed again).
+
+     Transient supports that too, but for now this feature is not a
+     focus and the interface is a bit more complicated.  A very basic
+     example using the current interface:
+
+          (define-transient-command outline-navigate ()
+            :transient-suffix     'transient--do-stay
+            :transient-non-suffix 'transient--do-warn
+            [("p" "previous visible heading" outline-previous-visible-heading)
+             ("n" "next visible heading" outline-next-visible-heading)])
+
+   • Transient supports infix arguments; values that are set by infix
+     commands and then consumed by the invoked suffix command(s).
+
+     To my knowledge, Hydra does not support that.
+
+   Both packages make it possible to specify how exactly the available
+commands are outlined:
+
+   • With Hydra this is often done using an explicit format string,
+     which gives authors a lot of flexibility and makes it possible to
+     do fancy things.
+
+     The downside of this is that it becomes harder for a user to add
+     additional commands to an existing hydra and to change key
+     bindings.
+
+   • Transient allows the author of a transient to organize the commands
+     into groups and the use of generic functions allows authors of
+     transients to control exactly how a certain command type is
+     displayed.
+
+     However while Transient supports giving sections a heading it does
+     not currently support giving the displayed information more
+     structure by, for example, using box-drawing characters.
+
+     That could be implemented by defining a new group class, which lets
+     the author specify a format string.  It should be possible to
+     implement that without modifying any existing code, but it does not
+     currently exist.
+
+\1f
+File: transient.info,  Node: FAQ,  Next: Keystroke Index,  Prev: Related Abstractions and Packages,  Up: Top
+
+Appendix A FAQ
+**************
+
+A.1 Can I control how the popup buffer is displayed?
+====================================================
+
+Yes, see ‘transient-display-buffer-action’ in *note Other Options::.
+
+A.2 Why did some of the key bindings change?
+============================================
+
+You may have noticed that the bindings for some of the common commands
+do *not* have the prefix ‘C-x’ and that furthermore some of these
+commands are grayed out while others are not.  That unfortunately is a
+bit confusing if the section of common commands is not shown
+permanently, making the following explanation necessary.
+
+   The purpose of usually hiding that section but showing it after the
+user pressed the respective prefix key is to conserve space and not
+overwhelm users with too much noise, while allowing the user to quickly
+list common bindings on demand.
+
+   That however should not keep us from using the best possible key
+bindings.  The bindings that do use a prefix do so to avoid wasting too
+many non-prefix bindings, keeping them available for use in individual
+transients.  The bindings that do not use a prefix and that are *not*
+grayed out are very important bindings that are *always* available, even
+when invoking the "common command key prefix" or *any other*
+transient-specific prefix.  The non-prefix keys that *are* grayed out
+however, are not available when any incomplete prefix key sequence is
+active.  They do not use the "common command key prefix" because it is
+likely that users want to invoke them several times in a row and e.g.
+‘M-p M-p M-p’ is much more convenient than ‘C-x M-p C-x M-p C-x M-p’.
+
+   You may also have noticed that the "Set" command is bound to ‘C-x s’,
+while Magit-Popup used to bind ‘C-c C-c’ instead.  I have seen several
+users praise the latter binding (sic), so I did not change it
+willy-nilly.  The reason that I changed it is that using different
+prefix keys for different common commands, would have made the temporary
+display of the common commands even more confusing, i.e.  after pressing
+‘C-c’ all the ‘C-x ...’ bindings would be grayed out.
+
+   Using a single prefix for common commands key means that all other
+potential prefix keys can be used for transient-specific commands
+*without* the section of common commands also popping up.  ‘C-c’ in
+particular is a prefix that I want to (and already do) use for Magit,
+and also using that for a common command would prevent me from doing so.
+
+   (Also see the next question.)
+
+A.3 Why does ‘q’ not quit popups anymore?
+=========================================
+
+I agree that ‘q’ is a good binding for commands that quit something.
+This includes quitting whatever transient is currently active, but it
+also includes quitting whatever it is that some specific transient is
+controlling.  The transient ‘magit-blame’ for example binds ‘q’ to the
+command that turns ‘magit-blame-mode’ off.
+
+   So I had to decide if ‘q’ should quit the active transient (like
+Magit-Popup used to) or whether ‘C-g’ should do that instead, so that
+‘q’ could be bound in individual transient to whatever commands make
+sense for them.  Because all other letters are already reserved for use
+by individual transients, I have decided to no longer make an exception
+for ‘q’.
+
+   If you want to get ‘q’’s old binding back then you can do so.  Doing
+that is a bit more complicated than changing a single key binding, so I
+have implemented a function, ‘transient-bind-q-to-quit’ that makes the
+necessary changes.  See its doc string for more information.
+
+\1f
+File: transient.info,  Node: Keystroke Index,  Next: Command Index,  Prev: FAQ,  Up: Top
+
+Appendix B Keystroke Index
+**************************
+
+\0\b[index\0\b]
+* Menu:
+
+* C-g:                                   Aborting and Resuming Transients.
+                                                               (line 25)
+* C-g <1>:                               Aborting and Resuming Transients.
+                                                               (line 26)
+* C-h:                                   Getting Help for Suffix Commands.
+                                                               (line 10)
+* C-q:                                   Aborting and Resuming Transients.
+                                                               (line 36)
+* C-x C-s:                               Saving Values.        (line 25)
+* C-x l:                                 Enabling and Disabling Suffixes.
+                                                               (line 49)
+* C-x s:                                 Saving Values.        (line 20)
+* C-x t:                                 Common Suffix Commands.
+                                                               (line 16)
+* C-z:                                   Aborting and Resuming Transients.
+                                                               (line 42)
+* M-n:                                   Using History.        (line 16)
+* M-p:                                   Using History.        (line 11)
+* M-x transient-resume:                  Aborting and Resuming Transients.
+                                                               (line 55)
+
+\1f
+File: transient.info,  Node: Command Index,  Next: Function Index,  Prev: Keystroke Index,  Up: Top
+
+Appendix C Command Index
+************************
+
+\0\b[index\0\b]
+* Menu:
+
+* transient-help:                        Getting Help for Suffix Commands.
+                                                               (line 10)
+* transient-history-next:                Using History.        (line 16)
+* transient-history-prev:                Using History.        (line 11)
+* transient-quit-all:                    Aborting and Resuming Transients.
+                                                               (line 36)
+* transient-quit-one:                    Aborting and Resuming Transients.
+                                                               (line 26)
+* transient-quit-seq:                    Aborting and Resuming Transients.
+                                                               (line 25)
+* transient-resume:                      Aborting and Resuming Transients.
+                                                               (line 55)
+* transient-save:                        Saving Values.        (line 25)
+* transient-scroll-down arg:             Other Commands.       (line 18)
+* transient-scroll-up arg:               Other Commands.       (line 12)
+* transient-set:                         Saving Values.        (line 20)
+* transient-set-level:                   Enabling and Disabling Suffixes.
+                                                               (line 49)
+* transient-suspend:                     Aborting and Resuming Transients.
+                                                               (line 42)
+* transient-toggle-common:               Common Suffix Commands.
+                                                               (line 16)
+
+\1f
+File: transient.info,  Node: Function Index,  Next: Variable Index,  Prev: Command Index,  Up: Top
+
+Appendix D Function Index
+*************************
+
+\0\b[index\0\b]
+* Menu:
+
+* define-infix-argument:                 Defining Suffix and Infix Commands.
+                                                              (line  63)
+* define-infix-command:                  Defining Suffix and Infix Commands.
+                                                              (line  27)
+* define-suffix-command:                 Defining Suffix and Infix Commands.
+                                                              (line   9)
+* define-transient-command:              Defining Transients. (line  13)
+* transient--do-call:                    Transient State.     (line  98)
+* transient--do-exit:                    Transient State.     (line  94)
+* transient--do-noop:                    Transient State.     (line 125)
+* transient--do-quit-all:                Transient State.     (line 138)
+* transient--do-quit-one:                Transient State.     (line 132)
+* transient--do-replace:                 Transient State.     (line 102)
+* transient--do-stay:                    Transient State.     (line  85)
+* transient--do-suspend:                 Transient State.     (line 144)
+* transient--do-warn:                    Transient State.     (line 121)
+* transient--history-init:               Prefix Classes.      (line  10)
+* transient--insert-group:               Group Methods.       (line   6)
+* transient-append-suffix:               Modifying Existing Transients.
+                                                              (line  47)
+* transient-args:                        Using Infix Arguments.
+                                                              (line  22)
+* transient-format:                      Suffix Format Methods.
+                                                              (line   6)
+* transient-format-description:          Suffix Format Methods.
+                                                              (line  20)
+* transient-format-key:                  Suffix Format Methods.
+                                                              (line  15)
+* transient-format-value:                Suffix Format Methods.
+                                                              (line  25)
+* transient-get-suffix:                  Modifying Existing Transients.
+                                                              (line  60)
+* transient-infix-read:                  Suffix Value Methods.
+                                                              (line  17)
+* transient-infix-set:                   Suffix Value Methods.
+                                                              (line  39)
+* transient-infix-value:                 Suffix Value Methods.
+                                                              (line  43)
+* transient-init-scope:                  Suffix Value Methods.
+                                                              (line  57)
+* transient-init-value:                  Suffix Value Methods.
+                                                              (line   6)
+* transient-insert-suffix:               Modifying Existing Transients.
+                                                              (line  42)
+* transient-prompt:                      Suffix Value Methods.
+                                                              (line  34)
+* transient-remove-suffix:               Modifying Existing Transients.
+                                                              (line  56)
+* transient-replace-suffix:              Modifying Existing Transients.
+                                                              (line  51)
+* transient-scroll-down:                 Other Commands.      (line  18)
+* transient-scroll-up:                   Other Commands.      (line  12)
+* transient-show-help:                   Suffix Format Methods.
+                                                              (line  30)
+* transient-suffix-put:                  Modifying Existing Transients.
+                                                              (line  65)
+
+\1f
+File: transient.info,  Node: Variable Index,  Prev: Function Index,  Up: Top
+
+Appendix E Variable Index
+*************************
+
+\0\b[index\0\b]
+* Menu:
+
+* current-transient-command:             Using Infix Arguments.
+                                                              (line  47)
+* current-transient-prefix:              Using Infix Arguments.
+                                                              (line  41)
+* current-transient-suffixes:            Using Infix Arguments.
+                                                              (line  32)
+* transient-default-level:               Enabling and Disabling Suffixes.
+                                                              (line  38)
+* transient-detect-key-conflicts:        Other Options.       (line 136)
+* transient-display-buffer-action:       Other Options.       (line  46)
+* transient-enable-popup-navigation:     Other Options.       (line  28)
+* transient-force-fixed-pitch:           Other Options.       (line 150)
+* transient-highlight-mismatched-keys:   Other Options.       (line  95)
+* transient-history-file:                Using History.       (line  33)
+* transient-history-limit:               Using History.       (line  38)
+* transient-levels-file:                 Enabling and Disabling Suffixes.
+                                                              (line  44)
+* transient-mode-line-format:            Other Options.       (line  71)
+* transient-read-with-initial-input:     Other Options.       (line  87)
+* transient-show-common-commands:        Common Suffix Commands.
+                                                              (line  23)
+* transient-show-popup:                  Other Options.       (line   6)
+* transient-substitute-key-function:     Other Options.       (line 114)
+* transient-values-file:                 Saving Values.       (line  30)
+
+
+\1f
+Tag Table:
+Node: Top\7f751
+Node: Introduction\7f3675
+Node: Usage\7f9462
+Node: Invoking Transients\7f9796
+Node: Aborting and Resuming Transients\7f10828
+Node: Common Suffix Commands\7f13487
+Node: Saving Values\7f15241
+Ref: Saving Values-Footnote-1\7f16499
+Node: Using History\7f16769
+Node: Getting Help for Suffix Commands\7f18310
+Node: Enabling and Disabling Suffixes\7f19703
+Node: Other Commands\7f22993
+Node: Other Options\7f23949
+Node: Modifying Existing Transients\7f30960
+Node: Defining New Commands\7f34364
+Node: Defining Transients\7f34700
+Node: Binding Suffix and Infix Commands\7f37132
+Node: Group Specifications\7f37987
+Node: Suffix Specifications\7f41320
+Node: Defining Suffix and Infix Commands\7f44887
+Node: Using Infix Arguments\7f48072
+Node: Transient State\7f50292
+Node: Classes and Methods\7f56165
+Node: Group Classes\7f58379
+Node: Group Methods\7f60296
+Node: Prefix Classes\7f60941
+Node: Suffix Classes\7f62033
+Node: Suffix Methods\7f64277
+Node: Suffix Value Methods\7f64598
+Node: Suffix Format Methods\7f67358
+Node: Prefix Slots\7f68810
+Node: Suffix Slots\7f71287
+Node: Predicate Slots\7f74138
+Node: Related Abstractions and Packages\7f75386
+Node: Comparison With Prefix Keys and Prefix Arguments\7f75673
+Node: Comparison With Other Packages\7f85985
+Node: FAQ\7f90176
+Node: Keystroke Index\7f93910
+Node: Command Index\7f95544
+Node: Function Index\7f97331
+Node: Variable Index\7f101488
+\1f
+End Tag Table
+
+\1f
+Local Variables:
+coding: utf-8
+End: