summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémi Vanicat <vanicat@debian.org>2021-11-06 10:56:32 +0100
committerRémi Vanicat <vanicat@debian.org>2021-11-06 10:56:32 +0100
commit5598125b9e1885c5964afb63fbb046f7fe2a661d (patch)
treee2f2124db932ec52aa88ccc50df29efa5cd922cd
parent9a4e41b934dce66a960c983256fe688a3b65b8c7 (diff)
parent5fbfeacd1188c9bf6cd9ce39a61957f23733135a (diff)
Update upstream source from tag 'upstream/0.3.7'
Update to upstream version '0.3.7' with Debian dir bed24b9fc0c89b99f71b127d876fa8492469543d
-rw-r--r--default.mk2
-rw-r--r--docs/CHANGELOG38
-rw-r--r--docs/Makefile4
-rw-r--r--docs/transient.org69
-rw-r--r--docs/transient.texi55
-rw-r--r--lisp/transient.el349
6 files changed, 329 insertions, 188 deletions
diff --git a/default.mk b/default.mk
index 28e03dc..4d6d0d2 100644
--- a/default.mk
+++ b/default.mk
@@ -3,7 +3,7 @@ PKG = transient
ELS = $(PKG).el
ELCS = $(ELS:.el=.elc)
-DEPS = dash
+DEPS =
VERSION ?= $(shell test -e $(TOP).git && git describe --tags --abbrev=0 | cut -c2-)
diff --git a/docs/CHANGELOG b/docs/CHANGELOG
index f92a727..61e01b2 100644
--- a/docs/CHANGELOG
+++ b/docs/CHANGELOG
@@ -1,4 +1,42 @@
# -*- mode: org -*-
+* v0.3.7 2021-10-25
+
+- Added an additional safety hatch to prevent Emacs from entering an
+ inconsistent state when an unexpected error occurs. 99e48369
+
+- Added support for implementing section movement commands in
+ third-party packages. This was requested by the maintainer of
+ Emacspeak. Because they would be of very limited use to sighted
+ users no such commands are added to Transient itself. 769219b5
+
+- ~transient-read-number-{N0,N+,N}~ now support infix arguments that
+ have three different states: disabled, enabled without an empty
+ value, and enabled with a non-empty value. 626d105e
+
+- If a command is called as a suffix of itself, then the help command
+ shows the function definition instead of the man-page as it usually
+ does for prefixes. e17e2b2f
+
+- Give users more control over how the transient buffer is displayed.
+ Various aspects that were previously hardcoded can now be changed
+ using the ~transient-display-buffer-action~ option. 7c677737
+
+- Added support for adding suffixes that might be neither defined nor
+ autoloaded when the prefix is invoked. This usually results in an
+ error and while it is now possible to override that using an extra
+ step, it is still discouraged. 6842305e
+
+Bug fixes:
+
+- 1e740608 transient-map: Bind C-u to universal-argument
+- e9048100 Explicitly call transient--pre-command in button action
+- be119ee4 Export variables for transient non-infix suffixes
+- b526b9c7 transient-infix-set: Consider all incompatibility rules
+- 7126d6aa Fix hydra-inspired colors
+- 0c2255a2 transient-get-value: Add an emergency exit
+
+Also contains various documentation updates and code clean-ups.
+
* v0.3.6 2021-07-01
- Added new option ~transient-force-single-column~, which may be useful
diff --git a/docs/Makefile b/docs/Makefile
index 1a75646..37cd779 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -7,8 +7,8 @@ info: $(PKG).info dir
html: $(PKG).html
pdf: $(PKG).pdf
-ORG_ARGS = --batch -Q $(ORG_LOAD_PATH) -l ox-extra -l ox-texinfo+.el
-ORG_EVAL = --eval "(ox-extras-activate '(ignore-headlines))"
+ORG_ARGS = --batch -Q $(ORG_LOAD_PATH) -l ox-texinfo+.el
+ORG_EVAL = --eval "(setq org-texinfo+-dissolve-noexport-headlines t)"
ORG_EVAL += --eval "(setq indent-tabs-mode nil)"
ORG_EVAL += --eval "(setq org-src-preserve-indentation nil)"
ORG_EVAL += --funcall org-texinfo-export-to-texinfo
diff --git a/docs/transient.org b/docs/transient.org
index 305684e..2211dd0 100644
--- a/docs/transient.org
+++ b/docs/transient.org
@@ -8,7 +8,7 @@
#+TEXINFO_DIR_CATEGORY: Emacs
#+TEXINFO_DIR_TITLE: Transient: (transient).
#+TEXINFO_DIR_DESC: Transient Commands
-#+SUBTITLE: for version 0.3.6
+#+SUBTITLE: for version 0.3.7
#+TEXINFO_DEFFN: t
#+OPTIONS: H:4 num:4 toc:2
@@ -37,7 +37,7 @@ Calling a suffix command usually causes the transient to be exited
but suffix commands can also be configured to not exit the transient.
#+TEXINFO: @noindent
-This manual is for Transient version 0.3.6.
+This manual is for Transient version 0.3.7.
#+BEGIN_QUOTE
Copyright (C) 2018-2021 Jonas Bernoulli <jonas@bernoul.li>
@@ -517,24 +517,39 @@ window, and the key bindings are the same as for ~scroll-up-command~ and
buffer. The transient popup buffer is displayed in a window using
~(display-buffer BUFFER transient-display-buffer-action)~.
- The value of this option has the form ~(FUNCTION . ALIST)~, where
- FUNCTION is a function or a list of functions. Each such function
- should accept two arguments: a buffer to display and an alist of the
- same form as ALIST. See [[info:elisp#Choosing Window]].
+ The value of this option has the form ~(FUNCTION . ALIST)~,
+ where FUNCTION is a function or a list of functions. Each such
+ function should accept two arguments: a buffer to display and an
+ alist of the same form as ALIST. See [[info:elisp#Choosing Window]]
+ for details.
+
+ The default is:
+
+ (display-buffer-in-side-window
+ (side . bottom)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
- 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:elisp#Display Action Functions]].
+ Another useful FUNCTION is ~display-buffer-below-selected~, which
+ is what ~magit-popup~ used by default. For more alternatives see
+ [[info:elisp#Display Action Functions]] and [[info:elisp#Buffer Display
+ Action Alists]].
+
+ Note that the buffer that was current before the transient buffer
+ is shown should remain the current buffer. Many suffix commands
+ act on the thing at point, if appropriate, and if the transient
+ buffer became the current buffer, then that would change what is
+ at point. To that effect ~inhibit-same-window~ ensures that the
+ selected window is not used to show the transient buffer.
It may be possible to display the window in another frame, but
whether that works in practice depends on the window-manager.
If the window manager selects the new window (Emacs frame),
- then it doesn't work.
+ then that unfortunately changes which buffer is current.
- If you change the value of this option, then you might also want
- to change the value of ~transient-mode-line-format~.
+ 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
@@ -755,7 +770,7 @@ that is used to invoke that transient.
the branch whose variables are being configured.
** Binding Suffix and Infix Commands
-*** _ :ignore:
+*** _
The macro ~transient-define-prefix~ is used to define a transient.
This defines the actual transient prefix command (see [[*Defining
@@ -923,6 +938,18 @@ argument that is mandatory in all cases.
be set in the suffix specification. Therefore if there is no object,
then you have to make sure to specify the KEY and the DESCRIPTION.
+ As a special case, if you want to add a command that might be neither
+ defined nor autoloaded, you can use a workaround like:
+
+ #+BEGIN_SRC emacs-lisp
+ (transient-insert-suffix 'some-prefix "k"
+ '("!" "Ceci n'est pas une commande" no-command
+ :if (lambda () (featurep 'no-library))))
+ #+END_SRC
+
+ Instead of ~featurep~ you could also use ~require~ with a non-nil value
+ for NOERROR.
+
- The mandatory argument can also be a command-line argument, a
string. In that case an anonymous command is defined and bound.
@@ -1077,7 +1104,7 @@ function, which for infix arguments serves about the same purpose as
returned value is a symbol, the transient prefix command.
** Transient State
-*** _ :ignore:
+*** _
Invoking a transient prefix command "activates" the respective
transient, i.e. it puts a transient keymap into effect, which binds
@@ -1230,7 +1257,7 @@ slot.
This is used when the user pressed ~C-z~.
* Classes and Methods
-** _ :ignore:
+** _
Transient uses classes and generic functions to make it possible to
define new types of suffix commands that are similar to existing
@@ -1406,7 +1433,7 @@ classes will likely get generalized and added to Transient. For now
they are very much subject to change and not documented.
** Suffix Methods
-*** _ :ignore:
+*** _
To get information about the methods implementing these generic
functions use ~describe-function~.
@@ -1537,7 +1564,8 @@ functions use ~describe-function~.
- ~incompatible~ A list of lists. Each sub-list specifies a set of
mutually exclusive arguments. Enabling one of these arguments
- causes the others to be disabled.
+ causes the others to be disabled. An argument may appear in
+ multiple sub-lists.
- ~scope~ For some transients it might be necessary to have a sort of
secondary value, called a "scope". See ~transient-define-prefix~.
@@ -2114,8 +2142,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
#+END_QUOTE
-* _ :ignore:
-
# LocalWords: ARGLIST ARGS DOCSTRING ELEMENTs EVAL GROUPs Infixes
# LocalWords: Infixes KEYWORDs LOC LocalWords MERCHANTABILITY Magit
# LocalWords: Magit's Makefile OBJ OBJ's Pre arglist
@@ -2127,9 +2153,8 @@ General Public License for more details.
# IMPORTANT: Also update ORG_ARGS and ORG_EVAL in the Makefile.
# Local Variables:
-# eval: (require 'ox-extra nil t)
# eval: (require 'ox-texinfo+ nil t)
-# eval: (and (featurep 'ox-extra) (ox-extras-activate '(ignore-headlines)))
+# org-texinfo+-dissolve-noexport-headlines: t
# indent-tabs-mode: nil
# org-src-preserve-indentation: nil
# End:
diff --git a/docs/transient.texi b/docs/transient.texi
index 9134e20..232e762 100644
--- a/docs/transient.texi
+++ b/docs/transient.texi
@@ -31,7 +31,7 @@ General Public License for more details.
@finalout
@titlepage
@title Transient User and Developer Manual
-@subtitle for version 0.3.6
+@subtitle for version 0.3.7
@author Jonas Bernoulli
@page
@vskip 0pt plus 1filll
@@ -65,7 +65,7 @@ Calling a suffix command usually causes the transient to be exited
but suffix commands can also be configured to not exit the transient.
@noindent
-This manual is for Transient version 0.3.6.
+This manual is for Transient version 0.3.7.
@quotation
Copyright (C) 2018-2021 Jonas Bernoulli <jonas@@bernoul.li>
@@ -708,24 +708,38 @@ This option specifies the action used to display the transient popup
buffer. The transient popup buffer is displayed in a window using
@code{(display-buffer BUFFER transient-display-buffer-action)}.
-The value of this option has the form @code{(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 @ref{Choosing Window,,,elisp,}.
+The value of this option has the form @code{(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 @ref{Choosing Window,,,elisp,}
+for details.
+
+The default is:
+
+(display-buffer-in-side-window
+ (side . bottom)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
-The default is @code{(display-buffer-in-side-window (side . bottom))}.
This displays the window at the bottom of the selected frame.
-Another useful value is @code{(display-buffer-below-selected)}. This is
-what @code{magit-popup} used by default. For more alternatives see
-@ref{Display Action Functions,,,elisp,}.
+Another useful FUNCTION is @code{display-buffer-below-selected}, which
+is what @code{magit-popup} used by default. For more alternatives see
+@ref{Display Action Functions,,,elisp,} and @ref{Buffer Display Action Alists,,,elisp,}.
+
+Note that the buffer that was current before the transient buffer
+is shown should remain the current buffer. Many suffix commands
+act on the thing at point, if appropriate, and if the transient
+buffer became the current buffer, then that would change what is
+at point. To that effect @code{inhibit-same-window} ensures that the
+selected window is not used to show the transient buffer.
It may be possible to display the window in another frame, but
whether that works in practice depends on the window-manager.
If the window manager selects the new window (Emacs frame),
-then it doesn't work.
+then that unfortunately changes which buffer is current.
-If you change the value of this option, then you might also want
-to change the value of @code{transient-mode-line-format}.
+If you change the value of this option, then you might also
+want to change the value of @code{transient-mode-line-format}.
@end defopt
@defopt transient-mode-line-format
@@ -1170,6 +1184,18 @@ be used to set the default for certain values that otherwise have to
be set in the suffix specification. Therefore if there is no object,
then you have to make sure to specify the KEY and the DESCRIPTION@.
+As a special case, if you want to add a command that might be neither
+defined nor autoloaded, you can use a workaround like:
+
+@lisp
+(transient-insert-suffix 'some-prefix "k"
+ '("!" "Ceci n'est pas une commande" no-command
+ :if (lambda () (featurep 'no-library))))
+@end lisp
+
+Instead of @code{featurep} you could also use @code{require} with a non-nil value
+for NOERROR@.
+
@item
The mandatory argument can also be a command-line argument, a
@@ -1898,7 +1924,8 @@ command is invoked. See @ref{Transient State}.
@item
@code{incompatible} A list of lists. Each sub-list specifies a set of
mutually exclusive arguments. Enabling one of these arguments
-causes the others to be disabled.
+causes the others to be disabled. An argument may appear in
+multiple sub-lists.
@item
diff --git a/lisp/transient.el b/lisp/transient.el
index 5f66a13..d0ba854 100644
--- a/lisp/transient.el
+++ b/lisp/transient.el
@@ -7,7 +7,7 @@
;; Keywords: bindings
;; Package-Requires: ((emacs "25.1"))
-;; Package-Version: 0.3.6
+;; Package-Version: 0.3.7
;; SPDX-License-Identifier: GPL-3.0-or-later
@@ -54,6 +54,7 @@
(require 'cl-lib)
(require 'eieio)
+(require 'edmacro)
(require 'format-spec)
(require 'seq)
@@ -74,7 +75,7 @@
(define-obsolete-function-alias 'define-infix-command
'transient-define-infix "Transient 0.3.0")
(define-obsolete-function-alias 'define-infix-argument
- 'transient-define-argument "Transient 0.3.0")
+ #'transient-define-argument "Transient 0.3.0")
(define-obsolete-variable-alias 'current-transient-prefix
'transient-current-prefix "Transient 0.3.0")
@@ -148,34 +149,46 @@ features are available:
(defcustom transient-display-buffer-action
'(display-buffer-in-side-window
(side . bottom)
- (inhibit-same-window . t))
+ (dedicated . t)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
"The action used to display the transient popup buffer.
The transient popup buffer is displayed in a window using
- \(display-buffer buf transient-display-buffer-action)
+ (display-buffer BUFFER transient-display-buffer-action)
The value of this option has the form (FUNCTION . ALIST),
where FUNCTION is a function or a list of functions. Each such
-function should accept two arguments: a buffer to display and
-an alist of the same form as ALIST. See `display-buffer' for
-details.
+function should accept two arguments: a buffer to display and an
+alist of the same form as ALIST. See info node `(elisp)Choosing
+Window' for details.
The default is:
(display-buffer-in-side-window
(side . bottom)
- (inhibit-same-window . t))
+ (dedicated . t)
+ (inhibit-same-window . t)
+ (window-parameters (no-other-window . t)))
This displays the window at the bottom of the selected frame.
-Another useful value is (display-buffer-below-selected). This
-is what `magit-popup' used by default. For more alternatives
-see info node `(elisp)Display Action Functions'.
+Another useful FUNCTION is `display-buffer-below-selected', which
+is what `magit-popup' used by default. For more alternatives see
+info node `(elisp)Display Action Functions' and info node
+`(elisp)Buffer Display Action Alists'.
+
+Note that the buffer that was current before the transient buffer
+is shown should remain the current buffer. Many suffix commands
+act on the thing at point, if appropriate, and if the transient
+buffer became the current buffer, then that would change what is
+at point. To that effect `inhibit-same-window' ensures that the
+selected window is not used to show the transient buffer.
It may be possible to display the window in another frame, but
whether that works in practice depends on the window-manager.
If the window manager selects the new window (Emacs frame),
-then it doesn't work.
+then that unfortunately changes which buffer is current.
If you change the value of this option, then you might also
want to change the value of `transient-mode-line-format'."
@@ -266,7 +279,7 @@ 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.
+using a layout optimized for Lisp.
(setq transient-substitute-key-function
(lambda (obj)
@@ -569,7 +582,7 @@ If `transient-save-history' is nil, then do nothing."
(transient-save-history)))
(unless noninteractive
- (add-hook 'kill-emacs-hook 'transient-maybe-save-history))
+ (add-hook 'kill-emacs-hook #'transient-maybe-save-history))
;;; Classes
;;;; Prefix
@@ -640,7 +653,7 @@ the prototype is stored in the clone's `prototype' slot.")
:initarg :if-not-derived
:initform nil
:documentation "Enable if major-mode does not derive from value."))
- "Abstract superclass for group and and suffix classes.
+ "Abstract superclass for group and suffix classes.
It is undefined what happens if more than one `if*' predicate
slot is non-nil."
@@ -729,7 +742,7 @@ slot is non-nil."
(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.")
+They become the value of this argument.")
;;;; Group
@@ -910,7 +923,7 @@ keyword.
(put ',name 'transient--suffix
(,(or class 'transient-switch) :command ',name ,@slots)))))
-(defalias 'transient-define-argument 'define-infix-command
+(defalias 'transient-define-argument #'transient-define-infix
"Define NAME as a transient infix command.
Only use this alias to define an infix command that actually
@@ -1061,7 +1074,8 @@ example, sets a variable use `transient-define-infix' instead.
(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)))))
+ (when (transient--use-suffix-p obj)
+ (error "Suffix %s is not defined or autoloaded as a command" cmd))))))
(defun transient--derive-shortarg (arg)
(save-match-data
@@ -1415,14 +1429,14 @@ then just return it. Otherwise return the symbol whose
(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 "C-M-v") 'transient-scroll-down)
- (define-key map [next] 'transient-scroll-up)
- (define-key map [prior] 'transient-scroll-down)
+ (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 "C-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.
@@ -1442,14 +1456,14 @@ to `transient-predicate-map'.")
(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 "C-u") #'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)
;; Also bound to "C-x p" and "C-x n" in transient-common-commands.
- (define-key map (kbd "C-M-p") 'transient-history-prev)
- (define-key map (kbd "C-M-n") 'transient-history-next)
+ (define-key map (kbd "C-M-p") #'transient-history-prev)
+ (define-key map (kbd "C-M-n") #'transient-history-next)
map)
"Top-level keymap used by all transients.
@@ -1459,16 +1473,16 @@ to `transient-predicate-map'. Also see `transient-base-map'.")
(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)
+ (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)
+ (define-key map (kbd "C-g") #'transient-quit-seq)
map)
"Keymap that is active while an incomplete key sequence is active.")
@@ -1503,36 +1517,36 @@ to `transient-predicate-map'. Also see `transient-base-map'.")
(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 [scroll-bar-toolkit-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)
+ (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 [scroll-bar-toolkit-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.
@@ -1606,22 +1620,23 @@ of the corresponding object.")
(sym (transient--suffix-symbol cmd)))
(cond
((oref obj inapt)
- (define-key map (vector sym) 'transient--do-warn-inapt))
+ (define-key map (vector sym) #'transient--do-warn-inapt))
((slot-boundp obj 'transient)
(define-key map (vector sym)
(let ((do (oref obj transient)))
(pcase do
- (`t (if sub-prefix
- 'transient--do-replace
- 'transient--do-stay))
+ (`t (cond (sub-prefix #'transient--do-replace)
+ ((cl-typep obj 'transient-infix)
+ #'transient--do-stay)
+ (t #'transient--do-call)))
(`nil 'transient--do-exit)
(_ do)))))
((not (lookup-key transient-predicate-map (vector sym)))
(define-key map (vector sym)
(if sub-prefix
- 'transient--do-replace
+ #'transient--do-replace
(or (oref transient--prefix transient-suffix)
- 'transient--do-exit)))))))
+ #'transient--do-exit)))))))
map))
(defun transient--make-redisplay-map ()
@@ -1649,7 +1664,7 @@ of the corresponding object.")
(listp def)
(keymapp def))
(define-key topmap (vconcat transient--redisplay-key (list key))
- 'transient-update)))
+ #'transient-update)))
(if transient--redisplay-key
(lookup-key transient--transient-map (vconcat transient--redisplay-key))
transient--transient-map))
@@ -1678,7 +1693,7 @@ EDIT may be non-nil."
(transient--pop-keymap 'transient--redisplay-map)
(setq name (oref transient--prefix command))
(setq params (list :scope (oref transient--prefix scope))))
- (transient--transient-map
+ (transient--prefix
;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}"
;; of an outer prefix. Unlike the usual `transient--do-replace',
;; these predicates fail to clean up after the outer prefix.
@@ -1953,8 +1968,10 @@ value. Otherwise return CHILDREN as is."
(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))
+ ;; Only delete the window if it never showed another buffer.
+ (unless (eq (car (window-parameter transient--window 'quit-restore)) 'other)
+ (with-demoted-errors "Error while exiting transient: %S"
+ (delete-window transient--window)))
(kill-buffer buf))))
(defun transient--export ()
@@ -2093,8 +2110,8 @@ value. Otherwise return CHILDREN as is."
(defun transient--emergency-exit ()
"Exit the current transient command after an error occurred.
-When no transient is active (i.e. when `transient--prefix') is
-nil, then do nothing."
+When no transient is active (i.e. when `transient--prefix' is
+nil) then do nothing."
(transient--debug 'emergency-exit)
(when transient--prefix
(setq transient--stack nil)
@@ -2171,17 +2188,17 @@ to `transient--do-warn'."
(setq this-command 'transient-popup-navigation-help))
transient--stay)
-(put 'transient--do-stay 'transient-color 'transient-blue)
-(put 'transient--do-noop 'transient-color 'transient-blue)
-(put 'transient--do-warn 'transient-color 'transient-blue)
-(put 'transient--do-warn-inapt 'transient-color 'transient-blue)
-(put 'transient--do-call 'transient-color 'transient-blue)
-(put 'transient--do-exit 'transient-color 'transient-red)
-(put 'transient--do-replace 'transient-color 'transient-red)
-(put 'transient--do-suspend 'transient-color 'transient-red)
-(put 'transient--do-quit-one 'transient-color 'transient-red)
-(put 'transient--do-quit-all 'transient-color 'transient-red)
-(put 'transient--do-move 'transient-color 'transient-blue)
+(put 'transient--do-stay 'transient-color 'transient-red)
+(put 'transient--do-noop 'transient-color 'transient-red)
+(put 'transient--do-warn 'transient-color 'transient-red)
+(put 'transient--do-warn-inapt 'transient-color 'transient-red)
+(put 'transient--do-call 'transient-color 'transient-red)
+(put 'transient--do-exit 'transient-color 'transient-blue)
+(put 'transient--do-replace 'transient-color 'transient-blue)
+(put 'transient--do-suspend 'transient-color 'transient-blue)
+(put 'transient--do-quit-one 'transient-color 'transient-blue)
+(put 'transient--do-quit-all 'transient-color 'transient-blue)
+(put 'transient--do-move 'transient-color 'transient-red)
;;; Commands
@@ -2209,7 +2226,18 @@ to `transient--do-warn'."
(propertize "?" 'face 'transient-key)
(propertize (symbol-name (transient--suffix-symbol
this-original-command))
- 'face 'font-lock-warning-face)))
+ 'face 'font-lock-warning-face))
+ (unless (and transient--transient-map
+ (memq transient--transient-map overriding-terminal-local-map))
+ (let ((transient--prefix (or transient--prefix 'sic)))
+ (transient--emergency-exit))
+ (view-lossage)
+ (other-window 1)
+ (display-warning 'transient "Inconsistent transient state detected.
+This should never happen.
+Please open an issue and post the shown command log.
+This is a heisenbug, so any additional details might help.
+Thanks!" :error)))
(defun transient-toggle-common ()
"Toggle whether common commands are always shown."
@@ -2407,14 +2435,14 @@ Non-infix suffix commands usually don't have a value."
(cl-defmethod transient-init-value :around ((obj transient-prefix))
"If bound, then call OBJ's `init-value' function.
-Otherwise call the primary method according to objects class."
+Otherwise call the primary method according to object's class."
(if (slot-boundp obj 'init-value)
(funcall (oref obj init-value) obj)
(cl-call-next-method obj)))
(cl-defmethod transient-init-value :around ((obj transient-infix))
"If bound, then call OBJ's `init-value' function.
-Otherwise call the primary method according to objects class."
+Otherwise call the primary method according to object's class."
(if (slot-boundp obj 'init-value)
(funcall (oref obj init-value) obj)
(cl-call-next-method obj)))
@@ -2595,13 +2623,12 @@ stand-alone command."
(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))))
+ (when (or (string-equal str "")
+ (string-match-p (if include-zero
+ "\\`\\(0\\|[1-9][0-9]*\\)\\'"
+ "\\`[1-9][0-9]*\\'")
+ str))
+ (cl-return str)))
(message "Please enter a natural number (%s zero)."
(if include-zero "including" "excluding"))
(sit-for 1)))))
@@ -2670,7 +2697,10 @@ prompt."
(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))))
+ (incomp (cl-mapcan (lambda (rule)
+ (and (member arg rule)
+ (remove arg rule)))
+ spec)))
(progn
(cl-call-next-method obj value)
(dolist (arg incomp)
@@ -2703,7 +2733,7 @@ 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."
- (delq nil (mapcar 'transient-infix-value (transient-suffixes prefix))))
+ (delq nil (mapcar #'transient-infix-value (transient-suffixes prefix))))
(defun transient-suffixes (prefix)
"Return the suffix objects of the transient prefix command PREFIX."
@@ -2714,11 +2744,12 @@ the set, saved or default value for PREFIX."
(transient--init-suffixes prefix)))))
(defun transient-get-value ()
- (delq nil (mapcar (lambda (obj)
- (and (or (not (slot-exists-p obj 'unsavable))
- (not (oref obj unsavable)))
- (transient-infix-value obj)))
- transient-current-suffixes)))
+ (transient--with-emergency-exit
+ (delq nil (mapcar (lambda (obj)
+ (and (or (not (slot-exists-p obj 'unsavable))
+ (not (oref obj unsavable)))
+ (transient-infix-value obj)))
+ transient-current-suffixes))))
(cl-defgeneric transient-infix-value (obj)
"Return the value of the suffix object OBJ.
@@ -2736,7 +2767,7 @@ Usually only infixes have a value, but see the method for
(cl-defmethod transient-infix-value ((_ transient-suffix))
"Return nil, which means \"no value\".
-Infix arguments contribute the the transient's value while suffix
+Infix arguments contribute the transient's value while suffix
commands consume it. This function is called for suffixes anyway
because a command that both contributes to the transient's value
and also consumes it is not completely unconceivable.
@@ -2860,16 +2891,11 @@ have a history of their own.")
(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
+ (with-current-buffer buf
(when transient-enable-popup-navigation
- (setq focus (button-get (point) 'command)))
+ (setq focus (or (button-get (point) 'command)
+ (transient--heading-at-point))))
(erase-buffer)
- (set-window-hscroll transient--window 0)
- (set-window-dedicated-p transient--window t)
- (set-window-parameter transient--window 'no-other-window t)
(setq window-size-fixed t)
(when (bound-and-true-p tab-line-format)
(setq tab-line-format nil))
@@ -2896,14 +2922,26 @@ have a history of their own.")
'transient-separator)))
(insert (propertize "__" 'face face 'display '(space :height (1))))
(insert (propertize "\n" 'face face 'line-height t))))
- (let ((window-resize-pixelwise t)
- (window-size-fixed nil))
- (fit-window-to-buffer nil nil 1))
(goto-char (point-min))
(when transient-force-fixed-pitch
(transient--force-fixed-pitch))
(when transient-enable-popup-navigation
- (transient--goto-button focus)))))
+ (transient--goto-button focus)))
+ (unless (window-live-p transient--window)
+ (setq transient--window
+ (display-buffer buf transient-display-buffer-action)))
+ (when (window-live-p transient--window)
+ (with-selected-window transient--window
+ (magit--fit-window-to-buffer transient--window)))))
+
+(defun magit--fit-window-to-buffer (window)
+ (let ((window-resize-pixelwise t)
+ (window-size-fixed nil))
+ (if (eq (car (window-parameter window 'quit-restore)) 'other)
+ ;; Grow but never shrink window that previously displayed
+ ;; another buffer and is going to display that again.
+ (fit-window-to-buffer window nil (window-height window))
+ (fit-window-to-buffer window nil 1))))
(defun transient--insert-groups ()
(let ((groups (cl-mapcan (lambda (group)
@@ -2946,7 +2984,7 @@ have a history of their own.")
(mapcar
(lambda (column)
(transient--maybe-pad-keys column group)
- (let ((rows (mapcar 'transient-format (oref column suffixes))))
+ (let ((rows (mapcar #'transient-format (oref column suffixes))))
(when-let ((desc (transient-format-description column)))
(push desc rows))
rows))
@@ -3249,12 +3287,13 @@ Show the first one that is specified."
(cl-defmethod transient-show-help ((obj transient-suffix))
"Show the command doc-string."
- (if (eq this-original-command 'transient-help)
+ (if (eq this-command 'transient-help)
(if-let ((manpage (oref transient--prefix man-page)))
(transient--show-manpage manpage)
(transient--describe-function (oref transient--prefix command)))
(if-let ((prefix (get (transient--suffix-command obj) 'transient--prefix))
- (manpage (oref prefix man-page)))
+ (manpage (oref prefix man-page))
+ (- (not (eq this-command (oref transient--prefix command)))))
(transient--show-manpage manpage)
(transient--describe-function this-original-command))))
@@ -3366,9 +3405,9 @@ Suffixes on levels %s and %s are unavailable.\n"
(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)
+ (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'.
@@ -3395,19 +3434,20 @@ resumes the suspended transient.")
;; Yes, I know that this is wrong(tm).
;; Unfortunately it is also necessary.
(setq this-original-command command)
+ (transient--pre-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)
+ (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)
@@ -3436,22 +3476,32 @@ See `forward-button' for information about N."
(forward-button n t)))
(defun transient--goto-button (command)
- (if (not command)
- (forward-button 1)
+ (cond
+ ((stringp command)
+ (when (re-search-forward (concat "^" (regexp-quote command)) nil t)
+ (goto-char (match-beginning 0))))
+ (command
(while (and (ignore-errors (forward-button 1))
(not (eq (button-get (button-at (point)) 'command) command))))
(unless (eq (button-get (button-at (point)) 'command) command)
(goto-char (point-min))
- (forward-button 1))))
+ (forward-button 1)))))
+
+(defun transient--heading-at-point ()
+ (and (eq (get-text-property (point) 'face) 'transient-heading)
+ (let ((beg (line-beginning-position)))
+ (buffer-substring-no-properties
+ beg (next-single-property-change
+ beg 'face nil (line-end-position))))))
;;;; 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)
+ (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)
@@ -3537,14 +3587,14 @@ search instead."
(funcall fn arg-mode)
(transient--resume-override t)))
-(advice-add 'edebug--recursive-edit :around 'transient--edebug--recursive-edit)
+(advice-add 'edebug--recursive-edit :around #'transient--edebug--recursive-edit)
(defun transient--abort-edebug ()
(when (bound-and-true-p edebug-active)
(transient--emergency-exit)))
-(advice-add 'abort-recursive-edit :before 'transient--abort-edebug)
-(advice-add 'top-level :before 'transient--abort-edebug)
+(advice-add 'abort-recursive-edit :before #'transient--abort-edebug)
+(advice-add 'top-level :before #'transient--abort-edebug)
(defun transient--edebug-command-p ()
(and (bound-and-true-p edebug-active)
@@ -3558,12 +3608,12 @@ search instead."
(defun transient--suspend-which-key-mode ()
(when (bound-and-true-p which-key-mode)
(which-key-mode -1)
- (add-hook 'transient-exit-hook 'transient--resume-which-key-mode)))
+ (add-hook 'transient-exit-hook #'transient--resume-which-key-mode)))
(defun transient--resume-which-key-mode ()
(unless transient--prefix
(which-key-mode 1)
- (remove-hook 'transient-exit-hook 'transient--resume-which-key-mode)))
+ (remove-hook 'transient-exit-hook #'transient--resume-which-key-mode)))
(defun transient-bind-q-to-quit ()
"Modify some keymaps to bind \"q\" to the appropriate quit command.
@@ -3583,10 +3633,10 @@ 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)
+ (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))
+ #'transient-rebind-quit-commands))
(defun transient-rebind-quit-commands (obj)
"See `transient-bind-q-to-quit'."
@@ -3672,5 +3722,6 @@ we stop there."
(provide 'transient)
;; Local Variables:
;; indent-tabs-mode: nil
+;; checkdoc-symbol-words: ("command-line" "edit-mode" "help-mode")
;; End:
;;; transient.el ends here