Can I return information about a transient from a suffix invocation? #306
Replies: 2 comments 2 replies
-
|
I plan to implement support for "returning values", but I don't think I will get to it for a few more months. Sorry. |
Beta Was this translation helpful? Give feedback.
-
|
Hey! I've been looking into something like what you describe, and would like to share my findings in case others are interested. (Some more comments on code are also included in the snippets. Possibly has some bugs.) With a few hacks, I managed to get a Code
(require 'transient)
(defvar demo-variable 0)
(defun demo-exit-recursive-edit ()
(remove-hook 'transient-exit-hook #'demo-exit-recursive-edit)
(exit-recursive-edit))
(transient-define-prefix demo-subdispatch ()
["Test"
("1" "Return 1" (lambda () (interactive) (setq demo-variable 1)))
("2" "Return 2" (lambda () (interactive) (setq demo-variable 2)))]
(interactive)
(transient-setup 'demo-subdispatch)
;; This advice causes the menu to be hidden when entering `recursive-edit', so
;; remove it.
(advice-remove 'recursive-edit #'transient--recursive-edit)
;; "Return" after submenu closes.
(add-hook 'transient-exit-hook #'demo-exit-recursive-edit)
;; The menu doesn't seem to get a chance to actually display before
;; `recursive-edit' is called, so nothing gets shown if we don't explicitly
;; call `redisplay'.
(redisplay)
(recursive-edit))
(transient-define-prefix demo-dispatch ()
["Test"
("v" demo-subdispatch
:description
(lambda ()
(concat "Set variable (" (prin1-to-string demo-variable) ")"))
:transient t)]
(interactive)
;; Reset variable for `demo-dispatch' invocation.
(setq demo-variable 0)
(transient-setup 'demo-dispatch))My experimenting also led to another approach, (ab)using Transient's scope feature to pass a shared object between prefixes (i.e., modifying scope value changes it for all sub/parent-prefixes with the object). For demonstration purposes, I used a list as a means of passing around a reference; my package uses a class object for scope values to make this more manageable, which should also be fairly easy to extend to satisfy this use case. Code
(require 'transient)
(defclass demo-prefix (transient-prefix) ()
"Class for managing shared scope between `demo-prefix' prefixes.")
(cl-defmethod transient-init-scope ((obj demo-prefix))
;; Adapted from `disproject.el'. Scopes between `demo-prefix' classes are
;; shared by reference, so modifying the scope in a subprefix causes it to be
;; modified in the parent prefix as well.
(if (cl-typep transient-current-prefix 'demo-prefix)
(let ((scope (transient-scope)))
(oset obj scope scope))
;; This method is also called for situations like returning from a
;; sub-prefix, in which case we want to keep the existing scope.
(unless (oref obj scope)
(oset obj scope (list 0)))))
(transient-define-prefix demo-subdispatch ()
:class demo-prefix
["Test"
("1" "Return 1" (lambda () (interactive)
(setf (car (transient-scope)) 1)))
("2" "Return 2" (lambda () (interactive)
(setf (car (transient-scope)) 2)))])
(transient-define-prefix demo-dispatch ()
:class demo-prefix
["Test"
("v" demo-subdispatch
:description
(lambda ()
(concat "Set variable (" (prin1-to-string (car (transient-scope))) ")"))
:transient t)]) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Transient is a very powerful and comfortable interface for choosing things. I want to use transient to select one or several elements of a list in a package I'm building. For minimal example, lets say the objects are
selectableobjects, which each have a name and key slot. I need a function which:selectableobjects as argument (e.g. selectable-list)I can't make the last bullet point happen. Is this something transient can or should do? If so, how can I do it? Here's what I have so far:
If I run
(setq var (transient-choose-selectable selectable-list)), select something and press RET, then inspectvar, the value ofvaris still nil. I see why this is happening: the body oftransient-choose-selectablefinishes with transient setup and then exits (returning nil). Is there any way I can retain or access the return value of the final confirmation?Beta Was this translation helpful? Give feedback.
All reactions