6

From time to time, by mistake, I split my screen vertically C-x 3 (binded to split-window-right), whereas I originally wanted a horizontal splitting C-x 2 (binded to split-window-below).

Question: is there a function to switch between vertical <-> horizontal splitting?

note: for the moment, I hide the buffer C-x 0 and re-split with the right C-x 2 (instead of C-x 3) and reselect the buffer... which is clearly not optimal.

6

I use the following for 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))))))

I picked that up from Magnars Sveen of Emacs Rocks fame.

  • Thanks! Just tested it, it works. I will wait a little to see if other solutions working with more than 2 windows are suggested. – Picaud Vincent Dec 18 '18 at 14:43
  • 3
    sure thing. I never thought about this until Magnars mentioned it somewhere, and now it's indispensible. For tweaking more complex layouts I find ace-swap-windows from the ace-window package is also quite handy. – Tyler Dec 18 '18 at 14:49
5

You can roll your own as @Tyler suggested, but there are some packages that support this. Check out the transpose-frame package on MELPA: https://melpa.org/#/transpose-frame

This handles the simple 2-window case, but can also handle more complex arrangements where you flip or rotate the windows around.

3

I've not tried the transpose-frame package so I don't know how it compares, but I use the package https://melpa.org/#/rotate . Combined that with https://melpa.org/#/smartrep using the config:

  (use-package smartrep
    :config
    (setq smartrep-mode-line-active-bg nil))

  (use-package rotate
    :config
    (smartrep-define-key global-map "C-|"
    '(("w" . rotate-window)
      ("l" . rotate-layout))))

And then C-| w w w w... etc. rotates through assigning buffers to windows, and C-| l l l l... etc. rotates through layouts (such as your use case of flipping between a vertical and horizontal split).

1

I use C-x 0 (or C-x 1) and then C-x 4 b. The buffer I just closed is offered as the default, so it is still quick to do.

  • 2
    That doesn't "switch between horizontal and vertical splitting"; it just gives you the default split. – phils Dec 19 '18 at 4:04
  • @phil I think @Dan was referring to the "note" section of question where I say I was reselecting the buffer. The trick is to use C-x 4 b, but yes, that does not solve the problem. – Picaud Vincent Dec 19 '18 at 9:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.