summaryrefslogtreecommitdiff
path: root/elpa/transient-20190831.802
diff options
context:
space:
mode:
authorblendoit <blendoit@gmail.com>2019-09-03 19:31:14 -0700
committerblendoit <blendoit@gmail.com>2019-09-03 19:31:14 -0700
commit9282e3afc2bcfbc2fe905a62ba5e03f7f019f46f (patch)
tree34b3df5ff601b78bd575a4992af77aa17db838f4 /elpa/transient-20190831.802
parent85f9213626a7230a3b5ca8d101c2e3181d06e07a (diff)
remove personal files
Diffstat (limited to 'elpa/transient-20190831.802')
-rw-r--r--elpa/transient-20190831.802/dir18
-rw-r--r--elpa/transient-20190831.802/transient-autoloads.el26
-rw-r--r--elpa/transient-20190831.802/transient-pkg.el13
-rw-r--r--elpa/transient-20190831.802/transient.el3089
-rw-r--r--elpa/transient-20190831.802/transient.elcbin123215 -> 0 bytes
-rw-r--r--elpa/transient-20190831.802/transient.info2384
6 files changed, 0 insertions, 5530 deletions
diff --git a/elpa/transient-20190831.802/dir b/elpa/transient-20190831.802/dir
deleted file mode 100644
index 4d6ad7f..0000000
--- a/elpa/transient-20190831.802/dir
+++ /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.
-
-File: dir, Node: Top This is the top of the INFO tree
-
- This (the Directory node) gives a menu of major topics.
- Typing "q" exits, "H" lists all Info commands, "d" returns here,
- "h" gives a primer for first-timers,
- "mEmacs<Return>" visits the Emacs manual, etc.
-
- In Emacs, you can click mouse button 2 on a menu item or cross reference
- to select it.
-
-* Menu:
-
-Emacs
-* Transient: (transient). Transient Commands.
diff --git a/elpa/transient-20190831.802/transient-autoloads.el b/elpa/transient-20190831.802/transient-autoloads.el
deleted file mode 100644
index 3114fc1..0000000
--- a/elpa/transient-20190831.802/transient-autoloads.el
+++ /dev/null
@@ -1,26 +0,0 @@
-;;; transient-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
- (or (file-name-directory #$) (car load-path))))
-
-
-;;;### (autoloads nil "transient" "transient.el" (0 0 0 0))
-;;; Generated autoloads from transient.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "transient" '("transient-" "post-transient-hook" "current-transient-" "define-")))
-
-;;;***
-
-;;;### (autoloads nil nil ("transient-pkg.el") (0 0 0 0))
-
-;;;***
-
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; transient-autoloads.el ends here
diff --git a/elpa/transient-20190831.802/transient-pkg.el b/elpa/transient-20190831.802/transient-pkg.el
deleted file mode 100644
index e15e49e..0000000
--- a/elpa/transient-20190831.802/transient-pkg.el
+++ /dev/null
@@ -1,13 +0,0 @@
-(define-package "transient" "20190831.802" "Transient commands"
- '((emacs "25.1")
- (dash "2.15.0"))
- :keywords
- '("bindings")
- :authors
- '(("Jonas Bernoulli" . "jonas@bernoul.li"))
- :maintainer
- '("Jonas Bernoulli" . "jonas@bernoul.li")
- :url "https://github.com/magit/transient")
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/transient-20190831.802/transient.el b/elpa/transient-20190831.802/transient.el
deleted file mode 100644
index f1dd349..0000000
--- a/elpa/transient-20190831.802/transient.el
+++ /dev/null
@@ -1,3089 +0,0 @@
-;;; transient.el --- Transient commands -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2018-2019 Jonas Bernoulli
-
-;; Author: Jonas Bernoulli <jonas@bernoul.li>
-;; Homepage: https://github.com/magit/transient
-;; Package-Requires: ((emacs "25.1") (dash "2.15.0"))
-;; Keywords: bindings
-
-;; This file is not part of GNU Emacs.
-
-;; This file is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published
-;; by the Free Software Foundation; either version 3 of the License,
-;; or (at your option) any later version.
-
-;; This file is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; For a full copy of the GNU GPL see http://www.gnu.org/licenses.
-
-;;; Commentary:
-
-;; Taking inspiration from prefix keys and prefix arguments, Transient
-;; implements a similar abstraction involving a prefix command, infix
-;; arguments and suffix commands. We could call this abstraction a
-;; "transient command", but because it always involves at least two
-;; commands (a prefix and a suffix) we prefer to call it just a
-;; "transient".
-
-;; When the user calls a transient prefix command, then a transient
-;; (temporary) keymap is activated, which binds the transient's infix
-;; and suffix commands, and functions that control the transient state
-;; are added to `pre-command-hook' and `post-command-hook'. The
-;; available suffix and infix commands and their state are shown in
-;; the echo area until the transient is exited by invoking a suffix
-;; command.
-
-;; Calling an infix command causes its value to be changed, possibly
-;; by reading a new value in the minibuffer.
-
-;; Calling a suffix command usually causes the transient to be exited
-;; but suffix commands can also be configured to not exit the
-;; transient state.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'dash)
-(require 'eieio)
-(require 'format-spec)
-
-(eval-when-compile
- (require 'subr-x))
-
-(declare-function info 'info)
-(declare-function Man-find-section 'man)
-(declare-function Man-next-section 'man)
-(declare-function Man-getpage-in-background 'man)
-
-(defvar Man-notify-method)
-
-;;; Options
-
-(defgroup transient nil
- "Transient commands."
- :group 'bindings)
-
-(defcustom transient-show-popup t
- "Whether to show the current transient in a popup buffer.
-
-- If t, then show the popup as soon as a transient prefix command
- is invoked.
-
-- If nil, then do not show the popup unless the user explicitly
- requests it, by pressing an incomplete prefix key sequence.
-
-- If a number, then delay displaying the popup and instead show
- a brief one-line summary. If zero or negative, then suppress
- even showing that summary and display the pressed key only.
-
- Show the popup when the user explicitly requests it by pressing
- an incomplete prefix key sequence. Unless zero, then also show
- the popup after that many seconds of inactivity (using the
- absolute value)."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type '(choice (const :tag "instantly" t)
- (const :tag "on demand" nil)
- (const :tag "on demand (no summary)" 0)
- (number :tag "after delay" 1)))
-
-(defcustom transient-enable-popup-navigation nil
- "Whether navigation commands are enabled in the transient popup.
-
-While a transient is active the transient popup buffer is not the
-current buffer, making it necesary to use dedicated commands to
-act on that buffer itself. If this non-nil, then the following
-features are available:
-
-- \"<up>\" moves the cursor to the previous suffix.
- \"<down>\" moves the cursor to the next suffix.
- \"RET\" invokes the suffix the cursor is on.
-- \"<mouse-1>\" invokes the clicked on suffix.
-- \"C-s\" and \"C-r\" start isearch in the popup buffer."
- :package-version '(transient . "0.2.0")
- :group 'transient
- :type 'boolean)
-
-(defcustom transient-display-buffer-action
- '(display-buffer-in-side-window (side . bottom))
- "The action used to display the transient popup buffer.
-
-The transient popup buffer is displayed in a window using
-
- \(display-buffer buf transient-display-buffer-action)
-
-The value of this option has the form (FUNCTION . ALIST),
-where FUNCTION is a function or a list of functions. Each such
-function should accept two arguments: a buffer to display and
-an alist of the same form as ALIST. See `display-buffer' for
-details.
-
-The default is (display-buffer-in-side-window (side . bottom)).
-This displays the window at the bottom of the selected frame.
-Another useful value is (display-buffer-below-selected). This
-is what `magit-popup' used by default. For more alternatives
-see info node `(elisp)Display Action Functions'.
-
-It may be possible to display the window in another frame, but
-whether that works in practice depends on the window-manager.
-If the window manager selects the new window (Emacs frame),
-then it doesn't work.
-
-If you change the value of this option, then you might also
-want to change the value of `transient-mode-line-format'."
- :package-version '(transient . "0.2.0")
- :group 'transient
- :type '(cons (choice function (repeat :tag "Functions" function))
- alist))
-
-(defcustom transient-mode-line-format 'line
- "The mode-line format for the transient popup buffer.
-
-If nil, then the buffer has no mode-line. If the buffer is not
-displayed right above the echo area, then this probably is not
-a good value.
-
-If `line' (the default), then the buffer also has no mode-line,
-but a thin line is drawn instead, using the background color of
-the face `transient-separator'.
-
-Otherwise this can be any mode-line format.
-See `mode-line-format' for details."
- :package-version '(transient . "0.2.0")
- :group 'transient
- :type '(choice (const :tag "hide mode-line" nil)
- (const :tag "substitute thin line" line)
- (const :tag "name of prefix command"
- ("%e" mode-line-front-space
- mode-line-buffer-identification))
- (sexp :tag "custom mode-line format")))
-
-(defcustom transient-show-common-commands nil
- "Whether to show common transient suffixes in the popup buffer.
-
-These commands are always shown after typing the prefix key
-\"C-x\" when a transient command is active. To toggle the value
-of this variable use \"C-x t\" when a transient is active."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'boolean)
-
-(defcustom transient-read-with-initial-input t
- "Whether to use the last history element as initial minibuffer input."
- :package-version '(transient . "0.2.0")
- :group 'transient
- :type 'boolean)
-
-(defcustom transient-highlight-mismatched-keys nil
- "Whether to highlight keys that do not match their argument.
-
-This only affects infix arguments that represent command-line
-arguments. When this option is non-nil, then the key binding
-for infix argument are highlighted when only a long argument
-\(e.g. \"--verbose\") is specified but no shor-thand (e.g \"-v\").
-In the rare case that a short-hand is specified but does not
-match the key binding, then it is highlighed differently.
-
-The highlighting is done using using `transient-mismatched-key'
-and `transient-nonstandard-key'."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'boolean)
-
-(defcustom transient-substitute-key-function nil
- "Function used to modify key bindings.
-
-This function is called with one argument, the prefix object,
-and must return a key binding description, either the existing
-key description it finds in the `key' slot, or a substitution.
-
-This is intended to let users replace certain prefix keys. It
-could also be used to make other substitutions, but that is
-discouraged.
-
-For example, \"=\" is hard to reach using my custom keyboard
-layout, so I substitute \"(\" for that, which is easy to reach
-using a layout optimized for lisp.
-
- (setq transient-substitute-key-function
- (lambda (obj)
- (let ((key (oref obj key)))
- (if (string-match \"\\\\`\\\\(=\\\\)[a-zA-Z]\" key)
- (replace-match \"(\" t t key 1)
- key)))))"
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type '(choice (const :tag "Transform no keys (nil)" nil) function))
-
-(defcustom transient-detect-key-conflicts nil
- "Whether to detect key binding conflicts.
-
-Conflicts are detected when a transient prefix command is invoked
-and results in an error, which prevents the transient from being
-used."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'boolean)
-
-(defcustom transient-default-level 4
- "Control what suffix levels are made available by default.
-
-Each suffix command is placed on a level and each prefix command
-has a level, which controls which suffix commands are available.
-Integers between 1 and 7 (inclusive) are valid levels.
-
-The levels of individual transients and/or their individual
-suffixes can be changed individually, by invoking the prefix and
-then pressing \"C-x l\".
-
-The default level for both transients and their suffixes is 4.
-This option only controls the default for transients. The default
-suffix level is always 4. The author of a transient should place
-certain suffixes on a higher level if they expect that it won't be
-of use to most users, and they should place very important suffixes
-on a lower level so that the remain available even if the user
-lowers the transient level.
-
-\(Magit currently places nearly all suffixes on level 4 and lower
-levels are not used at all yet. So for the time being you should
-not set a lower level here and using a higher level might not
-give you as many additional suffixes as you hoped.)"
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type '(choice (const :tag "1 - fewest suffixes" 1)
- (const 2)
- (const 3)
- (const :tag "4 - default" 4)
- (const 5)
- (const 6)
- (const :tag "7 - most suffixes" 7)))
-
-(defcustom transient-levels-file
- (locate-user-emacs-file (convert-standard-filename "transient/levels.el"))
- "File used to save levels of transients and their suffixes."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'file)
-
-(defcustom transient-values-file
- (locate-user-emacs-file (convert-standard-filename "transient/values.el"))
- "File used to save values of transients."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'file)
-
-(defcustom transient-history-file
- (locate-user-emacs-file (convert-standard-filename "transient/history.el"))
- "File used to save history of transients and their infixes."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'file)
-
-(defcustom transient-history-limit 10
- "Number of history elements to keep when saving to file."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'integer)
-
-(defcustom transient-save-history t
- "Whether to save history of transient commands when exiting Emacs."
- :package-version '(transient . "0.1.0")
- :group 'transient
- :type 'boolean)
-
-;;; Faces
-
-(defgroup transient-faces nil
- "Faces used by Transient."
- :group 'transient)
-
-(defface transient-heading '((t :inherit font-lock-keyword-face))
- "Face used for headings."
- :group 'transient-faces)
-
-(defface transient-key '((t :inherit font-lock-builtin-face))
- "Face used for keys."
- :group 'transient-faces)
-
-(defface transient-argument '((t :inherit font-lock-warning-face))
- "Face used for enabled arguments."
- :group 'transient-faces)
-
-(defface transient-value '((t :inherit font-lock-string-face))
- "Face used for values."
- :group 'transient-faces)
-
-(defface transient-inactive-argument '((t :inherit shadow))
- "Face used for inactive arguments."
- :group 'transient-faces)
-
-(defface transient-inactive-value '((t :inherit shadow))
- "Face used for inactive values."
- :group 'transient-faces)
-
-(defface transient-unreachable '((t :inherit shadow))
- "Face used for suffixes unreachable from the current prefix sequence."
- :group 'transient-faces)
-
-(defface transient-active-infix '((t :inherit secondary-selection))
- "Face used for the infix for which the value is being read."
- :group 'transient-faces)
-
-(defface transient-unreachable-key '((t :inherit shadow))
- "Face used for keys unreachable from the current prefix sequence."
- :group 'transient-faces)
-
-(defface transient-nonstandard-key '((t :underline t))
- "Face optionally used to highlight keys conflicting with short-argument.
-Also see option `transient-highlight-mismatched-keys'."
- :group 'transient-faces)
-
-(defface transient-mismatched-key '((t :underline t))
- "Face optionally used to highlight keys without a short-argument.
-Also see option `transient-highlight-mismatched-keys'."
- :group 'transient-faces)
-
-(defface transient-enabled-suffix
- '((t :background "green" :foreground "black" :weight bold))
- "Face used for enabled levels while editing suffix levels.
-See info node `(transient)Enabling and Disabling Suffixes'."
- :group 'transient-faces)
-
-(defface transient-disabled-suffix
- '((t :background "red" :foreground "black" :weight bold))
- "Face used for disabled levels while editing suffix levels.
-See info node `(transient)Enabling and Disabling Suffixes'."
- :group 'transient-faces)
-
-(defface transient-separator
- '((((class color) (background light)) :background "grey80")
- (((class color) (background dark)) :background "grey30"))
- "Face used to draw line below transient popup window.
-This is only used if `transient-mode-line-format' is `line'.
-Only the background color is significant."
- :group 'transient-faces)
-
-;;; Persistence
-
-(defun transient--read-file-contents (file)
- (with-demoted-errors "Transient error: %S"
- (and (file-exists-p file)
- (with-temp-buffer file
- (insert-file-contents file)
- (read (current-buffer))))))
-
-(defun transient--pp-to-file (object file)
- (make-directory (file-name-directory file) t)
- (setq object (cl-sort object #'string< :key #'car))
- (with-temp-file file
- (let ((print-level nil)
- (print-length nil))
- (pp object (current-buffer)))))
-
-(defvar transient-values
- (transient--read-file-contents transient-values-file)
- "Values of transient commands.
-The value of this variable persists between Emacs sessions
-and you usually should not change it manually.")
-
-(defun transient-save-values ()
- (transient--pp-to-file transient-values transient-values-file))
-
-(defvar transient-levels
- (transient--read-file-contents transient-levels-file)
- "Levels of transient commands.
-The value of this variable persists between Emacs sessions
-and you usually should not change it manually.")
-
-(defun transient-save-levels ()
- (transient--pp-to-file transient-levels transient-levels-file))
-
-(defvar transient-history
- (transient--read-file-contents transient-history-file)
- "History of transient commands and infix arguments.
-The value of this variable persists between Emacs sessions
-\(unless `transient-save-history' is nil) and you usually
-should not change it manually.")
-
-(defun transient-save-history ()
- (setq transient-history
- (cl-sort (mapcar (pcase-lambda (`(,key . ,val))
- (cons key (-take transient-history-limit
- (delete-dups val))))
- transient-history)
- #'string< :key #'car))
- (transient--pp-to-file transient-history transient-history-file))
-
-(defun transient-maybe-save-history ()
- "Save the value of `transient-history'.
-If `transient-save-history' is nil, then do nothing."
- (when transient-save-history
- (transient-save-history)))
-
-(unless noninteractive
- (add-hook 'kill-emacs-hook 'transient-maybe-save-history))
-
-;;; Classes
-;;;; Prefix
-
-(defclass transient-prefix ()
- ((prototype :initarg :prototype)
- (command :initarg :command)
- (level :initarg :level)
- (variable :initarg :variable :initform nil)
- (value :initarg :value)
- (scope :initarg :scope :initform nil)
- (history :initarg :history :initform nil)
- (history-pos :initarg :history-pos :initform 0)
- (history-key :initarg :history-key :initform nil)
- (man-page :initarg :man-page :initform nil)
- (info-manual :initarg :info-manual :initform nil)
- (transient-suffix :initarg :transient-suffix :initform nil)
- (transient-non-suffix :initarg :transient-non-suffix :initform nil)
- (incompatible :initarg :incompatible :initform nil))
- "Transient prefix command.
-
-Each transient prefix command consists of a command, which is
-stored in a symbols function slot and an object, which is stored
-in the `transient--prefix' property of the same object.
-
-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 clones `prototype' slot.")
-
-;;;; Suffix
-
-(defclass transient-child ()
- ((level
- :initarg :level
- :initform 1
- :documentation "Enable if level of prefix is equal or greater.")
- (if
- :initarg :if
- :initform nil
- :documentation "Enable if predicate returns non-nil.")
- (if-not
- :initarg :if-not
- :initform nil
- :documentation "Enable if predicate returns nil.")
- (if-non-nil
- :initarg :if-non-nil
- :initform nil
- :documentation "Enable if variable's value is non-nil.")
- (if-nil
- :initarg :if-nil
- :initform nil
- :documentation "Enable if variable's value is nil.")
- (if-mode
- :initarg :if-mode
- :initform nil
- :documentation "Enable if major-mode matches value.")
- (if-not-mode
- :initarg :if-not-mode
- :initform nil
- :documentation "Enable if major-mode does not match value.")
- (if-derived
- :initarg :if-derived
- :initform nil
- :documentation "Enable if major-mode derives from value.")
- (if-not-derived
- :initarg :if-not-derived
- :initform nil
- :documentation "Enable if major-mode does not derive from value."))
- "Abstract superclass for group and and suffix classes.
-
-It is undefined what happens if more than one `if*' predicate
-slot is non-nil."
- :abstract t)
-
-(defclass transient-suffix (transient-child)
- ((key :initarg :key)
- (command :initarg :command)
- (transient :initarg :transient)
- (format :initarg :format :initform " %k %d")
- (description :initarg :description :initform nil))
- "Superclass for suffix command.")
-
-(defclass transient-infix (transient-suffix)
- ((transient :initform t)
- (argument :initarg :argument)
- (shortarg :initarg :shortarg)
- (value :initform nil)
- (multi-value :initarg :multi-value :initform nil)
- (allow-empty :initarg :allow-empty :initform nil)
- (history-key :initarg :history-key :initform nil)
- (reader :initarg :reader :initform nil)
- (prompt :initarg :prompt :initform nil)
- (choices :initarg :choices :initform nil)
- (format :initform " %k %d (%v)"))
- "Transient infix command."
- :abstract t)
-
-(defclass transient-argument (transient-infix) ()
- "Abstract superclass for infix arguments."
- :abstract t)
-
-(defclass transient-switch (transient-argument) ()
- "Class used for command-line argument that can be turned on and off.")
-
-(defclass transient-option (transient-argument) ()
- "Class used for command-line argument that can take a value.")
-
-(defclass transient-variable (transient-infix)
- ((variable :initarg :variable)
- (format :initform " %k %d %v"))
- "Abstract superclass for infix commands that set a variable."
- :abstract t)
-
-(defclass transient-switches (transient-argument)
- ((argument-format :initarg :argument-format)
- (argument-regexp :initarg :argument-regexp))
- "Class used for sets of mutually exclusive command-line switches.")
-
-(defclass transient-files (transient-infix) ()
- "Class used for the \"--\" argument.
-All remaining arguments are treated as files.
-They become the value of this this argument.")
-
-;;;; Group
-
-(defclass transient-group (transient-child)
- ((suffixes :initarg :suffixes :initform nil)
- (hide :initarg :hide :initform nil)
- (description :initarg :description :initform nil))
- "Abstract superclass of all group classes."
- :abstract t)
-
-(defclass transient-column (transient-group) ()
- "Group class that displays each element on a separate line.")
-
-(defclass transient-row (transient-group) ()
- "Group class that displays all elements on a single line.")
-
-(defclass transient-columns (transient-group) ()
- "Group class that displays elements organized in columns.
-Direct elements have to be groups whose elements have to be
-commands or string. Each subgroup represents a column. This
-class takes care of inserting the subgroups' elements.")
-
-(defclass transient-subgroups (transient-group) ()
- "Group class that wraps other groups.
-
-Direct elements have to be groups whose elements have to be
-commands or strings. This group inserts an empty line between
-subgroups. The subgroups are responsible for displaying their
-elements themselves.")
-
-;;; Define
-
-(defmacro define-transient-command (name arglist &rest args)
- "Define NAME as a transient prefix command.
-
-ARGLIST are the arguments that command takes.
-DOCSTRING is the documentation string and is optional.
-
-These arguments can optionally be followed by key-value pairs.
-Each key has to be a keyword symbol, either `:class' or a keyword
-argument supported by the constructor of that class. The
-`transient-prefix' class is used if the class is not specified
-explicitly.
-
-GROUPs add key bindings for infix and suffix commands and specify
-how these bindings are presented in the popup buffer. At least
-one GROUP has to be specified. See info node `(transient)Binding
-Suffix and Infix Commands'.
-
-The BODY is optional. If it is omitted, then ARGLIST is also
-ignored and the function definition becomes:
-
- (lambda ()
- (interactive)
- (transient-setup \\='NAME))
-
-If BODY is specified, then it must begin with an `interactive'
-form that matches ARGLIST, and it must call `transient-setup'.
-It may however call that function only when some condition is
-satisfied; that is one of the reason why you might want to use
-an explicit BODY.
-
-All transients have a (possibly nil) value, which is exported
-when suffix commands are called, so that they can consume that
-value. For some transients it might be necessary to have a sort
-of secondary value, called a scope. Such a scope would usually
-be set in the commands `interactive' form and has to be passed
-to the setup function:
-
- (transient-setup \\='NAME nil nil :scope SCOPE)
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... GROUP... [BODY...])"
- (declare (debug (&define name lambda-list
- [&optional lambda-doc]
- [&rest keywordp sexp]
- [&rest vectorp]
- [&optional ("interactive" interactive) def-body])))
- (pcase-let ((`(,class ,slots ,suffixes ,docstr ,body)
- (transient--expand-define-args args)))
- `(progn
- (defalias ',name
- ,(if body
- `(lambda ,arglist ,@body)
- `(lambda ()
- (interactive)
- (transient-setup ',name))))
- (put ',name 'interactive-only t)
- (put ',name 'function-documentation ,docstr)
- (put ',name 'transient--prefix
- (,(or class 'transient-prefix) :command ',name ,@slots))
- (put ',name 'transient--layout
- ',(cl-mapcan (lambda (s) (transient--parse-child name s))
- suffixes)))))
-
-(defmacro define-suffix-command (name arglist &rest args)
- "Define NAME as a transient suffix command.
-
-ARGLIST are the arguments that the command takes.
-DOCSTRING is the documentation string and is optional.
-
-These arguments can optionally be followed by key-value pairs.
-Each key has to be a keyword symbol, either `:class' or a
-keyword argument supported by the constructor of that class.
-The `transient-suffix' class is used if the class is not
-specified explicitly.
-
-The BODY must begin with an `interactive' form that matches
-ARGLIST. Use the function `transient-args' or the low-level
-variable `current-transient-suffixes' if the former does not
-give you all the required details. This should, but does not
-necessarily have to be, done inside the `interactive' form;
-just like for `prefix-arg' and `current-prefix-arg'.
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]... BODY...)"
- (declare (debug (&define name lambda-list
- [&optional lambda-doc]
- [&rest keywordp sexp]
- ("interactive" interactive)
- def-body)))
- (pcase-let ((`(,class ,slots ,_ ,docstr ,body)
- (transient--expand-define-args args)))
- `(progn
- (defalias ',name (lambda ,arglist ,@body))
- (put ',name 'interactive-only t)
- (put ',name 'function-documentation ,docstr)
- (put ',name 'transient--suffix
- (,(or class 'transient-suffix) :command ',name ,@slots)))))
-
-(defmacro define-infix-command (name _arglist &rest args)
- "Define NAME as a transient infix command.
-
-ARGLIST is always ignored and reserved for future use.
-DOCSTRING is the documentation string and is optional.
-
-The key-value pairs are mandatory. All transient infix commands
-are equal to each other (but not eq), so it is meaningless to
-define an infix command without also setting at least `:class'
-and one other keyword (which it is depends on the used class,
-usually `:argument' or `:variable').
-
-Each key has to be a keyword symbol, either `:class' or a keyword
-argument supported by the constructor of that class. The
-`transient-switch' class is used if the class is not specified
-explicitly.
-
-The function definitions is always:
-
- (lambda ()
- (interactive)
- (let ((obj (transient-suffix-object)))
- (transient-infix-set obj (transient-infix-read obj)))
- (transient--show))
-
-`transient-infix-read' and `transient-infix-set' are generic
-functions. Different infix commands behave differently because
-the concrete methods are different for different infix command
-classes. In rare case the above command function might not be
-suitable, even if you define your own infix command class. In
-that case you have to use `transient-suffix-command' to define
-the infix command and use t as the value of the `:transient'
-keyword.
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)"
- (declare (debug (&define name lambda-list
- [&optional lambda-doc]
- [&rest keywordp sexp])))
- (pcase-let ((`(,class ,slots ,_ ,docstr ,_)
- (transient--expand-define-args args)))
- `(progn
- (defalias ',name ,(transient--default-infix-command))
- (put ',name 'interactive-only t)
- (put ',name 'function-documentation ,docstr)
- (put ',name 'transient--suffix
- (,(or class 'transient-switch) :command ',name ,@slots)))))
-
-(defalias 'define-infix-argument 'define-infix-command
- "Define NAME as a transient infix command.
-
-Only use this alias to define an infix command that actually
-sets an infix argument. To define a infix command that, for
-example, sets a variable use `define-infix-command' instead.
-
-\(fn NAME ARGLIST [DOCSTRING] [KEYWORD VALUE]...)")
-
-(defun transient--expand-define-args (args)
- (let (class keys suffixes docstr)
- (when (stringp (car args))
- (setq docstr (pop args)))
- (while (keywordp (car args))
- (let ((k (pop args))
- (v (pop args)))
- (if (eq k :class)
- (setq class v)
- (push k keys)
- (push v keys))))
- (while (vectorp (car args))
- (push (pop args) suffixes))
- (list (if (eq (car-safe class) 'quote)
- (cadr class)
- class)
- (nreverse keys)
- (nreverse suffixes)
- docstr
- args)))
-
-(defun transient--parse-child (prefix spec)
- (cl-etypecase spec
- (vector (when-let ((c (transient--parse-group prefix spec))) (list c)))
- (list (when-let ((c (transient--parse-suffix prefix spec))) (list c)))
- (string (list spec))))
-
-(defun transient--parse-group (prefix spec)
- (setq spec (append spec nil))
- (cl-symbol-macrolet
- ((car (car spec))
- (pop (pop spec)))
- (let (level class args)
- (when (integerp car)
- (setq level pop))
- (when (stringp car)
- (setq args (plist-put args :description pop)))
- (while (keywordp car)
- (let ((k pop))
- (if (eq k :class)
- (setq class pop)
- (setq args (plist-put args k pop)))))
- (vector (or level (oref-default 'transient-child level))
- (or class
- (if (vectorp car)
- 'transient-columns
- 'transient-column))
- args
- (cl-mapcan (lambda (s) (transient--parse-child prefix s)) spec)))))
-
-(defun transient--parse-suffix (prefix spec)
- (let (level class args)
- (cl-symbol-macrolet
- ((car (car spec))
- (pop (pop spec)))
- (when (integerp car)
- (setq level pop))
- (when (or (stringp car)
- (vectorp car))
- (setq args (plist-put args :key pop)))
- (when (or (stringp car)
- (eq (car-safe car) 'lambda)
- (and (symbolp car)
- (not (commandp car))
- (commandp (cadr spec))))
- (setq args (plist-put args :description pop)))
- (cond
- ((keywordp car)
- (error "Need command, got %S" car))
- ((symbolp car)
- (setq args (plist-put args :command pop)))
- ((or (stringp car)
- (and car (listp car)))
- (let ((arg pop))
- (cl-typecase arg
- (list
- (setq args (plist-put args :shortarg (car arg)))
- (setq args (plist-put args :argument (cadr arg)))
- (setq arg (cadr arg)))
- (string
- (when-let ((shortarg (transient--derive-shortarg arg)))
- (setq args (plist-put args :shortarg shortarg)))
- (setq args (plist-put args :argument arg))))
- (setq args (plist-put args :command
- (intern (format "transient:%s:%s"
- prefix arg))))
- (cond ((and car (not (keywordp car)))
- (setq class 'transient-option)
- (setq args (plist-put args :reader pop)))
- ((not (string-suffix-p "=" arg))
- (setq class 'transient-switch))
- (t
- (setq class 'transient-option)
- (setq args (plist-put args :reader 'read-string))))))
- (t
- (error "Needed command or argument, got %S" car)))
- (while (keywordp car)
- (let ((k pop))
- (cl-case k
- (:class (setq class pop))
- (:level (setq level pop))
- (t (setq args (plist-put args k pop)))))))
- (unless (plist-get args :key)
- (when-let ((shortarg (plist-get args :shortarg)))
- (setq args (plist-put args :key shortarg))))
- (list (or level (oref-default 'transient-child level))
- (or class 'transient-suffix)
- args)))
-
-(defun transient--default-infix-command ()
- (cons 'lambda '(()
- (interactive)
- (let ((obj (transient-suffix-object)))
- (transient-infix-set obj (transient-infix-read obj)))
- (transient--show))))
-
-(defun transient--ensure-infix-command (obj)
- (let ((cmd (oref obj command)))
- (unless (or (commandp cmd)
- (get cmd 'transient--infix-command))
- (if (or (cl-typep obj 'transient-switch)
- (cl-typep obj 'transient-option))
- (put cmd 'transient--infix-command
- (transient--default-infix-command))
- ;; This is not an anonymous infix argument.
- (error "Suffix %s is not defined or autoloaded as a command" cmd)))))
-
-(defun transient--derive-shortarg (arg)
- (save-match-data
- (and (string-match "\\`\\(-[a-zA-Z]\\)\\(\\'\\|=\\)" arg)
- (match-string 1 arg))))
-
-;;; Edit
-
-(defun transient--insert-suffix (prefix loc suffix action)
- (let* ((suf (cl-etypecase suffix
- (vector (transient--parse-group prefix suffix))
- (list (transient--parse-suffix prefix suffix))
- (string suffix)))
- (mem (transient--layout-member loc prefix))
- (elt (car mem)))
- (cond
- ((not mem)
- (message "Cannot insert %S into %s; %s not found"
- suffix prefix loc))
- ((or (and (vectorp suffix) (not (vectorp elt)))
- (and (listp suffix) (vectorp elt))
- (and (stringp suffix) (vectorp elt)))
- (message "Cannot place %S into %s at %s; %s"
- suffix prefix loc
- "suffixes and groups cannot be siblings"))
- (t
- (when (and (listp suffix)
- (listp elt))
- (let ((key (plist-get (nth 2 suf) :key)))
- (if (equal (transient--kbd key)
- (transient--kbd (plist-get (nth 2 elt) :key)))
- (setq action 'replace)
- (transient-remove-suffix prefix key))))
- (cl-ecase action
- (insert (setcdr mem (cons elt (cdr mem)))
- (setcar mem suf))
- (append (setcdr mem (cons suf (cdr mem))))
- (replace (setcar mem suf)))))))
-
-(defun transient-insert-suffix (prefix loc suffix)
- "Insert a SUFFIX into PREFIX before LOC.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
- the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
- as returned by `key-description'), or a coordination list
- (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
- (declare (indent defun))
- (transient--insert-suffix prefix loc suffix 'insert))
-
-(defun transient-append-suffix (prefix loc suffix)
- "Insert a SUFFIX into PREFIX after LOC.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
- the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
- as returned by `key-description'), or a coordination list
- (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
- (declare (indent defun))
- (transient--insert-suffix prefix loc suffix 'append))
-
-(defun transient-replace-suffix (prefix loc suffix)
- "Replace the suffix at LOC in PREFIX with SUFFIX.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
- the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
- as returned by `key-description'), or a coordination list
- (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
- (declare (indent defun))
- (transient--insert-suffix prefix loc suffix 'replace))
-
-(defun transient-remove-suffix (prefix loc)
- "Remove the suffix or group at LOC in PREFIX.
-PREFIX is a prefix command, a symbol.
-LOC is a command, a key vector, a key description (a string
- as returned by `key-description'), or a coordination list
- (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
- (declare (indent defun))
- (transient--layout-member loc prefix 'remove))
-
-(defun transient-get-suffix (prefix loc)
- "Return the suffix or group at LOC in PREFIX.
-PREFIX is a prefix command, a symbol.
-LOC is a command, a key vector, a key description (a string
- as returned by `key-description'), or a coordination list
- (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
- (if-let ((mem (transient--layout-member loc prefix)))
- (car mem)
- (error "%s not found in %s" loc prefix)))
-
-(defun transient-suffix-put (prefix loc prop value)
- "Edit the suffix at LOC in PREFIX, setting PROP to VALUE.
-PREFIX is a prefix command, a symbol.
-SUFFIX is a suffix command or a group specification (of
- the same forms as expected by `define-transient-command').
-LOC is a command, a key vector, a key description (a string
- as returned by `key-description'), or a coordination list
- (whose last element may also be a command or key).
-See info node `(transient)Modifying Existing Transients'."
- (let ((suf (transient-get-suffix prefix loc)))
- (setf (elt suf 2)
- (plist-put (elt suf 2) prop value))))
-
-(defun transient--layout-member (loc prefix &optional remove)
- (let ((val (or (get prefix 'transient--layout)
- (error "%s is not a transient command" prefix))))
- (when (listp loc)
- (while (integerp (car loc))
- (let* ((children (if (vectorp val) (aref val 3) val))
- (mem (transient--nthcdr (pop loc) children)))
- (if (and remove (not loc))
- (let ((rest (delq (car mem) children)))
- (if (vectorp val)
- (aset val 3 rest)
- (put prefix 'transient--layout rest))
- (setq val nil))
- (setq val (if loc (car mem) mem)))))
- (setq loc (car loc)))
- (if loc
- (transient--layout-member-1 (transient--kbd loc) val remove)
- val)))
-
-(defun transient--layout-member-1 (loc layout remove)
- (cond ((listp layout)
- (--any (transient--layout-member-1 loc it remove) layout))
- ((vectorp (car (aref layout 3)))
- (--any (transient--layout-member-1 loc it remove) (aref layout 3)))
- (remove
- (aset layout 3
- (delq (car (transient--group-member loc layout))
- (aref layout 3)))
- nil)
- (t (transient--group-member loc layout))))
-
-(defun transient--group-member (loc group)
- (cl-member-if (lambda (suffix)
- (and (listp suffix)
- (let* ((def (nth 2 suffix))
- (cmd (plist-get def :command)))
- (if (symbolp loc)
- (eq cmd loc)
- (equal (transient--kbd
- (or (plist-get def :key)
- (transient--command-key cmd)))
- loc)))))
- (aref group 3)))
-
-(defun transient--kbd (keys)
- (when (vectorp keys)
- (setq keys (key-description keys)))
- (when (stringp keys)
- (setq keys (kbd keys)))
- keys)
-
-(defun transient--command-key (cmd)
- (when-let ((obj (get cmd 'transient--suffix)))
- (cond ((slot-boundp obj 'key)
- (oref obj key))
- ((slot-exists-p obj 'shortarg)
- (if (slot-boundp obj 'shortarg)
- (oref obj shortarg)
- (transient--derive-shortarg (oref obj argument)))))))
-
-(defun transient--nthcdr (n list)
- (nthcdr (if (< n 0) (- (length list) (abs n)) n) list))
-
-;;; Variables
-
-(defvar current-transient-prefix nil
- "The transient from which this suffix command was invoked.
-This is an object representing that transient, use
-`current-transient-command' to get the respective command.")
-
-(defvar current-transient-command nil
- "The transient from which this suffix command was invoked.
-This is a symbol representing that transient, use
-`current-transient-object' to get the respective object.")
-
-(defvar current-transient-suffixes nil
- "The suffixes of the transient from which this suffix command was invoked.
-This is a list of objects. Usually it is sufficient to instead
-use the function `transient-args', which returns a list of
-values. In complex cases it might be necessary to use this
-variable instead.")
-
-(defvar post-transient-hook nil
- "Hook run after exiting a transient.")
-
-(defvar transient--prefix nil)
-(defvar transient--layout nil)
-(defvar transient--suffixes nil)
-
-(defconst transient--stay t "Do not exist the transient.")
-(defconst transient--exit nil "Do exit the transient.")
-
-(defvar transient--exitp nil "Whether to exit the transient.")
-(defvar transient--showp nil "Whether the transient is show in a popup buffer.")
-(defvar transient--helpp nil "Whether help-mode is active.")
-(defvar transient--editp nil "Whether edit-mode is active.")
-
-(defvar transient--active-infix nil "The active infix awaiting user input.")
-
-(defvar transient--timer nil)
-
-(defvar transient--stack nil)
-
-(defvar transient--buffer-name " *transient*"
- "Name of the transient buffer.")
-
-(defvar transient--window nil
- "The window used to display the transient popup.")
-
-(defvar transient--original-window nil
- "The window that was selected before the transient was invoked.
-Usually it remains selected while the transient is active.")
-
-(define-obsolete-variable-alias 'transient--source-buffer
- 'transient--original-buffer "Transient 0.2.0")
-
-(defvar transient--original-buffer nil
- "The buffer that was current before the transient was invoked.
-Usually it remains current while the transient is active.")
-
-(defvar transient--debug nil "Whether put debug information into *Messages*.")
-
-(defvar transient--history nil)
-
-;;; Identities
-
-(defun transient-suffix-object (&optional command)
- "Return the object associated with the current suffix command.
-
-Each suffix commands is associated with an object, which holds
-additional information about the suffix, such as its value (in
-the case of an infix command, which is a kind of suffix command).
-
-This function is intended to be called by infix commands, whose
-command definition usually (at least when defined using
-`define-infix-command') is this:
-
- (lambda ()
- (interactive)
- (let ((obj (transient-suffix-object)))
- (transient-infix-set obj (transient-infix-read obj)))
- (transient--show))
-
-\(User input is read outside of `interactive' to prevent the
-command from being added to `command-history'. See #23.)
-
-Such commands need to be able to access their associated object
-to guide how `transient-infix-read' reads the new value and to
-store the read value. Other suffix commands (including non-infix
-commands) may also need the object to guide their behavior.
-
-This function attempts to return the object associated with the
-current suffix command even if the suffix command was not invoked
-from a transient. (For some suffix command that is a valid thing
-to do, for others it is not.) In that case nil may be returned
-if the command was not defined using one of the macros intended
-to define such commands.
-
-The optional argument COMMAND is intended for internal use. If
-you are contemplating using it in your own code, then you should
-probably use this instead:
-
- (get COMMAND 'transient--suffix)"
- (if transient--prefix
- (cl-find-if (lambda (obj)
- (eq (transient--suffix-command obj)
- (or command this-original-command)))
- transient--suffixes)
- (when-let ((obj (get (or command this-command) 'transient--suffix))
- (obj (clone obj)))
- (transient-init-scope obj)
- (transient-init-value obj)
- obj)))
-
-(defun transient--suffix-command (arg)
- "Return the command specified by ARG.
-
-Given a suffix specified by ARG, this function returns the
-respective command or a symbol that represents it. It could
-therefore be considered the inverse of `transient-suffix-object'.
-
-Unlike that function it is only intended for internal use though,
-and it is more complicated to describe because of some internal
-tricks it has to account for. You do not actually have to know
-any of this.
-
-ARG can be a `transient-suffix' object, a symbol representing a
-command, or a command (which can be either a fbound symbol or a
-lambda expression).
-
-If it is an object, then the value of its `command' slot is used
-as follows. If ARG satisfies `commandp', then that is returned.
-Otherwise it is assumed to be a symbol that merely represents the
-command. In that case the lambda expression that is stored in
-the symbols `transient--infix-command' property is returned.
-
-Therefore, if ARG is an object, then this function always returns
-something that is callable as a command.
-
-ARG can also be something that is callable as a function. If it
-is a symbol, then that is returned. Otherwise it is a lambda
-expression and a symbol that merely representing that command is
-returned.
-
-Therefore, if ARG is something that is callable as a command,
-then this function always returns a symbol that is, or merely
-represents that command.
-
-The reason that there are \"symbols that merely represent a
-command\" is that by avoiding binding a symbol as a command we
-can prevent it from being offered as a completion candidate for
-`execute-extended-command'. That is useful for infix arguments,
-which usually do not work correctly unless called from a
-transient. Unfortunately this only works for infix arguments
-that are defined inline in the definition of a transient prefix
-command; explicitly defined infix arguments continue to pollute
-the command namespace. It would be better if all this were made
-unnecessary by a `execute-extended-command-ignore' symbol property
-but unfortunately that does not exist (yet?)."
- (if (transient-suffix--eieio-childp arg)
- (let ((sym (oref arg command)))
- (if (commandp sym)
- sym
- (get sym 'transient--infix-command)))
- (if (symbolp arg)
- arg
- ;; ARG is an interactive lambda. The symbol returned by this
- ;; is not actually a command, just a symbol representing it
- ;; for purposes other than invoking it as a command.
- (oref (transient-suffix-object) command))))
-
-;;; Keymaps
-
-(defvar transient-base-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "ESC ESC ESC") 'transient-quit-all)
- (define-key map (kbd "C-g") 'transient-quit-one)
- (define-key map (kbd "C-q") 'transient-quit-all)
- (define-key map (kbd "C-z") 'transient-suspend)
- (define-key map (kbd "C-v") 'transient-scroll-up)
- (define-key map (kbd "M-v") 'transient-scroll-down)
- (define-key map [next] 'transient-scroll-up)
- (define-key map [prior] 'transient-scroll-down)
- map)
- "Parent of other keymaps used by Transient.
-
-This is the parent keymap of all the keymaps that are used in
-all transients: `transient-map' (which in turn is the parent
-of the transient-specific keymaps), `transient-edit-map' and
-`transient-sticky-map'.
-
-If you change a binding here, then you might also have to edit
-`transient-sticky-map' and `transient-common-commands'. While
-the latter isn't a proper transient prefix command, it can be
-edited using the same functions as used for transients.")
-
-(defvar transient-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map transient-base-map)
- (define-key map (kbd "C-p") 'universal-argument)
- (define-key map (kbd "C--") 'negative-argument)
- (define-key map (kbd "C-t") 'transient-show)
- (define-key map (kbd "?") 'transient-help)
- (define-key map (kbd "C-h") 'transient-help)
- (define-key map (kbd "M-p") 'transient-history-prev)
- (define-key map (kbd "M-n") 'transient-history-next)
- map)
- "Top-level keymap used by all transients.")
-
-(defvar transient-edit-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map transient-base-map)
- (define-key map (kbd "?") 'transient-help)
- (define-key map (kbd "C-h") 'transient-help)
- (define-key map (kbd "C-x l") 'transient-set-level)
- map)
- "Keymap that is active while a transient in is in \"edit mode\".")
-
-(defvar transient-sticky-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map transient-base-map)
- (define-key map (kbd "C-g") 'transient-quit-seq)
- map)
- "Keymap that is active while an incomplete key sequence is active.")
-
-(defvar transient--common-command-prefixes '(?\C-x))
-
-(put 'transient-common-commands
- 'transient--layout
- (cl-mapcan
- (lambda (s) (transient--parse-child 'transient-common-commands s))
- '([:hide (lambda ()
- (and (not (memq (car transient--redisplay-key)
- transient--common-command-prefixes))
- (not transient-show-common-commands)))
- ["Value commands"
- ("C-x s " "Set" transient-set)
- ("C-x C-s" "Save" transient-save)
- ("M-p " "Previous value" transient-history-prev)
- ("M-n " "Next value" transient-history-next)]
- ["Sticky commands"
- ;; Like `transient-sticky-map' except that
- ;; "C-g" has to be bound to a different command.
- ("C-g" "Quit prefix or transient" transient-quit-one)
- ("C-q" "Quit transient stack" transient-quit-all)
- ("C-z" "Suspend transient stack" transient-suspend)]
- ["Customize"
- ("C-x t" transient-toggle-common
- :description (lambda ()
- (if transient-show-common-commands
- "Hide common commands"
- "Show common permanently")))
- ("C-x l" "Show/hide suffixes" transient-set-level)]])))
-
-(defvar transient-predicate-map
- (let ((map (make-sparse-keymap)))
- (define-key map [handle-switch-frame] 'transient--do-suspend)
- (define-key map [transient-suspend] 'transient--do-suspend)
- (define-key map [transient-help] 'transient--do-stay)
- (define-key map [transient-set-level] 'transient--do-stay)
- (define-key map [transient-history-prev] 'transient--do-stay)
- (define-key map [transient-history-next] 'transient--do-stay)
- (define-key map [universal-argument] 'transient--do-stay)
- (define-key map [negative-argument] 'transient--do-stay)
- (define-key map [digit-argument] 'transient--do-stay)
- (define-key map [transient-quit-all] 'transient--do-quit-all)
- (define-key map [transient-quit-one] 'transient--do-quit-one)
- (define-key map [transient-quit-seq] 'transient--do-stay)
- (define-key map [transient-show] 'transient--do-stay)
- (define-key map [transient-update] 'transient--do-stay)
- (define-key map [transient-toggle-common] 'transient--do-stay)
- (define-key map [transient-set] 'transient--do-call)
- (define-key map [transient-save] 'transient--do-call)
- (define-key map [describe-key-briefly] 'transient--do-stay)
- (define-key map [describe-key] 'transient--do-stay)
- (define-key map [transient-scroll-up] 'transient--do-stay)
- (define-key map [transient-scroll-down] 'transient--do-stay)
- (define-key map [mwheel-scroll] 'transient--do-stay)
- (define-key map [transient-noop] 'transient--do-noop)
- (define-key map [transient-mouse-push-button] 'transient--do-move)
- (define-key map [transient-push-button] 'transient--do-move)
- (define-key map [transient-backward-button] 'transient--do-move)
- (define-key map [transient-forward-button] 'transient--do-move)
- (define-key map [transient-isearch-backward] 'transient--do-move)
- (define-key map [transient-isearch-forward] 'transient--do-move)
- map)
- "Base keymap used to map common commands to their transient behavior.
-
-The \"transient behavior\" of a command controls, among other
-things, whether invoking the command causes the transient to be
-exited or not and whether infix arguments are exported before
-doing so.
-
-Each \"key\" is a command that is common to all transients and
-that is bound in `transient-map', `transient-edit-map',
-`transient-sticky-map' and/or `transient-common-command'.
-
-Each binding is a \"pre-command\", a function that controls the
-transient behavior of the respective command.
-
-For transient commands that are bound in individual transients,
-the transient behavior is specified using the `:transient' slot
-of the corresponding object.")
-
-(defvar transient-popup-navigation-map)
-
-(defvar transient--transient-map nil)
-(defvar transient--predicate-map nil)
-(defvar transient--redisplay-map nil)
-(defvar transient--redisplay-key nil)
-
-(defun transient--push-keymap (map)
- (transient--debug " push %s%s" map (if (symbol-value map) "" " VOID"))
- (with-demoted-errors "transient--push-keymap: %S"
- (internal-push-keymap (symbol-value map) 'overriding-terminal-local-map)))
-
-(defun transient--pop-keymap (map)
- (transient--debug " pop %s%s" map (if (symbol-value map) "" " VOID"))
- (with-demoted-errors "transient--pop-keymap: %S"
- (internal-pop-keymap (symbol-value map) 'overriding-terminal-local-map)))
-
-(defun transient--make-transient-map ()
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map (if transient--editp
- transient-edit-map
- transient-map))
- (dolist (obj transient--suffixes)
- (let ((key (oref obj key)))
- (when (vectorp key)
- (setq key (key-description key))
- (oset obj key key))
- (when transient-substitute-key-function
- (setq key (save-match-data
- (funcall transient-substitute-key-function obj)))
- (oset obj key key))
- (let ((kbd (kbd key))
- (cmd (transient--suffix-command obj)))
- (when-let ((conflict (and transient-detect-key-conflicts
- (transient--lookup-key map kbd))))
- (unless (eq cmd conflict)
- (error "Cannot bind %S to %s and also %s"
- (string-trim key)
- cmd conflict)))
- (define-key map kbd cmd))))
- (when transient-enable-popup-navigation
- (setq map
- (make-composed-keymap (list map transient-popup-navigation-map))))
- map))
-
-(defun transient--make-predicate-map ()
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map transient-predicate-map)
- (dolist (obj transient--suffixes)
- (let* ((cmd (transient--suffix-command obj))
- (sub-prefix (and (symbolp cmd) (get cmd 'transient--prefix))))
- (if (slot-boundp obj 'transient)
- (define-key map (vector cmd)
- (let ((do (oref obj transient)))
- (pcase do
- (`t (if sub-prefix
- 'transient--do-replace
- 'transient--do-stay))
- (`nil 'transient--do-exit)
- (_ do))))
- (unless (lookup-key transient-predicate-map (vector cmd))
- (define-key map (vector cmd)
- (if sub-prefix
- 'transient--do-replace
- (or (oref transient--prefix transient-suffix)
- 'transient--do-exit)))))))
- map))
-
-(defun transient--make-redisplay-map ()
- (setq transient--redisplay-key
- (cl-case this-command
- (transient-update
- (setq transient--showp t)
- (setq unread-command-events
- (listify-key-sequence (this-single-command-raw-keys))))
- (transient-quit-seq
- (setq unread-command-events
- (butlast (listify-key-sequence
- (this-single-command-raw-keys))
- 2))
- (butlast transient--redisplay-key))
- (t nil)))
- (let ((topmap (make-sparse-keymap))
- (submap (make-sparse-keymap)))
- (when transient--redisplay-key
- (define-key topmap (vconcat transient--redisplay-key) submap)
- (set-keymap-parent submap transient-sticky-map))
- (map-keymap-internal
- (lambda (key def)
- (when (and (not (eq key ?\e))
- (listp def)
- (keymapp def))
- (define-key topmap (vconcat transient--redisplay-key (list key))
- 'transient-update)))
- (if transient--redisplay-key
- (lookup-key transient--transient-map (vconcat transient--redisplay-key))
- transient--transient-map))
- topmap))
-
-;;; Setup
-
-(defun transient-setup (&optional name layout edit &rest params)
- "Setup the transient specified by NAME.
-
-This function is called by transient prefix commands to setup the
-transient. In that case NAME is mandatory, LAYOUT and EDIT must
-be nil and PARAMS may be (but usually is not) used to set e.g. the
-\"scope\" of the transient (see `transient-define-prefix').
-
-This function is also called internally in which case LAYOUT and
-EDIT may be non-nil."
- (transient--debug 'setup)
- (cond
- ((not name)
- ;; Switching between regular and edit mode.
- (transient--pop-keymap 'transient--transient-map)
- (transient--pop-keymap 'transient--redisplay-map)
- (setq name (oref transient--prefix command))
- (setq params (list :scope (oref transient--prefix scope))))
- ((not (or layout ; resuming parent/suspended prefix
- current-transient-command)) ; entering child prefix
- (transient--stack-zap)) ; replace suspended prefix, if any
- (edit
- ;; Returning from help to edit.
- (setq transient--editp t)))
- (transient--init-objects name layout params)
- (transient--history-init transient--prefix)
- (setq transient--predicate-map (transient--make-predicate-map))
- (setq transient--transient-map (transient--make-transient-map))
- (setq transient--redisplay-map (transient--make-redisplay-map))
- (setq transient--original-window (selected-window))
- (setq transient--original-buffer (current-buffer))
- (transient--redisplay)
- (transient--init-transient)
- (transient--suspend-which-key-mode))
-
-(defun transient--init-objects (name layout params)
- (setq transient--prefix
- (let ((proto (get name 'transient--prefix)))
- (apply #'clone proto
- :prototype proto
- :level (or (alist-get
- t (alist-get name transient-levels))
- transient-default-level)
- params)))
- (transient-init-value transient--prefix)
- (setq transient--layout
- (or layout
- (let ((levels (alist-get name transient-levels)))
- (cl-mapcan (lambda (c) (transient--init-child levels c))
- (append (get name 'transient--layout)
- (and (not transient--editp)
- (get 'transient-common-commands
- 'transient--layout)))))))
- (setq transient--suffixes
- (cl-labels ((s (def)
- (cond
- ((stringp def) nil)
- ((listp def) (cl-mapcan #'s def))
- ((transient-group--eieio-childp def)
- (cl-mapcan #'s (oref def suffixes)))
- ((transient-suffix--eieio-childp def)
- (list def)))))
- (cl-mapcan #'s transient--layout))))
-
-(defun transient--init-child (levels spec)
- (cl-etypecase spec
- (vector (transient--init-group levels spec))
- (list (transient--init-suffix levels spec))
- (string (list spec))))
-
-(defun transient--init-group (levels spec)
- (pcase-let ((`(,level ,class ,args ,children) (append spec nil)))
- (when (transient--use-level-p level)
- (let ((obj (apply class :level level args)))
- (when (transient--use-suffix-p obj)
- (when-let ((suffixes
- (cl-mapcan (lambda (c) (transient--init-child levels c))
- children)))
- (oset obj suffixes suffixes)
- (list obj)))))))
-
-(defun transient--init-suffix (levels spec)
- (pcase-let* ((`(,level ,class ,args) spec)
- (cmd (plist-get args :command))
- (level (or (alist-get (transient--suffix-command cmd) levels)
- level)))
- (let ((fn (and (symbolp cmd)
- (symbol-function cmd))))
- (when (autoloadp fn)
- (transient--debug " autoload %s" cmd)
- (autoload-do-load fn)))
- (when (transient--use-level-p level)
- (let ((obj (if-let ((proto (and cmd
- (symbolp cmd)
- (get cmd 'transient--suffix))))
- (apply #'clone proto :level level args)
- (apply class :level level args))))
- (transient--init-suffix-key obj)
- (transient--ensure-infix-command obj)
- (when (transient--use-suffix-p obj)
- (transient-init-scope obj)
- (transient-init-value obj)
- (list obj))))))
-
-(cl-defmethod transient--init-suffix-key ((obj transient-suffix))
- (unless (slot-boundp obj 'key)
- (error "No key for %s" (oref obj command))))
-
-(cl-defmethod transient--init-suffix-key ((obj transient-argument))
- (if (transient-switches--eieio-childp obj)
- (cl-call-next-method obj)
- (unless (slot-boundp obj 'shortarg)
- (when-let ((shortarg (transient--derive-shortarg (oref obj argument))))
- (oset obj shortarg shortarg)))
- (unless (slot-boundp obj 'key)
- (if (slot-boundp obj 'shortarg)
- (oset obj key (oref obj shortarg))
- (error "No key for %s" (oref obj command))))))
-
-(defun transient--use-level-p (level &optional edit)
- (or (and transient--editp (not edit))
- (and (>= level 1)
- (<= level (oref transient--prefix level)))))
-
-(defun transient--use-suffix-p (obj)
- (with-slots
- (if if-not if-nil if-non-nil if-mode if-not-mode if-derived if-not-derived)
- obj
- (cond
- (if (funcall if))
- (if-not (not (funcall if-not)))
- (if-non-nil (symbol-value if-non-nil))
- (if-nil (not (symbol-value if-nil)))
- (if-mode (if (atom if-mode)
- (eq major-mode if-mode)
- (memq major-mode if-mode)))
- (if-not-mode (not (if (atom if-not-mode)
- (eq major-mode if-not-mode)
- (memq major-mode if-not-mode))))
- (if-derived (if (atom if-derived)
- (derived-mode-p if-derived)
- (apply #'derived-mode-p if-derived)))
- (if-not-derived (not (if (atom if-not-derived)
- (derived-mode-p if-not-derived)
- (apply #'derived-mode-p if-not-derived))))
- (t))))
-
-;;; Flow-Control
-
-(defun transient--init-transient ()
- (transient--debug 'init-transient)
- (transient--push-keymap 'transient--transient-map)
- (transient--push-keymap 'transient--redisplay-map)
- (add-hook 'pre-command-hook #'transient--pre-command)
- (add-hook 'minibuffer-setup-hook #'transient--minibuffer-setup)
- (add-hook 'minibuffer-exit-hook #'transient--minibuffer-exit)
- (add-hook 'post-command-hook #'transient--post-command)
- (advice-add 'abort-recursive-edit :after #'transient--minibuffer-exit)
- (when transient--exitp
- ;; This prefix command was invoked as the suffix of another.
- ;; Prevent `transient--post-command' from removing the hooks
- ;; that we just added.
- (setq transient--exitp 'replace)))
-
-(defun transient--pre-command ()
- (transient--debug 'pre-command)
- (cond
- ((memq this-command '(transient-update transient-quit-seq))
- (transient--pop-keymap 'transient--redisplay-map))
- ((and transient--helpp
- (not (memq this-command '(transient-quit-one
- transient-quit-all))))
- (cond
- ((transient-help)
- (transient--do-suspend)
- (setq this-command 'transient-suspend)
- (transient--pre-exit))
- (t
- (setq this-command 'transient-undefined))))
- ((and transient--editp
- (transient-suffix-object)
- (not (memq this-command '(transient-quit-one
- transient-quit-all
- transient-help))))
- (setq this-command 'transient-set-level))
- (t
- (setq transient--exitp nil)
- (when (eq (if-let ((fn (or (lookup-key transient--predicate-map
- (vector this-original-command))
- (oref transient--prefix transient-non-suffix))))
- (let ((action (funcall fn)))
- (when (eq action transient--exit)
- (setq transient--exitp (or transient--exitp t)))
- action)
- (setq this-command
- (let ((keys (this-command-keys-vector)))
- (if (eq (aref keys (1- (length keys))) ?\C-g)
- 'transient-noop
- 'transient-undefined)))
- transient--stay)
- transient--exit)
- (transient--pre-exit)))))
-
-(defun transient--pre-exit ()
- (transient--debug 'pre-exit)
- (transient--delete-window)
- (transient--timer-cancel)
- (transient--pop-keymap 'transient--transient-map)
- (transient--pop-keymap 'transient--redisplay-map)
- (remove-hook 'pre-command-hook #'transient--pre-command)
- (unless transient--showp
- (message ""))
- (setq transient--transient-map nil)
- (setq transient--predicate-map nil)
- (setq transient--redisplay-map nil)
- (setq transient--redisplay-key nil)
- (setq transient--showp nil)
- (setq transient--helpp nil)
- (setq transient--editp nil)
- (setq transient--prefix nil)
- (setq transient--layout nil)
- (setq transient--suffixes nil)
- (setq transient--original-window nil)
- (setq transient--original-buffer nil)
- (setq transient--window nil))
-
-(defun transient--delete-window ()
- (when (window-live-p transient--window)
- (let ((buf (window-buffer transient--window)))
- (with-demoted-errors "Error while exiting transient: %S"
- (delete-window transient--window))
- (kill-buffer buf))))
-
-(defun transient--export ()
- (setq current-transient-prefix transient--prefix)
- (setq current-transient-command (oref transient--prefix command))
- (setq current-transient-suffixes transient--suffixes)
- (transient--history-push transient--prefix))
-
-(defun transient--minibuffer-setup ()
- (transient--debug 'minibuffer-setup)
- (unless (> (minibuffer-depth) 1)
- (unless transient--exitp
- (transient--pop-keymap 'transient--transient-map)
- (transient--pop-keymap 'transient--redisplay-map)
- (remove-hook 'pre-command-hook #'transient--pre-command))
- (remove-hook 'post-command-hook #'transient--post-command)))
-
-(defun transient--minibuffer-exit ()
- (transient--debug 'minibuffer-exit)
- (unless (> (minibuffer-depth) 1)
- (unless transient--exitp
- (transient--push-keymap 'transient--transient-map)
- (transient--push-keymap 'transient--redisplay-map)
- (add-hook 'pre-command-hook #'transient--pre-command))
- (add-hook 'post-command-hook #'transient--post-command)))
-
-(defun transient--post-command ()
- (transient--debug 'post-command)
- (if transient--exitp
- (progn
- (unless (and (eq transient--exitp 'replace)
- (or transient--prefix
- ;; The current command could act as a prefix,
- ;; but decided not to call `transient-setup'.
- (prog1 nil (transient--stack-zap))))
- (remove-hook 'minibuffer-setup-hook #'transient--minibuffer-setup)
- (remove-hook 'minibuffer-exit-hook #'transient--minibuffer-exit)
- (advice-remove 'abort-recursive-edit #'transient--minibuffer-exit)
- (remove-hook 'post-command-hook #'transient--post-command))
- (setq current-transient-prefix nil)
- (setq current-transient-command nil)
- (setq current-transient-suffixes nil)
- (let ((resume (and transient--stack
- (not (memq transient--exitp '(replace suspend))))))
- (setq transient--exitp nil)
- (setq transient--helpp nil)
- (setq transient--editp nil)
- (run-hooks 'post-transient-hook)
- (when resume
- (transient--stack-pop))))
- (transient--pop-keymap 'transient--redisplay-map)
- (setq transient--redisplay-map (transient--make-redisplay-map))
- (transient--push-keymap 'transient--redisplay-map)
- (unless (eq this-command (oref transient--prefix command))
- (transient--redisplay))))
-
-(defun transient--stack-push ()
- (transient--debug 'stack-push)
- (push (list (oref transient--prefix command)
- transient--layout
- transient--editp
- :scope (oref transient--prefix scope))
- transient--stack))
-
-(defun transient--stack-pop ()
- (transient--debug 'stack-pop)
- (and transient--stack
- (prog1 t (apply #'transient-setup (pop transient--stack)))))
-
-(defun transient--stack-zap ()
- (transient--debug 'stack-zap)
- (setq transient--stack nil))
-
-(defun transient--redisplay ()
- (if (or (eq transient-show-popup t)
- transient--showp)
- (unless (memq this-command '(transient-scroll-up
- transient-scroll-down
- mwheel-scroll))
- (transient--show))
- (when (and (numberp transient-show-popup)
- (not (zerop transient-show-popup))
- (not transient--timer))
- (transient--timer-start))
- (transient--show-brief)))
-
-(defun transient--timer-start ()
- (setq transient--timer
- (run-at-time (abs transient-show-popup) nil
- (lambda ()
- (transient--timer-cancel)
- (transient--show)
- (let ((message-log-max nil))
- (message ""))))))
-
-(defun transient--timer-cancel ()
- (when transient--timer
- (cancel-timer transient--timer)
- (setq transient--timer nil)))
-
-(defun transient--debug (arg &rest args)
- (when transient--debug
- (if (symbolp arg)
- (message "-- %-16s (cmd: %s, exit: %s)"
- arg this-command transient--exitp)
- (apply #'message arg args))))
-
-(defun transient--emergency-exit ()
- "Exit the current transient command after an error occured.
-Beside being used with `condition-case', this function also has
-to be a member of `debugger-mode-hook', else the debugger would
-be unusable and exiting it by pressing \"q\" would fail because
-the transient command would still be active and that key would
-either be unbound or do something else."
- (when transient--prefix
- (setq transient--stack nil)
- (setq transient--exitp t)
- (transient--pre-exit)
- (transient--post-command)))
-
-(add-hook 'debugger-mode-hook 'transient--emergency-exit)
-
-(defmacro transient--with-emergency-exit (&rest body)
- (declare (indent defun))
- `(condition-case nil
- ,(macroexp-progn body)
- (error (transient--emergency-exit))))
-
-;;; Pre-Commands
-
-(defun transient--do-stay ()
- "Call the command without exporting variables and stay transient."
- transient--stay)
-
-(defun transient--do-noop ()
- "Call `transient-noop' and stay transient."
- (setq this-command 'transient-noop)
- transient--stay)
-
-(defun transient--do-warn ()
- "Call `transient-undefined' and stay transient."
- (setq this-command 'transient-undefined)
- transient--stay)
-
-(defun transient--do-call ()
- "Call the command after exporting variables and stay transient."
- (transient--export)
- transient--stay)
-
-(defun transient--do-exit ()
- "Call the command after exporting variables and exit the transient."
- (transient--export)
- (transient--stack-zap)
- transient--exit)
-
-(defun transient--do-replace ()
- "Call the transient prefix command, replacing the active transient."
- (transient--export)
- (transient--stack-push)
- (setq transient--exitp 'replace)
- transient--exit)
-
-(defun transient--do-suspend ()
- "Suspend the active transient, saving the transient stack."
- (transient--stack-push)
- (setq transient--exitp 'suspend)
- transient--exit)
-
-(defun transient--do-quit-one ()
- "If active, quit help or edit mode, else exit the active transient."
- (cond (transient--helpp
- (setq transient--helpp nil)
- transient--stay)
- (transient--editp
- (setq transient--editp nil)
- (transient-setup)
- transient--stay)
- (t transient--exit)))
-
-(defun transient--do-quit-all ()
- "Exit all transients without saving the transient stack."
- (transient--stack-zap)
- transient--exit)
-
-(defun transient--do-move ()
- "Call the command if `transient-enable-popup-navigation' is non-nil.
-In that case behave like `transient--do-stay', otherwise similar
-to `transient--do-warn'."
- (unless transient-enable-popup-navigation
- (setq this-command 'transient-popup-navigation-help))
- transient--stay)
-
-;;; Commands
-
-(defun transient-noop ()
- "Do nothing at all."
- (interactive))
-
-(defun transient-undefined ()
- "Warn the user that the pressed key is not bound to any suffix."
- (interactive)
- (message "Unbound suffix: `%s' (Use `%s' to abort, `%s' for help)"
- (propertize (key-description (this-single-command-keys))
- 'face 'font-lock-warning-face)
- (propertize "C-g" 'face 'transient-key)
- (propertize "?" 'face 'transient-key)))
-
-(defun transient-toggle-common ()
- "Toggle whether common commands are always shown."
- (interactive)
- (setq transient-show-common-commands (not transient-show-common-commands)))
-
-(defun transient-suspend ()
- "Suspend the current transient.
-It can later be resumed using `transient-resume' while no other
-transient is active."
- (interactive))
-
-(defun transient-quit-all ()
- "Exit all transients without saving the transient stack."
- (interactive))
-
-(defun transient-quit-one ()
- "Exit the current transients, possibly returning to the previous."
- (interactive))
-
-(defun transient-quit-seq ()
- "Abort the current incomplete key sequence."
- (interactive))
-
-(defun transient-update ()
- "Redraw the transient's state in the popup buffer."
- (interactive))
-
-(defun transient-show ()
- "Show the transient's state in the popup buffer."
- (interactive)
- (setq transient--showp t))
-
-(defvar-local transient--restore-winconf nil)
-
-(defvar transient-resume-mode)
-
-(defun transient-help ()
- "Show help for the active transient or one of its suffixes."
- (interactive)
- (if (called-interactively-p 'any)
- (setq transient--helpp t)
- (with-demoted-errors "transient-help: %S"
- (when (lookup-key transient--transient-map
- (this-single-command-raw-keys))
- (setq transient--helpp nil)
- (let ((winconf (current-window-configuration)))
- (transient-show-help
- (if (eq this-original-command 'transient-help)
- transient--prefix
- (or (transient-suffix-object)
- this-original-command)))
- (setq transient--restore-winconf winconf))
- (fit-window-to-buffer nil (frame-height) (window-height))
- (transient-resume-mode)
- (message "Type \"q\" to resume transient command.")
- t))))
-
-(defun transient-set-level (&optional command level)
- "Set the level of the transient or one of its suffix commands."
- (interactive
- (let ((command this-original-command)
- (prefix (oref transient--prefix command)))
- (and (or (not (eq command 'transient-set-level))
- (and transient--editp
- (setq command prefix)))
- (list command
- (let ((keys (this-single-command-raw-keys)))
- (and (lookup-key transient--transient-map keys)
- (string-to-number
- (transient--read-number-N
- (format "Set level for `%s': "
- (transient--suffix-command command))
- nil nil (not (eq command prefix))))))))))
- (cond
- ((not command)
- (setq transient--editp t)
- (transient-setup))
- (level
- (let* ((prefix (oref transient--prefix command))
- (alist (alist-get prefix transient-levels))
- (key (transient--suffix-command command)))
- (if (eq command prefix)
- (progn (oset transient--prefix level level)
- (setq key t))
- (oset (transient-suffix-object command) level level))
- (setf (alist-get key alist) level)
- (setf (alist-get prefix transient-levels) alist))
- (transient-save-levels))
- (t
- (transient-undefined))))
-
-(defun transient-set ()
- "Save the value of the active transient for this Emacs session."
- (interactive)
- (transient-set-value (or transient--prefix current-transient-prefix)))
-
-(defun transient-save ()
- "Save the value of the active transient persistenly across Emacs sessions."
- (interactive)
- (transient-save-value (or transient--prefix current-transient-prefix)))
-
-(defun transient-history-next ()
- "Switch to the next value used for the active transient."
- (interactive)
- (let* ((obj transient--prefix)
- (pos (1- (oref obj history-pos)))
- (hst (oref obj history)))
- (if (< pos 0)
- (user-error "End of history")
- (oset obj history-pos pos)
- (oset obj value (nth pos hst))
- (mapc #'transient-init-value transient--suffixes))))
-
-(defun transient-history-prev ()
- "Switch to the previous value used for the active transient."
- (interactive)
- (let* ((obj transient--prefix)
- (pos (1+ (oref obj history-pos)))
- (hst (oref obj history))
- (len (length hst)))
- (if (> pos (1- len))
- (user-error "End of history")
- (oset obj history-pos pos)
- (oset obj value (nth pos hst))
- (mapc #'transient-init-value transient--suffixes))))
-
-(defun transient-scroll-up (&optional arg)
- "Scroll text of transient popup window upward ARG lines.
-If ARG is nil scroll near full screen. This is a wrapper
-around `scroll-up-command' (which see)."
- (interactive "^P")
- (with-selected-window transient--window
- (scroll-up-command arg)))
-
-(defun transient-scroll-down (&optional arg)
- "Scroll text of transient popup window down ARG lines.
-If ARG is nil scroll near full screen. This is a wrapper
-around `scroll-down-command' (which see)."
- (interactive "^P")
- (with-selected-window transient--window
- (scroll-down-command arg)))
-
-(defun transient-resume ()
- "Resume a previously suspended stack of transients."
- (interactive)
- (cond (transient--stack
- (let ((winconf transient--restore-winconf))
- (kill-local-variable 'transient--restore-winconf)
- (when transient-resume-mode
- (transient-resume-mode -1)
- (quit-window))
- (when winconf
- (set-window-configuration winconf)))
- (transient--stack-pop))
- (transient-resume-mode
- (kill-local-variable 'transient--restore-winconf)
- (transient-resume-mode -1)
- (quit-window))
- (t
- (message "No suspended transient command"))))
-
-;;; Value
-;;;; Init
-
-(cl-defgeneric transient-init-scope (obj)
- "Set the scope of the suffix object OBJ.
-
-The scope is actually a property of the transient prefix, not of
-individual suffixes. However it is possible to invoke a suffix
-command directly instead of from a transient. In that case, if
-the suffix expects a scope, then it has to determine that itself
-and store it in its `scope' slot.
-
-This function is called for all suffix commands, but unless a
-concrete method is implemented this falls through to the default
-implementation, which is a noop.")
-
-(cl-defmethod transient-init-scope ((_ transient-suffix))
- "Noop." nil)
-
-(cl-defgeneric transient-init-value (_)
- "Set the initial value of the object OBJ.
-
-This function is called for all prefix and suffix commands.
-
-For suffix commands (including infix argument commands) the
-default implementation is a noop. Classes derived from the
-abstract `transient-infix' class must implement this function.
-Non-infix suffix commands usually don't have a value."
- nil)
-
-(cl-defmethod transient-init-value ((obj transient-prefix))
- (if (slot-boundp obj 'value)
- (let ((value (oref obj value)))
- (when (functionp value)
- (oset obj value (funcall value))))
- (oset obj value
- (if-let ((saved (assq (oref obj command) transient-values)))
- (cdr saved)
- nil))))
-
-(cl-defmethod transient-init-value ((obj transient-switch))
- (oset obj value
- (car (member (oref obj argument)
- (oref transient--prefix value)))))
-
-(cl-defmethod transient-init-value ((obj transient-option))
- (oset obj value
- (transient--value-match (format "\\`%s\\(.*\\)" (oref obj argument)))))
-
-(cl-defmethod transient-init-value ((obj transient-switches))
- (oset obj value
- (transient--value-match (oref obj argument-regexp))))
-
-(defun transient--value-match (re)
- (when-let ((match (cl-find-if (lambda (v)
- (and (stringp v)
- (string-match re v)))
- (oref transient--prefix value))))
- (match-string 1 match)))
-
-(cl-defmethod transient-init-value ((obj transient-files))
- (oset obj value
- (cdr (assoc "--" (oref transient--prefix value)))))
-
-;;;; Read
-
-(cl-defgeneric transient-infix-read (obj)
- "Determine the new value of the infix object OBJ.
-
-This function merely determines the value; `transient-infix-set'
-is used to actually store the new value in the object.
-
-For most infix classes this is done by reading a value from the
-user using the reader specified by the `reader' slot (using the
-`transient-infix' method described below).
-
-For some infix classes the value is changed without reading
-anything in the minibuffer, i.e. the mere act of invoking the
-infix command determines what the new value should be, based
-on the previous value.")
-
-(cl-defmethod transient-infix-read :around ((obj transient-infix))
- "Highlight the infix in the popup buffer.
-
-Also arrange for the transient to be exited in case of an error
-because otherwise Emacs would get stuck in an inconsistent state,
-which might make it necessary to kill it from the outside."
- (let ((transient--active-infix obj))
- (transient--show))
- (transient--with-emergency-exit
- (cl-call-next-method obj)))
-
-(cl-defmethod transient-infix-read ((obj transient-infix))
- "Read a value while taking care of history.
-
-This method is suitable for a wide variety of infix commands,
-including but not limitted to inline arguments and variables.
-
-If you do not use this method for your own infix class, then
-you should likely replicate a lot of the behavior of this
-method. If you fail to do so, then users might not appreciate
-the lack of history, for example.
-
-Only for very simple classes that toggle or cycle through a very
-limitted number of possible values should you replace this with a
-simple method that does not handle history. (E.g. for a command
-line switch the only possible values are \"use it\" and \"don't use
-it\", in which case it is pointless to preserve history.)"
- (with-slots (value multi-value allow-empty choices) obj
- (if (and value
- (not multi-value)
- (not allow-empty)
- transient--prefix)
- (oset obj value nil)
- (let* ((overriding-terminal-local-map nil)
- (reader (oref obj reader))
- (prompt (transient-prompt obj))
- (value (if multi-value (mapconcat #'identity value ",") value))
- (history-key (or (oref obj history-key)
- (oref obj command)))
- (transient--history (alist-get history-key transient-history))
- (transient--history (if (or (null value)
- (eq value (car transient--history)))
- transient--history
- (cons value transient--history)))
- (initial-input (and transient-read-with-initial-input
- (car transient--history)))
- (history (cons 'transient--history (if initial-input 1 0)))
- (value
- (cond
- (reader (funcall reader prompt initial-input history))
- (multi-value
- (completing-read-multiple prompt choices nil nil
- initial-input history))
- (choices
- (completing-read prompt choices nil t initial-input history))
- (t (read-string prompt initial-input history)))))
- (cond ((and (equal value "") (not allow-empty))
- (setq value nil))
- ((and (equal value "\"\"") allow-empty)
- (setq value "")))
- (when value
- (setf (alist-get history-key transient-history)
- (delete-dups transient--history)))
- value))))
-
-(cl-defmethod transient-infix-read ((obj transient-switch))
- "Toggle the switch on or off."
- (if (oref obj value) nil (oref obj argument)))
-
-(cl-defmethod transient-infix-read ((obj transient-switches))
- "Cycle through the mutually exclusive switches.
-The last value is \"don't use any of these switches\"."
- (let ((choices (mapcar (apply-partially #'format (oref obj argument-format))
- (oref obj choices))))
- (if-let ((value (oref obj value)))
- (cadr (member value choices))
- (car choices))))
-
-;;;; Readers
-
-(defun transient-read-directory (prompt _initial-input _history)
- "Read a directory."
- (expand-file-name (read-directory-name prompt)))
-
-(defun transient-read-existing-directory (prompt _initial-input _history)
- "Read an existing directory."
- (expand-file-name (read-directory-name prompt nil nil t)))
-
-(defun transient-read-number-N0 (prompt initial-input history)
- "Read a natural number (including zero) and return it as a string."
- (transient--read-number-N prompt initial-input history t))
-
-(defun transient-read-number-N+ (prompt initial-input history)
- "Read a natural number (excluding zero) and return it as a string."
- (transient--read-number-N prompt initial-input history nil))
-
-(defun transient--read-number-N (prompt initial-input history include-zero)
- (save-match-data
- (cl-block nil
- (while t
- (let ((str (read-from-minibuffer prompt initial-input nil nil history)))
- (cond ((string-equal str "")
- (cl-return nil))
- ((string-match-p (if include-zero
- "\\`\\(0\\|[1-9][0-9]*\\)\\'"
- "\\`[1-9][0-9]*\\'")
- str)
- (cl-return str))))
- (message "Please enter a natural number (%s zero)."
- (if include-zero "including" "excluding"))
- (sit-for 1)))))
-
-(defun transient-read-date (prompt default-time _history)
- "Read a date using `org-read-date' (which see)."
- (require 'org)
- (when (fboundp 'org-read-date)
- (org-read-date 'with-time nil nil prompt default-time)))
-
-;;;; Prompt
-
-(cl-defgeneric transient-prompt (obj)
- "Return the prompt to be used to read infix object OBJ's value.")
-
-(cl-defmethod transient-prompt ((obj transient-infix))
- "Return the prompt to be used to read infix object OBJ's value.
-
-This implementation should be suitable for almost all infix
-commands.
-
-If the value of OBJ's `prompt' slot is non-nil, then it must be
-a string or a function. If it is a string, then use that. If
-it is a function, then call that with OBJ as the only argument.
-That function must return a string, which is then used as the
-prompt.
-
-Otherwise, if the value of either the `argument' or `variable'
-slot of OBJ is a string, then base the prompt on that (prefering
-the former), appending either \"=\" (if it appears to be a
-command-line option) or \": \".
-
-Finally fall through to using \"(BUG: no prompt): \" as the
-prompt."
- (if-let ((prompt (oref obj prompt)))
- (let ((prompt (if (functionp prompt)
- (funcall prompt obj)
- prompt)))
- (if (stringp prompt)
- prompt
- "(BUG: no prompt): "))
- (or (when-let ((arg (and (slot-boundp obj 'argument) (oref obj argument))))
- (if (and (stringp arg) (string-suffix-p "=" arg))
- arg
- (concat arg ": ")))
- (when-let ((var (and (slot-boundp obj 'variable) (oref obj variable))))
- (and (stringp var)
- (concat var ": ")))
- "(BUG: no prompt): ")))
-
-;;;; Set
-
-(defvar transient--unset-incompatible t)
-
-(cl-defgeneric transient-infix-set (obj value)
- "Set the value of infix object OBJ to value.")
-
-(cl-defmethod transient-infix-set ((obj transient-infix) value)
- "Set the value of infix object OBJ to value.
-
-This implementation should be suitable for almost all infix
-commands."
- (oset obj value value))
-
-(cl-defmethod transient-infix-set :around ((obj transient-argument) value)
- "Unset incompatible infix arguments."
- (let ((arg (if (slot-boundp obj 'argument)
- (oref obj argument)
- (oref obj argument-regexp))))
- (if-let ((sic (and value arg transient--unset-incompatible))
- (spec (oref transient--prefix incompatible))
- (incomp (remove arg (cl-find-if (lambda (elt) (member arg elt)) spec))))
- (progn
- (cl-call-next-method obj value)
- (dolist (arg incomp)
- (when-let ((obj (cl-find-if (lambda (obj)
- (and (slot-boundp obj 'argument)
- (equal (oref obj argument) arg)))
- transient--suffixes)))
- (let ((transient--unset-incompatible nil))
- (transient-infix-set obj nil)))))
- (cl-call-next-method obj value))))
-
-(cl-defmethod transient-set-value ((obj transient-prefix))
- (oset (oref obj prototype) value (transient-get-value))
- (transient--history-push obj))
-
-;;;; Save
-
-(cl-defmethod transient-save-value ((obj transient-prefix))
- (let ((value (transient-get-value)))
- (oset (oref obj prototype) value value)
- (setf (alist-get (oref obj command) transient-values) value)
- (transient-save-values))
- (transient--history-push obj))
-
-;;;; Get
-
-(defun transient-args (prefix)
- "Return the value of the transient prefix command PREFIX.
-If the current command was invoked from the transient prefix
-command PREFIX, then return the active infix arguments. If
-the current command was not invoked from PREFIX, then return
-the set, saved or default value for PREFIX."
- (if (eq current-transient-command prefix)
- (delq nil (mapcar 'transient-infix-value current-transient-suffixes))
- (let ((transient--prefix nil)
- (transient--layout nil)
- (transient--suffixes nil))
- (transient--init-objects prefix nil nil)
- (delq nil (mapcar 'transient-infix-value transient--suffixes)))))
-
-(defun transient-get-value ()
- (delq nil (mapcar 'transient-infix-value current-transient-suffixes)))
-
-(cl-defgeneric transient-infix-value (obj)
- "Return the value of the suffix object OBJ.
-
-This function is called by `transient-args' (which see), meaning
-this function is how the value of a transient is determined so
-that the invoked suffix command can use it.
-
-Currently most values are strings, but that is not set in stone.
-Nil is not a value, it means \"no value\".
-
-Usually only infixes have a value, but see the method for
-`transient-suffix'.")
-
-(cl-defmethod transient-infix-value ((_ transient-suffix))
- "Return nil, which means \"no value\".
-
-Infix arguments contribute the the transient's value while suffix
-commands consume it. This function is called for suffixes anyway
-because a command that both contributes to the transient's value
-and also consumes it is not completely unconceivable.
-
-If you define such a command, then you must define a derived
-class and implement this function because this default method
-does nothing." nil)
-
-(cl-defmethod transient-infix-value ((obj transient-infix))
- "Return the value of OBJ's `value' slot."
- (oref obj value))
-
-(cl-defmethod transient-infix-value ((obj transient-option))
- "Return (concat ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil. VALUE may be the empty string,
-which is not the same as nil."
- (when-let ((value (oref obj value)))
- (concat (oref obj argument) value)))
-
-(cl-defmethod transient-infix-value ((_ transient-variable))
- "Return nil, which means \"no value\".
-
-Setting the value of a variable is done by, well, setting the
-value of the variable. I.e. this is a side-effect and does not
-contribute to the value of the transient."
- nil)
-
-(cl-defmethod transient-infix-value ((obj transient-files))
- "Return (concat ARGUMENT VALUE) or nil.
-
-ARGUMENT and VALUE are the values of the respective slots of OBJ.
-If VALUE is nil, then return nil. VALUE may be the empty string,
-which is not the same as nil."
- (when-let ((value (oref obj value)))
- (cons (oref obj argument) value)))
-
-;;; History
-
-(cl-defgeneric transient--history-key (obj)
- "Return OBJ's history key.
-If the value of the `history-key' slot is non-nil, then return
-that. Otherwise return the value of the `command' slot."
- (or (oref obj history-key)
- (oref obj command)))
-
-(cl-defgeneric transient--history-push (obj)
- "Push the current value of OBJ to its entry in `transient-history'."
- (let ((key (transient--history-key obj)))
- (setf (alist-get key transient-history)
- (let ((args (transient-get-value)))
- (cons args (delete args (alist-get key transient-history)))))))
-
-(cl-defgeneric transient--history-init (obj)
- "Initialize OBJ's `history' slot.
-This is the transient-wide history; many individual infixes also
-have a history of their own.")
-
-(cl-defmethod transient--history-init ((obj transient-prefix))
- "Initialize OBJ's `history' slot from the variable `transient-history'."
- (let ((val (oref obj value)))
- (oset obj history
- (cons val (delete val (alist-get (transient--history-key obj)
- transient-history))))))
-
-;;; Draw
-
-(defun transient--show-brief ()
- (let ((message-log-max nil))
- (if (and transient-show-popup (<= transient-show-popup 0))
- (message "%s-" (key-description (this-command-keys)))
- (message
- "%s- [%s] %s"
- (key-description (this-command-keys))
- (oref transient--prefix command)
- (mapconcat
- #'identity
- (sort
- (cl-mapcan
- (lambda (suffix)
- (let ((key (kbd (oref suffix key))))
- ;; Don't list any common commands.
- (and (not (memq (oref suffix command)
- `(,(lookup-key transient-map key)
- ,(lookup-key transient-sticky-map key)
- ;; From transient-common-commands:
- transient-set
- transient-save
- transient-history-prev
- transient-history-next
- transient-quit-one
- transient-toggle-common
- transient-set-level)))
- (list (propertize (oref suffix key) 'face 'transient-key)))))
- transient--suffixes)
- #'string<)
- (propertize "|" 'face 'transient-unreachable-key))))))
-
-(defun transient--show ()
- (transient--timer-cancel)
- (setq transient--showp t)
- (let ((buf (get-buffer-create transient--buffer-name))
- (focus nil))
- (unless (window-live-p transient--window)
- (setq transient--window
- (display-buffer buf transient-display-buffer-action)))
- (with-selected-window transient--window
- (when transient-enable-popup-navigation
- (setq focus (button-get (point) 'command)))
- (erase-buffer)
- (set-window-hscroll transient--window 0)
- (set-window-dedicated-p transient--window t)
- (set-window-parameter transient--window 'no-other-window t)
- (setq window-size-fixed t)
- (setq mode-line-format (if (eq transient-mode-line-format 'line)
- nil
- transient-mode-line-format))
- (setq mode-line-buffer-identification
- (symbol-name (oref transient--prefix command)))
- (if transient-enable-popup-navigation
- (setq-local cursor-in-non-selected-windows 'box)
- (setq cursor-type nil))
- (setq display-line-numbers nil)
- (setq show-trailing-whitespace nil)
- (transient--insert-groups)
- (when (or transient--helpp transient--editp)
- (transient--insert-help))
- (when (eq transient-mode-line-format 'line)
- (insert (propertize "__" 'face 'transient-separator
- 'display '(space :height (1))))
- (insert (propertize "\n" 'face 'transient-separator 'line-height t)))
- (let ((window-resize-pixelwise t)
- (window-size-fixed nil))
- (fit-window-to-buffer nil nil 1))
- (goto-char (point-min))
- (when transient-enable-popup-navigation
- (transient--goto-button focus)))))
-
-(defun transient--insert-groups ()
- (let ((groups (cl-mapcan (lambda (group)
- (let ((hide (oref group hide)))
- (and (not (and (functionp hide)
- (funcall hide)))
- (list group))))
- transient--layout))
- group)
- (while (setq group (pop groups))
- (transient--insert-group group)
- (when groups
- (insert ?\n)))))
-
-(cl-defgeneric transient--insert-group (group)
- "Format GROUP and its elements and insert the result.")
-
-(cl-defmethod transient--insert-group :before ((group transient-group))
- "Insert GROUP's description, if any."
- (when-let ((desc (transient-format-description group)))
- (insert desc ?\n)))
-
-(cl-defmethod transient--insert-group ((group transient-row))
- (dolist (suffix (oref group suffixes))
- (insert (transient-format suffix))
- (insert " "))
- (insert ?\n))
-
-(cl-defmethod transient--insert-group ((group transient-column))
- (dolist (suffix (oref group suffixes))
- (let ((str (transient-format suffix)))
- (insert str)
- (unless (string-match-p ".\n\\'" str)
- (insert ?\n)))))
-
-(cl-defmethod transient--insert-group ((group transient-columns))
- (let* ((columns
- (mapcar
- (lambda (column)
- (let ((rows (mapcar 'transient-format (oref column suffixes))))
- (when-let ((desc (transient-format-description column)))
- (push desc rows))
- rows))
- (oref group suffixes)))
- (rs (apply #'max (mapcar #'length columns)))
- (cs (length columns))
- (cw (--map (apply #'max (mapcar #'length it)) columns))
- (cc (-reductions-from (apply-partially #'+ 3) 0 cw)))
- (dotimes (r rs)
- (dotimes (c cs)
- (insert (make-string (- (nth c cc) (current-column)) ?\s))
- (when-let ((cell (nth r (nth c columns))))
- (insert cell))
- (when (= c (1- cs))
- (insert ?\n))))))
-
-(cl-defmethod transient--insert-group ((group transient-subgroups))
- (let* ((subgroups (oref group suffixes))
- (n (length subgroups)))
- (dotimes (s n)
- (transient--insert-group (nth s subgroups))
- (when (< s (1- n))
- (insert ?\n)))))
-
-(cl-defgeneric transient-format (obj)
- "Format and return OBJ for display.
-
-When this function is called, then the current buffer is some
-temporary buffer. If you need the buffer from which the prefix
-command was invoked to be current, then do so by temporarily
-making `transient--original-buffer' current.")
-
-(cl-defmethod transient-format ((arg string))
- "Return the string ARG after applying the `transient-heading' face."
- (propertize arg 'face 'transient-heading))
-
-(cl-defmethod transient-format ((_ null))
- "Return a string containing just the newline character."
- "\n")
-
-(cl-defmethod transient-format ((arg integer))
- "Return a string containing just the ARG character."
- (char-to-string arg))
-
-(cl-defmethod transient-format :around ((obj transient-infix))
- "When reading user input for this infix, then highlight it."
- (let ((str (cl-call-next-method obj)))
- (when (eq obj transient--active-infix)
- (setq str (concat str "\n"))
- (add-face-text-property 0 (length str)
- 'transient-active-infix nil str))
- str))
-
-(cl-defmethod transient-format :around ((obj transient-suffix))
- "When edit-mode is enabled, then prepend the level information.
-Optional support for popup buttons is also implemented here."
- (let ((str (concat
- (and transient--editp
- (let ((level (oref obj level)))
- (propertize (format " %s " level)
- 'face (if (transient--use-level-p level t)
- 'transient-enabled-suffix
- 'transient-disabled-suffix))))
- (cl-call-next-method obj))))
- (if transient-enable-popup-navigation
- (make-text-button str nil
- 'type 'transient-button
- 'command (transient--suffix-command obj))
- str)))
-
-(cl-defmethod transient-format ((obj transient-infix))
- "Return a string generated using OBJ's `format'.
-%k is formatted using `transient-format-key'.
-%d is formatted using `transient-format-description'.
-%f is formatted using `transient-format-value'."
- (format-spec (oref obj format)
- `((?k . ,(transient-format-key obj))
- (?d . ,(transient-format-description obj))
- (?v . ,(transient-format-value obj)))))
-
-(cl-defmethod transient-format ((obj transient-suffix))
- "Return a string generated using OBJ's `format'.
-%k is formatted using `transient-format-key'.
-%d is formatted using `transient-format-description'."
- (format-spec (oref obj format)
- `((?k . ,(transient-format-key obj))
- (?d . ,(transient-format-description obj)))))
-
-(cl-defgeneric transient-format-key (obj)
- "Format OBJ's `key' for display and return the result.")
-
-(cl-defmethod transient-format-key ((obj transient-suffix))
- "Format OBJ's `key' for display and return the result."
- (let ((key (oref obj key)))
- (if transient--redisplay-key
- (let ((len (length transient--redisplay-key))
- (seq (cl-coerce (edmacro-parse-keys key t) 'list)))
- (cond
- ((equal (-take len seq) transient--redisplay-key)
- (let ((pre (key-description (vconcat (-take len seq))))
- (suf (key-description (vconcat (-drop len seq)))))
- (setq pre (replace-regexp-in-string "RET" "C-m" pre t))
- (setq pre (replace-regexp-in-string "TAB" "C-i" pre t))
- (setq suf (replace-regexp-in-string "RET" "C-m" suf t))
- (setq suf (replace-regexp-in-string "TAB" "C-i" suf t))
- ;; We use e.g. "-k" instead of the more correct "- k",
- ;; because the former is prettier. If we did that in
- ;; the definition, then we want to drop the space that
- ;; is reinserted above. False-positives are possible
- ;; for silly bindings like "-C-c C-c".
- (unless (string-match-p " " key)
- (setq pre (replace-regexp-in-string " " "" pre))
- (setq suf (replace-regexp-in-string " " "" suf)))
- (concat (propertize pre 'face 'default)
- (and (string-prefix-p (concat pre " ") key) " ")
- (propertize suf 'face 'transient-key)
- (save-excursion
- (when (string-match " +\\'" key)
- (match-string 0 key))))))
- ((transient--lookup-key transient-sticky-map (kbd key))
- (propertize key 'face 'transient-key))
- (t
- (propertize key 'face 'transient-unreachable-key))))
- (propertize key 'face 'transient-key))))
-
-(cl-defmethod transient-format-key :around ((obj transient-argument))
- (let ((key (cl-call-next-method obj)))
- (cond ((not transient-highlight-mismatched-keys))
- ((not (slot-boundp obj 'shortarg))
- (add-face-text-property
- 0 (length key) 'transient-nonstandard-key nil key))
- ((not (string-equal key (oref obj shortarg)))
- (add-face-text-property
- 0 (length key) 'transient-mismatched-key nil key)))
- key))
-
-(cl-defgeneric transient-format-description (obj)
- "Format OBJ's `description' for display and return the result.")
-
-(cl-defmethod transient-format-description ((obj transient-child))
- "The `description' slot may be a function, in which case that is
-called inside the correct buffer (see `transient-insert-group')
-and its value is returned to the caller."
- (when-let ((desc (oref obj description)))
- (if (functionp desc)
- (with-current-buffer transient--original-buffer
- (funcall desc))
- desc)))
-
-(cl-defmethod transient-format-description ((obj transient-group))
- "Format the description by calling the next method. If the result
-doesn't use the `face' property at all, then apply the face
-`transient-heading' to the complete string."
- (when-let ((desc (cl-call-next-method obj)))
- (if (text-property-not-all 0 (length desc) 'face nil desc)
- desc
- (propertize desc 'face 'transient-heading))))
-
-(cl-defmethod transient-format-description :around ((obj transient-suffix))
- "Format the description by calling the next method. If the result
-is nil, then use \"(BUG: no description)\" as the description.
-If the OBJ's `key' is currently unreachable, then apply the face
-`transient-unreachable' to the complete string."
- (let ((desc (or (cl-call-next-method obj)
- (propertize "(BUG: no description)" 'face 'error))))
- (if (transient--key-unreachable-p obj)
- (propertize desc 'face 'transient-unreachable)
- desc)))
-
-(cl-defgeneric transient-format-value (obj)
- "Format OBJ's value for display and return the result.")
-
-(cl-defmethod transient-format-value ((obj transient-suffix))
- (propertize (oref obj argument)
- 'face (if (oref obj value)
- 'transient-argument
- 'transient-inactive-argument)))
-
-(cl-defmethod transient-format-value ((obj transient-option))
- (let ((value (oref obj value)))
- (propertize (concat (oref obj argument) value)
- 'face (if value
- 'transient-value
- 'transient-inactive-value))))
-
-(cl-defmethod transient-format-value ((obj transient-switches))
- (with-slots (value argument-format choices) obj
- (format (propertize argument-format
- 'face (if value
- 'transient-value
- 'transient-inactive-value))
- (concat
- (propertize "[" 'face 'transient-inactive-value)
- (mapconcat
- (lambda (choice)
- (propertize choice 'face
- (if (equal (format argument-format choice) value)
- 'transient-value
- 'transient-inactive-value)))
- choices
- (propertize "|" 'face 'transient-inactive-value))
- (propertize "]" 'face 'transient-inactive-value)))))
-
-(cl-defmethod transient-format-value ((obj transient-files))
- (let ((argument (oref obj argument)))
- (if-let ((value (oref obj value)))
- (propertize (concat argument " "
- (mapconcat (lambda (f) (format "%S" f))
- (oref obj value) " "))
- 'face 'transient-argument)
- (propertize argument 'face 'transient-inactive-argument))))
-
-(defun transient--key-unreachable-p (obj)
- (and transient--redisplay-key
- (let ((key (oref obj key)))
- (not (or (equal (-take (length transient--redisplay-key)
- (cl-coerce (edmacro-parse-keys key t) 'list))
- transient--redisplay-key)
- (transient--lookup-key transient-sticky-map (kbd key)))))))
-
-(defun transient--lookup-key (keymap key)
- (let ((val (lookup-key keymap key)))
- (and val (not (integerp val)) val)))
-
-;;; Help
-
-(cl-defgeneric transient-show-help (obj)
- "Show help for OBJ's command.")
-
-(cl-defmethod transient-show-help ((obj transient-prefix))
- "Show the info manual, manpage or command doc-string.
-Show the first one that is specified."
- (if-let ((manual (oref obj info-manual)))
- (info manual)
- (if-let ((manpage (oref obj man-page)))
- (transient--show-manpage manpage)
- (transient--describe-function (oref obj command)))))
-
-(cl-defmethod transient-show-help ((_ transient-suffix))
- "Show the command doc-string."
- (if (eq this-original-command 'transient-help)
- (if-let ((manpage (oref transient--prefix man-page)))
- (transient--show-manpage manpage)
- (transient--describe-function (oref transient--prefix command)))
- (transient--describe-function this-original-command)))
-
-(cl-defmethod transient-show-help ((obj transient-infix))
- "Show the manpage if defined or the command doc-string.
-If the manpage is specified, then try to jump to the correct
-location."
- (if-let ((manpage (oref transient--prefix man-page)))
- (transient--show-manpage manpage (oref obj argument))
- (transient--describe-function this-original-command)))
-
-;; `cl-generic-generalizers' doesn't support `command' et al.
-(cl-defmethod transient-show-help (cmd)
- "Show the command doc-string."
- (transient--describe-function cmd))
-
-(defun transient--show-manpage (manpage &optional argument)
- (require 'man)
- (let* ((Man-notify-method 'meek)
- (buf (Man-getpage-in-background manpage))
- (proc (get-buffer-process buf)))
- (while (and proc (eq (process-status proc) 'run))
- (accept-process-output proc))
- (switch-to-buffer buf)
- (when argument
- (transient--goto-argument-description argument))))
-
-(defun transient--describe-function (fn)
- (describe-function fn)
- (select-window (get-buffer-window (help-buffer))))
-
-(defun transient--goto-argument-description (arg)
- (goto-char (point-min))
- (let ((case-fold-search nil)
- ;; This matches preceding/proceeding options. Options
- ;; such as "-a", "-S[<keyid>]", and "--grep=<pattern>"
- ;; are matched by this regex without the shy group.
- ;; The ". " in the shy group is for options such as
- ;; "-m parent-number", and the "-[^[:space:]]+ " is
- ;; for options such as "--mainline parent-number"
- (others "-\\(?:. \\|-[^[:space:]]+ \\)?[^[:space:]]+"))
- (when (re-search-forward
- ;; Should start with whitespace and may have
- ;; any number of options before and/or after.
- (format
- "^[\t\s]+\\(?:%s, \\)*?\\(?1:%s\\)%s\\(?:, %s\\)*$"
- others
- ;; Options don't necessarily end in an "="
- ;; (e.g., "--gpg-sign[=<keyid>]")
- (string-remove-suffix "=" arg)
- ;; Simple options don't end in an "=". Splitting this
- ;; into 2 cases should make getting false positives
- ;; less likely.
- (if (string-suffix-p "=" arg)
- ;; "[^[:space:]]*[^.[:space:]]" matches the option
- ;; value, which is usually after the option name
- ;; and either '=' or '[='. The value can't end in
- ;; a period, as that means it's being used at the
- ;; end of a sentence. The space is for options
- ;; such as '--mainline parent-number'.
- "\\(?: \\|\\[?=\\)[^[:space:]]*[^.[:space:]]"
- ;; Either this doesn't match anything (e.g., "-a"),
- ;; or the option is followed by a value delimited
- ;; by a "[", "<", or ":". A space might appear
- ;; before this value, as in "-f <file>". The
- ;; space alternative is for options such as
- ;; "-m parent-number".
- "\\(?:\\(?: \\| ?[\\[<:]\\)[^[:space:]]*[^.[:space:]]\\)?")
- others)
- nil t)
- (goto-char (match-beginning 1)))))
-
-(defun transient--insert-help ()
- (unless (looking-back "\n\n" 2)
- (insert "\n"))
- (when transient--helpp
- (insert
- (format (propertize "\
-Type a %s to show help for that suffix command, or %s to show manual.
-Type %s to exit help.\n"
- 'face 'transient-heading)
- (propertize "<KEY>" 'face 'transient-key)
- (propertize "?" 'face 'transient-key)
- (propertize "C-g" 'face 'transient-key))))
- (when transient--editp
- (unless transient--helpp
- (insert
- (format (propertize "\
-Type a %s to set level for that suffix command.
-Type %s to set what levels are available for this prefix command.\n"
- 'face 'transient-heading)
- (propertize "<KEY>" 'face 'transient-key)
- (propertize "C-x l" 'face 'transient-key))))
- (with-slots (level) transient--prefix
- (insert
- (format (propertize "
-Suffixes on levels %s are available.
-Suffixes on levels %s and %s are unavailable.\n"
- 'face 'transient-heading)
- (propertize (format "1-%s" level)
- 'face 'transient-enabled-suffix)
- (propertize " 0 "
- 'face 'transient-disabled-suffix)
- (propertize (format ">=%s" (1+ level))
- 'face 'transient-disabled-suffix))))))
-
-(defvar transient-resume-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [remap Man-quit] 'transient-resume)
- (define-key map [remap Info-exit] 'transient-resume)
- (define-key map [remap quit-window] 'transient-resume)
- map)
- "Keymap for `transient-resume-mode'.
-
-This keymap remaps every command that would usually just quit the
-documentation buffer to `transient-resume', which additionally
-resumes the suspended transient.")
-
-(define-minor-mode transient-resume-mode
- "Auxiliary minor-mode used to resume a transient after viewing help.")
-
-;;; Compatibility
-;;;; Popup Navigation
-
-(defun transient-popup-navigation-help ()
- "Inform the user how to enable popup navigation commands."
- (interactive)
- (message "This command is only available if `%s' is non-nil"
- 'transient-enable-popup-navigation))
-
-(define-button-type 'transient-button
- 'face nil
- 'action (lambda (button)
- (let ((command (button-get button 'command)))
- ;; Yes, I know that this is wrong(tm).
- ;; Unfortunately it is also necessary.
- (setq this-original-command command)
- (call-interactively command))))
-
-(defvar transient-popup-navigation-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "<down-mouse-1>") 'transient-noop)
- (define-key map (kbd "<mouse-1>") 'transient-mouse-push-button)
- (define-key map (kbd "RET") 'transient-push-button)
- (define-key map (kbd "<up>") 'transient-backward-button)
- (define-key map (kbd "C-p") 'transient-backward-button)
- (define-key map (kbd "<down>") 'transient-forward-button)
- (define-key map (kbd "C-n") 'transient-forward-button)
- (define-key map (kbd "C-r") 'transient-isearch-backward)
- (define-key map (kbd "C-s") 'transient-isearch-forward)
- map))
-
-(defun transient-mouse-push-button (&optional pos)
- "Invoke the suffix the user clicks on."
- (interactive (list last-command-event))
- (push-button pos))
-
-(defun transient-push-button ()
- "Invoke the selected suffix command."
- (interactive)
- (with-selected-window transient--window
- (push-button)))
-
-(defun transient-backward-button (n)
- "Move to the previous button in the transient popup buffer.
-See `backward-button' for information about N."
- (interactive "p")
- (with-selected-window transient--window
- (backward-button n t)))
-
-(defun transient-forward-button (n)
- "Move to the next button in the transient popup buffer.
-See `forward-button' for information about N."
- (interactive "p")
- (with-selected-window transient--window
- (forward-button n t)))
-
-(defun transient--goto-button (command)
- (if (not command)
- (forward-button 1)
- (while (and (ignore-errors (forward-button 1))
- (not (eq (button-get (button-at (point)) 'command) command))))
- (unless (eq (button-get (button-at (point)) 'command) command)
- (goto-char (point-min))
- (forward-button 1))))
-
-;;;; Popup Isearch
-
-(defvar transient--isearch-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map isearch-mode-map)
- (define-key map [remap isearch-exit] 'transient-isearch-exit)
- (define-key map [remap isearch-cancel] 'transient-isearch-cancel)
- (define-key map [remap isearch-abort] 'transient-isearch-abort)
- map))
-
-(defun transient-isearch-backward (&optional regexp-p)
- "Do incremental search backward.
-With a prefix argument, do an incremental regular expression
-search instead."
- (interactive "P")
- (transient--isearch-setup)
- (let ((isearch-mode-map transient--isearch-mode-map))
- (isearch-mode nil regexp-p)))
-
-(defun transient-isearch-forward (&optional regexp-p)
- "Do incremental search forward.
-With a prefix argument, do an incremental regular expression
-search instead."
- (interactive "P")
- (transient--isearch-setup)
- (let ((isearch-mode-map transient--isearch-mode-map))
- (isearch-mode t regexp-p)))
-
-(defun transient-isearch-exit ()
- "Like `isearch-exit' but adapted for `transient'."
- (interactive)
- (isearch-exit)
- (transient--isearch-exit))
-
-(defun transient-isearch-cancel ()
- "Like `isearch-cancel' but adapted for `transient'."
- (interactive)
- (condition-case nil (isearch-cancel) (quit))
- (transient--isearch-exit))
-
-(defun transient-isearch-abort ()
- "Like `isearch-abort' but adapted for `transient'."
- (interactive)
- (condition-case nil (isearch-abort) (quit))
- (transient--isearch-exit))
-
-(defun transient--isearch-setup ()
- (select-window transient--window)
- (transient--pop-keymap 'transient--transient-map)
- (transient--pop-keymap 'transient--redisplay-map)
- (remove-hook 'pre-command-hook #'transient--pre-command)
- (remove-hook 'post-command-hook #'transient--post-command))
-
-(defun transient--isearch-exit ()
- (select-window transient--original-window)
- (transient--push-keymap 'transient--transient-map)
- (transient--push-keymap 'transient--redisplay-map)
- (add-hook 'pre-command-hook #'transient--pre-command)
- (add-hook 'post-command-hook #'transient--post-command))
-
-;;;; Other Packages
-
-(declare-function which-key-mode "which-key" (&optional arg))
-
-(defun transient--suspend-which-key-mode ()
- (when (bound-and-true-p which-key-mode)
- (which-key-mode -1)
- (add-hook 'post-transient-hook 'transient--resume-which-key-mode)))
-
-(defun transient--resume-which-key-mode ()
- (unless transient--prefix
- (which-key-mode 1)
- (remove-hook 'post-transient-hook 'transient--resume-which-key-mode)))
-
-(defun transient-bind-q-to-quit ()
- "Modify some keymaps to bind \"q\" to the appropriate quit command.
-
-\"C-g\" is the default binding for such commands now, but Transient's
-predecessor Magit-Popup used \"q\" instead. If you would like to get
-that binding back, then call this function in your init file like so:
-
- (with-eval-after-load \\='transient
- (transient-bind-q-to-quit))
-
-Individual transients may already bind \"q\" to something else
-and such a binding would shadow the quit binding. If that is the
-case then \"Q\" is bound to whatever \"q\" would have been bound
-to by setting `transient-substitute-key-function' to a function
-that does that. Of course \"Q\" may already be bound to something
-else, so that function binds \"M-q\" to that command instead.
-Of course \"M-q\" may already be bound to something else, but
-we stop there."
- (define-key transient-base-map "q" 'transient-quit-one)
- (define-key transient-sticky-map "q" 'transient-quit-seq)
- (setq transient-substitute-key-function
- 'transient-rebind-quit-commands))
-
-(defun transient-rebind-quit-commands (obj)
- "See `transient-bind-q-to-quit'."
- (let ((key (oref obj key)))
- (cond ((string-equal key "q") "Q")
- ((string-equal key "Q") "M-q")
- (t key))))
-
-;;; Font-Lock
-
-(defconst transient-font-lock-keywords
- (eval-when-compile
- `((,(concat "("
- (regexp-opt (list "define-transient-command"
- "define-infix-command"
- "define-infix-argument"
- "define-suffix-command")
- t)
- "\\_>[ \t'\(]*"
- "\\(\\(?:\\sw\\|\\s_\\)+\\)?")
- (1 'font-lock-keyword-face)
- (2 'font-lock-function-name-face nil t)))))
-
-(font-lock-add-keywords 'emacs-lisp-mode transient-font-lock-keywords)
-
-;;; _
-(provide 'transient)
-;; Local Variables:
-;; indent-tabs-mode: nil
-;; End:
-;;; transient.el ends here
diff --git a/elpa/transient-20190831.802/transient.elc b/elpa/transient-20190831.802/transient.elc
deleted file mode 100644
index 36f62c3..0000000
--- a/elpa/transient-20190831.802/transient.elc
+++ /dev/null
Binary files differ
diff --git a/elpa/transient-20190831.802/transient.info b/elpa/transient-20190831.802/transient.info
deleted file mode 100644
index a9b4714..0000000
--- a/elpa/transient-20190831.802/transient.info
+++ /dev/null
@@ -1,2384 +0,0 @@
-This is transient.info, produced by makeinfo version 6.5 from
-transient.texi.
-
- Copyright (C) 2018-2019 Jonas Bernoulli <jonas@bernoul.li>
-
- You can redistribute this document and/or modify it under the terms
- of the GNU General Public License as published by the Free Software
- Foundation, either version 3 of the License, or (at your option)
- any later version.
-
- This document is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Transient: (transient). Transient Commands.
-END-INFO-DIR-ENTRY
-
-
-File: transient.info, Node: Top, Next: Introduction, Up: (dir)
-
-Transient User and Developer Manual
-***********************************
-
-Taking inspiration from prefix keys and prefix arguments, Transient
-implements a similar abstraction involving a prefix command, infix
-arguments and suffix commands. We could call this abstraction a
-"transient command", but because it always involves at least two
-commands (a prefix and a suffix) we prefer to call it just a
-"transient".
-
- When the user calls a transient prefix command, then a transient
-(temporary) keymap is activated, which binds the transient’s infix and
-suffix commands, and functions that control the transient state are
-added to ‘pre-command-hook’ and ‘post-command-hook’. The available
-suffix and infix commands and their state are shown in a popup buffer
-until the transient is exited by invoking a suffix command.
-
- Calling an infix command causes its value to be changed, possibly by
-reading a new value in the minibuffer.
-
- Calling a suffix command usually causes the transient to be exited
-but suffix commands can also be configured to not exit the transient.
-
-This manual is for Transient version 0.1.0 (v0.1.0-103-g68f31ed+1).
-
- Copyright (C) 2018-2019 Jonas Bernoulli <jonas@bernoul.li>
-
- You can redistribute this document and/or modify it under the terms
- of the GNU General Public License as published by the Free Software
- Foundation, either version 3 of the License, or (at your option)
- any later version.
-
- This document is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
-* Menu:
-
-* Introduction::
-* Usage::
-* Other Options::
-* Modifying Existing Transients::
-* Defining New Commands::
-* Classes and Methods::
-* Related Abstractions and Packages::
-* FAQ::
-* Keystroke Index::
-* Command Index::
-* Function Index::
-* Variable Index::
-
-— The Detailed Node Listing —
-
-Usage
-
-* Invoking Transients::
-* Aborting and Resuming Transients::
-* Common Suffix Commands::
-* Saving Values::
-* Using History::
-* Getting Help for Suffix Commands::
-* Enabling and Disabling Suffixes::
-* Other Commands::
-
-Defining New Commands
-
-* Defining Transients::
-* Binding Suffix and Infix Commands::
-* Defining Suffix and Infix Commands::
-* Using Infix Arguments::
-* Transient State::
-
-Binding Suffix and Infix Commands
-
-* Group Specifications::
-* Suffix Specifications::
-
-
-Classes and Methods
-
-* Group Classes::
-* Group Methods::
-* Prefix Classes::
-* Suffix Classes::
-* Suffix Methods::
-* Prefix Slots::
-* Suffix Slots::
-* Predicate Slots::
-
-Suffix Methods
-
-* Suffix Value Methods::
-* Suffix Format Methods::
-
-
-Related Abstractions and Packages
-
-* Comparison With Prefix Keys and Prefix Arguments::
-* Comparison With Other Packages::
-
-
-
-File: transient.info, Node: Introduction, Next: Usage, Prev: Top, Up: Top
-
-1 Introduction
-**************
-
-Taking inspiration from prefix keys and prefix arguments, Transient
-implements a similar abstraction involving a prefix command, infix
-arguments and suffix commands. We could call this abstraction a
-"transient command", but because it always involves at least two
-commands (a prefix and a suffix) we prefer to call it just a
-"transient".
-
- Transient keymaps are a feature provided by Emacs. Transients as
- implemented by this package involve the use of transient keymaps.
-
- Emacs provides a feature that it calls "prefix commands". When we
- talk about "prefix commands" in this manual, then we mean our own
- kind of "prefix commands", unless specified otherwise. To avoid
- ambiguity we sometimes use the terms "transient prefix command" for
- our kind and "regular prefix command" for Emacs’ kind.
-
- When the user calls a transient prefix command, then a transient
-(temporary) keymap is activated, which binds the transient’s infix and
-suffix commands, and functions that control the transient state are
-added to ‘pre-command-hook’ and ‘post-command-hook’. The available
-suffix and infix commands and their state are shown in a popup buffer
-until the transient state is exited by invoking a suffix command.
-
- Calling an infix command causes its value to be changed. How that is
-done depends on the type of the infix command. The simplest case is an
-infix command that represents a command-line argument that does not take
-a value. Invoking such an infix command causes the switch to be toggled
-on or off. More complex infix commands may read a value from the user,
-using the minibuffer.
-
- Calling a suffix command usually causes the transient to be exited;
-the transient keymaps and hook functions are removed, the popup buffer
-no longer shows information about the (no longer bound) suffix commands,
-the values of some public global variables are set, while some internal
-global variables are unset, and finally the command is actually called.
-Suffix commands can also be configured to not exit the transient.
-
- A suffix command can, but does not have to, use the infix arguments
-in much the same way it can choose to use or ignore the prefix
-arguments. For a suffix command that was invoked from a transient the
-variable ‘current-transient-suffixes’ and the function ‘transient-args’
-serve about the same purpose as the variables ‘prefix-arg’ and
-‘current-prefix-arg’ do for any command that was called after the prefix
-arguments have been set using a command such as ‘universal-argument’.
-
- The information shown in the popup buffer while a transient is active
-looks a bit like this:
-
- ,-----------------------------------------
- |Arguments
- | -f Force (--force)
- | -a Annotate (--annotate)
- |
- |Create
- | t tag
- | r telease
- `-----------------------------------------
-
- This is a simplified version of ‘magit-tag’. Info manuals do not
- support images or colored text, so the above "screenshot" lacks
- some information; in practice you would be able to tell whether the
- arguments ‘--force’ and ‘--annotate’ are enabled or not based on
- their color.
-
- Transient can be used to implement simple "command dispatchers". The
-main benefit then is that the user can see all the available commands in
-a popup buffer. That is useful by itself because it frees the user from
-having to remember all the keys that are valid after a certain prefix
-key or command. Magit’s ‘magit-dispatch’ command is an example of using
-Transient to merely implement a command dispatcher.
-
- In addition to that, Transient also allows users to interactively
-pass arguments to commands. These arguments can be much more complex
-than what is reasonable when using prefix arguments. There is a limit
-to how many aspects of a command can be controlled using prefix
-arguments. Furthermore what a certain prefix argument means for
-different commands can be completely different, and users have to read
-documentation to learn and then commit to memory what a certain prefix
-argument means to a certain command.
-
- Transient suffix commands on the other hand can accept dozens of
-different arguments without the user having to remember anything. When
-using Transient, then one can call a command with arguments that are
-just as complex as when calling the same function non-interactively
-using code.
-
- Invoking a transient command with arguments is similar to invoking a
-command in a shell with command-line completion and history enabled.
-One benefit of the Transient interface is that it remembers history not
-only on a global level ("this command was invoked using these arguments
-and previously it was invoked using those other arguments"), but also
-remembers the values of individual arguments independently. See *note
-Using History::.
-
- After a transient prefix command is invoked ‘C-h <key>’ can be used
-to show the documentation for the infix or suffix command that ‘<key>’
-is bound to (see *note Getting Help for Suffix Commands::) and infixes
-and suffixes can be removed from the transient using ‘C-x l <key>’.
-Infixes and suffixes that are disabled by default can be enabled the
-same way. See *note Enabling and Disabling Suffixes::.
-
- Transient ships with support for a few different types of specialized
-infix commands. A command that sets a command line option for example
-has different needs than a command that merely toggles a boolean flag.
-Additionally Transient provides abstractions for defining new types,
-which the author of Transient did not anticipate (or didn’t get around
-to implementing yet).
-
-
-File: transient.info, Node: Usage, Next: Other Options, Prev: Introduction, Up: Top
-
-2 Usage
-*******
-
-* Menu:
-
-* Invoking Transients::
-* Aborting and Resuming Transients::
-* Common Suffix Commands::
-* Saving Values::
-* Using History::
-* Getting Help for Suffix Commands::
-* Enabling and Disabling Suffixes::
-* Other Commands::
-
-
-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.
-
-
-File: transient.info, Node: Aborting and Resuming Transients, Next: Common Suffix Commands, Prev: Invoking Transients, Up: Usage
-
-2.2 Aborting and Resuming Transients
-====================================
-
-To quit the transient without invoking a suffix command press ‘C-g’.
-
- Key bindings in transient keymaps may be longer than a single event.
-After pressing a valid prefix key, all commands whose bindings do not
-begin with that prefix key are temporarily unavailable and grayed out.
-To abort the prefix key press ‘C-g’ (which in this case only quits the
-prefix key, but not the complete transient).
-
- A transient prefix command can be bound as a suffix of another
-transient. Invoking such a suffix replaces the current transient state
-with a new transient state, i.e. the available bindings change and the
-information displayed in the popup buffer is updated accordingly.
-Pressing ‘C-g’ while a nested transient is active only quits the
-innermost transient, causing a return to the previous transient.
-
- ‘C-q’ or ‘C-z’ on the other hand always exits all transients. If you
-use the latter, then you can later resume the stack of transients using
-‘M-x transient-resume’.
-
-‘C-g’ (‘transient-quit-seq’)
-‘C-g’ (‘transient-quit-one’)
-
- This key quits the currently active incomplete key sequence, if
- any, or else the current transient. When quitting the current
- transient, then it returns to the previous transient, if any.
-
- Transient’s predecessor bound ‘q’ instead of ‘C-g’ to the quit
-command. To learn how to get that binding back see
-‘transient-bind-q-to-quit’’s doc string.
-
-‘C-q’ (‘transient-quit-all’)
-
- This command quits the currently active incomplete key sequence, if
- any, and all transients, including the active transient and all
- suspended transients, if any.
-
-‘C-z’ (‘transient-suspend’)
-
- Like ‘transient-quit-all’, this command quits an incomplete key
- sequence, if any, and all transients. Additionally it saves the
- stack of transients so that it can easily be resumed (which is
- particularly useful if you quickly need to do "something else" and
- the stack is deeper than a single transient and/or you have already
- changed the values of some infix arguments).
-
- Note that only a single stack of transients can be saved at a time.
- If another stack is already saved, then saving a new stack discards
- the previous stack.
-
-‘M-x transient-resume’ (‘transient-resume’)
-
- This command resumes the previously suspended stack of transients,
- if any.
-
-
-File: transient.info, Node: Common Suffix Commands, Next: Saving Values, Prev: Aborting and Resuming Transients, Up: Usage
-
-2.3 Common Suffix Commands
-==========================
-
-A few shared suffix commands are available in all transients. These
-suffix commands are not shown in the popup buffer by default.
-
- Most of these commands are bound to ‘C-x <key>’ and after pressing
-‘C-x’ a section featuring all common commands is temporarily shown in
-the popup buffer. After invoking one of these commands, that section
-disappears again. Note however that one of these commands is described
-as "Show common permanently"; invoke that if you want the common
-commands to always be shown for all transients.
-
-‘C-x t’ (‘transient-toggle-common’)
-
- This command toggles whether the generic commands that are common
- to all transients are always displayed or only after typing the
- incomplete prefix key sequence ‘C-x’. This only affects the
- current Emacs session.
-
- -- User Option: transient-show-common-commands
-
- This option controls whether shared suffix commands are shown
- alongside the transient-specific infix and suffix commands. By
- default the shared commands are not shown to avoid overwhelming the
- user with to many options.
-
- While a transient is active, pressing ‘C-x’ always shows the common
- command. The value of this option can be changed for the current
- Emacs session by typing ‘C-x t’ while a transient is active.
-
- The other common commands are described in either the previous node
-or in one of the following nodes.
-
- Some of Transient’s key bindings differ from the respective bindings
-of Magit-Popup; see *note FAQ:: for more information.
-
-
-File: transient.info, Node: Saving Values, Next: Using History, Prev: Common Suffix Commands, Up: Usage
-
-2.4 Saving Values
-=================
-
-After setting the infix arguments in a transient, the user can save
-those arguments for future invocations.
-
- Most transients will start out with the saved arguments when they are
-invoked. There are a few exceptions though. Some transients are
-designed so that the value that they use is stored externally as the
-buffer-local value of some variable. Invoking such a transient again
-uses the buffer-local value. (1)
-
- If the user does not save the value and just exits using a regular
-suffix command, then the value is merely saved to the transient’s
-history. That value won’t be used when the transient is next invoked
-but it is easily accessible (see *note Using History::).
-
-‘C-x s’ (‘transient-set’)
-
- This command saves the value of the active transient for this Emacs
- session.
-
-‘C-x C-s’ (‘transient-save’)
-
- Save the value of the active transient persistently across Emacs
- sessions.
-
- -- User Option: transient-values-file
-
- This file is used to persist the values of transients between Emacs
- sessions.
-
- ---------- Footnotes ----------
-
- (1) ‘magit-diff’ and ‘magit-log’ are two prominent examples, and
-their handling of buffer-local values is actually a bit more complicated
-than outlined above and even customizable. This is something I am
-rethinking, but I don’t want to rush any changes.)
-
-
-File: transient.info, Node: Using History, Next: Getting Help for Suffix Commands, Prev: Saving Values, Up: Usage
-
-2.5 Using History
-=================
-
-Every time the user invokes a suffix command the transient’s current
-value is saved to its history. These values can be cycled through the
-same way one can cycle through the history of commands that read
-user-input in the minibuffer.
-
-‘M-p’ (‘transient-history-prev’)
-
- This command switches to the previous value used for the active
- transient.
-
-‘M-n’ (‘transient-history-next’)
-
- This command switches to the next value used for the active
- transient.
-
- In addition to the transient-wide history, Transient of course
-supports per-infix history. When an infix reads user-input using the
-minibuffer, then the user can use the regular minibuffer history
-commands to cycle through previously used values. Usually the same keys
-as those mentioned above are bound to those commands.
-
- Authors of transients should arrange for different infix commands
-that read the same kind of value to also use the same history key (see
-*note Suffix Slots::).
-
- Both kinds of history are saved to a file when Emacs is exited.
-
- -- User Option: transient-history-file
-
- This file is used to persist the history of transients and their
- infixes between Emacs sessions.
-
- -- User Option: transient-history-limit
-
- This option controls how many history elements are kept at the time
- the history is saved in ‘transient-history-file’.
-
-
-File: transient.info, Node: Getting Help for Suffix Commands, Next: Enabling and Disabling Suffixes, Prev: Using History, Up: Usage
-
-2.6 Getting Help for Suffix Commands
-====================================
-
-Transients can have many suffixes and infixes that the user might not be
-familiar with. To make it trivial to get help for these, Transient
-provides access to the documentation directly from the active transient.
-
-‘C-h’ (‘transient-help’)
-
- This command enters help mode. When help mode is active, then
- typing ‘<key>’ shows information about the suffix command that
- ‘<key>’ normally is bound to (instead of invoking it). Pressing
- ‘C-h’ a second time shows information about the _prefix_ command.
-
- After typing ‘<key>’ the stack of transient states is suspended and
- information about the suffix command is shown instead. Typing ‘q’
- in the help buffer buries that buffer and resumes the transient
- state.
-
- What sort of documentation is shown depends on how the transient was
-defined. For infix commands that represent command-line arguments this
-ideally shows the appropriate manpage. ‘transient-help’ then tries to
-jump to the correct location within that. Info manuals are also
-supported. The fallback is to show the command’s doc string, for
-non-infix suffixes this is usually appropriate.
-
-
-File: transient.info, Node: Enabling and Disabling Suffixes, Next: Other Commands, Prev: Getting Help for Suffix Commands, Up: Usage
-
-2.7 Enabling and Disabling Suffixes
-===================================
-
-The user base of a package that uses transients can be very diverse.
-This is certainly the case for Magit; some users have been using it and
-Git for a decade, while others are just getting started now.
-
- For that reason a mechanism is needed that authors can use to
-classify a transient’s infixes and suffixes along the
-essentials...everything spectrum. We use the term "levels" to describe
-that mechanism.
-
- Each suffix command is placed on a level and each transient has a
-level (called transient-level), which controls which suffix commands are
-available. Integers between 1 and 7 (inclusive) are valid levels. For
-suffixes, 0 is also valid; it means that the suffix is not displayed at
-any level.
-
- The levels of individual transients and/or their individual suffixes
-can be changed interactively, by invoking the transient and then
-pressing ‘C-x l’ to enter the "edit" mode, see below.
-
- The default level for both transients and their suffixes is 4. The
-‘transient-default-level’ option only controls the default for
-transients. The default suffix level is always 4. The authors of
-transients should place certain suffixes on a higher level, if they
-expect that it won’t be of use to most users, and they should place very
-important suffixes on a lower level, so that they remain available even
-if the user lowers the transient level.
-
- (Magit currently places nearly all suffixes on level 4 and lower
-levels are not used at all yet. So for the time being you should not
-set a lower default level and using a higher level might not give you as
-many additional suffixes as you hoped.)
-
- -- User Option: transient-default-level
-
- This option controls which suffix levels are made available by
- default. It sets the transient-level for transients for which the
- user has not set that individually.
-
- -- User Option: transient-levels-file
-
- This file is used to persist the levels of transients and their
- suffixes between Emacs sessions.
-
-‘C-x l’ (‘transient-set-level’)
-
- This command enters edit mode. When edit mode is active, then all
- infixes and suffixes that are currently usable are displayed along
- with their levels. The colors of the levels indicate whether they
- are enabled or not. The level of the transient is also displayed
- along with some usage information.
-
- In edit mode, pressing the key that would usually invoke a certain
- suffix instead prompts the user for the level that suffix should be
- placed on.
-
- Help mode is available in edit mode.
-
- To change the transient level press ‘C-x l’ again.
-
- To exit edit mode press ‘C-g’.
-
- Note that edit mode does not display any suffixes that are not
- currently usable. ‘magit-rebase’ for example shows different
- suffixes depending on whether a rebase is already in progress or
- not. The predicates also apply in edit mode.
-
- Therefore, to control which suffixes are available given a certain
- state, you have to make sure that that state is currently active.
-
-
-File: transient.info, Node: Other Commands, Prev: Enabling and Disabling Suffixes, Up: Usage
-
-2.8 Other Commands
-==================
-
-When invoking a transient in a small frame, the transient window may not
-show the complete buffer, making it necessary to scroll, using the
-following commands. These commands are never shown in the transient
-window, and the key bindings are the same as for ‘scroll-up-command’ and
-‘scroll-down-command’ in other buffers.
-
- -- Command: transient-scroll-up arg
-
- This command scrolls text of transient popup window upward ARG
- lines. If ARG is ‘nil’, then it scrolls near full screen. This is
- a wrapper around ‘scroll-up-command’ (which see).
-
- -- Command: transient-scroll-down arg
-
- This command scrolls text of transient popup window down ARG lines.
- If ARG is ‘nil’, then it scrolls near full screen. This is a
- wrapper around ‘scroll-down-command’ (which see).
-
-
-File: transient.info, Node: Other Options, Next: Modifying Existing Transients, Prev: Usage, Up: Top
-
-3 Other Options
-***************
-
- -- User Option: transient-show-popup
-
- This option controls whether the current transient’s infix and
- suffix commands are shown in the popup buffer.
-
- • If ‘t’ (the default) then the popup buffer is shown as soon as
- a transient prefix command is invoked.
-
- • If ‘nil’, then the popup buffer is not shown unless the user
- explicitly requests it, by pressing an incomplete prefix key
- sequence.
-
- • If a number, then the a brief one-line summary is shown
- instead of the popup buffer. If zero or negative, then not
- even that summary is shown; only the pressed key itself is
- shown.
-
- The popup is shown when the user explicitly requests it by
- pressing an incomplete prefix key sequence. Unless this is
- zero, then the popup is shown after that many seconds of
- inactivity (using the absolute value).
-
- -- User Option: transient-enable-popup-navigation
-
- This option controls whether navigation commands are enabled in the
- transient popup.
-
- While a transient is active the transient popup buffer is not the
- current buffer, making it necesary to use dedicated commands to act
- on that buffer itself. This is disabled by default. If this
- option is non-nil, then the following features are available:
-
- • ‘<up>’ moves the cursor to the previous suffix. ‘<down>’
- moves the cursor to the next suffix. ‘RET’ invokes the suffix
- the cursor is on.
-
- • ‘<mouse-1>’ invokes the clicked on suffix.
-
- • ‘C-s’ and ‘C-r’ start isearch in the popup buffer.
-
- -- User Option: transient-display-buffer-action
-
- This option specifies the action used to display the transient
- popup buffer. The transient popup buffer is displayed in a window
- using ‘(display-buffer buf transient-display-buffer-action)’.
-
- The value of this option has the form ‘(FUNCTION . ALIST)’, where
- FUNCTION is a function or a list of functions. Each such function
- should accept two arguments: a buffer to display and an alist of
- the same form as ALIST. See *note (elisp)Choosing Window::.
-
- The default is ‘(display-buffer-in-side-window (side . bottom))’.
- This displays the window at the bottom of the selected frame.
- Another useful value is ‘(display-buffer-below-selected)’. This is
- what ‘magit-popup’ used by default. For more alternatives see
- *note (elisp)Display Action Functions::.
-
- It may be possible to display the window in another frame, but
- whether that works in practice depends on the window-manager. If
- the window manager selects the new window (Emacs frame), then it
- doesn’t work.
-
- If you change the value of this option, then you might also want to
- change the value of ‘transient-mode-line-format’.
-
- -- User Option: transient-mode-line-format
-
- This option controls whether the transient popup buffer has a
- mode-line, separator line, or neither.
-
- If ‘nil’, then the buffer has no mode-line. If the buffer is not
- displayed right above the echo area, then this probably is not a
- good value.
-
- If ‘line’ (the default), then the buffer also has no mode-line, but
- a thin line is drawn instead, using the background color of the
- face ‘transient-separator’.
-
- Otherwise this can be any mode-line format. See *note (elisp)Mode
- Line Format:: for details.
-
- -- User Option: transient-read-with-initial-input
-
- This option controls whether the last history element is used as
- the initial minibuffer input when reading the value of an infix
- argument from the user. If ‘nil’, then there is no initial input
- and the first element has to be accessed the same way as the older
- elements.
-
- -- User Option: transient-highlight-mismatched-keys
-
- This option controls whether key bindings of infix commands that do
- not match the respective command-line argument should be
- highlighted. For other infix commands this option has no effect.
-
- When this option is non-nil, then the key binding for an infix
- argument is highlighted when only a long argument (e.g.
- ‘--verbose’) is specified but no shorthand (e.g ‘-v’). In the rare
- case that a shorthand is specified but the key binding does not
- match, then it is highlighted differently.
-
- Highlighting mismatched key bindings is useful when learning the
- arguments of the underlying command-line tool; you wouldn’t want to
- learn any short-hands that do not actually exist.
-
- The highlighting is done using one of the faces
- ‘transient-mismatched-key’ and ‘transient-nonstandard-key’.
-
- -- User Option: transient-substitute-key-function
-
- This function is used to modify key bindings. If the value of this
- option is nil (the default), then no substitution is performed.
-
- This function is called with one argument, the prefix object, and
- must return a key binding description, either the existing key
- description it finds in the ‘key’ slot, or key description that
- replaces the prefix key. It could be used to make other
- substitutions, but that is discouraged.
-
- For example, ‘=’ is hard to reach using my custom keyboard layout,
- so I substitute ‘(’ for that, which is easy to reach using a layout
- optimized for lisp.
-
- (setq transient-substitute-key-function
- (lambda (obj)
- (let ((key (oref obj key)))
- (if (string-match "\\`\\(=\\)[a-zA-Z]" key)
- (replace-match "(" t t key 1)
- key))))
-
- -- User Option: transient-detect-key-conflicts
-
- This option controls whether key binding conflicts should be
- detected at the time the transient is invoked. If so, then this
- results in an error, which prevents the transient from being used.
- Because of that, conflicts are ignored by default.
-
- Conflicts cannot be determined earlier, i.e. when the transient is
- being defined and when new suffixes are being added, because at
- that time there can be false-positives. It is actually valid for
- multiple suffixes to share a common key binding, provided the
- predicates of those suffixes prevent that more than one of them is
- enabled at a time.
-
-
-File: transient.info, Node: Modifying Existing Transients, Next: Defining New Commands, Prev: Other Options, Up: Top
-
-4 Modifying Existing Transients
-*******************************
-
-To an extent transients can be customized interactively, see *note
-Enabling and Disabling Suffixes::. This section explains how existing
-transients can be further modified non-interactively.
-
- The following functions share a few arguments:
-
- • PREFIX is a transient prefix command, a symbol.
-
- • SUFFIX is a transient infix or suffix specification in the same
- form as expected by ‘define-transient-command’. Note that an infix
- is a special kind of suffix. Depending on context "suffixes" means
- "suffixes (including infixes)" or "non-infix suffixes". Here it
- means the former. See *note Suffix Specifications::.
-
- SUFFIX may also be a group in the same form as expected by
- ‘define-transient-command’. See *note Group Specifications::.
-
- • LOC is a command, a key vector, a key description (a string as
- returned by ‘key-description’), or a list specifying coordinates
- (the last element may also be a command or key). For example ‘(1 0
- -1)’ identifies the last suffix (‘-1’) of the first subgroup (‘0’)
- of the second group (‘1’).
-
- If LOC is a list of coordinates, then it can be used to identify a
- group, not just an individual suffix command.
-
- The function ‘transient-get-suffix’ can be useful to determine
- whether a certain coordination list identifies the suffix or group
- that you expect it to identify. In hairy cases it may be necessary
- to look at the definition of the transient prefix command.
-
- These functions operate on the information stored in the
-‘transient--layout’ property of the PREFIX symbol. Suffix entries in
-that tree are not objects but have the form ‘(LEVEL CLASS PLIST)’, where
-plist should set at least ‘:key’, ‘:description’ and ‘:command’.
-
- -- Function: transient-insert-suffix prefix loc suffix
-
- This function inserts suffix or group SUFFIX into PREFIX before
- LOC.
-
- -- Function: transient-append-suffix prefix loc suffix
-
- This function inserts suffix or group SUFFIX into PREFIX after LOC.
-
- -- Function: transient-replace-suffix prefix loc suffix
-
- This function replaces the suffix or group at LOC in PREFIX with
- suffix or group SUFFIX.
-
- -- Function: transient-remove-suffix prefix loc
-
- This function removes the suffix or group at LOC in PREFIX.
-
- -- Function: transient-get-suffix prefix loc
-
- This function returns the suffix or group at LOC in PREFIX. The
- returned value has the form mentioned above.
-
- -- Function: transient-suffix-put prefix loc prop value
-
- This function edits the suffix or group at LOC in PREFIX, by
- setting the PROP of its plist to VALUE.
-
- Most of these functions do not signal an error if they cannot perform
-the requested modification. The functions that insert new suffixes show
-a warning if LOC cannot be found in PREFIX, without signaling an error.
-The reason for doing it like this is that establishing a key binding
-(and that is what we essentially are trying to do here) should not
-prevent the rest of the configuration from loading. Among these
-functions only ‘transient-get-suffix’ and ‘transient-suffix-put’ may
-signal an error.
-
-
-File: transient.info, Node: Defining New Commands, Next: Classes and Methods, Prev: Modifying Existing Transients, Up: Top
-
-5 Defining New Commands
-***********************
-
-* Menu:
-
-* Defining Transients::
-* Binding Suffix and Infix Commands::
-* Defining Suffix and Infix Commands::
-* Using Infix Arguments::
-* Transient State::
-
-
-File: transient.info, Node: Defining Transients, Next: Binding Suffix and Infix Commands, Up: Defining New Commands
-
-5.1 Defining Transients
-=======================
-
-A transient consists of a prefix command and at least one suffix
-command, though usually a transient has several infix and suffix
-commands. The below macro defines the transient prefix command *and*
-binds the transient’s infix and suffix commands. In other words, it
-defines the complete transient, not just the transient prefix command
-that is used to invoke that transient.
-
- -- Macro: define-transient-command name arglist [docstring] [keyword
- value]... group... [body...]
-
- This macro defines NAME as a transient prefix command and binds the
- transient’s infix and suffix commands.
-
- ARGLIST are the arguments that the prefix command takes. DOCSTRING
- is the documentation string and is optional.
-
- These arguments can optionally be followed by keyword-value pairs.
- Each key has to be a keyword symbol, either ‘:class’ or a keyword
- argument supported by the constructor of that class. The
- ‘transient-prefix’ class is used if the class is not specified
- explicitly.
-
- GROUPs add key bindings for infix and suffix commands and specify
- how these bindings are presented in the popup buffer. At least one
- GROUP has to be specified. See *note Binding Suffix and Infix
- Commands::.
-
- The BODY is optional. If it is omitted, then ARGLIST is ignored
- and the function definition becomes:
-
- (lambda ()
- (interactive)
- (transient-setup 'NAME))
-
- If BODY is specified, then it must begin with an ‘interactive’ form
- that matches ARGLIST, and it must call ‘transient-setup’. It may
- however call that function only when some condition is satisfied.
-
- All transients have a (possibly ‘nil’) value, which is exported
- when suffix commands are called, so that they can consume that
- value. For some transients it might be necessary to have a sort of
- secondary value, called a "scope". Such a scope would usually be
- set in the command’s ‘interactive’ form and has to be passed to the
- setup function:
-
- (transient-setup 'NAME nil nil :scope SCOPE)
-
- For example, the scope of the ‘magit-branch-configure’ transient is
- the branch whose variables are being configured.
-
-
-File: transient.info, Node: Binding Suffix and Infix Commands, Next: Defining Suffix and Infix Commands, Prev: Defining Transients, Up: Defining New Commands
-
-5.2 Binding Suffix and Infix Commands
-=====================================
-
-The macro ‘define-transient-command’ is used to define a transient.
-This defines the actual transient prefix command (see *note Defining
-Transients::) and adds the transient’s infix and suffix bindings, as
-described below.
-
- Users and third-party packages can add additional bindings using
-functions such as ‘transient-insert-suffix’ (See *note Modifying
-Existing Transients::). These functions take a "suffix specification"
-as one of their arguments, which has the same form as the specifications
-used in ‘define-transient-command’.
-
-* Menu:
-
-* Group Specifications::
-* Suffix Specifications::
-
-
-File: transient.info, Node: Group Specifications, Next: Suffix Specifications, Up: Binding Suffix and Infix Commands
-
-5.2.1 Group Specifications
---------------------------
-
-The suffix and infix commands of a transient are organized in groups.
-The grouping controls how the descriptions of the suffixes are outlined
-visually but also makes it possible to set certain properties for a set
-of suffixes.
-
- Several group classes exist, some of which organize suffixes in
-subgroups. In most cases the class does not have to be specified
-explicitly, but see *note Group Classes::.
-
- Groups are specified in the call to ‘define-transient-command’, using
-vectors. Because groups are represented using vectors, we cannot use
-square brackets to indicate an optional element and instead use curly
-brackets to do the latter.
-
- Group specifications then have this form:
-
- [{LEVEL} {DESCRIPTION} {KEYWORD VALUE}... ELEMENT...]
-
- The LEVEL is optional and defaults to 4. See *note Enabling and
-Disabling Suffixes::.
-
- The DESCRIPTION is optional. If present it is used as the heading of
-the group.
-
- The KEYWORD-VALUE pairs are optional. Each keyword has to be a
-keyword symbol, either ‘:class’ or a keyword argument supported by the
-constructor of that class.
-
- • One of these keywords, ‘:description’, is equivalent to specifying
- DESCRIPTION at the very beginning of the vector. The
- recommendation is to use ‘:description’ if some other keyword is
- also used, for consistency, or DESCRIPTION otherwise, because it
- looks better.
-
- • Likewise ‘:level’ is equivalent to LEVEL.
-
- • Other important keywords include the ‘:if...’ keywords. These
- keywords control whether the group is available in a certain
- situation.
-
- For example, one group of the ‘magit-rebase’ transient uses ‘:if
- magit-rebase-in-progress-p’, which contains the suffixes that are
- useful while rebase is already in progress; and another that uses
- ‘:if-not magit-rebase-in-progress-p’, which contains the suffixes
- that initiate a rebase.
-
- These predicates can also be used on individual suffixes and are
- only documented once, see *note Predicate Slots::.
-
- • Finally the value of ‘:hide’, if non-nil, is a predicate that
- controls whether the group is hidden by default. The key bindings
- for suffixes of a hidden group should all use the same prefix key.
- Pressing that prefix key should temporarily show the group and its
- suffixes, which assumes that a predicate like this is used:
-
- (lambda ()
- (eq (car transient--redisplay-key)
- ?\C-c)) ; the prefix key shared by all bindings
-
- The ELEMENTs are either all subgroups (vectors), or all suffixes
-(lists) and strings. (At least currently no group type exists that
-would allow mixing subgroups with commands at the same level, though in
-principle there is nothing that prevents that.)
-
- If the ELEMENTs are not subgroups, then they can be a mixture of
-lists that specify commands and strings. Strings are inserted verbatim.
-The empty string can be used to insert gaps between suffixes, which is
-particularly useful if the suffixes are outlined as a table.
-
- The form of suffix specifications is documented in the next node.
-
-
-File: transient.info, Node: Suffix Specifications, Prev: Group Specifications, Up: Binding Suffix and Infix Commands
-
-5.2.2 Suffix Specifications
----------------------------
-
-A transient’s suffix and infix commands are bound when the transient
-prefix command is defined using ‘define-transient-command’, see *note
-Defining Transients::. The commands are organized into groups, see
-*note Group Specifications::. Here we describe the form used to bind an
-individual suffix command.
-
- The same form is also used when later binding additional commands
-using functions such as ‘transient-insert-suffix’, see *note Modifying
-Existing Transients::.
-
- Note that an infix is a special kind of suffix. Depending on context
-"suffixes" means "suffixes (including infixes)" or "non-infix suffixes".
-Here it means the former.
-
- Suffix specifications have this form:
-
- ([LEVEL] [KEY] [DESCRIPTION] COMMAND|ARGUMENT [KEYWORD VALUE]...)
-
- LEVEL, KEY and DESCRIPTION can also be specified using the KEYWORDs
-‘:level’, ‘:key’ and ‘:description’. If the object that is associated
-with COMMAND sets these properties, then they do not have to be
-specified here. You can however specify them here anyway, possibly
-overriding the object’s values just for the binding inside this
-transient.
-
- • LEVEL is the suffix level, an integer between 1 and 7. See *note
- Enabling and Disabling Suffixes::.
-
- • KEY is the key binding, either a vector or key description string.
-
- • DESCRIPTION is the description, either a string or a function that
- returns a string. The function should be a lambda expression to
- avoid ambiguity. In some cases a symbol that is bound as a
- function would also work but to be safe you should use
- ‘:description’ in that case.
-
- The next element is either a command or an argument. This is the
-only argument that is mandatory in all cases.
-
- • COMMAND is a symbol that is bound as a function, which has to be a
- command. Any command will do; it does not need to have an object
- associated with it (as would be the case if ‘define-suffix-command’
- or ‘define-infix-command’ were used to define it).
-
- As mentioned above, the object that is associated with a command
- can be used to set the default for certain values that otherwise
- have to be set in the suffix specification. Therefore if there is
- no object, then you have to make sure to specify the KEY and the
- DESCRIPTION.
-
- • The mandatory argument can also be a command-line argument, a
- string. In that case an anonymous command is defined and bound.
-
- Instead of a string, this can also be a list of two strings, in
- which case the first string is used as the short argument (which
- can also be specified using ‘:shortarg’) and the second as the long
- argument (which can also be specified using ‘:argument’).
-
- Only the long argument is displayed in the popup buffer. See
- ‘transient-detect-key-conflicts’ for how the short argument may be
- used.
-
- Unless the class is specified explicitly, the appropriate class is
- guessed based on the long argument. If the argument ends with "=​"
- (e.g. "–format=") then ‘transient-option’ is used, otherwise
- ‘transient-switch’.
-
- Finally, details can be specified using optional KEYWORD-VALUE pairs.
-Each keyword has to be a keyword symbol, either ‘:class’ or a keyword
-argument supported by the constructor of that class. See *note Suffix
-Slots::.
-
-
-File: transient.info, Node: Defining Suffix and Infix Commands, Next: Using Infix Arguments, Prev: Binding Suffix and Infix Commands, Up: Defining New Commands
-
-5.3 Defining Suffix and Infix Commands
-======================================
-
-Note that an infix is a special kind of suffix. Depending on context
-"suffixes" means "suffixes (including infixes)" or "non-infix suffixes".
-
- -- Macro: define-suffix-command name arglist [docstring] [keyword
- value]... body...
-
- This macro defines NAME as a transient suffix command.
-
- ARGLIST are the arguments that the command takes. DOCSTRING is the
- documentation string and is optional.
-
- These arguments can optionally be followed by keyword-value pairs.
- Each keyword has to be a keyword symbol, either ‘:class’ or a
- keyword argument supported by the constructor of that class. The
- ‘transient-suffix’ class is used if the class is not specified
- explicitly.
-
- The BODY must begin with an ‘interactive’ form that matches
- ARGLIST. Use the function ‘transient-args’ or the low-level
- variable ‘current-transient-suffixes’ if the former does not give
- you all the required details. This should, but does not
- necessarily have to be, done inside the ‘interactive’ form; just
- like for ‘prefix-arg’ and ‘current-prefix-arg’.
-
- -- Macro: define-infix-command name arglist [docstring] [keyword
- value]...
-
- This macro defines NAME as a transient infix command.
-
- ARGLIST is always ignored (but mandatory never-the-less) and
- reserved for future use. DOCSTRING is the documentation string and
- is optional.
-
- The keyword-value pairs are mandatory. All transient infix
- commands are ‘equal’ to each other (but not ‘eq’), so it is
- meaningless to define an infix command without also setting at
- least ‘:class’ and one other keyword (which it is depends on the
- used class, usually ‘:argument’ or ‘:variable’).
-
- Each keyword has to be a keyword symbol, either ‘:class’ or a
- keyword argument supported by the constructor of that class. The
- ‘transient-switch’ class is used if the class is not specified
- explicitly.
-
- The function definition is always:
-
- (lambda ()
- (interactive)
- (let ((obj (transient-suffix-object)))
- (transient-infix-set obj (transient-infix-read obj)))
- (transient--show))
-
- ‘transient-infix-read’ and ‘transient-infix-set’ are generic
- functions. Different infix commands behave differently because the
- concrete methods are different for different infix command classes.
- In rare cases the above command function might not be suitable,
- even if you define your own infix command class. In that case you
- have to use ‘transient-suffix-command’ to define the infix command
- and use ‘t’ as the value of the ‘:transient’ keyword.
-
- -- Macro: define-infix-argument name arglist [docstring] [keyword
- value]...
-
- This macro defines NAME as a transient infix command.
-
- It is an alias for ‘define-infix-command’. Only use this alias to
- define an infix command that actually sets an infix argument. To
- define an infix command that, for example, sets a variable, use
- ‘define-infix-command’ instead.
-
-
-File: transient.info, Node: Using Infix Arguments, Next: Transient State, Prev: Defining Suffix and Infix Commands, Up: Defining New Commands
-
-5.4 Using Infix Arguments
-=========================
-
-The function and the variables described below allow suffix commands to
-access the value of the transient from which they were invoked; which is
-the value of its infix arguments. These variables are set when the user
-invokes a suffix command that exits the transient, but before actually
-calling the command.
-
- When returning to the command-loop after calling the suffix command,
-the arguments are reset to ‘nil’ (which causes the function to return
-‘nil’ too).
-
- Like for Emacs’ prefix arguments it is advisable, but not mandatory,
-to access the infix arguments inside the command’s ‘interactive’ form.
-The preferred way of doing that is to call the ‘transient-args’
-function, which for infix arguments serves about the same purpose as
-‘prefix-arg’ serves for prefix arguments.
-
- -- Function: transient-args &optional prefix
-
- This function returns the value of the transient prefix command
- PREFIX.
-
- If the current command was invoked from the transient prefix
- command PREFIX, then it returns the active infix arguments. If the
- current command was not invoked from PREFIX, then it returns the
- set, saved or default value for PREFIX.
-
- -- Variable: current-transient-suffixes
-
- The suffixes of the transient from which this suffix command was
- invoked. This is a list of objects. Usually it is sufficient to
- instead use the function ‘transient-args’, which returns a list of
- values. In complex cases it might be necessary to use this
- variable instead, i.e. if you need access to information beside
- the value.
-
- -- Variable: current-transient-prefix
-
- The transient from which this suffix command was invoked. The
- returned value is a ‘transient-prefix’ object, which holds
- information associated with the transient prefix command.
-
- -- Variable: current-transient-command
-
- The transient from which this suffix command was invoked. The
- returned value is a symbol, the transient prefix command.
-
-
-File: transient.info, Node: Transient State, Prev: Using Infix Arguments, Up: Defining New Commands
-
-5.5 Transient State
-===================
-
-Invoking a transient prefix command "activates" the respective
-transient, i.e. it puts a transient keymap into effect, which binds the
-transient’s infix and suffix commands.
-
- The default behavior while a transient is active is as follows:
-
- • Invoking an infix command does not affect the transient state; the
- transient remains active.
-
- • Invoking a (non-infix) suffix command "deactivates" the transient
- state by removing the transient keymap and performing some
- additional cleanup.
-
- • Invoking a command that is bound in a keymap other than the
- transient keymap is disallowed and trying to do so results in a
- warning. This does not "deactivate" the transient.
-
- But these are just the defaults. Whether a certain command
-deactivates or "exits" the transient is configurable. There is more
-than one way in which a command can be "transient" or "non-transient";
-the exact behavior is implemented by calling a so-called "pre-command"
-function. Whether non-suffix commands are allowed to be called is
-configurable per transient.
-
- • The transient-ness of suffix commands (including infix commands) is
- controlled by the value of their ‘transient’ slot, which can be set
- either when defining the command or when adding a binding to a
- transient while defining the respective transient prefix command.
-
- Valid values are booleans and the pre-commands described below.
-
- • ‘t’ is equivalent to ‘transient--do-stay’.
-
- • ‘nil’ is equivalent to ‘transient--do-exit’.
-
- • If ‘transient’ is unbound (and that is actually the default
- for non-infix suffixes) then the value of the prefix’s
- ‘transient-suffix’ slot is used instead. The default value of
- that slot is ‘nil’, so the suffix’s ‘transient’ slot being
- unbound is essentially equivalent to it being ‘nil’.
-
- • A suffix command can be a prefix command itself, i.e. a
- "sub-prefix". While a sub-prefix is active we nearly always want
- ‘C-g’ to take the user back to the "super-prefix". However in rare
- cases this may not be desirable, and that makes the following
- complication necessary:
-
- For ‘transient-suffix’ objects the ‘transient’ slot is unbound. We
- can ignore that for the most part because, as stated above, ‘nil’
- and the slot being unbound are equivalent, and mean "do exit".
- That isn’t actually true for suffixes that are sub-prefixes though.
- For such suffixes unbound means "do exit but allow going back",
- which is the default, while ‘nil’ means "do exit permanently",
- which requires that slot to be explicitly set to that value.
-
- • The transient-ness of certain built-in suffix commands is specified
- using ‘transient-predicate-map’. This is a special keymap, which
- binds commands to pre-commands (as opposed to keys to commands) and
- takes precedence over the ‘transient’ slot.
-
- The available pre-command functions are documented below. They are
-called by ‘transient--pre-command’, a function on ‘pre-command-hook’ and
-the value that they return determines whether the transient is exited.
-To do so the value of one of the constants ‘transient--exit’ or
-‘transient--stay’ is used (that way we don’t have to remember if ‘t’
-means "exit" or "stay").
-
- Additionally these functions may change the value of ‘this-command’
-(which explains why they have to be called using ‘pre-command-hook’),
-call ‘transient-export’, ‘transient--stack-zap’ or
-‘transient--stack-push’; and set the values of ‘transient--exitp’,
-‘transient--helpp’ or ‘transient--editp’.
-
-5.5.1 Pre-commands for Infixes
-------------------------------
-
-The default for infixes is ‘transient--do-stay’. This is also the only
-function that makes sense for infixes.
-
- -- Function: transient--do-stay
-
- Call the command without exporting variables and stay transient.
-
-5.5.2 Pre-commands for Suffixes
--------------------------------
-
-The default for suffixes is ‘transient--do-exit’.
-
- -- Function: transient--do-exit
-
- Call the command after exporting variables and exit the transient.
-
- -- Function: transient--do-call
-
- Call the command after exporting variables and stay transient.
-
- -- Function: transient--do-replace
-
- Call the transient prefix command, replacing the active transient.
-
- This is used for suffixes that are prefixes themselves, i.e. for
- sub-prefixes.
-
-5.5.3 Pre-commands for Non-Suffixes
------------------------------------
-
-The default for non-suffixes, i.e commands that are bound in other
-keymaps beside the transient keymap, is ‘transient--do-warn’. Silently
-ignoring the user-error is also an option, though probably not a good
-one.
-
- If you want to let the user invoke non-suffix commands, then use
-‘transient--do-stay’ as the value of the prefix’s ‘transient-non-suffix’
-slot.
-
- -- Function: transient--do-warn
-
- Call ‘transient-undefined’ and stay transient.
-
- -- Function: transient--do-noop
-
- Call ‘transient-noop’ and stay transient.
-
-5.5.4 Special Pre-Commands
---------------------------
-
- -- Function: transient--do-quit-one
-
- If active, quit help or edit mode, else exit the active transient.
-
- This is used when the user pressed ‘C-g’.
-
- -- Function: transient--do-quit-all
-
- Exit all transients without saving the transient stack.
-
- This is used when the user pressed ‘C-q’.
-
- -- Function: transient--do-suspend
-
- Suspend the active transient, saving the transient stack.
-
- This is used when the user pressed ‘C-z’.
-
-
-File: transient.info, Node: Classes and Methods, Next: Related Abstractions and Packages, Prev: Defining New Commands, Up: Top
-
-6 Classes and Methods
-*********************
-
-Transient uses classes and generic functions to make it possible to
-define new types of suffix commands that are similar to existing types,
-but behave differently in some aspects. It does the same for groups and
-prefix commands, though at least for prefix commands that *currently*
-appears to be less important.
-
- Every prefix, infix and suffix command is associated with an object,
-which holds information that controls certain aspects of its behavior.
-This happens in two ways.
-
- • Associating a command with a certain class gives the command a
- type. This makes it possible to use generic functions to do
- certain things that have to be done differently depending on what
- type of command it acts on.
-
- That in turn makes it possible for third-parties to add new types
- without having to convince the maintainer of Transient that that
- new type is important enough to justify adding a special case to a
- dozen or so functions.
-
- • Associating a command with an object makes it possible to easily
- store information that is specific to that particular command.
-
- Two commands may have the same type, but obviously their key
- bindings and descriptions still have to be different, for example.
-
- The values of some slots are functions. The ‘reader’ slot for
- example holds a function that is used to read a new value for an
- infix command. The values of such slots are regular functions.
-
- Generic functions are used when a function should do something
- different based on the type of the command, i.e. when all commands
- of a certain type should behave the same way but different from the
- behavior for other types. Object slots that hold a regular
- function as value are used when the task that they perform is
- likely to differ even between different commands of the same type.
-
-* Menu:
-
-* Group Classes::
-* Group Methods::
-* Prefix Classes::
-* Suffix Classes::
-* Suffix Methods::
-* Prefix Slots::
-* Suffix Slots::
-* Predicate Slots::
-
-
-File: transient.info, Node: Group Classes, Next: Group Methods, Up: Classes and Methods
-
-6.1 Group Classes
-=================
-
-The type of a group can be specified using the ‘:class’ property at the
-beginning of the class specification, e.g. ‘[:class transient-columns
-...]’ in a call to ‘define-transient-command’.
-
- • The abstract ‘transient-child’ class is the base class of both
- ‘transient-group’ (and therefore all groups) as well as of
- ‘transient-suffix’ (and therefore all suffix and infix commands).
-
- This class exists because the elements (aka "children") of certain
- groups can be other groups instead of suffix and infix commands.
-
- • The abstract ‘transient-group’ class is the superclass of all other
- group classes.
-
- • The ‘transient-column’ class is the simplest group.
-
- This is the default "flat" group. If the class is not specified
- explicitly and the first element is not a vector (i.e. not a
- group), then this class is used.
-
- This class displays each element on a separate line.
-
- • The ‘transient-row’ class displays all elements on a single line.
-
- • The ‘transient-columns’ class displays commands organized in
- columns.
-
- Direct elements have to be groups whose elements have to be
- commands or strings. Each subgroup represents a column. This
- class takes care of inserting the subgroups’ elements.
-
- This is the default "nested" group. If the class is not specified
- explicitly and the first element is a vector (i.e. a group), then
- this class is used.
-
- • The ‘transient-subgroups’ class wraps other groups.
-
- Direct elements have to be groups whose elements have to be
- commands or strings. This group inserts an empty line between
- subgroups. The subgroups themselves are responsible for displaying
- their elements.
-
-
-File: transient.info, Node: Group Methods, Next: Prefix Classes, Prev: Group Classes, Up: Classes and Methods
-
-6.2 Group Methods
-=================
-
- -- Function: transient--insert-group group
-
- This generic function formats the group and its elements and
- inserts the result into the current buffer, which is a temporary
- buffer. The contents of that buffer are later inserted into the
- popup buffer.
-
- Functions that are called by this function may need to operate in
- the buffer from which the transient was called. To do so they can
- temporally make the ‘transient--source-buffer’ the current buffer.
-
-
-File: transient.info, Node: Prefix Classes, Next: Suffix Classes, Prev: Group Methods, Up: Classes and Methods
-
-6.3 Prefix Classes
-==================
-
-Currently the ‘transient-prefix’ class is being used for all prefix
-commands and there is only a single generic function that can be
-specialized based on the class of a prefix command.
-
- -- Function: transient--history-init obj
-
- This generic function is called while setting up the transient and
- is responsible for initializing the ‘history’ slot. This is the
- transient-wide history; many individual infixes also have a history
- of their own.
-
- The default (and currently only) method extracts the value from the
- global variable ‘transient-history’.
-
- A transient prefix command’s object is stored in the
-‘transient--prefix’ property of the command symbol. While a transient
-is active, a clone of that object is stored in the variable
-‘transient--prefix’. A clone is used because some changes that are made
-to the active transient’s object should not affect later invocations.
-
-
-File: transient.info, Node: Suffix Classes, Next: Suffix Methods, Prev: Prefix Classes, Up: Classes and Methods
-
-6.4 Suffix Classes
-==================
-
- • All suffix and infix classes derive from ‘transient-suffix’, which
- in turn derives from ‘transient-child’, from which
- ‘transient-group’ also derives (see *note Group Classes::).
-
- • All infix classes derive from the abstract ‘transient-infix’ class,
- which in turn derives from the ‘transient-suffix’ class.
-
- Infixes are a special type of suffixes. The primary difference is
- that infixes always use the ‘transient--do-stay’ pre-command, while
- non-infix suffixes use a variety of pre-commands (see *note
- Transient State::). Doing that is most easily achieved by using
- this class, though theoretically it would be possible to define an
- infix class that does not do so. If you do that then you get to
- implement many methods.
-
- Also, infixes and non-infix suffixes are usually defined using
- different macros (see *note Defining Suffix and Infix Commands::).
-
- • Classes used for infix commands that represent arguments should be
- derived from the abstract ‘transient-argument’ class.
-
- • The ‘transient-switch’ class (or a derived class) is used for infix
- arguments that represent command-line switches (arguments that do
- not take a value).
-
- • The ‘transient-option’ class (or a derived class) is used for infix
- arguments that represent command-line options (arguments that do
- take a value).
-
- • The ‘transient-switches’ class can be used for a set of mutually
- exclusive command-line switches.
-
- • The ‘transient-files’ class can be used for a "–" argument that
- indicates that all remaining arguments are files.
-
- • Classes used for infix commands that represent variables should
- derived from the abstract ‘transient-variables’ class.
-
- Magit defines additional classes, which can serve as examples for the
-fancy things you can do without modifying Transient. Some of these
-classes will likely get generalized and added to Transient. For now
-they are very much subject to change and not documented.
-
-
-File: transient.info, Node: Suffix Methods, Next: Prefix Slots, Prev: Suffix Classes, Up: Classes and Methods
-
-6.5 Suffix Methods
-==================
-
-To get information about the methods implementing these generic
-functions use ‘describe-function’.
-
-* Menu:
-
-* Suffix Value Methods::
-* Suffix Format Methods::
-
-
-File: transient.info, Node: Suffix Value Methods, Next: Suffix Format Methods, Up: Suffix Methods
-
-6.5.1 Suffix Value Methods
---------------------------
-
- -- Function: transient-init-value obj
-
- This generic function sets the initial value of the object OBJ.
-
- This function is called for all suffix commands, but unless a
- concrete method is implemented this falls through to the default
- implementation, which is a noop. In other words this usually only
- does something for infix commands, but note that this is not
- implemented for the abstract class ‘transient-infix’, so if your
- class derives from that directly, then you must implement a method.
-
- -- Function: transient-infix-read obj
-
- This generic function determines the new value of the infix object
- OBJ.
-
- This function merely determines the value; ‘transient-infix-set’ is
- used to actually store the new value in the object.
-
- For most infix classes this is done by reading a value from the
- user using the reader specified by the ‘reader’ slot (using the
- ‘transient-infix-value’ method described below).
-
- For some infix classes the value is changed without reading
- anything in the minibuffer, i.e. the mere act of invoking the
- infix command determines what the new value should be, based on the
- previous value.
-
- -- Function: transient-prompt obj
-
- This generic function returns the prompt to be used to read infix
- object OBJ’s value.
-
- -- Function: transient-infix-set obj value
-
- This generic function sets the value of infix object OBJ to VALUE.
-
- -- Function: transient-infix-value obj
-
- This generic function returns the value of the suffix object OBJ.
-
- This function is called by ‘transient-args’ (which see), meaning
- this function is how the value of a transient is determined so that
- the invoked suffix command can use it.
-
- Currently most values are strings, but that is not set in stone.
- ‘nil’ is not a value, it means "no value".
-
- Usually only infixes have a value, but see the method for
- ‘transient-suffix’.
-
- -- Function: transient-init-scope obj
-
- This generic function sets the scope of the suffix object OBJ.
-
- The scope is actually a property of the transient prefix, not of
- individual suffixes. However it is possible to invoke a suffix
- command directly instead of from a transient. In that case, if the
- suffix expects a scope, then it has to determine that itself and
- store it in its ‘scope’ slot.
-
- This function is called for all suffix commands, but unless a
- concrete method is implemented this falls through to the default
- implementation, which is a noop.
-
-
-File: transient.info, Node: Suffix Format Methods, Prev: Suffix Value Methods, Up: Suffix Methods
-
-6.5.2 Suffix Format Methods
----------------------------
-
- -- Function: transient-format obj
-
- This generic function formats and returns OBJ for display.
-
- When this function is called, then the current buffer is some
- temporary buffer. If you need the buffer from which the prefix
- command was invoked to be current, then do so by temporarily making
- ‘transient--source-buffer’ current.
-
- -- Function: transient-format-key obj
-
- This generic function formats OBJ’s ‘key’ for display and returns
- the result.
-
- -- Function: transient-format-description obj
-
- This generic function formats OBJ’s ‘description’ for display and
- returns the result.
-
- -- Function: transient-format-value obj
-
- This generic function formats OBJ’s value for display and returns
- the result.
-
- -- Function: transient-show-help obj
-
- Show help for the prefix, infix or suffix command represented by
- OBJ.
-
- For prefixes, show the info manual, if that is specified using the
- ‘info-manual’ slot. Otherwise show the manpage if that is
- specified using the ‘man-page’ slot. Otherwise show the command’s
- doc string.
-
- For suffixes, show the command’s doc string.
-
- For infixes, show the manpage if that is specified. Otherwise show
- the command’s doc string.
-
-
-File: transient.info, Node: Prefix Slots, Next: Suffix Slots, Prev: Suffix Methods, Up: Classes and Methods
-
-6.6 *TODO* Prefix Slots
-=======================
-
-
-File: transient.info, Node: Suffix Slots, Next: Predicate Slots, Prev: Prefix Slots, Up: Classes and Methods
-
-6.7 Suffix Slots
-================
-
-Here we document most of the slots that are only available for suffix
-objects. Some slots are shared by suffix and group objects, they are
-documented in *note Predicate Slots::.
-
- Also see *note Suffix Classes::.
-
-6.7.1 Slots of ‘transient-suffix’
----------------------------------
-
- • ‘key’ The key, a key vector or a key description string.
-
- • ‘command’ The command, a symbol.
-
- • ‘transient’ Whether to stay transient. See *note Transient
- State::.
-
- • ‘format’ The format used to display the suffix in the popup buffer.
- It must contain the following %-placeholders:
-
- • ‘%k’ For the key.
-
- • ‘%d’ For the description.
-
- • ‘%v’ For the infix value. Non-infix suffixes don’t have a
- value.
-
- • ‘description’ The description, either a string or a function that
- is called with no argument and returns a string.
-
-6.7.2 Slots of ‘transient-infix’
---------------------------------
-
-Some of these slots are only meaningful for some of the subclasses.
-They are defined here anyway to allow sharing certain methods.
-
- • ‘argument’ The long argument, e.g. ‘--verbose’.
-
- • ‘shortarg’ The short argument, e.g. ‘-v’.
-
- • ‘multi-value’ For options, whether the option can have multiple
- values. If non-nil, then default to use
- ‘completing-read-multiple’.
-
- • ‘allow-empty’ For options, whether the empty string is a valid
- value.
-
- • ‘history-key’ The key used to store the history. This defaults to
- the command name. This is useful when multiple infixes should
- share the same history because their values are of the same kind.
-
- • ‘reader’ The function used to read the value of an infix. Not used
- for switches. The function takes three arguments, PROMPT,
- INITIAL-INPUT and HISTORY, and must return a string.
-
- • ‘prompt’ The prompt used when reading the value, either a string or
- a function that takes the object as the only argument and which
- returns a prompt string.
-
- • ‘choices’ A list of valid values. How exactly that is used depends
- on the class of the object.
-
-6.7.3 Slots of ‘transient-variable’
------------------------------------
-
- • ‘variable’ The variable.
-
-6.7.4 Slots of ‘transient-switches’
------------------------------------
-
- • ‘argument-format’ The display format. Must contain ‘%s’, one of
- the ‘choices’ is substituted for that. E.g. ‘--%s-order’.
-
- • ‘argument-regexp’ The regexp used to match any one of the switches.
- E.g. ‘\\(--\\(topo\\|author-date\\|date\\)-order\\)’.
-
-
-File: transient.info, Node: Predicate Slots, Prev: Suffix Slots, Up: Classes and Methods
-
-6.8 Predicate Slots
-===================
-
-Suffix and group objects share some predicate slots that control whether
-a group or suffix should be available depending on some state. Only one
-of these slots can be used at the same time. It is undefined what
-happens if you use more than one.
-
- • ‘if’ Enable if predicate returns non-nil.
-
- • ‘if-not’ Enable if predicate returns nil.
-
- • ‘if-non-nil’ Enable if variable’s value is non-nil.
-
- • ‘if-nil’ Enable if variable’s value is nil.
-
- • ‘if-mode’ Enable if major-mode matches value.
-
- • ‘if-not-mode’ Enable if major-mode does not match value.
-
- • ‘if-derived’ Enable if major-mode derives from value.
-
- • ‘if-not-derived’ Enable if major-mode does not derive from value.
-
- One more slot is shared between group and suffix classes, ‘level’.
-Like the slots documented above, it is a predicate, but it is used for a
-different purpose. The value has to be an integer between 1 and 7.
-‘level’ controls whether a suffix or a group should be available
-depending on user preference. See *note Enabling and Disabling
-Suffixes::.
-
-
-File: transient.info, Node: Related Abstractions and Packages, Next: FAQ, Prev: Classes and Methods, Up: Top
-
-7 Related Abstractions and Packages
-***********************************
-
-* Menu:
-
-* Comparison With Prefix Keys and Prefix Arguments::
-* Comparison With Other Packages::
-
-
-File: transient.info, Node: Comparison With Prefix Keys and Prefix Arguments, Next: Comparison With Other Packages, Up: Related Abstractions and Packages
-
-7.1 Comparison With Prefix Keys and Prefix Arguments
-====================================================
-
-While transient commands were inspired by regular prefix keys and prefix
-arguments, they are also quite different and much more complex.
-
- The following diagrams illustrate some of the differences.
-
- • ‘(c)’ represents a return to the command loop.
-
- • ‘(+)’ represents the user’s choice to press one key or another.
-
- • ‘{WORD}’ are possible behaviors.
-
- • ‘{NUMBER}’ is a footnote.
-
-7.1.1 Regular Prefix Commands
------------------------------
-
-See *note (elisp)Prefix Keys::.
-
- ,--> command1 --> (c)
- |
- (c)-(+)-> prefix command or key --+--> command2 --> (c)
- |
- `--> command3 --> (c)
-
-7.1.2 Regular Prefix Arguments
-------------------------------
-
-See *note (elisp)Prefix Command Arguments::.
-
- ,----------------------------------,
- | |
- v |
- (c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c)
- | ^ |
- | | |
- `-- sets or changes --, ,-- maybe used --' |
- | | |
- v | |
- prefix argument state |
- ^ |
- | |
- `-------- discards --------'
-
-7.1.3 Transients
-----------------
-
-(∩`-´)⊃━☆゚.*・。゚
-
- This diagram ignores the infix value and external state:
-
- (c)
- | ,- {stay} ------<-,-<------------<-,-<---,
- (+) | | | |
- | | | | |
- | | ,--> infix1 --| | |
- | | | | | |
- | | |--> infix2 --| | |
- v v | | | |
- prefix -(c)-(+)-> infix3 --' ^ |
- | | |
- |---------------> suffix1 -->--| |
- | | |
- |---------------> suffix2 ----{1}------> {exit} --> (c)
- | |
- |---------------> suffix3 -------------> {exit} --> (c)
- | |
- `--> any command --{2}-> {warn} -->--|
- | |
- |--> {noop} -->--|
- | |
- |--> {call} -->--'
- |
- `------------------> {exit} --> (c)
-
- This diagram takes the infix value into account to an extend, while
-still ignoring external state:
-
- (c)
- | ,- {stay} ------<-,-<------------<-,-<---,
- (+) | | | |
- | | | | |
- | | ,--> infix1 --| | |
- | | | | | | |
- | | ,--> infix2 --| | |
- v v | | | | |
- prefix -(c)-(+)-> infix3 --' | |
- | | ^ |
- | | | |
- |---------------> suffix1 -->--| |
- | | ^ | |
- | | | | |
- |---------------> suffix2 ----{1}------> {exit} --> (c)
- | | ^ | |
- | | | | v
- | | | | |
- |---------------> suffix3 -------------> {exit} --> (c)
- | | ^ | |
- | sets | | v
- | | maybe | |
- | | used | |
- | | | | |
- | | infix --' | |
- | `---> value | |
- | ^ | |
- | | | |
- | hides | |
- | | | |
- | `--------------------------<---|
- | | |
- `--> any command --{2}-> {warn} -->--| |
- | | |
- |--> {noop} -->--| |
- | | |
- |--> {call} -->--' ^
- | |
- `------------------> {exit} --> (c)
-
- This diagram provides more information about the infix value and also
-takes external state into account.
-
- ,----sets--- "anything"
- |
- v
- ,---------> external
- | state
- | | |
- | initialized | ☉‿⚆
- sets from |
- | | maybe
- | ,----------' used
- | | |
- (c) | | v
- | ,- {stay} --|---<-,-<------|-----<-,-<---,
- (+) | | | | | | |
- | | | v | | | |
- | | ,--> infix1 --| | | |
- | | | | | | | | |
- | | | | v | | | |
- | | ,--> infix2 --| | | |
- | | | | ^ | | | |
- v v | | | | | | |
- prefix -(c)-(+)-> infix3 --' | | |
- | | ^ | ^ |
- | | | v | |
- |---------------> suffix1 -->--| |
- | | | ^ | | |
- | | | | v | |
- |---------------> suffix2 ----{1}------> {exit} --> (c)
- | | | ^ | | |
- | | | | | | v
- | | | | v | |
- |---------------> suffix3 -------------> {exit} --> (c)
- | | | ^ | |
- | sets | | | v
- | | initalized maybe | |
- | | from used | |
- | | | | | |
- | | `-- infix --' | |
- | `---> value -----------------------------> persistent
- | ^ ^ | | across
- | | | | | invocations -,
- | hides | | | |
- | | `----------------------------------------------'
- | | | |
- | `--------------------------<---|
- | | |
- `--> any command --{2}-> {warn} -->--| |
- | | |
- |--> {noop} -->--| |
- | | |
- |--> {call} -->--' ^
- | |
- `------------------> {exit} --> (c)
-
- • ‘{1}’ Transients can be configured to be exited when a suffix
- command is invoked. The default is to do so for all suffixes
- except for those that are common to all transients and which are
- used to perform tasks such as providing help and saving the value
- of the infix arguments for future invocations. The behavior can
- also be specified for individual suffix commands and may even
- depend on state.
-
- • ‘{2}’ Transients can be configured to allow the user to invoke
- non-suffix commands. The default is to not allow that and instead
- warn the user.
-
- Despite already being rather complex, even the last diagram leaves
-out many details. Most importantly it implies that the decision whether
-to remain transient is made later than it actually is made (for the most
-part a function on ‘pre-command-hook’ is responsible). But such
-implementation details are of little relevance to users and are covered
-elsewhere.
-
-
-File: transient.info, Node: Comparison With Other Packages, Prev: Comparison With Prefix Keys and Prefix Arguments, Up: Related Abstractions and Packages
-
-7.2 Comparison With Other Packages
-==================================
-
-7.2.1 Magit-Popup
------------------
-
-Transient is the successor to Magit-Popup (see *note
-(magit-popup)Top::).
-
- One major difference between these two implementations of the same
-ideas is that while Transient uses transient keymaps and embraces the
-command-loop, Magit-Popup implemented an inferior mechanism that does
-not use transient keymaps and that instead of using the command-loop
-implements a naive alternative based on ‘read-char’.
-
- Magit-Popup does not use classes and generic functions and defining a
-new command type is near impossible as it involves adding hard-coded
-special-cases to many functions. Because of that only a single new type
-was added, which was not already part of Magit-Popup’s initial release.
-
- A lot of things are hard-coded in Magit-Popup. One random example is
-that the key bindings for switches must begin with "-" and those for
-options must begin with "=".
-
-7.2.2 Hydra
------------
-
-Hydra (see <https://github.com/abo-abo/hydra>) is another package that
-provides features similar to those of Transient.
-
- Both packages use transient keymaps to make a set of commands
-temporarily available and show the available commands in a popup buffer.
-
- A Hydra "body" is equivalent to a Transient "prefix" and a Hydra
-"head" is equivalent to a Transient "suffix". Hydra has no equivalent
-of a Transient "infix".
-
- Both hydras and transients can be used as simple command dispatchers.
-Used like this they are similar to regular prefix commands and prefix
-keys, except that the available commands are shown in the popup buffer.
-
- (Another package that does this is ‘which-key’. It does so
-automatically for any incomplete key sequence. The advantage of that
-approach is that no additional work is necessary; the disadvantage is
-that the available commands are not organized semantically.)
-
- Both Hydra and Transient provide features that go beyond simple
-command dispatchers:
-
- • Invoking a command from a hydra does not necessarily exit the
- hydra. That makes it possible to invoke the same command again,
- but using a shorter key sequence (i.e. the key that was used to
- enter the hydra does not have to be pressed again).
-
- Transient supports that too, but for now this feature is not a
- focus and the interface is a bit more complicated. A very basic
- example using the current interface:
-
- (define-transient-command outline-navigate ()
- :transient-suffix 'transient--do-stay
- :transient-non-suffix 'transient--do-warn
- [("p" "previous visible heading" outline-previous-visible-heading)
- ("n" "next visible heading" outline-next-visible-heading)])
-
- • Transient supports infix arguments; values that are set by infix
- commands and then consumed by the invoked suffix command(s).
-
- To my knowledge, Hydra does not support that.
-
- Both packages make it possible to specify how exactly the available
-commands are outlined:
-
- • With Hydra this is often done using an explicit format string,
- which gives authors a lot of flexibility and makes it possible to
- do fancy things.
-
- The downside of this is that it becomes harder for a user to add
- additional commands to an existing hydra and to change key
- bindings.
-
- • Transient allows the author of a transient to organize the commands
- into groups and the use of generic functions allows authors of
- transients to control exactly how a certain command type is
- displayed.
-
- However while Transient supports giving sections a heading it does
- not currently support giving the displayed information more
- structure by, for example, using box-drawing characters.
-
- That could be implemented by defining a new group class, which lets
- the author specify a format string. It should be possible to
- implement that without modifying any existing code, but it does not
- currently exist.
-
-
-File: transient.info, Node: FAQ, Next: Keystroke Index, Prev: Related Abstractions and Packages, Up: Top
-
-Appendix A FAQ
-**************
-
-A.1 Can I control how the popup buffer is displayed?
-====================================================
-
-Yes, see ‘transient-display-buffer-action’ in *note Other Options::.
-
-A.2 Why did some of the key bindings change?
-============================================
-
-You may have noticed that the bindings for some of the common commands
-do *not* have the prefix ‘C-x’ and that furthermore some of these
-commands are grayed out while others are not. That unfortunately is a
-bit confusing if the section of common commands is not shown
-permanently, making the following explanation necessary.
-
- The purpose of usually hiding that section but showing it after the
-user pressed the respective prefix key is to conserve space and not
-overwhelm users with too much noise, while allowing the user to quickly
-list common bindings on demand.
-
- That however should not keep us from using the best possible key
-bindings. The bindings that do use a prefix do so to avoid wasting too
-many non-prefix bindings, keeping them available for use in individual
-transients. The bindings that do not use a prefix and that are *not*
-grayed out are very important bindings that are *always* available, even
-when invoking the "common command key prefix" or *any other*
-transient-specific prefix. The non-prefix keys that *are* grayed out
-however, are not available when any incomplete prefix key sequence is
-active. They do not use the "common command key prefix" because it is
-likely that users want to invoke them several times in a row and e.g.
-‘M-p M-p M-p’ is much more convenient than ‘C-x M-p C-x M-p C-x M-p’.
-
- You may also have noticed that the "Set" command is bound to ‘C-x s’,
-while Magit-Popup used to bind ‘C-c C-c’ instead. I have seen several
-users praise the latter binding (sic), so I did not change it
-willy-nilly. The reason that I changed it is that using different
-prefix keys for different common commands, would have made the temporary
-display of the common commands even more confusing, i.e. after pressing
-‘C-c’ all the ‘C-x ...’ bindings would be grayed out.
-
- Using a single prefix for common commands key means that all other
-potential prefix keys can be used for transient-specific commands
-*without* the section of common commands also popping up. ‘C-c’ in
-particular is a prefix that I want to (and already do) use for Magit,
-and also using that for a common command would prevent me from doing so.
-
- (Also see the next question.)
-
-A.3 Why does ‘q’ not quit popups anymore?
-=========================================
-
-I agree that ‘q’ is a good binding for commands that quit something.
-This includes quitting whatever transient is currently active, but it
-also includes quitting whatever it is that some specific transient is
-controlling. The transient ‘magit-blame’ for example binds ‘q’ to the
-command that turns ‘magit-blame-mode’ off.
-
- So I had to decide if ‘q’ should quit the active transient (like
-Magit-Popup used to) or whether ‘C-g’ should do that instead, so that
-‘q’ could be bound in individual transient to whatever commands make
-sense for them. Because all other letters are already reserved for use
-by individual transients, I have decided to no longer make an exception
-for ‘q’.
-
- If you want to get ‘q’’s old binding back then you can do so. Doing
-that is a bit more complicated than changing a single key binding, so I
-have implemented a function, ‘transient-bind-q-to-quit’ that makes the
-necessary changes. See its doc string for more information.
-
-
-File: transient.info, Node: Keystroke Index, Next: Command Index, Prev: FAQ, Up: Top
-
-Appendix B Keystroke Index
-**************************
-
-
-* Menu:
-
-* C-g: Aborting and Resuming Transients.
- (line 25)
-* C-g <1>: Aborting and Resuming Transients.
- (line 26)
-* C-h: Getting Help for Suffix Commands.
- (line 10)
-* C-q: Aborting and Resuming Transients.
- (line 36)
-* C-x C-s: Saving Values. (line 25)
-* C-x l: Enabling and Disabling Suffixes.
- (line 49)
-* C-x s: Saving Values. (line 20)
-* C-x t: Common Suffix Commands.
- (line 16)
-* C-z: Aborting and Resuming Transients.
- (line 42)
-* M-n: Using History. (line 16)
-* M-p: Using History. (line 11)
-* M-x transient-resume: Aborting and Resuming Transients.
- (line 55)
-
-
-File: transient.info, Node: Command Index, Next: Function Index, Prev: Keystroke Index, Up: Top
-
-Appendix C Command Index
-************************
-
-
-* Menu:
-
-* transient-help: Getting Help for Suffix Commands.
- (line 10)
-* transient-history-next: Using History. (line 16)
-* transient-history-prev: Using History. (line 11)
-* transient-quit-all: Aborting and Resuming Transients.
- (line 36)
-* transient-quit-one: Aborting and Resuming Transients.
- (line 26)
-* transient-quit-seq: Aborting and Resuming Transients.
- (line 25)
-* transient-resume: Aborting and Resuming Transients.
- (line 55)
-* transient-save: Saving Values. (line 25)
-* transient-scroll-down arg: Other Commands. (line 18)
-* transient-scroll-up arg: Other Commands. (line 12)
-* transient-set: Saving Values. (line 20)
-* transient-set-level: Enabling and Disabling Suffixes.
- (line 49)
-* transient-suspend: Aborting and Resuming Transients.
- (line 42)
-* transient-toggle-common: Common Suffix Commands.
- (line 16)
-
-
-File: transient.info, Node: Function Index, Next: Variable Index, Prev: Command Index, Up: Top
-
-Appendix D Function Index
-*************************
-
-
-* Menu:
-
-* define-infix-argument: Defining Suffix and Infix Commands.
- (line 66)
-* define-infix-command: Defining Suffix and Infix Commands.
- (line 30)
-* define-suffix-command: Defining Suffix and Infix Commands.
- (line 9)
-* define-transient-command: Defining Transients. (line 13)
-* transient--do-call: Transient State. (line 98)
-* transient--do-exit: Transient State. (line 94)
-* transient--do-noop: Transient State. (line 125)
-* transient--do-quit-all: Transient State. (line 138)
-* transient--do-quit-one: Transient State. (line 132)
-* transient--do-replace: Transient State. (line 102)
-* transient--do-stay: Transient State. (line 85)
-* transient--do-suspend: Transient State. (line 144)
-* transient--do-warn: Transient State. (line 121)
-* transient--history-init: Prefix Classes. (line 10)
-* transient--insert-group: Group Methods. (line 6)
-* transient-append-suffix: Modifying Existing Transients.
- (line 47)
-* transient-args: Using Infix Arguments.
- (line 22)
-* transient-format: Suffix Format Methods.
- (line 6)
-* transient-format-description: Suffix Format Methods.
- (line 20)
-* transient-format-key: Suffix Format Methods.
- (line 15)
-* transient-format-value: Suffix Format Methods.
- (line 25)
-* transient-get-suffix: Modifying Existing Transients.
- (line 60)
-* transient-infix-read: Suffix Value Methods.
- (line 17)
-* transient-infix-set: Suffix Value Methods.
- (line 39)
-* transient-infix-value: Suffix Value Methods.
- (line 43)
-* transient-init-scope: Suffix Value Methods.
- (line 57)
-* transient-init-value: Suffix Value Methods.
- (line 6)
-* transient-insert-suffix: Modifying Existing Transients.
- (line 42)
-* transient-prompt: Suffix Value Methods.
- (line 34)
-* transient-remove-suffix: Modifying Existing Transients.
- (line 56)
-* transient-replace-suffix: Modifying Existing Transients.
- (line 51)
-* transient-scroll-down: Other Commands. (line 18)
-* transient-scroll-up: Other Commands. (line 12)
-* transient-show-help: Suffix Format Methods.
- (line 30)
-* transient-suffix-put: Modifying Existing Transients.
- (line 65)
-
-
-File: transient.info, Node: Variable Index, Prev: Function Index, Up: Top
-
-Appendix E Variable Index
-*************************
-
-
-* Menu:
-
-* current-transient-command: Using Infix Arguments.
- (line 47)
-* current-transient-prefix: Using Infix Arguments.
- (line 41)
-* current-transient-suffixes: Using Infix Arguments.
- (line 32)
-* transient-default-level: Enabling and Disabling Suffixes.
- (line 38)
-* transient-detect-key-conflicts: Other Options. (line 136)
-* transient-display-buffer-action: Other Options. (line 46)
-* transient-enable-popup-navigation: Other Options. (line 28)
-* transient-highlight-mismatched-keys: Other Options. (line 95)
-* transient-history-file: Using History. (line 33)
-* transient-history-limit: Using History. (line 38)
-* transient-levels-file: Enabling and Disabling Suffixes.
- (line 44)
-* transient-mode-line-format: Other Options. (line 71)
-* transient-read-with-initial-input: Other Options. (line 87)
-* transient-show-common-commands: Common Suffix Commands.
- (line 23)
-* transient-show-popup: Other Options. (line 6)
-* transient-substitute-key-function: Other Options. (line 114)
-* transient-values-file: Saving Values. (line 30)
-
-
-
-Tag Table:
-Node: Top751
-Node: Introduction3675
-Node: Usage9462
-Node: Invoking Transients9796
-Node: Aborting and Resuming Transients10828
-Node: Common Suffix Commands13487
-Node: Saving Values15241
-Ref: Saving Values-Footnote-116499
-Node: Using History16769
-Node: Getting Help for Suffix Commands18310
-Node: Enabling and Disabling Suffixes19703
-Node: Other Commands22993
-Node: Other Options23949
-Node: Modifying Existing Transients30562
-Node: Defining New Commands33966
-Node: Defining Transients34302
-Node: Binding Suffix and Infix Commands36734
-Node: Group Specifications37589
-Node: Suffix Specifications40922
-Node: Defining Suffix and Infix Commands44489
-Node: Using Infix Arguments47899
-Node: Transient State50119
-Node: Classes and Methods55992
-Node: Group Classes58206
-Node: Group Methods60123
-Node: Prefix Classes60768
-Node: Suffix Classes61860
-Node: Suffix Methods64104
-Node: Suffix Value Methods64425
-Node: Suffix Format Methods67185
-Node: Prefix Slots68637
-Node: Suffix Slots68801
-Node: Predicate Slots71652
-Node: Related Abstractions and Packages72900
-Node: Comparison With Prefix Keys and Prefix Arguments73187
-Node: Comparison With Other Packages83499
-Node: FAQ87690
-Node: Keystroke Index91424
-Node: Command Index93058
-Node: Function Index94845
-Node: Variable Index99002
-
-End Tag Table
-
-
-Local Variables:
-coding: utf-8
-End:
Copyright 2019--2024 Marius PETER