Vertical split shows more of each line, horizontal split shows more lines. This code toggles between them. It only works for frames with exactly two windows. The top window goes to the left or vice-versa. I was motivated by ediff-toggle-split and helped by TransposeWindows. There may well be better ways to write this.
(defun toggle-window-split () (interactive) (if (= (count-windows) 2) (let* ((this-win-buffer (window-buffer)) (next-win-buffer (window-buffer (next-window))) (this-win-edges (window-edges (selected-window))) (next-win-edges (window-edges (next-window))) (this-win-2nd (not (and (<= (car this-win-edges) (car next-win-edges)) (<= (cadr this-win-edges) (cadr next-win-edges))))) (splitter (if (= (car this-win-edges) (car (window-edges (next-window)))) 'split-window-horizontally 'split-window-vertically))) (delete-other-windows) (let ((first-win (selected-window))) (funcall splitter) (if this-win-2nd (other-window 1)) (set-window-buffer (selected-window) this-win-buffer) (set-window-buffer (next-window) next-win-buffer) (select-window first-win) (if this-win-2nd (other-window 1)))))) (define-key ctl-x-4-map "t" 'toggle-window-split)
Here’s a simpler implementation I wrote before knowing about this wiki page:
(defun toggle-frame-split () "If the frame is split vertically, split it horizontally or vice versa. Assumes that the frame is only split into two." (interactive) (unless (= (length (window-list)) 2) (error "Can only toggle a frame split in two")) (let ((split-vertically-p (window-combined-p))) (delete-window) ; closes current window (if split-vertically-p (split-window-horizontally) (split-window-vertically)) ; gives us a split with the other window twice (switch-to-buffer nil))) ; restore the original window in this part of the frame ;; I don't use the default binding of 'C-x 5', so use toggle-frame-split instead (global-set-key (kbd "C-x 5") 'toggle-frame-split)