diff --git a/docs/transient.org b/docs/transient.org index 07cfa7c6..c197ec37 100644 --- a/docs/transient.org +++ b/docs/transient.org @@ -1961,313 +1961,6 @@ and 7. ~level~ controls whether a suffix or a group should be available depending on user preference. See [[*Enabling and Disabling Suffixes]]. -* Related Abstractions and Packages -** Comparison With Prefix Keys and Prefix Arguments - -While transient commands were inspired by regular prefix keys and -prefix arguments, they are also quite different and much more complex. - -The following diagrams illustrate some of the differences. - -- =(c)= represents a return to the command loop. -- =(+)= represents the user's choice to press one key or another. -- ={WORD}= are possible behaviors. -- ={NUMBER}= is a footnote. - -*** Regular Prefix Commands -:PROPERTIES: -:UNNUMBERED: notoc -:END: - -See [[info:elisp#Prefix Keys]]. - -#+begin_example - ,--> command1 --> (c) - | - (c)-(+)-> prefix command or key --+--> command2 --> (c) - | - `--> command3 --> (c) -#+end_example - -*** Regular Prefix Arguments -:PROPERTIES: -:UNNUMBERED: notoc -:END: - -See [[info:elisp#Prefix Command Arguments]]. - -#+begin_example - ,----------------------------------, - | | - v | - (c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c) - | ^ | - | | | - `-- sets or changes --, ,-- maybe used --' | - | | | - v | | - prefix argument state | - ^ | - | | - `-------- discards --------' -#+end_example - -*** Transients -:PROPERTIES: -:UNNUMBERED: notoc -:END: - -(∩`-´)⊃━☆゚.*・。゚ - -This diagram ignores the infix value and external state: - -#+begin_example - (c) - | ,- {stay} ------<-,-<------------<-,-<---, - (+) | | | | - | | | | | - | | ,--> infix1 --| | | - | | | | | | - | | |--> infix2 --| | | - v v | | | | - prefix -(c)-(+)-> infix3 --' ^ | - | | | - |---------------> suffix1 -->--| | - | | | - |---------------> suffix2 ----{1}------> {exit} --> (c) - | | - |---------------> suffix3 -------------> {exit} --> (c) - | | - `--> any command --{2}-> {warn} -->--| - | | - |--> {noop} -->--| - | | - |--> {call} -->--' - | - `------------------> {exit} --> (c) -#+end_example - -This diagram takes the infix value into account to an extend, while -still ignoring external state: - -#+begin_example - (c) - | ,- {stay} ------<-,-<------------<-,-<---, - (+) | | | | - | | | | | - | | ,--> infix1 --| | | - | | | | | | | - | | ,--> infix2 --| | | - v v | | | | | - prefix -(c)-(+)-> infix3 --' | | - | | ^ | - | | | | - |---------------> suffix1 -->--| | - | | ^ | | - | | | | | - |---------------> suffix2 ----{1}------> {exit} --> (c) - | | ^ | | - | | | | v - | | | | | - |---------------> suffix3 -------------> {exit} --> (c) - | | ^ | | - | sets | | v - | | maybe | | - | | used | | - | | | | | - | | infix --' | | - | `---> value | | - | ^ | | - | | | | - | hides | | - | | | | - | `--------------------------<---| - | | | - `--> any command --{2}-> {warn} -->--| | - | | | - |--> {noop} -->--| | - | | | - |--> {call} -->--' ^ - | | - `------------------> {exit} --> (c) -#+end_example - -This diagram provides more information about the infix value -and also takes external state into account. - -#+begin_example - ,----sets--- "anything" - | - v - ,---------> external - | state - | | | - | initialized | ☉‿⚆ - sets from | - | | maybe - | ,----------' used - | | | - (c) | | v - | ,- {stay} --|---<-,-<------|-----<-,-<---, - (+) | | | | | | | - | | | v | | | | - | | ,--> infix1 --| | | | - | | | | | | | | | - | | | | v | | | | - | | ,--> infix2 --| | | | - | | | | ^ | | | | - v v | | | | | | | - prefix -(c)-(+)-> infix3 --' | | | - | | ^ | ^ | - | | | v | | - |---------------> suffix1 -->--| | - | | | ^ | | | - | | | | v | | - |---------------> suffix2 ----{1}------> {exit} --> (c) - | | | ^ | | | - | | | | | | v - | | | | v | | - |---------------> suffix3 -------------> {exit} --> (c) - | | | ^ | | - | sets | | | v - | | initialized maybe | | - | | from used | | - | | | | | | - | | `-- infix ---' | | - | `---> value -----------------------------> persistent - | ^ ^ | | across - | | | | | invocations -, - | hides | | | | - | | `----------------------------------------------' - | | | | - | `--------------------------<---| - | | | - `--> any command --{2}-> {warn} -->--| | - | | | - |--> {noop} -->--| | - | | | - |--> {call} -->--' ^ - | | - `------------------> {exit} --> (c) -#+end_example - -- ={1}= Transients can be configured to be exited when a suffix command - is invoked. The default is to do so for all suffixes except for - those that are common to all transients and which are used to - perform tasks such as providing help and saving the value of the - infix arguments for future invocations. The behavior can also be - specified for individual suffix commands and may even depend on - state. - -- ={2}= Transients can be configured to allow the user to invoke - non-suffix commands. The default is to not allow that and instead - warn the user. - -Despite already being rather complex, even the last diagram leaves out -many details. Most importantly it implies that the decision whether -to remain transient is made later than it actually is made (for the -most part a function on ~pre-command-hook~ is responsible). But such -implementation details are of little relevance to users and are -covered elsewhere. - -** Comparison With Other Packages -*** Magit-Popup -:PROPERTIES: -:UNNUMBERED: notoc -:END: - -Transient is the successor to Magit-Popup (see [[info:magit-popup]]). - -One major difference between these two implementations of the same -ideas is that while Transient uses transient keymaps and embraces the -command-loop, Magit-Popup implemented an inferior mechanism that does -not use transient keymaps and that instead of using the command-loop -implements a naive alternative based on ~read-char~. - -Magit-Popup does not use classes and generic functions and defining a -new command type is near impossible as it involves adding hard-coded -special-cases to many functions. Because of that only a single new -type was added, which was not already part of Magit-Popup's initial -release. - -A lot of things are hard-coded in Magit-Popup. One random example is -that the key bindings for switches must begin with ~-~ and those for -options must begin with ~=~. - -*** Hydra -:PROPERTIES: -:UNNUMBERED: notoc -:END: - -Hydra (see https://github.com/abo-abo/hydra) is another package that -provides features similar to those of Transient. - -Both packages use transient keymaps to make a set of commands -temporarily available and show the available commands in a popup -buffer. - -A Hydra “body” is equivalent to a Transient “prefix” and a Hydra -“head” is equivalent to a Transient “suffix”. Hydra has no equivalent -of a Transient “infix”. - -Both hydras and transients can be used as simple command dispatchers. -Used like this they are similar to regular prefix commands and prefix -keys, except that the available commands are shown in the popup buffer. - -(Another package that does this is ~which-key~. It does so automatically -for any incomplete key sequence. The advantage of that approach is -that no additional work is necessary; the disadvantage is that the -available commands are not organized semantically.) - -Both Hydra and Transient provide features that go beyond simple -command dispatchers: - -- Invoking a command from a hydra does not necessarily exit the hydra. - That makes it possible to invoke the same command again, but using a - shorter key sequence (i.e., the key that was used to enter the hydra - does not have to be pressed again). - - Transient supports that too, but for now this feature is not a focus - and the interface is a bit more complicated. A very basic example - using the current interface: - - #+BEGIN_SRC emacs-lisp - (transient-define-prefix outline-navigate () - :transient-suffix 'transient--do-stay - :transient-non-suffix 'transient--do-warn - [("p" "previous visible heading" outline-previous-visible-heading) - ("n" "next visible heading" outline-next-visible-heading)]) - #+END_SRC - -- Transient supports infix arguments; values that are set by infix - commands and then consumed by the invoked suffix command(s). - - To my knowledge, Hydra does not support that. - -Both packages make it possible to specify how exactly the available -commands are outlined: - -- With Hydra this is often done using an explicit format string, which - gives authors a lot of flexibility and makes it possible to do fancy - things. - - The downside of this is that it becomes harder for a user to add - additional commands to an existing hydra and to change key bindings. - -- Transient allows the author of a transient to organize the commands - into groups and the use of generic functions allows authors of - transients to control exactly how a certain command type is - displayed. - - However while Transient supports giving sections a heading it does - not currently support giving the displayed information more - structure by, for example, using box-drawing characters. - - That could be implemented by defining a new group class, which lets - the author specify a format string. It should be possible to - implement that without modifying any existing code, but it does not - currently exist. - * FAQ :PROPERTIES: :APPENDIX: t @@ -2296,6 +1989,20 @@ you will be able to yank it another buffer. #'transient--do-stay) #+end_src +** How does Transient compare to prefix keys and universal arguments? +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +See https://github.com/magit/transient/wiki/Comparison-with-prefix-keys-and-universal-arguments. + +** How does Transient compare to Magit-Popup and Hydra? +:PROPERTIES: +:UNNUMBERED: notoc +:END: + +See https://github.com/magit/transient/wiki/Comparison-with-other-packages. + ** Why did some of the key bindings change? :PROPERTIES: :UNNUMBERED: notoc diff --git a/docs/transient.texi b/docs/transient.texi index 8c11a8b6..ab211d49 100644 --- a/docs/transient.texi +++ b/docs/transient.texi @@ -85,7 +85,6 @@ This manual is for Transient version 0.4.3. * Modifying Existing Transients:: * Defining New Commands:: * Classes and Methods:: -* Related Abstractions and Packages:: * FAQ:: * Keystroke Index:: * Command and Function Index:: @@ -139,11 +138,6 @@ Suffix Methods * Suffix Format Methods:: -Related Abstractions and Packages - -* Comparison With Prefix Keys and Prefix Arguments:: -* Comparison With Other Packages:: - @end detailmenu @end menu @@ -2257,326 +2251,6 @@ and 7. @code{level} controls whether a suffix or a group should be available depending on user preference. See @ref{Enabling and Disabling Suffixes}. -@node Related Abstractions and Packages -@chapter Related Abstractions and Packages - -@node Comparison With Prefix Keys and Prefix Arguments -@section Comparison With Prefix Keys and Prefix Arguments - -While transient commands were inspired by regular prefix keys and -prefix arguments, they are also quite different and much more complex. - -The following diagrams illustrate some of the differences. - -@itemize -@item -@samp{(c)} represents a return to the command loop. -@item -@samp{(+)} represents the user's choice to press one key or another. -@item -@samp{@{WORD@}} are possible behaviors. -@item -@samp{@{NUMBER@}} is a footnote. -@end itemize - -@anchor{Regular Prefix Commands} -@subheading Regular Prefix Commands - -See @ref{Prefix Keys,,,elisp,}. - -@example - ,--> command1 --> (c) - | -(c)-(+)-> prefix command or key --+--> command2 --> (c) - | - `--> command3 --> (c) -@end example - -@anchor{Regular Prefix Arguments} -@subheading Regular Prefix Arguments - -See @ref{Prefix Command Arguments,,,elisp,}. - -@example - ,----------------------------------, - | | - v | -(c)-(+)---> prefix argument command --(c)-(+)-> any command --> (c) - | ^ | - | | | - `-- sets or changes --, ,-- maybe used --' | - | | | - v | | - prefix argument state | - ^ | - | | - `-------- discards --------' -@end example - -@anchor{Transients} -@subheading Transients - -(∩`-´)⊃━☆゚.*・。゚ - -This diagram ignores the infix value and external state: - -@example -(c) - | ,- @{stay@} ------<-,-<------------<-,-<---, -(+) | | | | - | | | | | - | | ,--> infix1 --| | | - | | | | | | - | | |--> infix2 --| | | - v v | | | | - prefix -(c)-(+)-> infix3 --' ^ | - | | | - |---------------> suffix1 -->--| | - | | | - |---------------> suffix2 ----@{1@}------> @{exit@} --> (c) - | | - |---------------> suffix3 -------------> @{exit@} --> (c) - | | - `--> any command --@{2@}-> @{warn@} -->--| - | | - |--> @{noop@} -->--| - | | - |--> @{call@} -->--' - | - `------------------> @{exit@} --> (c) -@end example - -This diagram takes the infix value into account to an extend, while -still ignoring external state: - -@example -(c) - | ,- @{stay@} ------<-,-<------------<-,-<---, -(+) | | | | - | | | | | - | | ,--> infix1 --| | | - | | | | | | | - | | ,--> infix2 --| | | - v v | | | | | - prefix -(c)-(+)-> infix3 --' | | - | | ^ | - | | | | - |---------------> suffix1 -->--| | - | | ^ | | - | | | | | - |---------------> suffix2 ----@{1@}------> @{exit@} --> (c) - | | ^ | | - | | | | v - | | | | | - |---------------> suffix3 -------------> @{exit@} --> (c) - | | ^ | | - | sets | | v - | | maybe | | - | | used | | - | | | | | - | | infix --' | | - | `---> value | | - | ^ | | - | | | | - | hides | | - | | | | - | `--------------------------<---| - | | | - `--> any command --@{2@}-> @{warn@} -->--| | - | | | - |--> @{noop@} -->--| | - | | | - |--> @{call@} -->--' ^ - | | - `------------------> @{exit@} --> (c) -@end example - -This diagram provides more information about the infix value -and also takes external state into account. - -@example - ,----sets--- "anything" - | - v - ,---------> external - | state - | | | - | initialized | ☉‿⚆ - sets from | - | | maybe - | ,----------' used - | | | -(c) | | v - | ,- @{stay@} --|---<-,-<------|-----<-,-<---, -(+) | | | | | | | - | | | v | | | | - | | ,--> infix1 --| | | | - | | | | | | | | | - | | | | v | | | | - | | ,--> infix2 --| | | | - | | | | ^ | | | | - v v | | | | | | | - prefix -(c)-(+)-> infix3 --' | | | - | | ^ | ^ | - | | | v | | - |---------------> suffix1 -->--| | - | | | ^ | | | - | | | | v | | - |---------------> suffix2 ----@{1@}------> @{exit@} --> (c) - | | | ^ | | | - | | | | | | v - | | | | v | | - |---------------> suffix3 -------------> @{exit@} --> (c) - | | | ^ | | - | sets | | | v - | | initialized maybe | | - | | from used | | - | | | | | | - | | `-- infix ---' | | - | `---> value -----------------------------> persistent - | ^ ^ | | across - | | | | | invocations -, - | hides | | | | - | | `----------------------------------------------' - | | | | - | `--------------------------<---| - | | | - `--> any command --@{2@}-> @{warn@} -->--| | - | | | - |--> @{noop@} -->--| | - | | | - |--> @{call@} -->--' ^ - | | - `------------------> @{exit@} --> (c) -@end example - -@itemize -@item -@samp{@{1@}} Transients can be configured to be exited when a suffix command -is invoked. The default is to do so for all suffixes except for -those that are common to all transients and which are used to -perform tasks such as providing help and saving the value of the -infix arguments for future invocations. The behavior can also be -specified for individual suffix commands and may even depend on -state. - -@item -@samp{@{2@}} Transients can be configured to allow the user to invoke -non-suffix commands. The default is to not allow that and instead -warn the user. -@end itemize - -Despite already being rather complex, even the last diagram leaves out -many details. Most importantly it implies that the decision whether -to remain transient is made later than it actually is made (for the -most part a function on @code{pre-command-hook} is responsible). But such -implementation details are of little relevance to users and are -covered elsewhere. - -@node Comparison With Other Packages -@section Comparison With Other Packages - -@anchor{Magit-Popup} -@subheading Magit-Popup - -Transient is the successor to Magit-Popup (see @ref{Top,,,magit-popup,}). - -One major difference between these two implementations of the same -ideas is that while Transient uses transient keymaps and embraces the -command-loop, Magit-Popup implemented an inferior mechanism that does -not use transient keymaps and that instead of using the command-loop -implements a naive alternative based on @code{read-char}. - -Magit-Popup does not use classes and generic functions and defining a -new command type is near impossible as it involves adding hard-coded -special-cases to many functions. Because of that only a single new -type was added, which was not already part of Magit-Popup's initial -release. - -A lot of things are hard-coded in Magit-Popup. One random example is -that the key bindings for switches must begin with @code{-} and those for -options must begin with @code{=}. - -@anchor{Hydra} -@subheading Hydra - -Hydra (see @uref{https://github.com/abo-abo/hydra}) is another package that -provides features similar to those of Transient. - -Both packages use transient keymaps to make a set of commands -temporarily available and show the available commands in a popup -buffer. - -A Hydra ``body'' is equivalent to a Transient “prefix” and a Hydra -``head'' is equivalent to a Transient “suffix”. Hydra has no equivalent -of a Transient ``infix''. - -Both hydras and transients can be used as simple command dispatchers. -Used like this they are similar to regular prefix commands and prefix -keys, except that the available commands are shown in the popup buffer. - -(Another package that does this is @code{which-key}. It does so automatically -for any incomplete key sequence. The advantage of that approach is -that no additional work is necessary; the disadvantage is that the -available commands are not organized semantically.) - -Both Hydra and Transient provide features that go beyond simple -command dispatchers: - -@itemize -@item -Invoking a command from a hydra does not necessarily exit the hydra. -That makes it possible to invoke the same command again, but using a -shorter key sequence (i.e., the key that was used to enter the hydra -does not have to be pressed again). - -Transient supports that too, but for now this feature is not a focus -and the interface is a bit more complicated. A very basic example -using the current interface: - -@lisp -(transient-define-prefix outline-navigate () - :transient-suffix 'transient--do-stay - :transient-non-suffix 'transient--do-warn - [("p" "previous visible heading" outline-previous-visible-heading) - ("n" "next visible heading" outline-next-visible-heading)]) -@end lisp - -@item -Transient supports infix arguments; values that are set by infix -commands and then consumed by the invoked suffix command(s). - -To my knowledge, Hydra does not support that. -@end itemize - -Both packages make it possible to specify how exactly the available -commands are outlined: - -@itemize -@item -With Hydra this is often done using an explicit format string, which -gives authors a lot of flexibility and makes it possible to do fancy -things. - -The downside of this is that it becomes harder for a user to add -additional commands to an existing hydra and to change key bindings. - -@item -Transient allows the author of a transient to organize the commands -into groups and the use of generic functions allows authors of -transients to control exactly how a certain command type is -displayed. - -However while Transient supports giving sections a heading it does -not currently support giving the displayed information more -structure by, for example, using box-drawing characters. - -That could be implemented by defining a new group class, which lets -the author specify a format string. It should be possible to -implement that without modifying any existing code, but it does not -currently exist. -@end itemize - @node FAQ @appendix FAQ @@ -2599,6 +2273,16 @@ you will be able to yank it another buffer. #'transient--do-stay) @end lisp +@anchor{How does Transient compare to prefix keys and universal arguments?} +@appendixsec How does Transient compare to prefix keys and universal arguments? + +See @uref{https://github.com/magit/transient/wiki/Comparison-with-prefix-keys-and-universal-arguments}. + +@anchor{How does Transient compare to Magit-Popup and Hydra?} +@appendixsec How does Transient compare to Magit-Popup and Hydra? + +See @uref{https://github.com/magit/transient/wiki/Comparison-with-other-packages}. + @anchor{Why did some of the key bindings change?} @appendixsec Why did some of the key bindings change?