* lisp/transient.el: Update to package version 0.3.7.

This commit is contained in:
Jonas Bernoulli 2021-10-25 20:19:52 +02:00
parent 40400e6977
commit 284c77eeb6

View file

@ -7,7 +7,7 @@
;; Keywords: bindings ;; Keywords: bindings
;; Package-Requires: ((emacs "25.1")) ;; Package-Requires: ((emacs "25.1"))
;; Package-Version: 0.3.6 ;; Package-Version: 0.3.7
;; SPDX-License-Identifier: GPL-3.0-or-later ;; SPDX-License-Identifier: GPL-3.0-or-later
@ -54,6 +54,7 @@
(require 'cl-lib) (require 'cl-lib)
(require 'eieio) (require 'eieio)
(require 'edmacro)
(require 'format-spec) (require 'format-spec)
(require 'seq) (require 'seq)
@ -74,7 +75,7 @@
(define-obsolete-function-alias 'define-infix-command (define-obsolete-function-alias 'define-infix-command
'transient-define-infix "Transient 0.3.0") 'transient-define-infix "Transient 0.3.0")
(define-obsolete-function-alias 'define-infix-argument (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 (define-obsolete-variable-alias 'current-transient-prefix
'transient-current-prefix "Transient 0.3.0") 'transient-current-prefix "Transient 0.3.0")
@ -148,34 +149,46 @@ features are available:
(defcustom transient-display-buffer-action (defcustom transient-display-buffer-action
'(display-buffer-in-side-window '(display-buffer-in-side-window
(side . bottom) (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 action used to display the transient popup buffer.
The transient popup buffer is displayed in a window using 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), The value of this option has the form (FUNCTION . ALIST),
where FUNCTION is a function or a list of functions. Each such where FUNCTION is a function or a list of functions. Each such
function should accept two arguments: a buffer to display and function should accept two arguments: a buffer to display and an
an alist of the same form as ALIST. See `display-buffer' for alist of the same form as ALIST. See info node `(elisp)Choosing
details. Window' for details.
The default is: The default is:
(display-buffer-in-side-window (display-buffer-in-side-window
(side . bottom) (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. This displays the window at the bottom of the selected frame.
Another useful value is (display-buffer-below-selected). This Another useful FUNCTION is `display-buffer-below-selected', which
is what `magit-popup' used by default. For more alternatives is what `magit-popup' used by default. For more alternatives see
see info node `(elisp)Display Action Functions'. 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 It may be possible to display the window in another frame, but
whether that works in practice depends on the window-manager. whether that works in practice depends on the window-manager.
If the window manager selects the new window (Emacs frame), 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 If you change the value of this option, then you might also
want to change the value of `transient-mode-line-format'." want to change the value of `transient-mode-line-format'."
@ -569,7 +582,7 @@ If `transient-save-history' is nil, then do nothing."
(transient-save-history))) (transient-save-history)))
(unless noninteractive (unless noninteractive
(add-hook 'kill-emacs-hook 'transient-maybe-save-history)) (add-hook 'kill-emacs-hook #'transient-maybe-save-history))
;;; Classes ;;; Classes
;;;; Prefix ;;;; Prefix
@ -910,7 +923,7 @@ keyword.
(put ',name 'transient--suffix (put ',name 'transient--suffix
(,(or class 'transient-switch) :command ',name ,@slots))))) (,(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. "Define NAME as a transient infix command.
Only use this alias to define an infix command that actually 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 (put cmd 'transient--infix-command
(transient--default-infix-command)) (transient--default-infix-command))
;; This is not an anonymous infix argument. ;; 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) (defun transient--derive-shortarg (arg)
(save-match-data (save-match-data
@ -1415,14 +1429,14 @@ then just return it. Otherwise return the symbol whose
(defvar transient-base-map (defvar transient-base-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map (kbd "ESC ESC ESC") 'transient-quit-all) (define-key map (kbd "ESC ESC ESC") #'transient-quit-all)
(define-key map (kbd "C-g") 'transient-quit-one) (define-key map (kbd "C-g") #'transient-quit-one)
(define-key map (kbd "C-q") 'transient-quit-all) (define-key map (kbd "C-q") #'transient-quit-all)
(define-key map (kbd "C-z") 'transient-suspend) (define-key map (kbd "C-z") #'transient-suspend)
(define-key map (kbd "C-v") 'transient-scroll-up) (define-key map (kbd "C-v") #'transient-scroll-up)
(define-key map (kbd "C-M-v") 'transient-scroll-down) (define-key map (kbd "C-M-v") #'transient-scroll-down)
(define-key map [next] 'transient-scroll-up) (define-key map [next] #'transient-scroll-up)
(define-key map [prior] 'transient-scroll-down) (define-key map [prior] #'transient-scroll-down)
map) map)
"Parent of other keymaps used by Transient. "Parent of other keymaps used by Transient.
@ -1442,14 +1456,14 @@ to `transient-predicate-map'.")
(defvar transient-map (defvar transient-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(set-keymap-parent map transient-base-map) (set-keymap-parent map transient-base-map)
(define-key map (kbd "C-p") 'universal-argument) (define-key map (kbd "C-u") #'universal-argument)
(define-key map (kbd "C--") 'negative-argument) (define-key map (kbd "C--") #'negative-argument)
(define-key map (kbd "C-t") 'transient-show) (define-key map (kbd "C-t") #'transient-show)
(define-key map (kbd "?") 'transient-help) (define-key map (kbd "?") #'transient-help)
(define-key map (kbd "C-h") 'transient-help) (define-key map (kbd "C-h") #'transient-help)
;; Also bound to "C-x p" and "C-x n" in transient-common-commands. ;; 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-p") #'transient-history-prev)
(define-key map (kbd "C-M-n") 'transient-history-next) (define-key map (kbd "C-M-n") #'transient-history-next)
map) map)
"Top-level keymap used by all transients. "Top-level keymap used by all transients.
@ -1459,16 +1473,16 @@ to `transient-predicate-map'. Also see `transient-base-map'.")
(defvar transient-edit-map (defvar transient-edit-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(set-keymap-parent map transient-base-map) (set-keymap-parent map transient-base-map)
(define-key map (kbd "?") 'transient-help) (define-key map (kbd "?") #'transient-help)
(define-key map (kbd "C-h") 'transient-help) (define-key map (kbd "C-h") #'transient-help)
(define-key map (kbd "C-x l") 'transient-set-level) (define-key map (kbd "C-x l") #'transient-set-level)
map) map)
"Keymap that is active while a transient in is in \"edit mode\".") "Keymap that is active while a transient in is in \"edit mode\".")
(defvar transient-sticky-map (defvar transient-sticky-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(set-keymap-parent map transient-base-map) (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) map)
"Keymap that is active while an incomplete key sequence is active.") "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 (defvar transient-predicate-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map [handle-switch-frame] 'transient--do-suspend) (define-key map [handle-switch-frame] #'transient--do-suspend)
(define-key map [transient-suspend] 'transient--do-suspend) (define-key map [transient-suspend] #'transient--do-suspend)
(define-key map [transient-help] 'transient--do-stay) (define-key map [transient-help] #'transient--do-stay)
(define-key map [transient-set-level] '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-prev] #'transient--do-stay)
(define-key map [transient-history-next] 'transient--do-stay) (define-key map [transient-history-next] #'transient--do-stay)
(define-key map [universal-argument] 'transient--do-stay) (define-key map [universal-argument] #'transient--do-stay)
(define-key map [negative-argument] 'transient--do-stay) (define-key map [negative-argument] #'transient--do-stay)
(define-key map [digit-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-all] #'transient--do-quit-all)
(define-key map [transient-quit-one] 'transient--do-quit-one) (define-key map [transient-quit-one] #'transient--do-quit-one)
(define-key map [transient-quit-seq] 'transient--do-stay) (define-key map [transient-quit-seq] #'transient--do-stay)
(define-key map [transient-show] 'transient--do-stay) (define-key map [transient-show] #'transient--do-stay)
(define-key map [transient-update] 'transient--do-stay) (define-key map [transient-update] #'transient--do-stay)
(define-key map [transient-toggle-common] 'transient--do-stay) (define-key map [transient-toggle-common] #'transient--do-stay)
(define-key map [transient-set] 'transient--do-call) (define-key map [transient-set] #'transient--do-call)
(define-key map [transient-save] '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-briefly] #'transient--do-stay)
(define-key map [describe-key] '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-up] #'transient--do-stay)
(define-key map [transient-scroll-down] 'transient--do-stay) (define-key map [transient-scroll-down] #'transient--do-stay)
(define-key map [mwheel-scroll] 'transient--do-stay) (define-key map [mwheel-scroll] #'transient--do-stay)
(define-key map [scroll-bar-toolkit-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-noop] #'transient--do-noop)
(define-key map [transient-mouse-push-button] 'transient--do-move) (define-key map [transient-mouse-push-button] #'transient--do-move)
(define-key map [transient-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-backward-button] #'transient--do-move)
(define-key map [transient-forward-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-backward] #'transient--do-move)
(define-key map [transient-isearch-forward] 'transient--do-move) (define-key map [transient-isearch-forward] #'transient--do-move)
map) map)
"Base keymap used to map common commands to their transient behavior. "Base keymap used to map common commands to their transient behavior.
@ -1606,22 +1620,23 @@ of the corresponding object.")
(sym (transient--suffix-symbol cmd))) (sym (transient--suffix-symbol cmd)))
(cond (cond
((oref obj inapt) ((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) ((slot-boundp obj 'transient)
(define-key map (vector sym) (define-key map (vector sym)
(let ((do (oref obj transient))) (let ((do (oref obj transient)))
(pcase do (pcase do
(`t (if sub-prefix (`t (cond (sub-prefix #'transient--do-replace)
'transient--do-replace ((cl-typep obj 'transient-infix)
'transient--do-stay)) #'transient--do-stay)
(t #'transient--do-call)))
(`nil 'transient--do-exit) (`nil 'transient--do-exit)
(_ do))))) (_ do)))))
((not (lookup-key transient-predicate-map (vector sym))) ((not (lookup-key transient-predicate-map (vector sym)))
(define-key map (vector sym) (define-key map (vector sym)
(if sub-prefix (if sub-prefix
'transient--do-replace #'transient--do-replace
(or (oref transient--prefix transient-suffix) (or (oref transient--prefix transient-suffix)
'transient--do-exit))))))) #'transient--do-exit)))))))
map)) map))
(defun transient--make-redisplay-map () (defun transient--make-redisplay-map ()
@ -1649,7 +1664,7 @@ of the corresponding object.")
(listp def) (listp def)
(keymapp def)) (keymapp def))
(define-key topmap (vconcat transient--redisplay-key (list key)) (define-key topmap (vconcat transient--redisplay-key (list key))
'transient-update))) #'transient-update)))
(if transient--redisplay-key (if transient--redisplay-key
(lookup-key transient--transient-map (vconcat transient--redisplay-key)) (lookup-key transient--transient-map (vconcat transient--redisplay-key))
transient--transient-map)) transient--transient-map))
@ -1678,7 +1693,7 @@ EDIT may be non-nil."
(transient--pop-keymap 'transient--redisplay-map) (transient--pop-keymap 'transient--redisplay-map)
(setq name (oref transient--prefix command)) (setq name (oref transient--prefix command))
(setq params (list :scope (oref transient--prefix scope)))) (setq params (list :scope (oref transient--prefix scope))))
(transient--transient-map (transient--prefix
;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}" ;; Invoked as a ":transient-non-suffix 'transient--do-{stay,call}"
;; of an outer prefix. Unlike the usual `transient--do-replace', ;; of an outer prefix. Unlike the usual `transient--do-replace',
;; these predicates fail to clean up after the outer prefix. ;; these predicates fail to clean up after the outer prefix.
@ -1953,8 +1968,10 @@ value. Otherwise return CHILDREN as is."
(defun transient--delete-window () (defun transient--delete-window ()
(when (window-live-p transient--window) (when (window-live-p transient--window)
(let ((buf (window-buffer transient--window))) (let ((buf (window-buffer transient--window)))
(with-demoted-errors "Error while exiting transient: %S" ;; Only delete the window if it never showed another buffer.
(delete-window transient--window)) (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)))) (kill-buffer buf))))
(defun transient--export () (defun transient--export ()
@ -2093,8 +2110,8 @@ value. Otherwise return CHILDREN as is."
(defun transient--emergency-exit () (defun transient--emergency-exit ()
"Exit the current transient command after an error occurred. "Exit the current transient command after an error occurred.
When no transient is active (i.e. when `transient--prefix') is When no transient is active (i.e. when `transient--prefix' is
nil, then do nothing." nil) then do nothing."
(transient--debug 'emergency-exit) (transient--debug 'emergency-exit)
(when transient--prefix (when transient--prefix
(setq transient--stack nil) (setq transient--stack nil)
@ -2171,17 +2188,17 @@ to `transient--do-warn'."
(setq this-command 'transient-popup-navigation-help)) (setq this-command 'transient-popup-navigation-help))
transient--stay) transient--stay)
(put 'transient--do-stay 'transient-color 'transient-blue) (put 'transient--do-stay 'transient-color 'transient-red)
(put 'transient--do-noop 'transient-color 'transient-blue) (put 'transient--do-noop 'transient-color 'transient-red)
(put 'transient--do-warn 'transient-color 'transient-blue) (put 'transient--do-warn 'transient-color 'transient-red)
(put 'transient--do-warn-inapt 'transient-color 'transient-blue) (put 'transient--do-warn-inapt 'transient-color 'transient-red)
(put 'transient--do-call 'transient-color 'transient-blue) (put 'transient--do-call 'transient-color 'transient-red)
(put 'transient--do-exit 'transient-color 'transient-red) (put 'transient--do-exit 'transient-color 'transient-blue)
(put 'transient--do-replace 'transient-color 'transient-red) (put 'transient--do-replace 'transient-color 'transient-blue)
(put 'transient--do-suspend 'transient-color 'transient-red) (put 'transient--do-suspend 'transient-color 'transient-blue)
(put 'transient--do-quit-one 'transient-color 'transient-red) (put 'transient--do-quit-one 'transient-color 'transient-blue)
(put 'transient--do-quit-all 'transient-color 'transient-red) (put 'transient--do-quit-all 'transient-color 'transient-blue)
(put 'transient--do-move 'transient-color 'transient-blue) (put 'transient--do-move 'transient-color 'transient-red)
;;; Commands ;;; Commands
@ -2209,7 +2226,18 @@ to `transient--do-warn'."
(propertize "?" 'face 'transient-key) (propertize "?" 'face 'transient-key)
(propertize (symbol-name (transient--suffix-symbol (propertize (symbol-name (transient--suffix-symbol
this-original-command)) 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 () (defun transient-toggle-common ()
"Toggle whether common commands are always shown." "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)) (cl-defmethod transient-init-value :around ((obj transient-prefix))
"If bound, then call OBJ's `init-value' function. "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) (if (slot-boundp obj 'init-value)
(funcall (oref obj init-value) obj) (funcall (oref obj init-value) obj)
(cl-call-next-method obj))) (cl-call-next-method obj)))
(cl-defmethod transient-init-value :around ((obj transient-infix)) (cl-defmethod transient-init-value :around ((obj transient-infix))
"If bound, then call OBJ's `init-value' function. "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) (if (slot-boundp obj 'init-value)
(funcall (oref obj init-value) obj) (funcall (oref obj init-value) obj)
(cl-call-next-method obj))) (cl-call-next-method obj)))
@ -2595,13 +2623,12 @@ stand-alone command."
(cl-block nil (cl-block nil
(while t (while t
(let ((str (read-from-minibuffer prompt initial-input nil nil history))) (let ((str (read-from-minibuffer prompt initial-input nil nil history)))
(cond ((string-equal str "") (when (or (string-equal str "")
(cl-return nil)) (string-match-p (if include-zero
((string-match-p (if include-zero "\\`\\(0\\|[1-9][0-9]*\\)\\'"
"\\`\\(0\\|[1-9][0-9]*\\)\\'" "\\`[1-9][0-9]*\\'")
"\\`[1-9][0-9]*\\'") str))
str) (cl-return str)))
(cl-return str))))
(message "Please enter a natural number (%s zero)." (message "Please enter a natural number (%s zero)."
(if include-zero "including" "excluding")) (if include-zero "including" "excluding"))
(sit-for 1))))) (sit-for 1)))))
@ -2670,7 +2697,10 @@ prompt."
(oref obj argument-regexp)))) (oref obj argument-regexp))))
(if-let ((sic (and value arg transient--unset-incompatible)) (if-let ((sic (and value arg transient--unset-incompatible))
(spec (oref transient--prefix 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 (progn
(cl-call-next-method obj value) (cl-call-next-method obj value)
(dolist (arg incomp) (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 command PREFIX, then return the active infix arguments. If
the current command was not invoked from PREFIX, then return the current command was not invoked from PREFIX, then return
the set, saved or default value for PREFIX." 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) (defun transient-suffixes (prefix)
"Return the suffix objects of the transient prefix command 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))))) (transient--init-suffixes prefix)))))
(defun transient-get-value () (defun transient-get-value ()
(delq nil (mapcar (lambda (obj) (transient--with-emergency-exit
(and (or (not (slot-exists-p obj 'unsavable)) (delq nil (mapcar (lambda (obj)
(not (oref obj unsavable))) (and (or (not (slot-exists-p obj 'unsavable))
(transient-infix-value obj))) (not (oref obj unsavable)))
transient-current-suffixes))) (transient-infix-value obj)))
transient-current-suffixes))))
(cl-defgeneric transient-infix-value (obj) (cl-defgeneric transient-infix-value (obj)
"Return the value of the suffix object OBJ. "Return the value of the suffix object OBJ.
@ -2860,16 +2891,11 @@ have a history of their own.")
(setq transient--showp t) (setq transient--showp t)
(let ((buf (get-buffer-create transient--buffer-name)) (let ((buf (get-buffer-create transient--buffer-name))
(focus nil)) (focus nil))
(unless (window-live-p transient--window) (with-current-buffer buf
(setq transient--window
(display-buffer buf transient-display-buffer-action)))
(with-selected-window transient--window
(when transient-enable-popup-navigation (when transient-enable-popup-navigation
(setq focus (button-get (point) 'command))) (setq focus (or (button-get (point) 'command)
(transient--heading-at-point))))
(erase-buffer) (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 window-size-fixed t)
(when (bound-and-true-p tab-line-format) (when (bound-and-true-p tab-line-format)
(setq tab-line-format nil)) (setq tab-line-format nil))
@ -2896,14 +2922,26 @@ have a history of their own.")
'transient-separator))) 'transient-separator)))
(insert (propertize "__" 'face face 'display '(space :height (1)))) (insert (propertize "__" 'face face 'display '(space :height (1))))
(insert (propertize "\n" 'face face 'line-height t)))) (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)) (goto-char (point-min))
(when transient-force-fixed-pitch (when transient-force-fixed-pitch
(transient--force-fixed-pitch)) (transient--force-fixed-pitch))
(when transient-enable-popup-navigation (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 () (defun transient--insert-groups ()
(let ((groups (cl-mapcan (lambda (group) (let ((groups (cl-mapcan (lambda (group)
@ -2946,7 +2984,7 @@ have a history of their own.")
(mapcar (mapcar
(lambda (column) (lambda (column)
(transient--maybe-pad-keys column group) (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))) (when-let ((desc (transient-format-description column)))
(push desc rows)) (push desc rows))
rows)) rows))
@ -3249,12 +3287,13 @@ Show the first one that is specified."
(cl-defmethod transient-show-help ((obj transient-suffix)) (cl-defmethod transient-show-help ((obj transient-suffix))
"Show the command doc-string." "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))) (if-let ((manpage (oref transient--prefix man-page)))
(transient--show-manpage manpage) (transient--show-manpage manpage)
(transient--describe-function (oref transient--prefix command))) (transient--describe-function (oref transient--prefix command)))
(if-let ((prefix (get (transient--suffix-command obj) 'transient--prefix)) (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--show-manpage manpage)
(transient--describe-function this-original-command)))) (transient--describe-function this-original-command))))
@ -3366,9 +3405,9 @@ Suffixes on levels %s and %s are unavailable.\n"
(defvar transient-resume-mode-map (defvar transient-resume-mode-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map [remap Man-quit] 'transient-resume) (define-key map [remap Man-quit] #'transient-resume)
(define-key map [remap Info-exit] 'transient-resume) (define-key map [remap Info-exit] #'transient-resume)
(define-key map [remap quit-window] 'transient-resume) (define-key map [remap quit-window] #'transient-resume)
map) map)
"Keymap for `transient-resume-mode'. "Keymap for `transient-resume-mode'.
@ -3395,19 +3434,20 @@ resumes the suspended transient.")
;; Yes, I know that this is wrong(tm). ;; Yes, I know that this is wrong(tm).
;; Unfortunately it is also necessary. ;; Unfortunately it is also necessary.
(setq this-original-command command) (setq this-original-command command)
(transient--pre-command)
(call-interactively command)))) (call-interactively command))))
(defvar transient-popup-navigation-map (defvar transient-popup-navigation-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(define-key map (kbd "<down-mouse-1>") 'transient-noop) (define-key map (kbd "<down-mouse-1>") #'transient-noop)
(define-key map (kbd "<mouse-1>") 'transient-mouse-push-button) (define-key map (kbd "<mouse-1>") #'transient-mouse-push-button)
(define-key map (kbd "RET") 'transient-push-button) (define-key map (kbd "RET") #'transient-push-button)
(define-key map (kbd "<up>") 'transient-backward-button) (define-key map (kbd "<up>") #'transient-backward-button)
(define-key map (kbd "C-p") 'transient-backward-button) (define-key map (kbd "C-p") #'transient-backward-button)
(define-key map (kbd "<down>") 'transient-forward-button) (define-key map (kbd "<down>") #'transient-forward-button)
(define-key map (kbd "C-n") '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-r") #'transient-isearch-backward)
(define-key map (kbd "C-s") 'transient-isearch-forward) (define-key map (kbd "C-s") #'transient-isearch-forward)
map)) map))
(defun transient-mouse-push-button (&optional pos) (defun transient-mouse-push-button (&optional pos)
@ -3436,22 +3476,32 @@ See `forward-button' for information about N."
(forward-button n t))) (forward-button n t)))
(defun transient--goto-button (command) (defun transient--goto-button (command)
(if (not command) (cond
(forward-button 1) ((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)) (while (and (ignore-errors (forward-button 1))
(not (eq (button-get (button-at (point)) 'command) command)))) (not (eq (button-get (button-at (point)) 'command) command))))
(unless (eq (button-get (button-at (point)) 'command) command) (unless (eq (button-get (button-at (point)) 'command) command)
(goto-char (point-min)) (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 ;;;; Popup Isearch
(defvar transient--isearch-mode-map (defvar transient--isearch-mode-map
(let ((map (make-sparse-keymap))) (let ((map (make-sparse-keymap)))
(set-keymap-parent map isearch-mode-map) (set-keymap-parent map isearch-mode-map)
(define-key map [remap isearch-exit] 'transient-isearch-exit) (define-key map [remap isearch-exit] #'transient-isearch-exit)
(define-key map [remap isearch-cancel] 'transient-isearch-cancel) (define-key map [remap isearch-cancel] #'transient-isearch-cancel)
(define-key map [remap isearch-abort] 'transient-isearch-abort) (define-key map [remap isearch-abort] #'transient-isearch-abort)
map)) map))
(defun transient-isearch-backward (&optional regexp-p) (defun transient-isearch-backward (&optional regexp-p)
@ -3537,14 +3587,14 @@ search instead."
(funcall fn arg-mode) (funcall fn arg-mode)
(transient--resume-override t))) (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 () (defun transient--abort-edebug ()
(when (bound-and-true-p edebug-active) (when (bound-and-true-p edebug-active)
(transient--emergency-exit))) (transient--emergency-exit)))
(advice-add 'abort-recursive-edit :before 'transient--abort-edebug) (advice-add 'abort-recursive-edit :before #'transient--abort-edebug)
(advice-add 'top-level :before 'transient--abort-edebug) (advice-add 'top-level :before #'transient--abort-edebug)
(defun transient--edebug-command-p () (defun transient--edebug-command-p ()
(and (bound-and-true-p edebug-active) (and (bound-and-true-p edebug-active)
@ -3558,12 +3608,12 @@ search instead."
(defun transient--suspend-which-key-mode () (defun transient--suspend-which-key-mode ()
(when (bound-and-true-p which-key-mode) (when (bound-and-true-p which-key-mode)
(which-key-mode -1) (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 () (defun transient--resume-which-key-mode ()
(unless transient--prefix (unless transient--prefix
(which-key-mode 1) (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 () (defun transient-bind-q-to-quit ()
"Modify some keymaps to bind \"q\" to the appropriate quit command. "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. else, so that function binds \"M-q\" to that command instead.
Of course \"M-q\" may already be bound to something else, but Of course \"M-q\" may already be bound to something else, but
we stop there." we stop there."
(define-key transient-base-map "q" 'transient-quit-one) (define-key transient-base-map "q" #'transient-quit-one)
(define-key transient-sticky-map "q" 'transient-quit-seq) (define-key transient-sticky-map "q" #'transient-quit-seq)
(setq transient-substitute-key-function (setq transient-substitute-key-function
'transient-rebind-quit-commands)) #'transient-rebind-quit-commands))
(defun transient-rebind-quit-commands (obj) (defun transient-rebind-quit-commands (obj)
"See `transient-bind-q-to-quit'." "See `transient-bind-q-to-quit'."