reddit / emacs

Transient for Special Modes

Psionikus · 2022-05-28 05:35
I love special modes. I also never read through the entire list of options. With Magit, I learned things about git. Thanks, transient. As Magit is to git, as transient is to Magit, transient can be to special modes. At least it seems that way. Prepare to read why any solution will look a lot like evil-collection. **If you work on special modes and transient, please speak up.** I started work on a modal package that's going well. What is clear early on is that a modal system in a special mode buffer is not going to work well without adaptation. The point of a special mode is to act more like an application. It has a data model, business rules, unique commands, and no use for many "normal" commands. I think there is a clear need to separate how I treat prog, text, and special modes. To quickly illustrate end state goal and current state, **imagine if magit was just a special mode**. It wouldn't be terribly different, but the slow buildup of pain would eat away at life like a payday loan. - Lack of contextual UI - Poor awareness of states related to available commands - Increased cognitive load when feedback about longer command construction gets difficult to keep track of - Help feedback cycle even for brief lookup is very disruptive compared to transient - Poor discovery / retention of what would be powerful workflows due to the previous points So how should transient be applied to fix the pain of special modes do? I really want to go toward a generated solution, but I don't think this is going to work. ### Tangent, looking at a special modes to get ideas Just looking at dired and ibuffer help menus, I was going to navigate up in dired. I open the help. Instead just use ivy to find the command and the binding. Backing up, I Google to see if I can use keep-lines to search only a narrowed set of the help buffer. Buffer is read only. Basically the help was a failure. So what even is `habits-dired-litter` at the top of the list. "Undocumented." At this point I think I'm writing the transcript to a screencast where I inadvertently make Emacs special modes look like a bowl of noodles and some user in the comments loses their mind about how if I would just use "C-h C-h" I could find the info pages on dired. Well. Sorry, but I see a list of how to say hello in various languages, and I think we are inadvertently furthering multiple points. ### Back to the design, and how the design loops back to keymaps themselves... While I might be able to make some generation rules for things like common prefixes, I don't have high expectations for the result. The logical groupings of activities that narrow commands to what the user is actually doing are pretty helpful in Magit, but I don't think I can automate this grouping. **There's just not a good enough signal in the keymap or help data to automate this easily without an AI or a bunch of heuristics, which will also still do very poorly I think.** Looking farther ahead to when users want to customize the results, I'm starting to understand other users comments about how transients are a bit difficult to integrate with the rest of Emacs (so far, and easily changed). Editing a transient command or searching for commands within transients are unavoidable a bit different than normal maps. `transient-mode-map` itself is already a clear and intentional break with the rest of the bindings hierarchy. Even packages like avy just use `read-key` instead of `transient-mode-map`. This is partly because most avy commands would have a fully dynamic map, making the utility of even creating a map completely questionable. Of course my modal system wants to alternate the keymap according to major and minor modes, but I believe the "free real estate" approach virtually all packages take is horrible. To escape from this, I instead vary the `emulation-mode-map-alists` depending on the major / minor modes to create all new real-estate. If a package doesn't use a transient or emulation map, I will never know it has anything bound. This is major mode maps and minor mode maps all over again. I have buffer-local `emulation-mode-map-alists`. **This is the madness of the "bundling & unbundling" cycle**, where the user starts off wanting lots of new things, eventually wants all of the things integrated, but then wants new things that the integrated solution can no longer easily provide, and ends up breaking out of the integration only to add a bunch of things and then demand a new integration. It's clown make-up time. Whatever we put into transient and emulation maps would eventually go back down into major and minor mode maps, except then we have to deal with the Emacs defaults. Emacs defaults, outside of some very sensible choices for very common things, look somewhat as if you put 1000 users in front of a keymap laid out on a soccer field and told them they could get as many keys as they got to first. Most minor modes give me this feeling as well. I could rant at length about overly densely populated keymaps. I'm driven to the conclusion that manually wrapping special modes with transients to group the commands and expose states for commands is likely to be a manual process. It's not likely to be faster to generate. Generation would only be useful on special modes with small keymaps. Most people will want this to be done for them and to fit a scheme. We are completely full circle, back at evil-collection where `vi` is the scheme. The drive to customize this will end up with a new modal scheme that has to live in `emulation-mode-map-alists` and vary itself on modes, minor modes, and special modes. Users will need to make a collection for the new scheme. **However, there is one bright point still on this road.** Transient uses `transient-mode-map` and that has precedence over `emulation-mode-map-alists`, so any work on a transient package to deeply integrate with a special mode's data model, to expose new workflows, will work no matter if the user is using default bindings or an emulation mode style. I think what might really work better for customization is just exposing a common interface for "special" states, leaving one key binding user-defined to drop the special state temporarily and adding some user-definable ways to re-enter the special state. This is my current state of progress in design. I may well go back to making parrots and injecting Steve Ballmer's _developers developers developers_ emoji into my git-push animation. If you have ideas for more emojis, applications of emojis, or thoughts about converting special modes into more powerful transient modes, let's hear it.
7890yuiop · 2022-05-28 06:43
> I'm driven to the conclusion that manually wrapping special modes with transients to group the commands and expose states for commands is likely to be a manual process. That was a big ramble, but maybe this was the noteworthy paragraph? Were you wondering if it was practical to have auto-generated transient menus for existing special modes, and concluding that it wouldn't work as well as if someone manually designed a transient interface? If so, I imagine that's a sane conclusion. It hadn't really occurred to me that anyone might attempt to automate that process; but if they did then it would be interesting to see the result. If I was to attempt such a thing (which I'm not going to), I suspect I'd drive it from the menu map.
_viz_ · 2022-05-28 08:15
I've never felt the need to have anything fancy besides the menu-bar especially when combined with https://www.emacswiki.org/emacs/LaCarte
Psionikus · 2022-05-28 10:35
Combining completions and transients into one pile of nasty user-generated interactive history buffet does seem tempting... What was that completions tool that will go and do another action? I sometimes wish to handle my key bindings within my workflows instead of running back to my elisp declarations and re-evaluating them. Someone remember? I gotta go out again.
Psionikus · 2022-05-28 10:39
> sane conclusion We're on the same page. It might make sense to just automate the handling of what would otherwise be errors and omitted commands. Short hands declarations are another area... I'm going to start a repo after I get one going. transient-special-modes. Don't namesquat me One trouble is that transient command-sentence patterns, which are good, is a superset of Emacs style very-long-instruction-word hyper-specific commands
_viz_ · 2022-05-28 13:07
Embark?
mickeyp · 2022-05-28 19:38
This is, in many ways, a problem I tried to solve on a smaller scale back in the day with `discover.el`: https://www.masteringemacs.org/article/discoverel-discover-emacs-context-menus The intent is, if I understand you correctly, more or less the same: that a *curated* popup interface which also exposes useful variables alongside commands is better than a mish-mash of whatever happens to be bound to a random key map. I've limited it to specific areas: Isearch, dired (especially, as it's so vast) and a couple of other items. I was also the first one to extract magits' popup interface into a distinct package --- but now of course you have `transient` and before that `magit-popup`.
Psionikus · 2022-05-29 03:52
Yes!