Prioritize split along the longest edge by default.
Currently, `split-window-sensibly' prefers to try to split vertically first, disregarding the actual shape of the frame or the user preferences. This is a good default when Emacs is taller than wider. However, when Emacs is in full-screen (landscape screen layout), trying to split vertically may not be what the user expected, since there is plenty of space available on the right. Typical scenario: Emacs is in landscape layout, one buffer is open in a window covering the entire frame. Another buffer is opened in a second window (C-x 4 f). Both splits are feasible but users may prefer the horizontal one. This patch preserves the behavior of the `split-height-threshold' and `split-width-threshold' variables. Splitting continues not to be permitted if the edge length is below the threshold. * lisp/window.el (split-window-sensibly): First tried split direction follows user preferences. * etc/NEWS: Add an entry for new variable `split-window-preferred-direction'. * doc/emacs/windows.texi: Document new variable.
This commit is contained in:
parent
028913c446
commit
77ff0df588
3 changed files with 78 additions and 25 deletions
|
@ -511,6 +511,7 @@ selected frame, and display the buffer in that new window.
|
|||
|
||||
@vindex split-height-threshold
|
||||
@vindex split-width-threshold
|
||||
@vindex split-window-preferred-direction
|
||||
The split can be either vertical or horizontal, depending on the
|
||||
variables @code{split-height-threshold} and
|
||||
@code{split-width-threshold}. These variables should have integer
|
||||
|
@ -519,7 +520,9 @@ window's height, the split puts the new window below. Otherwise, if
|
|||
@code{split-width-threshold} is smaller than the window's width, the
|
||||
split puts the new window on the right. If neither condition holds,
|
||||
Emacs tries to split so that the new window is below---but only if the
|
||||
window was not split before (to avoid excessive splitting).
|
||||
window was not split before (to avoid excessive splitting). Whether
|
||||
Emacs tries first to split vertically or horizontally, is
|
||||
determined by the value of @code{split-window-preferred-direction}.
|
||||
|
||||
@item
|
||||
Otherwise, display the buffer in a window previously showing it.
|
||||
|
|
8
etc/NEWS
8
etc/NEWS
|
@ -226,6 +226,14 @@ It has been obsolete since Emacs 30.1. Use '(category . comint)' instead.
|
|||
Another user option 'display-tex-shell-buffer-action' has been removed too
|
||||
for which you can use '(category . tex-shell)'.
|
||||
|
||||
+++
|
||||
*** New user option 'split-window-preferred-direction'.
|
||||
Users can now choose in which direction Emacs tries to split first:
|
||||
vertical or horizontal. With this new setting, when the frame is in
|
||||
landscape shape for instance, Emacs could split horizontally before
|
||||
splitting vertically. The default setting preserves Emacs historical
|
||||
behavior to try to split vertically first.
|
||||
|
||||
** Frames
|
||||
|
||||
+++
|
||||
|
|
|
@ -7394,20 +7394,64 @@ hold:
|
|||
(* 2 (max window-min-height
|
||||
(if mode-line-format 2 1))))))))))
|
||||
|
||||
(defcustom split-window-preferred-direction 'vertical
|
||||
"The first direction tried when Emacs needs to split a window.
|
||||
This variable controls in which order `split-window-sensibly' will try to
|
||||
split the window. That order specially matters when both dimensions of
|
||||
the frame are long enough to be split according to
|
||||
`split-width-threshold' and `split-height-threshold'. If this is set to
|
||||
`vertical' (the default), `split-window-sensibly' tries to split
|
||||
vertically first and then horizontally. If set to `horizontal' it does
|
||||
the opposite. If set to `longest', the first direction tried
|
||||
depends on the frame shape: in landscape orientation it will be like
|
||||
`horizontal', but in portrait it will be like `vertical'. Basically,
|
||||
the longest of the two dimension is split first.
|
||||
|
||||
If both `split-width-threshold' and `split-height-threshold' cannot be
|
||||
satisfied, it will fallback to split vertically.
|
||||
|
||||
See `split-window-preferred-function' for more control of the splitting
|
||||
strategy."
|
||||
:type '(radio
|
||||
(const :tag "Try to split vertically first"
|
||||
vertical)
|
||||
(const :tag "Try to split horizontally first"
|
||||
horizontal)
|
||||
(const :tag "Try to split along the longest edge first"
|
||||
longest))
|
||||
:version "31.1"
|
||||
:group 'windows)
|
||||
|
||||
(defun window--try-vertical-split (window)
|
||||
"Helper function for `split-window-sensibly'"
|
||||
(when (window-splittable-p window)
|
||||
(with-selected-window window
|
||||
(split-window-below))))
|
||||
|
||||
(defun window--try-horizontal-split (window)
|
||||
"Helper function for `split-window-sensibly'"
|
||||
(when (window-splittable-p window t)
|
||||
(with-selected-window window
|
||||
(split-window-right))))
|
||||
|
||||
(defun split-window-sensibly (&optional window)
|
||||
"Split WINDOW in a way suitable for `display-buffer'.
|
||||
WINDOW defaults to the currently selected window.
|
||||
If `split-height-threshold' specifies an integer, WINDOW is at
|
||||
least `split-height-threshold' lines tall and can be split
|
||||
vertically, split WINDOW into two windows one above the other and
|
||||
return the lower window. Otherwise, if `split-width-threshold'
|
||||
specifies an integer, WINDOW is at least `split-width-threshold'
|
||||
columns wide and can be split horizontally, split WINDOW into two
|
||||
windows side by side and return the window on the right. If this
|
||||
can't be done either and WINDOW is the only window on its frame,
|
||||
try to split WINDOW vertically disregarding any value specified
|
||||
by `split-height-threshold'. If that succeeds, return the lower
|
||||
window. Return nil otherwise.
|
||||
The variable `split-window-preferred-direction' prescribes an order of
|
||||
directions in which Emacs should try to split WINDOW. If that order
|
||||
mandates starting with a vertical split, and `split-height-threshold'
|
||||
specifies an integer that is at least as large a WINDOW's height, split
|
||||
WINDOW into two windows one below the other and return the lower one.
|
||||
If that order mandates starting with a horizontal split, and
|
||||
`split-width-threshold' specifies an integer that is at least as large
|
||||
as WINDOW's width, split WINDOW into two windows side by side and return
|
||||
the one on the right.
|
||||
|
||||
In either case, if the first attempt to split WINDOW fails, try to split
|
||||
the window in the other direction in the same manner as described above.
|
||||
If that attempt fails too, and WINDOW is the only window on its frame,
|
||||
try splitting WINDOW into two windows, one below the other, disregarding
|
||||
the value of `split-height-threshold' and return the window on the
|
||||
bottom.
|
||||
|
||||
By default `display-buffer' routines call this function to split
|
||||
the largest or least recently used window. To change the default
|
||||
|
@ -7427,14 +7471,14 @@ Have a look at the function `window-splittable-p' if you want to
|
|||
know how `split-window-sensibly' determines whether WINDOW can be
|
||||
split."
|
||||
(let ((window (or window (selected-window))))
|
||||
(or (and (window-splittable-p window)
|
||||
;; Split window vertically.
|
||||
(with-selected-window window
|
||||
(split-window-below)))
|
||||
(and (window-splittable-p window t)
|
||||
;; Split window horizontally.
|
||||
(with-selected-window window
|
||||
(split-window-right)))
|
||||
(or (if (or
|
||||
(eql split-window-preferred-direction 'horizontal)
|
||||
(and (eql split-window-preferred-direction 'longest)
|
||||
(> (frame-width) (frame-height))))
|
||||
(or (window--try-horizontal-split window)
|
||||
(window--try-vertical-split window))
|
||||
(or (window--try-vertical-split window)
|
||||
(window--try-horizontal-split window)))
|
||||
(and
|
||||
;; If WINDOW is the only usable window on its frame (it is
|
||||
;; the only one or, not being the only one, all the other
|
||||
|
@ -7452,10 +7496,8 @@ split."
|
|||
frame nil 'nomini)
|
||||
t)))
|
||||
(not (window-minibuffer-p window))
|
||||
(let ((split-height-threshold 0))
|
||||
(when (window-splittable-p window)
|
||||
(with-selected-window window
|
||||
(split-window-below))))))))
|
||||
(let ((split-height-threshold 0))
|
||||
(window--try-vertical-split window))))))
|
||||
|
||||
(defun window--try-to-split-window (window &optional alist)
|
||||
"Try to split WINDOW.
|
||||
|
|
Loading…
Add table
Reference in a new issue