-
-
Notifications
You must be signed in to change notification settings - Fork 68
Description
The vision is to make (interactive) forms in transient commands easier to write for both directly calling by M-x and via transient.
- If I call an interactive command by lisp, I pass arguments.
- When invoked as a command, the interactive form uses readers to obtain the values.
- When a transient suffix is called, it must extract the arguments it needs from the current prefix
- Transient infixes describe readers, but we can't easily re-use these readers to complete the interactive form
- To support both transient and M-x paths, the user must do everything explicitly using transient style code on one branch and traditional code on the M-x branch
It ends up looking like:
(transient-define-suffix pmx-frame-resolution (resolution)
(interactive
(if transient-current-command
(list
(transient-arg-value
"resolution="
(transient-args transient-current-command)))
(pmx-non-infix-resolution-reader)))Instead, I propose enabling a form like this:
(defun dual-use-suffix (arg1 arg2 arg3)
(interactive (list (infix) (infix) (infix))
( ... ))If the infix commands are made just a little smarter, they can call their reader and return the read value without using transient-infix-value. This has many advantages for reducing code size.
- Positional arguments using infix command symbols avoid
transient-arg-value. - There is no unnecessary stringly typed re-read.
- Moving the prefix versus M-x check to the infix class avoids requiring each suffix to check if
transient-current-commandis non-nil entirely.
To implement, when the infix is called and the transient is active, it should behave normally. When called without a prefix, the infix should be initialized, call its reader, and return its value.
Calling customized infixes without an active prefix may require smarter init-value and init-scope functions, but the user is opting into this by writing the (interactive (list (infix) (infix) (infix)) style. I will avoid discussing providing more kinds of history for infixes to usually produce smart reader defaults, but this proposal would enhance potential value in that discussion.
This usage pattern would also yield values without stringly typing values, eliminating the need to re-read them in the suffix. When providing alists for choices, we can use assoc instead of assoc-string and the even more brittle "my-value=" in calls to transient-args.
transient-args itself relies on stringly typed information to locate the arg, and IMO should be mostly relied upon for CLI interfaces.
However, CLI interfaces for new programs are not a good solution. When writing a new program, a JSON rpc style interface such as used by LSP or even an elisp extension with automatic serialization will lead to a less fragile Emacs <-> program interface. In this case, the stringly typing should be avoided and returning the infix value directly in interactive accomplishes this.