]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update transient
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 22 Dec 2024 12:21:24 +0000 (13:21 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 22 Dec 2024 12:53:08 +0000 (13:53 +0100)
Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
13 files changed:
elpa/transient-20240729.1524/dir [deleted file]
elpa/transient-20240729.1524/gpl.info [deleted file]
elpa/transient-20240729.1524/transient-autoloads.el [deleted file]
elpa/transient-20240729.1524/transient-pkg.el [deleted file]
elpa/transient-20240729.1524/transient.el [deleted file]
elpa/transient-20240729.1524/transient.info [deleted file]
elpa/transient-20241219.1713/dir [new file with mode: 0644]
elpa/transient-20241219.1713/gpl.info [new file with mode: 0644]
elpa/transient-20241219.1713/transient-autoloads.el [new file with mode: 0644]
elpa/transient-20241219.1713/transient-pkg.el [new file with mode: 0644]
elpa/transient-20241219.1713/transient.el [new file with mode: 0644]
elpa/transient-20241219.1713/transient.info [new file with mode: 0644]
elpa/transient-readme.txt [deleted file]

diff --git a/elpa/transient-20240729.1524/dir b/elpa/transient-20240729.1524/dir
deleted file mode 100644 (file)
index d4d5540..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 misc features
-* Transient: (transient).       Transient Commands.
diff --git a/elpa/transient-20240729.1524/gpl.info b/elpa/transient-20240729.1524/gpl.info
deleted file mode 100644 (file)
index 3a659de..0000000
+++ /dev/null
@@ -1,721 +0,0 @@
-This is gpl.info, produced by makeinfo version 6.8 from gpl.texi.
-
-                        Version 3, 29 June 2007
-
-     Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
-
-     Everyone is permitted to copy and distribute verbatim copies of this
-     license document, but changing it is not allowed.
-
-Preamble
-========
-
-The GNU General Public License is a free, copyleft license for software
-and other kinds of works.
-
-   The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-   When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-   To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-   For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-   Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-   For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-   Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-   Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-   The precise terms and conditions for copying, distribution and
-modification follow.
-
-TERMS AND CONDITIONS
-====================
-
-  0. Definitions.
-
-     "This License" refers to version 3 of the GNU General Public
-     License.
-
-     "Copyright" also means copyright-like laws that apply to other
-     kinds of works, such as semiconductor masks.
-
-     "The Program" refers to any copyrightable work licensed under this
-     License.  Each licensee is addressed as "you".  "Licensees" and
-     "recipients" may be individuals or organizations.
-
-     To "modify" a work means to copy from or adapt all or part of the
-     work in a fashion requiring copyright permission, other than the
-     making of an exact copy.  The resulting work is called a "modified
-     version" of the earlier work or a work "based on" the earlier work.
-
-     A "covered work" means either the unmodified Program or a work
-     based on the Program.
-
-     To "propagate" a work means to do anything with it that, without
-     permission, would make you directly or secondarily liable for
-     infringement under applicable copyright law, except executing it on
-     a computer or modifying a private copy.  Propagation includes
-     copying, distribution (with or without modification), making
-     available to the public, and in some countries other activities as
-     well.
-
-     To "convey" a work means any kind of propagation that enables other
-     parties to make or receive copies.  Mere interaction with a user
-     through a computer network, with no transfer of a copy, is not
-     conveying.
-
-     An interactive user interface displays "Appropriate Legal Notices"
-     to the extent that it includes a convenient and prominently visible
-     feature that (1) displays an appropriate copyright notice, and (2)
-     tells the user that there is no warranty for the work (except to
-     the extent that warranties are provided), that licensees may convey
-     the work under this License, and how to view a copy of this
-     License.  If the interface presents a list of user commands or
-     options, such as a menu, a prominent item in the list meets this
-     criterion.
-
-  1. Source Code.
-
-     The "source code" for a work means the preferred form of the work
-     for making modifications to it.  "Object code" means any non-source
-     form of a work.
-
-     A "Standard Interface" means an interface that either is an
-     official standard defined by a recognized standards body, or, in
-     the case of interfaces specified for a particular programming
-     language, one that is widely used among developers working in that
-     language.
-
-     The "System Libraries" of an executable work include anything,
-     other than the work as a whole, that (a) is included in the normal
-     form of packaging a Major Component, but which is not part of that
-     Major Component, and (b) serves only to enable use of the work with
-     that Major Component, or to implement a Standard Interface for
-     which an implementation is available to the public in source code
-     form.  A "Major Component", in this context, means a major
-     essential component (kernel, window system, and so on) of the
-     specific operating system (if any) on which the executable work
-     runs, or a compiler used to produce the work, or an object code
-     interpreter used to run it.
-
-     The "Corresponding Source" for a work in object code form means all
-     the source code needed to generate, install, and (for an executable
-     work) run the object code and to modify the work, including scripts
-     to control those activities.  However, it does not include the
-     work's System Libraries, or general-purpose tools or generally
-     available free programs which are used unmodified in performing
-     those activities but which are not part of the work.  For example,
-     Corresponding Source includes interface definition files associated
-     with source files for the work, and the source code for shared
-     libraries and dynamically linked subprograms that the work is
-     specifically designed to require, such as by intimate data
-     communication or control flow between those subprograms and other
-     parts of the work.
-
-     The Corresponding Source need not include anything that users can
-     regenerate automatically from other parts of the Corresponding
-     Source.
-
-     The Corresponding Source for a work in source code form is that
-     same work.
-
-  2. Basic Permissions.
-
-     All rights granted under this License are granted for the term of
-     copyright on the Program, and are irrevocable provided the stated
-     conditions are met.  This License explicitly affirms your unlimited
-     permission to run the unmodified Program.  The output from running
-     a covered work is covered by this License only if the output, given
-     its content, constitutes a covered work.  This License acknowledges
-     your rights of fair use or other equivalent, as provided by
-     copyright law.
-
-     You may make, run and propagate covered works that you do not
-     convey, without conditions so long as your license otherwise
-     remains in force.  You may convey covered works to others for the
-     sole purpose of having them make modifications exclusively for you,
-     or provide you with facilities for running those works, provided
-     that you comply with the terms of this License in conveying all
-     material for which you do not control copyright.  Those thus making
-     or running the covered works for you must do so exclusively on your
-     behalf, under your direction and control, on terms that prohibit
-     them from making any copies of your copyrighted material outside
-     their relationship with you.
-
-     Conveying under any other circumstances is permitted solely under
-     the conditions stated below.  Sublicensing is not allowed; section
-     10 makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-     No covered work shall be deemed part of an effective technological
-     measure under any applicable law fulfilling obligations under
-     article 11 of the WIPO copyright treaty adopted on 20 December
-     1996, or similar laws prohibiting or restricting circumvention of
-     such measures.
-
-     When you convey a covered work, you waive any legal power to forbid
-     circumvention of technological measures to the extent such
-     circumvention is effected by exercising rights under this License
-     with respect to the covered work, and you disclaim any intention to
-     limit operation or modification of the work as a means of
-     enforcing, against the work's users, your or third parties' legal
-     rights to forbid circumvention of technological measures.
-
-  4. Conveying Verbatim Copies.
-
-     You may convey verbatim copies of the Program's source code as you
-     receive it, in any medium, provided that you conspicuously and
-     appropriately publish on each copy an appropriate copyright notice;
-     keep intact all notices stating that this License and any
-     non-permissive terms added in accord with section 7 apply to the
-     code; keep intact all notices of the absence of any warranty; and
-     give all recipients a copy of this License along with the Program.
-
-     You may charge any price or no price for each copy that you convey,
-     and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-     You may convey a work based on the Program, or the modifications to
-     produce it from the Program, in the form of source code under the
-     terms of section 4, provided that you also meet all of these
-     conditions:
-
-       a. The work must carry prominent notices stating that you
-          modified it, and giving a relevant date.
-
-       b. The work must carry prominent notices stating that it is
-          released under this License and any conditions added under
-          section 7.  This requirement modifies the requirement in
-          section 4 to "keep intact all notices".
-
-       c. You must license the entire work, as a whole, under this
-          License to anyone who comes into possession of a copy.  This
-          License will therefore apply, along with any applicable
-          section 7 additional terms, to the whole of the work, and all
-          its parts, regardless of how they are packaged.  This License
-          gives no permission to license the work in any other way, but
-          it does not invalidate such permission if you have separately
-          received it.
-
-       d. If the work has interactive user interfaces, each must display
-          Appropriate Legal Notices; however, if the Program has
-          interactive interfaces that do not display Appropriate Legal
-          Notices, your work need not make them do so.
-
-     A compilation of a covered work with other separate and independent
-     works, which are not by their nature extensions of the covered
-     work, and which are not combined with it such as to form a larger
-     program, in or on a volume of a storage or distribution medium, is
-     called an "aggregate" if the compilation and its resulting
-     copyright are not used to limit the access or legal rights of the
-     compilation's users beyond what the individual works permit.
-     Inclusion of a covered work in an aggregate does not cause this
-     License to apply to the other parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-     You may convey a covered work in object code form under the terms
-     of sections 4 and 5, provided that you also convey the
-     machine-readable Corresponding Source under the terms of this
-     License, in one of these ways:
-
-       a. Convey the object code in, or embodied in, a physical product
-          (including a physical distribution medium), accompanied by the
-          Corresponding Source fixed on a durable physical medium
-          customarily used for software interchange.
-
-       b. Convey the object code in, or embodied in, a physical product
-          (including a physical distribution medium), accompanied by a
-          written offer, valid for at least three years and valid for as
-          long as you offer spare parts or customer support for that
-          product model, to give anyone who possesses the object code
-          either (1) a copy of the Corresponding Source for all the
-          software in the product that is covered by this License, on a
-          durable physical medium customarily used for software
-          interchange, for a price no more than your reasonable cost of
-          physically performing this conveying of source, or (2) access
-          to copy the Corresponding Source from a network server at no
-          charge.
-
-       c. Convey individual copies of the object code with a copy of the
-          written offer to provide the Corresponding Source.  This
-          alternative is allowed only occasionally and noncommercially,
-          and only if you received the object code with such an offer,
-          in accord with subsection 6b.
-
-       d. Convey the object code by offering access from a designated
-          place (gratis or for a charge), and offer equivalent access to
-          the Corresponding Source in the same way through the same
-          place at no further charge.  You need not require recipients
-          to copy the Corresponding Source along with the object code.
-          If the place to copy the object code is a network server, the
-          Corresponding Source may be on a different server (operated by
-          you or a third party) that supports equivalent copying
-          facilities, provided you maintain clear directions next to the
-          object code saying where to find the Corresponding Source.
-          Regardless of what server hosts the Corresponding Source, you
-          remain obligated to ensure that it is available for as long as
-          needed to satisfy these requirements.
-
-       e. Convey the object code using peer-to-peer transmission,
-          provided you inform other peers where the object code and
-          Corresponding Source of the work are being offered to the
-          general public at no charge under subsection 6d.
-
-     A separable portion of the object code, whose source code is
-     excluded from the Corresponding Source as a System Library, need
-     not be included in conveying the object code work.
-
-     A "User Product" is either (1) a "consumer product", which means
-     any tangible personal property which is normally used for personal,
-     family, or household purposes, or (2) anything designed or sold for
-     incorporation into a dwelling.  In determining whether a product is
-     a consumer product, doubtful cases shall be resolved in favor of
-     coverage.  For a particular product received by a particular user,
-     "normally used" refers to a typical or common use of that class of
-     product, regardless of the status of the particular user or of the
-     way in which the particular user actually uses, or expects or is
-     expected to use, the product.  A product is a consumer product
-     regardless of whether the product has substantial commercial,
-     industrial or non-consumer uses, unless such uses represent the
-     only significant mode of use of the product.
-
-     "Installation Information" for a User Product means any methods,
-     procedures, authorization keys, or other information required to
-     install and execute modified versions of a covered work in that
-     User Product from a modified version of its Corresponding Source.
-     The information must suffice to ensure that the continued
-     functioning of the modified object code is in no case prevented or
-     interfered with solely because modification has been made.
-
-     If you convey an object code work under this section in, or with,
-     or specifically for use in, a User Product, and the conveying
-     occurs as part of a transaction in which the right of possession
-     and use of the User Product is transferred to the recipient in
-     perpetuity or for a fixed term (regardless of how the transaction
-     is characterized), the Corresponding Source conveyed under this
-     section must be accompanied by the Installation Information.  But
-     this requirement does not apply if neither you nor any third party
-     retains the ability to install modified object code on the User
-     Product (for example, the work has been installed in ROM).
-
-     The requirement to provide Installation Information does not
-     include a requirement to continue to provide support service,
-     warranty, or updates for a work that has been modified or installed
-     by the recipient, or for the User Product in which it has been
-     modified or installed.  Access to a network may be denied when the
-     modification itself materially and adversely affects the operation
-     of the network or violates the rules and protocols for
-     communication across the network.
-
-     Corresponding Source conveyed, and Installation Information
-     provided, in accord with this section must be in a format that is
-     publicly documented (and with an implementation available to the
-     public in source code form), and must require no special password
-     or key for unpacking, reading or copying.
-
-  7. Additional Terms.
-
-     "Additional permissions" are terms that supplement the terms of
-     this License by making exceptions from one or more of its
-     conditions.  Additional permissions that are applicable to the
-     entire Program shall be treated as though they were included in
-     this License, to the extent that they are valid under applicable
-     law.  If additional permissions apply only to part of the Program,
-     that part may be used separately under those permissions, but the
-     entire Program remains governed by this License without regard to
-     the additional permissions.
-
-     When you convey a copy of a covered work, you may at your option
-     remove any additional permissions from that copy, or from any part
-     of it.  (Additional permissions may be written to require their own
-     removal in certain cases when you modify the work.)  You may place
-     additional permissions on material, added by you to a covered work,
-     for which you have or can give appropriate copyright permission.
-
-     Notwithstanding any other provision of this License, for material
-     you add to a covered work, you may (if authorized by the copyright
-     holders of that material) supplement the terms of this License with
-     terms:
-
-       a. Disclaiming warranty or limiting liability differently from
-          the terms of sections 15 and 16 of this License; or
-
-       b. Requiring preservation of specified reasonable legal notices
-          or author attributions in that material or in the Appropriate
-          Legal Notices displayed by works containing it; or
-
-       c. Prohibiting misrepresentation of the origin of that material,
-          or requiring that modified versions of such material be marked
-          in reasonable ways as different from the original version; or
-
-       d. Limiting the use for publicity purposes of names of licensors
-          or authors of the material; or
-
-       e. Declining to grant rights under trademark law for use of some
-          trade names, trademarks, or service marks; or
-
-       f. Requiring indemnification of licensors and authors of that
-          material by anyone who conveys the material (or modified
-          versions of it) with contractual assumptions of liability to
-          the recipient, for any liability that these contractual
-          assumptions directly impose on those licensors and authors.
-
-     All other non-permissive additional terms are considered "further
-     restrictions" within the meaning of section 10.  If the Program as
-     you received it, or any part of it, contains a notice stating that
-     it is governed by this License along with a term that is a further
-     restriction, you may remove that term.  If a license document
-     contains a further restriction but permits relicensing or conveying
-     under this License, you may add to a covered work material governed
-     by the terms of that license document, provided that the further
-     restriction does not survive such relicensing or conveying.
-
-     If you add terms to a covered work in accord with this section, you
-     must place, in the relevant source files, a statement of the
-     additional terms that apply to those files, or a notice indicating
-     where to find the applicable terms.
-
-     Additional terms, permissive or non-permissive, may be stated in
-     the form of a separately written license, or stated as exceptions;
-     the above requirements apply either way.
-
-  8. Termination.
-
-     You may not propagate or modify a covered work except as expressly
-     provided under this License.  Any attempt otherwise to propagate or
-     modify it is void, and will automatically terminate your rights
-     under this License (including any patent licenses granted under the
-     third paragraph of section 11).
-
-     However, if you cease all violation of this License, then your
-     license from a particular copyright holder is reinstated (a)
-     provisionally, unless and until the copyright holder explicitly and
-     finally terminates your license, and (b) permanently, if the
-     copyright holder fails to notify you of the violation by some
-     reasonable means prior to 60 days after the cessation.
-
-     Moreover, your license from a particular copyright holder is
-     reinstated permanently if the copyright holder notifies you of the
-     violation by some reasonable means, this is the first time you have
-     received notice of violation of this License (for any work) from
-     that copyright holder, and you cure the violation prior to 30 days
-     after your receipt of the notice.
-
-     Termination of your rights under this section does not terminate
-     the licenses of parties who have received copies or rights from you
-     under this License.  If your rights have been terminated and not
-     permanently reinstated, you do not qualify to receive new licenses
-     for the same material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-     You are not required to accept this License in order to receive or
-     run a copy of the Program.  Ancillary propagation of a covered work
-     occurring solely as a consequence of using peer-to-peer
-     transmission to receive a copy likewise does not require
-     acceptance.  However, nothing other than this License grants you
-     permission to propagate or modify any covered work.  These actions
-     infringe copyright if you do not accept this License.  Therefore,
-     by modifying or propagating a covered work, you indicate your
-     acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-     Each time you convey a covered work, the recipient automatically
-     receives a license from the original licensors, to run, modify and
-     propagate that work, subject to this License.  You are not
-     responsible for enforcing compliance by third parties with this
-     License.
-
-     An "entity transaction" is a transaction transferring control of an
-     organization, or substantially all assets of one, or subdividing an
-     organization, or merging organizations.  If propagation of a
-     covered work results from an entity transaction, each party to that
-     transaction who receives a copy of the work also receives whatever
-     licenses to the work the party's predecessor in interest had or
-     could give under the previous paragraph, plus a right to possession
-     of the Corresponding Source of the work from the predecessor in
-     interest, if the predecessor has it or can get it with reasonable
-     efforts.
-
-     You may not impose any further restrictions on the exercise of the
-     rights granted or affirmed under this License.  For example, you
-     may not impose a license fee, royalty, or other charge for exercise
-     of rights granted under this License, and you may not initiate
-     litigation (including a cross-claim or counterclaim in a lawsuit)
-     alleging that any patent claim is infringed by making, using,
-     selling, offering for sale, or importing the Program or any portion
-     of it.
-
-  11. Patents.
-
-     A "contributor" is a copyright holder who authorizes use under this
-     License of the Program or a work on which the Program is based.
-     The work thus licensed is called the contributor's "contributor
-     version".
-
-     A contributor's "essential patent claims" are all patent claims
-     owned or controlled by the contributor, whether already acquired or
-     hereafter acquired, that would be infringed by some manner,
-     permitted by this License, of making, using, or selling its
-     contributor version, but do not include claims that would be
-     infringed only as a consequence of further modification of the
-     contributor version.  For purposes of this definition, "control"
-     includes the right to grant patent sublicenses in a manner
-     consistent with the requirements of this License.
-
-     Each contributor grants you a non-exclusive, worldwide,
-     royalty-free patent license under the contributor's essential
-     patent claims, to make, use, sell, offer for sale, import and
-     otherwise run, modify and propagate the contents of its contributor
-     version.
-
-     In the following three paragraphs, a "patent license" is any
-     express agreement or commitment, however denominated, not to
-     enforce a patent (such as an express permission to practice a
-     patent or covenant not to sue for patent infringement).  To "grant"
-     such a patent license to a party means to make such an agreement or
-     commitment not to enforce a patent against the party.
-
-     If you convey a covered work, knowingly relying on a patent
-     license, and the Corresponding Source of the work is not available
-     for anyone to copy, free of charge and under the terms of this
-     License, through a publicly available network server or other
-     readily accessible means, then you must either (1) cause the
-     Corresponding Source to be so available, or (2) arrange to deprive
-     yourself of the benefit of the patent license for this particular
-     work, or (3) arrange, in a manner consistent with the requirements
-     of this License, to extend the patent license to downstream
-     recipients.  "Knowingly relying" means you have actual knowledge
-     that, but for the patent license, your conveying the covered work
-     in a country, or your recipient's use of the covered work in a
-     country, would infringe one or more identifiable patents in that
-     country that you have reason to believe are valid.
-
-     If, pursuant to or in connection with a single transaction or
-     arrangement, you convey, or propagate by procuring conveyance of, a
-     covered work, and grant a patent license to some of the parties
-     receiving the covered work authorizing them to use, propagate,
-     modify or convey a specific copy of the covered work, then the
-     patent license you grant is automatically extended to all
-     recipients of the covered work and works based on it.
-
-     A patent license is "discriminatory" if it does not include within
-     the scope of its coverage, prohibits the exercise of, or is
-     conditioned on the non-exercise of one or more of the rights that
-     are specifically granted under this License.  You may not convey a
-     covered work if you are a party to an arrangement with a third
-     party that is in the business of distributing software, under which
-     you make payment to the third party based on the extent of your
-     activity of conveying the work, and under which the third party
-     grants, to any of the parties who would receive the covered work
-     from you, a discriminatory patent license (a) in connection with
-     copies of the covered work conveyed by you (or copies made from
-     those copies), or (b) primarily for and in connection with specific
-     products or compilations that contain the covered work, unless you
-     entered into that arrangement, or that patent license was granted,
-     prior to 28 March 2007.
-
-     Nothing in this License shall be construed as excluding or limiting
-     any implied license or other defenses to infringement that may
-     otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-     If conditions are imposed on you (whether by court order, agreement
-     or otherwise) that contradict the conditions of this License, they
-     do not excuse you from the conditions of this License.  If you
-     cannot convey a covered work so as to satisfy simultaneously your
-     obligations under this License and any other pertinent obligations,
-     then as a consequence you may not convey it at all.  For example,
-     if you agree to terms that obligate you to collect a royalty for
-     further conveying from those to whom you convey the Program, the
-     only way you could satisfy both those terms and this License would
-     be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-     Notwithstanding any other provision of this License, you have
-     permission to link or combine any covered work with a work licensed
-     under version 3 of the GNU Affero General Public License into a
-     single combined work, and to convey the resulting work.  The terms
-     of this License will continue to apply to the part which is the
-     covered work, but the special requirements of the GNU Affero
-     General Public License, section 13, concerning interaction through
-     a network will apply to the combination as such.
-
-  14. Revised Versions of this License.
-
-     The Free Software Foundation may publish revised and/or new
-     versions of the GNU General Public License from time to time.  Such
-     new versions will be similar in spirit to the present version, but
-     may differ in detail to address new problems or concerns.
-
-     Each version is given a distinguishing version number.  If the
-     Program specifies that a certain numbered version of the GNU
-     General Public License "or any later version" applies to it, you
-     have the option of following the terms and conditions either of
-     that numbered version or of any later version published by the Free
-     Software Foundation.  If the Program does not specify a version
-     number of the GNU General Public License, you may choose any
-     version ever published by the Free Software Foundation.
-
-     If the Program specifies that a proxy can decide which future
-     versions of the GNU General Public License can be used, that
-     proxy's public statement of acceptance of a version permanently
-     authorizes you to choose that version for the Program.
-
-     Later license versions may give you additional or different
-     permissions.  However, no additional obligations are imposed on any
-     author or copyright holder as a result of your choosing to follow a
-     later version.
-
-  15. Disclaimer of Warranty.
-
-     THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-     APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE
-     COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
-     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE
-     RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
-     SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-     NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-     IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
-     AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
-     DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-     CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
-     THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
-     BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-     PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-     PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
-     THE POSSIBILITY OF SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-     If the disclaimer of warranty and limitation of liability provided
-     above cannot be given local legal effect according to their terms,
-     reviewing courts shall apply local law that most closely
-     approximates an absolute waiver of all civil liability in
-     connection with the Program, unless a warranty or assumption of
-     liability accompanies a copy of the Program in return for a fee.
-
-END OF TERMS AND CONDITIONS
-===========================
-
-How to Apply These Terms to Your New Programs
-=============================================
-
-If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
-
-   To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
-     Copyright (C) YEAR NAME OF AUTHOR
-
-     This program 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 program 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.
-
-     You should have received a copy of the GNU General Public License
-     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-   Also add information on how to contact you by electronic and paper
-mail.
-
-   If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-     PROGRAM Copyright (C) YEAR NAME OF AUTHOR
-     This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
-     This is free software, and you are welcome to redistribute it
-     under certain conditions; type 'show c' for details.
-
-   The hypothetical commands 'show w' and 'show c' should show the
-appropriate parts of the General Public License.  Of course, your
-program's commands might be different; for a GUI interface, you would
-use an "about box".
-
-   You should also get your employer (if you work as a programmer) or
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  For more information on this, and how to apply and follow
-the GNU GPL, see <https://www.gnu.org/licenses/>.
-
-   The GNU General Public License does not permit incorporating your
-program into proprietary programs.  If your program is a subroutine
-library, you may consider it more useful to permit linking proprietary
-applications with the library.  If this is what you want to do, use the
-GNU Lesser General Public License instead of this License.  But first,
-please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
-
-\1f
-Tag Table:
-\1f
-End Tag Table
-
-\1f
-Local Variables:
-coding: utf-8
-End:
diff --git a/elpa/transient-20240729.1524/transient-autoloads.el b/elpa/transient-20240729.1524/transient-autoloads.el
deleted file mode 100644 (file)
index df3d367..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-;;; transient-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
-;; Generated by the `loaddefs-generate' function.
-
-;; This file is part of GNU Emacs.
-
-;;; Code:
-
-(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
-
-
-\f
-;;; Generated autoloads from transient.el
-
-(autoload 'transient-insert-suffix "transient" "\
-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 `transient-define-prefix').
-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).
-Remove a conflicting binding unless optional KEEP-OTHER is
-  non-nil.
-See info node `(transient)Modifying Existing Transients'.
-
-(fn PREFIX LOC SUFFIX &optional KEEP-OTHER)")
-(function-put 'transient-insert-suffix 'lisp-indent-function 'defun)
-(autoload 'transient-append-suffix "transient" "\
-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 `transient-define-prefix').
-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).
-Remove a conflicting binding unless optional KEEP-OTHER is
-  non-nil.
-See info node `(transient)Modifying Existing Transients'.
-
-(fn PREFIX LOC SUFFIX &optional KEEP-OTHER)")
-(function-put 'transient-append-suffix 'lisp-indent-function 'defun)
-(autoload 'transient-replace-suffix "transient" "\
-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 `transient-define-prefix').
-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'.
-
-(fn PREFIX LOC SUFFIX)")
-(function-put 'transient-replace-suffix 'lisp-indent-function 'defun)
-(autoload 'transient-remove-suffix "transient" "\
-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'.
-
-(fn PREFIX LOC)")
-(function-put 'transient-remove-suffix 'lisp-indent-function 'defun)
-(register-definition-prefixes "transient" '("find-function-advised-original" "transient"))
-\f
-;;; End of scraped data
-
-(provide 'transient-autoloads)
-
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; no-native-compile: t
-;; coding: utf-8-emacs-unix
-;; End:
-
-;;; transient-autoloads.el ends here
diff --git a/elpa/transient-20240729.1524/transient-pkg.el b/elpa/transient-20240729.1524/transient-pkg.el
deleted file mode 100644 (file)
index 178fb45..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-(define-package "transient" "20240729.1524" "Transient commands"
-  '((emacs "26.1")
-    (compat "30.0.0.0")
-    (seq "2.24"))
-  :commit "6543000d5a509096f0f98eb4b814d7f6f2114ce3" :authors
-  '(("Jonas Bernoulli" . "emacs.transientNOSPAMjonas.bernoulli.dev"))
-  :maintainers
-  '(("Jonas Bernoulli" . "emacs.transientNOSPAMjonas.bernoulli.dev"))
-  :maintainer
-  '("Jonas Bernoulli" . "emacs.transientNOSPAMjonas.bernoulli.dev")
-  :keywords
-  '("extensions")
-  :url "https://github.com/magit/transient")
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/transient-20240729.1524/transient.el b/elpa/transient-20240729.1524/transient.el
deleted file mode 100644 (file)
index 9630be6..0000000
+++ /dev/null
@@ -1,4586 +0,0 @@
-;;; transient.el --- Transient commands  -*- lexical-binding:t -*-
-
-;; Copyright (C) 2018-2024 Free Software Foundation, Inc.
-
-;; Author: Jonas Bernoulli <emacs.transientNOSPAMjonas.bernoulli.dev>
-;; Homepage: https://github.com/magit/transient
-;; Keywords: extensions
-
-;; Package-Version: 0.7.3
-;; Package-Requires: ((emacs "26.1") (compat "30.0.0.0") (seq "2.24"))
-
-;; SPDX-License-Identifier: GPL-3.0-or-later
-
-;; This file is part of GNU Emacs.
-
-;; GNU Emacs 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.
-;;
-;; GNU Emacs 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.
-;;
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Transient is the library used to implement the keyboard-driven menus
-;; in Magit.  It is distributed as a separate package, so that it can be
-;; used to implement similar menus in other packages.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'compat)
-(require 'eieio)
-(require 'edmacro)
-(require 'format-spec)
-
-(eval-and-compile
-  (when (and (featurep 'seq)
-             (not (fboundp 'seq-keep)))
-    (unload-feature 'seq 'force)))
-(require 'seq)
-(unless (fboundp 'seq-keep)
-  (display-warning 'transient (substitute-command-keys "\
-Transient requires `seq' >= 2.24,
-but due to bad defaults, Emacs' package manager, refuses to
-upgrade this and other built-in packages to higher releases
-from GNU Elpa, when a package specifies that this is needed.
-
-To fix this, you have to add this to your init file:
-
-  (setq package-install-upgrade-built-in t)
-
-Then evaluate that expression by placing the cursor after it
-and typing \\[eval-last-sexp].
-
-Once you have done that, you have to explicitly upgrade `seq':
-
-  \\[package-upgrade] seq \\`RET'
-
-Then you also must make sure the updated version is loaded,
-by evaluating this form:
-
-  (progn (unload-feature 'seq t) (require 'seq))
-
-Until you do this, you will get random errors about `seq-keep'
-being undefined while using Transient.
-
-If you don't use the `package' package manager but still get
-this warning, then your chosen package manager likely has a
-similar defect.") :emergency))
-
-(eval-when-compile (require 'subr-x))
-
-(declare-function info "info" (&optional file-or-node buffer))
-(declare-function Man-find-section "man" (section))
-(declare-function Man-next-section "man" (n))
-(declare-function Man-getpage-in-background "man" (topic))
-
-(defvar Man-notify-method)
-(defvar pp-default-function) ; since Emacs 29.1
-
-(defmacro transient--with-emergency-exit (id &rest body)
-  (declare (indent defun))
-  (unless (keywordp id)
-    (setq body (cons id body))
-    (setq id nil))
-  `(condition-case err
-       (let ((debugger #'transient--exit-and-debug))
-         ,(macroexp-progn body))
-     ((debug error)
-      (transient--emergency-exit ,id)
-      (signal (car err) (cdr err)))))
-
-(defun transient--exit-and-debug (&rest args)
-  (transient--emergency-exit :debugger)
-  (apply #'debug args))
-
-;;; Options
-
-(defgroup transient nil
-  "Transient commands."
-  :group 'extensions)
-
-(defcustom transient-show-popup t
-  "Whether to show the current transient in a popup buffer.
-\\<transient-map>
-- 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 \\[transient-show] or a prefix key.
-
-- 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
-  \\[transient-show] or a prefix key.  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 t
-  "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 is non-nil, then the following
-bindings are available:
-
-\\<transient-popup-navigation-map>\
-- \\[transient-backward-button] moves the cursor to the previous suffix.
-- \\[transient-forward-button] moves the cursor to the next suffix.
-- \\[transient-push-button] invokes the suffix the cursor is on.
-\\<transient-button-map>\
-- \\`<mouse-1>' and \\`<mouse-2>' invoke the clicked on suffix.
-\\<transient-popup-navigation-map>\
-- \\[transient-isearch-backward]\
- and \\[transient-isearch-forward] start isearch in the popup buffer.
-
-\\`<mouse-1>' and \\`<mouse-2>' are bound in `transient-push-button'.
-All other bindings are in `transient-popup-navigation-map'.
-
-By default \\`M-RET' is bound to `transient-push-button', instead of
-\\`RET', because if a transient allows the invocation of non-suffixes
-then it is likely that you would want \\`RET' to do what it would do
-if no transient were active."
-  :package-version '(transient . "0.4.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-display-buffer-action
-  '(display-buffer-in-side-window
-    (side . bottom)
-    (dedicated . t)
-    (inhibit-same-window . t)
-    (window-parameters (no-other-window . t)))
-  "The action used to display the transient popup buffer.
-
-The transient popup buffer is displayed in a window using
-
-  (display-buffer BUFFER 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 info node `(elisp)Choosing
-Window' for details.
-
-The default is:
-
-  (display-buffer-in-side-window
-    (side . bottom)
-    (dedicated . t)
-    (inhibit-same-window . t)
-    (window-parameters (no-other-window . t)))
-
-This displays the window at the bottom of the selected frame.
-Another useful FUNCTION is `display-buffer-below-selected', which
-is what `magit-popup' used by default.  For more alternatives see
-info node `(elisp)Display Action Functions' and info node
-`(elisp)Buffer Display Action Alists'.
-
-Note that the buffer that was current before the transient buffer
-is shown should remain the current buffer.  Many suffix commands
-act on the thing at point, if appropriate, and if the transient
-buffer became the current buffer, then that would change what is
-at point.  To that effect `inhibit-same-window' ensures that the
-selected window is not used to show the transient buffer.
-
-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 that unfortunately changes which buffer is current.
-
-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.3.0")
-  :group 'transient
-  :type '(cons (choice function (repeat :tag "Functions" function))
-               alist))
-
-(defcustom transient-mode-line-format '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) or a natural number, then the buffer
-has no mode-line, but a line is drawn is drawn in its place.
-If a number is used, that specifies the thickness of the line.
-On termcap frames we cannot draw lines, so there `line' and
-numbers are synonyms for nil.
-
-The color of the line is used to indicate if non-suffixes are
-allowed and whether they exit the transient.  The foreground
-color of `transient-key-noop' (if non-suffix are disallowed),
-`transient-key-stay' (if allowed and transient stays active), or
-`transient-key-exit' (if allowed and they exit the transient) is
-used to draw the line.
-
-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)
-                 (number :tag "substitute line with thickness")
-                 (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 shorthand (e.g., \"-v\").
-In the rare case that a short-hand is specified but does not
-match the key binding, then it is highlighted differently.
-
-The highlighting is done using `transient-mismatched-key'
-and `transient-nonstandard-key'."
-  :package-version '(transient . "0.1.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-highlight-higher-levels nil
-  "Whether to highlight suffixes on higher levels.
-
-This is primarily intended for package authors.
-
-When non-nil then highlight the description of suffixes whose
-level is above 4, the default of `transient-default-level'.
-Assuming you have set that variable to 7, this highlights all
-suffixes that won't be available to users without them making
-the same customization."
-  :package-version '(transient . "0.3.6")
-  :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-semantic-coloring t
-  "Whether to use colors to indicate transient behavior.
-
-If non-nil, then the key binding of each suffix is colorized to
-indicate whether it exits the transient state or not, and the
-line that is drawn below the transient popup buffer is used to
-indicate the behavior of non-suffix commands."
-  :package-version '(transient . "0.5.0")
-  :group 'transient
-  :type 'boolean)
-
-(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-align-variable-pitch nil
-  "Whether to align columns pixel-wise in the popup buffer.
-
-If this is non-nil, then columns are aligned pixel-wise to
-support variable-pitch fonts.  Keys are not aligned, so you
-should use a fixed-pitch font for the `transient-key' face.
-Other key faces inherit from that face unless a theme is
-used that breaks that relationship.
-
-This option is intended for users who use a variable-pitch
-font for the `default' face.
-
-Also see `transient-force-fixed-pitch'."
-  :package-version '(transient . "0.4.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-force-fixed-pitch nil
-  "Whether to force use of monospaced font in the 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.
-
-Also see `transient-align-variable-pitch'."
-  :package-version '(transient . "0.2.0")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-force-single-column nil
-  "Whether to force use of a single column to display suffixes.
-
-This might be useful for users with low vision who use large
-text and might otherwise have to scroll in two dimensions."
-  :package-version '(transient . "0.3.6")
-  :group 'transient
-  :type 'boolean)
-
-(defcustom transient-hide-during-minibuffer-read nil
-  "Whether to hide the transient buffer while reading in the minibuffer."
-  :package-version '(transient . "0.4.0")
-  :group 'transient
-  :type 'boolean)
-
-(defconst transient--max-level 7)
-(defconst transient--default-child-level 1)
-(defconst transient--default-prefix-level 4)
-
-(defcustom transient-default-level transient--default-prefix-level
-  "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 "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 "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 "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-argument '((t :inherit font-lock-string-face :weight bold))
-  "Face used for enabled arguments."
-  :group 'transient-faces)
-
-(defface transient-inactive-argument '((t :inherit shadow))
-  "Face used for inactive arguments."
-  :group 'transient-faces)
-
-(defface transient-value '((t :inherit font-lock-string-face :weight bold))
-  "Face used for values."
-  :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-inapt-suffix '((t :inherit shadow :italic t))
-  "Face used for suffixes that are inapt at this time."
-  :group 'transient-faces)
-
-(defface transient-active-infix '((t :inherit highlight))
-  "Face used for the infix for which the value is being read."
-  :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-higher-level
-  `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1)
-              :color ,(let ((color (face-attribute 'shadow :foreground nil t)))
-                        (or (and (not (eq color 'unspecified)) color)
-                            "grey60")))))
-  "Face optionally used to highlight suffixes on higher levels.
-Also see option `transient-highlight-higher-levels'."
-  :group 'transient-faces)
-
-(defface transient-delimiter '((t :inherit shadow))
-  "Face used for delimiters and separators.
-This includes the parentheses around values and the pipe
-character used to separate possible values from each other."
-  :group 'transient-faces)
-
-(defface transient-key '((t :inherit font-lock-builtin-face))
-  "Face used for keys."
-  :group 'transient-faces)
-
-(defface transient-key-stay
-  `((((class color) (background light))
-     :inherit transient-key
-     :foreground "#22aa22")
-    (((class color) (background dark))
-     :inherit transient-key
-     :foreground "#ddffdd"))
-  "Face used for keys of suffixes that don't exit transient state."
-  :group 'transient-faces)
-
-(defface transient-key-noop
-  `((((class color) (background light))
-     :inherit transient-key
-     :foreground "grey80")
-    (((class color) (background dark))
-     :inherit transient-key
-     :foreground "grey30"))
-  "Face used for keys of suffixes that currently cannot be invoked."
-  :group 'transient-faces)
-
-(defface transient-key-return
-  `((((class color) (background light))
-     :inherit transient-key
-     :foreground "#aaaa11")
-    (((class color) (background dark))
-     :inherit transient-key
-     :foreground "#ffffcc"))
-  "Face used for keys of suffixes that return to the parent transient."
-  :group 'transient-faces)
-
-(defface transient-key-exit
-  `((((class color) (background light))
-     :inherit transient-key
-     :foreground "#aa2222")
-    (((class color) (background dark))
-     :inherit transient-key
-     :foreground "#ffdddd"))
-  "Face used for keys of suffixes that exit transient state."
-  :group 'transient-faces)
-
-(defface transient-unreachable-key
-  '((t :inherit (shadow transient-key) :weight normal))
-  "Face used for keys unreachable from the current prefix sequence."
-  :group 'transient-faces)
-
-(defface transient-nonstandard-key
-  `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1)
-              :color "cyan")))
-  "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 :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1)
-              :color "magenta")))
-  "Face optionally used to highlight keys without a short-argument.
-Also see option `transient-highlight-mismatched-keys'."
-  :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 (list file)
-  (make-directory (file-name-directory file) t)
-  (setq list (cl-sort (copy-sequence list) #'string< :key #'car))
-  (with-temp-file file
-    (let ((print-level nil)
-          (print-length nil)
-          (pp-default-function 'pp-28)
-          (fill-column 999))
-      (pp list (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)
-   (init-value  :initarg :init-value)
-   (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)
-   (show-help   :initarg :show-help   :initform nil)
-   (info-manual :initarg :info-manual :initform nil)
-   (man-page    :initarg :man-page    :initform nil)
-   (transient-suffix     :initarg :transient-suffix     :initform nil)
-   (transient-non-suffix :initarg :transient-non-suffix :initform nil)
-   (transient-switch-frame :initarg :transient-switch-frame)
-   (refresh-suffixes     :initarg :refresh-suffixes     :initform nil)
-   (incompatible         :initarg :incompatible         :initform nil)
-   (suffix-description   :initarg :suffix-description)
-   (variable-pitch       :initarg :variable-pitch       :initform nil)
-   (column-widths        :initarg :column-widths        :initform nil)
-   (unwind-suffix        :documentation "Internal use." :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 (symbol-value 'transient--default-child-level)
-    :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.")
-   (inapt
-    :initform nil)
-   (inapt-face
-    :initarg :inapt-face
-    :initform 'transient-inapt-suffix)
-   (inapt-if
-    :initarg :inapt-if
-    :initform nil
-    :documentation "Inapt if predicate returns non-nil.")
-   (inapt-if-not
-    :initarg :inapt-if-not
-    :initform nil
-    :documentation "Inapt if predicate returns nil.")
-   (inapt-if-non-nil
-    :initarg :inapt-if-non-nil
-    :initform nil
-    :documentation "Inapt if variable's value is non-nil.")
-   (inapt-if-nil
-    :initarg :inapt-if-nil
-    :initform nil
-    :documentation "Inapt if variable's value is nil.")
-   (inapt-if-mode
-    :initarg :inapt-if-mode
-    :initform nil
-    :documentation "Inapt if major-mode matches value.")
-   (inapt-if-not-mode
-    :initarg :inapt-if-not-mode
-    :initform nil
-    :documentation "Inapt if major-mode does not match value.")
-   (inapt-if-derived
-    :initarg :inapt-if-derived
-    :initform nil
-    :documentation "Inapt if major-mode derives from value.")
-   (inapt-if-not-derived
-    :initarg :inapt-if-not-derived
-    :initform nil
-    :documentation "Inapt if major-mode does not derive from value."))
-  "Abstract superclass for group 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)
-  ((definition  :allocation :class    :initform nil)
-   (key         :initarg :key)
-   (command     :initarg :command)
-   (transient   :initarg :transient)
-   (format      :initarg :format      :initform " %k %d")
-   (description :initarg :description :initform nil)
-   (face        :initarg :face        :initform nil)
-   (show-help   :initarg :show-help   :initform nil))
-  "Superclass for suffix command.")
-
-(defclass transient-information (transient-suffix)
-  ((format :initform " %k %d")
-   (key    :initform " "))
-  "Display-only information, aligned with suffix keys.
-Technically a suffix object with no associated command.")
-
-(defclass transient-information* (transient-information)
-  ((format :initform " %d"))
-  "Display-only information, aligned with suffix descriptions.
-Technically a suffix object with no associated command.")
-
-(defclass transient-infix (transient-suffix)
-  ((transient                         :initform t)
-   (argument    :initarg :argument)
-   (shortarg    :initarg :shortarg)
-   (value                             :initform nil)
-   (init-value  :initarg :init-value)
-   (unsavable   :initarg :unsavable   :initform nil)
-   (multi-value :initarg :multi-value :initform nil)
-   (always-read :initarg :always-read :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-option) ()
-  ((key         :initform "--")
-   (argument    :initform "--")
-   (multi-value :initform rest)
-   (reader      :initform transient-read-files))
-  "Class used for the \"--\" argument or similar.
-All remaining arguments are treated as files.
-They become the value of this argument.")
-
-(defclass transient-value-preset (transient-suffix)
-  ((transient :initform t)
-   (set :initarg := :initform nil))
-  "Class used by the `transient-preset' suffix command.")
-
-;;;; Group
-
-(defclass transient-group (transient-child)
-  ((suffixes       :initarg :suffixes       :initform nil)
-   (hide           :initarg :hide           :initform nil)
-   (description    :initarg :description    :initform nil)
-   (pad-keys       :initarg :pad-keys       :initform nil)
-   (info-format    :initarg :info-format    :initform nil)
-   (setup-children :initarg :setup-children))
-  "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 strings.  Each subgroup represents a column.
-This class takes care of inserting the subgroups' elements.")
-
-(defclass transient-subgroups (transient-group) ()
-  "Group class that wraps other groups.
-
-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 transient-define-prefix (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]))
-           (indent defun)
-           (doc-string 3))
-  (pcase-let
-      ((`(,class ,slots ,suffixes ,docstr ,body ,interactive-only)
-        (transient--expand-define-args args arglist 'transient-define-prefix)))
-    `(progn
-       (defalias ',name
-         ,(if body
-              `(lambda ,arglist ,@body)
-            `(lambda ()
-               (interactive)
-               (transient-setup ',name))))
-       (put ',name 'interactive-only ,interactive-only)
-       (put ',name 'function-documentation ,docstr)
-       (put ',name 'transient--prefix
-            (,(or class 'transient-prefix) :command ',name ,@slots))
-       (put ',name 'transient--layout
-            (list ,@(cl-mapcan (lambda (s) (transient--parse-child name s))
-                               suffixes))))))
-
-(defmacro transient-define-suffix (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]
-                    [&optional ("interactive" interactive) def-body]))
-           (indent defun)
-           (doc-string 3))
-  (pcase-let
-      ((`(,class ,slots ,_ ,docstr ,body ,interactive-only)
-        (transient--expand-define-args args arglist 'transient-define-suffix)))
-    `(progn
-       (defalias ',name
-         ,(if (and (not body) class (oref-default class definition))
-              `(oref-default ',class definition)
-            `(lambda ,arglist ,@body)))
-       (put ',name 'interactive-only ,interactive-only)
-       (put ',name 'function-documentation ,docstr)
-       (put ',name 'transient--suffix
-            (,(or class 'transient-suffix) :command ',name ,@slots)))))
-
-(defmacro transient-augment-suffix (name &rest args)
-  "Augment existing command NAME with a new transient suffix object.
-Similar to `transient-define-suffix' but define a suffix object only.
-\n\(fn NAME [KEYWORD VALUE]...)"
-  (declare (debug (&define name [&rest keywordp sexp]))
-           (indent defun))
-  (pcase-let
-      ((`(,class ,slots)
-        (transient--expand-define-args args nil 'transient-augment-suffix t)))
-    `(put ',name 'transient--suffix
-          (,(or class 'transient-suffix) :command ',name ,@slots))))
-
-(defmacro transient-define-infix (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.
-
-At least one key-value pair is required.  All transient infix
-commands are equal to each other (but not eq).  It is meaning-
-less to define an infix command, without providing at least one
-keyword argument (usually `:argument' or `:variable', depending
-on the class).  The suffix class defaults to `transient-switch'
-and can be set using the `:class' keyword.
-
-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-define-suffix' to define
-the infix command and use t as the value of the `:transient'
-keyword.
-
-\(fn NAME ARGLIST [DOCSTRING] KEYWORD VALUE [KEYWORD VALUE]...)"
-  (declare (debug ( &define name lambda-list
-                    [&optional lambda-doc]
-                    keywordp sexp
-                    [&rest keywordp sexp]))
-           (indent defun)
-           (doc-string 3))
-  (pcase-let
-      ((`(,class ,slots ,_ ,docstr ,_ ,interactive-only)
-        (transient--expand-define-args args arglist 'transient-define-infix t)))
-    `(progn
-       (defalias ',name #'transient--default-infix-command)
-       (put ',name 'interactive-only ,interactive-only)
-       (put ',name 'completion-predicate #'transient--suffix-only)
-       (put ',name 'function-documentation ,docstr)
-       (put ',name 'transient--suffix
-            (,(or class 'transient-switch) :command ',name ,@slots)))))
-
-(defalias 'transient-define-argument #'transient-define-infix
-  "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 `transient-define-infix' instead.
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)")
-
-(defun transient--default-infix-command ()
-  ;; Most infix commands are but an alias for this command.
-  "Cannot show any documentation for this transient infix command.
-
-When you request help for an infix command using `transient-help', that
-usually shows the respective man-page and tries to jump to the location
-where the respective argument is being described.
-
-If no man-page is specified for the containing transient menu, then the
-docstring is displayed instead, if any.
-
-If the infix command doesn't have a docstring, as is the case here, then
-this docstring is displayed instead, because technically infix commands
-are aliases for `transient--default-infix-command'.
-
-`describe-function' also shows the docstring of the infix command,
-falling back to that of the same aliased command."
-  (interactive)
-  (let ((obj (transient-suffix-object)))
-    (transient-infix-set obj (transient-infix-read obj)))
-  (transient--show))
-(put 'transient--default-infix-command 'interactive-only t)
-(put 'transient--default-infix-command 'completion-predicate
-     #'transient--suffix-only)
-
-(define-advice find-function-advised-original
-    (:around (fn func) transient-default-infix)
-  "Return nil instead of `transient--default-infix-command'.
-When using `find-function' to jump to the definition of a transient
-infix command/argument, then we want to actually jump to that, not to
-the definition of `transient--default-infix-command', which all infix
-commands are aliases for."
-  (let ((val (funcall fn func)))
-    (and val (not (eq val 'transient--default-infix-command)) val)))
-
-(eval-and-compile ;transient--expand-define-args
-  (defun transient--expand-define-args (args &optional arglist form nobody)
-    ;; ARGLIST and FORM are only optional for backward compatibility.
-    ;; This is necessary because "emoji.el" from Emacs 29 calls this
-    ;; function directly, with just one argument.
-    (unless (listp arglist)
-      (error "Mandatory ARGLIST is missing"))
-    (let (class keys suffixes docstr declare (interactive-only t))
-      (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 (let ((arg (car args)))
-               (or (vectorp arg)
-                   (and arg (symbolp arg))))
-        (push (pop args) suffixes))
-      (when (eq (car-safe (car args)) 'declare)
-        (setq declare (car args))
-        (setq args (cdr args))
-        (when-let ((int (assq 'interactive-only declare)))
-          (setq interactive-only (cadr int))
-          (delq int declare))
-        (unless (cdr declare)
-          (setq declare nil)))
-      (cond
-       ((not args))
-       (nobody
-        (error "%s: No function body allowed" form))
-       ((not (eq (car-safe (nth (if declare 1 0) args)) 'interactive))
-        (error "%s: Interactive form missing" form)))
-      (list (if (eq (car-safe class) 'quote)
-                (cadr class)
-              class)
-            (nreverse keys)
-            (nreverse suffixes)
-            docstr
-            (if declare (cons declare args) args)
-            interactive-only))))
-
-(defun transient--parse-child (prefix spec)
-  (cl-typecase spec
-    (null    (error "Invalid transient--parse-child spec: %s" spec))
-    (symbol  (let ((value (symbol-value spec)))
-               (if (and (listp value)
-                        (or (listp (car value))
-                            (vectorp (car value))))
-                   (cl-mapcan (lambda (s) (transient--parse-child prefix s)) value)
-                 (transient--parse-child prefix value))))
-    (vector  (and-let* ((c (transient--parse-group  prefix spec))) (list c)))
-    (list    (and-let* ((c (transient--parse-suffix prefix spec))) (list c)))
-    (string  (list spec))
-    (t       (error "Invalid transient--parse-child spec: %s" 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 ((key pop)
-              (val pop))
-          (cond ((eq key :class)
-                 (setq class (macroexp-quote val)))
-                ((or (symbolp val)
-                     (and (listp val) (not (eq (car val) 'lambda))))
-                 (setq args (plist-put args key (macroexp-quote val))))
-                ((setq args (plist-put args key val))))))
-      (unless (or spec class (not (plist-get args :setup-children)))
-        (message "WARNING: %s: When %s is used, %s must also be specified"
-                 'transient-define-prefix :setup-children :class))
-      (list 'vector
-            (or level transient--default-child-level)
-            (cond (class)
-                  ((or (vectorp car)
-                       (and car (symbolp car)))
-                   (quote 'transient-columns))
-                  ((quote 'transient-column)))
-            (and args (cons 'list args))
-            (cons 'list
-                  (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)))
-      (cond
-       ((or (stringp car)
-            (and (eq (car-safe car) 'lambda)
-                 (not (commandp car))))
-        (setq args (plist-put args :description pop)))
-       ((and (symbolp car)
-             (not (keywordp car))
-             (not (commandp car))
-             (commandp (cadr spec)))
-        (setq args (plist-put args :description (macroexp-quote pop)))))
-      (cond
-       ((memq car '(:info :info*)))
-       ((keywordp car)
-        (error "Need command, `:info' or `:info*', got `%s'" car))
-       ((symbolp car)
-        (setq args (plist-put args :command (macroexp-quote pop))))
-       ((and (commandp car)
-             (not (stringp car)))
-        (let ((cmd pop)
-              (sym (intern
-                    (format "transient:%s:%s"
-                            prefix
-                            (let ((desc (plist-get args :description)))
-                              (if (and (stringp desc)
-                                       (length< desc 16))
-                                  desc
-                                (plist-get args :key)))))))
-          (setq args (plist-put
-                      args :command
-                      `(prog1 ',sym
-                         (put ',sym 'interactive-only t)
-                         (put ',sym 'completion-predicate #'transient--suffix-only)
-                         (defalias ',sym
-                           ,(if (eq (car-safe cmd) 'lambda)
-                                cmd
-                              (macroexp-quote cmd))))))))
-       ((or (stringp car)
-            (and car (listp car)))
-        (let ((arg pop)
-              (sym nil))
-          (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 sym (intern (format "transient:%s:%s" prefix arg)))
-          (setq args (plist-put
-                      args :command
-                      `(prog1 ',sym
-                         (put ',sym 'interactive-only t)
-                         (put ',sym 'completion-predicate #'transient--suffix-only)
-                         (defalias ',sym #'transient--default-infix-command))))
-          (cond ((and car (not (keywordp car)))
-                 (setq class 'transient-option)
-                 (setq args (plist-put args :reader (macroexp-quote pop))))
-                ((not (string-suffix-p "=" arg))
-                 (setq class 'transient-switch))
-                (t
-                 (setq class 'transient-option)))))
-       (t
-        (error "Needed command or argument, got %S" car)))
-      (while (keywordp car)
-        (let ((key pop)
-              (val pop))
-          (cond ((eq key :class) (setq class val))
-                ((eq key :level) (setq level val))
-                ((eq key :info)
-                 (setq class 'transient-information)
-                 (setq args (plist-put args :description val)))
-                ((eq key :info*)
-                 (setq class 'transient-information*)
-                 (setq args (plist-put args :description val)))
-                ((eq (car-safe val) '\,)
-                 (setq args (plist-put args key (cadr val))))
-                ((or (symbolp val)
-                     (and (listp val) (not (eq (car val) 'lambda))))
-                 (setq args (plist-put args key (macroexp-quote val))))
-                ((setq args (plist-put args key val)))))))
-    (unless (plist-get args :key)
-      (when-let ((shortarg (plist-get args :shortarg)))
-        (setq args (plist-put args :key shortarg))))
-    (list 'list
-          (or level transient--default-child-level)
-          (macroexp-quote (or class 'transient-suffix))
-          (cons 'list args))))
-
-(defun transient--derive-shortarg (arg)
-  (save-match-data
-    (and (string-match "\\`\\(-[a-zA-Z]\\)\\(\\'\\|=\\)" arg)
-         (match-string 1 arg))))
-
-(defun transient-command-completion-not-suffix-only-p (symbol _buffer)
-  "Say whether SYMBOL should be offered as a completion.
-If the value of SYMBOL's `completion-predicate' property is
-`transient--suffix-only', then return nil, otherwise return t.
-This is the case when a command should only ever be used as a
-suffix of a transient prefix command (as opposed to bindings
-in regular keymaps or by using `execute-extended-command')."
-  (not (eq (get symbol 'completion-predicate) 'transient--suffix-only)))
-
-(defalias 'transient--suffix-only #'ignore
-  "Ignore ARGUMENTS, do nothing, and return nil.
-Also see `transient-command-completion-not-suffix-only-p'.
-Only use this alias as the value of the `completion-predicate'
-symbol property.")
-
-(when (and (boundp 'read-extended-command-predicate) ; since Emacs 28.1
-           (not read-extended-command-predicate))
-  (setq read-extended-command-predicate
-        #'transient-command-completion-not-suffix-only-p))
-
-(defun transient-parse-suffix (prefix suffix)
-  "Parse SUFFIX, to be added to PREFIX.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
-  the same forms as expected by `transient-define-prefix').
-Intended for use in a group's `:setup-children' function."
-  (cl-assert (and prefix (symbolp prefix)))
-  (eval (car (transient--parse-child prefix suffix)) t))
-
-(defun transient-parse-suffixes (prefix suffixes)
-  "Parse SUFFIXES, to be added to PREFIX.
-PREFIX is a prefix command, a symbol.
-SUFFIXES is a list of suffix command or a group specification
-  (of the same forms as expected by `transient-define-prefix').
-Intended for use in a group's `:setup-children' function."
-  (cl-assert (and prefix (symbolp prefix)))
-  (mapcar (apply-partially #'transient-parse-suffix prefix) suffixes))
-
-;;; Edit
-
-(defun transient--insert-suffix (prefix loc suffix action &optional keep-other)
-  (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)))
-    (setq suf (eval suf t))
-    (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-let* ((bindingp (listp suf))
-                  (key (transient--spec-key suf))
-                  (conflict (car (transient--layout-member key prefix)))
-                  (conflictp
-                   (and (not (and (eq action 'replace)
-                                  (eq conflict elt)))
-                        (or (not keep-other)
-                            (eq (plist-get (nth 2 suf) :command)
-                                (plist-get (nth 2 conflict) :command)))
-                        (equal (transient--suffix-predicate suf)
-                               (transient--suffix-predicate conflict)))))
-        (transient-remove-suffix prefix key))
-      (pcase-exhaustive action
-        ('insert  (setcdr mem (cons elt (cdr mem)))
-                  (setcar mem suf))
-        ('append  (setcdr mem (cons suf (cdr mem))))
-        ('replace (setcar mem suf)))))))
-
-;;;###autoload
-(defun transient-insert-suffix (prefix loc suffix &optional keep-other)
-  "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 `transient-define-prefix').
-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).
-Remove a conflicting binding unless optional KEEP-OTHER is
-  non-nil.
-See info node `(transient)Modifying Existing Transients'."
-  (declare (indent defun))
-  (transient--insert-suffix prefix loc suffix 'insert keep-other))
-
-;;;###autoload
-(defun transient-append-suffix (prefix loc suffix &optional keep-other)
-  "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 `transient-define-prefix').
-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).
-Remove a conflicting binding unless optional KEEP-OTHER is
-  non-nil.
-See info node `(transient)Modifying Existing Transients'."
-  (declare (indent defun))
-  (transient--insert-suffix prefix loc suffix 'append keep-other))
-
-;;;###autoload
-(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 `transient-define-prefix').
-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))
-
-;;;###autoload
-(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 `transient-define-prefix').
-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)
-        ((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)
-  (and-let* ((obj (transient--suffix-prototype cmd)))
-    (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 transient-current-prefix nil
-  "The transient from which this suffix command was invoked.
-This is an object representing that transient, use
-`transient-current-command' to get the respective command.")
-
-(defvar transient-current-command nil
-  "The transient from which this suffix command was invoked.
-This is a symbol representing that transient, use
-`transient-current-prefix' to get the respective object.")
-
-(defvar transient-current-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 transient-exit-hook nil
-  "Hook run after exiting a transient.")
-
-(defvar transient-setup-buffer-hook nil
-  "Hook run when setting up the transient buffer.
-That buffer is current and empty when this hook runs.")
-
-(defvar transient--prefix nil)
-(defvar transient--layout nil)
-(defvar transient--suffixes nil)
-
-(defconst transient--stay t   "Do not exit the transient.")
-(defconst transient--exit nil "Do exit the transient.")
-
-(defvar transient--exitp nil "Whether to exit the transient.")
-(defvar transient--showp nil "Whether to show the transient popup buffer.")
-(defvar transient--helpp nil "Whether help-mode is active.")
-(defvar transient--editp nil "Whether edit-mode is active.")
-
-(defvar transient--refreshp nil
-  "Whether to refresh the transient completely.")
-
-(defvar transient--all-levels-p nil
-  "Whether temporary display of suffixes on all levels is active.")
-
-(defvar transient--timer nil)
-
-(defvar transient--stack nil)
-
-(defvar transient--minibuffer-depth 0)
-
-(defvar transient--buffer-name " *transient*"
-  "Name of the transient buffer.")
-
-(defvar transient--buffer nil
-  "The transient menu buffer.")
-
-(defvar transient--window nil
-  "The window used to display the transient popup buffer.")
-
-(defvar transient--original-window nil
-  "The window that was selected before the transient was invoked.
-Usually it remains selected while the transient is active.")
-
-(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--restore-winconf nil
-  "Window configuration to restore after exiting help.")
-
-(defvar transient--shadowed-buffer nil
-  "The buffer that is temporarily shadowed by the transient buffer.
-This is bound while the suffix predicate is being evaluated and while
-drawing in the transient buffer.")
-
-(defvar transient--pending-suffix nil
-  "The suffix that is currently being processed.
-This is bound while the suffix predicate is being evaluated,
-and while functions that return faces are being evaluated.")
-
-(defvar transient--pending-group nil
-  "The group that is currently being processed.
-This is bound while the suffixes are drawn in the transient buffer.")
-
-(defvar transient--debug nil
-  "Whether to put debug information into *Messages*.")
-
-(defvar transient--history nil)
-
-(defvar transient--scroll-commands
-  '(transient-scroll-up
-    transient-scroll-down
-    mwheel-scroll
-    scroll-bar-toolkit-scroll))
-
-;;; Identities
-
-(defun transient-active-prefix (&optional prefixes)
-  "Return the active transient object.
-
-Return nil if there is no active transient, if the transient buffer
-isn't shown, and while the active transient is suspended (e.g., while
-the minibuffer is in use).
-
-Unlike `transient-current-prefix', which is only ever non-nil in code
-that is run directly by a command that is invoked while a transient
-is current, this function is also suitable for use in asynchronous
-code, such as timers and callbacks (this function's main use-case).
-
-If optional PREFIXES is non-nil, it must be a list of prefix command
-symbols, in which case the active transient object is only returned
-if it matches one of the PREFIXES."
-  (and transient--showp
-       transient--prefix
-       (or (not prefixes)
-           (memq (oref transient--prefix command) prefixes))
-       (or (memq 'transient--pre-command pre-command-hook)
-           (and (memq t pre-command-hook)
-                (memq 'transient--pre-command
-                      (default-value 'pre-command-hook))))
-       transient--prefix))
-
-(defun transient-prefix-object ()
-  "Return the current prefix as an object.
-
-While a transient is being setup or refreshed (which involves
-preparing its suffixes) the variable `transient--prefix' can be
-used to access the prefix object.  Thus this is what has to be
-used in suffix methods such as `transient-format-description',
-and in object-specific functions that are stored in suffix slots
-such as `description'.
-
-When a suffix command is invoked (i.e., in its `interactive' form
-and function body) then the variable `transient-current-prefix'
-has to be used instead.
-
-Two distinct variables are needed, because any prefix may itself
-be used as a suffix of another prefix, and such sub-prefixes have
-to be able to tell themselves apart from the prefix they were
-invoked from.
-
-Regular suffix commands, which are not prefixes, do not have to
-concern themselves with this distinction, so they can use this
-function instead.  In the context of a plain suffix, it always
-returns the value of the appropriate variable."
-  (or transient--prefix transient-current-prefix))
-
-(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, which
-are usually aliases of `transient--default-infix-command', which
-is defined like this:
-
-  (defun transient--default-infix-command ()
-    (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)"
-  (when command
-    (cl-check-type command command))
-  (cond
-   (transient--pending-suffix)
-   ((or transient--prefix
-        transient-current-prefix)
-    (let ((suffixes
-           (cl-remove-if-not
-            (lambda (obj)
-              (eq (oref obj command)
-                  (or command
-                      (if (eq this-command 'transient-set-level)
-                          ;; This is how it can look up for which
-                          ;; command it is setting the level.
-                          this-original-command
-                        this-command))))
-            (or transient--suffixes
-                transient-current-suffixes))))
-      (or (and (cdr suffixes)
-               (cl-find-if
-                (lambda (obj)
-                  (equal (listify-key-sequence (transient--kbd (oref obj key)))
-                         (listify-key-sequence (this-command-keys))))
-                suffixes))
-          (car suffixes))))
-   ((and-let* ((obj (transient--suffix-prototype (or command this-command)))
-               (obj (clone obj)))
-      (progn ; work around debbugs#31840
-        (transient-init-scope obj)
-        (transient-init-value obj)
-        obj)))))
-
-(defun transient--suffix-prototype (command)
-  (or (get command 'transient--suffix)
-      (seq-some (lambda (cmd) (get cmd 'transient--suffix))
-                (function-alias-p command))))
-
-;;; Keymaps
-
-(defvar-keymap transient-base-map
-  :doc "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.
-
-If you add a new command here, then you must also add a binding
-to `transient-predicate-map'."
-  "ESC ESC ESC" #'transient-quit-all
-  "C-g"     #'transient-quit-one
-  "C-q"     #'transient-quit-all
-  "C-z"     #'transient-suspend
-  "C-v"     #'transient-scroll-up
-  "C-M-v"   #'transient-scroll-down
-  "<next>"  #'transient-scroll-up
-  "<prior>" #'transient-scroll-down)
-
-(defvar-keymap transient-map
-  :doc "Top-level keymap used by all transients.
-
-If you add a new command here, then you must also add a binding
-to `transient-predicate-map'.  Also see `transient-base-map'."
-  :parent transient-base-map
-  "C-u"   #'universal-argument
-  "C--"   #'negative-argument
-  "C-t"   #'transient-show
-  "?"     #'transient-help
-  "C-h"   #'transient-help
-  ;; Also bound to "C-x p" and "C-x n" in transient-common-commands.
-  "C-M-p" #'transient-history-prev
-  "C-M-n" #'transient-history-next)
-
-(defvar-keymap transient-edit-map
-  :doc "Keymap that is active while a transient in is in \"edit mode\"."
-  :parent transient-base-map
-  "?"     #'transient-help
-  "C-h"   #'transient-help
-  "C-x l" #'transient-set-level)
-
-(defvar-keymap transient-sticky-map
-  :doc "Keymap that is active while an incomplete key sequence is active."
-  :parent transient-base-map
-  "C-g" #'transient-quit-seq)
-
-(defvar transient--common-command-prefixes '(?\C-x))
-
-(put 'transient-common-commands
-     'transient--layout
-     (list
-      (eval
-       (car (transient--parse-child
-             'transient-common-commands
-             (vector
-              :hide
-              (lambda ()
-                (and (not (memq
-                           (car (bound-and-true-p transient--redisplay-key))
-                           transient--common-command-prefixes))
-                     (not transient-show-common-commands)))
-              (vector
-               "Value commands"
-               (list "C-x s  " "Set"            #'transient-set)
-               (list "C-x C-s" "Save"           #'transient-save)
-               (list "C-x C-k" "Reset"          #'transient-reset)
-               (list "C-x p  " "Previous value" #'transient-history-prev)
-               (list "C-x n  " "Next value"     #'transient-history-next))
-              (vector
-               "Sticky commands"
-               ;; Like `transient-sticky-map' except that
-               ;; "C-g" has to be bound to a different command.
-               (list "C-g" "Quit prefix or transient" #'transient-quit-one)
-               (list "C-q" "Quit transient stack"     #'transient-quit-all)
-               (list "C-z" "Suspend transient stack"  #'transient-suspend))
-              (vector
-               "Customize"
-               (list "C-x t" 'transient-toggle-common :description
-                     (lambda ()
-                       (if transient-show-common-commands
-                           "Hide common commands"
-                         "Show common permanently")))
-               (list "C-x l" "Show/hide suffixes" #'transient-set-level)
-               (list "C-x a" #'transient-toggle-level-limit)))))
-       t)))
-
-(defvar-keymap transient-popup-navigation-map
-  :doc "One of the keymaps used when popup navigation is enabled.
-See `transient-enable-popup-navigation'."
-  "<down-mouse-1>" #'transient-noop
-  "<up>"   #'transient-backward-button
-  "<down>" #'transient-forward-button
-  "C-r"    #'transient-isearch-backward
-  "C-s"    #'transient-isearch-forward
-  "M-RET"  #'transient-push-button)
-
-(defvar-keymap transient-button-map
-  :doc "One of the keymaps used when popup navigation is enabled.
-See `transient-enable-popup-navigation'."
-  "<mouse-1>" #'transient-push-button
-  "<mouse-2>" #'transient-push-button)
-
-(defvar-keymap transient-resume-mode-map
-  :doc "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."
-  "<remap> <Man-quit>"    #'transient-resume
-  "<remap> <Info-exit>"   #'transient-resume
-  "<remap> <quit-window>" #'transient-resume)
-
-(defvar-keymap transient-predicate-map
-  :doc "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."
-  "<transient-suspend>"           #'transient--do-suspend
-  "<transient-help>"              #'transient--do-stay
-  "<transient-set-level>"         #'transient--do-stay
-  "<transient-history-prev>"      #'transient--do-stay
-  "<transient-history-next>"      #'transient--do-stay
-  "<universal-argument>"          #'transient--do-stay
-  "<universal-argument-more>"     #'transient--do-stay
-  "<negative-argument>"           #'transient--do-minus
-  "<digit-argument>"              #'transient--do-stay
-  "<top-level>"                   #'transient--do-quit-all
-  "<transient-quit-all>"          #'transient--do-quit-all
-  "<transient-quit-one>"          #'transient--do-quit-one
-  "<transient-quit-seq>"          #'transient--do-stay
-  "<transient-show>"              #'transient--do-stay
-  "<transient-update>"            #'transient--do-stay
-  "<transient-toggle-common>"     #'transient--do-stay
-  "<transient-set>"               #'transient--do-call
-  "<transient-set-and-exit>"      #'transient--do-exit
-  "<transient-save>"              #'transient--do-call
-  "<transient-save-and-exit>"     #'transient--do-exit
-  "<transient-reset>"             #'transient--do-call
-  "<describe-key-briefly>"        #'transient--do-stay
-  "<describe-key>"                #'transient--do-stay
-  "<transient-scroll-up>"         #'transient--do-stay
-  "<transient-scroll-down>"       #'transient--do-stay
-  "<mwheel-scroll>"               #'transient--do-stay
-  "<scroll-bar-toolkit-scroll>"   #'transient--do-stay
-  "<transient-noop>"              #'transient--do-noop
-  "<transient-mouse-push-button>" #'transient--do-move
-  "<transient-push-button>"       #'transient--do-push-button
-  "<transient-backward-button>"   #'transient--do-move
-  "<transient-forward-button>"    #'transient--do-move
-  "<transient-isearch-backward>"  #'transient--do-move
-  "<transient-isearch-forward>"   #'transient--do-move
-  ;; If a valid but incomplete prefix sequence is followed by
-  ;; an unbound key, then Emacs calls the `undefined' command
-  ;; but does not set `this-command', `this-original-command'
-  ;; or `real-this-command' accordingly.  Instead they are nil.
-  "<nil>"                         #'transient--do-warn
-  ;; Bound to the `mouse-movement' event, this command is similar
-  ;; to `ignore'.
-  "<ignore-preserving-kill-region>" #'transient--do-noop)
-
-(defvar transient--transient-map nil)
-(defvar transient--predicate-map nil)
-(defvar transient--redisplay-map nil)
-(defvar transient--redisplay-key nil)
-
-(defun transient--push-keymap (var)
-  (let ((map (symbol-value var)))
-    (transient--debug "     push %s%s" var (if map "" " VOID"))
-    (when map
-      (with-demoted-errors "transient--push-keymap: %S"
-        (internal-push-keymap map 'overriding-terminal-local-map)))))
-
-(defun transient--pop-keymap (var)
-  (let ((map (symbol-value var)))
-    (when map
-      (transient--debug "     pop  %s" var)
-      (with-demoted-errors "transient--pop-keymap: %S"
-        (internal-pop-keymap 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 (oref obj command))
-               (alt (transient--lookup-key map kbd)))
-          (cond ((not alt)
-                 (define-key map kbd cmd))
-                ((eq alt cmd))
-                ((transient--inapt-suffix-p obj))
-                ((and-let* ((obj (transient-suffix-object alt)))
-                   (transient--inapt-suffix-p obj))
-                 (define-key map kbd cmd))
-                (transient-detect-key-conflicts
-                 (error "Cannot bind %S to %s and also %s"
-                        (string-trim key) cmd alt))
-                ((define-key map kbd cmd))))))
-    (when-let ((b (keymap-lookup map "-"))) (keymap-set map "<kp-subtract>" b))
-    (when-let ((b (keymap-lookup map "="))) (keymap-set map "<kp-equal>" b))
-    (when-let ((b (keymap-lookup map "+"))) (keymap-set map "<kp-add>" b))
-    (when transient-enable-popup-navigation
-      ;; `transient--make-redisplay-map' maps only over bindings that are
-      ;; directly in the base keymap, so that cannot be a composed keymap.
-      (set-keymap-parent
-       map (make-composed-keymap
-            (keymap-parent map)
-            transient-popup-navigation-map)))
-    map))
-
-(defun transient--make-predicate-map ()
-  (let* ((default (transient--resolve-pre-command
-                   (oref transient--prefix transient-suffix)))
-         (return (and transient--stack (eq default t)))
-         (map (make-sparse-keymap)))
-    (set-keymap-parent map transient-predicate-map)
-    (when (or (and (slot-boundp transient--prefix 'transient-switch-frame)
-                   (transient--resolve-pre-command
-                    (not (oref transient--prefix transient-switch-frame))))
-              (memq (transient--resolve-pre-command
-                     (oref transient--prefix transient-non-suffix))
-                    '(nil transient--do-warn transient--do-noop)))
-      (define-key map [handle-switch-frame] #'transient--do-suspend))
-    (dolist (obj transient--suffixes)
-      (let* ((cmd (oref obj command))
-             (kind (cond ((get cmd 'transient--prefix)    'prefix)
-                         ((cl-typep obj 'transient-infix) 'infix)
-                         (t                               'suffix))))
-        (cond
-         ((oref obj inapt)
-          (define-key map (vector cmd) #'transient--do-warn-inapt))
-         ((slot-boundp obj 'transient)
-          (define-key map (vector cmd)
-            (pcase (list kind
-                         (transient--resolve-pre-command (oref obj transient))
-                         return)
-              (`(prefix   t ,_) #'transient--do-recurse)
-              (`(prefix nil ,_) #'transient--do-stack)
-              (`(infix    t ,_) #'transient--do-stay)
-              (`(suffix   t ,_) #'transient--do-call)
-              ('(suffix nil  t) #'transient--do-return)
-              (`(,_     nil ,_) #'transient--do-exit)
-              (`(,_     ,do ,_) do))))
-         ((not (lookup-key transient-predicate-map (vector cmd)))
-          (define-key map (vector cmd)
-            (pcase (list kind default return)
-              (`(prefix ,(or 'transient--do-stay 'transient--do-call) ,_)
-               #'transient--do-recurse)
-              (`(prefix   t ,_) #'transient--do-recurse)
-              (`(prefix  ,_ ,_) #'transient--do-stack)
-              (`(infix   ,_ ,_) #'transient--do-stay)
-              (`(suffix   t ,_) #'transient--do-call)
-              ('(suffix nil  t) #'transient--do-return)
-              (`(suffix nil ,_) #'transient--do-exit)
-              (`(suffix ,do ,_) do)))))))
-    map))
-
-(defun transient--make-redisplay-map ()
-  (setq transient--redisplay-key
-        (pcase 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))
-          (_ 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
-         (let ((key (vconcat transient--redisplay-key)))
-           (or (lookup-key transient--transient-map key)
-               (and-let* ((regular (lookup-key local-function-key-map key)))
-                 (lookup-key transient--transient-map (vconcat regular)))))
-       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)
-  (transient--with-emergency-exit :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))))
-     (transient--prefix
-      ;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}"
-      ;; of an outer prefix.  Unlike the usual `transient--do-stack',
-      ;; these predicates fail to clean up after the outer prefix.
-      (transient--pop-keymap 'transient--transient-map)
-      (transient--pop-keymap 'transient--redisplay-map))
-     ((not (or layout                      ; resuming parent/suspended prefix
-               transient-current-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--init-keymaps)
-    (transient--history-init transient--prefix)
-    (setq transient--original-window (selected-window))
-    (setq transient--original-buffer (current-buffer))
-    (setq transient--minibuffer-depth (minibuffer-depth))
-    (transient--redisplay)
-    (transient--init-transient)
-    (transient--suspend-which-key-mode)))
-
-(cl-defgeneric transient-setup-children (group children)
-  "Setup the CHILDREN of GROUP.
-If the value of the `setup-children' slot is non-nil, then call
-that function with CHILDREN as the only argument and return the
-value.  Otherwise return CHILDREN as is."
-  (if (slot-boundp group 'setup-children)
-      (funcall (oref group setup-children) children)
-    children))
-
-(defun transient--init-keymaps ()
-  (setq transient--predicate-map (transient--make-predicate-map))
-  (setq transient--transient-map (transient--make-transient-map))
-  (setq transient--redisplay-map (transient--make-redisplay-map)))
-
-(defun transient--init-objects (&optional name layout params)
-  (if name
-      (setq transient--prefix (transient--init-prefix name params))
-    (setq name (oref transient--prefix command)))
-  (setq transient--refreshp (oref transient--prefix refresh-suffixes))
-  (setq transient--layout (or layout (transient--init-suffixes name)))
-  (setq transient--suffixes (transient--flatten-suffixes transient--layout)))
-
-(defun transient--init-prefix (name &optional params)
-  (let ((obj (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--setup-recursion obj)
-    (transient-init-value obj)
-    obj))
-
-(defun transient--init-suffixes (name)
-  (let ((levels (alist-get name transient-levels)))
-    (cl-mapcan (lambda (c) (transient--init-child levels c nil))
-               (append (get name 'transient--layout)
-                       (and (not transient--editp)
-                            (get 'transient-common-commands
-                                 'transient--layout))))))
-
-(defun transient--flatten-suffixes (layout)
-  (cl-labels ((s (def)
-                (cond
-                 ((stringp def) nil)
-                 ((cl-typep def 'transient-information) nil)
-                 ((listp def) (cl-mapcan #'s def))
-                 ((cl-typep def 'transient-group)
-                  (cl-mapcan #'s (oref def suffixes)))
-                 ((cl-typep def 'transient-suffix)
-                  (list def)))))
-    (cl-mapcan #'s layout)))
-
-(defun transient--init-child (levels spec parent)
-  (cl-etypecase spec
-    (vector  (transient--init-group  levels spec parent))
-    (list    (transient--init-suffix levels spec parent))
-    (string  (list spec))))
-
-(defun transient--init-group (levels spec parent)
-  (pcase-let ((`(,level ,class ,args ,children) (append spec nil)))
-    (and-let* (((transient--use-level-p level))
-               (obj (apply class :level level args))
-               ((transient--use-suffix-p obj))
-               ((prog1 t
-                  (when (or (and parent (oref parent inapt))
-                            (transient--inapt-suffix-p obj))
-                    (oset obj inapt t))))
-               (suffixes (cl-mapcan
-                          (lambda (c) (transient--init-child levels c obj))
-                          (transient-setup-children obj children))))
-      (progn ; work around debbugs#31840
-        (oset obj suffixes suffixes)
-        (list obj)))))
-
-(defun transient--init-suffix (levels spec parent)
-  (pcase-let* ((`(,level ,class ,args) spec)
-               (cmd (plist-get args :command))
-               (key (transient--kbd (plist-get args :key)))
-               (level (or (alist-get (cons cmd key) levels nil nil #'equal)
-                          (alist-get 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 (child-of-class-p class 'transient-information)
-                     (apply class :level level args)
-                   (unless (and cmd (symbolp cmd))
-                     (error "BUG: Non-symbolic suffix command: %s" cmd))
-                   (if-let ((proto (and cmd (transient--suffix-prototype cmd))))
-                       (apply #'clone proto :level level args)
-                     (apply class :command cmd :level level args)))))
-        (cond ((not cmd))
-              ((commandp cmd))
-              ((or (cl-typep obj 'transient-switch)
-                   (cl-typep obj 'transient-option))
-               ;; As a temporary special case, if the package was compiled
-               ;; with an older version of Transient, then we must define
-               ;; "anonymous" switch and option commands here.
-               (defalias cmd #'transient--default-infix-command))
-              ((transient--use-suffix-p obj)
-               (error "Suffix command %s is not defined or autoloaded" cmd)))
-        (unless (cl-typep obj 'transient-information)
-          (transient--init-suffix-key obj))
-        (when (transient--use-suffix-p obj)
-          (if (or (and parent (oref parent inapt))
-                  (transient--inapt-suffix-p obj))
-              (oset obj inapt t)
-            (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 transient--all-levels-p
-      (and transient--editp (not edit))
-      (and (>= level 1)
-           (<= level (oref transient--prefix level)))))
-
-(defun transient--use-suffix-p (obj)
-  (let ((transient--shadowed-buffer (current-buffer))
-        (transient--pending-suffix obj))
-    (transient--do-suffix-p
-     (oref obj if)
-     (oref obj if-not)
-     (oref obj if-nil)
-     (oref obj if-non-nil)
-     (oref obj if-mode)
-     (oref obj if-not-mode)
-     (oref obj if-derived)
-     (oref obj if-not-derived)
-     t)))
-
-(defun transient--inapt-suffix-p (obj)
-  (let ((transient--shadowed-buffer (current-buffer))
-        (transient--pending-suffix obj))
-    (transient--do-suffix-p
-     (oref obj inapt-if)
-     (oref obj inapt-if-not)
-     (oref obj inapt-if-nil)
-     (oref obj inapt-if-non-nil)
-     (oref obj inapt-if-mode)
-     (oref obj inapt-if-not-mode)
-     (oref obj inapt-if-derived)
-     (oref obj inapt-if-not-derived)
-     nil)))
-
-(defun transient--do-suffix-p
-    (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived
-        default)
-  (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 (or (atom if-derived)
-                                (>= emacs-major-version 30))
-                            (derived-mode-p if-derived)
-                          (apply #'derived-mode-p if-derived)))
-   (if-not-derived (not (if (or (atom if-not-derived)
-                                (>= emacs-major-version 30))
-                            (derived-mode-p if-not-derived)
-                          (apply #'derived-mode-p if-not-derived))))
-   (default)))
-
-(defun transient--suffix-predicate (spec)
-  (let ((plist (nth 2 spec)))
-    (seq-some (lambda (prop)
-                (and-let* ((pred (plist-get plist prop)))
-                  (list prop pred)))
-              '( :if :if-not
-                 :if-nil :if-non-nil
-                 :if-mode :if-not-mode
-                 :if-derived :if-not-derived
-                 :inapt-if :inapt-if-not
-                 :inapt-if-nil :inapt-if-non-nil
-                 :inapt-if-mode :inapt-if-not-mode
-                 :inapt-if-derived :inapt-if-not-derived))))
-
-;;; 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 'post-command-hook #'transient--post-command)
-  (advice-add 'recursive-edit :around #'transient--recursive-edit)
-  (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--refresh-transient ()
-  (transient--debug 'refresh-transient)
-  (transient--pop-keymap 'transient--predicate-map)
-  (transient--pop-keymap 'transient--transient-map)
-  (transient--pop-keymap 'transient--redisplay-map)
-  (if (eq transient--refreshp 'updated-value)
-      ;; Preserve the prefix value this once, because the
-      ;; invoked suffix indicates that it has updated that.
-      (setq transient--refreshp (oref transient--prefix refresh-suffixes))
-    ;; Otherwise update the prefix value from suffix values.
-    (oset transient--prefix value (transient-get-value)))
-  (transient--init-objects)
-  (transient--init-keymaps)
-  (transient--push-keymap 'transient--transient-map)
-  (transient--push-keymap 'transient--redisplay-map)
-  (transient--redisplay))
-
-(defun transient--pre-command ()
-  (transient--debug 'pre-command)
-  (transient--with-emergency-exit :pre-command
-    ;; The use of `overriding-terminal-local-map' does not prevent the
-    ;; lookup of command remappings in the overridden maps, which can
-    ;; lead to a suffix being remapped to a non-suffix.  We have to undo
-    ;; the remapping in that case.  However, remapping a non-suffix to
-    ;; another should remain possible.
-    (when (and (transient--get-pre-command this-original-command 'suffix)
-               (not (transient--get-pre-command this-command 'suffix)))
-      (setq this-command this-original-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)
-      (transient--wrap-command))
-     (t
-      (setq transient--exitp nil)
-      (let ((exitp (eq (transient--call-pre-command) transient--exit)))
-        (transient--wrap-command)
-        (when exitp
-          (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)
-  (unless transient--showp
-    (let ((message-log-max nil))
-      (message "")))
-  (setq transient--transient-map nil)
-  (setq transient--predicate-map nil)
-  (setq transient--redisplay-map nil)
-  (setq transient--redisplay-key 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 ((remain-in-minibuffer-window
-           (and (minibuffer-selected-window)
-                (selected-window))))
-      ;; Only delete the window if it has never shown another buffer.
-      (unless (eq (car (window-parameter transient--window 'quit-restore))
-                  'other)
-        (with-demoted-errors "Error while exiting transient: %S"
-          (delete-window transient--window)))
-      (when (buffer-live-p transient--buffer)
-        (kill-buffer transient--buffer))
-      (setq transient--buffer nil)
-      (when remain-in-minibuffer-window
-        (select-window remain-in-minibuffer-window)))))
-
-(defun transient--export ()
-  (setq transient-current-prefix transient--prefix)
-  (setq transient-current-command (oref transient--prefix command))
-  (setq transient-current-suffixes transient--suffixes)
-  (transient--history-push transient--prefix))
-
-(defun transient--suspend-override (&optional nohide)
-  (transient--debug 'suspend-override)
-  (transient--timer-cancel)
-  (cond ((and (not nohide) transient-hide-during-minibuffer-read)
-         (transient--delete-window))
-        ((and transient--prefix transient--redisplay-key)
-         (setq transient--redisplay-key nil)
-         (when transient--showp
-           (if-let ((win (minibuffer-selected-window)))
-               (with-selected-window win
-                 (transient--show))
-             (transient--show)))))
-  (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--resume-override (&optional _ignore)
-  (transient--debug 'resume-override)
-  (when (and transient--showp transient-hide-during-minibuffer-read)
-    (transient--show))
-  (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--recursive-edit (fn)
-  (transient--debug 'recursive-edit)
-  (if (not transient--prefix)
-      (funcall fn)
-    (transient--suspend-override (bound-and-true-p edebug-active))
-    (funcall fn) ; Already unwind protected.
-    (cond ((memq this-command '(top-level abort-recursive-edit))
-           (setq transient--exitp t)
-           (transient--post-exit)
-           (transient--delete-window))
-          (transient--prefix
-           (transient--resume-override)))))
-
-(defmacro transient--with-suspended-override (&rest body)
-  (let ((depth (make-symbol "depth"))
-        (setup (make-symbol "setup"))
-        (exit  (make-symbol "exit")))
-    `(if (and transient--transient-map
-              (memq transient--transient-map
-                    overriding-terminal-local-map))
-         (let ((,depth (1+ (minibuffer-depth))) ,setup ,exit)
-           (setq ,setup
-                 (lambda () "@transient--with-suspended-override"
-                   (transient--debug 'minibuffer-setup)
-                   (remove-hook 'minibuffer-setup-hook ,setup)
-                   (transient--suspend-override)))
-           (setq ,exit
-                 (lambda () "@transient--with-suspended-override"
-                   (transient--debug 'minibuffer-exit)
-                   (when (= (minibuffer-depth) ,depth)
-                     (transient--resume-override))))
-           (unwind-protect
-               (progn
-                 (add-hook 'minibuffer-setup-hook ,setup)
-                 (add-hook 'minibuffer-exit-hook ,exit)
-                 ,@body)
-             (remove-hook 'minibuffer-setup-hook ,setup)
-             (remove-hook 'minibuffer-exit-hook ,exit)))
-       ,@body)))
-
-(static-if (>= emacs-major-version 30) ;transient--wrap-command
-    (defun transient--wrap-command ()
-      (cl-assert
-       (>= emacs-major-version 30) nil
-       "Emacs was downgraded, making it necessary to recompile Transient")
-      (letrec
-          ((prefix transient--prefix)
-           (suffix this-command)
-           (advice
-            (lambda (fn &rest args)
-              (interactive
-               (lambda (spec)
-                 (let ((abort t))
-                   (unwind-protect
-                       (prog1 (let ((debugger #'transient--exit-and-debug))
-                                (advice-eval-interactive-spec spec))
-                         (setq abort nil))
-                     (when abort
-                       (when-let ((unwind (oref prefix unwind-suffix)))
-                         (transient--debug 'unwind-interactive)
-                         (funcall unwind suffix))
-                       (advice-remove suffix advice)
-                       (oset prefix unwind-suffix nil))))))
-              (unwind-protect
-                  (let ((debugger #'transient--exit-and-debug))
-                    (apply fn args))
-                (when-let ((unwind (oref prefix unwind-suffix)))
-                  (transient--debug 'unwind-command)
-                  (funcall unwind suffix))
-                (advice-remove suffix advice)
-                (oset prefix unwind-suffix nil)))))
-        (when (symbolp this-command)
-          (advice-add suffix :around advice '((depth . -99))))))
-
-  (defun transient--wrap-command ()
-    (let* ((prefix transient--prefix)
-           (suffix this-command)
-           (advice nil)
-           (advice-interactive
-            (lambda (spec)
-              (let ((abort t))
-                (unwind-protect
-                    (prog1 (let ((debugger #'transient--exit-and-debug))
-                             (advice-eval-interactive-spec spec))
-                      (setq abort nil))
-                  (when abort
-                    (when-let ((unwind (oref prefix unwind-suffix)))
-                      (transient--debug 'unwind-interactive)
-                      (funcall unwind suffix))
-                    (advice-remove suffix advice)
-                    (oset prefix unwind-suffix nil))))))
-           (advice-body
-            (lambda (fn &rest args)
-              (unwind-protect
-                  (let ((debugger #'transient--exit-and-debug))
-                    (apply fn args))
-                (when-let ((unwind (oref prefix unwind-suffix)))
-                  (transient--debug 'unwind-command)
-                  (funcall unwind suffix))
-                (advice-remove suffix advice)
-                (oset prefix unwind-suffix nil)))))
-      (setq advice `(lambda (fn &rest args)
-                      (interactive ,advice-interactive)
-                      (apply ',advice-body fn args)))
-      (when (symbolp this-command)
-        (advice-add suffix :around advice '((depth . -99)))))))
-
-(defun transient--premature-post-command ()
-  (and (equal (this-command-keys-vector) [])
-       (= (minibuffer-depth)
-          (1+ transient--minibuffer-depth))
-       (progn
-         (transient--debug 'premature-post-command)
-         (transient--suspend-override)
-         (oset (or transient--prefix transient-current-prefix)
-               unwind-suffix
-               (if transient--exitp
-                   #'transient--post-exit
-                 #'transient--resume-override))
-         t)))
-
-(defun transient--post-command ()
-  (unless (transient--premature-post-command)
-    (transient--debug 'post-command)
-    (transient--with-emergency-exit :post-command
-      (cond (transient--exitp (transient--post-exit))
-            ;; If `this-command' is the current transient prefix, then we
-            ;; have already taken care of updating the transient buffer...
-            ((and (eq this-command (oref transient--prefix command))
-                  ;; ... but if `prefix-arg' is non-nil, then the values
-                  ;; of `this-command' and `real-this-command' are untrue
-                  ;; because `prefix-command-preserve-state' changes them.
-                  ;; We cannot use `current-prefix-arg' because it is set
-                  ;; too late (in `command-execute'), and if it were set
-                  ;; earlier, then we likely still would not be able to
-                  ;; rely on it, and `prefix-command-preserve-state-hook'
-                  ;; would have to be used to record that a universal
-                  ;; argument is in effect.
-                  (not prefix-arg)))
-            (transient--refreshp
-             (transient--refresh-transient))
-            ((let ((old transient--redisplay-map)
-                   (new (transient--make-redisplay-map)))
-               (unless (equal old new)
-                 (transient--pop-keymap 'transient--redisplay-map)
-                 (setq transient--redisplay-map new)
-                 (transient--push-keymap 'transient--redisplay-map))
-               (transient--redisplay)))))
-    (setq transient-current-prefix nil)
-    (setq transient-current-command nil)
-    (setq transient-current-suffixes nil)))
-
-(defun transient--post-exit (&optional command)
-  (transient--debug 'post-exit)
-  (unless (and (eq transient--exitp 'replace)
-               (or transient--prefix
-                   ;; The current command could act as a prefix,
-                   ;; but decided not to call `transient-setup',
-                   ;; or it is prevented from doing so because it
-                   ;; uses the minibuffer and the user aborted
-                   ;; that.
-                   (prog1 nil
-                     (if (let ((obj (transient-suffix-object command)))
-                           (and (slot-boundp obj 'transient)
-                                (oref obj transient)))
-                         ;; This sub-prefix is a transient suffix;
-                         ;; go back to outer prefix, by calling
-                         ;; `transient--stack-pop' further down.
-                         (setq transient--exitp nil)
-                       (transient--stack-zap)))))
-    (remove-hook 'pre-command-hook  #'transient--pre-command)
-    (remove-hook 'post-command-hook #'transient--post-command)
-    (advice-remove 'recursive-edit #'transient--recursive-edit))
-  (let ((resume (and transient--stack
-                     (not (memq transient--exitp '(replace suspend))))))
-    (unless (or resume (eq transient--exitp 'replace))
-      (setq transient--showp nil))
-    (setq transient--exitp nil)
-    (setq transient--helpp nil)
-    (setq transient--editp nil)
-    (setq transient--all-levels-p nil)
-    (setq transient--minibuffer-depth 0)
-    (run-hooks 'transient-exit-hook)
-    (when resume
-      (transient--stack-pop))))
-
-(defun transient--stack-push ()
-  (transient--debug 'stack-push)
-  (push (list (oref transient--prefix command)
-              transient--layout
-              transient--editp
-              :transient-suffix (oref transient--prefix transient-suffix)
-              :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
-          (or (memq this-command transient--scroll-commands)
-              (and (or (memq this-command '(mouse-drag-region
-                                            mouse-set-region))
-                       (equal (key-description (this-command-keys-vector))
-                              "<mouse-movement>"))
-                   (and (eq (current-buffer) transient--buffer))))
-        (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
-    (let ((inhibit-message (not (eq transient--debug 'message))))
-      (if (symbolp arg)
-          (message "-- %-22s (cmd: %s, event: %S, exit: %s%s)"
-                   arg
-                   (cond ((and (symbolp this-command) this-command))
-                         ((fboundp 'help-fns-function-name)
-                          (help-fns-function-name this-command))
-                         ((byte-code-function-p this-command)
-                          "#[...]")
-                         (this-command))
-                   (key-description (this-command-keys-vector))
-                   transient--exitp
-                   (cond ((keywordp (car args))
-                          (format ", from: %s"
-                                  (substring (symbol-name (car args)) 1)))
-                         ((stringp (car args))
-                          (concat ", " (apply #'format args)))
-                         ((functionp (car args))
-                          (concat ", " (apply (car args) (cdr args))))
-                         ("")))
-        (apply #'message arg args)))))
-
-(defun transient--emergency-exit (&optional id)
-  "Exit the current transient command after an error occurred.
-When no transient is active (i.e., when `transient--prefix' is
-nil) then do nothing.  Optional ID is a keyword identifying the
-exit."
-  (transient--debug 'emergency-exit id)
-  (when transient--prefix
-    (setq transient--stack nil)
-    (setq transient--exitp t)
-    (transient--pre-exit)
-    (transient--post-exit)))
-
-;;; Pre-Commands
-
-(defun transient--call-pre-command ()
-  (if-let ((fn (transient--get-pre-command this-command)))
-      (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))
-
-(defun transient--get-pre-command (&optional cmd enforce-type)
-  (or (and (not (eq enforce-type 'non-suffix))
-           (symbolp cmd)
-           (lookup-key transient--predicate-map (vector cmd)))
-      (and (not (eq enforce-type 'suffix))
-           (transient--resolve-pre-command
-            (oref transient--prefix transient-non-suffix)
-            t))))
-
-(defun transient--resolve-pre-command (pre &optional resolve-boolean)
-  (cond ((booleanp pre)
-         (if resolve-boolean
-             (if pre #'transient--do-stay #'transient--do-warn)
-           pre))
-        ((string-match-p "--do-" (symbol-name pre)) pre)
-        ((let ((sym (intern (format "transient--do-%s" pre))))
-           (if (functionp sym) sym pre)))))
-
-(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-warn-inapt ()
-  "Call `transient-inapt' and stay transient."
-  (setq this-command 'transient-inapt)
-  transient--stay)
-
-(defun transient--do-call ()
-  "Call the command after exporting variables and stay transient."
-  (transient--export)
-  transient--stay)
-
-(defun transient--do-return ()
-  "Call the command after exporting variables and return to parent prefix.
-If there is no parent prefix, then behave like `transient--do-exit'."
-  (if (not transient--stack)
-      (transient--do-exit)
-    (transient--export)
-    transient--exit))
-
-(defun transient--do-exit ()
-  "Call the command after exporting variables and exit the transient."
-  (transient--export)
-  (transient--stack-zap)
-  transient--exit)
-
-(defun transient--do-leave ()
-  "Call the command without exporting variables and exit the transient."
-  (transient--stack-zap)
-  transient--exit)
-
-(defun transient--do-push-button ()
-  "Call the command represented by the activated button.
-Use that command's pre-command to determine transient behavior."
-  (if (and (mouse-event-p last-command-event)
-           (not (eq (posn-window (event-start last-command-event))
-                    transient--window)))
-      transient--stay
-    (setq this-command
-          (with-selected-window transient--window
-            (get-text-property (if (mouse-event-p last-command-event)
-                                   (posn-point (event-start last-command-event))
-                                 (point))
-                               'command)))
-    (transient--call-pre-command)))
-
-(defun transient--do-recurse ()
-  "Call the transient prefix command, preparing for return to active transient.
-If there is no parent prefix, then just call the command."
-  (transient--do-stack))
-
-(defun transient--setup-recursion (prefix-obj)
-  (when transient--stack
-    (let ((command (oref prefix-obj command)))
-      (when-let ((suffix-obj (transient-suffix-object command)))
-        (when (memq (if (slot-boundp suffix-obj 'transient)
-                        (oref suffix-obj transient)
-                      (oref transient-current-prefix transient-suffix))
-                    (list t #'transient--do-recurse))
-          (oset prefix-obj transient-suffix t))))))
-
-(defun transient--do-stack ()
-  "Call the transient prefix command, stacking the active transient.
-Push the active transient to the transient stack."
-  (transient--export)
-  (transient--stack-push)
-  (setq transient--exitp 'replace)
-  transient--exit)
-
-(defun transient--do-replace ()
-  "Call the transient prefix command, replacing the active transient.
-Do not push the active transient to the transient stack."
-  (transient--export)
-  (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)
-        (prefix-arg
-         transient--stay)
-        (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-inhibit-move))
-  transient--stay)
-
-(defun transient--do-minus ()
-  "Call `negative-argument' or pivot to `transient-update'.
-If `negative-argument' is invoked using \"-\" then preserve the
-prefix argument and pivot to `transient-update'."
-  (when (equal (this-command-keys) "-")
-    (setq this-command 'transient-update))
-  transient--stay)
-
-(put 'transient--do-stay       'transient-face 'transient-key-stay)
-(put 'transient--do-noop       'transient-face 'transient-key-noop)
-(put 'transient--do-warn       'transient-face 'transient-key-noop)
-(put 'transient--do-warn-inapt 'transient-face 'transient-key-noop)
-(put 'transient--do-call       'transient-face 'transient-key-stay)
-(put 'transient--do-return     'transient-face 'transient-key-return)
-(put 'transient--do-exit       'transient-face 'transient-key-exit)
-(put 'transient--do-leave      'transient-face 'transient-key-exit)
-
-(put 'transient--do-recurse    'transient-face 'transient-key-stay)
-(put 'transient--do-stack      'transient-face 'transient-key-stay)
-(put 'transient--do-replace    'transient-face 'transient-key-exit)
-(put 'transient--do-suspend    'transient-face 'transient-key-exit)
-
-(put 'transient--do-quit-one   'transient-face 'transient-key-return)
-(put 'transient--do-quit-all   'transient-face 'transient-key-exit)
-(put 'transient--do-move       'transient-face 'transient-key-stay)
-(put 'transient--do-minus      'transient-face 'transient-key-stay)
-
-;;; Commands
-;;;; Noop
-
-(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)
-  (transient--invalid "Unbound suffix"))
-
-(defun transient-inapt ()
-  "Warn the user that the invoked command is inapt."
-  (interactive)
-  (transient--invalid "Inapt command"))
-
-(defun transient--invalid (msg)
-  (ding)
-  (message "%s: `%s' (Use `%s' to abort, `%s' for help)%s"
-           msg
-           (propertize (key-description (this-single-command-keys))
-                       'face 'font-lock-warning-face)
-           (propertize "C-g" 'face 'transient-key)
-           (propertize "?"   'face 'transient-key)
-           ;; `this-command' is `transient-undefined' or `transient-inapt'.
-           ;; Show the command (`this-original-command') the user actually
-           ;; tried to invoke.
-           (if-let ((cmd (or (ignore-errors (symbol-name this-original-command))
-                             (ignore-errors (symbol-name this-command)))))
-               (format " [%s]" (propertize cmd 'face 'font-lock-warning-face))
-             ""))
-  (unless (and transient--transient-map
-               (memq transient--transient-map overriding-terminal-local-map))
-    (let ((transient--prefix (or transient--prefix 'sic)))
-      (transient--emergency-exit))
-    (view-lossage)
-    (other-window 1)
-    (display-warning 'transient "Inconsistent transient state detected.
-This should never happen.
-Please open an issue and post the shown command log." :error)))
-
-(defun transient-inhibit-move ()
-  "Warn the user that popup navigation is disabled."
-  (interactive)
-  (message "To enable use of `%s', please customize `%s'"
-           this-original-command
-           'transient-enable-popup-navigation))
-
-;;;; Core
-
-(defun transient-quit-all ()
-  "Exit all transients without saving the transient stack."
-  (interactive))
-
-(defun transient-quit-one ()
-  "Exit the current transients, returning to outer transient, if any."
-  (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)
-  (setq prefix-arg current-prefix-arg))
-
-(defun transient-show ()
-  "Show the transient's state in the popup buffer."
-  (interactive)
-  (setq transient--showp t))
-
-(defun transient-push-button ()
-  "Invoke the suffix command represented by this button."
-  (interactive))
-
-;;;; Suspend
-
-(defun transient-suspend ()
-  "Suspend the current transient.
-It can later be resumed using `transient-resume', while no other
-transient is active."
-  (interactive))
-
-(define-minor-mode transient-resume-mode
-  "Auxiliary minor-mode used to resume a transient after viewing help.")
-
-(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"))))
-
-;;;; Help
-
-(defun transient-help (&optional interactive)
-  "Show help for the active transient or one of its suffixes.\n\n(fn)"
-  (interactive (list t))
-  (if interactive
-      (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-local transient--restore-winconf winconf))
-        (fit-window-to-buffer nil (frame-height) (window-height))
-        (transient-resume-mode)
-        (message (substitute-command-keys
-                  "Type \\`q' to resume transient command."))
-        t))))
-
-;;;; Level
-
-(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)
-                       (progn
-                         (transient--show)
-                         (string-to-number
-                          (transient--read-number-N
-                           (format "Set level for `%s': " 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))
-           (akey command))
-      (cond ((eq command prefix)
-             (oset transient--prefix level level)
-             (setq akey t))
-            (t
-             (oset (transient-suffix-object command) level level)
-             (when (cdr (cl-remove-if-not (lambda (obj)
-                                            (eq (oref obj command) command))
-                                          transient--suffixes))
-               (setq akey (cons command (this-command-keys))))))
-      (setf (alist-get akey alist) level)
-      (setf (alist-get prefix transient-levels) alist))
-    (transient-save-levels)
-    (transient--show))
-   (t
-    (transient-undefined))))
-
-(transient-define-suffix transient-toggle-level-limit ()
-  "Toggle whether to temporarily displayed suffixes on all levels."
-  :description
-  (lambda ()
-    (cond
-     ((= transient-default-level transient--max-level)
-      "Always displaying all levels")
-     (transient--all-levels-p
-      (format "Hide suffix %s"
-              (propertize
-               (format "levels > %s" (oref (transient-prefix-object) level))
-               'face 'transient-higher-level)))
-     ("Show all suffix levels")))
-  :inapt-if (lambda () (= transient-default-level transient--max-level))
-  :transient t
-  (interactive)
-  (setq transient--all-levels-p (not transient--all-levels-p))
-  (setq transient--refreshp t))
-
-;;;; Value
-
-(defun transient-set ()
-  "Set active transient's value for this Emacs session."
-  (interactive)
-  (transient-set-value (transient-prefix-object)))
-
-(defalias 'transient-set-and-exit #'transient-set
-  "Set active transient's value for this Emacs session and exit.")
-
-(defun transient-save ()
-  "Save active transient's value for this and future Emacs sessions."
-  (interactive)
-  (transient-save-value (transient-prefix-object)))
-
-(defalias 'transient-save-and-exit #'transient-save
-  "Save active transient's value for this and future Emacs sessions and exit.")
-
-(defun transient-reset ()
-  "Clear the set and saved values of the active transient."
-  (interactive)
-  (transient-reset-value (transient-prefix-object)))
-
-(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))))
-
-(transient-define-suffix transient-preset ()
-  "Put this preset into action."
-  :class transient-value-preset
-  (interactive)
-  (transient-prefix-set (oref (transient-suffix-object) set)))
-
-;;;; Auxiliary
-
-(defun transient-toggle-common ()
-  "Toggle whether common commands are permanently shown."
-  (interactive)
-  (setq transient-show-common-commands (not transient-show-common-commands)))
-
-(defun transient-toggle-debug ()
-  "Toggle debugging statements for transient commands."
-  (interactive)
-  (setq transient--debug (not transient--debug))
-  (message "Debugging transient %s"
-           (if transient--debug "enabled" "disabled")))
-
-(transient-define-suffix transient-echo-arguments (arguments)
-  "Show the transient's active ARGUMENTS in the echo area.
-Intended for use in prefixes used for demonstration purposes,
-such as when suggesting a new feature or reporting an issue."
-  :transient t
-  :description "Echo arguments"
-  :key "x"
-  (interactive (list (transient-args transient-current-command)))
-  (message "%s: %s"
-           (key-description (this-command-keys))
-           (mapconcat (lambda (arg)
-                        (propertize (if (string-match-p " " arg)
-                                        (format "%S" arg)
-                                      arg)
-                                    'face 'transient-argument))
-                      arguments " ")))
-
-;;; 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 :around ((obj transient-prefix))
-  "If bound, then call OBJ's `init-value' function.
-Otherwise call the primary method according to object's class."
-  (if (slot-boundp obj 'init-value)
-      (funcall (oref obj init-value) obj)
-    (cl-call-next-method obj)))
-
-(cl-defmethod transient-init-value :around ((obj transient-infix))
-  "If bound, then call OBJ's `init-value' function.
-Otherwise call the primary method according to object's class."
-  (if (slot-boundp obj 'init-value)
-      (funcall (oref obj init-value) obj)
-    (cl-call-next-method obj)))
-
-(cl-defmethod transient-init-value ((obj transient-prefix))
-  (if (slot-boundp obj 'value)
-      (oref obj value)
-    (oset obj value
-          (if-let ((saved (assq (oref obj command) transient-values)))
-              (cdr saved)
-            (transient-default-value obj)))))
-
-(cl-defmethod transient-init-value ((obj transient-argument))
-  (oset obj value
-        (let ((value (oref transient--prefix value))
-              (argument (and (slot-boundp obj 'argument)
-                             (oref obj argument)))
-              (multi-value (oref obj multi-value))
-              (case-fold-search nil)
-              (regexp (if (slot-exists-p obj 'argument-regexp)
-                          (oref obj argument-regexp)
-                        (format "\\`%s\\(.*\\)" (oref obj argument)))))
-          (if (memq multi-value '(t rest))
-              (cdr (assoc argument value))
-            (let ((match (lambda (v)
-                           (and (stringp v)
-                                (string-match regexp v)
-                                (match-string 1 v)))))
-              (if multi-value
-                  (delq nil (mapcar match value))
-                (cl-some match value)))))))
-
-(cl-defmethod transient-init-value ((obj transient-switch))
-  (oset obj value
-        (car (member (oref obj argument)
-                     (oref transient--prefix value)))))
-
-;;;; Default
-
-(cl-defgeneric transient-default-value (_)
-  "Return the default value."
-  nil)
-
-(cl-defmethod transient-default-value ((obj transient-prefix))
-  (if-let ((default (and (slot-boundp obj 'default-value)
-                         (oref obj default-value))))
-      (if (functionp default)
-          (funcall default)
-        default)
-    nil))
-
-;;;; 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))
-  "Refresh the transient buffer and call the next method.
-
-Also wrap `cl-call-next-method' with two macros:
-- `transient--with-suspended-override' allows use of minibuffer.
-- `transient--with-emergency-exit' arranges for the transient to
-  be exited in case of an error."
-  (transient--show)
-  (transient--with-emergency-exit :infix-read
-    (transient--with-suspended-override
-     (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 limited 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 always-read allow-empty choices) obj
-    (if (and value
-             (not multi-value)
-             (not always-read)
-             transient--prefix)
-        (oset obj value nil)
-      (let* ((enable-recursive-minibuffers t)
-             (reader (oref obj reader))
-             (choices (if (functionp choices) (funcall choices) choices))
-             (prompt (transient-prompt obj))
-             (value (if multi-value (string-join 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))
-               ((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 (and (bound-and-true-p ivy-mode)
-                     (stringp (car transient--history)))
-            (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))))
-
-(cl-defmethod transient-infix-read ((command symbol))
-  "Elsewhere use the reader of the infix command COMMAND.
-Use this if you want to share an infix's history with a regular
-stand-alone command."
-  (if-let ((obj (transient--suffix-prototype command)))
-      (cl-letf (((symbol-function #'transient--show) #'ignore))
-        (transient-infix-read obj))
-    (error "Not a suffix command: `%s'" command)))
-
-;;;; Readers
-
-(defun transient-read-file (prompt _initial-input _history)
-  "Read a file."
-  (file-local-name (expand-file-name (read-file-name prompt))))
-
-(defun transient-read-existing-file (prompt _initial-input _history)
-  "Read an existing file."
-  (file-local-name (expand-file-name (read-file-name prompt nil nil t))))
-
-(defun transient-read-directory (prompt _initial-input _history)
-  "Read a directory."
-  (file-local-name (expand-file-name (read-directory-name prompt))))
-
-(defun transient-read-existing-directory (prompt _initial-input _history)
-  "Read an existing directory."
-  (file-local-name (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)))
-          (when (or (string-equal str "")
-                    (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 (and-let* ((arg (and (slot-boundp obj 'argument) (oref obj argument))))
-          (if (and (stringp arg) (string-suffix-p "=" arg))
-              arg
-            (concat arg ": ")))
-        (and-let* ((var (and (slot-boundp obj 'variable) (oref obj variable))))
-          (and (stringp var)
-               (concat var ": ")))
-        "(BUG: no prompt): ")))
-
-;;;; Set
-
-(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."
-  (oset obj value value))
-
-(cl-defmethod transient-infix-set :after ((obj transient-argument) value)
-  "Unset incompatible infix arguments."
-  (when-let* ((value)
-              (val (transient-infix-value obj))
-              (arg (if (slot-boundp obj 'argument)
-                       (oref obj argument)
-                     (oref obj argument-format)))
-              (spec (oref transient--prefix incompatible))
-              (filter (lambda (x rule)
-                        (and (member x rule)
-                             (remove x rule))))
-              (incomp (nconc
-                       (cl-mapcan (apply-partially filter arg) spec)
-                       (and (not (equal val arg))
-                            (cl-mapcan (apply-partially filter val) spec)))))
-    (dolist (obj transient--suffixes)
-      (when-let* (((cl-typep obj 'transient-argument))
-                  (val (transient-infix-value obj))
-                  (arg (if (slot-boundp obj 'argument)
-                           (oref obj argument)
-                         (oref obj argument-format)))
-                  ((if (equal val arg)
-                       (member arg incomp)
-                     (or (member val incomp)
-                         (member arg incomp)))))
-        (transient-infix-set obj nil)))))
-
-(defun transient-prefix-set (value)
-  "Set the value of the active transient prefix to VALUE.
-Intended for use by transient suffix commands."
-  (oset transient--prefix value value)
-  (setq transient--refreshp 'updated-value))
-
-(cl-defgeneric transient-set-value (obj)
-  "Persist the value of the transient prefix OBJ.
-Only intended for use by `transient-set'.
-Also see `transient-prefix-set'.")
-
-(cl-defmethod transient-set-value ((obj transient-prefix))
-  (oset (oref obj prototype) value (transient-get-value))
-  (transient--history-push obj))
-
-;;;; Save
-
-(cl-defgeneric transient-save-value (obj)
-  "Save the value of the transient prefix OBJ.")
-
-(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))
-
-;;;; Reset
-
-(cl-defgeneric transient-reset-value (obj)
-  "Clear the set and saved values of the transient prefix OBJ.")
-
-(cl-defmethod transient-reset-value ((obj transient-prefix))
-  (let ((value (transient-default-value obj)))
-    (oset obj value value)
-    (oset (oref obj prototype) value value)
-    (setf (alist-get (oref obj command) transient-values nil 'remove) nil)
-    (transient-save-values))
-  (transient--history-push obj)
-  (mapc #'transient-init-value transient--suffixes))
-
-;;;; 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."
-  (cl-mapcan #'transient--get-wrapped-value (transient-suffixes prefix)))
-
-(defun transient-suffixes (prefix)
-  "Return the suffix objects of the transient prefix command PREFIX."
-  (if (eq transient-current-command prefix)
-      transient-current-suffixes
-    (let ((transient--prefix (transient--init-prefix prefix)))
-      (transient--flatten-suffixes
-       (transient--init-suffixes prefix)))))
-
-(defun transient-get-value ()
-  (transient--with-emergency-exit :get-value
-    (cl-mapcan (lambda (obj)
-                 (and (or (not (slot-exists-p obj 'unsavable))
-                          (not (oref obj unsavable)))
-                      (transient--get-wrapped-value obj)))
-               (or transient--suffixes transient-current-suffixes))))
-
-(defun transient--get-wrapped-value (obj)
-  (and-let* ((value (transient-infix-value obj)))
-    (pcase-exhaustive (and (slot-exists-p obj 'multi-value)
-                           (oref obj multi-value))
-      ('nil          (list value))
-      ((or 't 'rest) (list value))
-      ('repeat       value))))
-
-(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 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 ARGUMENT and VALUE as a unit or nil if the latter is nil."
-  (and-let* ((value (oref obj value)))
-    (let ((arg (oref obj argument)))
-      (pcase-exhaustive (oref obj multi-value)
-        ('nil          (concat arg value))
-        ((or 't 'rest) (cons arg value))
-        ('repeat       (mapcar (lambda (v) (concat arg v)) 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)
-
-;;;; Utilities
-
-(defun transient-arg-value (arg args)
-  "Return the value of ARG as it appears in ARGS.
-
-For a switch return a boolean.  For an option return the value as
-a string, using the empty string for the empty value, or nil if
-the option does not appear in ARGS."
-  (if (string-suffix-p "=" arg)
-      (save-match-data
-        (and-let* ((match (let ((case-fold-search nil)
-                                (re (format "\\`%s\\(?:=\\(.+\\)\\)?\\'"
-                                            (substring arg 0 -1))))
-                            (cl-find-if (lambda (a)
-                                          (and (stringp a)
-                                               (string-match re a)))
-                                        args))))
-          (or (match-string 1 match) "")))
-    (and (member arg args) t)))
-
-(defun transient-scope ()
-  "Return the value of the `scope' slot of the current prefix."
-  (oref (transient-prefix-object) scope))
-
-;;; 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-delimiter))))))
-
-(defun transient--show ()
-  (transient--timer-cancel)
-  (setq transient--showp t)
-  (let ((transient--shadowed-buffer (current-buffer))
-        (focus nil))
-    (setq transient--buffer (get-buffer-create transient--buffer-name))
-    (with-current-buffer transient--buffer
-      (when transient-enable-popup-navigation
-        (setq focus (or (button-get (point) 'command)
-                        (and (not (bobp))
-                             (button-get (1- (point)) 'command))
-                        (transient--heading-at-point))))
-      (erase-buffer)
-      (run-hooks 'transient-setup-buffer-hook)
-      (when transient-force-fixed-pitch
-        (transient--force-fixed-pitch))
-      (setq window-size-fixed t)
-      (when (bound-and-true-p tab-line-format)
-        (setq tab-line-format nil))
-      (setq header-line-format nil)
-      (setq mode-line-format
-            (if (or (natnump transient-mode-line-format)
-                    (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-let ((line (transient--separator-line)))
-        (insert line)))
-    (unless (window-live-p transient--window)
-      (setq transient--window
-            (display-buffer transient--buffer
-                            transient-display-buffer-action)))
-    (when (window-live-p transient--window)
-      (with-selected-window transient--window
-        (goto-char (point-min))
-        (when transient-enable-popup-navigation
-          (transient--goto-button focus))
-        (transient--fit-window-to-buffer transient--window)))))
-
-(defun transient--fit-window-to-buffer (window)
-  (let ((window-resize-pixelwise t)
-        (window-size-fixed nil))
-    (if (eq (car (window-parameter window 'quit-restore)) 'other)
-        ;; Grow but never shrink window that previously displayed
-        ;; another buffer and is going to display that again.
-        (fit-window-to-buffer window nil (window-height window))
-      (fit-window-to-buffer window nil 1))))
-
-(defun transient--separator-line ()
-  (and-let* ((height (cond ((not window-system) nil)
-                           ((natnump transient-mode-line-format)
-                            transient-mode-line-format)
-                           ((eq transient-mode-line-format 'line) 1)))
-             (face `(,@(and (>= emacs-major-version 27) '(:extend t))
-                     :background
-                     ,(or (face-foreground (transient--key-face nil 'non-suffix)
-                                           nil t)
-                          "#gray60"))))
-    (concat (propertize "__" 'face face 'display `(space :height (,height)))
-            (propertize "\n" 'face face 'line-height t))))
-
-(defmacro transient-with-shadowed-buffer (&rest body)
-  "While in the transient buffer, temporarily make the shadowed buffer current."
-  (declare (indent 0) (debug t))
-  `(with-current-buffer (or transient--shadowed-buffer (current-buffer))
-     ,@body))
-
-(defun transient--insert-groups ()
-  (let ((groups (cl-mapcan (lambda (group)
-                             (let ((hide (oref group hide)))
-                               (and (not (and (functionp hide)
-                                              (transient-with-shadowed-buffer
-                                                (funcall hide))))
-                                    (list group))))
-                           transient--layout)))
-    (while-let ((group (pop groups)))
-      (transient--insert-group group)
-      (when groups
-        (insert ?\n)))))
-
-(defvar transient--max-group-level 1)
-
-(cl-defgeneric transient--insert-group (group)
-  "Format GROUP and its elements and insert the result.")
-
-(cl-defmethod transient--insert-group :around ((group transient-group))
-  "Insert GROUP's description, if any."
-  (when-let ((desc (transient-with-shadowed-buffer
-                     (transient-format-description group))))
-    (insert desc ?\n))
-  (let ((transient--max-group-level
-         (max (oref group level) transient--max-group-level))
-        (transient--pending-group group))
-    (cl-call-next-method group)))
-
-(cl-defmethod transient--insert-group ((group transient-row))
-  (transient--maybe-pad-keys group)
-  (dolist (suffix (oref group suffixes))
-    (insert (transient-with-shadowed-buffer (transient-format suffix)))
-    (insert "   "))
-  (insert ?\n))
-
-(cl-defmethod transient--insert-group ((group transient-column)
-                                       &optional skip-empty)
-  (transient--maybe-pad-keys group)
-  (dolist (suffix (oref group suffixes))
-    (let ((str (transient-with-shadowed-buffer (transient-format suffix))))
-      (unless (and (not skip-empty) (equal str ""))
-        (insert str)
-        (unless (string-match-p ".\n\\'" str)
-          (insert ?\n))))))
-
-(cl-defmethod transient--insert-group ((group transient-columns))
-  (if transient-force-single-column
-      (dolist (group (oref group suffixes))
-        (transient--insert-group group t))
-    (let* ((columns
-            (mapcar
-             (lambda (column)
-               (transient--maybe-pad-keys column group)
-               (transient-with-shadowed-buffer
-                 `(,@(and-let* ((desc (transient-format-description column)))
-                       (list desc))
-                   ,@(let ((transient--pending-group column))
-                       (mapcar #'transient-format (oref column suffixes))))))
-             (oref group suffixes)))
-           (stops (transient--column-stops columns)))
-      (dolist (row (apply #'transient--mapn #'list columns))
-        (let ((stops stops))
-          (dolist (cell row)
-            (let ((stop (pop stops)))
-              (when cell
-                (transient--align-to stop)
-                (insert cell)))))
-        (insert ?\n)))))
-
-(cl-defmethod transient--insert-group ((group transient-subgroups))
-  (let ((subgroups (oref group suffixes)))
-    (while-let ((subgroup (pop subgroups)))
-      (transient--maybe-pad-keys subgroup group)
-      (transient--insert-group subgroup)
-      (when subgroups
-        (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-suffix))
-  "Add additional formatting if appropriate.
-When reading user input for this infix, then highlight it.
-When edit-mode is enabled, then prepend the level information.
-When `transient-enable-popup-navigation' is non-nil then format
-as a button."
-  (let ((str (cl-call-next-method obj)))
-    (when (and (cl-typep obj 'transient-infix)
-               (eq (oref obj command) this-original-command)
-               (active-minibuffer-window))
-      (setq str (transient--add-face str 'transient-active-infix)))
-    (when transient--editp
-      (setq str (concat (let ((level (oref obj level)))
-                          (propertize (format " %s " level)
-                                      'face (if (transient--use-level-p level t)
-                                                'transient-enabled-suffix
-                                              'transient-disabled-suffix)))
-                        str)))
-    (when (and transient-enable-popup-navigation
-               (slot-boundp obj 'command))
-      (setq str (make-text-button str nil
-                                  'type 'transient
-                                  'command (oref obj command))))
-    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'.
-%v 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 :around ((obj transient-suffix))
-  "Add `transient-inapt-suffix' face if suffix is inapt."
-  (let ((str (cl-call-next-method)))
-    (if (oref obj inapt)
-        (transient--add-face str 'transient-inapt-suffix)
-      str)))
-
-(cl-defmethod transient-format-key ((obj transient-suffix))
-  "Format OBJ's `key' for display and return the result."
-  (let ((key (if (slot-boundp obj 'key) (oref obj key) ""))
-        (cmd (and (slot-boundp obj 'command) (oref obj command))))
-    (when-let ((width (oref transient--pending-group pad-keys)))
-      (setq key (truncate-string-to-width key width nil ?\s)))
-    (if transient--redisplay-key
-        (let ((len (length transient--redisplay-key))
-              (seq (cl-coerce (edmacro-parse-keys key t) 'list)))
-          (cond
-           ((member (seq-take seq len)
-                    (list transient--redisplay-key
-                          (thread-last transient--redisplay-key
-                            (cl-substitute ?- 'kp-subtract)
-                            (cl-substitute ?= 'kp-equal)
-                            (cl-substitute ?+ 'kp-add))))
-            (let ((pre (key-description (vconcat (seq-take seq len))))
-                  (suf (key-description (vconcat (seq-drop seq len)))))
-              (setq pre (string-replace "RET" "C-m" pre))
-              (setq pre (string-replace "TAB" "C-i" pre))
-              (setq suf (string-replace "RET" "C-m" suf))
-              (setq suf (string-replace "TAB" "C-i" suf))
-              ;; 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-search " " key)
-                (setq pre (string-replace " " "" pre))
-                (setq suf (string-replace " " "" suf)))
-              (concat (propertize pre 'face 'transient-unreachable-key)
-                      (and (string-prefix-p (concat pre " ") key) " ")
-                      (propertize suf 'face (transient--key-face cmd))
-                      (save-excursion
-                        (and (string-match " +\\'" key)
-                             (propertize (match-string 0 key)
-                                         'face 'fixed-pitch))))))
-           ((transient--lookup-key transient-sticky-map (kbd key))
-            (propertize key 'face (transient--key-face cmd)))
-           (t
-            (propertize key 'face 'transient-unreachable-key))))
-      (propertize key 'face (transient--key-face cmd)))))
-
-(cl-defmethod transient-format-key :around ((obj transient-argument))
-  "Handle `transient-highlight-mismatched-keys'."
-  (let ((key (cl-call-next-method obj)))
-    (cond
-     ((not transient-highlight-mismatched-keys) key)
-     ((not (slot-boundp obj 'shortarg))
-      (transient--add-face key 'transient-nonstandard-key))
-     ((not (string-equal key (oref obj shortarg)))
-      (transient--add-face key 'transient-mismatched-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-suffix))
-  "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."
-  (transient--get-description obj))
-
-(cl-defmethod transient-format-description ((obj transient-value-preset))
-  (pcase-let* (((eieio description key set) obj)
-               ((eieio value) transient--prefix)
-               (active (seq-set-equal-p set value)))
-    (format
-     "%s %s"
-     (propertize (or description (format "Preset %s" key))
-                 'face (and active 'transient-argument))
-     (format (propertize "(%s)" 'face 'transient-delimiter)
-             (mapconcat (lambda (arg)
-                          (propertize
-                           arg 'face (cond (active 'transient-argument)
-                                           ((member arg value)
-                                            '((:weight demibold)
-                                              transient-inactive-argument))
-                                           ('transient-inactive-argument))))
-                        set " ")))))
-
-(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."
-  (and-let* ((desc (transient--get-description obj)))
-    (cond ((oref obj inapt)
-           (propertize desc 'face 'transient-inapt-suffix))
-          ((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)
-                  (and (slot-boundp transient--prefix 'suffix-description)
-                       (funcall (oref transient--prefix suffix-description)
-                                obj)))))
-    (if desc
-        (when-let ((face (transient--get-face obj 'face)))
-          (setq desc (transient--add-face desc face t)))
-      (setq desc (propertize "(BUG: no description)" 'face 'error)))
-    (when (if transient--all-levels-p
-              (> (oref obj level) transient--default-prefix-level)
-            (and transient-highlight-higher-levels
-                 (> (max (oref obj level) transient--max-group-level)
-                    transient--default-prefix-level)))
-      (setq desc (transient--add-face desc 'transient-higher-level)))
-    (when-let ((inapt-face (and (oref obj inapt)
-                                (transient--get-face obj 'inapt-face))))
-      (setq desc (transient--add-face desc inapt-face)))
-    (when (and (slot-boundp obj 'key)
-               (transient--key-unreachable-p obj))
-      (setq desc (transient--add-face desc '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 ((argument (oref obj argument)))
-    (if-let ((value (oref obj value)))
-        (pcase-exhaustive (oref obj multi-value)
-          ('nil
-           (concat (propertize argument 'face 'transient-argument)
-                   (propertize value    'face 'transient-value)))
-          ((or 't 'rest)
-           (concat (propertize (if (string-suffix-p " " argument)
-                                   argument
-                                 (concat argument " "))
-                               'face 'transient-argument)
-                   (propertize (mapconcat #'prin1-to-string value " ")
-                               'face 'transient-value)))
-          ('repeat
-           (mapconcat (lambda (value)
-                        (concat (propertize argument 'face 'transient-argument)
-                                (propertize value    'face 'transient-value)))
-                      value " ")))
-      (propertize argument 'face 'transient-inactive-argument))))
-
-(cl-defmethod transient-format-value ((obj transient-switches))
-  (with-slots (value argument-format choices) obj
-    (format (propertize argument-format
-                        'face (if value
-                                  'transient-argument
-                                'transient-inactive-argument))
-            (format
-             (propertize "[%s]" 'face 'transient-delimiter)
-             (mapconcat
-              (lambda (choice)
-                (propertize choice 'face
-                            (if (equal (format argument-format choice) value)
-                                'transient-value
-                              'transient-inactive-value)))
-              choices
-              (propertize "|" 'face 'transient-delimiter))))))
-
-(cl-defmethod transient--get-description ((obj transient-child))
-  (and-let* ((desc (oref obj description)))
-    (if (functionp desc)
-        (if (= (car (transient--func-arity desc)) 1)
-            (funcall desc obj)
-          (funcall desc))
-      desc)))
-
-(cl-defmethod transient--get-face ((obj transient-suffix) slot)
-  (and-let* (((slot-boundp obj slot))
-             (face (slot-value obj slot)))
-    (if (and (not (facep face))
-             (functionp face))
-        (let ((transient--pending-suffix obj))
-          (if (= (car (transient--func-arity face)) 1)
-              (funcall face obj)
-            (funcall face)))
-      face)))
-
-(defun transient--add-face (string face &optional append beg end)
-  (let ((str (copy-sequence string)))
-    (add-face-text-property (or beg 0) (or end (length str)) face append str)
-    str))
-
-(defun transient--key-face (&optional cmd enforce-type)
-  (or (and transient-semantic-coloring
-           (not transient--helpp)
-           (not transient--editp)
-           (or (and cmd (get cmd 'transient-face))
-               (get (transient--get-pre-command cmd enforce-type)
-                    'transient-face)))
-      (if cmd 'transient-key 'transient-key-noop)))
-
-(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)))
-
-(defun transient--maybe-pad-keys (group &optional parent)
-  (when-let ((pad (or (oref group pad-keys)
-                      (and parent (oref parent pad-keys)))))
-    (oset group pad-keys
-          (apply #'max
-                 (if (integerp pad) pad 0)
-                 (seq-keep (lambda (suffix)
-                             (and (eieio-object-p suffix)
-                                  (slot-boundp suffix 'key)
-                                  (length (oref suffix key))))
-                           (oref group suffixes))))))
-
-(defun transient--pixel-width (string)
-  (save-window-excursion
-    (with-temp-buffer
-      (insert string)
-      (set-window-dedicated-p nil nil)
-      (set-window-buffer nil (current-buffer))
-      (car (window-text-pixel-size
-            nil (line-beginning-position) (point))))))
-
-(defun transient--column-stops (columns)
-  (let* ((var-pitch (or transient-align-variable-pitch
-                        (oref transient--prefix variable-pitch)))
-         (char-width (and var-pitch (transient--pixel-width " "))))
-    (transient--seq-reductions-from
-     (apply-partially #'+ (* 2 (if var-pitch char-width 1)))
-     (transient--mapn
-      (lambda (cells min)
-        (apply #'max
-               (if min (if var-pitch (* min char-width) min) 0)
-               (mapcar (if var-pitch #'transient--pixel-width #'length) cells)))
-      columns
-      (oref transient--prefix column-widths))
-     0)))
-
-(defun transient--align-to (stop)
-  (unless (zerop stop)
-    (insert (if (or transient-align-variable-pitch
-                    (oref transient--prefix variable-pitch))
-                (propertize " " 'display `(space :align-to (,stop)))
-              (make-string (max 0 (- stop (current-column))) ?\s)))))
-
-(defun transient-command-summary-or-name (obj)
-  "Return the summary or name of the command represented by OBJ.
-
-If the command has a doc-string, then return the first line of
-that, else its name.
-
-Intended to be temporarily used as the `:suffix-description' of
-a prefix command, while porting a regular keymap to a transient."
-  (let ((command (oref obj command)))
-    (if-let ((doc (documentation command)))
-        (propertize (car (split-string doc "\n")) 'face 'font-lock-doc-face)
-      (propertize (symbol-name command) 'face 'font-lock-function-name-face))))
-
-;;; Help
-
-(cl-defgeneric transient-show-help (obj)
-  "Show documentation for the command represented by OBJ.")
-
-(cl-defmethod transient-show-help ((obj transient-prefix))
-  "Call `show-help' if non-nil, else show `info-manual',
-if non-nil, else show the `man-page' if non-nil, else use
-`describe-function'."
-  (with-slots (show-help info-manual man-page command) obj
-    (cond (show-help (funcall show-help obj))
-          (info-manual (transient--show-manual info-manual))
-          (man-page (transient--show-manpage man-page))
-          ((transient--describe-function command)))))
-
-(cl-defmethod transient-show-help ((obj transient-suffix))
-  "Call `show-help' if non-nil, else use `describe-function'.
-Also used to dispatch showing documentation for the current
-prefix.  If the suffix is a sub-prefix, then also call the
-prefix method."
-  (cond
-   ((eq this-command 'transient-help)
-    (transient-show-help transient--prefix))
-   ((let ((prefix (get (oref obj command)
-                       'transient--prefix)))
-      (and prefix (not (eq (oref transient--prefix command) this-command))
-           (prog1 t (transient-show-help prefix)))))
-   ((if-let ((show-help (oref obj show-help)))
-        (funcall show-help obj)
-      (transient--describe-function this-command)))))
-
-(cl-defmethod transient-show-help ((obj transient-infix))
-  "Call `show-help' if non-nil, else show the `man-page'
-if non-nil, else use `describe-function'.  When showing the
-manpage, then try to jump to the correct location."
-  (if-let ((show-help (oref obj show-help)))
-      (funcall show-help obj)
-    (if-let ((man-page (oref transient--prefix man-page))
-             (argument (and (slot-boundp obj 'argument)
-                            (oref obj argument))))
-        (transient--show-manpage man-page argument)
-      (transient--describe-function this-command))))
-
-;; `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--describe-function (fn)
-  (describe-function fn)
-  (unless (derived-mode-p 'help-mode)
-    (when-let* ((buf (get-buffer "*Help*"))
-                (win (or (and buf (get-buffer-window buf))
-                         (cl-find-if (lambda (win)
-                                       (with-current-buffer (window-buffer win)
-                                         (derived-mode-p 'help-mode)))
-                                     (window-list)))))
-      (select-window win))))
-
-(defun transient--show-manual (manual)
-  (info manual))
-
-(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--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))))))
-
-;;; Popup Navigation
-
-(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-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)))
-
-(define-button-type 'transient
-  'face nil
-  'keymap transient-button-map)
-
-(defun transient--goto-button (command)
-  (cond
-   ((stringp command)
-    (when (re-search-forward (concat "^" (regexp-quote command)) nil t)
-      (goto-char (match-beginning 0))))
-   (command
-    (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)))))
-
-(defun transient--heading-at-point ()
-  (and (eq (get-text-property (point) 'face) 'transient-heading)
-       (let ((beg (line-beginning-position)))
-         (buffer-substring-no-properties
-          beg (next-single-property-change
-               beg 'face nil (line-end-position))))))
-
-;;; Compatibility
-;;;; Popup Isearch
-
-(defvar-keymap transient--isearch-mode-map
-  :parent isearch-mode-map
-  "<remap> <isearch-exit>"   #'transient-isearch-exit
-  "<remap> <isearch-cancel>" #'transient-isearch-cancel
-  "<remap> <isearch-abort>"  #'transient-isearch-abort)
-
-(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)
-  (let ((around (lambda (fn)
-                  (condition-case nil (funcall fn) (quit))
-                  (transient--isearch-exit))))
-    (advice-add 'isearch-cancel :around around)
-    (unwind-protect
-        (isearch-abort)
-      (advice-remove 'isearch-cancel around))))
-
-(defun transient--isearch-setup ()
-  (select-window transient--window)
-  (transient--suspend-override t))
-
-(defun transient--isearch-exit ()
-  (select-window transient--original-window)
-  (transient--resume-override))
-
-;;;; 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
-
-(cl-pushnew (list nil (concat "^\\s-*("
-                              (eval-when-compile
-                                (regexp-opt
-                                 '("transient-define-prefix"
-                                   "transient-define-suffix"
-                                   "transient-define-infix"
-                                   "transient-define-argument")
-                                 t))
-                              "\\s-+\\(" lisp-mode-symbol-regexp "\\)")
-                  2)
-            lisp-imenu-generic-expression :test #'equal)
-
-(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 'transient-exit-hook #'transient--resume-which-key-mode)))
-
-(defun transient--resume-which-key-mode ()
-  (unless transient--prefix
-    (which-key-mode 1)
-    (remove-hook 'transient-exit-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."
-  (keymap-set transient-base-map   "q" #'transient-quit-one)
-  (keymap-set 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")
-          (key))))
-
-(defun transient--force-fixed-pitch ()
-  (require 'face-remap)
-  (face-remap-reset-base 'default)
-  (face-remap-add-relative 'default 'fixed-pitch))
-
-(defun transient--func-arity (fn)
-  (func-arity (advice--cd*r (if (symbolp fn) (symbol-function fn) fn))))
-
-(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)))
-
-(defun transient--mapn (function &rest lists)
-  "Apply FUNCTION to elements of LISTS.
-Like `cl-mapcar' but while that stops when the shortest list
-is exhausted, continue until the longest list is, using nil
-as stand-in for elements of exhausted lists."
-  (let (result)
-    (while (catch 'more (mapc (lambda (l) (and l (throw 'more t))) lists) nil)
-      (push (apply function (mapcar #'car-safe lists)) result)
-      (setq lists (mapcar #'cdr lists)))
-    (nreverse result)))
-
-;;; Font-Lock
-
-(defconst transient-font-lock-keywords
-  (eval-when-compile
-    `((,(concat "("
-                (regexp-opt (list "transient-define-prefix"
-                                  "transient-define-infix"
-                                  "transient-define-argument"
-                                  "transient-define-suffix")
-                            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)
-
-;;; Auxiliary Classes
-;;;; `transient-lisp-variable'
-
-(defclass transient-lisp-variable (transient-variable)
-  ((reader :initform #'transient-lisp-variable--reader)
-   (always-read :initform t)
-   (set-value :initarg :set-value :initform #'set))
-  "[Experimental] Class used for Lisp variables.")
-
-(cl-defmethod transient-init-value ((obj transient-lisp-variable))
-  (oset obj value (symbol-value (oref obj variable))))
-
-(cl-defmethod transient-infix-set ((obj transient-lisp-variable) value)
-  (funcall (oref obj set-value)
-           (oref obj variable)
-           (oset obj value value)))
-
-(cl-defmethod transient-format-description ((obj transient-lisp-variable))
-  (or (cl-call-next-method obj)
-      (symbol-name (oref obj variable))))
-
-(cl-defmethod transient-format-value ((obj transient-lisp-variable))
-  (propertize (prin1-to-string (oref obj value))
-              'face 'transient-value))
-
-(cl-defmethod transient-prompt ((obj transient-lisp-variable))
-  (if (and (slot-boundp obj 'prompt)
-           (oref obj prompt))
-      (cl-call-next-method obj)
-    (format "Set %s: " (oref obj variable))))
-
-(defun transient-lisp-variable--reader (prompt initial-input _history)
-  (read--expression prompt initial-input))
-
-;;; _
-(provide 'transient)
-;; Local Variables:
-;; indent-tabs-mode: nil
-;; checkdoc-symbol-words: ("command-line" "edit-mode" "help-mode")
-;; End:
-;;; transient.el ends here
diff --git a/elpa/transient-20240729.1524/transient.info b/elpa/transient-20240729.1524/transient.info
deleted file mode 100644 (file)
index bdfce81..0000000
+++ /dev/null
@@ -1,3318 +0,0 @@
-This is transient.info, produced by makeinfo version 6.8 from
-transient.texi.
-
-     Copyright (C) 2018–2024 Free Software Foundation, Inc.
-
-     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 misc features
-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
-***********************************
-
-Transient is the library used to implement the keyboard-driven “menus”
-in Magit.  It is distributed as a separate package, so that it can be
-used to implement similar menus in other packages.
-
-   This manual can be bit hard to digest when getting started.  A useful
-resource to get over that hurdle is Psionic K’s interactive tutorial,
-available at <https://github.com/positron-solutions/transient-showcase>.
-
-This manual is for Transient version 0.7.3.
-
-     Copyright (C) 2018–2024 Free Software Foundation, Inc.
-
-     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::
-* Modifying Existing Transients::
-* Defining New Commands::
-* Classes and Methods::
-* FAQ::
-* Keystroke Index::
-* Command and Function Index::
-* Variable Index::
-* Concept Index::
-* GNU General Public License::
-
-— 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::
-* Configuration::
-
-Defining New Commands
-
-* Technical Introduction::
-* 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::
-
-
-
-\1f
-File: transient.info,  Node: Introduction,  Next: Usage,  Prev: Top,  Up: Top
-
-1 Introduction
-**************
-
-Transient is the library used to implement the keyboard-driven “menus”
-in Magit.  It is distributed as a separate package, so that it can be
-used to implement similar menus in other packages.
-
-   This manual can be bit hard to digest when getting started.  A useful
-resource to get over that hurdle is Psionic K’s interactive tutorial,
-available at <https://github.com/positron-solutions/transient-showcase>.
-
-Some things that Transient can do
-=================================
-
-   • Display current state of arguments
-   • Display and manage lifecycle of modal bindings
-   • Contextual user interface
-   • Flow control for wizard-like composition of interactive forms
-   • History & persistence
-   • Rendering arguments for controlling CLI programs
-
-Complexity in CLI programs
-==========================
-
-Complexity tends to grow with time.  How do you manage the complexity of
-commands?  Consider the humble shell command ‘ls’.  It now has over
-_fifty_ command line options.  Some of these are boolean flags (‘ls
--l’).  Some take arguments (‘ls --sort=s’).  Some have no effect unless
-paired with other flags (‘ls -lh’).  Some are mutually exclusive.  Some
-shell commands even have so many options that they introduce
-_subcommands_ (‘git branch’, ‘git commit’), each with their own rich set
-of options (‘git branch -f’).
-
-Using Transient for composing interactive commands
-==================================================
-
-What about Emacs commands used interactively?  How do these handle
-options?  One solution is to make many versions of the same command, so
-you don’t need to!  Consider: ‘delete-other-windows’ vs.
-‘delete-other-windows-vertically’ (among many similar examples).
-
-   Some Emacs commands will simply prompt you for the next "argument"
-(‘M-x switch-to-buffer’).  Another common solution is to use prefix
-arguments which usually start with ‘C-u’.  Sometimes these are sensibly
-numerical in nature (‘C-u 4 M-x forward-paragraph’ to move forward 4
-paragraphs).  But sometimes they function instead as boolean "switches"
-(‘C-u C-SPACE’ to jump to the last mark instead of just setting it, ‘C-u
-C-u C-SPACE’ to unconditionally set the mark).  Since there aren’t many
-standards for the use of prefix options, you have to read the command’s
-documentation to find out what the possibilities are.
-
-   But when an Emacs command grows to have a truly large set of options
-and arguments, with dependencies between them, lots of option values,
-etc., these simple approaches just don’t scale.  Transient is designed
-to solve this issue.  Think of it as the humble prefix argument ‘C-u’,
-_raised to the power of 10_.  Like ‘C-u’, it is key driven.  Like the
-shell, it supports boolean "flag" options, options that take arguments,
-and even "sub-commands", with their own options.  But instead of
-searching through a man page or command documentation, well-designed
-transients _guide_ their users to the relevant set of options (and even
-their possible values!)  directly, taking into account any important
-pre-existing Emacs settings.  And while for shell commands like ‘ls’,
-there is only one way to "execute" (hit ‘Return’!), transients can
-"execute" using multiple different keys tied to one of many
-self-documenting _actions_ (imagine having 5 different colored return
-keys on your keyboard!).  Transients make navigating and setting large,
-complex groups of command options and arguments easy.  Fun even.  Once
-you’ve tried it, it’s hard to go back to the ‘C-u what can I do here
-again?’ way.
-
-\1f
-File: transient.info,  Node: Usage,  Next: Modifying Existing Transients,  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::
-* Configuration::
-
-\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, e.g., by setting the
-value of some variable.
-
-\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, 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 documentation 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’
-     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.
-
-   This includes the aborting commands mentioned in the previous
-section, as well as some other commands that are all bound to ‘C-x KEY’.
-After ‘C-x’ is pressed, a section featuring all these common commands is
-temporarily shown in the popup buffer.  After invoking one of them, the
-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 too many options.
-
-     While a transient is active, pressing ‘C-x’ always shows the common
-     commands.  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 or in
-one of the following sections.
-
-   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.
-
-‘C-x C-k’ (‘transient-reset’)
-     Clear the set and saved values of the active transient.
-
- -- User Option: transient-values-file
-     This option names the file that 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.
-
-\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.
-
-‘C-M-p’ (‘transient-history-prev’)
-‘C-x p’
-     This command switches to the previous value used for the active
-     transient.
-
-‘C-M-n’ (‘transient-history-next’)
-‘C-x n’
-     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, 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 option names the file that 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, typing a
-     key shows information about the suffix command that the key
-     normally is bound to (instead of invoking it).  Pressing ‘C-h’ a
-     second time shows information about the _prefix_ command.
-
-     After typing a 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 documentation 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.
-
- -- 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 option names the file that 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.
-
-‘C-x a’ (‘transient-toggle-level-limit’)
-     This command toggle whether suffixes that are on levels higher than
-     the level specified by ‘transient-default-level’ are temporarily
-     available anyway.
-
-\1f
-File: transient.info,  Node: Other Commands,  Next: Configuration,  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: Configuration,  Prev: Other Commands,  Up: Usage
-
-2.9 Configuration
-=================
-
-More options are described in *note Common Suffix Commands::, in *note
-Saving Values::, in *note Using History:: and in *note Enabling and
-Disabling Suffixes::.
-
-Essential Options
------------------
-
-Also see *note Common Suffix Commands::.
-
- -- 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, 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 buffer.
-
-     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 BUFFER 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::, for
-     details.
-
-     The default is:
-
-          (display-buffer-in-side-window
-            (side . bottom)
-            (inhibit-same-window . t)
-            (window-parameters (no-other-window . t)))
-
-     This displays the window at the bottom of the selected frame.
-     Another useful FUNCTION is ‘display-buffer-below-selected’, which
-     is what ‘magit-popup’ used by default.  For more alternatives see
-     *note (elisp)Buffer Display Action Functions::, and *note
-     (elisp)Buffer Display Action Alists::.
-
-     Note that the buffer that was current before the transient buffer
-     is shown should remain the current buffer.  Many suffix commands
-     act on the thing at point, if appropriate, and if the transient
-     buffer became the current buffer, then that would change what is at
-     point.  To that effect ‘inhibit-same-window’ ensures that the
-     selected window is not used to show the transient buffer.
-
-     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 that
-     unfortunately changes which buffer is current.
-
-     If you change the value of this option, then you might also want to
-     change the value of ‘transient-mode-line-format’.
-
-Accessibility Options
----------------------
-
- -- User Option: transient-force-single-column
-     This option controls whether the use of a single column to display
-     suffixes is enforced.  This might be useful for users with low
-     vision who use large text and might otherwise have to scroll in two
-     dimensions.
-
-Auxiliary Options
------------------
-
- -- 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) or a natural number, then the buffer has no
-     mode-line, but a line is drawn is drawn in its place.  If a number
-     is used, that specifies the thickness of the line.  On termcap
-     frames we cannot draw lines, so there ‘line’ and numbers are
-     synonyms for ‘nil’.
-
-     The color of the line is used to indicate if non-suffixes are
-     allowed and whether they exit the transient.  The foreground color
-     of ‘transient-key-noop’ (if non-suffix are disallowed),
-     ‘transient-key-stay’ (if allowed and transient stays active), or
-     ‘transient-key-exit’ (if allowed and they exit the transient) is
-     used to draw the line.
-
-     Otherwise this can be any mode-line format.  See *note (elisp)Mode
-     Line Format::, for details.
-
- -- User Option: transient-semantic-coloring
-     This option controls whether colors are used to indicate the
-     transient behavior of commands.
-
-     If non-‘nil’, then the key binding of each suffix is colorized to
-     indicate whether it exits the transient state or not.  The color of
-     the prefix is indicated using the line that is drawn when the value
-     of ‘transient-mode-line-format’ is ‘line’.
-
- -- 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’, 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 the 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-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’, there is no initial input and
-     the first element has to be accessed the same way as the older
-     elements.
-
- -- User Option: transient-hide-during-minibuffer-read
-     This option controls whether the transient buffer is hidden while
-     user input is being read in the minibuffer.
-
- -- User Option: transient-align-variable-pitch
-     This option controls whether columns are aligned pixel-wise in the
-     popup buffer.
-
-     If this is non-‘nil’, then columns are aligned pixel-wise to
-     support variable-pitch fonts.  Keys are not aligned, so you should
-     use a fixed-pitch font for the ‘transient-key’ face.  Other key
-     faces inherit from that face unless a theme is used that breaks
-     that relationship.
-
-     This option is intended for users who use a variable-pitch font for
-     the ‘default’ face.
-
- -- 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.
-
-Developer Options
------------------
-
-These options are mainly intended for developers.
-
- -- 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, 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-highlight-higher-levels
-     This option controls whether suffixes that would not be available
-     by default are highlighted.
-
-     When non-‘nil’ then the descriptions of suffixes are highlighted if
-     their level is above 4, the default of ‘transient-default-level’.
-     Assuming you have set that variable to 7, this highlights all
-     suffixes that won’t be available to users without them making the
-     same customization.
-
-\1f
-File: transient.info,  Node: Modifying Existing Transients,  Next: Defining New Commands,  Prev: Usage,  Up: Top
-
-3 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.  Let’s begin with
-an example:
-
-     (transient-append-suffix 'magit-patch-apply "-3"
-       '("-R" "Apply in reverse" "--reverse"))
-
-   This inserts a new infix argument to toggle the ‘--reverse’ argument
-after the infix argument that toggles ‘-3’ in ‘magit-patch-apply’.
-
-   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 ‘transient-define-prefix’.  Note that an infix
-     is a special kind of suffix.  Depending on context “suffixes” means
-     “suffixes (including infixes)” or “non-infix suffixes”.  Here it
-     means the former.  See *note Suffix Specifications::.
-
-     SUFFIX may also be a group in the same form as expected by
-     ‘transient-define-prefix’.  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 &optional
-          keep-other
- -- Function: transient-append-suffix prefix loc suffix &optional
-          keep-other
-     These functions insert the suffix or group SUFFIX into PREFIX
-     before or after LOC.
-
-     Conceptually adding a binding to a transient prefix is similar to
-     adding a binding to a keymap, but this is complicated by the fact
-     that multiple suffix commands can be bound to the same key,
-     provided they are never active at the same time, see *note
-     Predicate Slots::.
-
-     Unfortunately both false-positives and false-negatives are
-     possible.  To deal with the former use non-‘nil’ KEEP-OTHER.  To
-     deal with the latter remove the conflicting binding explicitly.
-
- -- 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
-
-4 Defining New Commands
-***********************
-
-* Menu:
-
-* Technical Introduction::
-* Defining Transients::
-* Binding Suffix and Infix Commands::
-* Defining Suffix and Infix Commands::
-* Using Infix Arguments::
-* Transient State::
-
-\1f
-File: transient.info,  Node: Technical Introduction,  Next: Defining Transients,  Up: Defining New Commands
-
-4.1 Technical Introduction
-==========================
-
-Taking inspiration from prefix keys and prefix arguments, Transient
-implements a similar abstraction involving a prefix command, infix
-arguments and suffix commands.
-
-   When the user calls a transient prefix command, 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 any command can choose to use or ignore the prefix
-arguments.  For a suffix command that was invoked from a transient, the
-variable ‘transient-current-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’.
-
-   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, which can be thought of as a “menus”.  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’ (on ‘C-x M-g’) 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, one can call a command with arguments that are just as
-complex as when calling the same function non-interactively from Lisp.
-
-   Invoking a transient suffix 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).
-
-   Note that suffix commands also support regular prefix arguments.  A
-suffix command may even be called with both infix and prefix arguments
-at the same time.  If you invoke a command as a suffix of a transient
-prefix command, but also want to pass prefix arguments to it, then first
-invoke the prefix command, and only after doing that invoke the prefix
-arguments, before finally invoking the suffix command.  If you instead
-began by providing the prefix arguments, then those would apply to the
-prefix command, not the suffix command.  Likewise, if you want to change
-infix arguments before invoking a suffix command with prefix arguments,
-then change the infix arguments before invoking the prefix arguments.
-In other words, regular prefix arguments always apply to the next
-command, and since transient prefix, infix and suffix commands are just
-regular commands, the same applies to them.  (Regular prefix keys behave
-differently because they are not commands at all, instead they are just
-incomplete key sequences, and those cannot be interrupted with prefix
-commands.)
-
-\1f
-File: transient.info,  Node: Defining Transients,  Next: Binding Suffix and Infix Commands,  Prev: Technical Introduction,  Up: Defining New Commands
-
-4.2 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: transient-define-prefix 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
-
-4.3 Binding Suffix and Infix Commands
-=====================================
-
-The macro ‘transient-define-prefix’ 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 ‘transient-define-prefix’.
-
-* Menu:
-
-* Group Specifications::
-* Suffix Specifications::
-
-\1f
-File: transient.info,  Node: Group Specifications,  Next: Suffix Specifications,  Up: Binding Suffix and Infix Commands
-
-4.3.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 ‘transient-define-prefix’, 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::.
-
-   • 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 value of ‘:setup-children’, if non-‘nil’, is a function that
-     takes one argument, a potentially list of children, and must return
-     a list of children or an empty list.  This can either be used to
-     somehow transform the group’s children that were defined the normal
-     way, or to dynamically create the children from scratch.
-
-     The returned children must have the same form as stored in the
-     prefix’s ‘transient--layout’ property, but it is often more
-     convenient to use the same form as understood by
-     ‘transient-define-prefix’, described below.  If you use the latter
-     approach, you can use the ‘transient-parse-suffixes’ and
-     ‘transient-parse-suffix’ functions to transform them from the
-     convenient to the expected form.  Depending on the used group
-     class, ‘transient-parse-suffixes’’s SUFFIXES must be a list of
-     group vectors (for ‘transient-columns’) or a list of suffix lists
-     (for all other group classes).
-
-     If you explicitly specify children and then transform them using
-     ‘:setup-children’, then the class of the group is determined as
-     usual, based on explicitly specified children.
-
-     If you do not explicitly specify children and thus rely solely on
-     ‘:setup-children’, then you must specify the class using ‘:class’.
-     For backward compatibility, if you fail to do so,
-     ‘transient-column’ is used and a warning is displayed.  This
-     warning will eventually be replaced with an error.
-
-          (transient-define-prefix my-finder-by-keyword ()
-            "Select a keyword and list matching packages."
-            ;; The real `finder-by-keyword' is more convenient
-            ;; of course, but that is not the point here.
-            [:class transient-columns
-             :setup-children
-             (lambda (_)
-               (transient-parse-suffixes
-                'my-finder-by-keyword
-                (let ((char (1- ?A)))
-                  (mapcar                  ; a list ...
-                   (lambda (partition)
-                     (vconcat              ; of group vectors ...
-                      (mapcar (lambda (elt)
-                                (let ((keyword (symbol-name (car elt))))
-                                           ; ... where each suffix is a list
-                                  (list (format "%c" (cl-incf char))
-                                        keyword
-                                        (lambda ()
-                                          (interactive)
-                                          (finder-list-matches keyword)))))
-                              partition)))
-                   (seq-partition finder-known-keywords 7)))))])
-
-   • The boolean ‘:pad-keys’ argument controls whether keys of all
-     suffixes contained in a group are right padded, effectively
-     aligning the descriptions.
-
-   The ELEMENTs are either all subgroups, or all suffixes and strings.
-(At least currently no group type exists that would allow mixing
-subgroups with commands at the same level, though in principle there is
-nothing that prevents that.)
-
-   If the ELEMENTs are not subgroups, then they can be a mixture of
-lists, which specify commands, and strings.  Strings are inserted
-verbatim into the buffer.  The empty string can be used to insert gaps
-between suffixes, which is particularly useful if the suffixes are
-outlined as a table.
-
-   Inside group specifications, including inside contained suffix
-specifications, nothing has to be quoted and quoting anyway is invalid.
-The value following a keyword, can be explicitly unquoted using ‘,’.
-This feature is experimental and should be avoided.
-
-   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
-
-4.3.2 Suffix Specifications
----------------------------
-
-A transient’s suffix and infix commands are bound when the transient
-prefix command is defined using ‘transient-define-prefix’, 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
-     takes zero or one arguments (the suffix object) and 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 should be a symbol that is bound as a function, which has
-     to be defined or at least autoloaded as a command by the time the
-     containing prefix command is invoked.
-
-     Any command will do; it does not need to have an object associated
-     with it (as would be the case if ‘transient-define-suffix’ or
-     ‘transient-define-infix’ were used to define it).
-
-     COMMAND can also be a ‘lambda’ expression.
-
-     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.
-
-     As a special case, if you want to add a command that might be
-     neither defined nor autoloaded, you can use a workaround like:
-
-          (transient-insert-suffix 'some-prefix "k"
-            '("!" "Ceci n'est pas une commande" no-command
-              :if (lambda () (featurep 'no-library))))
-
-     Instead of ‘featurep’ you could also use ‘require’ with a non-‘nil’
-     value for NOERROR.
-
-   • 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
-
-4.4 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: transient-define-suffix 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: transient-define-infix 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.
-
-     At least one key-value pair is required.  All transient infix
-     commands are ‘equal’ to each other (but not ‘eq’).  It is
-     meaningless to define an infix command, without providing at least
-     one keyword argument (usually ‘:argument’ or ‘:variable’, depending
-     on the class).  The suffix class defaults to ‘transient-switch’ and
-     can be set using the ‘:class’ keyword.
-
-     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-define-suffix’ to define the infix command
-     and use ‘t’ as the value of the ‘:transient’ keyword.
-
- -- Macro: transient-define-argument name arglist [docstring] [keyword
-          value]...
-     This macro defines NAME as a transient infix command.
-
-     This is an alias for ‘transient-define-infix’.  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
-     ‘transient-define-infix’ instead.
-
-\1f
-File: transient.info,  Node: Using Infix Arguments,  Next: Transient State,  Prev: Defining Suffix and Infix Commands,  Up: Defining New Commands
-
-4.5 Using Infix Arguments
-=========================
-
-The functions 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 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.
-
- -- Function: transient-arg-value arg args
-     This function return the value of ARG as it appears in ARGS.
-
-     For a switch a boolean is returned.  For an option the value is
-     returned as a string, using the empty string for the empty value,
-     or ‘nil’ if the option does not appear in ARGS.
-
- -- Function: transient-suffixes prefix
-     This function returns the suffixes of the transient prefix command
-     PREFIX.  This is a list of objects.  This function should only be
-     used if you need the objects (as opposed to just their values) and
-     if the current command is not being invoked from PREFIX.
-
- -- Variable: transient-current-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: transient-current-command
-     The transient from which this suffix command was invoked.  The
-     returned value is a symbol, the transient prefix command.
-
- -- Variable: transient-current-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: transient-active-prefix
-     This function returns the active transient object.  Return ‘nil’ if
-     there is no active transient, if the transient buffer isn’t shown,
-     and while the active transient is suspended (e.g., while the
-     minibuffer is in use).
-
-     Unlike ‘transient-current-prefix’, which is only ever non-‘nil’ in
-     code that is run directly by a command that is invoked while a
-     transient is current, this function is also suitable for use in
-     asynchronous code, such as timers and callbacks (this function’s
-     main use-case).
-
-     If optional PREFIXES is non-‘nil’, it must be a list of prefix
-     command symbols, in which case the active transient object is only
-     returned if it matches one of the PREFIXES."
-
-\1f
-File: transient.info,  Node: Transient State,  Prev: Using Infix Arguments,  Up: Defining New Commands
-
-4.6 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.
-
-   The behavior can be changed for all suffixes of a particular prefix
-and/or for individual suffixes.  The values should nearly always be
-booleans, but certain functions, called “pre-commands”, can also be
-used.  These functions are named ‘transient--do-VERB’, and the symbol
-‘VERB’ can be used as a shorthand.
-
-   A boolean is interpreted as answering the question "does the
-transient stay active, when this command is invoked?"  ‘t’ means that
-the transient stays active, while ‘nil’ means that invoking the command
-exits the transient.
-
-   Note that when the suffix is a “sub-prefix”, invoking that command
-always activates that sub-prefix, causing the outer prefix to no longer
-be active and displayed.  Here ‘t’ means that when you exit the inner
-prefix, then the outer prefix becomes active again, while ‘nil’ means
-that all outer prefixes are exited at once.
-
-   • The behavior for non-suffixes can be set for a particular prefix,
-     by the prefix’s ‘transient-non-suffix’ slot to a boolean, a
-     suitable pre-command function, or a shorthand for such a function.
-     See *note Pre-commands for Non-Suffixes::.
-
-   • The common behavior for the suffixes of a particular prefix can be
-     set using the prefix’s ‘transient-suffixes’ slot.
-
-     The value specified in this slot does *not* affect infixes.
-     Because it affects both regular suffixes as well as sub-prefixes,
-     which have different needs, it is best to avoid explicitly
-     specifying a function.
-
-   • The behavior of an individual suffix can be changed using its
-     ‘transient’ slot.  While it is usually best to use a boolean, for
-     this slot it can occasionally make sense to specify a function
-     explicitly.
-
-     Note that this slot can be set when defining a suffix command using
-     ‘transient-define-suffix’ and/or in the definition of the prefix.
-     If set in both places, then the latter takes precedence, as usual.
-
-   The available pre-command functions are documented in the following
-sub-sections.  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’.
-
-   For completeness sake, some notes about complications:
-
-   • 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 prefix’s ‘transient-suffix’ slot, but not
-     the suffix’s ‘transient’ slot.
-
-   • While a sub-prefix is active we nearly always want ‘C-g’ to take
-     the user back to the “super-prefix”, even when the other suffixes
-     don’t do that.  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 ‘nil’ and the slot being
-     unbound are treated as 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.
-
-Pre-commands for Infixes
-------------------------
-
-The default for infixes is ‘transient--do-stay’.  This is also the only
-function that makes sense for infixes, which is why this predicate is
-used even if the value of the prefix’s ‘transient-suffix’ slot is ‘t’.
-In extremely rare cases, one might want to use something else, which can
-be done by setting the infix’s ‘transient’ slot directly.
-
- -- Function: transient--do-stay
-     Call the command without exporting variables and stay transient.
-
-Pre-commands for Suffixes
--------------------------
-
-By default, invoking a suffix causes the transient to be exited.
-
-   The behavior for an individual suffix command can be changed by
-setting its ‘transient’ slot to a boolean (which is highly recommended),
-or to one of the following pre-commands.
-
- -- Function: transient--do-exit
-     Call the command after exporting variables and exit the transient.
-
- -- Function: transient--do-return
-     Call the command after exporting variables and return to the parent
-     prefix.  If there is no parent prefix, then call
-     ‘transient--do-exit’.
-
- -- Function: transient--do-call
-     Call the command after exporting variables and stay transient.
-
-   The following pre-commands are only suitable for sub-prefixes.  It is
-not necessary to explicitly use these predicates because the correct
-predicate is automatically picked based on the value of the ‘transient’
-slot for the sub-prefix itself.
-
- -- Function: transient--do-recurse
-     Call the transient prefix command, preparing for return to active
-     transient.
-
-     Whether we actually return to the parent transient is ultimately
-     under the control of each invoked suffix.  The difference between
-     this pre-command and ‘transient--do-stack’ is that it changes the
-     value of the ‘transient-suffix’ slot to ‘t’.
-
-     If there is no parent transient, then only call this command and
-     skip the second step.
-
- -- Function: transient--do-stack
-     Call the transient prefix command, stacking the active transient.
-     Push the active transient to the transient stack.
-
-     Unless ‘transient--do-recurse’ is explicitly used, this pre-command
-     is automatically used for suffixes that are prefixes themselves,
-     i.e., for sub-prefixes.
-
- -- Function: transient--do-replace
-     Call the transient prefix command, replacing the active transient.
-     Do not push the active transient to the transient stack.
-
-     Unless ‘transient--do-recurse’ is explicitly used, this pre-command
-     is automatically used for suffixes that are prefixes themselves,
-     i.e., for sub-prefixes.
-
- -- Function: transient--do-suspend
-     Suspend the active transient, saving the transient stack.
-
-     This is used by the command ‘transient-suspend’ and optionally also
-     by “external events” such as ‘handle-switch-frame’.  Such bindings
-     should be added to ‘transient-predicate-map’.
-
-Pre-commands for Non-Suffixes
------------------------------
-
-By default, non-suffixes (commands that are bound in other keymaps
-beside the transient keymap) cannot be invoked.  Trying to invoke such a
-command results in a warning and the transient stays active.
-
-   If you want a different behavior, then set the ‘transient-non-suffix’
-slot of the transient prefix command.  The value should be a boolean,
-answering the question, "is it allowed to invoke non-suffix commands?, a
-pre-command function, or a shorthand for such a function.
-
-   If the value is ‘t’, then non-suffixes can be invoked, when it is
-‘nil’ (the default) then they cannot be invoked.
-
-   The only other recommended value is ‘leave’.  If that is used, then
-non-suffixes can be invoked, but if one is invoked, then that exits the
-transient.
-
- -- Function: transient--do-warn
-     Call ‘transient-undefined’ and stay transient.
-
- -- Function: transient--do-stay
-     Call the command without exporting variables and stay transient.
-
- -- Function: transient--do-leave
-     Call the command without exporting variables and exit the
-     transient.
-
-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: FAQ,  Prev: Defining New Commands,  Up: Top
-
-5 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
-
-5.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 ‘transient-define-prefix’.
-
-   • 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 (or “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
-
-5.2 Group Methods
-=================
-
- -- Function: transient-setup-children group children
-     This generic function can be used to setup the children or a group.
-
-     The default implementation usually just returns the children
-     unchanged, but if the ‘setup-children’ slot of GROUP is non-‘nil’,
-     then it calls that function with CHILDREN as the only argument and
-     returns the value.
-
-     The children are given as a (potentially empty) list consisting of
-     either group or suffix specifications.  These functions can make
-     arbitrary changes to the children including constructing new
-     children from scratch.
-
- -- 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
-     temporarily 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
-
-5.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
-
-5.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-variable’ class.
-
-   • The ‘transient-information’ class is special in that suffixes that
-     use this class are not associated with a command and thus also not
-     with any key binding.  Such suffixes are only used to display
-     arbitrary information, and that anywhere a suffix can appear.
-     Display-only suffix specifications take this form:
-
-          ([LEVEL] :info DESCRIPTION [KEYWORD VALUE]...)
-
-     The ‘:info’ keyword argument replaces the ‘:description’ keyword
-     used for other suffix classes.  Other keyword arguments that you
-     might want to set, include ‘:face’, predicate keywords (such as
-     ‘:if’), and ‘:format’.  By default the value of ‘:format’ includes
-     ‘%k’, which for this class is replaced with the empty string or
-     spaces, if keys are being padded in the containing group.
-
-   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
-
-5.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
-
-5.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
-
-5.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
-     documentation string.
-
-     For suffixes, show the command’s documentation string.
-
-     For infixes, show the manpage if that is specified.  Otherwise show
-     the command’s documentation string.
-
-\1f
-File: transient.info,  Node: Prefix Slots,  Next: Suffix Slots,  Prev: Suffix Methods,  Up: Classes and Methods
-
-5.6 Prefix Slots
-================
-
-   • ‘show-help’, ‘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 arbitrary non-suffix
-     command is invoked.  See *note Transient State::.
-
-   • ‘refresh-suffixes’ Normally suffix objects and keymaps are only
-     setup once, when the prefix is invoked.  Setting this to ‘t’,
-     causes them to be recreated after every command.  This is useful
-     when using ‘:if...’ predicates, and those need to be rerun for some
-     reason.  Doing this is somewhat costly, and there is a risk of
-     losing state, so this is disabled by default and still considered
-     experimental.
-
-   • ‘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.  An argument may appear in
-     multiple sub-lists.  Arguments must me given in the same form as
-     used in the ‘argument’ or ‘argument-format’ slot of the respective
-     suffix objects, usually something like ‘--switch’ or ‘--option=%s’.
-     For options and ‘transient-switches’ suffixes it is also possible
-     to match against a specific value, as returned by
-     ‘transient-infix-value’, for example, ‘--option=one’.
-
-   • ‘scope’ For some transients it might be necessary to have a sort of
-     secondary value, called a “scope”.  See ‘transient-define-prefix’.
-
-Internal Prefix Slots
----------------------
-
-These slots are mostly intended for internal use.  They should not be
-set in calls to ‘transient-define-prefix’.
-
-   • ‘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
-
-5.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::.
-
-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, which
-     is called with zero or one argument (the suffix object), and
-     returns a string.
-
-   • ‘face’ Face used for the description.  In simple cases it is easier
-     to use this instead of using a function as ‘description’ and adding
-     the styling there.  ‘face’ is appended using
-     ‘add-face-text-property’.
-
-   • ‘show-help’ A function used to display help for the suffix.  If
-     unspecified, the prefix controls how help is displayed for its
-     suffixes.
-
-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’.
-
-   • ‘value’ The value.  Should not be accessed directly.
-
-   • ‘init-value’ Function that is responsible for setting the object’s
-     value.  If bound, then this is called with the object as the only
-     argument.  Usually this is not bound, in which case the object’s
-     primary ‘transient-init-value’ method is called instead.
-
-   • ‘unsavable’ Whether the value of the suffix is not saved as part of
-     the prefixes.
-
-   • ‘multi-value’ For options, whether the option can have multiple
-     values.  If this is non-‘nil’, then the values are read using
-     ‘completing-read-multiple’ by default and if you specify your own
-     reader, then it should read the values using that function or
-     similar.
-
-     Supported non-‘nil’ values are:
-
-        • Use ‘rest’ for an option that can have multiple values.  This
-          is useful e.g., for an ‘--’ argument that indicates that all
-          remaining arguments are files (such as ‘git log -- file1
-          file2’).
-
-          In the list returned by ‘transient-args’ such an option and
-          its values are represented by a single list of the form
-          ‘(ARGUMENT . VALUES)’.
-
-        • Use ‘repeat’ for an option that can be specified multiple
-          times.
-
-          In the list returned by ‘transient-args’ each instance of the
-          option and its value appears separately in the usual from, for
-          example: ‘("--another-argument" "--option=first"
-          "--option=second")’.
-
-     In both cases the option’s values have to be specified in the
-     default value of a prefix using the same format as returned by
-     ‘transient-args’, e.g., ‘("--other" "--o=1" "--o=2" ("--" "f1"
-     "f2"))’.
-
-   • ‘always-read’ For options, whether to read a value on every
-     invocation.  If this is ‘nil’, then options that have a value are
-     simply unset and have to be invoked a second time to set a new
-     value.
-
-   • ‘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, or a function that returns such a
-     list.  The latter is not implemented for ‘transient-switches’,
-     because I couldn’t think of a use-case.  How exactly the choices
-     are used varies depending on the class of the suffix.
-
-Slots of ‘transient-variable’
------------------------------
-
-   • ‘variable’ The variable.
-
-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
-
-5.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.
-
-   By default these predicates run when the prefix command is invoked,
-but this can be changes, using the ‘refresh-suffixes’ prefix slot.  See
-*note Prefix Slots::.
-
-   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: FAQ,  Next: Keystroke Index,  Prev: Classes and Methods,  Up: Top
-
-Appendix A FAQ
-**************
-
-A.1 Can I control how the popup buffer is displayed?
-====================================================
-
-Yes, see ‘transient-display-buffer-action’ in *note Configuration::.
-
-A.2 How can I copy text from the popup buffer?
-==============================================
-
-To be able to mark text in Transient’s popup buffer using the mouse, you
-have to add the below binding.  Note that for technical reasons, the
-region won’t be visualized, while doing so.  After you have quit the
-transient popup, you will be able to yank it in another buffer.
-
-     (keymap-set transient-predicate-map
-                 "<mouse-set-region>"
-                 #'transient--do-stay)
-
-A.3 How can I autoload prefix and suffix commands?
-==================================================
-
-If your package only supports Emacs 30, just prefix the definition with
-‘;;;###autoload’.  If your package supports released versions of Emacs,
-you unfortunately have to use a long form autoload comment as described
-in *note (elisp)Autoload::.
-
-     ;;;###autoload (autoload 'magit-dispatch "magit" nil t)
-     (transient-define-prefix magit-dispatch ()
-       ...)
-
-A.4 How does Transient compare to prefix keys and universal arguments?
-======================================================================
-
-See
-<https://github.com/magit/transient/wiki/Comparison-with-prefix-keys-and-universal-arguments>.
-
-A.5 How does Transient compare to Magit-Popup and Hydra?
-========================================================
-
-See
-<https://github.com/magit/transient/wiki/Comparison-with-other-packages>.
-
-A.6 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 bindings that begin with the ‘C-x’ prefix 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.7 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 documentation string for more information.
-
-\1f
-File: transient.info,  Node: Keystroke Index,  Next: Command and Function Index,  Prev: FAQ,  Up: Top
-
-Appendix B Keystroke Index
-**************************
-
-\0\b[index\0\b]
-* Menu:
-
-* C-g:                                   Aborting and Resuming Transients.
-                                                               (line 27)
-* C-g <1>:                               Aborting and Resuming Transients.
-                                                               (line 27)
-* C-h:                                   Getting Help for Suffix Commands.
-                                                               (line 11)
-* C-M-n:                                 Using History.        (line 18)
-* C-M-p:                                 Using History.        (line 13)
-* C-q:                                   Aborting and Resuming Transients.
-                                                               (line 36)
-* C-x a:                                 Enabling and Disabling Suffixes.
-                                                               (line 68)
-* C-x C-k:                               Saving Values.        (line 29)
-* C-x C-s:                               Saving Values.        (line 25)
-* C-x l:                                 Enabling and Disabling Suffixes.
-                                                               (line 43)
-* C-x n:                                 Using History.        (line 18)
-* C-x p:                                 Using History.        (line 13)
-* C-x s:                                 Saving Values.        (line 21)
-* C-x t:                                 Common Suffix Commands.
-                                                               (line 18)
-* C-z:                                   Aborting and Resuming Transients.
-                                                               (line 41)
-
-\1f
-File: transient.info,  Node: Command and Function Index,  Next: Variable Index,  Prev: Keystroke Index,  Up: Top
-
-Appendix C Command and Function Index
-*************************************
-
-\0\b[index\0\b]
-* Menu:
-
-* transient--do-call:                    Transient State.     (line 125)
-* transient--do-exit:                    Transient State.     (line 117)
-* transient--do-leave:                   Transient State.     (line 193)
-* transient--do-quit-all:                Transient State.     (line 205)
-* transient--do-quit-one:                Transient State.     (line 200)
-* transient--do-recurse:                 Transient State.     (line 133)
-* transient--do-replace:                 Transient State.     (line 153)
-* transient--do-return:                  Transient State.     (line 120)
-* transient--do-stack:                   Transient State.     (line 145)
-* transient--do-stay:                    Transient State.     (line 105)
-* transient--do-stay <1>:                Transient State.     (line 190)
-* transient--do-suspend:                 Transient State.     (line 161)
-* transient--do-suspend <1>:             Transient State.     (line 210)
-* transient--do-warn:                    Transient State.     (line 187)
-* transient--history-init:               Prefix Classes.      (line  10)
-* transient--insert-group:               Group Methods.       (line  19)
-* transient-append-suffix:               Modifying Existing Transients.
-                                                              (line  51)
-* transient-arg-value:                   Using Infix Arguments.
-                                                              (line  31)
-* transient-args:                        Using Infix Arguments.
-                                                              (line  22)
-* transient-define-argument:             Defining Suffix and Infix Commands.
-                                                              (line  57)
-* transient-define-infix:                Defining Suffix and Infix Commands.
-                                                              (line  26)
-* transient-define-prefix:               Defining Transients. (line  13)
-* transient-define-suffix:               Defining Suffix and Infix Commands.
-                                                              (line   9)
-* transient-format:                      Suffix Format Methods.
-                                                              (line   6)
-* transient-format-description:          Suffix Format Methods.
-                                                              (line  18)
-* transient-format-key:                  Suffix Format Methods.
-                                                              (line  14)
-* transient-format-value:                Suffix Format Methods.
-                                                              (line  22)
-* transient-get-suffix:                  Modifying Existing Transients.
-                                                              (line  73)
-* transient-help:                        Getting Help for Suffix Commands.
-                                                              (line  11)
-* transient-history-next:                Using History.       (line  18)
-* transient-history-prev:                Using History.       (line  13)
-* transient-infix-read:                  Suffix Value Methods.
-                                                              (line  16)
-* transient-infix-set:                   Suffix Value Methods.
-                                                              (line  36)
-* transient-infix-value:                 Suffix Value Methods.
-                                                              (line  39)
-* transient-init-scope:                  Suffix Value Methods.
-                                                              (line  52)
-* transient-init-value:                  Suffix Value Methods.
-                                                              (line   6)
-* transient-insert-suffix:               Modifying Existing Transients.
-                                                              (line  49)
-* transient-prompt:                      Suffix Value Methods.
-                                                              (line  32)
-* transient-quit-all:                    Aborting and Resuming Transients.
-                                                              (line  36)
-* transient-quit-one:                    Aborting and Resuming Transients.
-                                                              (line  27)
-* transient-quit-seq:                    Aborting and Resuming Transients.
-                                                              (line  27)
-* transient-remove-suffix:               Modifying Existing Transients.
-                                                              (line  70)
-* transient-replace-suffix:              Modifying Existing Transients.
-                                                              (line  66)
-* transient-reset:                       Saving Values.       (line  29)
-* transient-resume:                      Aborting and Resuming Transients.
-                                                              (line  53)
-* transient-save:                        Saving Values.       (line  25)
-* transient-scroll-down:                 Other Commands.      (line  17)
-* transient-scroll-up:                   Other Commands.      (line  12)
-* transient-set:                         Saving Values.       (line  21)
-* transient-set-level:                   Enabling and Disabling Suffixes.
-                                                              (line  43)
-* transient-setup-children:              Group Methods.       (line   6)
-* transient-show-help:                   Suffix Format Methods.
-                                                              (line  26)
-* transient-suffix-put:                  Modifying Existing Transients.
-                                                              (line  77)
-* transient-suffixes:                    Using Infix Arguments.
-                                                              (line  38)
-* transient-suspend:                     Aborting and Resuming Transients.
-                                                              (line  41)
-* transient-toggle-common:               Common Suffix Commands.
-                                                              (line  18)
-* transient-toggle-level-limit:          Enabling and Disabling Suffixes.
-                                                              (line  68)
-
-\1f
-File: transient.info,  Node: Variable Index,  Next: Concept Index,  Prev: Command and Function Index,  Up: Top
-
-Appendix D Variable Index
-*************************
-
-\0\b[index\0\b]
-* Menu:
-
-* transient-active-prefix:               Using Infix Arguments.
-                                                              (line  61)
-* transient-align-variable-pitch:        Configuration.       (line 185)
-* transient-current-command:             Using Infix Arguments.
-                                                              (line  52)
-* transient-current-prefix:              Using Infix Arguments.
-                                                              (line  56)
-* transient-current-suffixes:            Using Infix Arguments.
-                                                              (line  44)
-* transient-default-level:               Enabling and Disabling Suffixes.
-                                                              (line  33)
-* transient-detect-key-conflicts:        Configuration.       (line 210)
-* transient-display-buffer-action:       Configuration.       (line  51)
-* transient-enable-popup-navigation:     Configuration.       (line  36)
-* transient-force-fixed-pitch:           Configuration.       (line 198)
-* transient-force-single-column:         Configuration.       (line  93)
-* transient-hide-during-minibuffer-read: Configuration.       (line 181)
-* transient-highlight-higher-levels:     Configuration.       (line 223)
-* transient-highlight-mismatched-keys:   Configuration.       (line 135)
-* transient-history-file:                Using History.       (line  33)
-* transient-history-limit:               Using History.       (line  37)
-* transient-levels-file:                 Enabling and Disabling Suffixes.
-                                                              (line  38)
-* transient-mode-line-format:            Configuration.       (line 102)
-* transient-read-with-initial-input:     Configuration.       (line 174)
-* transient-semantic-coloring:           Configuration.       (line 126)
-* transient-show-common-commands:        Common Suffix Commands.
-                                                              (line  23)
-* transient-show-popup:                  Configuration.       (line  15)
-* transient-substitute-key-function:     Configuration.       (line 153)
-* transient-values-file:                 Saving Values.       (line  31)
-
-\1f
-File: transient.info,  Node: Concept Index,  Next: GNU General Public License,  Prev: Variable Index,  Up: Top
-
-Appendix E Concept Index
-************************
-
-\0\b[index\0\b]
-* Menu:
-
-* aborting transients:                   Aborting and Resuming Transients.
-                                                               (line  6)
-* classes and methods:                   Classes and Methods.  (line  6)
-* command dispatchers:                   Technical Introduction.
-                                                               (line 39)
-* common suffix commands:                Common Suffix Commands.
-                                                               (line  6)
-* defining infix commands:               Defining Suffix and Infix Commands.
-                                                               (line  6)
-* defining suffix commands:              Defining Suffix and Infix Commands.
-                                                               (line  6)
-* disabling suffixes:                    Enabling and Disabling Suffixes.
-                                                               (line  6)
-* enabling suffixes:                     Enabling and Disabling Suffixes.
-                                                               (line  6)
-* getting help:                          Getting Help for Suffix Commands.
-                                                               (line  6)
-* group specifications:                  Group Specifications. (line  6)
-* invoking transients:                   Invoking Transients.  (line  6)
-* levels:                                Enabling and Disabling Suffixes.
-                                                               (line 10)
-* modifying existing transients:         Modifying Existing Transients.
-                                                               (line  6)
-* quit transient:                        Aborting and Resuming Transients.
-                                                               (line  6)
-* resuming transients:                   Aborting and Resuming Transients.
-                                                               (line  6)
-* saving values of arguments:            Saving Values.        (line  6)
-* scope of a transient:                  Defining Transients.  (line 43)
-* suffix specifications:                 Suffix Specifications.
-                                                               (line  6)
-* transient state:                       Transient State.      (line  6)
-* transient-level:                       Enabling and Disabling Suffixes.
-                                                               (line 15)
-* value history:                         Using History.        (line  6)
-
-\1f
-File: transient.info,  Node: GNU General Public License,  Prev: Concept Index,  Up: Top
-
-Appendix F GNU General Public License
-*************************************
-
-                        Version 3, 29 June 2007
-
-     Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
-
-     Everyone is permitted to copy and distribute verbatim copies of this
-     license document, but changing it is not allowed.
-
-Preamble
-========
-
-The GNU General Public License is a free, copyleft license for software
-and other kinds of works.
-
-   The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program—to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-   When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-   To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-   For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-   Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-   For the developers’ and authors’ protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users’ and
-authors’ sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-   Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users’ freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-   Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-   The precise terms and conditions for copying, distribution and
-modification follow.
-
-TERMS AND CONDITIONS
-====================
-
-  0. Definitions.
-
-     “This License” refers to version 3 of the GNU General Public
-     License.
-
-     “Copyright” also means copyright-like laws that apply to other
-     kinds of works, such as semiconductor masks.
-
-     “The Program” refers to any copyrightable work licensed under this
-     License.  Each licensee is addressed as “you”.  “Licensees” and
-     “recipients” may be individuals or organizations.
-
-     To “modify” a work means to copy from or adapt all or part of the
-     work in a fashion requiring copyright permission, other than the
-     making of an exact copy.  The resulting work is called a “modified
-     version” of the earlier work or a work “based on” the earlier work.
-
-     A “covered work” means either the unmodified Program or a work
-     based on the Program.
-
-     To “propagate” a work means to do anything with it that, without
-     permission, would make you directly or secondarily liable for
-     infringement under applicable copyright law, except executing it on
-     a computer or modifying a private copy.  Propagation includes
-     copying, distribution (with or without modification), making
-     available to the public, and in some countries other activities as
-     well.
-
-     To “convey” a work means any kind of propagation that enables other
-     parties to make or receive copies.  Mere interaction with a user
-     through a computer network, with no transfer of a copy, is not
-     conveying.
-
-     An interactive user interface displays “Appropriate Legal Notices”
-     to the extent that it includes a convenient and prominently visible
-     feature that (1) displays an appropriate copyright notice, and (2)
-     tells the user that there is no warranty for the work (except to
-     the extent that warranties are provided), that licensees may convey
-     the work under this License, and how to view a copy of this
-     License.  If the interface presents a list of user commands or
-     options, such as a menu, a prominent item in the list meets this
-     criterion.
-
-  1. Source Code.
-
-     The “source code” for a work means the preferred form of the work
-     for making modifications to it.  “Object code” means any non-source
-     form of a work.
-
-     A “Standard Interface” means an interface that either is an
-     official standard defined by a recognized standards body, or, in
-     the case of interfaces specified for a particular programming
-     language, one that is widely used among developers working in that
-     language.
-
-     The “System Libraries” of an executable work include anything,
-     other than the work as a whole, that (a) is included in the normal
-     form of packaging a Major Component, but which is not part of that
-     Major Component, and (b) serves only to enable use of the work with
-     that Major Component, or to implement a Standard Interface for
-     which an implementation is available to the public in source code
-     form.  A “Major Component”, in this context, means a major
-     essential component (kernel, window system, and so on) of the
-     specific operating system (if any) on which the executable work
-     runs, or a compiler used to produce the work, or an object code
-     interpreter used to run it.
-
-     The “Corresponding Source” for a work in object code form means all
-     the source code needed to generate, install, and (for an executable
-     work) run the object code and to modify the work, including scripts
-     to control those activities.  However, it does not include the
-     work’s System Libraries, or general-purpose tools or generally
-     available free programs which are used unmodified in performing
-     those activities but which are not part of the work.  For example,
-     Corresponding Source includes interface definition files associated
-     with source files for the work, and the source code for shared
-     libraries and dynamically linked subprograms that the work is
-     specifically designed to require, such as by intimate data
-     communication or control flow between those subprograms and other
-     parts of the work.
-
-     The Corresponding Source need not include anything that users can
-     regenerate automatically from other parts of the Corresponding
-     Source.
-
-     The Corresponding Source for a work in source code form is that
-     same work.
-
-  2. Basic Permissions.
-
-     All rights granted under this License are granted for the term of
-     copyright on the Program, and are irrevocable provided the stated
-     conditions are met.  This License explicitly affirms your unlimited
-     permission to run the unmodified Program.  The output from running
-     a covered work is covered by this License only if the output, given
-     its content, constitutes a covered work.  This License acknowledges
-     your rights of fair use or other equivalent, as provided by
-     copyright law.
-
-     You may make, run and propagate covered works that you do not
-     convey, without conditions so long as your license otherwise
-     remains in force.  You may convey covered works to others for the
-     sole purpose of having them make modifications exclusively for you,
-     or provide you with facilities for running those works, provided
-     that you comply with the terms of this License in conveying all
-     material for which you do not control copyright.  Those thus making
-     or running the covered works for you must do so exclusively on your
-     behalf, under your direction and control, on terms that prohibit
-     them from making any copies of your copyrighted material outside
-     their relationship with you.
-
-     Conveying under any other circumstances is permitted solely under
-     the conditions stated below.  Sublicensing is not allowed; section
-     10 makes it unnecessary.
-
-  3. Protecting Users’ Legal Rights From Anti-Circumvention Law.
-
-     No covered work shall be deemed part of an effective technological
-     measure under any applicable law fulfilling obligations under
-     article 11 of the WIPO copyright treaty adopted on 20 December
-     1996, or similar laws prohibiting or restricting circumvention of
-     such measures.
-
-     When you convey a covered work, you waive any legal power to forbid
-     circumvention of technological measures to the extent such
-     circumvention is effected by exercising rights under this License
-     with respect to the covered work, and you disclaim any intention to
-     limit operation or modification of the work as a means of
-     enforcing, against the work’s users, your or third parties’ legal
-     rights to forbid circumvention of technological measures.
-
-  4. Conveying Verbatim Copies.
-
-     You may convey verbatim copies of the Program’s source code as you
-     receive it, in any medium, provided that you conspicuously and
-     appropriately publish on each copy an appropriate copyright notice;
-     keep intact all notices stating that this License and any
-     non-permissive terms added in accord with section 7 apply to the
-     code; keep intact all notices of the absence of any warranty; and
-     give all recipients a copy of this License along with the Program.
-
-     You may charge any price or no price for each copy that you convey,
-     and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-     You may convey a work based on the Program, or the modifications to
-     produce it from the Program, in the form of source code under the
-     terms of section 4, provided that you also meet all of these
-     conditions:
-
-       a. The work must carry prominent notices stating that you
-          modified it, and giving a relevant date.
-
-       b. The work must carry prominent notices stating that it is
-          released under this License and any conditions added under
-          section 7.  This requirement modifies the requirement in
-          section 4 to “keep intact all notices”.
-
-       c. You must license the entire work, as a whole, under this
-          License to anyone who comes into possession of a copy.  This
-          License will therefore apply, along with any applicable
-          section 7 additional terms, to the whole of the work, and all
-          its parts, regardless of how they are packaged.  This License
-          gives no permission to license the work in any other way, but
-          it does not invalidate such permission if you have separately
-          received it.
-
-       d. If the work has interactive user interfaces, each must display
-          Appropriate Legal Notices; however, if the Program has
-          interactive interfaces that do not display Appropriate Legal
-          Notices, your work need not make them do so.
-
-     A compilation of a covered work with other separate and independent
-     works, which are not by their nature extensions of the covered
-     work, and which are not combined with it such as to form a larger
-     program, in or on a volume of a storage or distribution medium, is
-     called an “aggregate” if the compilation and its resulting
-     copyright are not used to limit the access or legal rights of the
-     compilation’s users beyond what the individual works permit.
-     Inclusion of a covered work in an aggregate does not cause this
-     License to apply to the other parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-     You may convey a covered work in object code form under the terms
-     of sections 4 and 5, provided that you also convey the
-     machine-readable Corresponding Source under the terms of this
-     License, in one of these ways:
-
-       a. Convey the object code in, or embodied in, a physical product
-          (including a physical distribution medium), accompanied by the
-          Corresponding Source fixed on a durable physical medium
-          customarily used for software interchange.
-
-       b. Convey the object code in, or embodied in, a physical product
-          (including a physical distribution medium), accompanied by a
-          written offer, valid for at least three years and valid for as
-          long as you offer spare parts or customer support for that
-          product model, to give anyone who possesses the object code
-          either (1) a copy of the Corresponding Source for all the
-          software in the product that is covered by this License, on a
-          durable physical medium customarily used for software
-          interchange, for a price no more than your reasonable cost of
-          physically performing this conveying of source, or (2) access
-          to copy the Corresponding Source from a network server at no
-          charge.
-
-       c. Convey individual copies of the object code with a copy of the
-          written offer to provide the Corresponding Source.  This
-          alternative is allowed only occasionally and noncommercially,
-          and only if you received the object code with such an offer,
-          in accord with subsection 6b.
-
-       d. Convey the object code by offering access from a designated
-          place (gratis or for a charge), and offer equivalent access to
-          the Corresponding Source in the same way through the same
-          place at no further charge.  You need not require recipients
-          to copy the Corresponding Source along with the object code.
-          If the place to copy the object code is a network server, the
-          Corresponding Source may be on a different server (operated by
-          you or a third party) that supports equivalent copying
-          facilities, provided you maintain clear directions next to the
-          object code saying where to find the Corresponding Source.
-          Regardless of what server hosts the Corresponding Source, you
-          remain obligated to ensure that it is available for as long as
-          needed to satisfy these requirements.
-
-       e. Convey the object code using peer-to-peer transmission,
-          provided you inform other peers where the object code and
-          Corresponding Source of the work are being offered to the
-          general public at no charge under subsection 6d.
-
-     A separable portion of the object code, whose source code is
-     excluded from the Corresponding Source as a System Library, need
-     not be included in conveying the object code work.
-
-     A “User Product” is either (1) a “consumer product”, which means
-     any tangible personal property which is normally used for personal,
-     family, or household purposes, or (2) anything designed or sold for
-     incorporation into a dwelling.  In determining whether a product is
-     a consumer product, doubtful cases shall be resolved in favor of
-     coverage.  For a particular product received by a particular user,
-     “normally used” refers to a typical or common use of that class of
-     product, regardless of the status of the particular user or of the
-     way in which the particular user actually uses, or expects or is
-     expected to use, the product.  A product is a consumer product
-     regardless of whether the product has substantial commercial,
-     industrial or non-consumer uses, unless such uses represent the
-     only significant mode of use of the product.
-
-     “Installation Information” for a User Product means any methods,
-     procedures, authorization keys, or other information required to
-     install and execute modified versions of a covered work in that
-     User Product from a modified version of its Corresponding Source.
-     The information must suffice to ensure that the continued
-     functioning of the modified object code is in no case prevented or
-     interfered with solely because modification has been made.
-
-     If you convey an object code work under this section in, or with,
-     or specifically for use in, a User Product, and the conveying
-     occurs as part of a transaction in which the right of possession
-     and use of the User Product is transferred to the recipient in
-     perpetuity or for a fixed term (regardless of how the transaction
-     is characterized), the Corresponding Source conveyed under this
-     section must be accompanied by the Installation Information.  But
-     this requirement does not apply if neither you nor any third party
-     retains the ability to install modified object code on the User
-     Product (for example, the work has been installed in ROM).
-
-     The requirement to provide Installation Information does not
-     include a requirement to continue to provide support service,
-     warranty, or updates for a work that has been modified or installed
-     by the recipient, or for the User Product in which it has been
-     modified or installed.  Access to a network may be denied when the
-     modification itself materially and adversely affects the operation
-     of the network or violates the rules and protocols for
-     communication across the network.
-
-     Corresponding Source conveyed, and Installation Information
-     provided, in accord with this section must be in a format that is
-     publicly documented (and with an implementation available to the
-     public in source code form), and must require no special password
-     or key for unpacking, reading or copying.
-
-  7. Additional Terms.
-
-     “Additional permissions” are terms that supplement the terms of
-     this License by making exceptions from one or more of its
-     conditions.  Additional permissions that are applicable to the
-     entire Program shall be treated as though they were included in
-     this License, to the extent that they are valid under applicable
-     law.  If additional permissions apply only to part of the Program,
-     that part may be used separately under those permissions, but the
-     entire Program remains governed by this License without regard to
-     the additional permissions.
-
-     When you convey a copy of a covered work, you may at your option
-     remove any additional permissions from that copy, or from any part
-     of it.  (Additional permissions may be written to require their own
-     removal in certain cases when you modify the work.)  You may place
-     additional permissions on material, added by you to a covered work,
-     for which you have or can give appropriate copyright permission.
-
-     Notwithstanding any other provision of this License, for material
-     you add to a covered work, you may (if authorized by the copyright
-     holders of that material) supplement the terms of this License with
-     terms:
-
-       a. Disclaiming warranty or limiting liability differently from
-          the terms of sections 15 and 16 of this License; or
-
-       b. Requiring preservation of specified reasonable legal notices
-          or author attributions in that material or in the Appropriate
-          Legal Notices displayed by works containing it; or
-
-       c. Prohibiting misrepresentation of the origin of that material,
-          or requiring that modified versions of such material be marked
-          in reasonable ways as different from the original version; or
-
-       d. Limiting the use for publicity purposes of names of licensors
-          or authors of the material; or
-
-       e. Declining to grant rights under trademark law for use of some
-          trade names, trademarks, or service marks; or
-
-       f. Requiring indemnification of licensors and authors of that
-          material by anyone who conveys the material (or modified
-          versions of it) with contractual assumptions of liability to
-          the recipient, for any liability that these contractual
-          assumptions directly impose on those licensors and authors.
-
-     All other non-permissive additional terms are considered “further
-     restrictions” within the meaning of section 10.  If the Program as
-     you received it, or any part of it, contains a notice stating that
-     it is governed by this License along with a term that is a further
-     restriction, you may remove that term.  If a license document
-     contains a further restriction but permits relicensing or conveying
-     under this License, you may add to a covered work material governed
-     by the terms of that license document, provided that the further
-     restriction does not survive such relicensing or conveying.
-
-     If you add terms to a covered work in accord with this section, you
-     must place, in the relevant source files, a statement of the
-     additional terms that apply to those files, or a notice indicating
-     where to find the applicable terms.
-
-     Additional terms, permissive or non-permissive, may be stated in
-     the form of a separately written license, or stated as exceptions;
-     the above requirements apply either way.
-
-  8. Termination.
-
-     You may not propagate or modify a covered work except as expressly
-     provided under this License.  Any attempt otherwise to propagate or
-     modify it is void, and will automatically terminate your rights
-     under this License (including any patent licenses granted under the
-     third paragraph of section 11).
-
-     However, if you cease all violation of this License, then your
-     license from a particular copyright holder is reinstated (a)
-     provisionally, unless and until the copyright holder explicitly and
-     finally terminates your license, and (b) permanently, if the
-     copyright holder fails to notify you of the violation by some
-     reasonable means prior to 60 days after the cessation.
-
-     Moreover, your license from a particular copyright holder is
-     reinstated permanently if the copyright holder notifies you of the
-     violation by some reasonable means, this is the first time you have
-     received notice of violation of this License (for any work) from
-     that copyright holder, and you cure the violation prior to 30 days
-     after your receipt of the notice.
-
-     Termination of your rights under this section does not terminate
-     the licenses of parties who have received copies or rights from you
-     under this License.  If your rights have been terminated and not
-     permanently reinstated, you do not qualify to receive new licenses
-     for the same material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-     You are not required to accept this License in order to receive or
-     run a copy of the Program.  Ancillary propagation of a covered work
-     occurring solely as a consequence of using peer-to-peer
-     transmission to receive a copy likewise does not require
-     acceptance.  However, nothing other than this License grants you
-     permission to propagate or modify any covered work.  These actions
-     infringe copyright if you do not accept this License.  Therefore,
-     by modifying or propagating a covered work, you indicate your
-     acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-     Each time you convey a covered work, the recipient automatically
-     receives a license from the original licensors, to run, modify and
-     propagate that work, subject to this License.  You are not
-     responsible for enforcing compliance by third parties with this
-     License.
-
-     An “entity transaction” is a transaction transferring control of an
-     organization, or substantially all assets of one, or subdividing an
-     organization, or merging organizations.  If propagation of a
-     covered work results from an entity transaction, each party to that
-     transaction who receives a copy of the work also receives whatever
-     licenses to the work the party’s predecessor in interest had or
-     could give under the previous paragraph, plus a right to possession
-     of the Corresponding Source of the work from the predecessor in
-     interest, if the predecessor has it or can get it with reasonable
-     efforts.
-
-     You may not impose any further restrictions on the exercise of the
-     rights granted or affirmed under this License.  For example, you
-     may not impose a license fee, royalty, or other charge for exercise
-     of rights granted under this License, and you may not initiate
-     litigation (including a cross-claim or counterclaim in a lawsuit)
-     alleging that any patent claim is infringed by making, using,
-     selling, offering for sale, or importing the Program or any portion
-     of it.
-
-  11. Patents.
-
-     A “contributor” is a copyright holder who authorizes use under this
-     License of the Program or a work on which the Program is based.
-     The work thus licensed is called the contributor’s “contributor
-     version”.
-
-     A contributor’s “essential patent claims” are all patent claims
-     owned or controlled by the contributor, whether already acquired or
-     hereafter acquired, that would be infringed by some manner,
-     permitted by this License, of making, using, or selling its
-     contributor version, but do not include claims that would be
-     infringed only as a consequence of further modification of the
-     contributor version.  For purposes of this definition, “control”
-     includes the right to grant patent sublicenses in a manner
-     consistent with the requirements of this License.
-
-     Each contributor grants you a non-exclusive, worldwide,
-     royalty-free patent license under the contributor’s essential
-     patent claims, to make, use, sell, offer for sale, import and
-     otherwise run, modify and propagate the contents of its contributor
-     version.
-
-     In the following three paragraphs, a “patent license” is any
-     express agreement or commitment, however denominated, not to
-     enforce a patent (such as an express permission to practice a
-     patent or covenant not to sue for patent infringement).  To “grant”
-     such a patent license to a party means to make such an agreement or
-     commitment not to enforce a patent against the party.
-
-     If you convey a covered work, knowingly relying on a patent
-     license, and the Corresponding Source of the work is not available
-     for anyone to copy, free of charge and under the terms of this
-     License, through a publicly available network server or other
-     readily accessible means, then you must either (1) cause the
-     Corresponding Source to be so available, or (2) arrange to deprive
-     yourself of the benefit of the patent license for this particular
-     work, or (3) arrange, in a manner consistent with the requirements
-     of this License, to extend the patent license to downstream
-     recipients.  “Knowingly relying” means you have actual knowledge
-     that, but for the patent license, your conveying the covered work
-     in a country, or your recipient’s use of the covered work in a
-     country, would infringe one or more identifiable patents in that
-     country that you have reason to believe are valid.
-
-     If, pursuant to or in connection with a single transaction or
-     arrangement, you convey, or propagate by procuring conveyance of, a
-     covered work, and grant a patent license to some of the parties
-     receiving the covered work authorizing them to use, propagate,
-     modify or convey a specific copy of the covered work, then the
-     patent license you grant is automatically extended to all
-     recipients of the covered work and works based on it.
-
-     A patent license is “discriminatory” if it does not include within
-     the scope of its coverage, prohibits the exercise of, or is
-     conditioned on the non-exercise of one or more of the rights that
-     are specifically granted under this License.  You may not convey a
-     covered work if you are a party to an arrangement with a third
-     party that is in the business of distributing software, under which
-     you make payment to the third party based on the extent of your
-     activity of conveying the work, and under which the third party
-     grants, to any of the parties who would receive the covered work
-     from you, a discriminatory patent license (a) in connection with
-     copies of the covered work conveyed by you (or copies made from
-     those copies), or (b) primarily for and in connection with specific
-     products or compilations that contain the covered work, unless you
-     entered into that arrangement, or that patent license was granted,
-     prior to 28 March 2007.
-
-     Nothing in this License shall be construed as excluding or limiting
-     any implied license or other defenses to infringement that may
-     otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others’ Freedom.
-
-     If conditions are imposed on you (whether by court order, agreement
-     or otherwise) that contradict the conditions of this License, they
-     do not excuse you from the conditions of this License.  If you
-     cannot convey a covered work so as to satisfy simultaneously your
-     obligations under this License and any other pertinent obligations,
-     then as a consequence you may not convey it at all.  For example,
-     if you agree to terms that obligate you to collect a royalty for
-     further conveying from those to whom you convey the Program, the
-     only way you could satisfy both those terms and this License would
-     be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-     Notwithstanding any other provision of this License, you have
-     permission to link or combine any covered work with a work licensed
-     under version 3 of the GNU Affero General Public License into a
-     single combined work, and to convey the resulting work.  The terms
-     of this License will continue to apply to the part which is the
-     covered work, but the special requirements of the GNU Affero
-     General Public License, section 13, concerning interaction through
-     a network will apply to the combination as such.
-
-  14. Revised Versions of this License.
-
-     The Free Software Foundation may publish revised and/or new
-     versions of the GNU General Public License from time to time.  Such
-     new versions will be similar in spirit to the present version, but
-     may differ in detail to address new problems or concerns.
-
-     Each version is given a distinguishing version number.  If the
-     Program specifies that a certain numbered version of the GNU
-     General Public License “or any later version” applies to it, you
-     have the option of following the terms and conditions either of
-     that numbered version or of any later version published by the Free
-     Software Foundation.  If the Program does not specify a version
-     number of the GNU General Public License, you may choose any
-     version ever published by the Free Software Foundation.
-
-     If the Program specifies that a proxy can decide which future
-     versions of the GNU General Public License can be used, that
-     proxy’s public statement of acceptance of a version permanently
-     authorizes you to choose that version for the Program.
-
-     Later license versions may give you additional or different
-     permissions.  However, no additional obligations are imposed on any
-     author or copyright holder as a result of your choosing to follow a
-     later version.
-
-  15. Disclaimer of Warranty.
-
-     THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-     APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE
-     COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS”
-     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
-     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE
-     RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
-     SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
-     NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-     IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
-     AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
-     DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-     CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
-     THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
-     BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-     PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-     PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
-     THE POSSIBILITY OF SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-     If the disclaimer of warranty and limitation of liability provided
-     above cannot be given local legal effect according to their terms,
-     reviewing courts shall apply local law that most closely
-     approximates an absolute waiver of all civil liability in
-     connection with the Program, unless a warranty or assumption of
-     liability accompanies a copy of the Program in return for a fee.
-
-END OF TERMS AND CONDITIONS
-===========================
-
-How to Apply These Terms to Your New Programs
-=============================================
-
-If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these
-terms.
-
-   To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least the
-“copyright” line and a pointer to where the full notice is found.
-
-     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
-     Copyright (C) YEAR NAME OF AUTHOR
-
-     This program 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 program 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.
-
-     You should have received a copy of the GNU General Public License
-     along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-   Also add information on how to contact you by electronic and paper
-mail.
-
-   If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-     PROGRAM Copyright (C) YEAR NAME OF AUTHOR
-     This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
-     This is free software, and you are welcome to redistribute it
-     under certain conditions; type ‘show c’ for details.
-
-   The hypothetical commands ‘show w’ and ‘show c’ should show the
-appropriate parts of the General Public License.  Of course, your
-program’s commands might be different; for a GUI interface, you would
-use an “about box”.
-
-   You should also get your employer (if you work as a programmer) or
-school, if any, to sign a “copyright disclaimer” for the program, if
-necessary.  For more information on this, and how to apply and follow
-the GNU GPL, see <https://www.gnu.org/licenses/>.
-
-   The GNU General Public License does not permit incorporating your
-program into proprietary programs.  If your program is a subroutine
-library, you may consider it more useful to permit linking proprietary
-applications with the library.  If this is what you want to do, use the
-GNU Lesser General Public License instead of this License.  But first,
-please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
-
-
-\1f
-Tag Table:
-Node: Top\7f763
-Node: Introduction\7f2976
-Ref: Some things that Transient can do\7f3504
-Ref: Complexity in CLI programs\7f3857
-Ref: Using Transient for composing interactive commands\7f4458
-Node: Usage\7f6700
-Node: Invoking Transients\7f7068
-Node: Aborting and Resuming Transients\7f8147
-Node: Common Suffix Commands\7f10768
-Node: Saving Values\7f12604
-Ref: Saving Values-Footnote-1\7f13975
-Node: Using History\7f14168
-Node: Getting Help for Suffix Commands\7f15742
-Node: Enabling and Disabling Suffixes\7f17120
-Node: Other Commands\7f20408
-Node: Configuration\7f21384
-Ref: Essential Options\7f21664
-Ref: Accessibility Options\7f25325
-Ref: Auxiliary Options\7f25648
-Ref: Developer Options\7f30611
-Node: Modifying Existing Transients\7f31859
-Node: Defining New Commands\7f36051
-Node: Technical Introduction\7f36414
-Node: Defining Transients\7f42115
-Node: Binding Suffix and Infix Commands\7f44582
-Node: Group Specifications\7f45440
-Node: Suffix Specifications\7f51968
-Node: Defining Suffix and Infix Commands\7f56181
-Node: Using Infix Arguments\7f59229
-Node: Transient State\7f62853
-Ref: Pre-commands for Infixes\7f67668
-Ref: Pre-commands for Suffixes\7f68188
-Ref: Pre-commands for Non-Suffixes\7f70642
-Ref: Special Pre-Commands\7f71778
-Node: Classes and Methods\7f72286
-Node: Group Classes\7f74470
-Node: Group Methods\7f76397
-Node: Prefix Classes\7f77650
-Node: Suffix Classes\7f78741
-Node: Suffix Methods\7f81828
-Node: Suffix Value Methods\7f82149
-Node: Suffix Format Methods\7f84907
-Node: Prefix Slots\7f86386
-Ref: Internal Prefix Slots\7f88521
-Node: Suffix Slots\7f89778
-Ref: Slots of transient-suffix\7f90146
-Ref: Slots of transient-infix\7f91283
-Ref: Slots of transient-variable\7f94579
-Ref: Slots of transient-switches\7f94681
-Node: Predicate Slots\7f95044
-Node: FAQ\7f96479
-Ref: Can I control how the popup buffer is displayed?\7f96608
-Ref: How can I copy text from the popup buffer?\7f96789
-Ref: How can I autoload prefix and suffix commands?\7f97283
-Ref: How does Transient compare to prefix keys and universal arguments?\7f97757
-Ref: How does Transient compare to Magit-Popup and Hydra?\7f98000
-Ref: Why did some of the key bindings change?\7f98194
-Ref: Why does q not quit popups anymore?\7f100547
-Node: Keystroke Index\7f101650
-Node: Command and Function Index\7f103515
-Node: Variable Index\7f110107
-Node: Concept Index\7f112517
-Node: GNU General Public License\7f115253
-\1f
-End Tag Table
-
-\1f
-Local Variables:
-coding: utf-8
-End:
diff --git a/elpa/transient-20241219.1713/dir b/elpa/transient-20241219.1713/dir
new file mode 100644 (file)
index 0000000..d4d5540
--- /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 misc features
+* Transient: (transient).       Transient Commands.
diff --git a/elpa/transient-20241219.1713/gpl.info b/elpa/transient-20241219.1713/gpl.info
new file mode 100644 (file)
index 0000000..3a659de
--- /dev/null
@@ -0,0 +1,721 @@
+This is gpl.info, produced by makeinfo version 6.8 from gpl.texi.
+
+                        Version 3, 29 June 2007
+
+     Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+
+     Everyone is permitted to copy and distribute verbatim copies of this
+     license document, but changing it is not allowed.
+
+Preamble
+========
+
+The GNU General Public License is a free, copyleft license for software
+and other kinds of works.
+
+   The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+   When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+   To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+   For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+   Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+   For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+   Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+   Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+   The precise terms and conditions for copying, distribution and
+modification follow.
+
+TERMS AND CONDITIONS
+====================
+
+  0. Definitions.
+
+     "This License" refers to version 3 of the GNU General Public
+     License.
+
+     "Copyright" also means copyright-like laws that apply to other
+     kinds of works, such as semiconductor masks.
+
+     "The Program" refers to any copyrightable work licensed under this
+     License.  Each licensee is addressed as "you".  "Licensees" and
+     "recipients" may be individuals or organizations.
+
+     To "modify" a work means to copy from or adapt all or part of the
+     work in a fashion requiring copyright permission, other than the
+     making of an exact copy.  The resulting work is called a "modified
+     version" of the earlier work or a work "based on" the earlier work.
+
+     A "covered work" means either the unmodified Program or a work
+     based on the Program.
+
+     To "propagate" a work means to do anything with it that, without
+     permission, would make you directly or secondarily liable for
+     infringement under applicable copyright law, except executing it on
+     a computer or modifying a private copy.  Propagation includes
+     copying, distribution (with or without modification), making
+     available to the public, and in some countries other activities as
+     well.
+
+     To "convey" a work means any kind of propagation that enables other
+     parties to make or receive copies.  Mere interaction with a user
+     through a computer network, with no transfer of a copy, is not
+     conveying.
+
+     An interactive user interface displays "Appropriate Legal Notices"
+     to the extent that it includes a convenient and prominently visible
+     feature that (1) displays an appropriate copyright notice, and (2)
+     tells the user that there is no warranty for the work (except to
+     the extent that warranties are provided), that licensees may convey
+     the work under this License, and how to view a copy of this
+     License.  If the interface presents a list of user commands or
+     options, such as a menu, a prominent item in the list meets this
+     criterion.
+
+  1. Source Code.
+
+     The "source code" for a work means the preferred form of the work
+     for making modifications to it.  "Object code" means any non-source
+     form of a work.
+
+     A "Standard Interface" means an interface that either is an
+     official standard defined by a recognized standards body, or, in
+     the case of interfaces specified for a particular programming
+     language, one that is widely used among developers working in that
+     language.
+
+     The "System Libraries" of an executable work include anything,
+     other than the work as a whole, that (a) is included in the normal
+     form of packaging a Major Component, but which is not part of that
+     Major Component, and (b) serves only to enable use of the work with
+     that Major Component, or to implement a Standard Interface for
+     which an implementation is available to the public in source code
+     form.  A "Major Component", in this context, means a major
+     essential component (kernel, window system, and so on) of the
+     specific operating system (if any) on which the executable work
+     runs, or a compiler used to produce the work, or an object code
+     interpreter used to run it.
+
+     The "Corresponding Source" for a work in object code form means all
+     the source code needed to generate, install, and (for an executable
+     work) run the object code and to modify the work, including scripts
+     to control those activities.  However, it does not include the
+     work's System Libraries, or general-purpose tools or generally
+     available free programs which are used unmodified in performing
+     those activities but which are not part of the work.  For example,
+     Corresponding Source includes interface definition files associated
+     with source files for the work, and the source code for shared
+     libraries and dynamically linked subprograms that the work is
+     specifically designed to require, such as by intimate data
+     communication or control flow between those subprograms and other
+     parts of the work.
+
+     The Corresponding Source need not include anything that users can
+     regenerate automatically from other parts of the Corresponding
+     Source.
+
+     The Corresponding Source for a work in source code form is that
+     same work.
+
+  2. Basic Permissions.
+
+     All rights granted under this License are granted for the term of
+     copyright on the Program, and are irrevocable provided the stated
+     conditions are met.  This License explicitly affirms your unlimited
+     permission to run the unmodified Program.  The output from running
+     a covered work is covered by this License only if the output, given
+     its content, constitutes a covered work.  This License acknowledges
+     your rights of fair use or other equivalent, as provided by
+     copyright law.
+
+     You may make, run and propagate covered works that you do not
+     convey, without conditions so long as your license otherwise
+     remains in force.  You may convey covered works to others for the
+     sole purpose of having them make modifications exclusively for you,
+     or provide you with facilities for running those works, provided
+     that you comply with the terms of this License in conveying all
+     material for which you do not control copyright.  Those thus making
+     or running the covered works for you must do so exclusively on your
+     behalf, under your direction and control, on terms that prohibit
+     them from making any copies of your copyrighted material outside
+     their relationship with you.
+
+     Conveying under any other circumstances is permitted solely under
+     the conditions stated below.  Sublicensing is not allowed; section
+     10 makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+     No covered work shall be deemed part of an effective technological
+     measure under any applicable law fulfilling obligations under
+     article 11 of the WIPO copyright treaty adopted on 20 December
+     1996, or similar laws prohibiting or restricting circumvention of
+     such measures.
+
+     When you convey a covered work, you waive any legal power to forbid
+     circumvention of technological measures to the extent such
+     circumvention is effected by exercising rights under this License
+     with respect to the covered work, and you disclaim any intention to
+     limit operation or modification of the work as a means of
+     enforcing, against the work's users, your or third parties' legal
+     rights to forbid circumvention of technological measures.
+
+  4. Conveying Verbatim Copies.
+
+     You may convey verbatim copies of the Program's source code as you
+     receive it, in any medium, provided that you conspicuously and
+     appropriately publish on each copy an appropriate copyright notice;
+     keep intact all notices stating that this License and any
+     non-permissive terms added in accord with section 7 apply to the
+     code; keep intact all notices of the absence of any warranty; and
+     give all recipients a copy of this License along with the Program.
+
+     You may charge any price or no price for each copy that you convey,
+     and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+     You may convey a work based on the Program, or the modifications to
+     produce it from the Program, in the form of source code under the
+     terms of section 4, provided that you also meet all of these
+     conditions:
+
+       a. The work must carry prominent notices stating that you
+          modified it, and giving a relevant date.
+
+       b. The work must carry prominent notices stating that it is
+          released under this License and any conditions added under
+          section 7.  This requirement modifies the requirement in
+          section 4 to "keep intact all notices".
+
+       c. You must license the entire work, as a whole, under this
+          License to anyone who comes into possession of a copy.  This
+          License will therefore apply, along with any applicable
+          section 7 additional terms, to the whole of the work, and all
+          its parts, regardless of how they are packaged.  This License
+          gives no permission to license the work in any other way, but
+          it does not invalidate such permission if you have separately
+          received it.
+
+       d. If the work has interactive user interfaces, each must display
+          Appropriate Legal Notices; however, if the Program has
+          interactive interfaces that do not display Appropriate Legal
+          Notices, your work need not make them do so.
+
+     A compilation of a covered work with other separate and independent
+     works, which are not by their nature extensions of the covered
+     work, and which are not combined with it such as to form a larger
+     program, in or on a volume of a storage or distribution medium, is
+     called an "aggregate" if the compilation and its resulting
+     copyright are not used to limit the access or legal rights of the
+     compilation's users beyond what the individual works permit.
+     Inclusion of a covered work in an aggregate does not cause this
+     License to apply to the other parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+     You may convey a covered work in object code form under the terms
+     of sections 4 and 5, provided that you also convey the
+     machine-readable Corresponding Source under the terms of this
+     License, in one of these ways:
+
+       a. Convey the object code in, or embodied in, a physical product
+          (including a physical distribution medium), accompanied by the
+          Corresponding Source fixed on a durable physical medium
+          customarily used for software interchange.
+
+       b. Convey the object code in, or embodied in, a physical product
+          (including a physical distribution medium), accompanied by a
+          written offer, valid for at least three years and valid for as
+          long as you offer spare parts or customer support for that
+          product model, to give anyone who possesses the object code
+          either (1) a copy of the Corresponding Source for all the
+          software in the product that is covered by this License, on a
+          durable physical medium customarily used for software
+          interchange, for a price no more than your reasonable cost of
+          physically performing this conveying of source, or (2) access
+          to copy the Corresponding Source from a network server at no
+          charge.
+
+       c. Convey individual copies of the object code with a copy of the
+          written offer to provide the Corresponding Source.  This
+          alternative is allowed only occasionally and noncommercially,
+          and only if you received the object code with such an offer,
+          in accord with subsection 6b.
+
+       d. Convey the object code by offering access from a designated
+          place (gratis or for a charge), and offer equivalent access to
+          the Corresponding Source in the same way through the same
+          place at no further charge.  You need not require recipients
+          to copy the Corresponding Source along with the object code.
+          If the place to copy the object code is a network server, the
+          Corresponding Source may be on a different server (operated by
+          you or a third party) that supports equivalent copying
+          facilities, provided you maintain clear directions next to the
+          object code saying where to find the Corresponding Source.
+          Regardless of what server hosts the Corresponding Source, you
+          remain obligated to ensure that it is available for as long as
+          needed to satisfy these requirements.
+
+       e. Convey the object code using peer-to-peer transmission,
+          provided you inform other peers where the object code and
+          Corresponding Source of the work are being offered to the
+          general public at no charge under subsection 6d.
+
+     A separable portion of the object code, whose source code is
+     excluded from the Corresponding Source as a System Library, need
+     not be included in conveying the object code work.
+
+     A "User Product" is either (1) a "consumer product", which means
+     any tangible personal property which is normally used for personal,
+     family, or household purposes, or (2) anything designed or sold for
+     incorporation into a dwelling.  In determining whether a product is
+     a consumer product, doubtful cases shall be resolved in favor of
+     coverage.  For a particular product received by a particular user,
+     "normally used" refers to a typical or common use of that class of
+     product, regardless of the status of the particular user or of the
+     way in which the particular user actually uses, or expects or is
+     expected to use, the product.  A product is a consumer product
+     regardless of whether the product has substantial commercial,
+     industrial or non-consumer uses, unless such uses represent the
+     only significant mode of use of the product.
+
+     "Installation Information" for a User Product means any methods,
+     procedures, authorization keys, or other information required to
+     install and execute modified versions of a covered work in that
+     User Product from a modified version of its Corresponding Source.
+     The information must suffice to ensure that the continued
+     functioning of the modified object code is in no case prevented or
+     interfered with solely because modification has been made.
+
+     If you convey an object code work under this section in, or with,
+     or specifically for use in, a User Product, and the conveying
+     occurs as part of a transaction in which the right of possession
+     and use of the User Product is transferred to the recipient in
+     perpetuity or for a fixed term (regardless of how the transaction
+     is characterized), the Corresponding Source conveyed under this
+     section must be accompanied by the Installation Information.  But
+     this requirement does not apply if neither you nor any third party
+     retains the ability to install modified object code on the User
+     Product (for example, the work has been installed in ROM).
+
+     The requirement to provide Installation Information does not
+     include a requirement to continue to provide support service,
+     warranty, or updates for a work that has been modified or installed
+     by the recipient, or for the User Product in which it has been
+     modified or installed.  Access to a network may be denied when the
+     modification itself materially and adversely affects the operation
+     of the network or violates the rules and protocols for
+     communication across the network.
+
+     Corresponding Source conveyed, and Installation Information
+     provided, in accord with this section must be in a format that is
+     publicly documented (and with an implementation available to the
+     public in source code form), and must require no special password
+     or key for unpacking, reading or copying.
+
+  7. Additional Terms.
+
+     "Additional permissions" are terms that supplement the terms of
+     this License by making exceptions from one or more of its
+     conditions.  Additional permissions that are applicable to the
+     entire Program shall be treated as though they were included in
+     this License, to the extent that they are valid under applicable
+     law.  If additional permissions apply only to part of the Program,
+     that part may be used separately under those permissions, but the
+     entire Program remains governed by this License without regard to
+     the additional permissions.
+
+     When you convey a copy of a covered work, you may at your option
+     remove any additional permissions from that copy, or from any part
+     of it.  (Additional permissions may be written to require their own
+     removal in certain cases when you modify the work.)  You may place
+     additional permissions on material, added by you to a covered work,
+     for which you have or can give appropriate copyright permission.
+
+     Notwithstanding any other provision of this License, for material
+     you add to a covered work, you may (if authorized by the copyright
+     holders of that material) supplement the terms of this License with
+     terms:
+
+       a. Disclaiming warranty or limiting liability differently from
+          the terms of sections 15 and 16 of this License; or
+
+       b. Requiring preservation of specified reasonable legal notices
+          or author attributions in that material or in the Appropriate
+          Legal Notices displayed by works containing it; or
+
+       c. Prohibiting misrepresentation of the origin of that material,
+          or requiring that modified versions of such material be marked
+          in reasonable ways as different from the original version; or
+
+       d. Limiting the use for publicity purposes of names of licensors
+          or authors of the material; or
+
+       e. Declining to grant rights under trademark law for use of some
+          trade names, trademarks, or service marks; or
+
+       f. Requiring indemnification of licensors and authors of that
+          material by anyone who conveys the material (or modified
+          versions of it) with contractual assumptions of liability to
+          the recipient, for any liability that these contractual
+          assumptions directly impose on those licensors and authors.
+
+     All other non-permissive additional terms are considered "further
+     restrictions" within the meaning of section 10.  If the Program as
+     you received it, or any part of it, contains a notice stating that
+     it is governed by this License along with a term that is a further
+     restriction, you may remove that term.  If a license document
+     contains a further restriction but permits relicensing or conveying
+     under this License, you may add to a covered work material governed
+     by the terms of that license document, provided that the further
+     restriction does not survive such relicensing or conveying.
+
+     If you add terms to a covered work in accord with this section, you
+     must place, in the relevant source files, a statement of the
+     additional terms that apply to those files, or a notice indicating
+     where to find the applicable terms.
+
+     Additional terms, permissive or non-permissive, may be stated in
+     the form of a separately written license, or stated as exceptions;
+     the above requirements apply either way.
+
+  8. Termination.
+
+     You may not propagate or modify a covered work except as expressly
+     provided under this License.  Any attempt otherwise to propagate or
+     modify it is void, and will automatically terminate your rights
+     under this License (including any patent licenses granted under the
+     third paragraph of section 11).
+
+     However, if you cease all violation of this License, then your
+     license from a particular copyright holder is reinstated (a)
+     provisionally, unless and until the copyright holder explicitly and
+     finally terminates your license, and (b) permanently, if the
+     copyright holder fails to notify you of the violation by some
+     reasonable means prior to 60 days after the cessation.
+
+     Moreover, your license from a particular copyright holder is
+     reinstated permanently if the copyright holder notifies you of the
+     violation by some reasonable means, this is the first time you have
+     received notice of violation of this License (for any work) from
+     that copyright holder, and you cure the violation prior to 30 days
+     after your receipt of the notice.
+
+     Termination of your rights under this section does not terminate
+     the licenses of parties who have received copies or rights from you
+     under this License.  If your rights have been terminated and not
+     permanently reinstated, you do not qualify to receive new licenses
+     for the same material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+     You are not required to accept this License in order to receive or
+     run a copy of the Program.  Ancillary propagation of a covered work
+     occurring solely as a consequence of using peer-to-peer
+     transmission to receive a copy likewise does not require
+     acceptance.  However, nothing other than this License grants you
+     permission to propagate or modify any covered work.  These actions
+     infringe copyright if you do not accept this License.  Therefore,
+     by modifying or propagating a covered work, you indicate your
+     acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+     Each time you convey a covered work, the recipient automatically
+     receives a license from the original licensors, to run, modify and
+     propagate that work, subject to this License.  You are not
+     responsible for enforcing compliance by third parties with this
+     License.
+
+     An "entity transaction" is a transaction transferring control of an
+     organization, or substantially all assets of one, or subdividing an
+     organization, or merging organizations.  If propagation of a
+     covered work results from an entity transaction, each party to that
+     transaction who receives a copy of the work also receives whatever
+     licenses to the work the party's predecessor in interest had or
+     could give under the previous paragraph, plus a right to possession
+     of the Corresponding Source of the work from the predecessor in
+     interest, if the predecessor has it or can get it with reasonable
+     efforts.
+
+     You may not impose any further restrictions on the exercise of the
+     rights granted or affirmed under this License.  For example, you
+     may not impose a license fee, royalty, or other charge for exercise
+     of rights granted under this License, and you may not initiate
+     litigation (including a cross-claim or counterclaim in a lawsuit)
+     alleging that any patent claim is infringed by making, using,
+     selling, offering for sale, or importing the Program or any portion
+     of it.
+
+  11. Patents.
+
+     A "contributor" is a copyright holder who authorizes use under this
+     License of the Program or a work on which the Program is based.
+     The work thus licensed is called the contributor's "contributor
+     version".
+
+     A contributor's "essential patent claims" are all patent claims
+     owned or controlled by the contributor, whether already acquired or
+     hereafter acquired, that would be infringed by some manner,
+     permitted by this License, of making, using, or selling its
+     contributor version, but do not include claims that would be
+     infringed only as a consequence of further modification of the
+     contributor version.  For purposes of this definition, "control"
+     includes the right to grant patent sublicenses in a manner
+     consistent with the requirements of this License.
+
+     Each contributor grants you a non-exclusive, worldwide,
+     royalty-free patent license under the contributor's essential
+     patent claims, to make, use, sell, offer for sale, import and
+     otherwise run, modify and propagate the contents of its contributor
+     version.
+
+     In the following three paragraphs, a "patent license" is any
+     express agreement or commitment, however denominated, not to
+     enforce a patent (such as an express permission to practice a
+     patent or covenant not to sue for patent infringement).  To "grant"
+     such a patent license to a party means to make such an agreement or
+     commitment not to enforce a patent against the party.
+
+     If you convey a covered work, knowingly relying on a patent
+     license, and the Corresponding Source of the work is not available
+     for anyone to copy, free of charge and under the terms of this
+     License, through a publicly available network server or other
+     readily accessible means, then you must either (1) cause the
+     Corresponding Source to be so available, or (2) arrange to deprive
+     yourself of the benefit of the patent license for this particular
+     work, or (3) arrange, in a manner consistent with the requirements
+     of this License, to extend the patent license to downstream
+     recipients.  "Knowingly relying" means you have actual knowledge
+     that, but for the patent license, your conveying the covered work
+     in a country, or your recipient's use of the covered work in a
+     country, would infringe one or more identifiable patents in that
+     country that you have reason to believe are valid.
+
+     If, pursuant to or in connection with a single transaction or
+     arrangement, you convey, or propagate by procuring conveyance of, a
+     covered work, and grant a patent license to some of the parties
+     receiving the covered work authorizing them to use, propagate,
+     modify or convey a specific copy of the covered work, then the
+     patent license you grant is automatically extended to all
+     recipients of the covered work and works based on it.
+
+     A patent license is "discriminatory" if it does not include within
+     the scope of its coverage, prohibits the exercise of, or is
+     conditioned on the non-exercise of one or more of the rights that
+     are specifically granted under this License.  You may not convey a
+     covered work if you are a party to an arrangement with a third
+     party that is in the business of distributing software, under which
+     you make payment to the third party based on the extent of your
+     activity of conveying the work, and under which the third party
+     grants, to any of the parties who would receive the covered work
+     from you, a discriminatory patent license (a) in connection with
+     copies of the covered work conveyed by you (or copies made from
+     those copies), or (b) primarily for and in connection with specific
+     products or compilations that contain the covered work, unless you
+     entered into that arrangement, or that patent license was granted,
+     prior to 28 March 2007.
+
+     Nothing in this License shall be construed as excluding or limiting
+     any implied license or other defenses to infringement that may
+     otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+     If conditions are imposed on you (whether by court order, agreement
+     or otherwise) that contradict the conditions of this License, they
+     do not excuse you from the conditions of this License.  If you
+     cannot convey a covered work so as to satisfy simultaneously your
+     obligations under this License and any other pertinent obligations,
+     then as a consequence you may not convey it at all.  For example,
+     if you agree to terms that obligate you to collect a royalty for
+     further conveying from those to whom you convey the Program, the
+     only way you could satisfy both those terms and this License would
+     be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+     Notwithstanding any other provision of this License, you have
+     permission to link or combine any covered work with a work licensed
+     under version 3 of the GNU Affero General Public License into a
+     single combined work, and to convey the resulting work.  The terms
+     of this License will continue to apply to the part which is the
+     covered work, but the special requirements of the GNU Affero
+     General Public License, section 13, concerning interaction through
+     a network will apply to the combination as such.
+
+  14. Revised Versions of this License.
+
+     The Free Software Foundation may publish revised and/or new
+     versions of the GNU General Public License from time to time.  Such
+     new versions will be similar in spirit to the present version, but
+     may differ in detail to address new problems or concerns.
+
+     Each version is given a distinguishing version number.  If the
+     Program specifies that a certain numbered version of the GNU
+     General Public License "or any later version" applies to it, you
+     have the option of following the terms and conditions either of
+     that numbered version or of any later version published by the Free
+     Software Foundation.  If the Program does not specify a version
+     number of the GNU General Public License, you may choose any
+     version ever published by the Free Software Foundation.
+
+     If the Program specifies that a proxy can decide which future
+     versions of the GNU General Public License can be used, that
+     proxy's public statement of acceptance of a version permanently
+     authorizes you to choose that version for the Program.
+
+     Later license versions may give you additional or different
+     permissions.  However, no additional obligations are imposed on any
+     author or copyright holder as a result of your choosing to follow a
+     later version.
+
+  15. Disclaimer of Warranty.
+
+     THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+     APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE
+     COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE
+     RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
+     SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+     NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+     IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
+     AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
+     DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+     CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+     THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+     BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+     PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+     PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
+     THE POSSIBILITY OF SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+     If the disclaimer of warranty and limitation of liability provided
+     above cannot be given local legal effect according to their terms,
+     reviewing courts shall apply local law that most closely
+     approximates an absolute waiver of all civil liability in
+     connection with the Program, unless a warranty or assumption of
+     liability accompanies a copy of the Program in return for a fee.
+
+END OF TERMS AND CONDITIONS
+===========================
+
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+   To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
+     Copyright (C) YEAR NAME OF AUTHOR
+
+     This program 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 program 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.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+   Also add information on how to contact you by electronic and paper
+mail.
+
+   If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+     PROGRAM Copyright (C) YEAR NAME OF AUTHOR
+     This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type 'show c' for details.
+
+   The hypothetical commands 'show w' and 'show c' should show the
+appropriate parts of the General Public License.  Of course, your
+program's commands might be different; for a GUI interface, you would
+use an "about box".
+
+   You should also get your employer (if you work as a programmer) or
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  For more information on this, and how to apply and follow
+the GNU GPL, see <https://www.gnu.org/licenses/>.
+
+   The GNU General Public License does not permit incorporating your
+program into proprietary programs.  If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library.  If this is what you want to do, use the
+GNU Lesser General Public License instead of this License.  But first,
+please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
+
+\1f
+Tag Table:
+\1f
+End Tag Table
+
+\1f
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/transient-20241219.1713/transient-autoloads.el b/elpa/transient-20241219.1713/transient-autoloads.el
new file mode 100644 (file)
index 0000000..df3d367
--- /dev/null
@@ -0,0 +1,78 @@
+;;; transient-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+\f
+;;; Generated autoloads from transient.el
+
+(autoload 'transient-insert-suffix "transient" "\
+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 `transient-define-prefix').
+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).
+Remove a conflicting binding unless optional KEEP-OTHER is
+  non-nil.
+See info node `(transient)Modifying Existing Transients'.
+
+(fn PREFIX LOC SUFFIX &optional KEEP-OTHER)")
+(function-put 'transient-insert-suffix 'lisp-indent-function 'defun)
+(autoload 'transient-append-suffix "transient" "\
+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 `transient-define-prefix').
+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).
+Remove a conflicting binding unless optional KEEP-OTHER is
+  non-nil.
+See info node `(transient)Modifying Existing Transients'.
+
+(fn PREFIX LOC SUFFIX &optional KEEP-OTHER)")
+(function-put 'transient-append-suffix 'lisp-indent-function 'defun)
+(autoload 'transient-replace-suffix "transient" "\
+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 `transient-define-prefix').
+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'.
+
+(fn PREFIX LOC SUFFIX)")
+(function-put 'transient-replace-suffix 'lisp-indent-function 'defun)
+(autoload 'transient-remove-suffix "transient" "\
+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'.
+
+(fn PREFIX LOC)")
+(function-put 'transient-remove-suffix 'lisp-indent-function 'defun)
+(register-definition-prefixes "transient" '("find-function-advised-original" "transient"))
+\f
+;;; End of scraped data
+
+(provide 'transient-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; transient-autoloads.el ends here
diff --git a/elpa/transient-20241219.1713/transient-pkg.el b/elpa/transient-20241219.1713/transient-pkg.el
new file mode 100644 (file)
index 0000000..e905ce0
--- /dev/null
@@ -0,0 +1,12 @@
+;; -*- no-byte-compile: t; lexical-binding: nil -*-
+(define-package "transient" "20241219.1713"
+  "Transient commands."
+  '((emacs  "26.1")
+    (compat "30.0.0.0")
+    (seq    "2.24"))
+  :url "https://github.com/magit/transient"
+  :commit "5a18a79100bc5c4a5239f3917c1c1c4058a11769"
+  :revdesc "5a18a79100bc"
+  :keywords '("extensions")
+  :authors '(("Jonas Bernoulli" . "emacs.transientNOSPAMjonas.bernoulli.dev"))
+  :maintainers '(("Jonas Bernoulli" . "emacs.transientNOSPAMjonas.bernoulli.dev")))
diff --git a/elpa/transient-20241219.1713/transient.el b/elpa/transient-20241219.1713/transient.el
new file mode 100644 (file)
index 0000000..4892007
--- /dev/null
@@ -0,0 +1,4982 @@
+;;; transient.el --- Transient commands  -*- lexical-binding:t -*-
+
+;; Copyright (C) 2018-2024 Free Software Foundation, Inc.
+
+;; Author: Jonas Bernoulli <emacs.transientNOSPAMjonas.bernoulli.dev>
+;; Homepage: https://github.com/magit/transient
+;; Keywords: extensions
+
+;; Package-Version: 20241219.1713
+;; Package-Revision: 5a18a79100bc
+;; Package-Requires: ((emacs "26.1") (compat "30.0.0.0") (seq "2.24"))
+
+;; SPDX-License-Identifier: GPL-3.0-or-later
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+;;
+;; GNU Emacs 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.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Transient is the library used to implement the keyboard-driven menus
+;; in Magit.  It is distributed as a separate package, so that it can be
+;; used to implement similar menus in other packages.
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'compat)
+(require 'eieio)
+(require 'edmacro)
+(require 'format-spec)
+(require 'pcase)
+
+(eval-and-compile
+  (when (and (featurep 'seq)
+             (not (fboundp 'seq-keep)))
+    (unload-feature 'seq 'force)))
+(require 'seq)
+(unless (fboundp 'seq-keep)
+  (display-warning 'transient (substitute-command-keys "\
+Transient requires `seq' >= 2.24,
+but due to bad defaults, Emacs's package manager, refuses to
+upgrade this and other built-in packages to higher releases
+from GNU Elpa, when a package specifies that this is needed.
+
+To fix this, you have to add this to your init file:
+
+  (setq package-install-upgrade-built-in t)
+
+Then evaluate that expression by placing the cursor after it
+and typing \\[eval-last-sexp].
+
+Once you have done that, you have to explicitly upgrade `seq':
+
+  \\[package-upgrade] seq \\`RET'
+
+Then you also must make sure the updated version is loaded,
+by evaluating this form:
+
+  (progn (unload-feature 'seq t) (require 'seq))
+
+Until you do this, you will get random errors about `seq-keep'
+being undefined while using Transient.
+
+If you don't use the `package' package manager but still get
+this warning, then your chosen package manager likely has a
+similar defect.") :emergency))
+
+(eval-when-compile (require 'subr-x))
+
+(declare-function info "info" (&optional file-or-node buffer))
+(declare-function Man-find-section "man" (section))
+(declare-function Man-next-section "man" (n))
+(declare-function Man-getpage-in-background "man" (topic))
+
+(defvar Man-notify-method)
+(defvar pp-default-function) ; since Emacs 29.1
+
+(eval-and-compile
+  (when (< emacs-major-version 28)
+    (pcase-defmacro cl-type (type)
+      "Pcase pattern that matches objects of TYPE.
+TYPE is a type descriptor as accepted by `cl-typep', which see."
+      (static-if (< emacs-major-version 30)
+          `(pred (pcase--flip cl-typep ',type))
+        `(pred (cl-typep _ ',type))))))
+
+(make-obsolete-variable 'transient-hide-during-minibuffer-read
+                        "use `transient-show-during-minibuffer-read' instead."
+                        "0.8.0")
+
+(defmacro transient--with-emergency-exit (id &rest body)
+  (declare (indent defun))
+  (unless (keywordp id)
+    (setq body (cons id body))
+    (setq id nil))
+  `(condition-case err
+       (let ((debugger #'transient--exit-and-debug))
+         ,(macroexp-progn body))
+     ((debug error)
+      (transient--emergency-exit ,id)
+      (signal (car err) (cdr err)))))
+
+(defun transient--exit-and-debug (&rest args)
+  (transient--emergency-exit :debugger)
+  (apply #'debug args))
+
+;;; Options
+
+(defgroup transient nil
+  "Transient commands."
+  :group 'extensions)
+
+(defcustom transient-show-popup t
+  "Whether to show the current transient in a popup buffer.
+\\<transient-map>
+- 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 \\[transient-show] or a prefix key.
+
+- 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
+  \\[transient-show] or a prefix key.  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 'verbose
+  "Whether navigation commands are enabled in the transient popup.
+
+If the value is `verbose', additionally show brief documentation
+about the command under point in the echo area.
+
+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 is non-nil, then the following
+bindings are available:
+
+\\<transient-popup-navigation-map>\
+- \\[transient-backward-button] moves the cursor to the previous suffix.
+- \\[transient-forward-button] moves the cursor to the next suffix.
+- \\[transient-push-button] invokes the suffix the cursor is on.
+\\<transient-button-map>\
+- \\`<mouse-1>' and \\`<mouse-2>' invoke the clicked on suffix.
+\\<transient-popup-navigation-map>\
+- \\[transient-isearch-backward]\
+ and \\[transient-isearch-forward] start isearch in the popup buffer.
+
+\\`<mouse-1>' and \\`<mouse-2>' are bound in `transient-push-button'.
+All other bindings are in `transient-popup-navigation-map'.
+
+By default \\`M-RET' is bound to `transient-push-button', instead of
+\\`RET', because if a transient allows the invocation of non-suffixes,
+then it is likely, that you would want \\`RET' to do what it would do
+if no transient were active."
+  :package-version '(transient . "0.7.8")
+  :group 'transient
+  :type '(choice (const :tag "enable navigation and echo summary" verbose)
+                 (const :tag "enable navigation commands" t)
+                 (const :tag "disable navigation commands" nil)))
+
+(defcustom transient-display-buffer-action
+  '(display-buffer-in-side-window
+    (side . bottom)
+    (dedicated . t)
+    (inhibit-same-window . t))
+  "The action used to display the transient popup buffer.
+
+The transient popup buffer is displayed in a window using
+
+  (display-buffer BUFFER 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 info node `(elisp)Choosing
+Window' for details.
+
+The default is:
+
+  (display-buffer-in-side-window
+    (side . bottom)
+    (dedicated . t)
+    (inhibit-same-window . t))
+
+This displays the window at the bottom of the selected frame.
+For alternatives see info node `(elisp)Display Action Functions'
+and info node `(elisp)Buffer Display Action Alists'.
+
+Note that the buffer that was current before the transient buffer
+is shown should remain the current buffer.  Many suffix commands
+act on the thing at point, if appropriate, and if the transient
+buffer became the current buffer, then that would change what is
+at point.  To that effect `inhibit-same-window' ensures that the
+selected window is not used to show the transient buffer.
+
+The use of a horizontal split to display the menu window can lead
+to incompatibilities and is thus discouraged.  Transient tries to
+mitigate such issue but cannot proactively deal with all possible
+configurations and combinations of third-party packages.
+
+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 that unfortunately changes which buffer is current.
+
+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.7.5")
+  :group 'transient
+  :type '(cons (choice function (repeat :tag "Functions" function))
+               alist))
+
+(defcustom transient-minimal-frame-width 83
+  "Minimal width of dedicated frame used to display transient menu.
+This is only used if the transient menu is actually displayed in a
+dedicated frame (see `transient-display-buffer-action').  The value
+is in characters."
+  :package-version '(transient . "0.8.1")
+  :group 'transient
+  :type 'natnum)
+
+(defcustom transient-mode-line-format '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) or a natural number, then the buffer has no
+mode-line, but a line is drawn in its place.  If a number is used,
+that specifies the thickness of the line.  On termcap frames we
+cannot draw lines, so there `line' and numbers are synonyms for nil.
+
+The color of the line is used to indicate if non-suffixes are
+allowed and whether they exit the transient.  The foreground
+color of `transient-key-noop' (if non-suffixes are disallowed),
+`transient-key-stay' (if allowed and transient stays active), or
+`transient-key-exit' (if allowed and they exit the transient) is
+used to draw the line.
+
+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)
+                 (number :tag "substitute line with thickness")
+                 (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-show-during-minibuffer-read nil
+  "Whether to show the transient menu while reading in the minibuffer.
+
+This is only relevant to commands that do not close the menu, such as
+commands that set infix arguments.  If a command exits the menu, and
+uses the minibuffer, then the menu is always closed before the
+minibuffer is entered, irrespective of the value of this option.
+
+When nil (the default), hide the menu while the minibuffer is in use.
+When t, keep showing the menu, but allow for the menu window to be
+resized, to ensure that completion candidates can be displayed.
+
+When `fixed', keep showing the menu and prevent it from being resized,
+which may make it impossible to display the completion candidates.  If
+that ever happens for you, consider using t or an integer, as described
+below.
+
+If the value is `fixed' and the menu window uses the full height of its
+frame, then the former is ignored and resizing is allowed anyway.  This
+is necessary because individual menus may use unusual display actions
+different from what `transient-display-buffer-action' specifies (likely
+to display that menu in a side-window).
+
+When using a third-party mode, which automatically resizes windows
+\(e.g., by calling `balance-windows' on `post-command-hook'), then
+`fixed' (or nil) is likely a better choice than t.
+
+The value can also be an integer, in which case the behavior depends on
+whether at least that many lines are left to display windows other than
+the menu window.  If that is the case, display the menu and preserve the
+size of that window.  Otherwise, allow resizing the menu window if the
+number is positive, or hide the menu if it is negative."
+  :package-version '(transient . "0.8.0")
+  :group 'transient
+  :type '(choice
+          (const :tag "Hide menu" nil)
+          (const :tag "Show menu and preserve size" fixed)
+          (const :tag "Show menu and allow resizing" t)
+          (natnum :tag "Show menu, allow resizing if less than N lines left"
+                  :format "\n   %t: %v"
+                  :value 20)
+          (integer :tag "Show menu, except if less than N lines left"
+                   :format "\n   %t: %v"
+                   :value -20)))
+
+(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 shorthand (e.g., \"-v\").
+In the rare case that a short-hand is specified but does not
+match the key binding, then it is highlighted differently.
+
+The highlighting is done using `transient-mismatched-key'
+and `transient-nonstandard-key'."
+  :package-version '(transient . "0.1.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-highlight-higher-levels nil
+  "Whether to highlight suffixes on higher levels.
+
+This is primarily intended for package authors.
+
+When non-nil then highlight the description of suffixes whose
+level is above 4, the default of `transient-default-level'.
+Assuming you have set that variable to 7, this highlights all
+suffixes that won't be available to users without them making
+the same customization."
+  :package-version '(transient . "0.3.6")
+  :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-semantic-coloring t
+  "Whether to use colors to indicate transient behavior.
+
+If non-nil, then the key binding of each suffix is colorized to
+indicate whether it exits the transient state or not, and the
+line that is drawn below the transient popup buffer is used to
+indicate the behavior of non-suffix commands."
+  :package-version '(transient . "0.5.0")
+  :group 'transient
+  :type 'boolean)
+
+(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-align-variable-pitch nil
+  "Whether to align columns pixel-wise in the popup buffer.
+
+If this is non-nil, then columns are aligned pixel-wise to
+support variable-pitch fonts.  Keys are not aligned, so you
+should use a fixed-pitch font for the `transient-key' face.
+Other key faces inherit from that face unless a theme is
+used that breaks that relationship.
+
+This option is intended for users who use a variable-pitch
+font for the `default' face.
+
+See also `transient-force-fixed-pitch'."
+  :package-version '(transient . "0.4.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-force-fixed-pitch nil
+  "Whether to force use of monospaced font in the 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.
+
+See also `transient-align-variable-pitch'."
+  :package-version '(transient . "0.2.0")
+  :group 'transient
+  :type 'boolean)
+
+(defcustom transient-force-single-column nil
+  "Whether to force use of a single column to display suffixes.
+
+This might be useful for users with low vision who use large
+text and might otherwise have to scroll in two dimensions."
+  :package-version '(transient . "0.3.6")
+  :group 'transient
+  :type 'boolean)
+
+(defconst transient--max-level 7)
+(defconst transient--default-child-level 1)
+(defconst transient--default-prefix-level 4)
+
+(defcustom transient-default-level transient--default-prefix-level
+  "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 "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 "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 "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-argument '((t :inherit font-lock-string-face :weight bold))
+  "Face used for enabled arguments."
+  :group 'transient-faces)
+
+(defface transient-inactive-argument '((t :inherit shadow))
+  "Face used for inactive arguments."
+  :group 'transient-faces)
+
+(defface transient-value '((t :inherit font-lock-string-face :weight bold))
+  "Face used for values."
+  :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-inapt-suffix '((t :inherit shadow :italic t))
+  "Face used for suffixes that are inapt at this time."
+  :group 'transient-faces)
+
+(defface transient-active-infix '((t :inherit highlight))
+  "Face used for the infix for which the value is being read."
+  :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-higher-level
+  `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1)
+              :color ,(let ((color (face-attribute 'shadow :foreground nil t)))
+                        (or (and (not (eq color 'unspecified)) color)
+                            "grey60")))))
+  "Face optionally used to highlight suffixes on higher levels.
+See also option `transient-highlight-higher-levels'."
+  :group 'transient-faces)
+
+(defface transient-delimiter '((t :inherit shadow))
+  "Face used for delimiters and separators.
+This includes the parentheses around values and the pipe
+character used to separate possible values from each other."
+  :group 'transient-faces)
+
+(defface transient-key '((t :inherit font-lock-builtin-face))
+  "Face used for keys."
+  :group 'transient-faces)
+
+(defface transient-key-stay
+  `((((class color) (background light))
+     :inherit transient-key
+     :foreground "#22aa22")
+    (((class color) (background dark))
+     :inherit transient-key
+     :foreground "#ddffdd"))
+  "Face used for keys of suffixes that don't exit transient state."
+  :group 'transient-faces)
+
+(defface transient-key-noop
+  `((((class color) (background light))
+     :inherit transient-key
+     :foreground "grey80")
+    (((class color) (background dark))
+     :inherit transient-key
+     :foreground "grey30"))
+  "Face used for keys of suffixes that currently cannot be invoked."
+  :group 'transient-faces)
+
+(defface transient-key-return
+  `((((class color) (background light))
+     :inherit transient-key
+     :foreground "#aaaa11")
+    (((class color) (background dark))
+     :inherit transient-key
+     :foreground "#ffffcc"))
+  "Face used for keys of suffixes that return to the parent transient."
+  :group 'transient-faces)
+
+(defface transient-key-exit
+  `((((class color) (background light))
+     :inherit transient-key
+     :foreground "#aa2222")
+    (((class color) (background dark))
+     :inherit transient-key
+     :foreground "#ffdddd"))
+  "Face used for keys of suffixes that exit transient state."
+  :group 'transient-faces)
+
+(defface transient-unreachable-key
+  '((t :inherit (shadow transient-key) :weight normal))
+  "Face used for keys unreachable from the current prefix sequence."
+  :group 'transient-faces)
+
+(defface transient-nonstandard-key
+  `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1)
+              :color "cyan")))
+  "Face optionally used to highlight keys conflicting with short-argument.
+See also option `transient-highlight-mismatched-keys'."
+  :group 'transient-faces)
+
+(defface transient-mismatched-key
+  `((t :box ( :line-width ,(if (>= emacs-major-version 28) (cons -1 -1) -1)
+              :color "magenta")))
+  "Face optionally used to highlight keys without a short-argument.
+See also option `transient-highlight-mismatched-keys'."
+  :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 (list file)
+  (make-directory (file-name-directory file) t)
+  (setq list (cl-sort (copy-sequence list) #'string< :key #'car))
+  (with-temp-file file
+    (let ((print-level nil)
+          (print-length nil)
+          (pp-default-function 'pp-28)
+          (fill-column 999))
+      (pp list (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)
+   (init-value  :initarg :init-value)
+   (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)
+   (show-help   :initarg :show-help   :initform nil)
+   (info-manual :initarg :info-manual :initform nil)
+   (man-page    :initarg :man-page    :initform nil)
+   (transient-suffix     :initarg :transient-suffix     :initform nil)
+   (transient-non-suffix :initarg :transient-non-suffix :initform nil)
+   (transient-switch-frame :initarg :transient-switch-frame)
+   (refresh-suffixes     :initarg :refresh-suffixes     :initform nil)
+   (environment          :initarg :environment          :initform nil)
+   (incompatible         :initarg :incompatible         :initform nil)
+   (suffix-description   :initarg :suffix-description)
+   (display-action       :initarg :display-action       :initform nil)
+   (mode-line-format     :initarg :mode-line-format)
+   (variable-pitch       :initarg :variable-pitch       :initform nil)
+   (column-widths        :initarg :column-widths        :initform nil)
+   (unwind-suffix        :documentation "Internal use." :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 ()
+  ((parent
+    :initarg :parent
+    :initform nil
+    :documentation "The parent group object.")
+   (level
+    :initarg :level
+    :initform (symbol-value 'transient--default-child-level)
+    :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.")
+   (inapt
+    :initform nil)
+   (inapt-face
+    :initarg :inapt-face
+    :initform 'transient-inapt-suffix)
+   (inapt-if
+    :initarg :inapt-if
+    :initform nil
+    :documentation "Inapt if predicate returns non-nil.")
+   (inapt-if-not
+    :initarg :inapt-if-not
+    :initform nil
+    :documentation "Inapt if predicate returns nil.")
+   (inapt-if-non-nil
+    :initarg :inapt-if-non-nil
+    :initform nil
+    :documentation "Inapt if variable's value is non-nil.")
+   (inapt-if-nil
+    :initarg :inapt-if-nil
+    :initform nil
+    :documentation "Inapt if variable's value is nil.")
+   (inapt-if-mode
+    :initarg :inapt-if-mode
+    :initform nil
+    :documentation "Inapt if major-mode matches value.")
+   (inapt-if-not-mode
+    :initarg :inapt-if-not-mode
+    :initform nil
+    :documentation "Inapt if major-mode does not match value.")
+   (inapt-if-derived
+    :initarg :inapt-if-derived
+    :initform nil
+    :documentation "Inapt if major-mode derives from value.")
+   (inapt-if-not-derived
+    :initarg :inapt-if-not-derived
+    :initform nil
+    :documentation "Inapt if major-mode does not derive from value."))
+  "Abstract superclass for group and suffix classes.
+
+It is undefined which predicates are used if more than one `if*'
+predicate slots or more than one `inapt-if*' slots are non-nil."
+  :abstract t)
+
+(defclass transient-suffix (transient-child)
+  ((definition  :allocation :class    :initform nil)
+   (key         :initarg :key)
+   (command     :initarg :command)
+   (transient   :initarg :transient)
+   (format      :initarg :format      :initform " %k %d")
+   (description :initarg :description :initform nil)
+   (face        :initarg :face        :initform nil)
+   (show-help   :initarg :show-help   :initform nil)
+   (summary     :initarg :summary     :initform nil))
+  "Superclass for suffix command.")
+
+(defclass transient-information (transient-suffix)
+  ((format :initform " %k %d")
+   (key    :initform " "))
+  "Display-only information, aligned with suffix keys.
+Technically a suffix object with no associated command.")
+
+(defclass transient-information* (transient-information)
+  ((format :initform " %d"))
+  "Display-only information, aligned with suffix descriptions.
+Technically a suffix object with no associated command.")
+
+(defclass transient-infix (transient-suffix)
+  ((transient                         :initform t)
+   (argument    :initarg :argument)
+   (shortarg    :initarg :shortarg)
+   (value                             :initform nil)
+   (init-value  :initarg :init-value)
+   (unsavable   :initarg :unsavable   :initform nil)
+   (multi-value :initarg :multi-value :initform nil)
+   (always-read :initarg :always-read :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-option) ()
+  ((key         :initform "--")
+   (argument    :initform "--")
+   (multi-value :initform rest)
+   (reader      :initform transient-read-files))
+  "Class used for the \"--\" argument or similar.
+All remaining arguments are treated as files.
+They become the value of this argument.")
+
+(defclass transient-value-preset (transient-suffix)
+  ((transient :initform t)
+   (set :initarg := :initform nil))
+  "Class used by the `transient-preset' suffix command.")
+
+(defclass transient-describe-target (transient-suffix)
+  ((transient :initform #'transient--do-suspend)
+   (helper :initarg :helper :initform nil)
+   (target :initarg := :initform nil))
+  "Class used by the `transient-describe' suffix command.")
+
+;;;; Group
+
+(defclass transient-group (transient-child)
+  ((suffixes       :initarg :suffixes       :initform nil)
+   (hide           :initarg :hide           :initform nil)
+   (description    :initarg :description    :initform nil)
+   (pad-keys       :initarg :pad-keys       :initform nil)
+   (info-format    :initarg :info-format    :initform nil)
+   (setup-children :initarg :setup-children))
+  "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 strings.  Each subgroup represents a column.
+This class takes care of inserting the subgroups' elements.")
+
+(defclass transient-subgroups (transient-group) ()
+  "Group class that wraps other groups.
+
+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 transient-define-prefix (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]))
+           (indent defun)
+           (doc-string 3))
+  (pcase-let
+      ((`(,class ,slots ,suffixes ,docstr ,body ,interactive-only)
+        (transient--expand-define-args args arglist 'transient-define-prefix)))
+    `(progn
+       (defalias ',name
+         ,(if body
+              `(lambda ,arglist ,@body)
+            `(lambda ()
+               (interactive)
+               (transient-setup ',name))))
+       (put ',name 'interactive-only ,interactive-only)
+       (put ',name 'function-documentation ,docstr)
+       (put ',name 'transient--prefix
+            (,(or class 'transient-prefix) :command ',name ,@slots))
+       (put ',name 'transient--layout
+            (list ,@(mapcan (lambda (s) (transient--parse-child name s))
+                            suffixes))))))
+
+(defmacro transient-define-suffix (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]
+                    [&optional ("interactive" interactive) def-body]))
+           (indent defun)
+           (doc-string 3))
+  (pcase-let
+      ((`(,class ,slots ,_ ,docstr ,body ,interactive-only)
+        (transient--expand-define-args args arglist 'transient-define-suffix)))
+    `(progn
+       (defalias ',name
+         ,(if (and (not body) class (oref-default class definition))
+              `(oref-default ',class definition)
+            `(lambda ,arglist ,@body)))
+       (put ',name 'interactive-only ,interactive-only)
+       (put ',name 'function-documentation ,docstr)
+       (put ',name 'transient--suffix
+            (,(or class 'transient-suffix) :command ',name ,@slots)))))
+
+(defmacro transient-augment-suffix (name &rest args)
+  "Augment existing command NAME with a new transient suffix object.
+Similar to `transient-define-suffix' but define a suffix object only.
+\n\(fn NAME [KEYWORD VALUE]...)"
+  (declare (debug (&define name [&rest keywordp sexp]))
+           (indent defun))
+  (pcase-let
+      ((`(,class ,slots)
+        (transient--expand-define-args args nil 'transient-augment-suffix t)))
+    `(put ',name 'transient--suffix
+          (,(or class 'transient-suffix) :command ',name ,@slots))))
+
+(defmacro transient-define-infix (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.
+
+At least one key-value pair is required.  All transient infix
+commands are equal to each other (but not eq).  It is meaning-
+less to define an infix command, without providing at least one
+keyword argument (usually `:argument' or `:variable', depending
+on the class).  The suffix class defaults to `transient-switch'
+and can be set using the `:class' keyword.
+
+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-define-suffix' to define
+the infix command and use t as the value of the `:transient'
+keyword.
+
+\(fn NAME ARGLIST [DOCSTRING] KEYWORD VALUE [KEYWORD VALUE]...)"
+  (declare (debug ( &define name lambda-list
+                    [&optional lambda-doc]
+                    keywordp sexp
+                    [&rest keywordp sexp]))
+           (indent defun)
+           (doc-string 3))
+  (pcase-let
+      ((`(,class ,slots ,_ ,docstr ,_ ,interactive-only)
+        (transient--expand-define-args args arglist 'transient-define-infix t)))
+    `(progn
+       (defalias ',name #'transient--default-infix-command)
+       (put ',name 'interactive-only ,interactive-only)
+       (put ',name 'completion-predicate #'transient--suffix-only)
+       (put ',name 'function-documentation ,docstr)
+       (put ',name 'transient--suffix
+            (,(or class 'transient-switch) :command ',name ,@slots)))))
+
+(defalias 'transient-define-argument #'transient-define-infix
+  "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 `transient-define-infix' instead.
+
+\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)")
+
+(defun transient--default-infix-command ()
+  ;; Most infix commands are but an alias for this command.
+  "Cannot show any documentation for this transient infix command.
+
+When you request help for an infix command using `transient-help', that
+usually shows the respective man-page and tries to jump to the location
+where the respective argument is being described.
+
+If no man-page is specified for the containing transient menu, then the
+docstring is displayed instead, if any.
+
+If the infix command doesn't have a docstring, as is the case here, then
+this docstring is displayed instead, because technically infix commands
+are aliases for `transient--default-infix-command'.
+
+`describe-function' also shows the docstring of the infix command,
+falling back to that of the same aliased command."
+  (interactive)
+  (let ((obj (transient-suffix-object)))
+    (transient-infix-set obj (transient-infix-read obj)))
+  (transient--show))
+(put 'transient--default-infix-command 'interactive-only t)
+(put 'transient--default-infix-command 'completion-predicate
+     #'transient--suffix-only)
+
+(define-advice find-function-advised-original
+    (:around (fn func) transient-default-infix)
+  "Return nil instead of `transient--default-infix-command'.
+When using `find-function' to jump to the definition of a transient
+infix command/argument, then we want to actually jump to that, not to
+the definition of `transient--default-infix-command', which all infix
+commands are aliases for."
+  (let ((val (funcall fn func)))
+    (and val (not (eq val 'transient--default-infix-command)) val)))
+
+(eval-and-compile ;transient--expand-define-args
+  (defun transient--expand-define-args (args &optional arglist form nobody)
+    ;; ARGLIST and FORM are only optional for backward compatibility.
+    ;; This is necessary because "emoji.el" from Emacs 29 calls this
+    ;; function directly, with just one argument.
+    (unless (listp arglist)
+      (error "Mandatory ARGLIST is missing"))
+    (let (class keys suffixes docstr declare (interactive-only t))
+      (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 (let ((arg (car args)))
+               (or (vectorp arg)
+                   (and arg (symbolp arg))))
+        (push (pop args) suffixes))
+      (when (eq (car-safe (car args)) 'declare)
+        (setq declare (car args))
+        (setq args (cdr args))
+        (when-let ((int (assq 'interactive-only declare)))
+          (setq interactive-only (cadr int))
+          (delq int declare))
+        (unless (cdr declare)
+          (setq declare nil)))
+      (cond
+       ((not args))
+       (nobody
+        (error "%s: No function body allowed" form))
+       ((not (eq (car-safe (nth (if declare 1 0) args)) 'interactive))
+        (error "%s: Interactive form missing" form)))
+      (list (if (eq (car-safe class) 'quote)
+                (cadr class)
+              class)
+            (nreverse keys)
+            (nreverse suffixes)
+            docstr
+            (if declare (cons declare args) args)
+            interactive-only))))
+
+(defun transient--parse-child (prefix spec)
+  (cl-typecase spec
+    (null    (error "Invalid transient--parse-child spec: %s" spec))
+    (symbol  (let ((value (symbol-value spec)))
+               (if (and (listp value)
+                        (or (listp (car value))
+                            (vectorp (car value))))
+                   (mapcan (lambda (s) (transient--parse-child prefix s)) value)
+                 (transient--parse-child prefix value))))
+    (vector  (and-let* ((c (transient--parse-group  prefix spec))) (list c)))
+    (list    (and-let* ((c (transient--parse-suffix prefix spec))) (list c)))
+    (string  (list spec))
+    (t       (error "Invalid transient--parse-child spec: %s" spec))))
+
+(defun transient--parse-group (prefix spec)
+  (let ((spec (append spec nil))
+        level class args)
+    (when (integerp (car spec))
+      (setq level (pop spec)))
+    (when (stringp (car spec))
+      (setq args (plist-put args :description (pop spec))))
+    ;; Merge value of [... GROUP-VARIABLE], if any.
+    (let ((spec* spec))
+      (while (keywordp (car spec*))
+        (setq spec* (cddr spec*)))
+      (when (and (length= spec* 1) (symbolp (car spec*)))
+        (let ((rest (append (symbol-value (car spec*)) nil))
+              (args nil))
+          (while (keywordp (car rest))
+            (setq args (nconc (list (pop rest) (pop rest)) args)))
+          (setq spec (nconc args (butlast spec) rest)))))
+    (while (keywordp (car spec))
+      (let* ((key (pop spec))
+             (val (if spec (pop spec) (error "No value for `%s'" key))))
+        (cond ((eq key :class)
+               (setq class val))
+              ((or (symbolp val)
+                   (and (listp val) (not (eq (car val) 'lambda))))
+               (setq args (plist-put args key (macroexp-quote val))))
+              ((setq args (plist-put args key val))))))
+    (unless (or spec class (not (plist-get args :setup-children)))
+      (message "WARNING: %s: When %s is used, %s must also be specified"
+               'transient-define-prefix :setup-children :class))
+    (list 'vector
+          (or level transient--default-child-level)
+          (list 'quote
+                (cond (class)
+                      ((cl-typep (car spec)
+                                 '(or vector (and symbol (not null))))
+                       'transient-columns)
+                      ('transient-column)))
+          (and args (cons 'list args))
+          (cons 'list
+                (mapcan (lambda (s) (transient--parse-child prefix s)) spec)))))
+
+(defun transient--parse-suffix (prefix spec)
+  (let (level class args)
+    (cl-flet ((use (prop value)
+                (setq args (plist-put args prop value))))
+      (pcase (car spec)
+        ((cl-type integer)
+         (setq level (pop spec))))
+      (pcase (car spec)
+        ((cl-type (or string vector))
+         (use :key (pop spec))))
+      (pcase (car spec)
+        ((guard (or (stringp (car spec))
+                    (and (eq (car-safe (car spec)) 'lambda)
+                         (not (commandp (car spec))))))
+         (use :description (pop spec)))
+        ((and (cl-type (and symbol (not keyword) (not command)))
+              (guard (commandp (cadr spec))))
+         (use :description (macroexp-quote (pop spec)))))
+      (pcase (car spec)
+        ((or :info :info*))
+        ((and (cl-type keyword) invalid)
+         (error "Need command, argument, `:info' or `:info*'; got `%s'" invalid))
+        ((cl-type symbol)
+         (use :command (macroexp-quote (pop spec))))
+        ;; During macro-expansion this is expected to be a `lambda'
+        ;; expression (i.e., source code).  When this is called from a
+        ;; `:setup-children' function, it may also be a function object
+        ;; (a.k.a a function value).  However, we never treat a string
+        ;; as a command, so we have to check for that explicitly.
+        ((cl-type (and command (not string)))
+         (let ((cmd (pop spec))
+               (sym (intern
+                     (format
+                      "transient:%s:%s:%d" prefix
+                      (replace-regexp-in-string (plist-get args :key) " " "")
+                      (prog1 gensym-counter (cl-incf gensym-counter))))))
+           (use :command
+                `(prog1 ',sym
+                   (put ',sym 'interactive-only t)
+                   (put ',sym 'completion-predicate #'transient--suffix-only)
+                   (defalias ',sym ,cmd)))))
+        ((cl-type (or string (and list (not null))))
+         (let ((arg (pop spec)))
+           (cl-typecase arg
+             (list
+              (use :shortarg (car arg))
+              (use :argument (cadr arg))
+              (setq arg (cadr arg)))
+             (string
+              (when-let ((shortarg (transient--derive-shortarg arg)))
+                (use :shortarg shortarg))
+              (use :argument arg)))
+           (use :command
+                (let ((sym (intern (format "transient:%s:%s" prefix arg))))
+                  `(prog1 ',sym
+                     (put ',sym 'interactive-only t)
+                     (put ',sym 'completion-predicate #'transient--suffix-only)
+                     (defalias ',sym #'transient--default-infix-command))))
+           (pcase (car spec)
+             ((cl-type (and (not null) (not keyword)))
+              (setq class 'transient-option)
+              (use :reader (macroexp-quote (pop spec))))
+             ((guard (string-suffix-p "=" arg))
+              (setq class 'transient-option))
+             (_ (setq class 'transient-switch)))))
+        (invalid
+         (error "Need command, argument, `:info' or `:info*'; got %s" invalid)))
+      (while (keywordp (car spec))
+        (let* ((key (pop spec))
+               (val (if spec (pop spec) (error "No value for `%s'" key))))
+          (pcase key
+            (:class (setq class val))
+            (:level (setq level val))
+            (:info  (setq class 'transient-information)
+                    (use :description val))
+            (:info* (setq class 'transient-information*)
+                    (use :description val))
+            ((guard (eq (car-safe val) '\,))
+             (use key (cadr val)))
+            ((guard (or (symbolp val)
+                        (and (listp val) (not (eq (car val) 'lambda)))))
+             (use key (macroexp-quote val)))
+            (_ (use key val)))))
+      (when spec
+        (error "Need keyword, got %S" (car spec)))
+      (when-let* (((not (plist-get args :key)))
+                  (shortarg (plist-get args :shortarg)))
+        (use :key shortarg)))
+    (list 'list
+          (or level transient--default-child-level)
+          (macroexp-quote (or class 'transient-suffix))
+          (cons 'list args))))
+
+(defun transient--derive-shortarg (arg)
+  (save-match-data
+    (and (string-match "\\`\\(-[a-zA-Z]\\)\\(\\'\\|=\\)" arg)
+         (match-string 1 arg))))
+
+(defun transient-command-completion-not-suffix-only-p (symbol _buffer)
+  "Say whether SYMBOL should be offered as a completion.
+If the value of SYMBOL's `completion-predicate' property is
+`transient--suffix-only', then return nil, otherwise return t.
+This is the case when a command should only ever be used as a
+suffix of a transient prefix command (as opposed to bindings
+in regular keymaps or by using `execute-extended-command')."
+  (not (eq (get symbol 'completion-predicate) 'transient--suffix-only)))
+
+(defalias 'transient--suffix-only #'ignore
+  "Ignore ARGUMENTS, do nothing, and return nil.
+See also `transient-command-completion-not-suffix-only-p'.
+Only use this alias as the value of the `completion-predicate'
+symbol property.")
+
+(when (and (boundp 'read-extended-command-predicate) ; since Emacs 28.1
+           (not read-extended-command-predicate))
+  (setq read-extended-command-predicate
+        #'transient-command-completion-not-suffix-only-p))
+
+(defun transient-parse-suffix (prefix suffix)
+  "Parse SUFFIX, to be added to PREFIX.
+PREFIX is a prefix command, a symbol.
+SUFFIX is a suffix command or a group specification (of
+  the same forms as expected by `transient-define-prefix').
+Intended for use in a group's `:setup-children' function."
+  (cl-assert (and prefix (symbolp prefix)))
+  (eval (car (transient--parse-child prefix suffix)) t))
+
+(defun transient-parse-suffixes (prefix suffixes)
+  "Parse SUFFIXES, to be added to PREFIX.
+PREFIX is a prefix command, a symbol.
+SUFFIXES is a list of suffix command or a group specification
+  (of the same forms as expected by `transient-define-prefix').
+Intended for use in a group's `:setup-children' function."
+  (cl-assert (and prefix (symbolp prefix)))
+  (mapcar (apply-partially #'transient-parse-suffix prefix) suffixes))
+
+;;; Edit
+
+(defun transient--insert-suffix (prefix loc suffix action &optional keep-other)
+  (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)))
+    (setq suf (eval suf t))
+    (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-let* ((bindingp (listp suf))
+                  (key (transient--spec-key suf))
+                  (conflict (car (transient--layout-member key prefix)))
+                  (conflictp
+                   (and (not (and (eq action 'replace)
+                                  (eq conflict elt)))
+                        (or (not keep-other)
+                            (eq (plist-get (nth 2 suf) :command)
+                                (plist-get (nth 2 conflict) :command)))
+                        (equal (transient--suffix-predicate suf)
+                               (transient--suffix-predicate conflict)))))
+        (transient-remove-suffix prefix key))
+      (pcase-exhaustive action
+        ('insert  (setcdr mem (cons elt (cdr mem)))
+                  (setcar mem suf))
+        ('append  (setcdr mem (cons suf (cdr mem))))
+        ('replace (setcar mem suf)))))))
+
+;;;###autoload
+(defun transient-insert-suffix (prefix loc suffix &optional keep-other)
+  "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 `transient-define-prefix').
+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).
+Remove a conflicting binding unless optional KEEP-OTHER is
+  non-nil.
+See info node `(transient)Modifying Existing Transients'."
+  (declare (indent defun))
+  (transient--insert-suffix prefix loc suffix 'insert keep-other))
+
+;;;###autoload
+(defun transient-append-suffix (prefix loc suffix &optional keep-other)
+  "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 `transient-define-prefix').
+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).
+Remove a conflicting binding unless optional KEEP-OTHER is
+  non-nil.
+See info node `(transient)Modifying Existing Transients'."
+  (declare (indent defun))
+  (transient--insert-suffix prefix loc suffix 'append keep-other))
+
+;;;###autoload
+(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 `transient-define-prefix').
+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))
+
+;;;###autoload
+(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 `transient-define-prefix').
+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)
+        ((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)
+  (and-let* ((obj (transient--suffix-prototype cmd)))
+    (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 transient-current-prefix nil
+  "The transient from which this suffix command was invoked.
+This is an object representing that transient, use
+`transient-current-command' to get the respective command.")
+
+(defvar transient-current-command nil
+  "The transient from which this suffix command was invoked.
+This is a symbol representing that transient, use
+`transient-current-prefix' to get the respective object.")
+
+(defvar transient-current-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 transient-exit-hook nil
+  "Hook run after exiting a transient.")
+
+(defvar transient-setup-buffer-hook nil
+  "Hook run when setting up the transient buffer.
+That buffer is current and empty when this hook runs.")
+
+(defvar transient--prefix nil)
+(defvar transient--layout nil)
+(defvar transient--suffixes nil)
+
+(defconst transient--stay t   "Do not exit the transient.")
+(defconst transient--exit nil "Do exit the transient.")
+
+(defvar transient--exitp nil "Whether to exit the transient.")
+(defvar transient--showp nil "Whether to show the transient popup buffer.")
+(defvar transient--helpp nil "Whether help-mode is active.")
+(defvar transient--docsp nil "Whether docstring-mode is active.")
+(defvar transient--editp nil "Whether edit-mode is active.")
+
+(defvar transient--refreshp nil
+  "Whether to refresh the transient completely.")
+
+(defvar transient--all-levels-p nil
+  "Whether temporary display of suffixes on all levels is active.")
+
+(defvar transient--timer nil)
+
+(defvar transient--stack nil)
+
+(defvar transient--minibuffer-depth 0)
+
+(defvar transient--buffer-name " *transient*"
+  "Name of the transient buffer.")
+
+(defvar transient--buffer nil
+  "The transient menu buffer.")
+
+(defvar transient--window nil
+  "The window used to display the transient popup buffer.")
+
+(defvar transient--original-window nil
+  "The window that was selected before the transient was invoked.
+Usually it remains selected while the transient is active.")
+
+(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--restore-winconf nil
+  "Window configuration to restore after exiting help.")
+
+(defvar transient--shadowed-buffer nil
+  "The buffer that is temporarily shadowed by the transient buffer.
+This is bound while the suffix predicate is being evaluated and while
+drawing in the transient buffer.")
+
+(defvar transient--pending-suffix nil
+  "The suffix that is currently being processed.
+This is bound while the suffix predicate is being evaluated,
+and while functions that return faces are being evaluated.")
+
+(defvar transient--pending-group nil
+  "The group that is currently being processed.
+This is bound while the suffixes are drawn in the transient buffer.")
+
+(defvar transient--debug nil
+  "Whether to put debug information into *Messages*.")
+
+(defvar transient--history nil)
+
+(defvar transient--scroll-commands
+  '(transient-scroll-up
+    transient-scroll-down
+    mwheel-scroll
+    scroll-bar-toolkit-scroll))
+
+;;; Identities
+
+(defun transient-active-prefix (&optional prefixes)
+  "Return the active transient object.
+
+Return nil if there is no active transient, if the transient buffer
+isn't shown, and while the active transient is suspended (e.g., while
+the minibuffer is in use).
+
+Unlike `transient-current-prefix', which is only ever non-nil in code
+that is run directly by a command that is invoked while a transient
+is current, this function is also suitable for use in asynchronous
+code, such as timers and callbacks (this function's main use-case).
+
+If optional PREFIXES is non-nil, it must be a prefix command symbol
+or a list of symbols, in which case the active transient object is
+only returned if it matches one of PREFIXES."
+  (and transient--showp
+       transient--prefix
+       (or (not prefixes)
+           (memq (oref transient--prefix command) (ensure-list prefixes)))
+       (or (memq 'transient--pre-command pre-command-hook)
+           (and (memq t pre-command-hook)
+                (memq 'transient--pre-command
+                      (default-value 'pre-command-hook))))
+       transient--prefix))
+
+(defun transient-prefix-object ()
+  "Return the current prefix as an object.
+
+While a transient is being setup or refreshed (which involves
+preparing its suffixes) the variable `transient--prefix' can be
+used to access the prefix object.  Thus this is what has to be
+used in suffix methods such as `transient-format-description',
+and in object-specific functions that are stored in suffix slots
+such as `description'.
+
+When a suffix command is invoked (i.e., in its `interactive' form
+and function body) then the variable `transient-current-prefix'
+has to be used instead.
+
+Two distinct variables are needed, because any prefix may itself
+be used as a suffix of another prefix, and such sub-prefixes have
+to be able to tell themselves apart from the prefix they were
+invoked from.
+
+Regular suffix commands, which are not prefixes, do not have to
+concern themselves with this distinction, so they can use this
+function instead.  In the context of a plain suffix, it always
+returns the value of the appropriate variable."
+  (or transient--prefix transient-current-prefix))
+
+(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, which
+are usually aliases of `transient--default-infix-command', which
+is defined like this:
+
+  (defun transient--default-infix-command ()
+    (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)"
+  (when command
+    (cl-check-type command command))
+  (cond
+   (transient--pending-suffix)
+   ((or transient--prefix
+        transient-current-prefix)
+    (let ((suffixes
+           (cl-remove-if-not
+            (lambda (obj)
+              (eq (oref obj command)
+                  (or command
+                      (if (eq this-command 'transient-set-level)
+                          ;; This is how it can look up for which
+                          ;; command it is setting the level.
+                          this-original-command
+                        this-command))))
+            (or transient--suffixes
+                transient-current-suffixes))))
+      (or (if (cdr suffixes)
+              (cl-find-if
+               (lambda (obj)
+                 (equal (listify-key-sequence (transient--kbd (oref obj key)))
+                        (listify-key-sequence (this-command-keys))))
+               suffixes)
+            (car suffixes))
+          ;; COMMAND is only provided if `this-command' is meaningless, in
+          ;; which case `this-command-keys' is also meaningless, making it
+          ;; impossible to disambiguate redundant bindings.
+          (if command
+              (car suffixes)
+            ;; TODO Decide whether it is legimate to use this function
+            ;; as a predicate, and also whether to return an object for
+            ;; suffixes common to all prefixes.  See #29 and #337.
+            (error "BUG: Cannot determine suffix object")))))
+   ((and-let* ((obj (transient--suffix-prototype (or command this-command)))
+               (obj (clone obj)))
+      (progn
+        (transient-init-scope obj)
+        (transient-init-value obj)
+        obj)))))
+
+(defun transient--suffix-prototype (command)
+  (or (get command 'transient--suffix)
+      (seq-some (lambda (cmd) (get cmd 'transient--suffix))
+                (function-alias-p command))))
+
+;;; Keymaps
+
+(defvar-keymap transient-base-map
+  :doc "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.
+
+If you add a new command here, then you must also add a binding
+to `transient-predicate-map'."
+  "ESC ESC ESC" #'transient-quit-all
+  "C-g"     #'transient-quit-one
+  "C-q"     #'transient-quit-all
+  "C-z"     #'transient-suspend
+  "C-v"     #'transient-scroll-up
+  "C-M-v"   #'transient-scroll-down
+  "<next>"  #'transient-scroll-up
+  "<prior>" #'transient-scroll-down)
+
+(defvar transient-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map transient-base-map)
+    (keymap-set map "C-u"   #'universal-argument)
+    (keymap-set map "C--"   #'negative-argument)
+    (keymap-set map "C-t"   #'transient-show)
+    (keymap-set map "?"     #'transient-help)
+    (keymap-set map "C-h"   #'transient-help)
+    ;; Also bound to "C-x p" and "C-x n" in transient-common-commands.
+    (keymap-set map "C-M-p" #'transient-history-prev)
+    (keymap-set map "C-M-n" #'transient-history-next)
+    (when (fboundp 'other-frame-prefix) ;Emacs >= 28.1
+      (keymap-set map "C-x 5 5" 'other-frame-prefix)
+      (keymap-set map "C-x 4 4" 'other-window-prefix))
+    map)
+  "Top-level keymap used by all transients.
+
+If you add a new command here, then you must also add a binding
+to `transient-predicate-map'.  See also `transient-base-map'.")
+
+(defvar-keymap transient-edit-map
+  :doc "Keymap that is active while a transient in is in \"edit mode\"."
+  :parent transient-base-map
+  "?"     #'transient-help
+  "C-h"   #'transient-help
+  "C-x l" #'transient-set-level)
+
+(defvar-keymap transient-sticky-map
+  :doc "Keymap that is active while an incomplete key sequence is active."
+  :parent transient-base-map
+  "C-g" #'transient-quit-seq)
+
+(defvar transient--common-command-prefixes '(?\C-x))
+
+(put 'transient-common-commands
+     'transient--layout
+     (list
+      (eval
+       (car (transient--parse-child
+             'transient-common-commands
+             (vector
+              :hide
+              (lambda ()
+                (and (not (memq
+                           (car (bound-and-true-p transient--redisplay-key))
+                           transient--common-command-prefixes))
+                     (not transient-show-common-commands)))
+              (vector
+               "Value commands"
+               (list "C-x s  " "Set"            #'transient-set)
+               (list "C-x C-s" "Save"           #'transient-save)
+               (list "C-x C-k" "Reset"          #'transient-reset)
+               (list "C-x p  " "Previous value" #'transient-history-prev)
+               (list "C-x n  " "Next value"     #'transient-history-next))
+              (vector
+               "Sticky commands"
+               ;; Like `transient-sticky-map' except that
+               ;; "C-g" has to be bound to a different command.
+               (list "C-g" "Quit prefix or transient" #'transient-quit-one)
+               (list "C-q" "Quit transient stack"     #'transient-quit-all)
+               (list "C-z" "Suspend transient stack"  #'transient-suspend))
+              (vector
+               "Customize"
+               (list "C-x t" #'transient-toggle-common)
+               (list "C-x l" "Show/hide suffixes" #'transient-set-level)
+               (list "C-x a" #'transient-toggle-level-limit)))))
+       t)))
+
+(defvar-keymap transient-popup-navigation-map
+  :doc "One of the keymaps used when popup navigation is enabled.
+See `transient-enable-popup-navigation'."
+  "<down-mouse-1>" #'transient-noop
+  "<up>"   #'transient-backward-button
+  "<down>" #'transient-forward-button
+  "C-r"    #'transient-isearch-backward
+  "C-s"    #'transient-isearch-forward
+  "M-RET"  #'transient-push-button)
+
+(defvar-keymap transient-button-map
+  :doc "One of the keymaps used when popup navigation is enabled.
+See `transient-enable-popup-navigation'."
+  "<mouse-1>" #'transient-push-button
+  "<mouse-2>" #'transient-push-button)
+
+(defvar-keymap transient-resume-mode-map
+  :doc "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."
+  "<remap> <Man-quit>"    #'transient-resume
+  "<remap> <Info-exit>"   #'transient-resume
+  "<remap> <quit-window>" #'transient-resume)
+
+(defvar-keymap transient-predicate-map
+  :doc "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."
+  "<transient-suspend>"           #'transient--do-suspend
+  "<transient-help>"              #'transient--do-stay
+  "<transient-set-level>"         #'transient--do-stay
+  "<transient-history-prev>"      #'transient--do-stay
+  "<transient-history-next>"      #'transient--do-stay
+  "<universal-argument>"          #'transient--do-stay
+  "<universal-argument-more>"     #'transient--do-stay
+  "<negative-argument>"           #'transient--do-minus
+  "<digit-argument>"              #'transient--do-stay
+  "<other-frame-prefix>"          #'transient--do-stay
+  "<other-window-prefix>"         #'transient--do-stay
+  "<top-level>"                   #'transient--do-quit-all
+  "<transient-quit-all>"          #'transient--do-quit-all
+  "<transient-quit-one>"          #'transient--do-quit-one
+  "<transient-quit-seq>"          #'transient--do-stay
+  "<transient-show>"              #'transient--do-stay
+  "<transient-update>"            #'transient--do-stay
+  "<transient-set>"               #'transient--do-call
+  "<transient-set-and-exit>"      #'transient--do-exit
+  "<transient-save>"              #'transient--do-call
+  "<transient-save-and-exit>"     #'transient--do-exit
+  "<transient-reset>"             #'transient--do-call
+  "<describe-key-briefly>"        #'transient--do-stay
+  "<describe-key>"                #'transient--do-stay
+  "<transient-scroll-up>"         #'transient--do-stay
+  "<transient-scroll-down>"       #'transient--do-stay
+  "<mwheel-scroll>"               #'transient--do-stay
+  "<scroll-bar-toolkit-scroll>"   #'transient--do-stay
+  "<transient-noop>"              #'transient--do-noop
+  "<transient-mouse-push-button>" #'transient--do-move
+  "<transient-push-button>"       #'transient--do-push-button
+  "<transient-backward-button>"   #'transient--do-move
+  "<transient-forward-button>"    #'transient--do-move
+  "<transient-isearch-backward>"  #'transient--do-move
+  "<transient-isearch-forward>"   #'transient--do-move
+  "<transient-copy-menu-text>"    #'transient--do-stay
+  "<transient-toggle-docstrings>" #'transient--do-stay
+  ;; If a valid but incomplete prefix sequence is followed by
+  ;; an unbound key, then Emacs calls the `undefined' command
+  ;; but does not set `this-command', `this-original-command'
+  ;; or `real-this-command' accordingly.  Instead they are nil.
+  "<nil>"                         #'transient--do-warn
+  ;; Bound to the `mouse-movement' event, this command is similar
+  ;; to `ignore'.
+  "<ignore-preserving-kill-region>" #'transient--do-noop)
+
+(defvar transient--transient-map nil)
+(defvar transient--predicate-map nil)
+(defvar transient--redisplay-map nil)
+(defvar transient--redisplay-key nil)
+
+(defun transient--push-keymap (var)
+  (let ((map (symbol-value var)))
+    (transient--debug "     push %s%s" var (if map "" " VOID"))
+    (when map
+      (with-demoted-errors "transient--push-keymap: %S"
+        (internal-push-keymap map 'overriding-terminal-local-map)))))
+
+(defun transient--pop-keymap (var)
+  (let ((map (symbol-value var)))
+    (when map
+      (transient--debug "     pop  %s" var)
+      (with-demoted-errors "transient--pop-keymap: %S"
+        (internal-pop-keymap 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 (oref obj command))
+               (alt (transient--lookup-key map kbd)))
+          (cond ((not alt)
+                 (define-key map kbd cmd))
+                ((eq alt cmd))
+                ((transient--inapt-suffix-p obj))
+                ((and-let* ((obj (transient-suffix-object alt)))
+                   (transient--inapt-suffix-p obj))
+                 (define-key map kbd cmd))
+                (transient-detect-key-conflicts
+                 (error "Cannot bind %S to %s and also %s"
+                        (string-trim key) cmd alt))
+                ((define-key map kbd cmd))))))
+    (when-let ((b (keymap-lookup map "-"))) (keymap-set map "<kp-subtract>" b))
+    (when-let ((b (keymap-lookup map "="))) (keymap-set map "<kp-equal>" b))
+    (when-let ((b (keymap-lookup map "+"))) (keymap-set map "<kp-add>" b))
+    (when transient-enable-popup-navigation
+      ;; `transient--make-redisplay-map' maps only over bindings that are
+      ;; directly in the base keymap, so that cannot be a composed keymap.
+      (set-keymap-parent
+       map (make-composed-keymap
+            (keymap-parent map)
+            transient-popup-navigation-map)))
+    map))
+
+(defun transient--make-predicate-map ()
+  (let* ((default (transient--resolve-pre-command
+                   (oref transient--prefix transient-suffix)))
+         (return (and transient--stack (eq default t)))
+         (map (make-sparse-keymap)))
+    (set-keymap-parent map transient-predicate-map)
+    (when (or (and (slot-boundp transient--prefix 'transient-switch-frame)
+                   (transient--resolve-pre-command
+                    (not (oref transient--prefix transient-switch-frame))))
+              (memq (transient--resolve-pre-command
+                     (oref transient--prefix transient-non-suffix))
+                    '(nil transient--do-warn transient--do-noop)))
+      (define-key map [handle-switch-frame] #'transient--do-suspend))
+    (dolist (obj transient--suffixes)
+      (let* ((cmd (oref obj command))
+             (id (vector cmd))
+             (kind (cond ((get cmd 'transient--prefix)    'prefix)
+                         ((cl-typep obj 'transient-infix) 'infix)
+                         (t                               'suffix)))
+             (pre (cond
+                   ((oref obj inapt) #'transient--do-warn-inapt)
+                   ((slot-boundp obj 'transient)
+                    (pcase (list kind
+                                 (transient--resolve-pre-command
+                                  (oref obj transient))
+                                 return)
+                      (`(prefix   t ,_) #'transient--do-recurse)
+                      (`(prefix nil ,_) #'transient--do-stack)
+                      (`(infix    t ,_) #'transient--do-stay)
+                      (`(suffix   t ,_) #'transient--do-call)
+                      ('(suffix nil  t) #'transient--do-return)
+                      (`(,_     nil ,_) #'transient--do-exit)
+                      (`(,_     ,do ,_) do)))
+                   ((not (lookup-key transient-predicate-map id))
+                    (pcase (list kind default return)
+                      (`(prefix ,(or 'transient--do-stay 'transient--do-call) ,_)
+                       #'transient--do-recurse)
+                      (`(prefix   t ,_) #'transient--do-recurse)
+                      (`(prefix  ,_ ,_) #'transient--do-stack)
+                      (`(infix   ,_ ,_) #'transient--do-stay)
+                      (`(suffix   t ,_) #'transient--do-call)
+                      ('(suffix nil  t) #'transient--do-return)
+                      (`(suffix nil ,_) #'transient--do-exit)
+                      (`(suffix ,do ,_) do))))))
+        (when pre
+          (if-let ((alt (lookup-key map id)))
+              (unless (eq alt pre)
+                (define-key map (vconcat (oref obj key) id) pre))
+            (define-key map id pre)))))
+    map))
+
+(defun transient--make-redisplay-map ()
+  (setq transient--redisplay-key
+        (pcase this-command
+          ('transient-update
+           (setq transient--showp t)
+           (let ((keys (listify-key-sequence (this-single-command-raw-keys))))
+             (setq unread-command-events (mapcar (lambda (key) (cons t key)) keys))
+             keys))
+          ('transient-quit-seq
+           (setq unread-command-events
+                 (butlast (listify-key-sequence
+                           (this-single-command-raw-keys))
+                          2))
+           (butlast transient--redisplay-key))
+          (_ 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
+         (let ((key (vconcat transient--redisplay-key)))
+           (or (lookup-key transient--transient-map key)
+               (and-let* ((regular (lookup-key local-function-key-map key)))
+                 (lookup-key transient--transient-map (vconcat regular)))))
+       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)
+  (transient--with-emergency-exit :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))))
+     (transient--prefix
+      ;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}"
+      ;; of an outer prefix.  Unlike the usual `transient--do-stack',
+      ;; these predicates fail to clean up after the outer prefix.
+      (transient--pop-keymap 'transient--transient-map)
+      (transient--pop-keymap 'transient--redisplay-map))
+     ((not (or layout                      ; resuming parent/suspended prefix
+               transient-current-command)) ; entering child prefix
+      (transient--stack-zap))              ; replace suspended prefix, if any
+     (edit
+      ;; Returning from help to edit.
+      (setq transient--editp t)))
+    (transient--env-apply
+     (lambda ()
+       (transient--init-transient name layout params)
+       (transient--history-init transient--prefix)
+       (setq transient--original-window (selected-window))
+       (setq transient--original-buffer (current-buffer))
+       (setq transient--minibuffer-depth (minibuffer-depth))
+       (transient--redisplay))
+     (get name 'transient--prefix))
+    (transient--setup-transient)
+    (transient--suspend-which-key-mode)))
+
+(cl-defgeneric transient-setup-children (group children)
+  "Setup the CHILDREN of GROUP.
+If the value of the `setup-children' slot is non-nil, then call
+that function with CHILDREN as the only argument and return the
+value.  Otherwise return CHILDREN as is.")
+
+(cl-defmethod transient-setup-children ((group transient-group) children)
+  (if (slot-boundp group 'setup-children)
+      (funcall (oref group setup-children) children)
+    children))
+
+(defun transient--env-apply (fn &optional prefix)
+  (if-let ((env (oref (or prefix transient--prefix) environment)))
+      (funcall env fn)
+    (funcall fn)))
+
+(defun transient--init-transient (&optional name layout params)
+  (unless name
+    ;; Re-init.
+    (if (eq transient--refreshp 'updated-value)
+        ;; Preserve the prefix value this once, because the
+        ;; invoked suffix indicates that it has updated that.
+        (setq transient--refreshp (oref transient--prefix refresh-suffixes))
+      ;; Otherwise update the prefix value from suffix values.
+      (oset transient--prefix value (transient-get-value))))
+  (transient--init-objects name layout params)
+  (transient--init-keymaps))
+
+(defun transient--init-keymaps ()
+  (setq transient--predicate-map (transient--make-predicate-map))
+  (setq transient--transient-map (transient--make-transient-map))
+  (setq transient--redisplay-map (transient--make-redisplay-map)))
+
+(defun transient--init-objects (&optional name layout params)
+  (if name
+      (setq transient--prefix (transient--init-prefix name params))
+    (setq name (oref transient--prefix command)))
+  (setq transient--refreshp (oref transient--prefix refresh-suffixes))
+  (setq transient--layout (or (and (not transient--refreshp) layout)
+                              (transient--init-suffixes name)))
+  (setq transient--suffixes (transient--flatten-suffixes transient--layout)))
+
+(defun transient--init-prefix (name &optional params)
+  (let ((obj (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--setup-recursion obj)
+    (transient-init-scope obj)
+    (transient-init-value obj)
+    obj))
+
+(defun transient--init-suffixes (name)
+  (let ((levels (alist-get name transient-levels)))
+    (mapcan (lambda (c) (transient--init-child levels c nil))
+            (append (get name 'transient--layout)
+                    (and (not transient--editp)
+                         (get 'transient-common-commands
+                              'transient--layout))))))
+
+(defun transient--flatten-suffixes (layout)
+  (cl-labels ((s (def)
+                (cond
+                 ((stringp def) nil)
+                 ((cl-typep def 'transient-information) nil)
+                 ((listp def) (mapcan #'s def))
+                 ((cl-typep def 'transient-group)
+                  (mapcan #'s (oref def suffixes)))
+                 ((cl-typep def 'transient-suffix)
+                  (list def)))))
+    (mapcan #'s layout)))
+
+(defun transient--init-child (levels spec parent)
+  (cl-etypecase spec
+    (vector  (transient--init-group  levels spec parent))
+    (list    (transient--init-suffix levels spec parent))
+    (string  (list spec))))
+
+(defun transient--init-group (levels spec parent)
+  (pcase-let ((`(,level ,class ,args ,children) (append spec nil)))
+    (and-let* (((transient--use-level-p level))
+               (obj (apply class :parent parent :level level args))
+               ((transient--use-suffix-p obj))
+               ((prog1 t
+                  (when (transient--inapt-suffix-p obj)
+                    (oset obj inapt t))))
+               (suffixes (mapcan (lambda (c) (transient--init-child levels c obj))
+                                 (transient-setup-children obj children))))
+      (progn
+        (oset obj suffixes suffixes)
+        (list obj)))))
+
+(defun transient--init-suffix (levels spec parent)
+  (pcase-let* ((`(,level ,class ,args) spec)
+               (cmd (plist-get args :command))
+               (key (transient--kbd (plist-get args :key)))
+               (level (or (alist-get (cons cmd key) levels nil nil #'equal)
+                          (alist-get 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 (child-of-class-p class 'transient-information)
+                     (apply class :parent parent :level level args)
+                   (unless (and cmd (symbolp cmd))
+                     (error "BUG: Non-symbolic suffix command: %s" cmd))
+                   (if-let ((proto (and cmd (transient--suffix-prototype cmd))))
+                       (apply #'clone proto :level level args)
+                     (apply class :command cmd :parent parent :level level
+                            args)))))
+        (cond ((not cmd))
+              ((commandp cmd))
+              ((or (cl-typep obj 'transient-switch)
+                   (cl-typep obj 'transient-option))
+               ;; As a temporary special case, if the package was compiled
+               ;; with an older version of Transient, then we must define
+               ;; "anonymous" switch and option commands here.
+               (defalias cmd #'transient--default-infix-command))
+              ((transient--use-suffix-p obj)
+               (error "Suffix command %s is not defined or autoloaded" cmd)))
+        (unless (cl-typep obj 'transient-information)
+          (transient--init-suffix-key obj))
+        (when (transient--use-suffix-p obj)
+          (if (transient--inapt-suffix-p obj)
+              (oset obj inapt t)
+            (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)
+    (when-let* (((not (slot-boundp obj 'shortarg)))
+                (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 transient--all-levels-p
+      (and transient--editp (not edit))
+      (and (>= level 1)
+           (<= level (oref transient--prefix level)))))
+
+(defun transient--use-suffix-p (obj)
+  (let ((transient--shadowed-buffer (current-buffer))
+        (transient--pending-suffix obj))
+    (transient--do-suffix-p
+     (oref obj if)
+     (oref obj if-not)
+     (oref obj if-nil)
+     (oref obj if-non-nil)
+     (oref obj if-mode)
+     (oref obj if-not-mode)
+     (oref obj if-derived)
+     (oref obj if-not-derived)
+     t)))
+
+(defun transient--inapt-suffix-p (obj)
+  (or (and-let* ((parent (oref obj parent)))
+        (oref parent inapt))
+      (let ((transient--shadowed-buffer (current-buffer))
+            (transient--pending-suffix obj))
+        (transient--do-suffix-p
+         (oref obj inapt-if)
+         (oref obj inapt-if-not)
+         (oref obj inapt-if-nil)
+         (oref obj inapt-if-non-nil)
+         (oref obj inapt-if-mode)
+         (oref obj inapt-if-not-mode)
+         (oref obj inapt-if-derived)
+         (oref obj inapt-if-not-derived)
+         nil))))
+
+(defun transient--do-suffix-p
+    (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived
+        default)
+  (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 (or (atom if-derived)
+                                (>= emacs-major-version 30))
+                            (derived-mode-p if-derived)
+                          (apply #'derived-mode-p if-derived)))
+   (if-not-derived (not (if (or (atom if-not-derived)
+                                (>= emacs-major-version 30))
+                            (derived-mode-p if-not-derived)
+                          (apply #'derived-mode-p if-not-derived))))
+   (default)))
+
+(defun transient--suffix-predicate (spec)
+  (let ((plist (nth 2 spec)))
+    (seq-some (lambda (prop)
+                (and-let* ((pred (plist-get plist prop)))
+                  (list prop pred)))
+              '( :if :if-not
+                 :if-nil :if-non-nil
+                 :if-mode :if-not-mode
+                 :if-derived :if-not-derived
+                 :inapt-if :inapt-if-not
+                 :inapt-if-nil :inapt-if-non-nil
+                 :inapt-if-mode :inapt-if-not-mode
+                 :inapt-if-derived :inapt-if-not-derived))))
+
+;;; Flow-Control
+
+(defun transient--setup-transient ()
+  (transient--debug 'setup-transient)
+  (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)
+  (advice-add 'recursive-edit :around #'transient--recursive-edit)
+  (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--refresh-transient ()
+  (transient--debug 'refresh-transient)
+  (transient--pop-keymap 'transient--predicate-map)
+  (transient--pop-keymap 'transient--transient-map)
+  (transient--pop-keymap 'transient--redisplay-map)
+  (transient--init-transient)
+  (transient--push-keymap 'transient--transient-map)
+  (transient--push-keymap 'transient--redisplay-map)
+  (transient--redisplay))
+
+(defun transient--pre-command ()
+  (transient--debug 'pre-command)
+  (transient--with-emergency-exit :pre-command
+    ;; The use of `overriding-terminal-local-map' does not prevent the
+    ;; lookup of command remappings in the overridden maps, which can
+    ;; lead to a suffix being remapped to a non-suffix.  We have to undo
+    ;; the remapping in that case.  However, remapping a non-suffix to
+    ;; another should remain possible.
+    (when (and (transient--get-pre-command this-original-command nil 'suffix)
+               (not (transient--get-pre-command this-command nil 'suffix)))
+      (setq this-command this-original-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
+           ;; See TODO in that function.
+           (ignore-errors (transient-suffix-object))
+           (not (memq this-command '(transient-quit-one
+                                     transient-quit-all
+                                     transient-help))))
+      (setq this-command 'transient-set-level)
+      (transient--wrap-command))
+     (t
+      (setq transient--exitp nil)
+      (let ((exitp (eq (transient--call-pre-command) transient--exit)))
+        (transient--wrap-command)
+        (when exitp
+          (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)
+  (unless transient--showp
+    (let ((message-log-max nil))
+      (message "")))
+  (setq transient--transient-map nil)
+  (setq transient--predicate-map nil)
+  (setq transient--redisplay-map nil)
+  (setq transient--redisplay-key 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 ((win transient--window)
+          (remain-in-minibuffer-window
+           (and (minibuffer-selected-window)
+                (selected-window))))
+      (cond
+       ((eq (car (window-parameter win 'quit-restore)) 'other)
+        ;; Window used to display another buffer.
+        (set-window-parameter win 'no-other-window
+                              (window-parameter win 'prev--no-other-window))
+        (set-window-parameter win 'prev--no-other-window nil))
+       ((with-demoted-errors "Error while exiting transient: %S"
+          (if (window-parent win)
+              (delete-window win)
+            (delete-frame (window-frame win) t)))))
+      (when remain-in-minibuffer-window
+        (select-window remain-in-minibuffer-window))))
+  (when (buffer-live-p transient--buffer)
+    (kill-buffer transient--buffer))
+  (setq transient--buffer nil))
+
+(defun transient--export ()
+  (setq transient-current-prefix transient--prefix)
+  (setq transient-current-command (oref transient--prefix command))
+  (setq transient-current-suffixes transient--suffixes)
+  (transient--history-push transient--prefix))
+
+(defun transient--suspend-override (&optional nohide)
+  (transient--debug 'suspend-override)
+  (transient--timer-cancel)
+  (let ((show (if nohide 'fixed transient-show-during-minibuffer-read)))
+    (when (and (integerp show)
+               (< (frame-height (window-frame transient--window))
+                  (+ (abs show)
+                     (window-height transient--window))))
+      (setq show (natnump show)))
+    (cond ((not show)
+           (transient--delete-window))
+          ((and transient--prefix transient--redisplay-key)
+           (setq transient--redisplay-key nil)
+           (when transient--showp
+             (if-let ((win (minibuffer-selected-window)))
+                 (with-selected-window win
+                   (transient--show))
+               (transient--show)))))
+    (when (and (window-live-p transient--window)
+               (and show
+                    (or (not (eq show 'fixed))
+                        (window-full-height-p transient--window))))
+      (set-window-parameter transient--window 'window-preserved-size
+                            (list (window-buffer transient--window) nil nil))))
+  (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--resume-override (&optional _ignore)
+  (transient--debug 'resume-override)
+  (cond ((and transient--showp (not (window-live-p transient--window)))
+         (transient--show))
+        ((window-live-p transient--window)
+         (transient--fit-window-to-buffer transient--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))
+
+(defun transient--recursive-edit (fn)
+  (transient--debug 'recursive-edit)
+  (if (not transient--prefix)
+      (funcall fn)
+    (transient--suspend-override (bound-and-true-p edebug-active))
+    (funcall fn) ; Already unwind protected.
+    (cond ((memq this-command '(top-level abort-recursive-edit))
+           (setq transient--exitp t)
+           (transient--post-exit this-command)
+           (transient--delete-window))
+          (transient--prefix
+           (transient--resume-override)))))
+
+(defmacro transient--with-suspended-override (&rest body)
+  (let ((depth (make-symbol "depth"))
+        (setup (make-symbol "setup"))
+        (exit  (make-symbol "exit")))
+    `(if (and transient--transient-map
+              (memq transient--transient-map
+                    overriding-terminal-local-map))
+         (let ((,depth (1+ (minibuffer-depth))) ,setup ,exit)
+           (setq ,setup
+                 (lambda () "@transient--with-suspended-override"
+                   (transient--debug 'minibuffer-setup)
+                   (remove-hook 'minibuffer-setup-hook ,setup)
+                   (transient--suspend-override)))
+           (setq ,exit
+                 (lambda () "@transient--with-suspended-override"
+                   (transient--debug 'minibuffer-exit)
+                   (when (= (minibuffer-depth) ,depth)
+                     (transient--resume-override))))
+           (unwind-protect
+               (progn
+                 (add-hook 'minibuffer-setup-hook ,setup)
+                 (add-hook 'minibuffer-exit-hook ,exit)
+                 ,@body)
+             (remove-hook 'minibuffer-setup-hook ,setup)
+             (remove-hook 'minibuffer-exit-hook ,exit)))
+       ,@body)))
+
+(defun transient--wrap-command ()
+  (static-if (>= emacs-major-version 30)
+      (letrec
+          ((prefix transient--prefix)
+           (suffix this-command)
+           (advice
+            (lambda (fn &rest args)
+              (interactive
+               (lambda (spec)
+                 (let ((abort t))
+                   (unwind-protect
+                       (prog1 (let ((debugger #'transient--exit-and-debug))
+                                (advice-eval-interactive-spec spec))
+                         (setq abort nil))
+                     (when abort
+                       (when-let ((unwind (oref prefix unwind-suffix)))
+                         (transient--debug 'unwind-interactive)
+                         (funcall unwind suffix))
+                       (advice-remove suffix advice)
+                       (oset prefix unwind-suffix nil))))))
+              (unwind-protect
+                  (let ((debugger #'transient--exit-and-debug))
+                    (apply fn args))
+                (when-let ((unwind (oref prefix unwind-suffix)))
+                  (transient--debug 'unwind-command)
+                  (funcall unwind suffix))
+                (advice-remove suffix advice)
+                (oset prefix unwind-suffix nil)))))
+        (when (symbolp this-command)
+          (advice-add suffix :around advice '((depth . -99))))
+        (cl-assert
+         (>= emacs-major-version 30) nil
+         "Emacs was downgraded, making it necessary to recompile Transient"))
+    ;; (< emacs-major-version 30)
+    (let* ((prefix transient--prefix)
+           (suffix this-command)
+           (advice nil)
+           (advice-interactive
+            (lambda (spec)
+              (let ((abort t))
+                (unwind-protect
+                    (prog1 (let ((debugger #'transient--exit-and-debug))
+                             (advice-eval-interactive-spec spec))
+                      (setq abort nil))
+                  (when abort
+                    (when-let ((unwind (oref prefix unwind-suffix)))
+                      (transient--debug 'unwind-interactive)
+                      (funcall unwind suffix))
+                    (advice-remove suffix advice)
+                    (oset prefix unwind-suffix nil))))))
+           (advice-body
+            (lambda (fn &rest args)
+              (unwind-protect
+                  (let ((debugger #'transient--exit-and-debug))
+                    (apply fn args))
+                (when-let ((unwind (oref prefix unwind-suffix)))
+                  (transient--debug 'unwind-command)
+                  (funcall unwind suffix))
+                (advice-remove suffix advice)
+                (oset prefix unwind-suffix nil)))))
+      (setq advice `(lambda (fn &rest args)
+                      (interactive ,advice-interactive)
+                      (apply ',advice-body fn args)))
+      (when (symbolp this-command)
+        (advice-add suffix :around advice '((depth . -99)))))))
+
+(defun transient--premature-post-command ()
+  (and (equal (this-command-keys-vector) [])
+       (= (minibuffer-depth)
+          (1+ transient--minibuffer-depth))
+       (progn
+         (transient--debug 'premature-post-command)
+         (transient--suspend-override)
+         (oset (or transient--prefix transient-current-prefix)
+               unwind-suffix
+               (if transient--exitp
+                   #'transient--post-exit
+                 #'transient--resume-override))
+         t)))
+
+(defun transient--post-command ()
+  (unless (transient--premature-post-command)
+    (transient--debug 'post-command)
+    (transient--with-emergency-exit :post-command
+      (cond (transient--exitp (transient--post-exit))
+            ;; If `this-command' is the current transient prefix, then we
+            ;; have already taken care of updating the transient buffer...
+            ((and (eq this-command (oref transient--prefix command))
+                  ;; ... but if `prefix-arg' is non-nil, then the values
+                  ;; of `this-command' and `real-this-command' are untrue
+                  ;; because `prefix-command-preserve-state' changes them.
+                  ;; We cannot use `current-prefix-arg' because it is set
+                  ;; too late (in `command-execute'), and if it were set
+                  ;; earlier, then we likely still would not be able to
+                  ;; rely on it, and `prefix-command-preserve-state-hook'
+                  ;; would have to be used to record that a universal
+                  ;; argument is in effect.
+                  (not prefix-arg)))
+            (transient--refreshp
+             (transient--env-apply #'transient--refresh-transient))
+            ((let ((old transient--redisplay-map)
+                   (new (transient--make-redisplay-map)))
+               (unless (equal old new)
+                 (transient--pop-keymap 'transient--redisplay-map)
+                 (setq transient--redisplay-map new)
+                 (transient--push-keymap 'transient--redisplay-map))
+               (transient--env-apply #'transient--redisplay)))))
+    (setq transient-current-prefix nil)
+    (setq transient-current-command nil)
+    (setq transient-current-suffixes nil)))
+
+(defun transient--post-exit (&optional command)
+  (transient--debug 'post-exit)
+  (unless (and (eq transient--exitp 'replace)
+               (or transient--prefix
+                   ;; The current command could act as a prefix,
+                   ;; but decided not to call `transient-setup',
+                   ;; or it is prevented from doing so because it
+                   ;; uses the minibuffer and the user aborted
+                   ;; that.
+                   (prog1 nil
+                     (if (let ((obj (transient-suffix-object command)))
+                           (and (slot-boundp obj 'transient)
+                                (oref obj transient)))
+                         ;; This sub-prefix is a transient suffix;
+                         ;; go back to outer prefix, by calling
+                         ;; `transient--stack-pop' further down.
+                         (setq transient--exitp nil)
+                       (transient--stack-zap)))))
+    (remove-hook 'pre-command-hook  #'transient--pre-command)
+    (remove-hook 'post-command-hook #'transient--post-command)
+    (advice-remove 'recursive-edit #'transient--recursive-edit))
+  (let ((resume (and transient--stack
+                     (not (memq transient--exitp '(replace suspend))))))
+    (unless (or resume (eq transient--exitp 'replace))
+      (setq transient--showp nil))
+    (setq transient--exitp nil)
+    (setq transient--helpp nil)
+    (setq transient--editp nil)
+    (setq transient--all-levels-p nil)
+    (setq transient--minibuffer-depth 0)
+    (run-hooks 'transient-exit-hook)
+    (when command
+      (setq transient-current-prefix nil)
+      (setq transient-current-command nil)
+      (setq transient-current-suffixes nil))
+    (when resume
+      (transient--stack-pop))))
+
+(defun transient--stack-push ()
+  (transient--debug 'stack-push)
+  (push (list (oref transient--prefix command)
+              transient--layout
+              transient--editp
+              :transient-suffix (oref transient--prefix transient-suffix)
+              :scope (oref transient--prefix scope)
+              :value (transient-get-value))
+        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
+          (or (memq this-command transient--scroll-commands)
+              (and (or (memq this-command '(mouse-drag-region
+                                            mouse-set-region))
+                       (equal (key-description (this-command-keys-vector))
+                              "<mouse-movement>"))
+                   (and (eq (current-buffer) transient--buffer))))
+        (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
+    (let ((inhibit-message (not (eq transient--debug 'message))))
+      (if (symbolp arg)
+          (message "-- %-22s (cmd: %s, event: %S, exit: %s%s)"
+                   arg
+                   (cond ((and (symbolp this-command) this-command))
+                         ((fboundp 'help-fns-function-name)
+                          (help-fns-function-name this-command))
+                         ((byte-code-function-p this-command)
+                          "#[...]")
+                         (this-command))
+                   (key-description (this-command-keys-vector))
+                   transient--exitp
+                   (cond ((keywordp (car args))
+                          (format ", from: %s"
+                                  (substring (symbol-name (car args)) 1)))
+                         ((stringp (car args))
+                          (concat ", " (apply #'format args)))
+                         ((functionp (car args))
+                          (concat ", " (apply (car args) (cdr args))))
+                         ("")))
+        (apply #'message arg args)))))
+
+(defun transient--emergency-exit (&optional id)
+  "Exit the current transient command after an error occurred.
+When no transient is active (i.e., when `transient--prefix' is
+nil) then do nothing.  Optional ID is a keyword identifying the
+exit."
+  (transient--debug 'emergency-exit id)
+  (when transient--prefix
+    (setq transient--stack nil)
+    (setq transient--exitp t)
+    (transient--pre-exit)
+    (transient--post-exit this-command)))
+
+;;; Pre-Commands
+
+(defun transient--call-pre-command ()
+  (if-let ((fn (transient--get-pre-command this-command
+                                           (this-command-keys-vector))))
+      (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))
+
+(defun transient--get-pre-command (&optional cmd key enforce-type)
+  (or (and (not (eq enforce-type 'non-suffix))
+           (symbolp cmd)
+           (or (and key
+                    (let ((def (lookup-key transient--predicate-map
+                                           (vconcat key (list cmd)))))
+                      (and (symbolp def) def)))
+               (lookup-key transient--predicate-map (vector cmd))))
+      (and (not (eq enforce-type 'suffix))
+           (transient--resolve-pre-command
+            (oref transient--prefix transient-non-suffix)
+            t))))
+
+(defun transient--resolve-pre-command (pre &optional resolve-boolean)
+  (cond ((booleanp pre)
+         (if resolve-boolean
+             (if pre #'transient--do-stay #'transient--do-warn)
+           pre))
+        ((string-match-p "--do-" (symbol-name pre)) pre)
+        ((let ((sym (intern (format "transient--do-%s" pre))))
+           (if (functionp sym) sym pre)))))
+
+(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-warn-inapt ()
+  "Call `transient-inapt' and stay transient."
+  (setq this-command 'transient-inapt)
+  transient--stay)
+
+(defun transient--do-call ()
+  "Call the command after exporting variables and stay transient."
+  (transient--export)
+  transient--stay)
+
+(defun transient--do-return ()
+  "Call the command after exporting variables and return to parent prefix.
+If there is no parent prefix, then behave like `transient--do-exit'."
+  (if (not transient--stack)
+      (transient--do-exit)
+    (transient--export)
+    transient--exit))
+
+(defun transient--do-exit ()
+  "Call the command after exporting variables and exit the transient."
+  (transient--export)
+  (transient--stack-zap)
+  transient--exit)
+
+(defun transient--do-leave ()
+  "Call the command without exporting variables and exit the transient."
+  (transient--stack-zap)
+  transient--exit)
+
+(defun transient--do-push-button ()
+  "Call the command represented by the activated button.
+Use that command's pre-command to determine transient behavior."
+  (if (and (mouse-event-p last-command-event)
+           (not (eq (posn-window (event-start last-command-event))
+                    transient--window)))
+      transient--stay
+    (setq this-command
+          (with-selected-window transient--window
+            (get-text-property (if (mouse-event-p last-command-event)
+                                   (posn-point (event-start last-command-event))
+                                 (point))
+                               'command)))
+    (transient--call-pre-command)))
+
+(defun transient--do-recurse ()
+  "Call the transient prefix command, preparing for return to active transient.
+If there is no parent prefix, then just call the command."
+  (transient--do-stack))
+
+(defun transient--setup-recursion (prefix-obj)
+  (when transient--stack
+    (let ((command (oref prefix-obj command)))
+      (when-let ((suffix-obj (transient-suffix-object command)))
+        (when (memq (if (slot-boundp suffix-obj 'transient)
+                        (oref suffix-obj transient)
+                      (oref transient-current-prefix transient-suffix))
+                    (list t #'transient--do-recurse))
+          (oset prefix-obj transient-suffix t))))))
+
+(defun transient--do-stack ()
+  "Call the transient prefix command, stacking the active transient.
+Push the active transient to the transient stack."
+  (transient--export)
+  (transient--stack-push)
+  (setq transient--exitp 'replace)
+  transient--exit)
+
+(defun transient--do-replace ()
+  "Call the transient prefix command, replacing the active transient.
+Do not push the active transient to the transient stack."
+  (transient--export)
+  (setq transient--exitp 'replace)
+  transient--exit)
+
+(defun transient--do-suspend ()
+  "Suspend the active transient, saving the transient stack."
+  ;; Export so that `transient-describe' instances can use
+  ;; `transient-suffix-object' to get their respective object.
+  (transient--export)
+  (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)
+        (prefix-arg
+         transient--stay)
+        (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-inhibit-move))
+  transient--stay)
+
+(defun transient--do-minus ()
+  "Call `negative-argument' or pivot to `transient-update'.
+If `negative-argument' is invoked using \"-\" then preserve the
+prefix argument and pivot to `transient-update'."
+  (when (equal (this-command-keys) "-")
+    (setq this-command 'transient-update))
+  transient--stay)
+
+(put 'transient--do-stay       'transient-face 'transient-key-stay)
+(put 'transient--do-noop       'transient-face 'transient-key-noop)
+(put 'transient--do-warn       'transient-face 'transient-key-noop)
+(put 'transient--do-warn-inapt 'transient-face 'transient-key-noop)
+(put 'transient--do-call       'transient-face 'transient-key-stay)
+(put 'transient--do-return     'transient-face 'transient-key-return)
+(put 'transient--do-exit       'transient-face 'transient-key-exit)
+(put 'transient--do-leave      'transient-face 'transient-key-exit)
+
+(put 'transient--do-recurse    'transient-face 'transient-key-stay)
+(put 'transient--do-stack      'transient-face 'transient-key-stay)
+(put 'transient--do-replace    'transient-face 'transient-key-exit)
+(put 'transient--do-suspend    'transient-face 'transient-key-exit)
+
+(put 'transient--do-quit-one   'transient-face 'transient-key-return)
+(put 'transient--do-quit-all   'transient-face 'transient-key-exit)
+(put 'transient--do-move       'transient-face 'transient-key-stay)
+(put 'transient--do-minus      'transient-face 'transient-key-stay)
+
+;;; Commands
+;;;; Noop
+
+(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)
+  (transient--invalid "Unbound suffix"))
+
+(defun transient-inapt ()
+  "Warn the user that the invoked command is inapt."
+  (interactive)
+  (transient--invalid "Inapt command"))
+
+(defun transient--invalid (msg)
+  (ding)
+  (message "%s: `%s' (Use `%s' to abort, `%s' for help)%s"
+           msg
+           (propertize (key-description (this-single-command-keys))
+                       'face 'font-lock-warning-face)
+           (propertize "C-g" 'face 'transient-key)
+           (propertize "?"   'face 'transient-key)
+           ;; `this-command' is `transient-undefined' or `transient-inapt'.
+           ;; Show the command (`this-original-command') the user actually
+           ;; tried to invoke.
+           (if-let ((cmd (or (ignore-errors (symbol-name this-original-command))
+                             (ignore-errors (symbol-name this-command)))))
+               (format " [%s]" (propertize cmd 'face 'font-lock-warning-face))
+             ""))
+  (unless (and transient--transient-map
+               (memq transient--transient-map overriding-terminal-local-map))
+    (let ((transient--prefix (or transient--prefix 'sic)))
+      (transient--emergency-exit))
+    (view-lossage)
+    (other-window 1)
+    (display-warning 'transient "Inconsistent transient state detected.
+This should never happen.
+Please open an issue and post the shown command log." :error)))
+
+(defun transient-inhibit-move ()
+  "Warn the user that popup navigation is disabled."
+  (interactive)
+  (message "To enable use of `%s', please customize `%s'"
+           this-original-command
+           'transient-enable-popup-navigation))
+
+;;;; Core
+
+(defun transient-quit-all ()
+  "Exit all transients without saving the transient stack."
+  (interactive))
+
+(defun transient-quit-one ()
+  "Exit the current transients, returning to outer transient, if any."
+  (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)
+  (setq prefix-arg current-prefix-arg))
+
+(defun transient-show ()
+  "Show the transient's state in the popup buffer."
+  (interactive)
+  (setq transient--showp t))
+
+(defun transient-push-button ()
+  "Invoke the suffix command represented by this button."
+  (interactive))
+
+;;;; Suspend
+
+(defun transient-suspend ()
+  "Suspend the current transient.
+It can later be resumed using `transient-resume', while no other
+transient is active."
+  (interactive))
+
+(define-minor-mode transient-resume-mode
+  "Auxiliary minor-mode used to resume a transient after viewing help.")
+
+(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"))))
+
+;;;; Help
+
+(defun transient-help (&optional interactive)
+  "Show help for the active transient or one of its suffixes.\n\n(fn)"
+  (interactive (list t))
+  (if interactive
+      (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)
+        (transient--display-help #'transient-show-help
+                                 (if (eq this-original-command 'transient-help)
+                                     transient--prefix
+                                   (or (transient-suffix-object)
+                                       this-original-command)))))))
+
+(transient-define-suffix transient-describe ()
+  "From a transient menu, describe something in another buffer.
+
+This command can be bound multiple times to describe different targets.
+Each binding must specify the thing it describes, be setting the value
+of its `target' slot, using the keyword argument `:='.
+
+The `helper' slot specifies the low-level function used to describe the
+target, and can be omitted, in which case `transient--describe-function'
+is used for a symbol, `transient--show-manual' is used for a string
+beginning with a parenthesis, and `transient--show-manpage' is used for
+any other string.
+
+For example:
+  [(\"e\" \"about emacs\" transient-describe := \"(emacs)\")
+   (\"g\" \"about git\"   transient-describe := \"git\")]"
+  :class 'transient-describe-target
+  (interactive)
+  (with-slots (helper target) (transient-suffix-object)
+    (transient--display-help helper target)))
+
+;;;; Level
+
+(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)
+                       (progn
+                         (transient--show)
+                         (string-to-number
+                          (transient--read-number-N
+                           (format "Set level for `%s': " 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))
+           (akey command))
+      (cond ((eq command prefix)
+             (oset transient--prefix level level)
+             (setq akey t))
+            (t
+             (oset (transient-suffix-object command) level level)
+             (when (cdr (cl-remove-if-not (lambda (obj)
+                                            (eq (oref obj command) command))
+                                          transient--suffixes))
+               (setq akey (cons command (this-command-keys))))))
+      (setf (alist-get akey alist) level)
+      (setf (alist-get prefix transient-levels) alist))
+    (transient-save-levels)
+    (transient--show))
+   (t
+    (transient-undefined))))
+
+(transient-define-suffix transient-toggle-level-limit ()
+  "Toggle whether to temporarily displayed suffixes on all levels."
+  :description
+  (lambda ()
+    (cond
+     ((= transient-default-level transient--max-level)
+      "Always displaying all levels")
+     (transient--all-levels-p
+      (format "Hide suffix %s"
+              (propertize
+               (format "levels > %s" (oref (transient-prefix-object) level))
+               'face 'transient-higher-level)))
+     ("Show all suffix levels")))
+  :inapt-if (lambda () (= transient-default-level transient--max-level))
+  :transient t
+  (interactive)
+  (setq transient--all-levels-p (not transient--all-levels-p))
+  (setq transient--refreshp t))
+
+;;;; Value
+
+(defun transient-set ()
+  "Set active transient's value for this Emacs session."
+  (interactive)
+  (transient-set-value (transient-prefix-object)))
+
+(defalias 'transient-set-and-exit #'transient-set
+  "Set active transient's value for this Emacs session and exit.")
+
+(defun transient-save ()
+  "Save active transient's value for this and future Emacs sessions."
+  (interactive)
+  (transient-save-value (transient-prefix-object)))
+
+(defalias 'transient-save-and-exit #'transient-save
+  "Save active transient's value for this and future Emacs sessions and exit.")
+
+(defun transient-reset ()
+  "Clear the set and saved values of the active transient."
+  (interactive)
+  (transient-reset-value (transient-prefix-object)))
+
+(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))))
+
+(transient-define-suffix transient-preset ()
+  "Put this preset into action."
+  :class transient-value-preset
+  (interactive)
+  (transient-prefix-set (oref (transient-suffix-object) set)))
+
+;;;; Auxiliary
+
+(transient-define-suffix transient-toggle-common ()
+  "Toggle whether common commands are permanently shown."
+  :transient t
+  :description (lambda ()
+                 (if transient-show-common-commands
+                     "Hide common commands"
+                   "Show common permanently"))
+  (interactive)
+  (setq transient-show-common-commands (not transient-show-common-commands)))
+
+(transient-define-suffix transient-toggle-docstrings ()
+  "Toggle whether to show docstrings instead of suffix descriptions.
+To make this available in all menus, bind it in `transient-map'."
+  :transient t
+  (interactive)
+  (setq transient--docsp (not transient--docsp)))
+
+(defun transient-toggle-debug ()
+  "Toggle debugging statements for transient commands."
+  (interactive)
+  (setq transient--debug (not transient--debug))
+  (message "Debugging transient %s"
+           (if transient--debug "enabled" "disabled")))
+
+(defun transient-copy-menu-text ()
+  "Copy the contents of the menu buffer to the kill ring.
+To make this available in all menus, bind it in `transient-map'"
+  (interactive)
+  (transient--show)
+  (with-current-buffer (get-buffer transient--buffer-name)
+    (copy-region-as-kill (point-min) (point-max))))
+
+(transient-define-suffix transient-echo-arguments (arguments)
+  "Show the transient's active ARGUMENTS in the echo area.
+Intended for use in prefixes used for demonstration purposes,
+such as when suggesting a new feature or reporting an issue."
+  :transient t
+  :description "Echo arguments"
+  :key "x"
+  (interactive (list (transient-args transient-current-command)))
+  (message "%s: %s"
+           (key-description (this-command-keys))
+           (mapconcat (lambda (arg)
+                        (propertize (if (string-match-p " " arg)
+                                        (format "%S" arg)
+                                      arg)
+                                    'face 'transient-argument))
+                      arguments " ")))
+
+;;; Value
+;;;; Init
+
+(cl-defgeneric transient-init-value (obj)
+  "Set the initial value of the prefix or suffix object OBJ.
+
+This function is called for all prefix and suffix commands.
+
+Third-party subclasses of `transient-infix' must implement a primary
+method.")
+
+(cl-defmethod transient-init-value :around ((obj transient-prefix))
+  "If bound, use the value returned by OBJ' `init-value' function.
+If the value of OBJ's `init-value' is non-nil, call that function to
+determine the value.  Otherwise call the primary method according to
+OBJ's class."
+  (if (slot-boundp obj 'init-value)
+      (funcall (oref obj init-value) obj)
+    (cl-call-next-method obj)))
+
+(cl-defmethod transient-init-value :around ((obj transient-infix))
+  "If bound, use the value returned by OBJ's `init-value' function.
+If the value of OBJ's `init-value' is non-nil, call that function to
+determine the value.  Otherwise call the primary method according to
+OBJ's class."
+  (if (slot-boundp obj 'init-value)
+      (funcall (oref obj init-value) obj)
+    (cl-call-next-method obj)))
+
+(cl-defmethod transient-init-value ((obj transient-prefix))
+  "Set OBJ's initial value to the set, saved or default value.
+Use `transient-default-value' to determine the default value."
+  (if (slot-boundp obj 'value)
+      ;; Already set because the live object is cloned from
+      ;; the prototype, were the set (if any) value is stored.
+      (oref obj value)
+    (oset obj value
+          (if-let ((saved (assq (oref obj command) transient-values)))
+              (cdr saved)
+            (transient-default-value obj)))))
+
+(cl-defmethod transient-init-value ((obj transient-suffix))
+  "Non-infix suffixes usually don't have a value.
+Call `transient-default-value' but because that is a noop for
+`transient-suffix', this function is effectively also a noop."
+  (let ((value (transient-default-value obj)))
+    (unless (eq value eieio--unbound)
+      (oset obj value value))))
+
+(cl-defmethod transient-init-value ((obj transient-argument))
+  "Extract OBJ's value from the value of the prefix object."
+  (oset obj value
+        (let ((value (oref transient--prefix value))
+              (argument (and (slot-boundp obj 'argument)
+                             (oref obj argument)))
+              (multi-value (oref obj multi-value))
+              (case-fold-search nil)
+              (regexp (if (slot-exists-p obj 'argument-regexp)
+                          (oref obj argument-regexp)
+                        (format "\\`%s\\(.*\\)" (oref obj argument)))))
+          (if (memq multi-value '(t rest))
+              (cdr (assoc argument value))
+            (let ((match (lambda (v)
+                           (and (stringp v)
+                                (string-match regexp v)
+                                (match-string 1 v)))))
+              (if multi-value
+                  (delq nil (mapcar match value))
+                (cl-some match value)))))))
+
+(cl-defmethod transient-init-value ((obj transient-switch))
+  "Extract OBJ's value from the value of the prefix object."
+  (oset obj value
+        (car (member (oref obj argument)
+                     (oref transient--prefix value)))))
+
+;;;; Default
+
+(cl-defgeneric transient-default-value (obj)
+  "Return the default value.")
+
+(cl-defmethod transient-default-value ((obj transient-prefix))
+  "Return the default value as specified by the `default-value' slot.
+If the value of the `default-value' slot is a function, call it to
+determine the value.  If the slot's value isn't a function, return
+that.  If the slot is unbound, return nil."
+  (if-let ((default (and (slot-boundp obj 'default-value)
+                         (oref obj default-value))))
+      (if (functionp default)
+          (funcall default)
+        default)
+    nil))
+
+(cl-defmethod transient-default-value ((_   transient-suffix))
+  "Return `eieio--unbound' to indicate that there is no default value.
+Doing so causes `transient-init-value' to skip setting the `value' slot."
+  eieio--unbound)
+
+;;;; 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
+method for `transient-infix', 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))
+  "Refresh the transient buffer and call the next method.
+
+Also wrap `cl-call-next-method' with two macros:
+- `transient--with-suspended-override' allows use of minibuffer.
+- `transient--with-emergency-exit' arranges for the transient to
+  be exited in case of an error."
+  (transient--show)
+  (transient--with-emergency-exit :infix-read
+    (transient--with-suspended-override
+     (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 limited 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 always-read allow-empty choices) obj
+    (if (and value
+             (not multi-value)
+             (not always-read)
+             transient--prefix)
+        (oset obj value nil)
+      (let* ((enable-recursive-minibuffers t)
+             (reader (oref obj reader))
+             (choices (if (functionp choices) (funcall choices) choices))
+             (prompt (transient-prompt obj))
+             (value (if multi-value (string-join 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))
+               ((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 (and (bound-and-true-p ivy-mode)
+                     (stringp (car transient--history)))
+            (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))))
+
+(cl-defmethod transient-infix-read ((command symbol))
+  "Elsewhere use the reader of the infix command COMMAND.
+Use this if you want to share an infix's history with a regular
+stand-alone command."
+  (if-let ((obj (transient--suffix-prototype command)))
+      (cl-letf (((symbol-function #'transient--show) #'ignore))
+        (transient-infix-read obj))
+    (error "Not a suffix command: `%s'" command)))
+
+;;;; Readers
+
+(defun transient-read-file (prompt _initial-input _history)
+  "Read a file."
+  (file-local-name (expand-file-name (read-file-name prompt))))
+
+(defun transient-read-existing-file (prompt _initial-input _history)
+  "Read an existing file."
+  (file-local-name (expand-file-name (read-file-name prompt nil nil t))))
+
+(defun transient-read-directory (prompt _initial-input _history)
+  "Read a directory."
+  (file-local-name (expand-file-name (read-directory-name prompt))))
+
+(defun transient-read-existing-directory (prompt _initial-input _history)
+  "Read an existing directory."
+  (file-local-name (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)))
+          (when (or (string-equal str "")
+                    (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 (and-let* ((arg (and (slot-boundp obj 'argument) (oref obj argument))))
+          (if (and (stringp arg) (string-suffix-p "=" arg))
+              arg
+            (concat arg ": ")))
+        (and-let* ((var (and (slot-boundp obj 'variable) (oref obj variable))))
+          (and (stringp var)
+               (concat var ": ")))
+        "(BUG: no prompt): ")))
+
+;;;; Set
+
+(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."
+  (oset obj value value))
+
+(cl-defmethod transient-infix-set :after ((obj transient-argument) value)
+  "Unset incompatible infix arguments."
+  (when-let* ((value)
+              (val (transient-infix-value obj))
+              (arg (if (slot-boundp obj 'argument)
+                       (oref obj argument)
+                     (oref obj argument-format)))
+              (spec (oref transient--prefix incompatible))
+              (filter (lambda (x rule)
+                        (and (member x rule)
+                             (remove x rule))))
+              (incomp (nconc
+                       (mapcan (apply-partially filter arg) spec)
+                       (and (not (equal val arg))
+                            (mapcan (apply-partially filter val) spec)))))
+    (dolist (obj transient--suffixes)
+      (when-let* (((cl-typep obj 'transient-argument))
+                  (val (transient-infix-value obj))
+                  (arg (if (slot-boundp obj 'argument)
+                           (oref obj argument)
+                         (oref obj argument-format)))
+                  ((if (equal val arg)
+                       (member arg incomp)
+                     (or (member val incomp)
+                         (member arg incomp)))))
+        (transient-infix-set obj nil)))))
+
+(defun transient-prefix-set (value)
+  "Set the value of the active transient prefix to VALUE.
+Intended for use by transient suffix commands."
+  (oset transient--prefix value value)
+  (setq transient--refreshp 'updated-value))
+
+(cl-defgeneric transient-set-value (obj)
+  "Persist the value of the transient prefix OBJ.
+Only intended for use by `transient-set'.
+See also `transient-prefix-set'.")
+
+(cl-defmethod transient-set-value ((obj transient-prefix))
+  (oset (oref obj prototype) value (transient-get-value))
+  (transient--history-push obj))
+
+;;;; Save
+
+(cl-defgeneric transient-save-value (obj)
+  "Save the value of the transient prefix OBJ.")
+
+(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))
+
+;;;; Reset
+
+(cl-defgeneric transient-reset-value (obj)
+  "Clear the set and saved values of the transient prefix OBJ.")
+
+(cl-defmethod transient-reset-value ((obj transient-prefix))
+  (let ((value (transient-default-value obj)))
+    (oset obj value value)
+    (oset (oref obj prototype) value value)
+    (setf (alist-get (oref obj command) transient-values nil 'remove) nil)
+    (transient-save-values))
+  (transient--history-push obj)
+  (mapc #'transient-init-value transient--suffixes))
+
+;;;; 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.
+
+PREFIX may also be a list of prefixes.  If no prefix is active, the
+fallback value of the first of these prefixes is used.
+
+The generic function `transient-prefix-value' is used to determine the
+returned value."
+  (when (listp prefix)
+    (setq prefix (car (or (memq transient-current-command prefix) prefix))))
+  (if-let ((obj (get prefix 'transient--prefix)))
+      (transient-prefix-value obj)
+    (error "Not a transient prefix: %s" prefix)))
+
+(cl-defgeneric transient-prefix-value (obj)
+  "Return the value of the prefix object OBJ.
+This function is used by `transient-args'.")
+
+(cl-defmethod transient-prefix-value ((obj transient-prefix))
+  "Return a list of the values of the suffixes the prefix object OBJ.
+Use `transient-infix-value' to collect the values of individual suffix
+objects."
+  (mapcan #'transient--get-wrapped-value
+          (transient-suffixes (oref obj command))))
+
+(defun transient-suffixes (prefix)
+  "Return the suffix objects of the transient prefix command PREFIX.
+
+If PREFIX is not the current prefix, initialize the suffixes so that
+they can be returned.  Doing so doesn't have any side-effects."
+  (if (eq transient-current-command prefix)
+      transient-current-suffixes
+    (let ((transient--prefix (transient--init-prefix prefix)))
+      (transient--flatten-suffixes
+       (transient--init-suffixes prefix)))))
+
+(defun transient-get-value ()
+  "Return the value of the current prefix.
+
+This is mostly intended for internal use, but may also be of use
+in `transient-set-value' and `transient-save-value' methods.  Unlike
+`transient-args', this does not include the values of suffixes whose
+`unsavable' slot is non-nil."
+  (transient--with-emergency-exit :get-value
+    (mapcan (lambda (obj)
+              (and (or (not (slot-exists-p obj 'unsavable))
+                       (not (oref obj unsavable)))
+                   (transient--get-wrapped-value obj)))
+            (or transient--suffixes transient-current-suffixes))))
+
+(defun transient--get-wrapped-value (obj)
+  "Return a list of the value(s) of suffix object OBJ.
+
+Internally a suffix only ever has one value, stored in its `value'
+slot, but callers of `transient-args', wish to treat the values of
+certain suffixes as multiple values.  That translation is handled
+here.  The object's `multi-value' slot specifies whether and how
+to interpret the `value' as multiple values."
+  (and-let* ((value (transient-infix-value obj)))
+    (pcase-exhaustive (and (slot-exists-p obj 'multi-value)
+                           (oref obj multi-value))
+      ('nil          (list value))
+      ((or 't 'rest) (list value))
+      ('repeat       value))))
+
+(cl-defgeneric transient-infix-value (obj)
+  "Return the value of the suffix object OBJ.
+
+By default this function is involved when determining the prefix's
+overall value, returned by `transient-args' (which see),  so that
+the invoked suffix command can use that.
+
+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 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 ARGUMENT and VALUE as a unit or nil if the latter is nil."
+  (and-let* ((value (oref obj value)))
+    (let ((arg (oref obj argument)))
+      (pcase-exhaustive (oref obj multi-value)
+        ('nil          (concat arg value))
+        ((or 't 'rest) (cons arg value))
+        ('repeat       (mapcar (lambda (v) (concat arg v)) 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)
+
+;;;; Utilities
+
+(defun transient-arg-value (arg args)
+  "Return the value of ARG as it appears in ARGS.
+
+For a switch return a boolean.  For an option return the value as
+a string, using the empty string for the empty value, or nil if
+the option does not appear in ARGS.
+
+Append \"=\ to ARG to indicate that it is an option."
+  (if (string-suffix-p "=" arg)
+      (save-match-data
+        (and-let* ((match (let ((case-fold-search nil)
+                                (re (format "\\`%s\\(?:=\\(.+\\)\\)?\\'"
+                                            (substring arg 0 -1))))
+                            (cl-find-if (lambda (a)
+                                          (and (stringp a)
+                                               (string-match re a)))
+                                        args))))
+          (or (match-string 1 match) "")))
+    (and (member arg args) t)))
+
+;;; Scope
+;;;; Init
+
+(cl-defgeneric transient-init-scope (obj)
+  "Set the scope of the prefix or 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 prefix and suffix commands, but
+unless a concrete method is implemented, this falls through to
+a default implementation, which is a noop.")
+
+(cl-defmethod transient-init-scope ((_   transient-prefix))
+  "Noop." nil)
+
+(cl-defmethod transient-init-scope ((_   transient-suffix))
+  "Noop." nil)
+
+;;;; Get
+
+(defun transient-scope (&optional prefixes)
+  "Return the scope of the active or current transient prefix command.
+
+If optional PREFIXES is nil, return the scope of the prefix currently
+being setup, making this variant useful, e.g., in `:if*' predicates.
+If no prefix is being setup, but the current command was invoked from
+some prefix, then return the scope of that.
+
+When this function is called from the body or `interactive' form of a
+suffix command, PREFIXES should be non-nil.
+
+If PREFIXES is non-nil, it must be a prefix command or a list of such
+commands.  In this case try the following in order:
+
+- If the current suffix command was invoked from a prefix, which
+  appears in PREFIXES, then return the scope of that prefix.
+
+- If a prefix is being setup and it appears in PREFIXES, then return
+  its scope.
+
+- Finally try to return the default scope of the first prefix in
+  PREFIXES.  This only works if that slot is set in the respective
+  class definition or using its `transient-init-scope' method.
+
+If no prefix matches, return nil."
+  (if prefixes
+      (let ((prefixes (ensure-list prefixes)))
+        (if-let* ((obj (or (and-let* ((obj transient-current-prefix))
+                             (and (memq (oref obj command) prefixes) obj))
+                           (and-let* ((obj transient--prefix))
+                             (and (memq (oref obj command) prefixes) obj)))))
+            (oref obj scope)
+          (and (get (car prefixes) 'transient--prefix)
+               (oref (transient--init-prefix (car prefixes)) scope))))
+    (and-let* ((obj (transient-prefix-object)))
+      (oref obj scope))))
+
+;;; History
+
+(cl-defgeneric transient--history-key (obj)
+  "Return OBJ's history key.")
+
+(cl-defmethod transient--history-key ((obj transient-prefix))
+  "If the value of the `history-key' slot is non-nil, 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'.")
+
+(cl-defmethod transient--history-push ((obj transient-prefix))
+  (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
+         (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-delimiter))))))
+
+(defun transient--show ()
+  (transient--timer-cancel)
+  (setq transient--showp t)
+  (let ((transient--shadowed-buffer (current-buffer))
+        (setup (not (get-buffer transient--buffer-name)))
+        (focus nil))
+    (setq transient--buffer (get-buffer-create transient--buffer-name))
+    (with-current-buffer transient--buffer
+      (when transient-enable-popup-navigation
+        (setq focus (or (button-get (point) 'command)
+                        (and (not (bobp))
+                             (button-get (1- (point)) 'command))
+                        (transient--heading-at-point))))
+      (erase-buffer)
+      (when setup
+        (when transient-force-fixed-pitch
+          (transient--force-fixed-pitch))
+        (when (bound-and-true-p tab-line-format)
+          (setq tab-line-format nil))
+        (setq header-line-format nil)
+        (setq mode-line-format
+              (let ((format (transient--mode-line-format)))
+                (if (or (natnump format) (eq format 'line)) nil 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)
+        (run-hooks 'transient-setup-buffer-hook))
+      (transient--insert-groups)
+      (when (or transient--helpp transient--editp)
+        (transient--insert-help))
+      (when-let ((line (transient--separator-line)))
+        (insert line)))
+    (unless (window-live-p transient--window)
+      (setq transient--window
+            (display-buffer transient--buffer
+                            (transient--display-action)))
+      (with-selected-window transient--window
+        (set-window-parameter nil 'prev--no-other-window
+                              (window-parameter nil 'no-other-window))))
+    (when (window-live-p transient--window)
+      (with-selected-window transient--window
+        (set-window-parameter nil 'no-other-window t)
+        (goto-char (point-min))
+        (when transient-enable-popup-navigation
+          (transient--goto-button focus))
+        (transient--fit-window-to-buffer transient--window)))))
+
+(defun transient--display-action ()
+  (let ((action
+         (cond ((oref transient--prefix display-action))
+               ((memq 'display-buffer-full-frame
+                      (ensure-list (car transient-display-buffer-action)))
+                (user-error "%s disallowed in %s"
+                            'display-buffer-full-frame
+                            'transient-display-buffer-action))
+               (transient-display-buffer-action))))
+    (when (and (assq 'pop-up-frame-parameters (cdr action))
+               (fboundp 'buffer-line-statistics)) ; Emacs >= 28.1
+      (setq action (copy-tree action))
+      (pcase-let ((`(,height ,width)
+                   (buffer-line-statistics transient--buffer))
+                  (params (assq 'pop-up-frame-parameters (cdr action))))
+        (setf (alist-get 'height params) height)
+        (setf (alist-get 'width params)
+              (max width (or transient-minimal-frame-width 0)))))
+    action))
+
+(defun transient--fit-window-to-buffer (window)
+  (set-window-parameter window 'window-preserved-size nil)
+  (let ((fit-window-to-buffer-horizontally t)
+        (window-resize-pixelwise t)
+        (window-size-fixed nil))
+    (cond ((not (window-parent window))
+           (fit-frame-to-buffer (window-frame window) nil nil nil
+                                transient-minimal-frame-width))
+          ((eq (car (window-parameter window 'quit-restore)) 'other)
+           ;; Grow but never shrink window that previously displayed
+           ;; another buffer and is going to display that again.
+           (fit-window-to-buffer window nil (window-height window)))
+          ((fit-window-to-buffer window nil 1))))
+  (set-window-parameter window 'window-preserved-size
+                        (list (window-buffer window)
+                              (window-body-width window t)
+                              (window-body-height window t))))
+
+(defun transient--mode-line-format ()
+  (if (slot-boundp transient--prefix 'mode-line-format)
+      (oref transient--prefix mode-line-format)
+    transient-mode-line-format))
+
+(defun transient--separator-line ()
+  (and-let* ((format (transient--mode-line-format))
+             (height (cond ((not window-system) nil)
+                           ((natnump format) format)
+                           ((eq format 'line) 1)))
+             (face `(,@(and (>= emacs-major-version 27) '(:extend t))
+                     :background ,(transient--prefix-color))))
+    (concat (propertize "__" 'face face 'display `(space :height (,height)))
+            (propertize "\n" 'face face 'line-height t))))
+
+(defun transient--prefix-color ()
+  (or (face-foreground (transient--key-face nil nil 'non-suffix) nil t)
+      "#gray60"))
+
+(defmacro transient-with-shadowed-buffer (&rest body)
+  "While in the transient buffer, temporarily make the shadowed buffer current."
+  (declare (indent 0) (debug t))
+  `(with-current-buffer (or transient--shadowed-buffer (current-buffer))
+     ,@body))
+
+(defun transient--insert-groups ()
+  (let ((groups (mapcan (lambda (group)
+                          (let ((hide (oref group hide)))
+                            (and (not (and (functionp hide)
+                                           (transient-with-shadowed-buffer
+                                             (funcall hide))))
+                                 (list group))))
+                        transient--layout)))
+    (while-let ((group (pop groups)))
+      (transient--insert-group group)
+      (when groups
+        (insert ?\n)))))
+
+(defvar transient--max-group-level 1)
+
+(cl-defgeneric transient--insert-group (group)
+  "Format GROUP and its elements and insert the result.")
+
+(cl-defmethod transient--insert-group :around ((group transient-group)
+                                               &optional _)
+  "Insert GROUP's description, if any."
+  (when-let ((desc (transient-with-shadowed-buffer
+                     (transient-format-description group))))
+    (insert desc ?\n))
+  (let ((transient--max-group-level
+         (max (oref group level) transient--max-group-level))
+        (transient--pending-group group))
+    (cl-call-next-method group)))
+
+(cl-defmethod transient--insert-group ((group transient-row))
+  (transient--maybe-pad-keys group)
+  (dolist (suffix (oref group suffixes))
+    (insert (transient-with-shadowed-buffer (transient-format suffix)))
+    (insert "   "))
+  (insert ?\n))
+
+(cl-defmethod transient--insert-group ((group transient-column)
+                                       &optional skip-empty)
+  (transient--maybe-pad-keys group)
+  (dolist (suffix (oref group suffixes))
+    (let ((str (transient-with-shadowed-buffer (transient-format suffix))))
+      (unless (and (not skip-empty) (equal str ""))
+        (insert str)
+        (unless (string-match-p ".\n\\'" str)
+          (insert ?\n))))))
+
+(cl-defmethod transient--insert-group ((group transient-columns))
+  (if (or transient-force-single-column transient--docsp)
+      (dolist (group (oref group suffixes))
+        (transient--insert-group group t))
+    (let* ((columns
+            (mapcar
+             (lambda (column)
+               (transient--maybe-pad-keys column group)
+               (transient-with-shadowed-buffer
+                 `(,@(and-let* ((desc (transient-format-description column)))
+                       (list desc))
+                   ,@(let ((transient--pending-group column))
+                       (mapcar #'transient-format (oref column suffixes))))))
+             (oref group suffixes)))
+           (stops (transient--column-stops columns)))
+      (dolist (row (apply #'transient--mapn #'list columns))
+        (let ((stops stops))
+          (dolist (cell row)
+            (let ((stop (pop stops)))
+              (when cell
+                (transient--align-to stop)
+                (insert cell)))))
+        (insert ?\n)))))
+
+(cl-defmethod transient--insert-group ((group transient-subgroups))
+  (let ((subgroups (oref group suffixes)))
+    (while-let ((subgroup (pop subgroups)))
+      (transient--maybe-pad-keys subgroup group)
+      (transient--insert-group subgroup)
+      (when subgroups
+        (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-suffix))
+  "Add additional formatting if appropriate.
+When reading user input for this infix, then highlight it.
+When edit-mode is enabled, then prepend the level information.
+When `transient-enable-popup-navigation' is non-nil then format
+as a button."
+  (let ((str (cl-call-next-method obj)))
+    (when (and (cl-typep obj 'transient-infix)
+               (eq (oref obj command) this-original-command)
+               (active-minibuffer-window))
+      (setq str (transient--add-face str 'transient-active-infix)))
+    (when transient--editp
+      (setq str (concat (let ((level (oref obj level)))
+                          (propertize (format " %s " level)
+                                      'face (if (transient--use-level-p level t)
+                                                'transient-enabled-suffix
+                                              'transient-disabled-suffix)))
+                        str)))
+    (when (and transient-enable-popup-navigation
+               (slot-boundp obj 'command))
+      (setq str (make-text-button str nil
+                                  'type 'transient
+                                  'suffix obj
+                                  'command (oref obj command))))
+    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'.
+%v 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 (if (slot-boundp obj 'key) (oref obj key) ""))
+        (cmd (and (slot-boundp obj 'command) (oref obj command))))
+    (when-let ((width (oref transient--pending-group pad-keys)))
+      (setq key (truncate-string-to-width key width nil ?\s)))
+    (if transient--redisplay-key
+        (let ((len (length transient--redisplay-key))
+              (seq (cl-coerce (edmacro-parse-keys key t) 'list)))
+          (cond
+           ((member (seq-take seq len)
+                    (list transient--redisplay-key
+                          (thread-last transient--redisplay-key
+                            (cl-substitute ?- 'kp-subtract)
+                            (cl-substitute ?= 'kp-equal)
+                            (cl-substitute ?+ 'kp-add))))
+            (let ((pre (key-description (vconcat (seq-take seq len))))
+                  (suf (key-description (vconcat (seq-drop seq len)))))
+              (setq pre (string-replace "RET" "C-m" pre))
+              (setq pre (string-replace "TAB" "C-i" pre))
+              (setq suf (string-replace "RET" "C-m" suf))
+              (setq suf (string-replace "TAB" "C-i" suf))
+              ;; 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-search " " key)
+                (setq pre (string-replace " " "" pre))
+                (setq suf (string-replace " " "" suf)))
+              (concat (propertize pre 'face 'transient-unreachable-key)
+                      (and (string-prefix-p (concat pre " ") key) " ")
+                      (propertize suf 'face (transient--key-face cmd key))
+                      (save-excursion
+                        (and (string-match " +\\'" key)
+                             (propertize (match-string 0 key)
+                                         'face 'fixed-pitch))))))
+           ((transient--lookup-key transient-sticky-map (kbd key))
+            (propertize key 'face (transient--key-face cmd key)))
+           (t
+            (propertize key 'face 'transient-unreachable-key))))
+      (propertize key 'face (transient--key-face cmd key)))))
+
+(cl-defmethod transient-format-key :around ((obj transient-argument))
+  "Handle `transient-highlight-mismatched-keys'."
+  (let ((key (cl-call-next-method obj)))
+    (cond
+     ((not transient-highlight-mismatched-keys) key)
+     ((not (slot-boundp obj 'shortarg))
+      (transient--add-face key 'transient-nonstandard-key))
+     ((not (string-equal key (oref obj shortarg)))
+      (transient--add-face key 'transient-mismatched-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-suffix))
+  "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."
+  (transient--get-description obj))
+
+(cl-defmethod transient-format-description ((obj transient-value-preset))
+  (pcase-let* (((eieio description key set) obj)
+               ((eieio value) transient--prefix)
+               (active (seq-set-equal-p set value)))
+    (format
+     "%s %s"
+     (propertize (or description (format "Preset %s" key))
+                 'face (and active 'transient-argument))
+     (format (propertize "(%s)" 'face 'transient-delimiter)
+             (mapconcat (lambda (arg)
+                          (propertize
+                           arg 'face (cond (active 'transient-argument)
+                                           ((member arg value)
+                                            '((:weight demibold)
+                                              transient-inactive-argument))
+                                           ('transient-inactive-argument))))
+                        set " ")))))
+
+(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."
+  (and-let* ((desc (transient--get-description obj)))
+    (cond ((oref obj inapt)
+           (propertize desc 'face 'transient-inapt-suffix))
+          ((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 (if-let ((transient--docsp)
+                       (cmd (oref obj command))
+                       (doc (ignore-errors (documentation cmd)))
+                       ((not (equal doc (documentation
+                                         'transient--default-infix-command)))))
+                  (substring doc 0 (string-match "\\.?\n" doc))
+                (or (cl-call-next-method obj)
+                    (and (slot-boundp transient--prefix 'suffix-description)
+                         (funcall (oref transient--prefix suffix-description)
+                                  obj))))))
+    (if desc
+        (when-let ((face (transient--get-face obj 'face)))
+          (setq desc (transient--add-face desc face t)))
+      (setq desc (propertize "(BUG: no description)" 'face 'error)))
+    (when (if transient--all-levels-p
+              (> (oref obj level) transient--default-prefix-level)
+            (and transient-highlight-higher-levels
+                 (> (max (oref obj level) transient--max-group-level)
+                    transient--default-prefix-level)))
+      (setq desc (transient--add-face desc 'transient-higher-level)))
+    (when-let ((inapt-face (and (oref obj inapt)
+                                (transient--get-face obj 'inapt-face))))
+      (setq desc (transient--add-face desc inapt-face)))
+    (when (and (slot-boundp obj 'key)
+               (transient--key-unreachable-p obj))
+      (setq desc (transient--add-face desc '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 ((argument (oref obj argument)))
+    (if-let ((value (oref obj value)))
+        (pcase-exhaustive (oref obj multi-value)
+          ('nil
+           (concat (propertize argument 'face 'transient-argument)
+                   (propertize value    'face 'transient-value)))
+          ((or 't 'rest)
+           (concat (propertize (if (string-suffix-p " " argument)
+                                   argument
+                                 (concat argument " "))
+                               'face 'transient-argument)
+                   (propertize (mapconcat #'prin1-to-string value " ")
+                               'face 'transient-value)))
+          ('repeat
+           (mapconcat (lambda (value)
+                        (concat (propertize argument 'face 'transient-argument)
+                                (propertize value    'face 'transient-value)))
+                      value " ")))
+      (propertize argument 'face 'transient-inactive-argument))))
+
+(cl-defmethod transient-format-value ((obj transient-switches))
+  (with-slots (value argument-format choices) obj
+    (format (propertize argument-format
+                        'face (if value
+                                  'transient-argument
+                                'transient-inactive-argument))
+            (format
+             (propertize "[%s]" 'face 'transient-delimiter)
+             (mapconcat
+              (lambda (choice)
+                (propertize choice 'face
+                            (if (equal (format argument-format choice) value)
+                                'transient-value
+                              'transient-inactive-value)))
+              choices
+              (propertize "|" 'face 'transient-delimiter))))))
+
+(cl-defmethod transient--get-description ((obj transient-child))
+  (and-let* ((desc (oref obj description)))
+    (if (functionp desc)
+        (if (= (car (transient--func-arity desc)) 1)
+            (funcall desc obj)
+          (funcall desc))
+      desc)))
+
+(cl-defmethod transient--get-face ((obj transient-suffix) slot)
+  (and-let* (((slot-boundp obj slot))
+             (face (slot-value obj slot)))
+    (if (and (not (facep face))
+             (functionp face))
+        (let ((transient--pending-suffix obj))
+          (if (= (car (transient--func-arity face)) 1)
+              (funcall face obj)
+            (funcall face)))
+      face)))
+
+(defun transient--add-face (string face &optional append beg end)
+  (let ((str (copy-sequence string)))
+    (add-face-text-property (or beg 0) (or end (length str)) face append str)
+    str))
+
+(defun transient--key-face (cmd key &optional enforce-type)
+  (or (and transient-semantic-coloring
+           (not transient--helpp)
+           (not transient--editp)
+           (get (transient--get-pre-command cmd key enforce-type)
+                'transient-face))
+      (if cmd 'transient-key 'transient-key-noop)))
+
+(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)))
+
+(defun transient--maybe-pad-keys (group &optional parent)
+  (when-let ((pad (or (oref group pad-keys)
+                      (and parent (oref parent pad-keys)))))
+    (oset group pad-keys
+          (apply #'max
+                 (if (integerp pad) pad 0)
+                 (seq-keep (lambda (suffix)
+                             (and (eieio-object-p suffix)
+                                  (slot-boundp suffix 'key)
+                                  (length (oref suffix key))))
+                           (oref group suffixes))))))
+
+(defun transient--pixel-width (string)
+  (save-window-excursion
+    (with-temp-buffer
+      (insert string)
+      (set-window-dedicated-p nil nil)
+      (set-window-buffer nil (current-buffer))
+      (car (window-text-pixel-size
+            nil (line-beginning-position) (point))))))
+
+(defun transient--column-stops (columns)
+  (let* ((var-pitch (or transient-align-variable-pitch
+                        (oref transient--prefix variable-pitch)))
+         (char-width (and var-pitch (transient--pixel-width " "))))
+    (transient--seq-reductions-from
+     (apply-partially #'+ (* 2 (if var-pitch char-width 1)))
+     (transient--mapn
+      (lambda (cells min)
+        (apply #'max
+               (if min (if var-pitch (* min char-width) min) 0)
+               (mapcar (if var-pitch #'transient--pixel-width #'length) cells)))
+      columns
+      (oref transient--prefix column-widths))
+     0)))
+
+(defun transient--align-to (stop)
+  (unless (zerop stop)
+    (insert (if (or transient-align-variable-pitch
+                    (oref transient--prefix variable-pitch))
+                (propertize " " 'display `(space :align-to (,stop)))
+              (make-string (max 0 (- stop (current-column))) ?\s)))))
+
+(defun transient-command-summary-or-name (obj)
+  "Return the summary or name of the command represented by OBJ.
+
+If the command has a doc-string, then return the first line of
+that, else its name.
+
+Intended to be temporarily used as the `:suffix-description' of
+a prefix command, while porting a regular keymap to a transient."
+  (let ((command (oref obj command)))
+    (if-let ((doc (documentation command)))
+        (propertize (car (split-string doc "\n")) 'face 'font-lock-doc-face)
+      (propertize (symbol-name command) 'face 'font-lock-function-name-face))))
+
+;;; Help
+
+(cl-defgeneric transient-show-help (obj)
+  "Show documentation for the command represented by OBJ.")
+
+(cl-defmethod transient-show-help ((obj transient-prefix))
+  "Call `show-help' if non-nil, else show `info-manual',
+if non-nil, else show the `man-page' if non-nil, else use
+`describe-function'."
+  (with-slots (show-help info-manual man-page command) obj
+    (cond (show-help (funcall show-help obj))
+          (info-manual (transient--show-manual info-manual))
+          (man-page (transient--show-manpage man-page))
+          ((transient--describe-function command)))))
+
+(cl-defmethod transient-show-help ((obj transient-suffix))
+  "Call `show-help' if non-nil, else use `describe-function'.
+Also used to dispatch showing documentation for the current
+prefix.  If the suffix is a sub-prefix, then also call the
+prefix method."
+  (cond
+   ((eq this-command 'transient-help)
+    (transient-show-help transient--prefix))
+   ((let ((prefix (get (oref obj command)
+                       'transient--prefix)))
+      (and prefix (not (eq (oref transient--prefix command) this-command))
+           (prog1 t (transient-show-help prefix)))))
+   ((if-let ((show-help (oref obj show-help)))
+        (funcall show-help obj)
+      (transient--describe-function this-command)))))
+
+(cl-defmethod transient-show-help ((obj transient-infix))
+  "Call `show-help' if non-nil, else show the `man-page'
+if non-nil, else use `describe-function'.  When showing the
+manpage, then try to jump to the correct location."
+  (if-let ((show-help (oref obj show-help)))
+      (funcall show-help obj)
+    (if-let ((man-page (oref transient--prefix man-page))
+             (argument (and (slot-boundp obj 'argument)
+                            (oref obj argument))))
+        (transient--show-manpage man-page argument)
+      (transient--describe-function this-command))))
+
+;; `cl-generic-generalizers' doesn't support `command' et al.
+(cl-defmethod transient-show-help (cmd)
+  "Show the command doc-string."
+  (transient--describe-function cmd))
+
+(defmacro transient-with-help-window (&rest body)
+  "Evaluate BODY, send output to *Help* buffer, and display it in a window.
+Select the help window, and make the help buffer current and return it."
+  (declare (indent 0))
+  `(let ((buffer nil)
+         (help-window-select t))
+     (with-help-window (help-buffer)
+       ,@body
+       (setq buffer (current-buffer)))
+     (set-buffer buffer)))
+
+(defun transient--display-help (helper target)
+  (let ((winconf (current-window-configuration)))
+    (funcall (cond (helper)
+                   ((symbolp target) #'transient--describe-function)
+                   ((stringp target)
+                    (if (string-prefix-p "(" target)
+                        #'transient--show-manual
+                      #'transient--show-manpage))
+                   ((error "Unknown how to show help for %S" target)))
+             target)
+    (setq-local transient--restore-winconf winconf))
+  (fit-window-to-buffer nil (frame-height) (window-height))
+  (transient-resume-mode)
+  (message (substitute-command-keys "Type \\`q' to resume transient command.")))
+
+(defun transient--describe-function (fn)
+  (let* ((buffer nil)
+         (help-window-select t)
+         (temp-buffer-window-setup-hook
+          (cons (lambda () (setq buffer (current-buffer)))
+                temp-buffer-window-setup-hook)))
+    (describe-function fn)
+    (set-buffer buffer)))
+
+(defun transient--show-manual (manual)
+  (info manual))
+
+(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--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))))))
+
+(cl-defgeneric transient-show-summary (obj &optional return)
+  "Show brief summary about the command at point in the echo area.
+
+If OBJ's `summary' slot is a string, use that.  If it is a function,
+call that with OBJ as the only argument and use the returned string.
+If `summary' is or returns something other than a string or nil,
+show no summary.  If `summary' is or returns nil, use the first line
+of the documentation string, if any.
+
+If RETURN is non-nil, return the summary instead of showing it.
+This is used when a tooltip is needed.")
+
+(cl-defmethod transient-show-summary ((obj transient-suffix) &optional return)
+  (with-slots (command summary) obj
+    (when-let*
+        ((doc (cond ((functionp summary)
+                     (funcall summary obj))
+                    (summary)
+                    ((car (split-string (documentation command) "\n")))))
+         ((stringp doc))
+         ((not (equal doc
+                      (car (split-string (documentation
+                                          'transient--default-infix-command)
+                                         "\n"))))))
+      (when (string-suffix-p "." doc)
+        (setq doc (substring doc 0 -1)))
+      (if return
+          doc
+        (let ((message-log-max nil))
+          (message "%s" doc))))))
+
+;;; Popup Navigation
+
+(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-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)
+    (when (eq transient-enable-popup-navigation 'verbose)
+      (transient-show-summary (get-text-property (point) 'suffix)))))
+
+(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)
+    (when (eq transient-enable-popup-navigation 'verbose)
+      (transient-show-summary (get-text-property (point) 'suffix)))))
+
+(define-button-type 'transient
+  'face nil
+  'keymap transient-button-map
+  'help-echo (lambda (win buf pos)
+               (with-selected-window win
+                 (with-current-buffer buf
+                   (transient-show-summary
+                    (get-text-property pos 'suffix) t)))))
+
+(defun transient--goto-button (command)
+  (cond
+   ((stringp command)
+    (when (re-search-forward (concat "^" (regexp-quote command)) nil t)
+      (goto-char (match-beginning 0))))
+   (command
+    (cl-flet ((found () (eq (button-get (button-at (point)) 'command) command)))
+      (while (and (ignore-errors (forward-button 1))
+                  (not (found))))
+      (unless (found)
+        (goto-char (point-min))
+        (ignore-errors (forward-button 1))
+        (unless (found)
+          (goto-char (point-min))))))))
+
+(defun transient--heading-at-point ()
+  (and (eq (get-text-property (point) 'face) 'transient-heading)
+       (let ((beg (line-beginning-position)))
+         (buffer-substring-no-properties
+          beg (next-single-property-change
+               beg 'face nil (line-end-position))))))
+
+;;; Compatibility
+;;;; Popup Isearch
+
+(defvar-keymap transient--isearch-mode-map
+  :parent isearch-mode-map
+  "<remap> <isearch-exit>"   #'transient-isearch-exit
+  "<remap> <isearch-cancel>" #'transient-isearch-cancel
+  "<remap> <isearch-abort>"  #'transient-isearch-abort)
+
+(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)
+  (let ((around (lambda (fn)
+                  (condition-case nil (funcall fn) (quit))
+                  (transient--isearch-exit))))
+    (advice-add 'isearch-cancel :around around)
+    (unwind-protect
+        (isearch-abort)
+      (advice-remove 'isearch-cancel around))))
+
+(defun transient--isearch-setup ()
+  (select-window transient--window)
+  (transient--suspend-override t))
+
+(defun transient--isearch-exit ()
+  (select-window transient--original-window)
+  (transient--resume-override))
+
+;;;; 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
+
+(cl-pushnew (list nil (concat "^\\s-*("
+                              (eval-when-compile
+                                (regexp-opt
+                                 '("transient-define-prefix"
+                                   "transient-define-suffix"
+                                   "transient-define-infix"
+                                   "transient-define-argument")
+                                 t))
+                              "\\s-+\\(" lisp-mode-symbol-regexp "\\)")
+                  2)
+            lisp-imenu-generic-expression :test #'equal)
+
+(declare-function which-key-mode "ext:which-key" (&optional arg))
+
+(defun transient--suspend-which-key-mode ()
+  (when (bound-and-true-p which-key-mode)
+    (which-key-mode -1)
+    (add-hook 'transient-exit-hook #'transient--resume-which-key-mode)))
+
+(defun transient--resume-which-key-mode ()
+  (unless transient--prefix
+    (which-key-mode 1)
+    (remove-hook 'transient-exit-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."
+  (keymap-set transient-base-map   "q" #'transient-quit-one)
+  (keymap-set 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")
+          (key))))
+
+(defun transient--force-fixed-pitch ()
+  (require 'face-remap)
+  (face-remap-reset-base 'default)
+  (face-remap-add-relative 'default 'fixed-pitch))
+
+(defun transient--func-arity (fn)
+  (func-arity (advice--cd*r (if (symbolp fn) (symbol-function fn) fn))))
+
+(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)))
+
+(defun transient--mapn (function &rest lists)
+  "Apply FUNCTION to elements of LISTS.
+Like `cl-mapcar' but while that stops when the shortest list
+is exhausted, continue until the longest list is, using nil
+as stand-in for elements of exhausted lists."
+  (let (result)
+    (while (catch 'more (mapc (lambda (l) (and l (throw 'more t))) lists) nil)
+      (push (apply function (mapcar #'car-safe lists)) result)
+      (setq lists (mapcar #'cdr lists)))
+    (nreverse result)))
+
+;;; Font-Lock
+
+(defconst transient-font-lock-keywords
+  (eval-when-compile
+    `((,(concat "("
+                (regexp-opt (list "transient-define-prefix"
+                                  "transient-define-infix"
+                                  "transient-define-argument"
+                                  "transient-define-suffix")
+                            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)
+
+;;; Auxiliary Classes
+;;;; `transient-lisp-variable'
+
+(defclass transient-lisp-variable (transient-variable)
+  ((reader :initform #'transient-lisp-variable--reader)
+   (always-read :initform t)
+   (set-value :initarg :set-value :initform #'set))
+  "[Experimental] Class used for Lisp variables.")
+
+(cl-defmethod transient-init-value ((obj transient-lisp-variable))
+  (oset obj value (symbol-value (oref obj variable))))
+
+(cl-defmethod transient-infix-set ((obj transient-lisp-variable) value)
+  (funcall (oref obj set-value)
+           (oref obj variable)
+           (oset obj value value)))
+
+(cl-defmethod transient-format-description ((obj transient-lisp-variable))
+  (or (cl-call-next-method obj)
+      (symbol-name (oref obj variable))))
+
+(cl-defmethod transient-format-value ((obj transient-lisp-variable))
+  (propertize (prin1-to-string (oref obj value))
+              'face 'transient-value))
+
+(cl-defmethod transient-prompt ((obj transient-lisp-variable))
+  (if (and (slot-boundp obj 'prompt)
+           (oref obj prompt))
+      (cl-call-next-method obj)
+    (format "Set %s: " (oref obj variable))))
+
+(defun transient-lisp-variable--reader (prompt initial-input _history)
+  (read--expression prompt initial-input))
+
+;;; _
+(provide 'transient)
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; checkdoc-symbol-words: ("command-line" "edit-mode" "help-mode")
+;; End:
+;;; transient.el ends here
diff --git a/elpa/transient-20241219.1713/transient.info b/elpa/transient-20241219.1713/transient.info
new file mode 100644 (file)
index 0000000..da24513
--- /dev/null
@@ -0,0 +1,3720 @@
+This is transient.info, produced by makeinfo version 6.8 from
+transient.texi.
+
+     Copyright (C) 2018–2024 Free Software Foundation, Inc.
+
+     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 misc features
+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
+***********************************
+
+Transient is the library used to implement the keyboard-driven “menus”
+in Magit.  It is distributed as a separate package, so that it can be
+used to implement similar menus in other packages.
+
+   This manual can be bit hard to digest when getting started.  A useful
+resource to get over that hurdle is Psionic K’s interactive tutorial,
+available at <https://github.com/positron-solutions/transient-showcase>.
+
+This manual is for Transient version 0.8.1.
+
+     Copyright (C) 2018–2024 Free Software Foundation, Inc.
+
+     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::
+* Modifying Existing Transients::
+* Defining New Commands::
+* Classes and Methods::
+* FAQ::
+* Keystroke Index::
+* Command and Function Index::
+* Variable Index::
+* Concept Index::
+* GNU General Public License::
+
+— 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::
+* Configuration::
+
+Defining New Commands
+
+* Technical Introduction::
+* Defining Transients::
+* Binding Suffix and Infix Commands::
+* Defining Suffix and Infix Commands::
+* Using Infix Arguments::
+* Current Suffix Command::
+* Current Prefix Command::
+* Transient State::
+
+Binding Suffix and Infix Commands
+
+* Group Specifications::
+* Suffix Specifications::
+
+
+Classes and Methods
+
+* Group Classes::
+* Group Methods::
+* Prefix Classes::
+* Suffix Classes::
+* Prefix Methods::
+* Suffix Methods::
+* Prefix Slots::
+* Suffix Slots::
+* Predicate Slots::
+
+Suffix Methods
+
+* Suffix Value Methods::
+* Suffix Format Methods::
+
+
+
+\1f
+File: transient.info,  Node: Introduction,  Next: Usage,  Prev: Top,  Up: Top
+
+1 Introduction
+**************
+
+Transient is the library used to implement the keyboard-driven “menus”
+in Magit.  It is distributed as a separate package, so that it can be
+used to implement similar menus in other packages.
+
+   This manual can be bit hard to digest when getting started.  A useful
+resource to get over that hurdle is Psionic K’s interactive tutorial,
+available at <https://github.com/positron-solutions/transient-showcase>.
+
+Some things that Transient can do
+=================================
+
+   • Display current state of arguments
+   • Display and manage lifecycle of modal bindings
+   • Contextual user interface
+   • Flow control for wizard-like composition of interactive forms
+   • History & persistence
+   • Rendering arguments for controlling CLI programs
+
+Complexity in CLI programs
+==========================
+
+Complexity tends to grow with time.  How do you manage the complexity of
+commands?  Consider the humble shell command ‘ls’.  It now has over
+_fifty_ command line options.  Some of these are boolean flags (‘ls
+-l’).  Some take arguments (‘ls --sort=s’).  Some have no effect unless
+paired with other flags (‘ls -lh’).  Some are mutually exclusive.  Some
+shell commands even have so many options that they introduce
+_subcommands_ (‘git branch’, ‘git commit’), each with their own rich set
+of options (‘git branch -f’).
+
+Using Transient for composing interactive commands
+==================================================
+
+What about Emacs commands used interactively?  How do these handle
+options?  One solution is to make many versions of the same command, so
+you don’t need to!  Consider: ‘delete-other-windows’ vs.
+‘delete-other-windows-vertically’ (among many similar examples).
+
+   Some Emacs commands will simply prompt you for the next "argument"
+(‘M-x switch-to-buffer’).  Another common solution is to use prefix
+arguments which usually start with ‘C-u’.  Sometimes these are sensibly
+numerical in nature (‘C-u 4 M-x forward-paragraph’ to move forward 4
+paragraphs).  But sometimes they function instead as boolean "switches"
+(‘C-u C-SPACE’ to jump to the last mark instead of just setting it, ‘C-u
+C-u C-SPACE’ to unconditionally set the mark).  Since there aren’t many
+standards for the use of prefix options, you have to read the command’s
+documentation to find out what the possibilities are.
+
+   But when an Emacs command grows to have a truly large set of options
+and arguments, with dependencies between them, lots of option values,
+etc., these simple approaches just don’t scale.  Transient is designed
+to solve this issue.  Think of it as the humble prefix argument ‘C-u’,
+_raised to the power of 10_.  Like ‘C-u’, it is key driven.  Like the
+shell, it supports boolean "flag" options, options that take arguments,
+and even "sub-commands", with their own options.  But instead of
+searching through a man page or command documentation, well-designed
+transients _guide_ their users to the relevant set of options (and even
+their possible values!)  directly, taking into account any important
+pre-existing Emacs settings.  And while for shell commands like ‘ls’,
+there is only one way to "execute" (hit ‘Return’!), transients can
+"execute" using multiple different keys tied to one of many
+self-documenting _actions_ (imagine having 5 different colored return
+keys on your keyboard!).  Transients make navigating and setting large,
+complex groups of command options and arguments easy.  Fun even.  Once
+you’ve tried it, it’s hard to go back to the ‘C-u what can I do here
+again?’ way.
+
+\1f
+File: transient.info,  Node: Usage,  Next: Modifying Existing Transients,  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::
+* Configuration::
+
+\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, and that those bindings are displayed in a transient menu,
+displayed in a popup buffer.  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 the 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, e.g., by setting the
+value of some variable.
+
+\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, 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 documentation 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’
+     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.
+
+   This includes the aborting commands mentioned in the previous
+section, as well as some other commands that are all bound to ‘C-x KEY’.
+After ‘C-x’ is pressed, a section featuring all these common commands is
+temporarily shown in the popup buffer.  After invoking one of them, the
+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 too many options.
+
+     While a transient is active, pressing ‘C-x’ always shows the common
+     commands.  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 or in
+one of the following sections.
+
+\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’)
+     This command saves the value of the active transient persistently
+     across Emacs sessions.
+
+‘C-x C-k’ (‘transient-reset’)
+     This command clears the set and saved values of the active
+     transient.
+
+ -- User Option: transient-values-file
+     This option names the file that 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.
+
+\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.
+
+‘C-M-p’ (‘transient-history-prev’)
+‘C-x p’
+     This command switches to the previous value used for the active
+     transient.
+
+‘C-M-n’ (‘transient-history-next’)
+‘C-x n’
+     This command switches to the next value used for the active
+     transient.
+
+   In addition to the transient-wide history, infixes can have their own
+history.  When an infix reads user-input using the minibuffer, 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-save-history
+     This option controls whether the history of transient commands is
+     saved when exiting Emacs.
+
+ -- User Option: transient-history-file
+     This option names the file that 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, typing a
+     key shows information about the suffix command that the key
+     normally is bound to (instead of invoking it).  Pressing ‘C-h’ a
+     second time shows information about the _prefix_ command.
+
+     After typing a 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 documentation 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.
+
+ -- 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 option names the file that 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.
+
+‘C-x a’ (‘transient-toggle-level-limit’)
+     This command toggle whether suffixes that are on levels higher than
+     the level specified by ‘transient-default-level’ are temporarily
+     available anyway.
+
+\1f
+File: transient.info,  Node: Other Commands,  Next: Configuration,  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).
+
+   The following commands are not available by default.  If you would
+like to use them for all menus, bind them in ‘transient-map’.
+
+ -- Command: transient-copy-menu-text
+     This command copies the contents of the menu buffer to the kill
+     ring.
+
+ -- Command: transient-toggle-docstrings
+     This command toggle between showing suffix descriptions in the menu
+     (as usual) or showing the first lines of the respective docstrings
+     in their place.  For commands that do not have a docstring, always
+     display the suffix description.  Because there likely isn’t enough
+     room to display multiple docstrings side-by-side, a single column
+     is used when displaying docstrings.
+
+\1f
+File: transient.info,  Node: Configuration,  Prev: Other Commands,  Up: Usage
+
+2.9 Configuration
+=================
+
+More options are described in *note Common Suffix Commands::, in *note
+Saving Values::, in *note Using History:: and in *note Enabling and
+Disabling Suffixes::.
+
+Essential Options
+-----------------
+
+Also see *note Common Suffix Commands::.
+
+ -- 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, the popup is shown after that many seconds of inactivity
+          (using the absolute value).
+
+ -- 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 too many options.
+
+     While a transient is active, pressing ‘C-x’ always shows the common
+     commands.  The value of this option can be changed for the current
+     Emacs session by typing ‘C-x t’ while a transient is active.
+
+ -- User Option: transient-show-during-minibuffer-read
+     This option controls whether the transient menu continues to be
+     displayed while the minibuffer is used to read user input.
+
+     This is only relevant to commands that do not close the menu, such
+     as commands that set infix arguments.  If a command exits the menu,
+     and uses the minibuffer, then the menu is always closed before the
+     minibuffer is entered, irrespective of the value of this option.
+
+     When ‘nil’ (the default), hide the menu while the minibuffer is in
+     use.  When ‘t’, keep showing the menu, but allow for the menu
+     window to be resized, to ensure that completion candidates can be
+     displayed.
+
+     When ‘fixed’, keep showing the menu and prevent it from being
+     resized, which may make it impossible to display the completion
+     candidates.  If that ever happens for you, consider using ‘t’ or an
+     integer, as described below.
+
+     If the value is ‘fixed’ and the menu window uses the full height of
+     its frame, then the former is ignored and resizing is allowed
+     anyway.  This is necessary because individual menus may use unusual
+     display actions different from what
+     ‘transient-display-buffer-action’ specifies (likely to display that
+     menu in a side-window).
+
+     When using a third-party mode, which automatically resizes windows
+     (e.g., by calling ‘balance-windows’ on ‘post-command-hook’), then
+     ‘fixed’ (or ‘nil’) is likely a better choice than ‘t’.
+
+     The value can also be an integer, in which case the behavior
+     depends on whether at least that many lines are left to display
+     windows other than the menu window.  If that is the case, display
+     the menu and preserve the size of that window.  Otherwise, allow
+     resizing the menu window if the number is positive, or hide the
+     menu if it is negative.
+
+ -- 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’, there is no initial input and
+     the first element has to be accessed the same way as the older
+     elements.
+
+ -- User Option: transient-enable-popup-navigation
+     This option controls whether navigation commands are enabled in the
+     transient popup buffer.  If the value is ‘verbose’ (the default),
+     brief documentation about the command under point is additionally
+     show in the echo area.
+
+     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 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.
+        • ‘M-<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.
+
+     By default ‘M-<RET>’ is bound to ‘transient-push-button’, instead
+     of ‘<RET>’, because if a transient allows the invocation of
+     non-suffixes, then it is likely, that you would want ‘<RET>’ to do
+     what it would do if no transient were active."
+
+ -- 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 BUFFER 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::, for
+     details.
+
+     The default is:
+
+          (display-buffer-in-side-window
+           (side . bottom)
+           (dedicated . t)
+           (inhibit-same-window . t))
+
+     This displays the window at the bottom of the selected frame.  For
+     alternatives see *note (elisp)Buffer Display Action Functions::,
+     and *note (elisp)Buffer Display Action Alists::.
+
+     Note that the buffer that was current before the transient buffer
+     is shown should remain the current buffer.  Many suffix commands
+     act on the thing at point, if appropriate, and if the transient
+     buffer became the current buffer, then that would change what is at
+     point.  To that effect ‘inhibit-same-window’ ensures that the
+     selected window is not used to show the transient buffer.
+
+     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 that
+     unfortunately changes which buffer is current.
+
+     If you change the value of this option, then you might also want to
+     change the value of ‘transient-mode-line-format’.
+
+     This user option may be overridden if ‘:display-action’ is passed
+     when creating a new prefix with ‘transient-define-prefix’.
+
+Accessibility Options
+---------------------
+
+ -- User Option: transient-force-single-column
+     This option controls whether the use of a single column to display
+     suffixes is enforced.  This might be useful for users with low
+     vision who use large text and might otherwise have to scroll in two
+     dimensions.
+
+Auxiliary Options
+-----------------
+
+ -- 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) or a natural number, then the buffer has no
+     mode-line, but a line is drawn in its place.  If a number is used,
+     that specifies the thickness of the line.  On termcap frames we
+     cannot draw lines, so there ‘line’ and numbers are synonyms for
+     ‘nil’.
+
+     The color of the line is used to indicate if non-suffixes are
+     allowed and whether they exit the transient.  The foreground color
+     of ‘transient-key-noop’ (if non-suffixes are disallowed),
+     ‘transient-key-stay’ (if allowed and transient stays active), or
+     ‘transient-key-exit’ (if allowed and they exit the transient) is
+     used to draw the line.
+
+     This user option may be overridden if ‘:mode-line-format’ is passed
+     when creating a new prefix with ‘transient-define-prefix’.
+
+     Otherwise this can be any mode-line format.  See *note (elisp)Mode
+     Line Format::, for details.
+
+ -- User Option: transient-semantic-coloring
+     This option controls whether colors are used to indicate the
+     transient behavior of commands.
+
+     If non-‘nil’, then the key binding of each suffix is colorized to
+     indicate whether it exits the transient state or not.  The color of
+     the prefix is indicated using the line that is drawn when the value
+     of ‘transient-mode-line-format’ is ‘line’.
+
+ -- 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’, 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 the 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-align-variable-pitch
+     This option controls whether columns are aligned pixel-wise in the
+     popup buffer.
+
+     If this is non-‘nil’, then columns are aligned pixel-wise to
+     support variable-pitch fonts.  Keys are not aligned, so you should
+     use a fixed-pitch font for the ‘transient-key’ face.  Other key
+     faces inherit from that face unless a theme is used that breaks
+     that relationship.
+
+     This option is intended for users who use a variable-pitch font for
+     the ‘default’ face.
+
+ -- 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.
+
+Developer Options
+-----------------
+
+These options are mainly intended for developers.
+
+ -- 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, 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-highlight-higher-levels
+     This option controls whether suffixes that would not be available
+     by default are highlighted.
+
+     When non-‘nil’ then the descriptions of suffixes are highlighted if
+     their level is above 4, the default of ‘transient-default-level’.
+     Assuming you have set that variable to 7, this highlights all
+     suffixes that won’t be available to users without them making the
+     same customization.
+
+Hook Variables
+--------------
+
+ -- Variable: transient-exit-hook
+     This hook is run after a transient is exited.
+
+ -- Variable: transient-setup-buffer-hook
+     This hook is run when the transient buffer is being setup.  That
+     buffer is current and empty when this hook is runs.
+
+\1f
+File: transient.info,  Node: Modifying Existing Transients,  Next: Defining New Commands,  Prev: Usage,  Up: Top
+
+3 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.  Let’s begin with
+an example:
+
+     (transient-append-suffix 'magit-patch-apply "-3"
+       '("-R" "Apply in reverse" "--reverse"))
+
+   This inserts a new infix argument to toggle the ‘--reverse’ argument
+after the infix argument that toggles ‘-3’ in ‘magit-patch-apply’.
+
+   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 ‘transient-define-prefix’.  Note that an infix
+     is a special kind of suffix.  Depending on context “suffixes” means
+     “suffixes (including infixes)” or “non-infix suffixes”.  Here it
+     means the former.  See *note Suffix Specifications::.
+
+     SUFFIX may also be a group in the same form as expected by
+     ‘transient-define-prefix’.  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 &optional
+          keep-other
+ -- Function: transient-append-suffix prefix loc suffix &optional
+          keep-other
+     These functions insert the suffix or group SUFFIX into PREFIX
+     before or after LOC.
+
+     Conceptually adding a binding to a transient prefix is similar to
+     adding a binding to a keymap, but this is complicated by the fact
+     that multiple suffix commands can be bound to the same key,
+     provided they are never active at the same time, see *note
+     Predicate Slots::.
+
+     Unfortunately both false-positives and false-negatives are
+     possible.  To deal with the former use non-‘nil’ KEEP-OTHER.  To
+     deal with the latter remove the conflicting binding explicitly.
+
+ -- 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
+
+4 Defining New Commands
+***********************
+
+* Menu:
+
+* Technical Introduction::
+* Defining Transients::
+* Binding Suffix and Infix Commands::
+* Defining Suffix and Infix Commands::
+* Using Infix Arguments::
+* Current Suffix Command::
+* Current Prefix Command::
+* Transient State::
+
+\1f
+File: transient.info,  Node: Technical Introduction,  Next: Defining Transients,  Up: Defining New Commands
+
+4.1 Technical Introduction
+==========================
+
+Taking inspiration from prefix keys and prefix arguments, Transient
+implements a similar abstraction involving a prefix command, infix
+arguments and suffix commands.
+
+   When the user calls a transient prefix command, 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 any command can choose to use or ignore the prefix
+arguments.  For a suffix command that was invoked from a transient, the
+variable ‘transient-current-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’.
+
+   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, which can be thought of as a “menu”.  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’ (on ‘C-x M-g’) 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, one can call a command with arguments that are just as
+complex as when calling the same function non-interactively from Lisp.
+
+   Invoking a transient suffix 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).
+
+   Note that suffix commands also support regular prefix arguments.  A
+suffix command may even be called with both infix and prefix arguments
+at the same time.  If you invoke a command as a suffix of a transient
+prefix command, but also want to pass prefix arguments to it, then first
+invoke the prefix command, and only after doing that invoke the prefix
+arguments, before finally invoking the suffix command.  If you instead
+began by providing the prefix arguments, then those would apply to the
+prefix command, not the suffix command.  Likewise, if you want to change
+infix arguments before invoking a suffix command with prefix arguments,
+then change the infix arguments before invoking the prefix arguments.
+In other words, regular prefix arguments always apply to the next
+command, and since transient prefix, infix and suffix commands are just
+regular commands, the same applies to them.  (Regular prefix keys behave
+differently because they are not commands at all, instead they are just
+incomplete key sequences, and those cannot be interrupted with prefix
+commands.)
+
+\1f
+File: transient.info,  Node: Defining Transients,  Next: Binding Suffix and Infix Commands,  Prev: Technical Introduction,  Up: Defining New Commands
+
+4.2 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: transient-define-prefix 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
+
+4.3 Binding Suffix and Infix Commands
+=====================================
+
+The macro ‘transient-define-prefix’ 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 ‘transient-define-prefix’.
+
+* Menu:
+
+* Group Specifications::
+* Suffix Specifications::
+
+\1f
+File: transient.info,  Node: Group Specifications,  Next: Suffix Specifications,  Up: Binding Suffix and Infix Commands
+
+4.3.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 ‘transient-define-prefix’, 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...’ and ‘:inapt-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::.
+
+   • 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 value of ‘:setup-children’, if non-‘nil’, is a function that
+     takes one argument, a potentially list of children, and must return
+     a list of children or an empty list.  This can either be used to
+     somehow transform the group’s children that were defined the normal
+     way, or to dynamically create the children from scratch.
+
+     The returned children must have the same form as stored in the
+     prefix’s ‘transient--layout’ property, but it is often more
+     convenient to use the same form as understood by
+     ‘transient-define-prefix’, described below.  If you use the latter
+     approach, you can use the ‘transient-parse-suffixes’ and
+     ‘transient-parse-suffix’ functions to transform them from the
+     convenient to the expected form.  Depending on the used group
+     class, ‘transient-parse-suffixes’’s SUFFIXES must be a list of
+     group vectors (for ‘transient-columns’) or a list of suffix lists
+     (for all other group classes).
+
+     If you explicitly specify children and then transform them using
+     ‘:setup-children’, then the class of the group is determined as
+     usual, based on explicitly specified children.
+
+     If you do not explicitly specify children and thus rely solely on
+     ‘:setup-children’, then you must specify the class using ‘:class’.
+     For backward compatibility, if you fail to do so,
+     ‘transient-column’ is used and a warning is displayed.  This
+     warning will eventually be replaced with an error.
+
+          (transient-define-prefix my-finder-by-keyword ()
+            "Select a keyword and list matching packages."
+            ;; The real `finder-by-keyword' is more convenient
+            ;; of course, but that is not the point here.
+            [:class transient-columns
+             :setup-children
+             (lambda (_)
+               (transient-parse-suffixes
+                'my-finder-by-keyword
+                (let ((char (1- ?A)))
+                  (mapcar                  ; a list ...
+                   (lambda (partition)
+                     (vconcat              ; of group vectors ...
+                      (mapcar (lambda (elt)
+                                (let ((keyword (symbol-name (car elt))))
+                                           ; ... where each suffix is a list
+                                  (list (format "%c" (cl-incf char))
+                                        keyword
+                                        (lambda ()
+                                          (interactive)
+                                          (finder-list-matches keyword)))))
+                              partition)))
+                   (seq-partition finder-known-keywords 7)))))])
+
+   • The boolean ‘:pad-keys’ argument controls whether keys of all
+     suffixes contained in a group are right padded, effectively
+     aligning the descriptions.
+
+   The ELEMENTs are either all subgroups, or all suffixes and strings.
+(At least currently no group type exists that would allow mixing
+subgroups with commands at the same level, though in principle there is
+nothing that prevents that.)
+
+   If the ELEMENTs are not subgroups, then they can be a mixture of
+lists, which specify commands, and strings.  Strings are inserted
+verbatim into the buffer.  The empty string can be used to insert gaps
+between suffixes, which is particularly useful if the suffixes are
+outlined as a table.
+
+   Inside group specifications, including inside contained suffix
+specifications, nothing has to be quoted and quoting anyway is invalid.
+The value following a keyword, can be explicitly unquoted using ‘,’.
+This feature is experimental and should be avoided.
+
+   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
+
+4.3.2 Suffix Specifications
+---------------------------
+
+A transient’s suffix and infix commands are bound when the transient
+prefix command is defined using ‘transient-define-prefix’, 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
+     takes zero or one arguments (the suffix object) and 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 should be a symbol that is bound as a function, which has
+     to be defined or at least autoloaded as a command by the time the
+     containing prefix command is invoked.
+
+     Any command will do; it does not need to have an object associated
+     with it (as would be the case if ‘transient-define-suffix’ or
+     ‘transient-define-infix’ were used to define it).
+
+     COMMAND can also be a ‘lambda’ expression.
+
+     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.
+
+     As a special case, if you want to add a command that might be
+     neither defined nor autoloaded, you can use a workaround like:
+
+          (transient-insert-suffix 'some-prefix "k"
+            '("!" "Ceci n'est pas une commande" no-command
+              :if (lambda () (featurep 'no-library))))
+
+     Instead of ‘featurep’ you could also use ‘require’ with a non-‘nil’
+     value for NOERROR.
+
+   • 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
+
+4.4 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: transient-define-suffix 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: transient-define-infix 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.
+
+     At least one key-value pair is required.  All transient infix
+     commands are ‘equal’ to each other (but not ‘eq’).  It is
+     meaningless to define an infix command, without providing at least
+     one keyword argument (usually ‘:argument’ or ‘:variable’, depending
+     on the class).  The suffix class defaults to ‘transient-switch’ and
+     can be set using the ‘:class’ keyword.
+
+     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-define-suffix’ to define the infix command
+     and use ‘t’ as the value of the ‘:transient’ keyword.
+
+ -- Macro: transient-define-argument name arglist [docstring] [keyword
+          value]...
+     This macro defines NAME as a transient infix command.
+
+     This is an alias for ‘transient-define-infix’.  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
+     ‘transient-define-infix’ instead.
+
+\1f
+File: transient.info,  Node: Using Infix Arguments,  Next: Current Suffix Command,  Prev: Defining Suffix and Infix Commands,  Up: Defining New Commands
+
+4.5 Using Infix Arguments
+=========================
+
+The functions 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’s 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 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.
+
+ -- Function: transient-get-value
+     This function returns the value of the current prefix.
+
+     This is mostly intended for internal use, but may also be of use in
+     ‘transient-set-value’ and ‘transient-save-value’ methods.  Unlike
+     ‘transient-args’, this does not include the values of suffixes
+     whose ‘unsavable’ slot is non-‘nil’.
+
+ -- Function: transient-arg-value arg args
+     This function returns the value of ARG as it appears in ARGS.
+
+     For a switch a boolean is returned.  For an option the value is
+     returned as a string, using the empty string for the empty value,
+     or ‘nil’ if the option does not appear in ARGS.
+
+ -- Function: transient-suffixes prefix
+     This function returns the suffixes of the transient prefix command
+     PREFIX.  This is a list of objects.  This function should only be
+     used if you need the objects (as opposed to just their values) and
+     if the current command is not being invoked from PREFIX.
+
+\1f
+File: transient.info,  Node: Current Suffix Command,  Next: Current Prefix Command,  Prev: Using Infix Arguments,  Up: Defining New Commands
+
+4.6 Current Suffix Command
+==========================
+
+ -- Function: transient-suffix-object command
+     This function returns 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, which are
+     usually aliases of ‘transient--default-infix-command’, which is
+     defined like this:
+
+          (defun transient--default-infix-command ()
+            (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’.)
+
+     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)
+
+ -- Variable: transient-current-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.
+
+\1f
+File: transient.info,  Node: Current Prefix Command,  Next: Transient State,  Prev: Current Suffix Command,  Up: Defining New Commands
+
+4.7 Current Prefix Command
+==========================
+
+ -- Function: transient-prefix-object
+     This function returns the current prefix as an object.
+
+     While a transient is being setup or refreshed (which involves
+     preparing its suffixes) the variable ‘transient--prefix’ can be
+     used to access the prefix object.  Thus this is what has to be used
+     in suffix methods such as ‘transient-format-description’, and in
+     object-specific functions that are stored in suffix slots such as
+     ‘description’.
+
+     When a suffix command is invoked (i.e., in its ‘interactive’ form
+     and function body) then the variable ‘transient-current-prefix’ has
+     to be used instead.
+
+     Two distinct variables are needed, because any prefix may itself be
+     used as a suffix of another prefix, and such sub-prefixes have to
+     be able to tell themselves apart from the prefix they were invoked
+     from.
+
+     Regular suffix commands, which are not prefixes, do not have to
+     concern themselves with this distinction, so they can use this
+     function instead.  In the context of a plain suffix, it always
+     returns the value of the appropriate variable.
+
+ -- Variable: transient-current-prefix
+     The transient from which this suffix command was invoked.  The
+     value is a ‘transient-prefix’ object, which holds information
+     associated with the transient prefix command.
+
+ -- Variable: transient-current-command
+     The transient from which this suffix command was invoked.  The
+     value is a symbol, the transient prefix command.
+
+ -- Function: transient-active-prefix &optional prefixes
+     This function returns the active transient object.  It returns
+     ‘nil’ if there is no active transient, if the transient buffer
+     isn’t shown, and while the active transient is suspended (e.g.,
+     while the minibuffer is in use).
+
+     Unlike ‘transient-current-prefix’, which is only ever non-‘nil’ in
+     code that is run directly by a command that is invoked while a
+     transient is current, this function is also suitable for use in
+     asynchronous code, such as timers and callbacks (this function’s
+     main use-case).
+
+     If optional PREFIXES is non-‘nil’, it must be a prefix command
+     symbol or a list of symbols, in which case the active transient
+     object is only returned if it matches one of the PREFIXES.
+
+\1f
+File: transient.info,  Node: Transient State,  Prev: Current Prefix Command,  Up: Defining New Commands
+
+4.8 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.
+
+   The behavior can be changed for all suffixes of a particular prefix
+and/or for individual suffixes.  The values should nearly always be
+booleans, but certain functions, called “pre-commands”, can also be
+used.  These functions are named ‘transient--do-VERB’, and the symbol
+‘VERB’ can be used as a shorthand.
+
+   A boolean is interpreted as answering the question "does the
+transient stay active, when this command is invoked?"  ‘t’ means that
+the transient stays active, while ‘nil’ means that invoking the command
+exits the transient.
+
+   Note that when the suffix is a “sub-prefix”, invoking that command
+always activates that sub-prefix, causing the outer prefix to no longer
+be active and displayed.  Here ‘t’ means that when you exit the inner
+prefix, then the outer prefix becomes active again, while ‘nil’ means
+that all outer prefixes are exited at once.
+
+   • The behavior for non-suffixes can be set for a particular prefix,
+     by the prefix’s ‘transient-non-suffix’ slot to a boolean, a
+     suitable pre-command function, or a shorthand for such a function.
+     See *note Pre-commands for Non-Suffixes::.
+
+   • The common behavior for the suffixes of a particular prefix can be
+     set using the prefix’s ‘transient-suffixes’ slot.
+
+     The value specified in this slot does *not* affect infixes.
+     Because it affects both regular suffixes as well as sub-prefixes,
+     which have different needs, it is best to avoid explicitly
+     specifying a function.
+
+   • The behavior of an individual suffix can be changed using its
+     ‘transient’ slot.  While it is usually best to use a boolean, for
+     this slot it can occasionally make sense to specify a function
+     explicitly.
+
+     Note that this slot can be set when defining a suffix command using
+     ‘transient-define-suffix’ and/or in the definition of the prefix.
+     If set in both places, then the latter takes precedence, as usual.
+
+   The available pre-command functions are documented in the following
+sub-sections.  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’.
+
+   For completeness sake, some notes about complications:
+
+   • 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 prefix’s ‘transient-suffix’ slot, but not
+     the suffix’s ‘transient’ slot.
+
+   • While a sub-prefix is active we nearly always want ‘C-g’ to take
+     the user back to the “super-prefix”, even when the other suffixes
+     don’t do that.  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 ‘nil’ and the slot being
+     unbound are treated as 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.
+
+Pre-commands for Infixes
+------------------------
+
+The default for infixes is ‘transient--do-stay’.  This is also the only
+function that makes sense for infixes, which is why this predicate is
+used even if the value of the prefix’s ‘transient-suffix’ slot is ‘t’.
+In extremely rare cases, one might want to use something else, which can
+be done by setting the infix’s ‘transient’ slot directly.
+
+ -- Function: transient--do-stay
+     Call the command without exporting variables and stay transient.
+
+Pre-commands for Suffixes
+-------------------------
+
+By default, invoking a suffix causes the transient to be exited.
+
+   The behavior for an individual suffix command can be changed by
+setting its ‘transient’ slot to a boolean (which is highly recommended),
+or to one of the following pre-commands.
+
+ -- Function: transient--do-exit
+     Call the command after exporting variables and exit the transient.
+
+ -- Function: transient--do-return
+     Call the command after exporting variables and return to the parent
+     prefix.  If there is no parent prefix, then call
+     ‘transient--do-exit’.
+
+ -- Function: transient--do-call
+     Call the command after exporting variables and stay transient.
+
+   The following pre-commands are only suitable for sub-prefixes.  It is
+not necessary to explicitly use these predicates because the correct
+predicate is automatically picked based on the value of the ‘transient’
+slot for the sub-prefix itself.
+
+ -- Function: transient--do-recurse
+     Call the transient prefix command, preparing for return to active
+     transient.
+
+     Whether we actually return to the parent transient is ultimately
+     under the control of each invoked suffix.  The difference between
+     this pre-command and ‘transient--do-stack’ is that it changes the
+     value of the ‘transient-suffix’ slot to ‘t’.
+
+     If there is no parent transient, then only call this command and
+     skip the second step.
+
+ -- Function: transient--do-stack
+     Call the transient prefix command, stacking the active transient.
+     Push the active transient to the transient stack.
+
+     Unless ‘transient--do-recurse’ is explicitly used, this pre-command
+     is automatically used for suffixes that are prefixes themselves,
+     i.e., for sub-prefixes.
+
+ -- Function: transient--do-replace
+     Call the transient prefix command, replacing the active transient.
+     Do not push the active transient to the transient stack.
+
+     Unless ‘transient--do-recurse’ is explicitly used, this pre-command
+     is automatically used for suffixes that are prefixes themselves,
+     i.e., for sub-prefixes.
+
+ -- Function: transient--do-suspend
+     Suspend the active transient, saving the transient stack.
+
+     This is used by the command ‘transient-suspend’ and optionally also
+     by “external events” such as ‘handle-switch-frame’.  Such bindings
+     should be added to ‘transient-predicate-map’.
+
+Pre-commands for Non-Suffixes
+-----------------------------
+
+By default, non-suffixes (commands that are bound in other keymaps
+beside the transient keymap) cannot be invoked.  Trying to invoke such a
+command results in a warning and the transient stays active.
+
+   If you want a different behavior, then set the ‘transient-non-suffix’
+slot of the transient prefix command.  The value should be a boolean,
+answering the question, "is it allowed to invoke non-suffix commands?, a
+pre-command function, or a shorthand for such a function.
+
+   If the value is ‘t’, then non-suffixes can be invoked, when it is
+‘nil’ (the default) then they cannot be invoked.
+
+   The only other recommended value is ‘leave’.  If that is used, then
+non-suffixes can be invoked, but if one is invoked, then that exits the
+transient.
+
+ -- Function: transient--do-warn
+     Call ‘transient-undefined’ and stay transient.
+
+ -- Function: transient--do-stay
+     Call the command without exporting variables and stay transient.
+
+ -- Function: transient--do-leave
+     Call the command without exporting variables and exit the
+     transient.
+
+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: FAQ,  Prev: Defining New Commands,  Up: Top
+
+5 Classes and Methods
+*********************
+
+Transient uses classes and generic functions to make it possible to
+define new types of suffix and prefix commands, which are similar to
+existing types, but behave differently in some respects.
+
+   Every prefix, infix and suffix command is associated with an object,
+which holds information, which 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::
+* Prefix Methods::
+* Suffix Methods::
+* Prefix Slots::
+* Suffix Slots::
+* Predicate Slots::
+
+\1f
+File: transient.info,  Node: Group Classes,  Next: Group Methods,  Up: Classes and Methods
+
+5.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 ‘transient-define-prefix’.
+
+   • 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 (or “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
+
+5.2 Group Methods
+=================
+
+ -- Function: transient-setup-children group children
+     This generic function can be used to setup the children or a group.
+
+     The default implementation usually just returns the children
+     unchanged, but if the ‘setup-children’ slot of GROUP is non-‘nil’,
+     then it calls that function with CHILDREN as the only argument and
+     returns the value.
+
+     The children are given as a (potentially empty) list consisting of
+     either group or suffix specifications.  These functions can make
+     arbitrary changes to the children including constructing new
+     children from scratch.
+
+ -- 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
+     temporarily make the ‘transient--shadowed-buffer’ the current
+     buffer.
+
+\1f
+File: transient.info,  Node: Prefix Classes,  Next: Suffix Classes,  Prev: Group Methods,  Up: Classes and Methods
+
+5.3 Prefix Classes
+==================
+
+Transient itself provides a single class for prefix commands,
+‘transient-prefix’, but package authors may wish to define specialized
+classes.  Doing so makes it possible to change the behavior of the set
+of prefix commands that use that class, by implementing specialized
+methods for certain generic functions (see *note Prefix Methods::).
+
+   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: Prefix Methods,  Prev: Prefix Classes,  Up: Classes and Methods
+
+5.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-variable’ class.
+
+   • The ‘transient-information’ and ‘transient-information*’ classes
+     are special in that suffixes that use these class are not
+     associated with a command and thus also not with any key binding.
+     Such suffixes are only used to display arbitrary information, and
+     that anywhere a suffix can appear.  Display-only suffix
+     specifications take these form:
+
+          ([LEVEL] :info DESCRIPTION [KEYWORD VALUE]...)
+          ([LEVEL] :info* DESCRIPTION [KEYWORD VALUE]...)
+
+     The ‘:info’ and ‘:info*’ keyword arguments replaces the
+     ‘:description’ keyword used for other suffix classes.  Other
+     keyword arguments that you might want to set, include ‘:face’,
+     predicate keywords (such as ‘:if’ and ‘:inapt-if’), and ‘:format’.
+     By default the value of ‘:format’ includes ‘%k’, which for this
+     class is replaced with the empty string or spaces, if keys are
+     being padded in the containing group.
+
+     The only difference between these two classes is that ‘:info*’
+     aligns its description with the descriptions of suffix commands,
+     while for ‘:info’ the description bleeds into the area where
+     suffixes display their key bindings.
+
+   • The ‘transient-lisp-variable’ class can be used to show and change
+     the value of lisp variables.  This class is not fully featured yet
+     and it is somewhat likely that future improvements won’t be fully
+     backward compatible.
+
+   • The ‘transient-describe-target’ class is used by the command
+     ‘transient-describe’.
+
+   • The ‘transient-value-preset’ class is used to implement the command
+     ‘transient-preset’, which activates a value preset.
+
+   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: Prefix Methods,  Next: Suffix Methods,  Prev: Suffix Classes,  Up: Classes and Methods
+
+5.5 Prefix Methods
+==================
+
+To get information about the methods implementing these generic
+functions use ‘describe-function’.
+
+ -- Function: transient-init-value obj
+     This generic function sets the initial value of the object OBJ.
+     Methods exist for both prefix and suffix objects.
+
+     The default method for prefix objects sets the value of OBJ’s
+     ‘value’ slot to the set, saved or default value.  The value that is
+     set for the current session is preferred over the saved value,
+     which is preferred over the default value.
+
+     The default value is determined using the generic function
+     ‘transient-default-value’.  If you need to change how the value for
+     a prefix class is determined, its usually sufficient to implement a
+     method for that function.
+
+ -- Function: transient-default-value obj
+     This generic function returns the default value of the object OBJ.
+     Methods exist for both prefix and suffix objects.
+
+     The default method for prefix objects returns the value of the
+     ‘default-value’ slot if that is bound and not a function.  If it is
+     a function, that is called to get the value.  If the slot is
+     unbound, ‘nil’ is returned.
+
+ -- Function: transient-prefix-value obj
+     This generic function returns the value of the prefix object OBJ.
+     The respective generic function for infix and suffix objects is
+     named ‘transient-infix-value’.
+
+ -- Function: transient-init-scope obj
+     This generic function sets the scope of the object OBJ.  Methods
+     exist for both prefix and suffix objects.
+
+     This function is called for all prefix and suffix commands, but
+     unless a concrete method is implemented this falls through to the
+     default implementation, which is a noop.
+
+   ‘transient-set-value’, ‘transient-save-value’,
+‘transient-reset-value’, ‘transient--history-key’,
+‘transient--history-push’ and ‘transient--history-init’ are other
+generic functions dealing with the value of prefix objects.  See their
+doc-strings for more information.
+
+   ‘transient-show-help’ is another generic function implemented for
+prefix commands.  The default method effectively describes the command
+using ‘describe-function’.
+
+\1f
+File: transient.info,  Node: Suffix Methods,  Next: Prefix Slots,  Prev: Prefix Methods,  Up: Classes and Methods
+
+5.6 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
+
+5.6.1 Suffix Value Methods
+--------------------------
+
+ -- Function: transient-init-value obj
+     This generic function sets the initial value of the object OBJ.
+     Methods exist for both prefix and suffix objects.
+
+     For ‘transient-argument’ objects this function handles setting the
+     value by itself.
+
+     For other ‘transient-suffix’ objects (including ‘transient-infix’
+     objects), this calls ‘transient-default-value’ and uses the value
+     returned by that, unless it is the special value ‘eieio--unbound’,
+     which indicates that there is no default value.  Since that is what
+     the default method for ‘transient-suffix’ objects does, both of
+     these functions effectively are noops for these classes.
+
+     If you implement a class that derives from ‘transient-infix’
+     directly, then you must implement a dedicated method for this
+     function and/or ‘transient-default-value’.
+
+ -- Function: transient-default-value obj
+     This generic function returns the default value of the object OBJ.
+     Methods exist for both prefix and suffix objects.
+
+ -- 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 object OBJ.  Methods
+     exist for both prefix and suffix objects.
+
+     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 prefix and 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
+
+5.6.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.
+
+     Regardless of OBJ’s type, if its ‘show-help’ slot is non-‘nil’,
+     that must be a function, which takes OBJ is its only argument.  It
+     must prepare, display and return a buffer, and select the window
+     used to display it.  The ‘transient-show-help-window’ macro is
+     intended for use in such functions.
+
+     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
+     documentation string.
+
+     For suffixes, show the command’s documentation string.
+
+     For infixes, show the manpage if that is specified.  Otherwise show
+     the command’s documentation string.
+
+ -- Macro: transient-with-help-window &rest body
+     Evaluate BODY, send output to ‘*Help*’ buffer, and display it in a
+     window.  Select the help window, and make the help buffer current
+     and return it.
+
+ -- Function: transient-show-summary obj &optional return
+     This generic function shows or, if optional RETURN is non-‘nil’,
+     returns a brief summary about the command at point or hovered with
+     the mouse.
+
+     This function is called when the mouse is moved over a command and
+     (if the value of ‘transient-enable-popup-navigation’ is ‘verbose’)
+     when the user navigates to a command using the keyboard.
+
+     If OBJ’s ‘summary’ slot is a string, that is used.  If ‘summary’ is
+     a function, that is called with OBJ as the only argument and the
+     returned string is used.  If ‘summary’ is or returns something
+     other than a string or ‘nil’, no summary is shown.  If ‘summary’ is
+     or returns ‘nil’, the first line of the documentation string is
+     used, if any.
+
+     If RETURN is non-‘nil’, this function returns the summary instead
+     of showing it.  This is used when a tooltip is needed.
+
+\1f
+File: transient.info,  Node: Prefix Slots,  Next: Suffix Slots,  Prev: Suffix Methods,  Up: Classes and Methods
+
+5.7 Prefix Slots
+================
+
+Value and Scope
+---------------
+
+   • ‘default-value’ The default value of the prefix.  Use the keyword
+     argument ‘:value’ (sic) to set this slot in the definition of a
+     prefix.
+
+   • ‘init-value’ A function that is responsible for setting the
+     object’s value.  If bound, then this is called with the object as
+     the only argument.  Usually this is not bound, in which case the
+     object’s primary ‘transient-init-value’ method is called instead.
+
+   • ‘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.
+
+   • ‘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.  An argument may appear in
+     multiple sub-lists.  Arguments must me given in the same form as
+     used in the ‘argument’ or ‘argument-format’ slot of the respective
+     suffix objects, usually something like ‘--switch’ or ‘--option=%s’.
+     For options and ‘transient-switches’ suffixes it is also possible
+     to match against a specific value, as returned by
+     ‘transient-infix-value’, for example, ‘--option=one’.
+
+   • ‘scope’ For some transients it might be necessary to have a sort of
+     secondary value, called a “scope”.  See ‘transient-define-prefix’.
+
+Behavior
+--------
+
+   • ‘transient-suffix’, ‘transient-non-suffix’ and
+     ‘transient-switch-frame’ play a part when determining whether the
+     currently active transient prefix command remains active/transient
+     when a suffix or arbitrary non-suffix command is invoked.  See
+     *note Transient State::.
+
+   • ‘refresh-suffixes’ Normally suffix objects and keymaps are only
+     setup once, when the prefix is invoked.  Setting this to ‘t’,
+     causes them to be recreated after every command.  This is useful
+     when using ‘:if...’ predicates, and those need to be rerun for some
+     reason.  Doing this is somewhat costly, and there is a risk of
+     losing state, so this is disabled by default and still considered
+     experimental.
+
+   • ‘environment’ A function used to establish an environment while
+     initializing, refreshing or redisplaying a transient prefix menu.
+     This is useful to establish a cache, in case multiple suffixes
+     require the same expensive work.  The provided function is called
+     with at least one argument, the function for which it establishes
+     the environment.  It must ‘funcall’ that function with no
+     arguments.  During initialization the second argument is the prefix
+     object being initialized.  This slot is still experimental.
+
+Appearance
+----------
+
+   • ‘display-action’ determines how this prefix is displayed,
+     overriding ‘transient-display-buffer-action’.  It should have the
+     same type.
+
+   • ‘mode-line-format’ is this prefix’s mode line format, overriding
+     ‘transient-mode-line-format’.  It should have the same type.
+
+   • ‘column-width’ is only respected inside ‘transient-columns’ groups
+     and allows aligning columns across separate instances of that.
+
+   • ‘variable-pitch’ controls whether alignment is done pixel-wise to
+     account for use of variable-pitch characters, which is useful,
+     e.g., when using emoji.
+
+Documentation
+-------------
+
+   • ‘show-help’, ‘man-page’ or ‘info-manual’ can be used to specify the
+     documentation for the prefix and its suffixes.  The command
+     ‘transient-help’ uses the function ‘transient-show-help’ (which
+     see) to lookup and use these values.
+
+   • ‘suffix-description’ can be used to specify a function which
+     provides fallback descriptions for suffixes that lack a
+     description.  This is intended to be temporarily used when
+     implementing of a new prefix command, at which time
+     ‘transient-command-summary-or-name’ is a useful value.
+
+Internal
+--------
+
+These slots are mostly intended for internal use.  They should not be
+set in calls to ‘transient-define-prefix’.
+
+   • ‘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.
+
+   • ‘unwind-suffix’ is used internally to ensure transient state is
+     properly exited, even in case of an error.
+
+\1f
+File: transient.info,  Node: Suffix Slots,  Next: Predicate Slots,  Prev: Prefix Slots,  Up: Classes and Methods
+
+5.8 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::.
+
+Slots of ‘transient-child’
+--------------------------
+
+This is the abstract superclass of ‘transient-suffix’ and
+‘transient-group’.  This is where the shared ‘if*’ and ‘inapt-if*’ slots
+(see *note Predicate Slots::) and the ‘level’ slot (see *note Enabling
+and Disabling Suffixes::) are defined.
+
+   • ‘parent’ The object for the parent group.
+
+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, which
+     is called with zero or one argument (the suffix object), and
+     returns a string.
+
+   • ‘face’ Face used for the description.  In simple cases it is easier
+     to use this instead of using a function as ‘description’ and adding
+     the styling there.  ‘face’ is appended using
+     ‘add-face-text-property’.
+
+   • ‘show-help’ A function used to display help for the suffix.  If
+     unspecified, the prefix controls how help is displayed for its
+     suffixes.  See also function ‘transient-show-help’.
+
+   • ‘summary’ The summary displayed in the echo area, or as a tooltip.
+     If this is ‘nil’, which it usually should be, the first line of the
+     documentation string is used instead.  See ‘transient-show-summary’
+     for details.
+
+   • ‘definition’ A command, which is used if the body is omitted when
+     defining a command using ‘transient-define-suffix’.
+
+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’.
+
+   • ‘value’ The value.  Should not be accessed directly.
+
+   • ‘init-value’ Function that is responsible for setting the object’s
+     value.  If bound, then this is called with the object as the only
+     argument.  Usually this is not bound, in which case the object’s
+     primary ‘transient-init-value’ method is called instead.
+
+   • ‘unsavable’ Whether the value of the suffix is not saved as part of
+     the prefixes.
+
+   • ‘multi-value’ For options, whether the option can have multiple
+     values.  If this is non-‘nil’, then the values are read using
+     ‘completing-read-multiple’ by default and if you specify your own
+     reader, then it should read the values using that function or
+     similar.
+
+     Supported non-‘nil’ values are:
+
+        • Use ‘rest’ for an option that can have multiple values.  This
+          is useful e.g., for an ‘--’ argument that indicates that all
+          remaining arguments are files (such as ‘git log -- file1
+          file2’).
+
+          In the list returned by ‘transient-args’ such an option and
+          its values are represented by a single list of the form
+          ‘(ARGUMENT . VALUES)’.
+
+        • Use ‘repeat’ for an option that can be specified multiple
+          times.
+
+          In the list returned by ‘transient-args’ each instance of the
+          option and its value appears separately in the usual from, for
+          example: ‘("--another-argument" "--option=first"
+          "--option=second")’.
+
+     In both cases the option’s values have to be specified in the
+     default value of a prefix using the same format as returned by
+     ‘transient-args’, e.g., ‘("--other" "--o=1" "--o=2" ("--" "f1"
+     "f2"))’.
+
+   • ‘always-read’ For options, whether to read a value on every
+     invocation.  If this is ‘nil’, then options that have a value are
+     simply unset and have to be invoked a second time to set a new
+     value.
+
+   • ‘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, or a function that returns such a
+     list.  The latter is not implemented for ‘transient-switches’,
+     because I couldn’t think of a use-case.  How exactly the choices
+     are used varies depending on the class of the suffix.
+
+Slots of ‘transient-variable’
+-----------------------------
+
+   • ‘variable’ The variable.
+
+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
+
+5.9 Predicate Slots
+===================
+
+Suffix and group objects share two sets of predicate slots that control
+whether a group or suffix should be available depending on some state.
+Only one slot from each set can be used at the same time.  It is
+undefined which slot is honored if you use more than one.
+
+   Predicates from the first group control whether the suffix is present
+in the menu at all.
+
+   • ‘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.
+
+   Predicates from the second group control whether the suffix can be
+invoked.  The suffix is shown in the menu regardless, but when it is
+considered "inapt", then it is grayed out to indicated that it currently
+cannot be invoked.
+
+   • ‘inapt-if’ Inapt if predicate returns non-‘nil’.
+   • ‘inapt-if-not’ Inapt if predicate returns ‘nil’.
+   • ‘inapt-if-non-nil’ Inapt if variable’s value is non-‘nil’.
+   • ‘inapt-if-nil’ Inapt if variable’s value is ‘nil’.
+   • ‘inapt-if-mode’ Inapt if major-mode matches value.
+   • ‘inapt-if-not-mode’ Inapt if major-mode does not match value.
+   • ‘inapt-if-derived’ Inapt if major-mode derives from value.
+   • ‘inapt-if-not-derived’ Inapt if major-mode does not derive from
+     value.
+
+   By default these predicates run when the prefix command is invoked,
+but this can be changes, using the ‘refresh-suffixes’ prefix slot.  See
+*note Prefix Slots::.
+
+   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: FAQ,  Next: Keystroke Index,  Prev: Classes and Methods,  Up: Top
+
+Appendix A FAQ
+**************
+
+A.1 Can I control how the popup buffer is displayed?
+====================================================
+
+Yes, see ‘transient-display-buffer-action’ in *note Configuration::.
+You can also control how the popup buffer is displayed on a case-by-case
+basis by passing ‘:display-action’ to ‘transient-define-prefix’.
+
+A.2 How can I copy text from the popup buffer?
+==============================================
+
+To be able to mark text in Transient’s popup buffer using the mouse, you
+have to add the below binding.  Note that for technical reasons, the
+region won’t be visualized, while doing so.  After you have quit the
+transient popup, you will be able to yank it in another buffer.
+
+     (keymap-set transient-predicate-map
+                 "<mouse-set-region>"
+                 #'transient--do-stay)
+
+A.3 How can I autoload prefix and suffix commands?
+==================================================
+
+If your package only supports Emacs 30, just prefix the definition with
+‘;;;###autoload’.  If your package supports released versions of Emacs,
+you unfortunately have to use a long form autoload comment as described
+in *note (elisp)Autoload::.
+
+     ;;;###autoload (autoload 'magit-dispatch "magit" nil t)
+     (transient-define-prefix magit-dispatch ()
+       ...)
+
+A.4 How does Transient compare to prefix keys and universal arguments?
+======================================================================
+
+See
+<https://github.com/magit/transient/wiki/Comparison-with-prefix-keys-and-universal-arguments>.
+
+A.5 How does Transient compare to Magit-Popup and Hydra?
+========================================================
+
+See
+<https://github.com/magit/transient/wiki/Comparison-with-other-packages>.
+
+A.6 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 bindings that begin with the ‘C-x’ prefix 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.
+
+   (See also the next question.)
+
+A.7 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 documentation string for more information.
+
+\1f
+File: transient.info,  Node: Keystroke Index,  Next: Command and Function Index,  Prev: FAQ,  Up: Top
+
+Appendix B Keystroke Index
+**************************
+
+\0\b[index\0\b]
+* Menu:
+
+* C-g:                                   Aborting and Resuming Transients.
+                                                               (line 27)
+* C-g <1>:                               Aborting and Resuming Transients.
+                                                               (line 27)
+* C-h:                                   Getting Help for Suffix Commands.
+                                                               (line 11)
+* C-M-n:                                 Using History.        (line 18)
+* C-M-p:                                 Using History.        (line 13)
+* C-q:                                   Aborting and Resuming Transients.
+                                                               (line 36)
+* C-x a:                                 Enabling and Disabling Suffixes.
+                                                               (line 68)
+* C-x C-k:                               Saving Values.        (line 29)
+* C-x C-s:                               Saving Values.        (line 25)
+* C-x l:                                 Enabling and Disabling Suffixes.
+                                                               (line 43)
+* C-x n:                                 Using History.        (line 18)
+* C-x p:                                 Using History.        (line 13)
+* C-x s:                                 Saving Values.        (line 21)
+* C-x t:                                 Common Suffix Commands.
+                                                               (line 18)
+* C-z:                                   Aborting and Resuming Transients.
+                                                               (line 41)
+
+\1f
+File: transient.info,  Node: Command and Function Index,  Next: Variable Index,  Prev: Keystroke Index,  Up: Top
+
+Appendix C Command and Function Index
+*************************************
+
+\0\b[index\0\b]
+* Menu:
+
+* transient--do-call:                    Transient State.     (line 125)
+* transient--do-exit:                    Transient State.     (line 117)
+* transient--do-leave:                   Transient State.     (line 193)
+* transient--do-quit-all:                Transient State.     (line 205)
+* transient--do-quit-one:                Transient State.     (line 200)
+* transient--do-recurse:                 Transient State.     (line 133)
+* transient--do-replace:                 Transient State.     (line 153)
+* transient--do-return:                  Transient State.     (line 120)
+* transient--do-stack:                   Transient State.     (line 145)
+* transient--do-stay:                    Transient State.     (line 105)
+* transient--do-stay <1>:                Transient State.     (line 190)
+* transient--do-suspend:                 Transient State.     (line 161)
+* transient--do-suspend <1>:             Transient State.     (line 210)
+* transient--do-warn:                    Transient State.     (line 187)
+* transient--insert-group:               Group Methods.       (line  19)
+* transient-active-prefix:               Current Prefix Command.
+                                                              (line  39)
+* transient-append-suffix:               Modifying Existing Transients.
+                                                              (line  51)
+* transient-arg-value:                   Using Infix Arguments.
+                                                              (line  39)
+* transient-args:                        Using Infix Arguments.
+                                                              (line  22)
+* transient-copy-menu-text:              Other Commands.      (line  25)
+* transient-default-value:               Prefix Methods.      (line  23)
+* transient-default-value <1>:           Suffix Value Methods.
+                                                              (line  24)
+* transient-define-argument:             Defining Suffix and Infix Commands.
+                                                              (line  57)
+* transient-define-infix:                Defining Suffix and Infix Commands.
+                                                              (line  26)
+* transient-define-prefix:               Defining Transients. (line  13)
+* transient-define-suffix:               Defining Suffix and Infix Commands.
+                                                              (line   9)
+* transient-format:                      Suffix Format Methods.
+                                                              (line   6)
+* transient-format-description:          Suffix Format Methods.
+                                                              (line  18)
+* transient-format-key:                  Suffix Format Methods.
+                                                              (line  14)
+* transient-format-value:                Suffix Format Methods.
+                                                              (line  22)
+* transient-get-suffix:                  Modifying Existing Transients.
+                                                              (line  73)
+* transient-get-value:                   Using Infix Arguments.
+                                                              (line  31)
+* transient-help:                        Getting Help for Suffix Commands.
+                                                              (line  11)
+* transient-history-next:                Using History.       (line  18)
+* transient-history-prev:                Using History.       (line  13)
+* transient-infix-read:                  Suffix Value Methods.
+                                                              (line  28)
+* transient-infix-set:                   Suffix Value Methods.
+                                                              (line  48)
+* transient-infix-value:                 Suffix Value Methods.
+                                                              (line  51)
+* transient-init-scope:                  Prefix Methods.      (line  37)
+* transient-init-scope <1>:              Suffix Value Methods.
+                                                              (line  64)
+* transient-init-value:                  Prefix Methods.      (line   9)
+* transient-init-value <1>:              Suffix Value Methods.
+                                                              (line   6)
+* transient-insert-suffix:               Modifying Existing Transients.
+                                                              (line  49)
+* transient-prefix-object:               Current Prefix Command.
+                                                              (line   6)
+* transient-prefix-value:                Prefix Methods.      (line  32)
+* transient-prompt:                      Suffix Value Methods.
+                                                              (line  44)
+* transient-quit-all:                    Aborting and Resuming Transients.
+                                                              (line  36)
+* transient-quit-one:                    Aborting and Resuming Transients.
+                                                              (line  27)
+* transient-quit-seq:                    Aborting and Resuming Transients.
+                                                              (line  27)
+* transient-remove-suffix:               Modifying Existing Transients.
+                                                              (line  70)
+* transient-replace-suffix:              Modifying Existing Transients.
+                                                              (line  66)
+* transient-reset:                       Saving Values.       (line  29)
+* transient-resume:                      Aborting and Resuming Transients.
+                                                              (line  53)
+* transient-save:                        Saving Values.       (line  25)
+* transient-scroll-down:                 Other Commands.      (line  17)
+* transient-scroll-up:                   Other Commands.      (line  12)
+* transient-set:                         Saving Values.       (line  21)
+* transient-set-level:                   Enabling and Disabling Suffixes.
+                                                              (line  43)
+* transient-setup-children:              Group Methods.       (line   6)
+* transient-show-help:                   Suffix Format Methods.
+                                                              (line  26)
+* transient-show-summary:                Suffix Format Methods.
+                                                              (line  51)
+* transient-suffix-object:               Current Suffix Command.
+                                                              (line   6)
+* transient-suffix-put:                  Modifying Existing Transients.
+                                                              (line  77)
+* transient-suffixes:                    Using Infix Arguments.
+                                                              (line  46)
+* transient-suspend:                     Aborting and Resuming Transients.
+                                                              (line  41)
+* transient-toggle-common:               Common Suffix Commands.
+                                                              (line  18)
+* transient-toggle-docstrings:           Other Commands.      (line  29)
+* transient-toggle-level-limit:          Enabling and Disabling Suffixes.
+                                                              (line  68)
+* transient-with-help-window:            Suffix Format Methods.
+                                                              (line  46)
+
+\1f
+File: transient.info,  Node: Variable Index,  Next: Concept Index,  Prev: Command and Function Index,  Up: Top
+
+Appendix D Variable Index
+*************************
+
+\0\b[index\0\b]
+* Menu:
+
+* transient-align-variable-pitch:        Configuration.       (line 239)
+* transient-current-command:             Current Prefix Command.
+                                                              (line  35)
+* transient-current-prefix:              Current Prefix Command.
+                                                              (line  30)
+* transient-current-suffixes:            Current Suffix Command.
+                                                              (line  45)
+* transient-default-level:               Enabling and Disabling Suffixes.
+                                                              (line  33)
+* transient-detect-key-conflicts:        Configuration.       (line 264)
+* transient-display-buffer-action:       Configuration.       (line 112)
+* transient-enable-popup-navigation:     Configuration.       (line  90)
+* transient-exit-hook:                   Configuration.       (line 290)
+* transient-force-fixed-pitch:           Configuration.       (line 252)
+* transient-force-single-column:         Configuration.       (line 155)
+* transient-highlight-higher-levels:     Configuration.       (line 277)
+* transient-highlight-mismatched-keys:   Configuration.       (line 200)
+* transient-history-file:                Using History.       (line  37)
+* transient-history-limit:               Using History.       (line  41)
+* transient-levels-file:                 Enabling and Disabling Suffixes.
+                                                              (line  38)
+* transient-mode-line-format:            Configuration.       (line 164)
+* transient-read-with-initial-input:     Configuration.       (line  83)
+* transient-save-history:                Using History.       (line  33)
+* transient-semantic-coloring:           Configuration.       (line 191)
+* transient-setup-buffer-hook:           Configuration.       (line 293)
+* transient-show-common-commands:        Common Suffix Commands.
+                                                              (line  23)
+* transient-show-common-commands <1>:    Configuration.       (line  36)
+* transient-show-during-minibuffer-read: Configuration.       (line  46)
+* transient-show-popup:                  Configuration.       (line  15)
+* transient-substitute-key-function:     Configuration.       (line 218)
+* transient-values-file:                 Saving Values.       (line  32)
+
+\1f
+File: transient.info,  Node: Concept Index,  Next: GNU General Public License,  Prev: Variable Index,  Up: Top
+
+Appendix E Concept Index
+************************
+
+\0\b[index\0\b]
+* Menu:
+
+* aborting transients:                   Aborting and Resuming Transients.
+                                                               (line  6)
+* classes and methods:                   Classes and Methods.  (line  6)
+* command dispatchers:                   Technical Introduction.
+                                                               (line 39)
+* common suffix commands:                Common Suffix Commands.
+                                                               (line  6)
+* defining infix commands:               Defining Suffix and Infix Commands.
+                                                               (line  6)
+* defining suffix commands:              Defining Suffix and Infix Commands.
+                                                               (line  6)
+* disabling suffixes:                    Enabling and Disabling Suffixes.
+                                                               (line  6)
+* enabling suffixes:                     Enabling and Disabling Suffixes.
+                                                               (line  6)
+* getting help:                          Getting Help for Suffix Commands.
+                                                               (line  6)
+* group specifications:                  Group Specifications. (line  6)
+* invoking transients:                   Invoking Transients.  (line  6)
+* levels:                                Enabling and Disabling Suffixes.
+                                                               (line 10)
+* modifying existing transients:         Modifying Existing Transients.
+                                                               (line  6)
+* quit transient:                        Aborting and Resuming Transients.
+                                                               (line  6)
+* resuming transients:                   Aborting and Resuming Transients.
+                                                               (line  6)
+* saving values of arguments:            Saving Values.        (line  6)
+* scope of a transient:                  Defining Transients.  (line 43)
+* suffix specifications:                 Suffix Specifications.
+                                                               (line  6)
+* transient state:                       Transient State.      (line  6)
+* transient-level:                       Enabling and Disabling Suffixes.
+                                                               (line 15)
+* value history:                         Using History.        (line  6)
+
+\1f
+File: transient.info,  Node: GNU General Public License,  Prev: Concept Index,  Up: Top
+
+Appendix F GNU General Public License
+*************************************
+
+                        Version 3, 29 June 2007
+
+     Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
+
+     Everyone is permitted to copy and distribute verbatim copies of this
+     license document, but changing it is not allowed.
+
+Preamble
+========
+
+The GNU General Public License is a free, copyleft license for software
+and other kinds of works.
+
+   The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program—to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+   When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+   To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+   For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+   Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+   For the developers’ and authors’ protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users’ and
+authors’ sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+   Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users’ freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+   Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+   The precise terms and conditions for copying, distribution and
+modification follow.
+
+TERMS AND CONDITIONS
+====================
+
+  0. Definitions.
+
+     “This License” refers to version 3 of the GNU General Public
+     License.
+
+     “Copyright” also means copyright-like laws that apply to other
+     kinds of works, such as semiconductor masks.
+
+     “The Program” refers to any copyrightable work licensed under this
+     License.  Each licensee is addressed as “you”.  “Licensees” and
+     “recipients” may be individuals or organizations.
+
+     To “modify” a work means to copy from or adapt all or part of the
+     work in a fashion requiring copyright permission, other than the
+     making of an exact copy.  The resulting work is called a “modified
+     version” of the earlier work or a work “based on” the earlier work.
+
+     A “covered work” means either the unmodified Program or a work
+     based on the Program.
+
+     To “propagate” a work means to do anything with it that, without
+     permission, would make you directly or secondarily liable for
+     infringement under applicable copyright law, except executing it on
+     a computer or modifying a private copy.  Propagation includes
+     copying, distribution (with or without modification), making
+     available to the public, and in some countries other activities as
+     well.
+
+     To “convey” a work means any kind of propagation that enables other
+     parties to make or receive copies.  Mere interaction with a user
+     through a computer network, with no transfer of a copy, is not
+     conveying.
+
+     An interactive user interface displays “Appropriate Legal Notices”
+     to the extent that it includes a convenient and prominently visible
+     feature that (1) displays an appropriate copyright notice, and (2)
+     tells the user that there is no warranty for the work (except to
+     the extent that warranties are provided), that licensees may convey
+     the work under this License, and how to view a copy of this
+     License.  If the interface presents a list of user commands or
+     options, such as a menu, a prominent item in the list meets this
+     criterion.
+
+  1. Source Code.
+
+     The “source code” for a work means the preferred form of the work
+     for making modifications to it.  “Object code” means any non-source
+     form of a work.
+
+     A “Standard Interface” means an interface that either is an
+     official standard defined by a recognized standards body, or, in
+     the case of interfaces specified for a particular programming
+     language, one that is widely used among developers working in that
+     language.
+
+     The “System Libraries” of an executable work include anything,
+     other than the work as a whole, that (a) is included in the normal
+     form of packaging a Major Component, but which is not part of that
+     Major Component, and (b) serves only to enable use of the work with
+     that Major Component, or to implement a Standard Interface for
+     which an implementation is available to the public in source code
+     form.  A “Major Component”, in this context, means a major
+     essential component (kernel, window system, and so on) of the
+     specific operating system (if any) on which the executable work
+     runs, or a compiler used to produce the work, or an object code
+     interpreter used to run it.
+
+     The “Corresponding Source” for a work in object code form means all
+     the source code needed to generate, install, and (for an executable
+     work) run the object code and to modify the work, including scripts
+     to control those activities.  However, it does not include the
+     work’s System Libraries, or general-purpose tools or generally
+     available free programs which are used unmodified in performing
+     those activities but which are not part of the work.  For example,
+     Corresponding Source includes interface definition files associated
+     with source files for the work, and the source code for shared
+     libraries and dynamically linked subprograms that the work is
+     specifically designed to require, such as by intimate data
+     communication or control flow between those subprograms and other
+     parts of the work.
+
+     The Corresponding Source need not include anything that users can
+     regenerate automatically from other parts of the Corresponding
+     Source.
+
+     The Corresponding Source for a work in source code form is that
+     same work.
+
+  2. Basic Permissions.
+
+     All rights granted under this License are granted for the term of
+     copyright on the Program, and are irrevocable provided the stated
+     conditions are met.  This License explicitly affirms your unlimited
+     permission to run the unmodified Program.  The output from running
+     a covered work is covered by this License only if the output, given
+     its content, constitutes a covered work.  This License acknowledges
+     your rights of fair use or other equivalent, as provided by
+     copyright law.
+
+     You may make, run and propagate covered works that you do not
+     convey, without conditions so long as your license otherwise
+     remains in force.  You may convey covered works to others for the
+     sole purpose of having them make modifications exclusively for you,
+     or provide you with facilities for running those works, provided
+     that you comply with the terms of this License in conveying all
+     material for which you do not control copyright.  Those thus making
+     or running the covered works for you must do so exclusively on your
+     behalf, under your direction and control, on terms that prohibit
+     them from making any copies of your copyrighted material outside
+     their relationship with you.
+
+     Conveying under any other circumstances is permitted solely under
+     the conditions stated below.  Sublicensing is not allowed; section
+     10 makes it unnecessary.
+
+  3. Protecting Users’ Legal Rights From Anti-Circumvention Law.
+
+     No covered work shall be deemed part of an effective technological
+     measure under any applicable law fulfilling obligations under
+     article 11 of the WIPO copyright treaty adopted on 20 December
+     1996, or similar laws prohibiting or restricting circumvention of
+     such measures.
+
+     When you convey a covered work, you waive any legal power to forbid
+     circumvention of technological measures to the extent such
+     circumvention is effected by exercising rights under this License
+     with respect to the covered work, and you disclaim any intention to
+     limit operation or modification of the work as a means of
+     enforcing, against the work’s users, your or third parties’ legal
+     rights to forbid circumvention of technological measures.
+
+  4. Conveying Verbatim Copies.
+
+     You may convey verbatim copies of the Program’s source code as you
+     receive it, in any medium, provided that you conspicuously and
+     appropriately publish on each copy an appropriate copyright notice;
+     keep intact all notices stating that this License and any
+     non-permissive terms added in accord with section 7 apply to the
+     code; keep intact all notices of the absence of any warranty; and
+     give all recipients a copy of this License along with the Program.
+
+     You may charge any price or no price for each copy that you convey,
+     and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+     You may convey a work based on the Program, or the modifications to
+     produce it from the Program, in the form of source code under the
+     terms of section 4, provided that you also meet all of these
+     conditions:
+
+       a. The work must carry prominent notices stating that you
+          modified it, and giving a relevant date.
+
+       b. The work must carry prominent notices stating that it is
+          released under this License and any conditions added under
+          section 7.  This requirement modifies the requirement in
+          section 4 to “keep intact all notices”.
+
+       c. You must license the entire work, as a whole, under this
+          License to anyone who comes into possession of a copy.  This
+          License will therefore apply, along with any applicable
+          section 7 additional terms, to the whole of the work, and all
+          its parts, regardless of how they are packaged.  This License
+          gives no permission to license the work in any other way, but
+          it does not invalidate such permission if you have separately
+          received it.
+
+       d. If the work has interactive user interfaces, each must display
+          Appropriate Legal Notices; however, if the Program has
+          interactive interfaces that do not display Appropriate Legal
+          Notices, your work need not make them do so.
+
+     A compilation of a covered work with other separate and independent
+     works, which are not by their nature extensions of the covered
+     work, and which are not combined with it such as to form a larger
+     program, in or on a volume of a storage or distribution medium, is
+     called an “aggregate” if the compilation and its resulting
+     copyright are not used to limit the access or legal rights of the
+     compilation’s users beyond what the individual works permit.
+     Inclusion of a covered work in an aggregate does not cause this
+     License to apply to the other parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+     You may convey a covered work in object code form under the terms
+     of sections 4 and 5, provided that you also convey the
+     machine-readable Corresponding Source under the terms of this
+     License, in one of these ways:
+
+       a. Convey the object code in, or embodied in, a physical product
+          (including a physical distribution medium), accompanied by the
+          Corresponding Source fixed on a durable physical medium
+          customarily used for software interchange.
+
+       b. Convey the object code in, or embodied in, a physical product
+          (including a physical distribution medium), accompanied by a
+          written offer, valid for at least three years and valid for as
+          long as you offer spare parts or customer support for that
+          product model, to give anyone who possesses the object code
+          either (1) a copy of the Corresponding Source for all the
+          software in the product that is covered by this License, on a
+          durable physical medium customarily used for software
+          interchange, for a price no more than your reasonable cost of
+          physically performing this conveying of source, or (2) access
+          to copy the Corresponding Source from a network server at no
+          charge.
+
+       c. Convey individual copies of the object code with a copy of the
+          written offer to provide the Corresponding Source.  This
+          alternative is allowed only occasionally and noncommercially,
+          and only if you received the object code with such an offer,
+          in accord with subsection 6b.
+
+       d. Convey the object code by offering access from a designated
+          place (gratis or for a charge), and offer equivalent access to
+          the Corresponding Source in the same way through the same
+          place at no further charge.  You need not require recipients
+          to copy the Corresponding Source along with the object code.
+          If the place to copy the object code is a network server, the
+          Corresponding Source may be on a different server (operated by
+          you or a third party) that supports equivalent copying
+          facilities, provided you maintain clear directions next to the
+          object code saying where to find the Corresponding Source.
+          Regardless of what server hosts the Corresponding Source, you
+          remain obligated to ensure that it is available for as long as
+          needed to satisfy these requirements.
+
+       e. Convey the object code using peer-to-peer transmission,
+          provided you inform other peers where the object code and
+          Corresponding Source of the work are being offered to the
+          general public at no charge under subsection 6d.
+
+     A separable portion of the object code, whose source code is
+     excluded from the Corresponding Source as a System Library, need
+     not be included in conveying the object code work.
+
+     A “User Product” is either (1) a “consumer product”, which means
+     any tangible personal property which is normally used for personal,
+     family, or household purposes, or (2) anything designed or sold for
+     incorporation into a dwelling.  In determining whether a product is
+     a consumer product, doubtful cases shall be resolved in favor of
+     coverage.  For a particular product received by a particular user,
+     “normally used” refers to a typical or common use of that class of
+     product, regardless of the status of the particular user or of the
+     way in which the particular user actually uses, or expects or is
+     expected to use, the product.  A product is a consumer product
+     regardless of whether the product has substantial commercial,
+     industrial or non-consumer uses, unless such uses represent the
+     only significant mode of use of the product.
+
+     “Installation Information” for a User Product means any methods,
+     procedures, authorization keys, or other information required to
+     install and execute modified versions of a covered work in that
+     User Product from a modified version of its Corresponding Source.
+     The information must suffice to ensure that the continued
+     functioning of the modified object code is in no case prevented or
+     interfered with solely because modification has been made.
+
+     If you convey an object code work under this section in, or with,
+     or specifically for use in, a User Product, and the conveying
+     occurs as part of a transaction in which the right of possession
+     and use of the User Product is transferred to the recipient in
+     perpetuity or for a fixed term (regardless of how the transaction
+     is characterized), the Corresponding Source conveyed under this
+     section must be accompanied by the Installation Information.  But
+     this requirement does not apply if neither you nor any third party
+     retains the ability to install modified object code on the User
+     Product (for example, the work has been installed in ROM).
+
+     The requirement to provide Installation Information does not
+     include a requirement to continue to provide support service,
+     warranty, or updates for a work that has been modified or installed
+     by the recipient, or for the User Product in which it has been
+     modified or installed.  Access to a network may be denied when the
+     modification itself materially and adversely affects the operation
+     of the network or violates the rules and protocols for
+     communication across the network.
+
+     Corresponding Source conveyed, and Installation Information
+     provided, in accord with this section must be in a format that is
+     publicly documented (and with an implementation available to the
+     public in source code form), and must require no special password
+     or key for unpacking, reading or copying.
+
+  7. Additional Terms.
+
+     “Additional permissions” are terms that supplement the terms of
+     this License by making exceptions from one or more of its
+     conditions.  Additional permissions that are applicable to the
+     entire Program shall be treated as though they were included in
+     this License, to the extent that they are valid under applicable
+     law.  If additional permissions apply only to part of the Program,
+     that part may be used separately under those permissions, but the
+     entire Program remains governed by this License without regard to
+     the additional permissions.
+
+     When you convey a copy of a covered work, you may at your option
+     remove any additional permissions from that copy, or from any part
+     of it.  (Additional permissions may be written to require their own
+     removal in certain cases when you modify the work.)  You may place
+     additional permissions on material, added by you to a covered work,
+     for which you have or can give appropriate copyright permission.
+
+     Notwithstanding any other provision of this License, for material
+     you add to a covered work, you may (if authorized by the copyright
+     holders of that material) supplement the terms of this License with
+     terms:
+
+       a. Disclaiming warranty or limiting liability differently from
+          the terms of sections 15 and 16 of this License; or
+
+       b. Requiring preservation of specified reasonable legal notices
+          or author attributions in that material or in the Appropriate
+          Legal Notices displayed by works containing it; or
+
+       c. Prohibiting misrepresentation of the origin of that material,
+          or requiring that modified versions of such material be marked
+          in reasonable ways as different from the original version; or
+
+       d. Limiting the use for publicity purposes of names of licensors
+          or authors of the material; or
+
+       e. Declining to grant rights under trademark law for use of some
+          trade names, trademarks, or service marks; or
+
+       f. Requiring indemnification of licensors and authors of that
+          material by anyone who conveys the material (or modified
+          versions of it) with contractual assumptions of liability to
+          the recipient, for any liability that these contractual
+          assumptions directly impose on those licensors and authors.
+
+     All other non-permissive additional terms are considered “further
+     restrictions” within the meaning of section 10.  If the Program as
+     you received it, or any part of it, contains a notice stating that
+     it is governed by this License along with a term that is a further
+     restriction, you may remove that term.  If a license document
+     contains a further restriction but permits relicensing or conveying
+     under this License, you may add to a covered work material governed
+     by the terms of that license document, provided that the further
+     restriction does not survive such relicensing or conveying.
+
+     If you add terms to a covered work in accord with this section, you
+     must place, in the relevant source files, a statement of the
+     additional terms that apply to those files, or a notice indicating
+     where to find the applicable terms.
+
+     Additional terms, permissive or non-permissive, may be stated in
+     the form of a separately written license, or stated as exceptions;
+     the above requirements apply either way.
+
+  8. Termination.
+
+     You may not propagate or modify a covered work except as expressly
+     provided under this License.  Any attempt otherwise to propagate or
+     modify it is void, and will automatically terminate your rights
+     under this License (including any patent licenses granted under the
+     third paragraph of section 11).
+
+     However, if you cease all violation of this License, then your
+     license from a particular copyright holder is reinstated (a)
+     provisionally, unless and until the copyright holder explicitly and
+     finally terminates your license, and (b) permanently, if the
+     copyright holder fails to notify you of the violation by some
+     reasonable means prior to 60 days after the cessation.
+
+     Moreover, your license from a particular copyright holder is
+     reinstated permanently if the copyright holder notifies you of the
+     violation by some reasonable means, this is the first time you have
+     received notice of violation of this License (for any work) from
+     that copyright holder, and you cure the violation prior to 30 days
+     after your receipt of the notice.
+
+     Termination of your rights under this section does not terminate
+     the licenses of parties who have received copies or rights from you
+     under this License.  If your rights have been terminated and not
+     permanently reinstated, you do not qualify to receive new licenses
+     for the same material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+     You are not required to accept this License in order to receive or
+     run a copy of the Program.  Ancillary propagation of a covered work
+     occurring solely as a consequence of using peer-to-peer
+     transmission to receive a copy likewise does not require
+     acceptance.  However, nothing other than this License grants you
+     permission to propagate or modify any covered work.  These actions
+     infringe copyright if you do not accept this License.  Therefore,
+     by modifying or propagating a covered work, you indicate your
+     acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+     Each time you convey a covered work, the recipient automatically
+     receives a license from the original licensors, to run, modify and
+     propagate that work, subject to this License.  You are not
+     responsible for enforcing compliance by third parties with this
+     License.
+
+     An “entity transaction” is a transaction transferring control of an
+     organization, or substantially all assets of one, or subdividing an
+     organization, or merging organizations.  If propagation of a
+     covered work results from an entity transaction, each party to that
+     transaction who receives a copy of the work also receives whatever
+     licenses to the work the party’s predecessor in interest had or
+     could give under the previous paragraph, plus a right to possession
+     of the Corresponding Source of the work from the predecessor in
+     interest, if the predecessor has it or can get it with reasonable
+     efforts.
+
+     You may not impose any further restrictions on the exercise of the
+     rights granted or affirmed under this License.  For example, you
+     may not impose a license fee, royalty, or other charge for exercise
+     of rights granted under this License, and you may not initiate
+     litigation (including a cross-claim or counterclaim in a lawsuit)
+     alleging that any patent claim is infringed by making, using,
+     selling, offering for sale, or importing the Program or any portion
+     of it.
+
+  11. Patents.
+
+     A “contributor” is a copyright holder who authorizes use under this
+     License of the Program or a work on which the Program is based.
+     The work thus licensed is called the contributor’s “contributor
+     version”.
+
+     A contributor’s “essential patent claims” are all patent claims
+     owned or controlled by the contributor, whether already acquired or
+     hereafter acquired, that would be infringed by some manner,
+     permitted by this License, of making, using, or selling its
+     contributor version, but do not include claims that would be
+     infringed only as a consequence of further modification of the
+     contributor version.  For purposes of this definition, “control”
+     includes the right to grant patent sublicenses in a manner
+     consistent with the requirements of this License.
+
+     Each contributor grants you a non-exclusive, worldwide,
+     royalty-free patent license under the contributor’s essential
+     patent claims, to make, use, sell, offer for sale, import and
+     otherwise run, modify and propagate the contents of its contributor
+     version.
+
+     In the following three paragraphs, a “patent license” is any
+     express agreement or commitment, however denominated, not to
+     enforce a patent (such as an express permission to practice a
+     patent or covenant not to sue for patent infringement).  To “grant”
+     such a patent license to a party means to make such an agreement or
+     commitment not to enforce a patent against the party.
+
+     If you convey a covered work, knowingly relying on a patent
+     license, and the Corresponding Source of the work is not available
+     for anyone to copy, free of charge and under the terms of this
+     License, through a publicly available network server or other
+     readily accessible means, then you must either (1) cause the
+     Corresponding Source to be so available, or (2) arrange to deprive
+     yourself of the benefit of the patent license for this particular
+     work, or (3) arrange, in a manner consistent with the requirements
+     of this License, to extend the patent license to downstream
+     recipients.  “Knowingly relying” means you have actual knowledge
+     that, but for the patent license, your conveying the covered work
+     in a country, or your recipient’s use of the covered work in a
+     country, would infringe one or more identifiable patents in that
+     country that you have reason to believe are valid.
+
+     If, pursuant to or in connection with a single transaction or
+     arrangement, you convey, or propagate by procuring conveyance of, a
+     covered work, and grant a patent license to some of the parties
+     receiving the covered work authorizing them to use, propagate,
+     modify or convey a specific copy of the covered work, then the
+     patent license you grant is automatically extended to all
+     recipients of the covered work and works based on it.
+
+     A patent license is “discriminatory” if it does not include within
+     the scope of its coverage, prohibits the exercise of, or is
+     conditioned on the non-exercise of one or more of the rights that
+     are specifically granted under this License.  You may not convey a
+     covered work if you are a party to an arrangement with a third
+     party that is in the business of distributing software, under which
+     you make payment to the third party based on the extent of your
+     activity of conveying the work, and under which the third party
+     grants, to any of the parties who would receive the covered work
+     from you, a discriminatory patent license (a) in connection with
+     copies of the covered work conveyed by you (or copies made from
+     those copies), or (b) primarily for and in connection with specific
+     products or compilations that contain the covered work, unless you
+     entered into that arrangement, or that patent license was granted,
+     prior to 28 March 2007.
+
+     Nothing in this License shall be construed as excluding or limiting
+     any implied license or other defenses to infringement that may
+     otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others’ Freedom.
+
+     If conditions are imposed on you (whether by court order, agreement
+     or otherwise) that contradict the conditions of this License, they
+     do not excuse you from the conditions of this License.  If you
+     cannot convey a covered work so as to satisfy simultaneously your
+     obligations under this License and any other pertinent obligations,
+     then as a consequence you may not convey it at all.  For example,
+     if you agree to terms that obligate you to collect a royalty for
+     further conveying from those to whom you convey the Program, the
+     only way you could satisfy both those terms and this License would
+     be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+     Notwithstanding any other provision of this License, you have
+     permission to link or combine any covered work with a work licensed
+     under version 3 of the GNU Affero General Public License into a
+     single combined work, and to convey the resulting work.  The terms
+     of this License will continue to apply to the part which is the
+     covered work, but the special requirements of the GNU Affero
+     General Public License, section 13, concerning interaction through
+     a network will apply to the combination as such.
+
+  14. Revised Versions of this License.
+
+     The Free Software Foundation may publish revised and/or new
+     versions of the GNU General Public License from time to time.  Such
+     new versions will be similar in spirit to the present version, but
+     may differ in detail to address new problems or concerns.
+
+     Each version is given a distinguishing version number.  If the
+     Program specifies that a certain numbered version of the GNU
+     General Public License “or any later version” applies to it, you
+     have the option of following the terms and conditions either of
+     that numbered version or of any later version published by the Free
+     Software Foundation.  If the Program does not specify a version
+     number of the GNU General Public License, you may choose any
+     version ever published by the Free Software Foundation.
+
+     If the Program specifies that a proxy can decide which future
+     versions of the GNU General Public License can be used, that
+     proxy’s public statement of acceptance of a version permanently
+     authorizes you to choose that version for the Program.
+
+     Later license versions may give you additional or different
+     permissions.  However, no additional obligations are imposed on any
+     author or copyright holder as a result of your choosing to follow a
+     later version.
+
+  15. Disclaimer of Warranty.
+
+     THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+     APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE
+     COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS”
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
+     INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+     MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE
+     RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
+     SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
+     NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+     IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+     WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
+     AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
+     DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+     CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
+     THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
+     BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+     PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+     PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
+     THE POSSIBILITY OF SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+     If the disclaimer of warranty and limitation of liability provided
+     above cannot be given local legal effect according to their terms,
+     reviewing courts shall apply local law that most closely
+     approximates an absolute waiver of all civil liability in
+     connection with the Program, unless a warranty or assumption of
+     liability accompanies a copy of the Program in return for a fee.
+
+END OF TERMS AND CONDITIONS
+===========================
+
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+   To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least the
+“copyright” line and a pointer to where the full notice is found.
+
+     ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
+     Copyright (C) YEAR NAME OF AUTHOR
+
+     This program 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 program 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.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+   Also add information on how to contact you by electronic and paper
+mail.
+
+   If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+     PROGRAM Copyright (C) YEAR NAME OF AUTHOR
+     This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
+     This is free software, and you are welcome to redistribute it
+     under certain conditions; type ‘show c’ for details.
+
+   The hypothetical commands ‘show w’ and ‘show c’ should show the
+appropriate parts of the General Public License.  Of course, your
+program’s commands might be different; for a GUI interface, you would
+use an “about box”.
+
+   You should also get your employer (if you work as a programmer) or
+school, if any, to sign a “copyright disclaimer” for the program, if
+necessary.  For more information on this, and how to apply and follow
+the GNU GPL, see <https://www.gnu.org/licenses/>.
+
+   The GNU General Public License does not permit incorporating your
+program into proprietary programs.  If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library.  If this is what you want to do, use the
+GNU Lesser General Public License instead of this License.  But first,
+please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
+
+
+\1f
+Tag Table:
+Node: Top\7f763
+Node: Introduction\7f3049
+Ref: Some things that Transient can do\7f3577
+Ref: Complexity in CLI programs\7f3930
+Ref: Using Transient for composing interactive commands\7f4531
+Node: Usage\7f6773
+Node: Invoking Transients\7f7141
+Node: Aborting and Resuming Transients\7f8310
+Node: Common Suffix Commands\7f10931
+Node: Saving Values\7f12638
+Ref: Saving Values-Footnote-1\7f14042
+Node: Using History\7f14235
+Node: Getting Help for Suffix Commands\7f15941
+Node: Enabling and Disabling Suffixes\7f17319
+Node: Other Commands\7f20607
+Node: Configuration\7f22284
+Ref: Essential Options\7f22564
+Ref: Accessibility Options\7f29394
+Ref: Auxiliary Options\7f29717
+Ref: Developer Options\7f34295
+Ref: Hook Variables\7f35543
+Node: Modifying Existing Transients\7f35830
+Node: Defining New Commands\7f40022
+Node: Technical Introduction\7f40439
+Node: Defining Transients\7f46139
+Node: Binding Suffix and Infix Commands\7f48606
+Node: Group Specifications\7f49464
+Node: Suffix Specifications\7f56015
+Node: Defining Suffix and Infix Commands\7f60228
+Node: Using Infix Arguments\7f63276
+Node: Current Suffix Command\7f65669
+Node: Current Prefix Command\7f68029
+Node: Transient State\7f70585
+Ref: Pre-commands for Infixes\7f75401
+Ref: Pre-commands for Suffixes\7f75921
+Ref: Pre-commands for Non-Suffixes\7f78375
+Ref: Special Pre-Commands\7f79511
+Node: Classes and Methods\7f80019
+Node: Group Classes\7f82106
+Node: Group Methods\7f84033
+Node: Prefix Classes\7f85293
+Node: Suffix Classes\7f86138
+Node: Prefix Methods\7f90118
+Node: Suffix Methods\7f92511
+Node: Suffix Value Methods\7f92832
+Node: Suffix Format Methods\7f96181
+Node: Prefix Slots\7f99183
+Ref: Value and Scope\7f99333
+Ref: Behavior\7f100812
+Ref: Appearance\7f102153
+Ref: Documentation\7f102812
+Ref: Internal\7f103432
+Node: Suffix Slots\7f104787
+Ref: Slots of transient-child\7f105155
+Ref: Slots of transient-suffix\7f105530
+Ref: Slots of transient-infix\7f107103
+Ref: Slots of transient-variable\7f110399
+Ref: Slots of transient-switches\7f110501
+Node: Predicate Slots\7f110864
+Node: FAQ\7f113209
+Ref: Can I control how the popup buffer is displayed?\7f113338
+Ref: How can I copy text from the popup buffer?\7f113665
+Ref: How can I autoload prefix and suffix commands?\7f114159
+Ref: How does Transient compare to prefix keys and universal arguments?\7f114633
+Ref: How does Transient compare to Magit-Popup and Hydra?\7f114876
+Ref: Why did some of the key bindings change?\7f115070
+Ref: Why does q not quit popups anymore?\7f117423
+Node: Keystroke Index\7f118526
+Node: Command and Function Index\7f120391
+Node: Variable Index\7f128309
+Node: Concept Index\7f130877
+Node: GNU General Public License\7f133613
+\1f
+End Tag Table
+
+\1f
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/transient-readme.txt b/elpa/transient-readme.txt
deleted file mode 100644 (file)
index 674b25f..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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.