19

Emacs is constantly making new windows and it's been ruining my day lately. How can I tell emacs to use the following policy when creating windows?

  • Prefer vertical splits
  • Stop doing vertical splits when windows would be less than 80 columns.
  • Stop doing horizontal splits when window would be less than 60 rows.
  • When I reach this 6x6 grid, on my 27" monitor, start reusing windows!

Also, I'd prefer my windows to always be balanced, but every split leaves the widow sizes unbalanced. I'd rather have 3 equally sized windows than 1 large and two which are too small! Is there a setting for this, or a sensible place to put a balance-windows advice?

9
  • What operations are creating the split windows? Commented Feb 22, 2016 at 12:18
  • I'm mostly doing clojure programming lately so cider commands like: cider-test-run-tests, cider-find-var, cider-doc, cider-switch-to-repl-buffer etc etc
    – expez
    Commented Feb 22, 2016 at 12:42
  • 1
    Most people aren't interested in opening up the source code -- e.g., the cider-stuff -- to customize it to suit their needs. Instead, they look for simple fixes like customizing the display-buffer-alist. Others just programmatically fix it after the fact -- e.g., delete-window and switch-to-buffer, split-vertically/horizontally, and so forth. And, there are some additional libraries to help manage the windows and/or revert back to the prior layout. I prefer the first option -- i.e., modify the source and make it absolutely perfect, but I am in the rare minority of people.
    – lawlist
    Commented Feb 22, 2016 at 17:26
  • 6
    Have a look at the section in the manual regarding window-splitting -- split-height-threshold and split-width-threshold -- gnu.org/software/emacs/manual/html_node/emacs/…
    – lawlist
    Commented Feb 22, 2016 at 17:49
  • 1
    It sounds like you want to define a custom ACTION function to use with a very generic CONDITION in display-buffer-alist. See display-buffer for the requirements of such an ACTION function (and the list of standard functions, the code for which you can examine), but it will be responsible for displaying the buffer in whichever manner you so wish (and can certainly balance the windows afterwards).
    – phils
    Commented May 29, 2016 at 11:52

4 Answers 4

6

A little late, but because I also searched for this and could not find a ready solution:

You could define your own split-window-sensibly function.
To do so, put the following in your init.el:

(setq split-height-threshold 120
      split-width-threshold 160)

(defun my-split-window-sensibly (&optional window)
    "replacement `split-window-sensibly' function which prefers vertical splits"
    (interactive)
    (let ((window (or window (selected-window))))
        (or (and (window-splittable-p window t)
                 (with-selected-window window
                     (split-window-right)))
            (and (window-splittable-p window)
                 (with-selected-window window
                     (split-window-below))))))

(setq split-window-preferred-function #'my-split-window-sensibly)

Note: the thresholds need to be twice as big as the smallest window allowed, because the new windows each use half of former window size.
The last line tells emacs to use the defined split function.

3

I've been using the following for a long time. You might need to edit it to accommodate your own preferred style.

;; ------------------------------------------------------------------
;; display-buffer

;; The default behaviour of `display-buffer' is to always create a new
;; window. As I normally use a large display sporting a number of
;; side-by-side windows, this is a bit obnoxious.
;;
;; The code below will make Emacs reuse existing windows, with the
;; exception that if have a single window open in a large display, it
;; will be split horisontally.

(setq pop-up-windows nil)

(defun my-display-buffer-function (buf not-this-window)
  (if (and (not pop-up-frames)
           (one-window-p)
           (or not-this-window
               (not (eq (window-buffer (selected-window)) buf)))
           (> (frame-width) 162))
      (split-window-horizontally))
  ;; Note: Some modules sets `pop-up-windows' to t before calling
  ;; `display-buffer' -- Why, oh, why!
  (let ((display-buffer-function nil)
        (pop-up-windows nil))
    (display-buffer buf not-this-window)))

(setq display-buffer-function 'my-display-buffer-function)
2
  • shouldn't the function be set to split-window-preferred-function instead of display-buffer-function?
    – Gangula
    Commented Jun 25 at 7:43
  • I guess you would add a function to that variable as well. However, you can't add this function, as functions in split-window-preferred-function are called with different arguments. Commented Jun 26 at 13:22
0

This will make you prefer vertical splits

(setq split-width-threshold 1)
0

This works for me on both my 15" MacBook Pro and external widescreen display:

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

  • Setting split-height-threshold to basically never wanting to split horizontally
  • 200 seems like a high-enough number that even on a large external display Emacs will only split at most once.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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