Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to prepopulate infix arguments on the fly? #89

Closed
karthink opened this issue May 24, 2020 · 10 comments
Closed

Is there a way to prepopulate infix arguments on the fly? #89

karthink opened this issue May 24, 2020 · 10 comments
Labels
support User needs some help

Comments

@karthink
Copy link

I'm writing a transient menu that looks like this:

Screenshot_20200523_195315

I would like to be able to select a profile:

Screenshot_20200523_195520

And have the other arguments automatically be populated to certain values that I can do minor edits on before running the command. Is there some way to do this? I couldn't find anything relevant in the info manual.

So far I have all options defined using define-infix-argument but I'm not sure this is the right way to go about it.

@tarsius
Copy link
Member

tarsius commented May 24, 2020

transient-history-prev and transient-history-next have to switch to a different set of values and your command has to do about the same, except that it gets the values from somewhere else of course.

Such internal commands can be defined using just defun because some of their behavior is hard-coded elsewhere (transient-predicate-map). Your command however will probably end up being defined using transient-define-suffix (not *-infix because the generated function body won't do here), which sets :transient to t aka transient--do-stay.

@karthink
Copy link
Author

I can't find transient-define-suffix in transient.el. Did you mean define-suffix-command?

@kyleam
Copy link
Member

kyleam commented May 29, 2020

This was part of the renaming in dd0c44c (Use the package prefix for everything, 2020-05-16).

@karthink
Copy link
Author

karthink commented May 29, 2020

Thanks, looks like I'm a few commits behind.

I checked out transient-history-prev & co, and it looks like they get the object corresponding to the option being edited using the transient--prefix variable. I define a suffix command as follows:

(define-suffix-command ffmpeg-preset-load ()
  "Load a preset argument list"
  :transient t
  (interactive)
  (let ((obj ???))
    (transient-infix-set obj preset-value)))

Where obj is the object corresponding to one of the infix arguments being set. How do I find the ????

Here is an example of the kind of value I'm trying to set from a preset:

(define-infix-argument ffmpeg-dispatch:-r ()
  :description "Output frame rate"
  :class 'ffmpeg-option
  :shortarg "-r"
  :argument "-framerate"
  :reader 'transient-read-number-N+
  )

EDIT: Discovered that transient-current-suffixes gives a list of all the active suffixes. Is there some way to address/access just one of these objects? I'm looking for a handle to a single object in this list.

@tarsius
Copy link
Member

tarsius commented May 30, 2020

I don't quite understand what you are trying to do. It looks to me like you want the "preset load" command to change the value of a single other command (an infix argument).

That seems very strange to me but I am going to assume its the right thing to do.

Discovered that transient-current-suffixes gives a list of all the active suffixes. Is there some way to address/access just one of these objects? I'm looking for a handle to a single object in this list.

Why not just:

(cl-find-if #'your-predicate transient-current-suffixes)

You seem to be looking for:

(cl-find-if (lambda (obj)
              (eq (oref obj command)
                  'ffmpeg-dispatch:-r))
            transient-current-suffixes)

@tarsius tarsius added the support User needs some help label May 30, 2020
@karthink
Copy link
Author

karthink commented May 30, 2020

Thanks! I was grasping for the command slot. However, transient-current-suffixes is evaluating to nil:

(transient-define-suffix print-all-commands ()
  "Print all commands"
  :transient t
  (interactive)
  (prin1 (mapcar (lambda (obj) (oref obj command))
                 transient-current-suffixes)))

This returns nil. If I turn it into an "exiting" suffix by turning off :transient t then it works as expected. Is there some way to access transient-current-suffixes without exiting transient?

That seems very strange to me but I am going to assume its the right thing to do.

I'm afraid I might be wandering into an XY problem here. I'm planning to set all infix arguments from a preset list, but was trying just one as a test first.

@tarsius
Copy link
Member

tarsius commented Jun 9, 2020

Is there some way to access transient-current-suffixes without exiting transient?

Use transient--suffixes instead.

I'm afraid I might be wandering into an XY problem here.

Going back to my earlier suggestion:

(transient-define-suffix magit-log-an-argument-preset ()
  :transient 'transient--do-stay
  (interactive)
  (oset transient--prefix value '("--patch" "--stat"))
  (mapc #'transient-init-value transient--suffixes))

(transient-append-suffix 'magit-log "h"
  '("X" "use some argument preset" magit-log-an-argument-preset))

@tarsius tarsius closed this as completed Jun 10, 2020
@dyereh
Copy link

dyereh commented Apr 23, 2021

I'm looking to do something similar (but slightly different) to this. I'm looking to pre-populate a bunch of infix arguments before I call the transient. Is this possible?

@tarsius
Copy link
Member

tarsius commented Apr 23, 2021

If that means that you want to set the default value of a transient that you defined yourself, then you can do that using :value. If you want to set and then remember the value for a third-party transient, then see https://magit.vc/manual/transient/Saving-Values.html.

@dyereh
Copy link

dyereh commented Apr 28, 2021

Thanks for the reply @tarsius - I was trying to set the value in a lasting way. Turns out I was looking for the 'transient-lisp-variable class:

  (defvar my--build-container nil)
  (transient-define-argument my/transient-arg/build-container ()
    "Set a lisp variable"
    :description "Docker container to use for build"
    :class 'transient-lisp-variable
    :variable 'my--build-container)

This works great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support User needs some help
Projects
None yet
Development

No branches or pull requests

4 participants