README.org (4109B)
1 * Transient command menus 2 3 Transient is the library used to implement the keyboard-driven “menus” 4 in [[https://github.com/magit/magit/][Magit]]. It is distributed as a separate package, so that it can be 5 used to implement similar menus in [[https://melpa.org/#/transient][other packages]]. 6 7 ** Some things that Transient can do 8 9 - Display current state of arguments 10 - Display and manage lifecycle of modal bindings 11 - Contextual user interface 12 - Flow control for wizard-like composition of interactive forms 13 - History & persistence 14 - Rendering arguments for controlling CLI programs 15 16 ** Complexity in CLI programs 17 18 Complexity tends to grow with time. How do you manage the complexity 19 of commands? Consider the humble shell command =ls=. It now has over 20 /fifty/ command line options. Some of these are boolean flags (=ls -l=). 21 Some take arguments (=ls --sort=s=). Some have no effect unless paired 22 with other flags (=ls -lh=). Some are mutually exclusive. Some shell 23 commands even have so many options that they introduce /subcommands/ 24 (=git branch=, =git commit=), each with their own rich set of options 25 (=git branch -f=). 26 27 ** Using Transient for composing interactive commands 28 29 What about Emacs commands used interactively? How do these handle 30 options? One solution is to make many versions of the same command, 31 so you don't need to! Consider: =delete-other-windows= vs. 32 =delete-other-windows-vertically= (among many similar examples). 33 34 Some Emacs commands will simply prompt you for the next "argument" 35 (=M-x switch-to-buffer=). Another common solution is to use prefix 36 arguments which usually start with =C-u=. Sometimes these are sensibly 37 numerical in nature (=C-u 4 M-x forward-paragraph= to move forward 4 38 paragraphs). But sometimes they function instead as boolean 39 "switches" (=C-u C-SPACE= to jump to the last mark instead of just 40 setting it, =C-u C-u C-SPACE= to unconditionally set the mark). Since 41 there aren't many standards for the use of prefix options, you have to 42 read the command's documentation to find out what the possibilities 43 are. 44 45 But when an Emacs command grows to have a truly large set of options 46 and arguments, with dependencies between them, lots of option values, 47 etc., these simple approaches just don't scale. Transient is designed 48 to solve this issue. Think of it as the humble prefix argument =C-u=, 49 /raised to the power of 10/. Like =C-u=, it is key driven. Like the 50 shell, it supports boolean "flag" options, options that take 51 arguments, and even "sub-commands", with their own options. But 52 instead of searching through a man page or command documentation, 53 well-designed transients /guide/ their users to the relevant set of 54 options (and even their possible values!) directly, taking into 55 account any important pre-existing Emacs settings. And while for 56 shell commands like =ls=, there is only one way to "execute" (hit 57 =Return=!), transients can "execute" using multiple different keys tied 58 to one of many self-documenting /actions/ (imagine having 5 different 59 colored return keys on your keyboard!). Transients make navigating 60 and setting large, complex groups of command options and arguments 61 easy. Fun even. Once you've tried it, it's hard to go back to the 62 =C-u what can I do here again?= way. 63 64 [[http://readme.emacsair.me/transient.png]] 65 66 #+html: <br><br> 67 #+html: <a href="https://github.com/magit/transient/actions/workflows/compile.yml"><img alt="Compile" src="https://github.com/magit/transient/actions/workflows/compile.yml/badge.svg"/></a> 68 #+html: <a href="https://github.com/magit/transient/actions/workflows/manual.yml"><img alt="Manual" src="https://github.com/magit/transient/actions/workflows/manual.yml/badge.svg"/></a> 69 #+html: <a href="https://elpa.gnu.org/packages/transient.html"><img alt="GNU ELPA" src="https://emacsair.me/assets/badges/gnu-elpa.svg"/></a> 70 #+html: <a href="https://stable.melpa.org/#/transient"><img alt="MELPA Stable" src="https://stable.melpa.org/packages/transient-badge.svg"/></a> 71 #+html: <a href="https://melpa.org/#/transient"><img alt="MELPA" src="https://melpa.org/packages/transient-badge.svg"/></a>