reddit / emacs
Transient for resizing windows
Vince_Vice · 2022-11-06 01:37
Has anyone gotten this to work? So far I used a hydra including [this](https://github.com/abo-abo/hydra/blob/317e1de33086637579a7aeb60f77ed0405bf359b/hydra-examples.el#L61) snippet to resize windows. As many others I wanted to try out transients for my keybindings. In particular I liked that I could use an infix toggle state to switch between windmove and resizing using the same keys (I guess I could also bind the toggling key to switch back and forth between different hydras too). I have used the same functions as the hydra in the link. Namely these:
```
(defun hydra-move-splitter-left (arg)
"Move window splitter left."
(interactive "p")
(if (let ((windmove-wrap-around))
(windmove-find-other-window
'right))
(shrink-window-horizontally arg)
(enlarge-window-horizontally arg)))
```
The resizing more often then not fails however, because the transient window in and on itself is fixed-size and does allow neither explicit, nor implicit resizing. So every Splitter that touches the transient can't move and the command fails silently. Since this is probably a common application does somebody know how to get this to work?
akirakom · 2022-11-06 02:49
The snippet is hardly readable. Please reformat it into multiple lines.
Vince_Vice · 2022-11-06 03:48
Thx for letting me know. I assumed it was my foss mobile client that was broken in that regard.
Not sure if its much better now, but I can't do much on mobile
akirakom · 2022-11-06 07:13
You basically can't resize dedicated windows, but you can work around it temporarily using `with-window-non-dedicated`. Is this the answer you need? I think the hydra should work.
0lMon · 2022-11-06 09:15
Hej Hej,
I have my transient for something similar. But I had some issues with it, most problems were solved by calling the transient recursively.
This will disable the transient window, do the operation and call the transient again.
You can have a look at it here:
(transient-define-prefix ol/transient-window ()
""
[["Resize"
("}" "h+" enlarge-window-horizontally :transient t)
("{" "h-" shrink-window-horizontally :transient t)
("^" "v+" enlarge-window :transient t)
("V" "v-" shrink-window :transient t)]
["Split"
("v" "vertical" (lambda ()
(interactive)
(split-window-right)
(windmove-right)) :transient t)
("h" "horizontal" (lambda ()
(interactive)
(split-window-below)
(windmove-down)) :transient t)
("wv" "win-vertical" (lambda ()
(interactive)
(select-window (ol/split-window-right))
(ol/transient-window)) :transient nil)
("wh" "win-horizontal" (lambda ()
(interactive)
(select-window (ol/split-window-below))
(ol/transient-window)) :transient nil)]
["Misc"
("B" "switch buffer" (lambda ()
(interactive)
(consult-buffer)
(ol/transient-window)))
("z" "undo" (lambda ()
(interactive)
(winner-undo)
(setq this-command 'winner-undo)) :transient t)
("Z" "redo" winner-redo :transient t)]]
[["Move"
("b" "←" windmove-left :transient t)
("n" "↓" windmove-down :transient t)
("f" "→" windmove-right :transient t)
("p" "↑" windmove-up :transient t)]
["Swap"
("sb" "←" windmove-swap-states-left :transient t)
("sn" "↓" windmove-swap-states-down :transient t)
("sf" "→" windmove-swap-states-right :transient t)
("sp" "↑" windmove-swap-states-up :transient t)]
["Delete"
("db" "←" windmove-delete-left :transient t)
("dn" "↓" windmove-delete-down :transient t)
("df" "→" windmove-delete-right :transient t)
("dp" "↑" windmove-delete-up :transient t)
("D" "This" delete-window :transient t)]
["Transpose"
("tt" "↜" (lambda ()
(interactive)
(transpose-frame)
(ol/transient-window)) :transient nil)
("ti" "↕" (lambda ()
(interactive)
(flip-frame)
(ol/transient-window)) :transient nil)
("to" "⟷" (lambda ()
(interactive)
(flop-frame)
(ol/transient-window)) :transient nil)
("tc" "⟳" (lambda ()
(interactive)
(rotate-frame-clockwise)
(ol/transient-window)) :transient nil)
("ta" "⟲" (lambda ()
(interactive)
(rotate-frame-anticlockwise)
(ol/transient-window)) :transient nil)]])
It is by no means perfect, and I did not put much effort in it. So take it with a grain of salt.
Cheers!
TheKrister2 · 2022-11-06 09:39
The snippet itself is correctly formatted, but you've gotta use indentation instead of triple backtics. Old Reddit and new Reddit do not support the same things.
Vince_Vice · 2022-11-06 12:43
Hey thanks a lot!
That works indeed! I can't believe I didn't try that.
Now I only have to find out how to remember the infix value in the new transient so it stays in resize mode.
And thanks for sharing your transient, btw your resize group looks like it won't work either for the same reason!
Edit: haha bc I use the same handler for resize and windmove and switch depending on a toggle (that allows me to do both with hjkl) the transient now follows me around ofc. I guess I'll have to hack this together with `with-selected-window`, *sigh*
Edit: if you are intrested: `with-window-non-dedicated` makes the recursion (and my other hacks) obsolete. I've learned about it thanks to [this answer](https://reddit.com/r/emacs/comments/ynd5xs/transient_for_resizing_windows/iv98hcq?context=3)
Vince_Vice · 2022-11-06 12:54
Yes I used the hydra previously.
Thanks for the tip! I'll look into `with-window-non-dedicated`! so far I have worked around it using a recursive transient call instead of `:transient t`, as 0IMon suggested.
But if your way will allow me to resize with `:transient t` I'd prefer that bc I need the infix state and don't want to handle it explicitly if I don't have to.
rswgnu · 2022-11-06 14:08
If your goal is functionality and not to hack on this yourself, then install and activate the Hyperbole package and read the Info manual section on HyControl which lets you set quickly adjust window and frame settings interactively from the keyboard or embed the same sequence of adjustments as one press hyperbuttons in any file. It has its own minibuffer-based menu system. It uses transient keymaps but not the transient package.
Vince_Vice · 2022-11-06 14:53
Thanks for the suggestion. I've watched the introductory video of HyControl.
It does look extremely complete. I still am surprised at all the undiscovered (by me) emacs features/pkgs.
Its definitely worth a note to look into at some point. So far I'll shy away from introducing another systemof which I would only use a tiny fraction of its functionality, but it looks cool!
Vince_Vice · 2022-11-06 16:30
Okay, I wish I had tried that before. This is exactly what I wanted. I can revert all my hacks now.
Thanks you!
tarsius_ · 2022-11-06 22:17
This is about resizing the frame, but might also be relevant: https://github.com/magit/transient/issues/216.
Vince_Vice · 2022-11-07 02:11
Interesting, maybe this is why `with-window-non-dedicated` lets me resize vertically but not horizontally.
Thanks tarsius!
rswgnu · 2022-11-13 14:03
Like many things in Emacs, you just find a useful piece, start with that and grow into the other things. Once you understand implicit buttons, you probably won’t want to live without them.
Vince_Vice · 2022-11-13 14:13
> On e you understand implicit buttons, you probably won’t want to live without them.
Wow those look cool indeed. I have been wanting to hack together a way to jump from a position on a debug log to the position in the file-buffer.
I will definitely pull hyperbole in for this! Thanks!
Vince_Vice · 2022-11-13 15:35
I have to say HyControl did not exite me too much because it needs a lot of qualifiers.
IMO its preferential to have short key-sequences to the most used functionality, while being able to retrieve controls for edge cases either through qualifiers/guiding interfaces (transient, hydra which-key) or fuzzy completion (vertico, selectrum, ivy, ido, helm)
Therefore my preferred way of operating emacs is DWIM. If that is not possible (i.e. from context it is barely ever clear if a frame or a window should be the target for a resize operation) than prioretize the common use-case, accepting that the uncommon case will be buried deeper. This is better than using qualifiers that result is same length key sequences. As an example I barely ever want to resize a frame, but rather often a window, therefore I prefer dropping the "w" or "f" qualifier in the key sequence and operate on the window by default.
HyControl seems to keep the options laid out at the same depth (needs a "w" or "f") and therefore doesn't look like the perfect candidate for me (its great for putting it on the "quick-access" transient though).
However Hyperbole looks like a great addition in that regard as it builds on DWIM concept and judging by context and having one/two keys as entrypoints.
It also seems like it has been conceptualized pretty well by the people involved. I am exited about it
rswgnu · 2022-11-13 17:01
HyControl is for when you want to do a lot if window or frame manipulation rapidly with a quickly resettable and persistent prefix argument. Thus, you flip into window or frame mode once with that one key and then do a bunch of operations and wuit the mode. For single operations it is not necessary.
Enjoy as you explore Hyperbole.
Vince_Vice · 2022-11-13 18:21
Thanks!
Hey I just realized that you are the author of hyperbole.
Thank you for your work! It come across as an incredibly well thought out and implemented package!
I am curious to find out what one can do with it!
rswgnu · 2022-11-13 18:28
Appreciate the sentiment, as a lot of usability design has gone into it.