Function: rotate-windows
rotate-windows is an autoloaded, interactive and byte-compiled
function defined in window-x.el.gz.
Signature
(rotate-windows &optional WINDOW REVERSE)
Documentation
Rotate child windows of WINDOW in cyclic ordering.
WINDOW must be a parent window and defaults to the main window of the selected frame. Interactively, with a prefix argument, rotate the child windows of the selected window's parent.
Optional argument REVERSE non-nil means to rotate windows backwards, in
reverse cyclic order. Signal an error if WINDOW is not a parent window
or some descendants of WINDOW are of fixed size or atomic. Also signal
an error if transpose-dedicated-windows is nil and a descendant window
is dedicated.
Rotating windows leaves the way a frame layout has been produced via splitting, deleting and resizing windows unaltered. It only "moves" windows within that layout such that the space formerly occupied by any window is now occupied by the window preceding (following if REVERSE is non-nil) it in the cycling ordering.
If you want to rotate the entire layout of windows, consider using the
function window-layout-rotate-clockwise instead. If you want to
rotate a layout twice in a row in order to have a window on the bottom
appear on the top and a window on the right appear on the left (or
vice-versa), consider running window-layout-flip-leftright and
window-layout-flip-topdown instead.
Probably introduced at or before Emacs version 31.1.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/window-x.el.gz
;;;###autoload
(defun rotate-windows (&optional window reverse)
"Rotate child windows of WINDOW in cyclic ordering.
WINDOW must be a parent window and defaults to the main window of the
selected frame. Interactively, with a prefix argument, rotate the child
windows of the selected window's parent.
Optional argument REVERSE non-nil means to rotate windows backwards, in
reverse cyclic order. Signal an error if WINDOW is not a parent window
or some descendants of WINDOW are of fixed size or atomic. Also signal
an error if `transpose-dedicated-windows' is nil and a descendant window
is dedicated.
Rotating windows leaves the way a frame layout has been produced via
splitting, deleting and resizing windows unaltered. It only \"moves\"
windows within that layout such that the space formerly occupied by any
window is now occupied by the window preceding (following if REVERSE is
non-nil) it in the cycling ordering.
If you want to rotate the entire layout of windows, consider using the
function `window-layout-rotate-clockwise' instead. If you want to
rotate a layout twice in a row in order to have a window on the bottom
appear on the top and a window on the right appear on the left (or
vice-versa), consider running `window-layout-flip-leftright' and
`window-layout-flip-topdown' instead."
(interactive (list (window--rotate-interactive-arg)))
(setq window (or window (window-main-window)))
(when (window-live-p window)
(user-error "No windows to rotate"))
(let* ((frame (window-frame window))
(selected-window (frame-selected-window window))
(x-y (and rotate-windows-change-selected
(cons (1+ (window-pixel-left selected-window))
(1+ (window-pixel-top selected-window)))))
(win-tree (car (window-tree-normal-sizes window)))
(winls (or
(seq-filter
(lambda (win)
(window-live-p win))
(flatten-list win-tree))))
(rotated-ls (if reverse
(append (cdr winls) (list (car winls)))
(append (last winls) winls)))
(first-window (car rotated-ls))
(new-win-tree
;; Recursively process `win-tree' and construct a new tree
;; with the same shape and rotated windows at the leaves.
(named-let rec ((tree win-tree))
(cond
((consp tree) (cons (rec (car tree)) (rec (cdr tree))))
((window-live-p tree)
(pop rotated-ls))
(t tree)))))
(when (or (seq-some #'window-atom-root winls)
(seq-some #'window-fixed-size-p winls)
(and (not transpose-dedicated-windows)
(seq-some #'window-dedicated-p winls)))
(user-error "Cannot rotate windows due to dedicated, fixed size or atomic window"))
(delete-other-windows-internal first-window window)
(window--transpose-1 new-win-tree first-window '(below . right) t nil)
(when x-y
;; Try to select the window at the position previously occupied by
;; the selected window.
(let ((window-at-x-y (window-at-x-y (car x-y) (cdr x-y) frame t)))
(when window-at-x-y
(setq selected-window window-at-x-y))))
(set-frame-selected-window frame selected-window)))