Setting Emacs to Split Buffers Side-by-Side
Asked Answered
H

8

95

A lot of Emacs functions automatically split the screen. However, they all do so such that the windows are one on top of the other. Is there any way to make them split such that they are side-by-side by default instead?

Holladay answered 17/1, 2010 at 16:5 Comment(3)
I would swap usage of horizontal and vertical in this question - I'd say the default behaviour is to split horizontally (the split is a horizontal line across the screen).Superpower
C-x 3 runs the command split-window-horizontally, for the command which gives side-by-side windows, so I am using the same.Holladay
@Superpower "Vertical" and "horizontal" are ambiguous and could be interpreted differently; they could describe how the divider is oriented or how the partitions are oriented. My normal inclination is to agree with the wording of the original question (that is, I would normally interpret "split vertically" as "splitting the vertical space").Deliver
L
98
(setq split-height-threshold nil)
(setq split-width-threshold 0)

GNU Emacs Lisp Reference Manual: Choosing Window Options

Littles answered 17/1, 2010 at 17:53 Comment(8)
Note that these work because of how they affect split-window-preferred-function and the split-window-sensibly function that is set to - if you read the docs for that, you can find out how these variables being set affect things. For those of us who prefer vertical splitting by default, we can just use (setq split-width-threshold nil) which doesn't allow the system to split windows horizontally.Selftaught
After reading up the docs and playing around a bit, I have set split-height-threshold to nil and the split-width-threshold to 80 so that it will first see if it can split horizontally and only then try vertically. Having it only split vertically often just gets ugly as the windows become to narrow.Holladay
This sounds very plausible. However, this is not working for GDB/GUD integration in emacs. If I have one single window an start the debugger, emacs always splits vertically. Is there any GUD/GDB-specific setting for that?Polarity
@Nikwin: In my case, this solution limits "C-x 4 b" to two 80 column windows side-by-side (my current screen real estate can only fit that much). Invoking "C-x 4 b" a second time does not open up a new vertically split "other" window. Instead, it opens up the buffer on the "other" currently available window. How can I make it behave (try horizontally then vertically) as you have described?Hiltner
This isn't in the familiar C-x something format I know about. How do I execute these commands?Avert
Typically, you put them into your ~/.emacs, where they will take effect the next time you start emacs. Or you can just type them into any buffer, and for each of those two lines, put the cursor at the end of the line, and then type C-x C-e.Littles
Thanks. Actually, I needed the opposite, and I switched the 0 and nil and it works like a charm! I usually have my emacs window on the right side of my screen, with the browser on the left. And then when I am doing something with wide lines, I maximize my emacs window, and then it was doing horizontal divides... Now that problem is fixed!Trescott
Note that this code will also prevent the system from reusing existing window splits. That probably isn't what you want.Riches
S
8

Two solutions here, use any one you like:

A: Vertically(left/right) by default:

(setq split-height-threshold nil)
(setq split-width-threshold 0)

B: Automatically split window vertically(left/right) if current window is wide enough

(defun display-new-buffer (buffer force-other-window)
  "If BUFFER is visible, select it.
If it's not visible and there's only one window, split the
current window and select BUFFER in the new window. If the
current window (before the split) is more than 100 columns wide,
split horizontally(left/right), else split vertically(up/down).
If the current buffer contains more than one window, select
BUFFER in the least recently used window.
This function returns the window which holds BUFFER.
FORCE-OTHER-WINDOW is ignored."
  (or (get-buffer-window buffer)
    (if (one-window-p)
        (let ((new-win
               (if (> (window-width) 100)
                   (split-window-horizontally)
                 (split-window-vertically))))
          (set-window-buffer new-win buffer)
          new-win)
      (let ((new-win (get-lru-window)))
        (set-window-buffer new-win buffer)
        new-win))))
