From: pranshu sharma <pranshusharma366@gmail.com>
To: martin rudalics <rudalics@gmx.at>
Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org
Subject: Re: Add function to rotate/transpose all windows
Date: Tue, 01 Oct 2024 19:17:01 +1000 [thread overview]
Message-ID: <878qv8kws2.fsf@gmail.com> (raw)
In-Reply-To: <0d879e95-c37e-416d-b439-daa6384c4f30@gmx.at> (martin rudalics's message of "Mon, 30 Sep 2024 10:57:57 +0200")
martin rudalics <rudalics@gmx.at> writes:
> Alternatively, we could give 'window-tree' an optional PIXELWISE
> argument so it returns the pixel edges of windows.
You decide
>
> Lines should not exceed 80 characters and you probably want to use
> 'cons' instead of 'list' here.
>
Done
>
> I think you should rename all these into something like
> 'rotate-windows-anticlockwise' and 'transpose-windows' (we are already
> using plurals in 'transpose-lines' and 'transpose-chars'). And we do
> not rotate the entire frame - the minibuffer window stays in place, for
> example. So I would try to say
>
> (defun rotate-windows-anticlockwise (&optional frame window)
> "Rotate windows of FRAME anticlockwise by 90 degrees.
> FRAME must be a live frame and defaults to the selected frame. By
> default rotate the root window of FRAME (or its main window if it
> differs from the root window). If WINDOW is non-nil ..."
>
> Which means that we need the additional features:
>
> (1) Rotate windows on any live frame.
>
> (2) Run the function on 'window-main-window' of FRAME unless WINDOW is
> defined and never rotate a side window. Rotating side windows would
> cause completely undefined behavior because their slots are expected to
> never change. Hence, if WINDOW is specified and is a side window, say
> that you cannot rotate side windows.
>
> (3) "subtree of selected window" is an undefined concept. You should
> say something like "to transpose all windows in the same combination as
> WINDOW" instead. But note that with a slightly more complex layout, no
> average user will know what that combination is (think of C-x 2 C-x 3
> C-x o C-x o C-x 3). We could eventually try to flash all windows that
> would be affected by the change but that would be non-trivial.
>
Done, I just said all 'windows of' instead.
Also instead of seperate window and frame args, I just added added one
window-or-frame arg.
> I'd call this something like 'transpose-windows--rearrange' so you can
> change its behavior whenever you want.
>
Yes, good idea
> Is fwin not the same as what 'frame-first-window' returns? If not,
> please telly why in a comment.
It was, I just found out the function exists, thx
> Please tell in a comment why you flatten win-tree her.
>
>> (flatten-list win-tree))
>> (toggle-window-split win-tree fwin conf norm-size)
>> (select-window fwin))))
>>
>> (defun toggle-window-split (subtree cwin conf norm-size)
>
> Should become window--... and have its arguments described.
I just did as subroutine style, same as something like
`window--atom-check-1'.
> Here I'd write
>
> (let ((refer (seq-some
> (lambda (x)
> (and (windowp x) x))
> (flatten-list win))))
> (toggle-window-split
> win (split-window cwin split-size split-type t refer)
> conf norm-size))
>
> but I won't argue about styles.
Although this would be cleaner, but it means the instance of refer would
be stored in memory unnecessarily while the old toggle-window-split
would be going recursivly.
> Whenever using things like cdddr, caaddr or caddr, please say in a
> comment what these are supposed to be. You have condensed the original
> version of your code considerably so please think about people who
> eventually want to understand what the code does.
>
Yeah I did that, after all, I found out while doing this orignally how
hard the code in in trasnpose-frame.el was to read. Well even without
the comments(which I added now), the code is more readable now thanks
you adding refer argument to split-window.
---------------------------------------------
(defun window--subtree-with-size (window &optional next)
"Like `window--subtree' but each window is replaced with the
list: (WINDOW (PIXEL-HEIGHT . PIXEL-WIDTH)), and window-edges is replaced
with the cons cell: (PIXEL-HEIGHT . PIXEL-WIDTH)."
(let (list)
(while window
(setq list
(cons
(cond
((window-top-child window)
(cons t (cons (cons (window-pixel-height window)
(window-pixel-width window))
(window--subtree-with-size
(window-top-child window) t))))
((window-left-child window)
(cons nil (cons (cons (window-pixel-height window)
(window-pixel-width window))
(window--subtree-with-size
(window-left-child window) t))))
(t (list window (cons (window-pixel-height window)
(window-pixel-width window)))))
list))
(setq window (when next (window-next-sibling window))))
(nreverse list)))
(defun rotate-windows-anticlockwise (&optional frame-or-window)
"Rotate windows of FRAME-OR-WINDOW 90 degrees anticlockwise.
See `rotate-windows-clockwise' for more."
(interactive `(,(and prefix-arg (window-parent (selected-window)))))
(let ((window (if (windowp frame-or-window)
frame-or-window
(frame-root-window frame-or-window))))
(transpose-windows--rearrange window '(right . above) nil)))
(defun rotate-windows-clockwise (&optional frame-or-window)
"Rotate windows of FRAME-OR-WINDOW clockwise by 90 degrees.
FRAME-OR-WINDOW must be a live frame or window and defaults to the
selected frame. If FRAME-OR-WINDOW is a frame, rotate from the root
window of the frame, otherwise rotate from FRAME-OR-WINDOW."
(interactive `(,(and prefix-arg (window-parent (selected-window)))))
(let ((window (if (windowp frame-or-window)
frame-or-window
(frame-root-window frame-or-window))))
(transpose-windows--rearrange window '(left . below) nil)))
(defun flip-windows-horizontally (&optional frame-or-window)
"Horizontally flip windows of FRAME-OR-WINDOW.
FRAME-OR-WINDOW must be a live frame or window and defaults to the
selected frame. If FRAME-OR-WINDOW is a frame, flip from the root
window of the frame, otherwise flip from FRAME-OR-WINDOW."
(interactive `(,(and prefix-arg (window-parent (selected-window)))))
(let ((window (if (windowp frame-or-window)
frame-or-window
(frame-root-window frame-or-window))))
(transpose-windows--rearrange window '(below . left) t)))
(defun flip-windows-vertically (&optional frame-or-window)
"Vertically flip windows of FRAME-OR-WINDOW.
See `flip-windows-horizontally' for more."
(interactive `(,(and prefix-arg (window-parent (selected-window)))))
(let ((window (if (windowp frame-or-window)
frame-or-window
(frame-root-window frame-or-window))))
(transpose-windows--rearrange window '(above . right) t)))
(defun transpose-windows (&optional frame-or-window)
"Transpose windows of FRAME-OR-WINDOW.
Windows are rearanged such that where an horizontal split was used, an
vertical one is instead, and vice versa. FRAME-OR-WINDOW must be a live
frame or window and defaults to the selected frame. If FRAME-OR-WINDOW
is a frame, transpose from the root window of the frame, otherwise
transpose from FRAME-OR-WINDOW."
(interactive `(,(and prefix-arg (window-parent (selected-window)))))
(let ((window (if (windowp frame-or-window)
frame-or-window
(frame-root-window frame-or-window))))
(transpose-windows--rearrange window '(right . below) nil)))
(defun transpose-windows--rearrange (frame-or-window conf norm-size)
"Rearrange windows of FRAME-OR-WINDOW recursively.
CONF should be a cons cell: (HORIZONTAL-SPLIT . VERTICAL-SPLIT) where
horizontal split is called when splitting a window that was previously
horizontally split, and VERTICAL-SPLIT for a window that was previously
vertically split. When is NORM-SIZE non-nil, the size argument of the
window-split is converted from vertical to horizontal or vice versa,
with the same proportion of the total split."
(let ((rwin (if (framep frame-or-window)
(frame-root-window frame-root-window)
frame-or-window)))
(if (or (not rwin)
(zerop (window-child-count rwin)))
(message "Not enough windows")
(let* ((fwin (frame-first-window rwin))
(selwin (frame-selected-window frame-or-window))
(win-tree (car (window--subtree-with-size rwin))))
;; All child windows need to be recursively deleted.
(mapc (lambda (win)
(when (and (windowp win)
(not (eq win fwin)))
(delete-window win)))
;; We know for sure that first 2 in the list are not
;; windows.
(cddr (flatten-list win-tree)))
(transpose-windows--rearrange-1 win-tree fwin conf norm-size)
;; Go back to previously selected window.
(select-window selwin)))))
(defun transpose-windows--rearrange-1 (subtree cwin conf norm-size)
"Subroutine of `transpose-windows--rearrange'."
;; `ilen' is the max size a window could be of given the split type.
;; `flen' is max size the window could be converted to the opposite
;; of the given split type.
(pcase-let ((`(,ilen . ,flen) (if (car subtree)
(cons (float (car (cadr subtree)))
(float (window-pixel-width cwin)))
(cons (float (cdr (cadr subtree)))
(float (window-pixel-height cwin))))))
(mapc
(pcase-lambda (`(,win . ,size))
(let ((split-size (- (if norm-size
size
(round (* flen (/ size ilen))))))
(split-type
(funcall (if (car subtree) 'car 'cdr) conf)))
(if (listp win)
;; `win' is a window subtree.
(transpose-windows--rearrange-1 win (split-window cwin
split-size
split-type
t
(seq-some
(lambda (x)
(and (windowp x) x))
(flatten-list win)))
conf norm-size)
;; `win' is a window.
(split-window cwin split-size
split-type t
win))))
(mapcar
(lambda (e)
(let ((window? (if (windowp (car e)) (car e) e)))
(cons window?
;; The relevent size of the window.
(if (car subtree)
(car (cadr e))
(cdr (cadr e))))))
;; By using cdddr, we ignore over window split type, sizes and
;; the first window (it's implicitly created).
(nreverse (cdddr subtree))))
;; (caaddr subtree) is the first window.
(unless (windowp (caaddr subtree))
(transpose-windows--rearrange-1 (caddr subtree) cwin conf norm-size))))
next prev parent reply other threads:[~2024-10-01 9:17 UTC|newest]
Thread overview: 111+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-24 13:45 Add function to rotate/transpose all windows pranshu sharma
2024-09-24 13:53 ` Eli Zaretskii
2024-09-25 8:05 ` martin rudalics
2024-09-25 8:34 ` pranshu sharma
2024-09-25 9:31 ` martin rudalics
2024-09-25 10:50 ` pranshu sharma
2024-09-25 13:53 ` martin rudalics
2024-09-25 15:31 ` pranshu sharma
2024-09-26 14:10 ` martin rudalics
2024-09-26 14:22 ` Eli Zaretskii
2024-09-27 17:29 ` martin rudalics
2024-09-28 7:52 ` pranshu sharma
2024-09-28 9:26 ` martin rudalics
2024-09-28 10:53 ` pranshu sharma
2024-09-28 14:48 ` martin rudalics
2024-09-29 7:36 ` pranshu sharma
2024-09-29 8:40 ` martin rudalics
2024-09-29 9:23 ` pranshu sharma
2024-09-29 14:48 ` martin rudalics
2024-09-30 6:29 ` pranshu sharma
2024-09-30 8:57 ` martin rudalics
2024-10-01 9:17 ` pranshu sharma [this message]
2024-10-02 9:04 ` martin rudalics
2024-10-03 7:06 ` pranshu sharma
2024-10-03 8:17 ` martin rudalics
2024-10-03 10:09 ` pranshu sharma
2024-10-03 14:18 ` martin rudalics
2024-10-04 5:50 ` pranshu sharma
2024-10-04 8:08 ` martin rudalics
2024-10-04 15:10 ` pranshu sharma
2024-10-05 14:43 ` martin rudalics
2024-10-06 2:54 ` pranshu sharma
2024-10-06 15:02 ` martin rudalics
2024-10-06 15:52 ` pranshu sharma
2024-10-07 8:33 ` martin rudalics
2024-10-07 9:42 ` pranshu sharma
2024-10-03 15:12 ` Eli Zaretskii
2024-10-08 18:35 ` Juri Linkov
2024-10-09 6:59 ` pranshu sharma
2024-10-09 16:21 ` Juri Linkov
2024-10-10 11:49 ` pranshu sharma
2024-10-10 16:57 ` Juri Linkov
2024-10-13 5:43 ` pranshu sharma
2024-10-13 8:17 ` martin rudalics
2024-10-14 17:36 ` Juri Linkov
2024-10-15 8:34 ` pranshu sharma
2024-10-15 16:16 ` Juri Linkov
2024-10-18 14:52 ` pranshu sharma
2024-10-18 17:48 ` martin rudalics
2024-10-18 18:37 ` Eli Zaretskii
2024-10-19 1:45 ` pranshu sharma
2024-10-19 6:45 ` Eli Zaretskii
2024-10-19 18:19 ` Juri Linkov
2024-10-19 8:33 ` martin rudalics
2024-10-20 8:19 ` martin rudalics
2024-10-20 14:11 ` Pranshu Sharma
2024-10-20 17:37 ` martin rudalics
2024-10-21 5:54 ` Pranshu Sharma
2024-10-21 8:14 ` martin rudalics
2024-10-21 9:23 ` martin rudalics
2024-10-21 13:37 ` Pranshu Sharma
2024-10-22 18:12 ` martin rudalics
2024-10-24 14:38 ` Pranshu Sharma
2024-10-24 18:39 ` martin rudalics
2024-10-25 14:24 ` Pranshu Sharma
2024-10-25 17:09 ` martin rudalics
2024-10-26 9:14 ` Pranshu Sharma
2024-10-27 8:23 ` martin rudalics
2024-11-02 14:06 ` Pranshu Sharma
2024-11-05 18:01 ` martin rudalics
2024-11-08 9:23 ` Pranshu Sharma
2024-11-08 10:06 ` Pranshu Sharma
2024-11-08 15:52 ` martin rudalics
2024-11-09 2:14 ` Pranshu Sharma
2024-11-09 8:48 ` martin rudalics
2024-11-08 15:52 ` martin rudalics
2024-11-09 2:09 ` Pranshu Sharma
2024-11-09 8:48 ` martin rudalics
2024-11-09 10:55 ` Pranshu Sharma
2024-11-09 18:06 ` martin rudalics
2024-11-10 10:09 ` Pranshu Sharma
2024-11-10 16:36 ` martin rudalics
2024-11-11 14:47 ` Pranshu Sharma
2024-11-11 16:55 ` martin rudalics
2024-11-12 13:50 ` Pranshu Sharma
2024-11-12 17:46 ` martin rudalics
2024-11-16 13:36 ` Pranshu Sharma
2024-11-16 16:54 ` martin rudalics
2024-11-17 2:45 ` Pranshu Sharma
2024-11-17 10:22 ` martin rudalics
2024-11-17 15:03 ` Pranshu Sharma
2024-11-17 16:38 ` martin rudalics
2024-11-18 0:37 ` Pranshu Sharma
2024-11-18 8:55 ` martin rudalics
2024-10-14 17:32 ` Juri Linkov
2024-09-28 7:58 ` pranshu sharma
2024-09-28 8:18 ` Eli Zaretskii
2024-09-28 9:40 ` martin rudalics
2024-09-28 11:35 ` Eli Zaretskii
2024-09-28 14:58 ` martin rudalics
2024-09-28 15:28 ` Eli Zaretskii
2024-10-07 8:33 ` martin rudalics
2024-09-28 13:22 ` pranshu sharma
2024-09-28 14:21 ` Eli Zaretskii
2024-09-28 14:49 ` martin rudalics
2024-09-27 10:06 ` pranshu sharma
2024-09-27 17:29 ` martin rudalics
2024-09-24 17:40 ` Petteri Hintsanen
2024-09-24 19:34 ` Charles Choi
2024-09-25 2:00 ` Emanuel Berg
2024-09-25 7:00 ` pranshu sharma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=878qv8kws2.fsf@gmail.com \
--to=pranshusharma366@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=rudalics@gmx.at \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).