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?
2 Answers
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)
-
@xuchunyang sorry, I didn't see your answer when I started writing my answer, only after I posted it– bmagApr 16, 2016 at 10:31
-
Never mind, actually, I think your answer is more helpful to the OP. Apr 16, 2016 at 11:54
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)))
-
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?– xuhdevApr 16, 2016 at 10:11
-
I don't really know. Maybe you can read
split-window-preferred-function
's doc-string and takesplit-window-sensibly
as an example to write your own split function. Apr 16, 2016 at 10:20 -
Searching the source of Emacs 24.5, the only function that calls
split-window-sensibly
directly is the obsoletedired-pop-to-buffer
. Anywhere else the value ofsplit-window-preferred-function
is respected.– bmagApr 16, 2016 at 10:40