2

I would like to have split-window-sensibly splitting the window horizontally if the width is larger than height, or vertically otherwise. How can I achieve this?

xuhdev
  • 1,839
  • 13
  • 26

2 Answers2

2

The function split-window-sensibly isn't really customizable. Instead, you need to set split-window-preferred-function to your own function.

For example, here is a naive attempt to split horizontally if the width is larger than height, and vertically otherwise.

(defun my-sensible-window-split (&optional window)
  (cond
    ((and (> (window-width window)
             (window-height window))
          (window-splittable-p window 'horizontal))
      (with-selected-window window
        (split-window-right)))
    ((window-splittable-p window)
      (with-selected-window window
        (split-window-below)))))

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

A few notes:

You might want a different height/width ratio than 1:1, since the height of one line is actually larger than the width of one column. For a 1:2 ratio, you should use this condition:

(> (window-width window)
   (* 2 (window-height window)))

Since window-splittable-p takes into account split-height-threshold and split-width-threshold, in addition to the allowed minimal window sizes, you may want to change their default value. A value of 0 means no threshold. The default values (on my machine) are 80 and 160:

(setq split-height-threshold 0)
(setq split-width-threshold 0)
bmag
  • 1,703
  • 10
  • 12
0

In a graphic Emacs, window-pixel-width and window-pixel-height can return window's width and height in pixels, so if you only use graphic Emacs, these two functions should be sufficient, e.g.

(defun my-split-window ()
  (interactive)
  (if (> (window-pixel-width) (window-pixel-height))
      (split-window-horizontally)
    (split-window-vertically)))

In a terminal Emacs, it seems that window-width / window-pixel-width is almost a constant:

(when (display-graphic-p)
  (let ((w1 (window-width))
        (h1 (window-height))
        (w2 (window-pixel-width))
        (h2 (window-pixel-height)))
    (cons (/ (+ w2 .0) w1)
          (/ (+ h2 .0) h1))))
    ⇒ (8.112994350282486 . 16.93877551020408)

so we can get window-width in pixel base on this.

(setq display-resolution-ration '(8.112994350282486 . 16.93877551020408))

(defun window-width>height-p ()
  (if (display-graphic-p)
      (> (window-pixel-width)
         (window-pixel-height))
    (> (* (window-width) (car display-resolution-ration))
       (* (window-height) (cdr display-resolution-ration)))))

(defun my-another-split-window ()
  (interactive)
  (if (window-width>height-p)
      (split-window-horizontally)
    (split-window-vertically)))
xuchunyang
  • 14,302
  • 1
  • 18
  • 39
  • Thanks for the answer. However, what I was askjng is about the split-window-sensibly function, which is called by many extensions internally. How xan I change the behavior of that? – xuhdev Apr 16 '16 at 10:11
  • I don't really know. Maybe you can read `split-window-preferred-function`'s doc-string and take `split-window-sensibly` as an example to write your own split function. – xuchunyang Apr 16 '16 at 10:20
  • Searching the source of Emacs 24.5, the only function that calls `split-window-sensibly` directly is the obsolete `dired-pop-to-buffer`. Anywhere else the value of `split-window-preferred-function` is respected. – bmag Apr 16 '16 at 10:40