How can I define transient color per command, like hydra?
Table of Contents
Problem: I need one transient command to end to the transient-session after it is done
From a Reddit thread at https://www.reddit.com/r/emacs/comments/15u0c7w/how_can_i_define_transient_color_per_command/
This is basically like using Hydra semantic colors1.
I have a transient that starts with :transient-suffix 'transient--do-stay
near its definition, which allows me to execute several of its commands in a sequence without quiting the transient. There are certain commands within that transient, however, that should quit the transient if they are used. How can I specify a different transient-suffix on a certain few exception commands?
Example
My big transient has a mapping that includes the ability to winmove between different panes using my arrow keys; I should be able to do this rapidly and repeatedly for multiple movements. Same story with adjusting the pane (“splitter”) size; I need to be able to do it repeatedly to get the split size I want. However, other commands should terminate the transient session immediately, such as finding a file or spawning a sub-process.
Solution
("f" "find-file" find-file :transient transient--do-quit-one)
Individual commands can take a :transient
argument, as per the above; this means that I can still do my repeatable commands on a 'transient--do-stay
basis, but when I do the find-file command, it will end the transient session when finished.
Full code example
The tsa/
commands are custom, but the point still comes across without me providing their definitions.
(transient-define-prefix tsa/transient-window ()
"Window navigation transient"
:transient-suffix 'transient--do-stay
[["Movement"
("h" "focus ←" windmove-left)
("t" "focus ↓" windmove-down)
("c" "focus ↑" windmove-up)
("n" "focus →" windmove-right)]
["Resize"
("<left>" "X←" tsa/move-splitter-left)
("<down>" "X↓" tsa/move-splitter-down)
("<up>" "X↑" tsa/move-splitter-up)
("<right>" "X→" tsa/move-splitter-right)]
["Switch"
("b" "buffer" switch-to-buffer)
("f" "find-file" find-file :transient transient--do-quit-one)
("g" "git-grep" consult-git-grep :transient transient--do-quit-one)
("G" "Projectile RG" consult-ripgrep :transient transient--do-quit-one)
("p" "projectileF" projectile-find-file)
("F" "follow" follow-mode)
("a" "ace 1" transient-ace-cmd)
("&" "sub emacs" tsa/sub-emacs :transient transient--do-quit-one)]
["Split"
("v" "vertical" tsa/split-vertical)
("x" "horizontal" tsa/split-horizontal)
("`" "exwm swap" tsa/exwm-workspace-swap)
("s" "swap" tsa/screen-swap)
("S" "split" tsa/toggle-window-split)]
["Scroll"
("." "left" scroll-left)
("," "right" scroll-right)
("4" "quad view" tsa/split-window-4)
("=" "Scratch" tsa/open-scratch)
("w" "Switch to Test" projectile-toggle-between-implementation-and-test "test<>imp")
]
["Window Lifecycle"
("d" "delete select 🗔" delete-window)
("D" "delete this 🗔" tsa/del-window)
("o" "delete adjacent 🗔" delete-other-windows)
("z" "winner back" tsa/winner-back)
("Z" "winner redo" winner-redo)
("SPC" "quit" transient-quit-all)
]])
Footnotes
1 Hydra semantic colors are such a useful idea that transient happily made the same a default. https://oremacs.com/2015/02/02/colorful-hydrae/ for the hydra implementation details, and code comments on inclusion in transient here: https://github.com/magit/transient/blob/226db67b3680acbeb74cb0403e1a302917054174/lisp/transient.el#L289. It was addressed in this major change, with good discussion: https://github.com/magit/transient/commit/248862c58e3bc0c13c6e3315adc2f3bb43c3c476