6

Magit defines a transient state

(transient-define-prefix magit-dispatch ()
  "Invoke a Magit command from a list of available commands."
  ["Transient and dwim commands"
   [("A" "Apply"          magit-cherry-pick)
   ...
  ["Essential commands"
   :if-derived magit-mode
   ...
   ("C-h m" "   show all key bindings"    describe-mode)])

I would like to add <escape> and <q> as key-bindings to exit the transient state.

If I edit magit.el directly, I can achieve what I want:

(transient-define-prefix magit-dispatch ()
  "Invoke a Magit command from a list of available commands."
  ["Transient and dwim commands"
   [("A" "Apply"          magit-cherry-pick)
   ...
  ["Essential commands"
   :if-derived magit-mode
   ...
   ("<escape>" "quit transient state"     transient-quit-one)    ; <--- I added 
   ("q" "       quit transient state"     transient-quit-one)    ; <--- these
   ("C-h m" "   show all key bindings"    describe-mode)])

However, unless I can upstream my changes, this won't persist if I reload my packages from elpa, etc.

How can I add these key-bindings in my own init.el so they augment the transient state magit defines?

1 Answer 1

2

I've never actually used the transient package before (which is what magit uses to create these cool menus), so instead of giving you the answer, I'll describe how to find it.

First, take a look at the definition of the the transient-define-prefix macro. There's no direct way to go to a macro definition, so start by visiting the source for magit-dispatch; type C-h f magit-dispatch <RET> to visit the documentation for the function, then click the source link. Then type M-. on the call to the macro to jump to its definition.

This macro defines the name you give it to be a function which implements the menu the other arguments define. The macro parses those objects and then stores them alongside the function definition under a different property name. You can retrieve the menu definition with (get 'magit-dispatch 'transient--layout). The double-dash in the name is a naming convention meaning that this data is considered private to the transient package, so there is some risk to modifying this data. The exact format is not explicitly defined, and there may or may not be useful functions for adding things to it. It looks like a set of nested vectors, so you might end up just appending some new vectors to the end of it.

With that knowledge you may be able to find functions that retrieve the value stored in this property, and hopefully one will modify it. I recommend starting with transient-insert-suffix.

As an aside, I note that the transient package has an info manual, and chapter 4 is titled "Modifying Existing Transients", which sounds relevant to your interests.

2
  • What a great answer, thank you so much! Commented Jun 11, 2020 at 11:13
  • You're welcome.
    – db48x
    Commented Jun 11, 2020 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.