18

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?

expez
  • 381
  • 2
  • 8
  • What operations are creating the split windows? – Andrew Swann Feb 22 '16 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 Feb 22 '16 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 Feb 22 '16 at 17:26
  • 6
    Have a look at the section in the manual regarding window-splitting -- `split-height-threshold` and `split-width-threshold` -- https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Choice.html – lawlist Feb 22 '16 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 May 29 '16 at 11:52
  • You might want to check out the `shackle` package, which allows you to specify rules about how window popups work. I can't guarantee it will give you complete control. – Att Righ Mar 09 '17 at 19:44
  • Doesn't answer your actual question, but I find `winner-mode` helps with with this problem enormously as it gives you a window configuration history and allows changes to be easily undone. – stevoooo Apr 04 '17 at 14:26
  • I can't stand "sensible" vertical splits. @lawlist gave the simplest answer in his comment, thanks! – Bogatyr Mar 02 '21 at 15:35

4 Answers4

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.

jue
  • 4,476
  • 8
  • 20
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)
Lindydancer
  • 6,095
  • 1
  • 13
  • 25
0

This will make you prefer vertical splits

(setq split-width-threshold 1)
Stefan
  • 26,154
  • 3
  • 46
  • 84
CESCO
  • 364
  • 2
  • 13
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.