From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Pranshu Sharma Newsgroups: gmane.emacs.devel Subject: Re: Add function to rotate/transpose all windows Date: Sat, 26 Oct 2024 19:14:57 +1000 Message-ID: <875xpfns32.fsf@gmail.com> References: <87setpdv21.fsf@gmail.com> <878qv8kws2.fsf@gmail.com> <87ed4xvf60.fsf@gmail.com> <861q0qfnhr.fsf@mail.linkov.net> <878quxdant.fsf@gmail.com> <86zfndi6wh.fsf@mail.linkov.net> <87zfncuqhu.fsf@gmail.com> <86v7y00w68.fsf@mail.linkov.net> <87y12smubh.fsf@gmail.com> <96ea5140-9043-4c1b-97f3-4c534296355e@gmx.at> <87frotqx90.fsf@gmail.com> <87y12iyidd.fsf@gmail.com> <87iktld1bd.fsf@gmail.com> <87r085r2gl.fsf@gmail.com> <87zfms6z1a.fsf@gmail.com> <71571413-02ba-4e3c-ad43-35c110811fab@gmx.at> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="34125"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: Juri Linkov , Eli Zaretskii , emacs-devel@gnu.org To: martin rudalics Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sat Oct 26 15:25:33 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1t4gnN-0008ic-IR for ged-emacs-devel@m.gmane-mx.org; Sat, 26 Oct 2024 15:25:33 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1t4gmO-0008Nv-LD; Sat, 26 Oct 2024 09:24:32 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1t4csw-00053X-F6 for emacs-devel@gnu.org; Sat, 26 Oct 2024 05:15:02 -0400 Original-Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1t4csu-00037k-RQ; Sat, 26 Oct 2024 05:15:02 -0400 Original-Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-20c805a0753so27538185ad.0; Sat, 26 Oct 2024 02:14:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729934099; x=1730538899; darn=gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=4jnHs52XeDEU+ffmnkNh5E0ntCgFRKtKJJTHfvZ6yzY=; b=fngSL+ssbISctfIkJZb8nTdOThE0WLf0lq8EH2MIBKIGJ4Y4W/Giplc5pSPWHXUjOc UTFrJbL0L7V1jO38slrgr6gV4y2L7yv8nZtx4BWI1AsT0SqQEdJUe3iuBDYDL5RfJuQ3 TaStiW4UOJNlO+r9NkGnwmWAvDzbsdinLsI+0qR2bJr8IQN+w7aVt1Z3kUPHbX+5yEoo 3+mdmiOzS8yLzNRl5KGpfwJNEhViUhuPUHhZIzyWSp+IP1vB7paUOub3PB38UKB6ck7H WlPG0tXJAYUIkIAYdMn97LMzABy73Z8cWZ86sVn22NCbkZHA0WdY3qu1AAU3SENI9g7w p14A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729934099; x=1730538899; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=4jnHs52XeDEU+ffmnkNh5E0ntCgFRKtKJJTHfvZ6yzY=; b=BjZGun0A4hHHKtlnC40LsFGuoce0Uhlf/7rlPNPQ7zohs/qxhLqlaWKqHbe6Rm3Xnu 6NzBaxb7N/Lh7fDU6teYXlOiljW7prtUoA1Vn5+msuqwUnii26bc36Zfj0QmCGh3XVCn LjFyeNuZM+QfW9zEOu75Df38scbBzo27lgw04zwJfQfIyNf9gsmxBxWSaU7/mefMLktf stnYhjS2lfEFRNlRoYbuDtW0S+QYFxyP3lx793ARpAZY/e08ZFSbkaPfGdhy2axZUsVG v0/V/38pRxVrsd40IoS9di6oUcB78CB2zcoBql9BAZq2USYkCWZQ5Qd6H1hI81H/r+Bh bi5A== X-Forwarded-Encrypted: i=1; AJvYcCVVluabY+qYvmKNW79Y1pRYo+FHKUEZlOqMR1b0QNAcrjYJ1b+gquFh9AiD2cKDKfehIAts@gnu.org, AJvYcCXRLdxDsK7Nbajq5CWHJNJ7ZvoysjOK3nyIVsURktowy1QWReMonxGa7JnCkw9XFgtbdI2MOqeCVJrfIL4=@gnu.org X-Gm-Message-State: AOJu0YyZO9yrq6G75RpkVIzzA1ra2ZPe1S58V/2sDDSx5U1QVw/aBN9q e7sKl7bqoOkzqsUvq3SsoFtbcHPDoobyzMHONmqscy+4kdUa7tFUATWvVq84 X-Google-Smtp-Source: AGHT+IFMXiEBzCMu7swI16eYqJkQAFXVXRAsZ4u0atRFJ/gjsFxSiDRSsCwis4MWnsamNo2a3k/xnA== X-Received: by 2002:a17:902:f546:b0:20b:9f8c:e9de with SMTP id d9443c01a7336-210c68995ccmr26260205ad.13.1729934098427; Sat, 26 Oct 2024 02:14:58 -0700 (PDT) Original-Received: from pranshu-ThinkPad-E560 ([2001:8003:7816:8300:b7af:fc3:878:375]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-210bc02ecf5sm20925745ad.199.2024.10.26.02.14.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 26 Oct 2024 02:14:57 -0700 (PDT) In-Reply-To: <71571413-02ba-4e3c-ad43-35c110811fab@gmx.at> (martin rudalics's message of "Fri, 25 Oct 2024 19:09:12 +0200") Received-SPF: pass client-ip=2607:f8b0:4864:20::633; envelope-from=pranshusharma366@gmail.com; helo=mail-pl1-x633.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 26 Oct 2024 09:24:30 -0400 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:324850 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable martin rudalics writes: > I don't see it in the code you sent, though. Look in window--transpose > In rotate-windows-anticlockwise: > window-transpose.el:59:48: Warning: Unused lexical argument =E2=80=98subt= ree=E2=80=99 Oh, I just realised these ones also existed in before code > In window--transpose-1: > window-transpose.el:209:28: Warning: reference to free variable =E2=80=98= fwin=E2=80=99 > > The last one keeps it from running. This one happend becuase you turned on lexical scoping. I changed the code so it works with lexical Also the C-x 3 C-x 2 C-x 3 split has some size messups (still works tho), that will need fixing --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=window-transpose.el Content-Transfer-Encoding: quoted-printable ;;; -*- lexical-binding:t -*- (defun window-tree-pixel-sizes (window &optional next) "Return pixel sizes of all windows rooted at WINDOW. The return value is a list where each window is represented either by a triple whose first element is either t for an internal window that is a horizontal combination, nil for an internal window that is a vertical combination, or the window itself for a valid window. The second element is a cons of the pixel height and pixel width of the window. The third element is specified for internal windows only and recursively lists that window's child windows using the same triple structure." (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-tree-pixel-sizes (window-top-child window) t)))) ((window-left-child window) (cons nil (cons (cons (window-pixel-height window) (window-pixel-width window)) (window-tree-pixel-sizes (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 subtree frame-or-window) "Rotate windows of FRAME-OR-WINDOW anticlockwise by 90 degrees. FRAME-OR-WINDOW must be a valid frame or window and defaults to the selected frame. If FRAME-OR-WINDOW is a frame, rotate the main window of the frame, otherwise rotate FRAME-OR-WINDOW. See `rotate-windows-clockwise' for how to rotate windows in the opposite direction. If SUBTREE is non-nil, the function will act as if FRAME-OR-WINDOW is the parent window of the selected window." (interactive "P") (let ((window (cond (subtree (window-parent)) ((windowp frame-or-window) frame-or-window) (t (window-main-window frame-or-window))))) (window--transpose window '(right . above) nil))) (defun rotate-windows-clockwise (&optional subtree frame-or-window) "Rotate windows of FRAME-OR-WINDOW clockwise by 90 degrees. FRAME-OR-WINDOW must be a valid frame or window and defaults to the selected frame. If FRAME-OR-WINDOW is a frame, rotate the main window of the frame, otherwise rotate FRAME-OR-WINDOW. See `rotate-windows-anticlockwise' for how to rotate windows in the opposite direction. If SUBTREE is non-nil, the function will act as if FRAME-OR-WINDOW is the parent window of the selected window." (interactive "P") (let ((window (cond (subtree (window-parent)) ((windowp frame-or-window) frame-or-window) (t (window-main-window frame-or-window))))) (window--transpose window '(left . below) nil))) (defun flip-windows-horizontally (&optional subtree frame-or-window) "Horizontally flip windows of FRAME-OR-WINDOW. When the windows are flipped horzontally, the window layout is made to it's reflection from the side edge. FRAME-OR-WINDOW must be a valid frame or window and defaults to the selected frame. If FRAME-OR-WINDOW is a frame, flip from the main window of the frame, otherwise flip from FRAME-OR-WINDOW. See `flip-windows-vertically' for how to flip windows vertically. If SUBTREE is non-nil, the function will act as if FRAME-OR-WINDOW is the parent window of the selected window." (interactive "P") (let ((window (cond (subtree (window-parent)) ((windowp frame-or-window) frame-or-window) (t (window-main-window frame-or-window))))) (window--transpose window '(below . left) t))) (defun flip-windows-vertically (&optional subtree frame-or-window) "Horizontally flip windows of FRAME-OR-WINDOW. When the windows are flipped vertically, the window layout is made to it's reflection from the top edge. FRAME-OR-WINDOW must be a valid frame or window and defaults to the selected frame. If FRAME-OR-WINDOW is a frame, flip from the main window of the frame, otherwise flip from FRAME-OR-WINDOW. See `flip-windows-horizontally' for how to flip windows horizontally." (interactive "P") (let ((window (cond (subtree (window-parent)) ((windowp frame-or-window) frame-or-window) (t (window-main-window frame-or-window))))) (window--transpose window '(above . right) t))) (defun transpose-windows (&optional subtree frame-or-window) "Transpose windows of FRAME-OR-WINDOW. Rearrange windows such that where a horizontal split was used a vertical one is used instead, and vice versa. FRAME-OR-WINDOW must be a valid frame or window and defaults to the selected frame. If FRAME-OR-WINDOW is a frame, transpose the main window of the frame, otherwise transpose FRAME-OR-WINDOW. If SUBTREE is non-nil, the function will act as if FRAME-OR-WINDOW is the parent window of the selected window." (interactive "P") (let ((window (cond (subtree (window-parent)) ((windowp frame-or-window) frame-or-window) (t (window-main-window frame-or-window))))) (window--transpose window '(right . below) nil))) (defun window--transpose (window conf do-not-convert-size) "Rearrange windows of WINDOW recursively. CONF should be a cons cell: (HORIZONTAL-SPLIT . VERTICAL-SPLIT) where HORIZONTAL-SPLIT will be used as the third argument of `split-window' when splitting a window that was previously horizontally split, and VERTICAL-SPLIT as third argument of `split-window' for a window that was previously vertically split. If DO-NOT-CONVERT-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." (if (or (not window) (window-live-p window)) (message "No windows to transpose") (let* ((frame (window-frame window)) (fwin window) (selwin (frame-selected-window window)) (window-combination-limit t) (win-tree (car (window-tree-pixel-sizes window)))) (while (not (window-live-p fwin)) (setq fwin (window-child fwin))) ;; All child windows need to be recursively deleted. (delete-other-windows-internal fwin) (window--transpose-1 win-tree fwin conf do-not-convert-size fwin nil) ;; Go back to previously selected window. (set-frame-selected-window frame selwin)))) (defun window--transpose-1 (subtree cwin conf do-not-convert-size fwin &optional o-size o-split) "Subroutine of `window--transpose'. SUBTREE must be in the format of the result of `window-tree-pixel-sizes'. CWIN is the current window through which the window splits are made. The CONF and DO-NOT-CONVERT-SIZE arguments are the same as the ones in `window--transpose'." ;; `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 . ,fflen) (if (car subtree) (cons (float (car (cadr subtree))) (float (window-pixel-width cwin))) (cons (float (cdr (cadr subtree))) (float (window-pixel-height cwin))))) (split-type (funcall (if (car subtree) 'car 'cdr) conf)) (flen (if (eq o-split split-type) (- fflen o-size) fflen )) (deepest-window (seq-reduce (pcase-lambda (parent-win `(,win . ,size)) (if (eq fwin win) ;; We are at root win parent-win (let ((split-size (and size (if do-not-convert-size size (round (* flen (/ size ilen))))))) (if (listp win) ;; win is a subtree instead of a window (if (and (not size) o-size) ;; We need to keep going down the ;; identity of correct window. (window--transpose-1 win parent-win conf do-not-convert-size fwin o-size o-split) (window--transpose-1 win parent-win conf do-not-convert-size fwin split-size split-type)) (if (and (not size) o-size) (split-window parent-win o-size o-split t win) (split-window parent-win split-size split-type t win)))))) (let ((ls (mapcar (lambda (e) (let ((window? (if (windowp (car e)) (car e) e))) (cons window? ;; The respective size of the window. (if (car subtree) (car (cadr e)) (cdr (cadr e)))))) ;; By using cdddr, we ignore first window (irelevnt unless tree) (cddr subtree)))) ;; I add lookahead in size. The size of first win is lost, ;; but it is irelevent as it is total size minus size of rest ;; of windows (seq-mapn 'cons (mapcar 'car ls) (cons nil (mapcar 'cdr ls)))) cwin))) ;; Perfoming recursive ascent (dotimes (_ (- (length subtree) 3)) (setq deepest-window (window-parent deepest-window))) deepest-window)) --=-=-=--