;; use display-buffer-alist instead of display-buffer-function if the following line won't work
(setq display-buffer-function 'display-new-buffer)

Put any one in you .emacs/init.el file. You can change the "100" to the value you like, depending on you screen.

If you got two windows in one frame, and you want to change the layout from vertical to horizontal or vice verse, here is a solution:

(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))))))
;; C-x 4 t 'toggle-window-split
(define-key ctl-x-4-map "t" 'toggle-window-split)

Put it in your .emacs/init.el file, Use C-x 4 t to toggle the layout of your windows.

Surrender answered 30/8, 2014 at 22:38 Comment(2)
On solution view when I was using undo-tree pressing q does not cluse the bufferOutsole
horizontal (top/bottom) by default: (setq split-height-threshold 0) (setq split-width-threshold nil)Eberto
B
4
(setq split-height-threshold 0) (setq split-width-threshold 0)

is what i had to use to get the desired behaviour (no horizontal splitting)

Baskin answered 22/2, 2011 at 8:49 Comment(0)
F
4

Sometimes we need change between Horizontal and Vertical according current display and our requirement (more lines or more columns).

I recommand the great ToggleWindowSplit, And I bind key to "C-c y"

http://www.emacswiki.org/emacs/ToggleWindowSplit

Facsimile answered 15/11, 2012 at 12:57 Comment(1)
Or transpose-frame, which is more elegant.Cardcarrying
T
1

the simple answer of setting 2 variables to nil and 0 didn't work for me, so I wrote 2 simple functions: one just splits the window into NX vertical buffers and opens files named (for example) file.1 file.2 ... file.NX in each and another one does the same think, except does it in 2D (NY rows by NX columns for opening files f.1 f.2 ... f.[NX*NY]). To install, add this code to .emacs:

    (defun grid-files-h (nx wx pfx)
  "Using dotimes, split the window into NX side-by-side buffers of width WX and load files starting with prefix PFX and ending in numbers 1 through NX"
  (let (ox fn k)  ; ox is not used, but fn is used to store the filename, and k to store the index string
    (dotimes (x (- nx 1) ox) ; go through buffers, x goes from 0 to nx-2 and ox is not used here
;     (print x)
      (setq k (number-to-string (+ x 1) ) )  ; k is a string that goes from "1" to "nx-1"
;     (print k)
      (setq fn (concat pfx k) ) ; fn is filename - concatenate prefix with k
;     (print fn)
      (find-file fn) ; open the filename in current buffer
      (split-window-horizontally wx) ; split window (current buffer gets wx-columns)
      (other-window 1) ; switch to the next (right) buffer
      )
    (setq k (number-to-string nx )) ; last (rightmost) buffer gets the "nx" file
    (setq fn (concat pfx k) ) ; fn = "pfx"+"nx"
    (find-file fn ) ; open fn
    (other-window 1) ; go back to the first buffer
    )  
  )

   (defun grid-files-sq (ny wy nx wx pfx)
      "Using dotimes, split the window into NX columns of width WX and NY rows of height WY and load files starting with prefix PFX and ending in numbers 1 through NX*NY"
      (let (oy ox fn k)  
        (dotimes (y ny oy) ; go through rows, y goes from 0 to ny-1 and oy is not used here
          (split-window-vertically wy) ; create this row
          (dotimes (x (- nx 1) ox) ; go through columns, x goes from 0 to nx-2 and ox is not used here
        (setq k (number-to-string (+ 1 (+ x (* y nx) ) ) ) ) ; k must convert 2 indecies (x,y) into one linear one (like sub2ind in matlab)
        (setq fn (concat pfx k) ) ; filename
        (find-file fn ) ; open
        (split-window-horizontally wx) ; create this column in this row (this "cell")
        (other-window 1) ; go to the next buffer on the right 
        )
          (setq k (number-to-string (+ nx (* y nx) ) ) ) ; rightmost buffer in this row needs a file too
          (setq fn (concat pfx k) ) ; filename
          (find-file fn ) ; open
          (other-window 1) ; go to next row (one buffer down)
          )
        )
      )

and then to use the vertical one, I go to *scratch* (C-x b *scratch* RET,C-x 1), type in (grid-files-h 3 20 "file.") then C-x C-e, or if you want to test out the square qrid one, C-x 1, type in (grid-files-sq 2 15 3 20 "f.") and then C-x C-e and you should see something like 2x3 grid

This probably can be done better/more efficiently, but it's a start and it does what I need it to do (display a bunch of sequentially named small files). Feel free to improve or reuse.

Telegonus answered 11/7, 2012 at 20:50 Comment(0)
O
1

I use multiple frames (OSX windows) in emacs regularly for different projects. Here's how I setup a few frames initially split to a left and right window.

  (defun make-maximized-split-frame (name)
    (let (( f (make-frame (list (cons 'name  name))) ))
      (maximize-frame f)
      (split-window (frame-root-window f) nil t)
      ))

  (make-maximized-split-frame "DocRaptor")
  (make-maximized-split-frame "Gauges")
  (make-maximized-split-frame "Instrumental")
Ostrich answered 15/3, 2015 at 23:23 Comment(0)
C
0

The direct answer is to press C-c 3.

It's not clear from the question if you want a permanent setting change, but I found this question looking for this answer and didn't find it. (The answer has actually been sitting in a comment for the last 11 years)

Crosspollination answered 13/10, 2021 at 22:14 Comment(0)
I
0

The emacs ediff mode which I use a lot has always showed the two buffers above and below each other and today I really wanted side-by-side. The above suggestions only sort-of worked for me, but then I saw that the ediff window that pops up gives the answer if you click on the '?': Tap the '|' character to toggle the split direction. It was always there but I never looked.

Incuse answered 28/3 at 17:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.