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?

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)
  • @xuchunyang sorry, I didn't see your answer when I started writing my answer, only after I posted it – bmag Apr 16 '16 at 10:31
  • Never mind, actually, I think your answer is more helpful to the OP. – xuchunyang Apr 16 '16 at 11:54
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)))
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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