unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Prefer to split along the longest edge
@ 2024-12-14 10:05 Nicolas Desprès
  2024-12-14 11:30 ` Eli Zaretskii
  2024-12-14 18:35 ` Juri Linkov
  0 siblings, 2 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-14 10:05 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 2066 bytes --]

Hi,

I have been enjoying using Emacs since more than 20 years now.  So,
thank you all guys for this impressive work.

It is the first time I send a patch to this list.  I am not a very
fluent lisp coder so please do apologies if the style is not very
good and feel free to tell me how to improve it.

Currently, `split-window-sensibly' prefers to split vertically,
disregarding the shape of the frame.  This is a good default when
Emacs is taller than wider.  However, when Emacs is in fullscreen
(landscape screen layout), splitting vertically is generally not the
thing to do because there is plenty of space on the right.

Typical scenario: Emacs is in fullscreen; one buffer is open in a window
covering the entire frame.  Another buffer is opened in a second
window (C-x 4 f). In this case, the split should generally be horizontal.
The attached patch changes `split-window-sensibly' to just try
spliting the longest edge first. It works well when implemented in my
init.el
and installed by setting `split-window-preferred-function'.

However, when the same logic is implemented by directly modifying
`split-window-sensibly' in window.el, it does not work for one very specific
case: when the frame is 80x30 and C-x 4 f is pressed, the window is not
split and the buffer is opened in another frame. The problem seems to
come from the last eval expression at the bottom of `split-window-sensibly',
but I failed to find a solution. I though better elisp coder than me will
find a
solution quickly that's why I am posting here.

Apart from that, I have been using this alternate approach for a couple of
weeks now, and it works well, that's why I am submitting it for inclusion
in Emacs.

I have tested on 8d94a9ec613470b7e8e4ee0e86b643f34f8a724c with emacs built
with --with-imagemagick --with-native-compilation=yes
--with-compress-install --with-mailutils --with-gnutls --with-tree-sitter
--with-xwidgets --disable-gc-mark-trace --no-create --no-recursion on macOS
15.2.

Best regards,
Nico

-- 
Nicolas Desprès

[-- Attachment #1.2: Type: text/html, Size: 3928 bytes --]

[-- Attachment #2: 0001-Split-along-the-longest-edge-by-default.patch --]
[-- Type: application/octet-stream, Size: 5926 bytes --]

From 8d94a9ec613470b7e8e4ee0e86b643f34f8a724c Mon Sep 17 00:00:00 2001
From: Nicolas Despres <nicolas.despres@gmail.com>
Date: Fri, 13 Dec 2024 19:58:13 +0100
Subject: [PATCH] Split along the longest edge by default.

Currently, `split-window-sensibly' prefer to split vertically
disregarding the actual shape of the frame.  This is a good default when
Emacs is taller than wider.  However, when Emacs is in fullscreen
(landscape screen layout) splitting vertically is generally not the
things to do because there is plenty more space on the right.

Typical scenario: Emacs is in fullscreen, one buffer is open in window
covering the entire frame.  Another buffer is opened in a second
window (C-x 4 f). In this case, the split should happen horizontally.

I have tested this approach since a couple of weeks now and it works well
if `split-height-threshold' and `split-width-threshold' are set
properly.

* lisp/window.el (split-window-sensibly): Always prefer the longest edge
instead of blindly splitting vertically, unless width is less than 80 columns.

A part from that, the patch carefully preserves the current split logic.
---
 lisp/window.el | 68 ++++++++++++++++++++++++++++++--------------------
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..58ca6c8679d 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7347,20 +7347,30 @@ window-splittable-p
 		      (* 2 (max window-min-height
 				(if mode-line-format 2 1))))))))))
 
+(defun window--try-split-window-vertically (window)
+  "Helper function for `split-window-sensibly'"
+  (when (window-splittable-p window)
+    (with-selected-window window
+      (split-window-below))))
+
+(defun window--try-split-window-horizontally (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.
+WINDOW defaults to the currently selected window.  First, try to split
+along the longest edge of the window.  If the threshold
+(`split-height-threshold' respectively `split-width-threshold')
+specifies an integer, WINDOW is at least that threshold lines tall
+(resp. wide) and can be split (vertically respectively horizontally).
+If that fails, try to split along the shortest edge.  If this can't be
+done either and WINDOW is the only window on its frame, try to split
+WINDOW along the longest edge disregarding any value specified by
+`split-height-threshold' respectively `split-width-threshold'. If that
+succeeds, return the lower window.  Return nil otherwise.
 
 By default `display-buffer' routines call this function to split
 the largest or least recently used window.  To change the default
@@ -7379,21 +7389,27 @@ split-window-sensibly
 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)))
+  (let ((window (or window (selected-window)))
+        (first-split nil)
+        (second-split nil)
+        (first-threshold-variable nil))
+    ;; Choose preferred splitting edge.
+    (if (and (> (frame-width) (frame-height)) (> (frame-width) 80))
+        (setq first-split 'window--try-split-window-horizontally
+              second-split 'window--try-split-window-vertically
+              first-threshold-variable 'split-width-threshold)
+      (setq first-split 'window--try-split-window-vertically
+            second-split 'window--try-split-window-horizontally
+            first-threshold-variable 'split-height-threshold))
+    (or (funcall first-split window)
+	(funcall second-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
          ;; ones are dedicated) and is not the minibuffer window, try
-         ;; to split it vertically disregarding the value of
-         ;; `split-height-threshold'.
+         ;; to split it along the longest edge disregarding the value of
+         ;; the matching threshold (`split-height-threshold'
+         ;; or `split-width-threshold').
          (let ((frame (window-frame window)))
            (or
             (eq window (frame-root-window frame))
@@ -7405,10 +7421,8 @@ split-window-sensibly
                                 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))))))))
+	 (eval `(let ((,first-threshold-variable 0))
+                  (funcall first-split window)))))))
 
 (defun window--try-to-split-window (window &optional alist)
   "Try to split WINDOW.
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 10:05 Prefer to split along the longest edge Nicolas Desprès
@ 2024-12-14 11:30 ` Eli Zaretskii
  2024-12-14 11:45   ` Nicolas Desprès
  2024-12-14 17:16   ` martin rudalics
  2024-12-14 18:35 ` Juri Linkov
  1 sibling, 2 replies; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-14 11:30 UTC (permalink / raw)
  To: Nicolas Desprès, martin rudalics; +Cc: emacs-devel

> From: Nicolas Desprès <nicolas.despres@gmail.com>
> Date: Sat, 14 Dec 2024 11:05:30 +0100
> 
> Currently, `split-window-sensibly' prefers to split vertically,
> disregarding the shape of the frame.  This is a good default when
> Emacs is taller than wider.  However, when Emacs is in fullscreen
> (landscape screen layout), splitting vertically is generally not the
> thing to do because there is plenty of space on the right.
> 
> Typical scenario: Emacs is in fullscreen; one buffer is open in a window
> covering the entire frame.  Another buffer is opened in a second
> window (C-x 4 f). In this case, the split should generally be horizontal.
> The attached patch changes `split-window-sensibly' to just try
> spliting the longest edge first. It works well when implemented in my init.el
> and installed by setting `split-window-preferred-function'.

Why don't the user options split-height-threshold and
split-width-threshold we already have are not enough to allow to have
this without any code changes?

I add martin to this discussion, since I expect him to have a lot of
insight on these matters.

Thanks.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 11:30 ` Eli Zaretskii
@ 2024-12-14 11:45   ` Nicolas Desprès
  2024-12-14 12:34     ` Eli Zaretskii
  2024-12-14 17:16   ` martin rudalics
  1 sibling, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-14 11:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: martin rudalics, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1411 bytes --]

On Sat, Dec 14, 2024 at 12:30 PM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Nicolas Desprès <nicolas.despres@gmail.com>
> > Date: Sat, 14 Dec 2024 11:05:30 +0100
> >
> > Currently, `split-window-sensibly' prefers to split vertically,
> > disregarding the shape of the frame.  This is a good default when
> > Emacs is taller than wider.  However, when Emacs is in fullscreen
> > (landscape screen layout), splitting vertically is generally not the
> > thing to do because there is plenty of space on the right.
> >
> > Typical scenario: Emacs is in fullscreen; one buffer is open in a window
> > covering the entire frame.  Another buffer is opened in a second
> > window (C-x 4 f). In this case, the split should generally be horizontal.
> > The attached patch changes `split-window-sensibly' to just try
> > spliting the longest edge first. It works well when implemented in my
> init.el
> > and installed by setting `split-window-preferred-function'.
>
> Why don't the user options split-height-threshold and
> split-width-threshold we already have are not enough to allow to have
> this without any code changes?
>
> I add martin to this discussion, since I expect him to have a lot of
> insight on these matters.
>
>
Because these variables define the minimum size to allow splitting, not the
order by which split orientations are tried.

Thanks for replying :)
-Nico

[-- Attachment #2: Type: text/html, Size: 2167 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 11:45   ` Nicolas Desprès
@ 2024-12-14 12:34     ` Eli Zaretskii
  2024-12-14 14:06       ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-14 12:34 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: rudalics, emacs-devel

> From: Nicolas Desprès <nicolas.despres@gmail.com>
> Date: Sat, 14 Dec 2024 12:45:26 +0100
> Cc: martin rudalics <rudalics@gmx.at>, emacs-devel@gnu.org
> 
> On Sat, Dec 14, 2024 at 12:30 PM Eli Zaretskii <eliz@gnu.org> wrote:
> 
>  > From: Nicolas Desprès <nicolas.despres@gmail.com>
>  > Date: Sat, 14 Dec 2024 11:05:30 +0100
>  > 
>  > Currently, `split-window-sensibly' prefers to split vertically,
>  > disregarding the shape of the frame.  This is a good default when
>  > Emacs is taller than wider.  However, when Emacs is in fullscreen
>  > (landscape screen layout), splitting vertically is generally not the
>  > thing to do because there is plenty of space on the right.
>  > 
>  > Typical scenario: Emacs is in fullscreen; one buffer is open in a window
>  > covering the entire frame.  Another buffer is opened in a second
>  > window (C-x 4 f). In this case, the split should generally be horizontal.
>  > The attached patch changes `split-window-sensibly' to just try
>  > spliting the longest edge first. It works well when implemented in my init.el
>  > and installed by setting `split-window-preferred-function'.
> 
>  Why don't the user options split-height-threshold and
>  split-width-threshold we already have are not enough to allow to have
>  this without any code changes?
> 
> Because these variables define the minimum size to allow splitting, not the order by which split orientations
> are tried.

Sorry, I don't understand: does it mean you are unable to change the
value of split-height-threshold to cause the function to split
horizontally?  If so, can you show a recipe?



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 12:34     ` Eli Zaretskii
@ 2024-12-14 14:06       ` Nicolas Desprès
  2024-12-14 14:55         ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-14 14:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2049 bytes --]

On Sat, Dec 14, 2024 at 1:34 PM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Nicolas Desprès <nicolas.despres@gmail.com>
> > Date: Sat, 14 Dec 2024 12:45:26 +0100
> > Cc: martin rudalics <rudalics@gmx.at>, emacs-devel@gnu.org
> >
> > On Sat, Dec 14, 2024 at 12:30 PM Eli Zaretskii <eliz@gnu.org> wrote:
> >
> >  > From: Nicolas Desprès <nicolas.despres@gmail.com>
> >  > Date: Sat, 14 Dec 2024 11:05:30 +0100
> >  >
>
[...]

> >  >
> >  > Typical scenario: Emacs is in fullscreen; one buffer is open in a
> window
> >  > covering the entire frame.  Another buffer is opened in a second
> >  > window (C-x 4 f). In this case, the split should generally be
> horizontal.
> >  > The attached patch changes `split-window-sensibly' to just try
> >  > spliting the longest edge first. It works well when implemented in my
> init.el
> >  > and installed by setting `split-window-preferred-function'.
> >
> >  Why don't the user options split-height-threshold and
> >  split-width-threshold we already have are not enough to allow to have
> >  this without any code changes?
> >
> > Because these variables define the minimum size to allow splitting, not
> the order by which split orientations
> > are tried.
>
> Sorry, I don't understand: does it mean you are unable to change the
> value of split-height-threshold to cause the function to split
> horizontally?  If so, can you show a recipe?
>

I can by setting split-height-threshold to nil, but then it will never
split vertically.

The current implementation first tries to split vertically. If it fails, it
tries to split horizontally then it
falls back to vertical splitting.

So to split horizontally, it must first fail to split vertically.

The default threshold values are fine. I just want the default behavior to
try the longest edge first.
This way when both splitting would have succeeded (according to their
respective threshold value) it will split first where there is more room.

Cheers,
-Nico




-- 
Nicolas Desprès

[-- Attachment #2: Type: text/html, Size: 4100 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 14:06       ` Nicolas Desprès
@ 2024-12-14 14:55         ` Eli Zaretskii
  2024-12-14 15:41           ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-14 14:55 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: rudalics, emacs-devel

> From: Nicolas Desprès <nicolas.despres@gmail.com>
> Date: Sat, 14 Dec 2024 15:06:40 +0100
> Cc: rudalics@gmx.at, emacs-devel@gnu.org
> 
>  > Because these variables define the minimum size to allow splitting, not the order by which split
>  orientations
>  > are tried.
> 
>  Sorry, I don't understand: does it mean you are unable to change the
>  value of split-height-threshold to cause the function to split
>  horizontally?  If so, can you show a recipe?
> 
> I can by setting split-height-threshold to nil, but then it will never split vertically.

You can also set it to a large enough value, no?

> The current implementation first tries to split vertically. If it fails, it tries to split horizontally then it
> falls back to vertical splitting.
> 
> So to split horizontally, it must first fail to split vertically. 

Yes.

> The default threshold values are fine. I just want the default behavior to try the longest edge first.
> This way when both splitting would have succeeded (according to their respective threshold value) it will
> split first where there is more room.

But N columns are not equivalent to N lines.  IOW, if you have a
window that is (N+1)xN, splitting horizontally is not necessarily TRT.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 14:55         ` Eli Zaretskii
@ 2024-12-14 15:41           ` Nicolas Desprès
  0 siblings, 0 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-14 15:41 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: rudalics, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2010 bytes --]

On Sat, Dec 14, 2024 at 3:55 PM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Nicolas Desprès <nicolas.despres@gmail.com>
> > Date: Sat, 14 Dec 2024 15:06:40 +0100
> > Cc: rudalics@gmx.at, emacs-devel@gnu.org
> >
> >  > Because these variables define the minimum size to allow splitting,
> not the order by which split
> >  orientations
> >  > are tried.
> >
> >  Sorry, I don't understand: does it mean you are unable to change the
> >  value of split-height-threshold to cause the function to split
> >  horizontally?  If so, can you show a recipe?
> >
> > I can by setting split-height-threshold to nil, but then it will never
> split vertically.
>
> You can also set it to a large enough value, no?
>

Yes, with the same result of disabling vertical split.


>
> > The current implementation first tries to split vertically. If it fails,
> it tries to split horizontally then it
> > falls back to vertical splitting.
> >
> > So to split horizontally, it must first fail to split vertically.
>
> Yes.
>
> > The default threshold values are fine. I just want the default behavior
> to try the longest edge first.
> > This way when both splitting would have succeeded (according to their
> respective threshold value) it will
> > split first where there is more room.
>
> But N columns are not equivalent to N lines.  IOW, if you have a
> window that is (N+1)xN, splitting horizontally is not necessarily TRT.
>

In such a case, both are equally good, I guess. Most generally, Emacs'
frames are rectangles rather than squarish.

Note that I added a condition when the width is fewer than 80 columns to
preserve the historical behavior of Emacs to split vertically first.

The condition deciding which orientation is tried first could be further
tweaked to accommodate the difference between line height and column width.
It could be pixel-based, for instance.

My main point is that we can achieve a better default than blindly
splitting vertically.

[-- Attachment #2: Type: text/html, Size: 3375 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 11:30 ` Eli Zaretskii
  2024-12-14 11:45   ` Nicolas Desprès
@ 2024-12-14 17:16   ` martin rudalics
  2024-12-14 17:33     ` Eli Zaretskii
  2024-12-14 17:36     ` Eli Zaretskii
  1 sibling, 2 replies; 58+ messages in thread
From: martin rudalics @ 2024-12-14 17:16 UTC (permalink / raw)
  To: Eli Zaretskii, Nicolas Desprès; +Cc: emacs-devel

 > I add martin to this discussion, since I expect him to have a lot of
 > insight on these matters.

'split-window-sensibly' (initially called 'window--try-to-split-window')
was written by Stefan Monnier and was supposed to subsume the
functionality of 'split-window-preferred-horizontally' (written by Juri
Linkov).  Both know more about this issue than I do.

I only recall that initially many people hated the idea that it would
make a window on the right and subsequently set 'split-width-threshold'
to nil (Bug#431, Bug33929).  I'm afraid that changing the default
behavior again may lead to similar reactions even if people who set
‘split-width-threshold’ to nil should not be affected.

So whatever you do here please read the reports on Bug#1806, Bug#3142,
Bug#20189 (unless you have done so already) first and also do a search
for 'split-width-threshold' on emacs-devel.

Thanks, martin

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 17:16   ` martin rudalics
@ 2024-12-14 17:33     ` Eli Zaretskii
  2024-12-14 17:36     ` Eli Zaretskii
  1 sibling, 0 replies; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-14 17:33 UTC (permalink / raw)
  To: martin rudalics, Stefan Monnier; +Cc: nicolas.despres, emacs-devel

> Date: Sat, 14 Dec 2024 18:16:14 +0100
> Cc: emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > I add martin to this discussion, since I expect him to have a lot of
>  > insight on these matters.
> 
> 'split-window-sensibly' (initially called 'window--try-to-split-window')
> was written by Stefan Monnier and was supposed to subsume the
> functionality of 'split-window-preferred-horizontally' (written by Juri
> Linkov).  Both know more about this issue than I do.
> 
> I only recall that initially many people hated the idea that it would
> make a window on the right and subsequently set 'split-width-threshold'
> to nil (Bug#431, Bug33929).  I'm afraid that changing the default
> behavior again may lead to similar reactions even if people who set
> ‘split-width-threshold’ to nil should not be affected.
> 
> So whatever you do here please read the reports on Bug#1806, Bug#3142,
> Bug#20189 (unless you have done so already) first and also do a search
> for 'split-width-threshold' on emacs-devel.

Thanks, I added Stefan and Juri to the discussion.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 17:16   ` martin rudalics
  2024-12-14 17:33     ` Eli Zaretskii
@ 2024-12-14 17:36     ` Eli Zaretskii
  1 sibling, 0 replies; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-14 17:36 UTC (permalink / raw)
  To: martin rudalics, Stefan Monnier, Juri Linkov; +Cc: nicolas.despres, emacs-devel

> Date: Sat, 14 Dec 2024 18:16:14 +0100
> Cc: emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > I add martin to this discussion, since I expect him to have a lot of
>  > insight on these matters.
> 
> 'split-window-sensibly' (initially called 'window--try-to-split-window')
> was written by Stefan Monnier and was supposed to subsume the
> functionality of 'split-window-preferred-horizontally' (written by Juri
> Linkov).  Both know more about this issue than I do.
> 
> I only recall that initially many people hated the idea that it would
> make a window on the right and subsequently set 'split-width-threshold'
> to nil (Bug#431, Bug33929).  I'm afraid that changing the default
> behavior again may lead to similar reactions even if people who set
> ‘split-width-threshold’ to nil should not be affected.
> 
> So whatever you do here please read the reports on Bug#1806, Bug#3142,
> Bug#20189 (unless you have done so already) first and also do a search
> for 'split-width-threshold' on emacs-devel.

Thanks, adding Stefan and Juri to the discussion.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 10:05 Prefer to split along the longest edge Nicolas Desprès
  2024-12-14 11:30 ` Eli Zaretskii
@ 2024-12-14 18:35 ` Juri Linkov
  2024-12-14 20:10   ` Nicolas Desprès
  1 sibling, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2024-12-14 18:35 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: emacs-devel

> Currently, `split-window-sensibly' prefers to split vertically,
> disregarding the shape of the frame.  This is a good default when
> Emacs is taller than wider.  However, when Emacs is in fullscreen
> (landscape screen layout), splitting vertically is generally not the
> thing to do because there is plenty of space on the right.
>
> Typical scenario: Emacs is in fullscreen; one buffer is open in a window
> covering the entire frame.  Another buffer is opened in a second
> window (C-x 4 f). In this case, the split should generally be horizontal.
> The attached patch changes `split-window-sensibly' to just try
> spliting the longest edge first.

I see no symmetry between width and height.

To make a window usable you need to decide how many columns you need
to fit into the window by customizing split-width-threshold.

By default it's 160 that means two horizontally split windows
with 80 columns in each that allows a comfortable use of each window.

OTOH, the window height has less relevance since most of the time
all windows are scrolled vertically.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 18:35 ` Juri Linkov
@ 2024-12-14 20:10   ` Nicolas Desprès
  2024-12-15  7:34     ` Juri Linkov
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-14 20:10 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2035 bytes --]

On Sat, Dec 14, 2024 at 7:38 PM Juri Linkov <juri@linkov.net> wrote:

> > Currently, `split-window-sensibly' prefers to split vertically,
> > disregarding the shape of the frame.  This is a good default when
> > Emacs is taller than wider.  However, when Emacs is in fullscreen
> > (landscape screen layout), splitting vertically is generally not the
> > thing to do because there is plenty of space on the right.
> >
> > Typical scenario: Emacs is in fullscreen; one buffer is open in a window
> > covering the entire frame.  Another buffer is opened in a second
> > window (C-x 4 f). In this case, the split should generally be horizontal.
> > The attached patch changes `split-window-sensibly' to just try
> > spliting the longest edge first.
>
> I see no symmetry between width and height.
>
> To make a window usable you need to decide how many columns you need
> to fit into the window by customizing split-width-threshold.
>
> By default it's 160 that means two horizontally split windows
> with 80 columns in each that allows a comfortable use of each window.
>
> OTOH, the window height has less relevance since most of the time
> all windows are scrolled vertically.
>

Thanks for your reply.

My proposal is not about questioning the relevance of the
split-width-threshold and split-height-threshold. They are perfectly fine
to me.

I don't want to scroll twice more because of a vertical split, whereas I
have the 2/3 of my screen free to show another buffer of code.

In this scenario both splits would succeed because the frame dimension
exceeds by a lot their respective threshold.

My point is about the order in which splits are tried. I would like it to
first tries the longest edge.

So that if it succeed it is likely to be the direction where there is the
more space available.

But I understand the bias toward vertical splitting, that's why I added a
condition to prioritize vertical split if the width is less than 80. This
heuristic could be improved, thought.

[-- Attachment #2: Type: text/html, Size: 3206 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-14 20:10   ` Nicolas Desprès
@ 2024-12-15  7:34     ` Juri Linkov
  2024-12-15  9:29       ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2024-12-15  7:34 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: emacs-devel

> I don't want to scroll twice more because of a vertical split, whereas I
> have the 2/3 of my screen free to show another buffer of code.

What frame dimensions do you consider in this case?  Does the frame width allow
showing two horizontally split windows with enough number of columns?

> In this scenario both splits would succeed because the frame dimension
> exceeds by a lot their respective threshold.

Maybe increasing the value of split-height-threshold will help you?
For example, I customized it to a large value, so I have no problems
because then windows are split only horizontally.

> My point is about the order in which splits are tried. I would like it to
> first tries the longest edge.

Trying the longest edge might cause problems.  For example, for
frame dimension 100x90, the longest edge is the width 100.
But splitting the frame horizontally will create two windows
with only 50 columns that are too narrow for comfortable editing.

> So that if it succeed it is likely to be the direction where there is the
> more space available.

Not only the criteria for more available space is important.
Another criteria to not make too narrow window has no less importance.

> But I understand the bias toward vertical splitting, that's why I added a
> condition to prioritize vertical split if the width is less than 80. This
> heuristic could be improved, thought. 

I don't see the bias toward vertical splitting.

But if you could write in a clear form the current rules for an overview
and what changes do you propose, then the heuristic could be improved.
For example, how these rules could look:

1. split vertically if the width is less than 80
2. split horizontally if split-width-threshold is more than 160
3. split vertically otherwise
...



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-15  7:34     ` Juri Linkov
@ 2024-12-15  9:29       ` Nicolas Desprès
  2024-12-16  7:55         ` Juri Linkov
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-15  9:29 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2840 bytes --]

On Sun, Dec 15, 2024 at 8:48 AM Juri Linkov <juri@linkov.net> wrote:

> > I don't want to scroll twice more because of a vertical split, whereas I
> > have the 2/3 of my screen free to show another buffer of code.
>
> What frame dimensions do you consider in this case?  Does the frame width
> allow
> showing two horizontally split windows with enough number of columns?
>
> > In this scenario both splits would succeed because the frame dimension
> > exceeds by a lot their respective threshold.
>
> Maybe increasing the value of split-height-threshold will help you?
> For example, I customized it to a large value, so I have no problems
> because then windows are split only horizontally.
>

Yes, but I do want it to split vertically at some point.
Typically, in fullscreen mode, after 3 or 4 horizontal splits, I want it to
split vertically.


> > My point is about the order in which splits are tried. I would like it to
> > first tries the longest edge.
>
> Trying the longest edge might cause problems.  For example, for
> frame dimension 100x90, the longest edge is the width 100.
> But splitting the frame horizontally will create two windows
> with only 50 columns that are too narrow for comfortable editing.
>
> > So that if it succeed it is likely to be the direction where there is the
> > more space available.
>
> Not only the criteria for more available space is important.
> Another criteria to not make too narrow window has no less importance.
>

Agreed. See below.


> > But I understand the bias toward vertical splitting, that's why I added a
> > condition to prioritize vertical split if the width is less than 80. This
> > heuristic could be improved, thought.
>
> I don't see the bias toward vertical splitting.
>

Vertical split will be preferred even if you have a large width and a very
narrow height as long as it is higher than the threshold.


>
> But if you could write in a clear form the current rules for an overview
> and what changes do you propose, then the heuristic could be improved.
> For example, how these rules could look:
>
> 1. split vertically if the width is less than 80
> 2. split horizontally if split-width-threshold is more than 160
> 3. split vertically otherwise
>

The patch I attached does this:

if width > height and width > 80
   try to split horizontally, then try vertically and finally fallback to
horizontal split
else
   try to split vertically, then try horizontally and finally fallback to
vertical split

I have been using it for a couple of weeks and it is working fine.
The condition could be tweaked, specially the (widht > 80) part. We could
also decide to always fallback to vertical split at the end (which will fix
my implementation problem).

The else part is the original behavior.

[-- Attachment #2: Type: text/html, Size: 4939 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-15  9:29       ` Nicolas Desprès
@ 2024-12-16  7:55         ` Juri Linkov
  2024-12-16 11:56           ` Nicolas Desprès
  2024-12-16 17:15           ` [External] : " Drew Adams
  0 siblings, 2 replies; 58+ messages in thread
From: Juri Linkov @ 2024-12-16  7:55 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: emacs-devel

>> Maybe increasing the value of split-height-threshold will help you?
>> For example, I customized it to a large value, so I have no problems
>> because then windows are split only horizontally.
>
> Yes, but I do want it to split vertically at some point.
> Typically, in fullscreen mode, after 3 or 4 horizontal splits, I want it to
> split vertically.

Makes sense.  Then what about adding a new option that defines
the minimal number of columns each window should have after split?
With a name like 'split-columns-threshold'.

As long as the width of a new window will fit into 'split-columns-threshold',
split horizontally, otherwise vertically.

Then you can split to 3 or 4 horizontal splits until reaching the limit
of 'split-columns-threshold'.  After that should split the narrow windows
vertically.

>>> But I understand the bias toward vertical splitting, that's why I added a
>>> condition to prioritize vertical split if the width is less than 80.
>>> This heuristic could be improved, thought. 
>>
>> I don't see the bias toward vertical splitting.
>>
>> Vertical split will be preferred even if you have a large width and a very
>> narrow height as long as it is higher than the threshold.

Agreed, this is a problem.

>> But if you could write in a clear form the current rules for an overview
>> and what changes do you propose, then the heuristic could be improved.
>> For example, how these rules could look:
>>
>> 1. split vertically if the width is less than 80
>> 2. split horizontally if split-width-threshold is more than 160
>> 3. split vertically otherwise
>
> The patch I attached does this:
>
> if width > height and width > 80
>    try to split horizontally, then try vertically and finally fallback to horizontal split
> else
>    try to split vertically, then try horizontally and finally fallback to vertical split

We need to carefully check if it can handle various use cases.

> I have been using it for a couple of weeks and it is working fine.
> The condition could be tweaked, specially the (widht > 80) part. We could
> also decide to always fallback to vertical split at the end (which will fix
> my implementation problem).

Indeed, better to fallback to vertical split when all options are exhausted.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16  7:55         ` Juri Linkov
@ 2024-12-16 11:56           ` Nicolas Desprès
  2024-12-16 17:14             ` Eli Zaretskii
                               ` (2 more replies)
  2024-12-16 17:15           ` [External] : " Drew Adams
  1 sibling, 3 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-16 11:56 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 2301 bytes --]

On Mon, Dec 16, 2024 at 8:59 AM Juri Linkov <juri@linkov.net> wrote:

> >> Maybe increasing the value of split-height-threshold will help you?
> >> For example, I customized it to a large value, so I have no problems
> >> because then windows are split only horizontally.
> >
> > Yes, but I do want it to split vertically at some point.
> > Typically, in fullscreen mode, after 3 or 4 horizontal splits, I want it
> to
> > split vertically.
>
> Makes sense.  Then what about adding a new option that defines
> the minimal number of columns each window should have after split?
> With a name like 'split-columns-threshold'.
>
> As long as the width of a new window will fit into
> 'split-columns-threshold',
> split horizontally, otherwise vertically.
>
> Then you can split to 3 or 4 horizontal splits until reaching the limit
> of 'split-columns-threshold'.  After that should split the narrow windows
> vertically.
>

I think the variables split-width-threshold and split-height-threshold
already do that.

[...]

>
> > The patch I attached does this:
> >
> > if width > height and width > 80
> >    try to split horizontally, then try vertically and finally fallback
> to horizontal split
> > else
> >    try to split vertically, then try horizontally and finally fallback
> to vertical split
>
> We need to carefully check if it can handle various use cases.
>

Yes, one can install the new behavior using split-window-preferred-function
to try it out.

>
> > I have been using it for a couple of weeks and it is working fine.
> > The condition could be tweaked, specially the (widht > 80) part. We could
> > also decide to always fallback to vertical split at the end (which will
> fix
> > my implementation problem).
>
> Indeed, better to fallback to vertical split when all options are
> exhausted.
>

I wrote a new patch that always fallback on vertical split, and I got rid
of the weird (width > 80) condition since split-width-threshold already
does it.

The result is a simpler patch that works perfectly.

It basically does that:

if width > height:
   try to split horizontally, then try to split vertically
else
   try to split vertically, then try to split horizontally
fallback to vertical split

Cheers,
-Nico

[-- Attachment #1.2: Type: text/html, Size: 4222 bytes --]

[-- Attachment #2: 0001-Prioritize-split-along-the-longest-edge-by-default.patch --]
[-- Type: application/octet-stream, Size: 5058 bytes --]

From b6639a615a590a69ad66ab730c975fea74fcdb62 Mon Sep 17 00:00:00 2001
From: Nicolas Despres <nicolas.despres@gmail.com>
Date: Mon, 16 Dec 2024 12:40:20 +0100
Subject: [PATCH] Prioritize split along the longest edge by default.

Currently, `split-window-sensibly' prefer to try to split vertically
first disregarding the actual shape of the frame.  This is a good
default when Emacs is taller than wider.  However, when Emacs is in
fullscreen (landscape screen layout) trying to split vertically is
generally not the things to do because there is plenty more space
available on the right.

Typical scenario: Emacs is in fullscreen, one buffer is open in window
covering the entire frame.  Another buffer is opened in a second window
(C-x 4 f). In this case, the split should happen horizontally.

I have tested this approach since a couple of weeks now and it works
well.

This patch preserves the behavior of the `split-height-threshold' and
`split-width-threshold' variables. Splitting continue not be permitted
if the edge lenght is below the threshold.

* lisp/window.el (split-window-sensibly): Always prefer to try first the
longest edge instead of blindly trying to split vertically.

A part from that, the patch carefully preserves the current split logic.
---
 lisp/window.el | 53 +++++++++++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 24 deletions(-)

diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..a91666837c6 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7347,20 +7347,30 @@ window-splittable-p
 		      (* 2 (max window-min-height
 				(if mode-line-format 2 1))))))))))
 
+(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.
+WINDOW defaults to the currently selected window.  First, try to split
+along the longest edge of the window.  If the threshold
+(`split-height-threshold' respectively `split-width-threshold')
+specifies an integer, WINDOW is at least that threshold lines tall
+(resp. wide) and can be split (vertically respectively horizontally).
+If that fails, try to split along the shortest edge.  If this can't be
+done either and WINDOW is the only window on its frame, try to split
+WINDOW along the longest edge disregarding any value specified by
+`split-height-threshold' respectively `split-width-threshold'. If that
+succeeds, return the lower window.  Return nil otherwise.
 
 By default `display-buffer' routines call this function to split
 the largest or least recently used window.  To change the default
@@ -7380,14 +7390,11 @@ split-window-sensibly
 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 (> (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
@@ -7405,10 +7412,8 @@ split-window-sensibly
                                 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.
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 11:56           ` Nicolas Desprès
@ 2024-12-16 17:14             ` Eli Zaretskii
  2024-12-16 17:44               ` Juri Linkov
  2024-12-17  6:06               ` Nicolas Desprès
  2024-12-16 17:32             ` Juri Linkov
  2024-12-17  1:51             ` Liu Hui
  2 siblings, 2 replies; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-16 17:14 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: juri, emacs-devel

> From: Nicolas Desprès <nicolas.despres@gmail.com>
> Date: Mon, 16 Dec 2024 12:56:47 +0100
> Cc: emacs-devel@gnu.org
> 
> I wrote a new patch that always fallback on vertical split, and I got rid of the weird (width > 80) condition since
> split-width-threshold already does it.
> 
> The result is a simpler patch that works perfectly.
> 
> It basically does that:
> 
> if width > height:
>    try to split horizontally, then try to split vertically
> else
>    try to split vertically, then try to split horizontally
> fallback to vertical split

AFAIU, this is an incompatible change in behavior, with no way for
users who want the old behavior to get it back.

If so, please augment the change by a user option which controls
whether windows are split as they were before or according to the new
algorithm.  We can then discuss whether the default will be the old
behavior or the new one.

In any case, such a change needs a NEW entry, and probably also an
update for the manuals.

Last, but not least: for a contribution this size we'll need you to
assign copyright for your code to the FSF.  If you agree, I will send
you the form to fill and the instructions to start the paperwork of
assigning the copyright.

Thanks.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* RE: [External] : Re: Prefer to split along the longest edge
  2024-12-16  7:55         ` Juri Linkov
  2024-12-16 11:56           ` Nicolas Desprès
@ 2024-12-16 17:15           ` Drew Adams
  2024-12-17  8:39             ` Nicolas Desprès
  1 sibling, 1 reply; 58+ messages in thread
From: Drew Adams @ 2024-12-16 17:15 UTC (permalink / raw)
  To: Juri Linkov, Nicolas Desprès; +Cc: emacs-devel@gnu.org

> Makes sense.  Then what about adding a new option that defines
> the minimal number of columns each window should have after split?
> With a name like 'split-columns-threshold'.

(Caveat: not following this thread.)

Just a comment that a name such as `*-threshold' doesn't
tell you whether the threshold is a lower or upper bound.

Usually, a word such as `min' or `max' in the name is
more helpful.

(Of course, regardless of the name, the doc string should
anyway spell things out appropriately.)



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 11:56           ` Nicolas Desprès
  2024-12-16 17:14             ` Eli Zaretskii
@ 2024-12-16 17:32             ` Juri Linkov
  2024-12-17  9:01               ` martin rudalics
  2024-12-17  1:51             ` Liu Hui
  2 siblings, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2024-12-16 17:32 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: martin rudalics, emacs-devel

> I wrote a new patch that always fallback on vertical split, and I got rid
> of the weird (width > 80) condition since split-width-threshold already
> does it.
>
> The result is a simpler patch that works perfectly.

Thanks, a new patch is much better.

> It basically does that:
>
> if width > height:
>    try to split horizontally, then try to split vertically
> else
>    try to split vertically, then try to split horizontally
> fallback to vertical split

This makes sense, so Cc-ing Martin to confirm
if this is the right thing to do.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 17:14             ` Eli Zaretskii
@ 2024-12-16 17:44               ` Juri Linkov
  2024-12-16 19:07                 ` Eli Zaretskii
  2024-12-17  6:06               ` Nicolas Desprès
  1 sibling, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2024-12-16 17:44 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Nicolas Desprès, emacs-devel

>> I wrote a new patch that always fallback on vertical split, and I got rid of the weird (width > 80) condition since
>> split-width-threshold already does it.
>> 
>> The result is a simpler patch that works perfectly.
>> 
>> It basically does that:
>> 
>> if width > height:
>>    try to split horizontally, then try to split vertically
>> else
>>    try to split vertically, then try to split horizontally
>> fallback to vertical split
>
> AFAIU, this is an incompatible change in behavior, with no way for
> users who want the old behavior to get it back.
>
> If so, please augment the change by a user option which controls
> whether windows are split as they were before or according to the new
> algorithm.  We can then discuss whether the default will be the old
> behavior or the new one.

There is already the existing option 'split-window-preferred-function'.
It could provide a choice of more values to select a predefined
behavior.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 17:44               ` Juri Linkov
@ 2024-12-16 19:07                 ` Eli Zaretskii
  2024-12-16 19:14                   ` Juri Linkov
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-16 19:07 UTC (permalink / raw)
  To: Juri Linkov; +Cc: nicolas.despres, emacs-devel

> From: Juri Linkov <juri@linkov.net>
> Cc: Nicolas Desprès <nicolas.despres@gmail.com>,
>   emacs-devel@gnu.org
> Date: Mon, 16 Dec 2024 19:44:04 +0200
> 
> >> I wrote a new patch that always fallback on vertical split, and I got rid of the weird (width > 80) condition since
> >> split-width-threshold already does it.
> >> 
> >> The result is a simpler patch that works perfectly.
> >> 
> >> It basically does that:
> >> 
> >> if width > height:
> >>    try to split horizontally, then try to split vertically
> >> else
> >>    try to split vertically, then try to split horizontally
> >> fallback to vertical split
> >
> > AFAIU, this is an incompatible change in behavior, with no way for
> > users who want the old behavior to get it back.
> >
> > If so, please augment the change by a user option which controls
> > whether windows are split as they were before or according to the new
> > algorithm.  We can then discuss whether the default will be the old
> > behavior or the new one.
> 
> There is already the existing option 'split-window-preferred-function'.
> It could provide a choice of more values to select a predefined
> behavior.

We cannot ask users to write a function in order to get back old
behavior.  Customizations via functions is not user-friendly enough
for such simple tasks.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 19:07                 ` Eli Zaretskii
@ 2024-12-16 19:14                   ` Juri Linkov
  2024-12-16 19:53                     ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2024-12-16 19:14 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: nicolas.despres, emacs-devel

>> > If so, please augment the change by a user option which controls
>> > whether windows are split as they were before or according to the new
>> > algorithm.  We can then discuss whether the default will be the old
>> > behavior or the new one.
>> 
>> There is already the existing option 'split-window-preferred-function'.
>> It could provide a choice of more values to select a predefined
>> behavior.
>
> We cannot ask users to write a function in order to get back old
> behavior.  Customizations via functions is not user-friendly enough
> for such simple tasks.

I meant a choice from predefined functions.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 19:14                   ` Juri Linkov
@ 2024-12-16 19:53                     ` Eli Zaretskii
  2024-12-17  6:12                       ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-16 19:53 UTC (permalink / raw)
  To: Juri Linkov; +Cc: nicolas.despres, emacs-devel

> From: Juri Linkov <juri@linkov.net>
> Cc: nicolas.despres@gmail.com,  emacs-devel@gnu.org
> Date: Mon, 16 Dec 2024 21:14:46 +0200
> 
> >> > If so, please augment the change by a user option which controls
> >> > whether windows are split as they were before or according to the new
> >> > algorithm.  We can then discuss whether the default will be the old
> >> > behavior or the new one.
> >> 
> >> There is already the existing option 'split-window-preferred-function'.
> >> It could provide a choice of more values to select a predefined
> >> behavior.
> >
> > We cannot ask users to write a function in order to get back old
> > behavior.  Customizations via functions is not user-friendly enough
> > for such simple tasks.
> 
> I meant a choice from predefined functions.

Which ones?  I don't see any.

And how will we advertise this in a way that users affected by this
change will discover it easily?  split-window-sensibly is not a
command that users could look up, and split-window-preferred-function
is called by display-buffer, so finding this information in order to
use it for restoring previous behavior will not be easy.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 11:56           ` Nicolas Desprès
  2024-12-16 17:14             ` Eli Zaretskii
  2024-12-16 17:32             ` Juri Linkov
@ 2024-12-17  1:51             ` Liu Hui
  2024-12-17  7:43               ` Juri Linkov
  2024-12-17  8:26               ` Nicolas Desprès
  2 siblings, 2 replies; 58+ messages in thread
From: Liu Hui @ 2024-12-17  1:51 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: emacs-devel, Juri Linkov



在 2024/12/16 19:56, Nicolas Desprès 写道:
> 
> I wrote a new patch that always fallback on vertical split, and I got 
> rid of the weird (width > 80) condition since split-width-threshold 
> already does it.
> 
> The result is a simpler patch that works perfectly.
> 
> It basically does that:
> 
> if width > height:
>     try to split horizontally, then try to split vertically
> else
>     try to split vertically, then try to split horizontally
> fallback to vertical split

Hi,

I have the same problem when using emacs. Thank you for the patch.

I think the main reason is that vertical split is always preferred
when vertical and horizontal split are both feasible (i.e. width >
split-width-threshold and height > split-height-threshold).

So it seems unnecessary to compare the width and height. How about
adding an option, e.g. split-window-preferred-direction, and change
the condition as follows?

if user prefers horizontal split
     try to split horizontally, then try to split vertically
else
     try to split vertically, then try to split horizontally


Hui



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 17:14             ` Eli Zaretskii
  2024-12-16 17:44               ` Juri Linkov
@ 2024-12-17  6:06               ` Nicolas Desprès
  2024-12-17 12:52                 ` Eli Zaretskii
  2024-12-17 12:59                 ` Eli Zaretskii
  1 sibling, 2 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-17  6:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: juri, emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 1571 bytes --]

On Mon, Dec 16, 2024 at 6:14 PM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Nicolas Desprès <nicolas.despres@gmail.com>
> > Date: Mon, 16 Dec 2024 12:56:47 +0100
> > Cc: emacs-devel@gnu.org
> >
> > I wrote a new patch that always fallback on vertical split, and I got
> rid of the weird (width > 80) condition since
> > split-width-threshold already does it.
> >
> > The result is a simpler patch that works perfectly.
> >
> > It basically does that:
> >
> > if width > height:
> >    try to split horizontally, then try to split vertically
> > else
> >    try to split vertically, then try to split horizontally
> > fallback to vertical split
>
> AFAIU, this is an incompatible change in behavior, with no way for
> users who want the old behavior to get it back.
>
> If so, please augment the change by a user option which controls
> whether windows are split as they were before or according to the new
> algorithm.  We can then discuss whether the default will be the old
> behavior or the new one.
>
> In any case, such a change needs a NEW entry, and probably also an
> update for the manuals.
>

I have attached a new patch that should address all your remarks.

I added a new option `preferred-split-edge' and updated the NEWS file and
the manual.


>
> Last, but not least: for a contribution this size we'll need you to
> assign copyright for your code to the FSF.  If you agree, I will send
> you the form to fill and the instructions to start the paperwork of
> assigning the copyright.
>
>
I agree.
-Nico

[-- Attachment #1.2: Type: text/html, Size: 2946 bytes --]

[-- Attachment #2: 0001-Prioritize-split-along-the-longest-edge-by-default.patch --]
[-- Type: application/octet-stream, Size: 7545 bytes --]

From 6e1ebcbb7768f73b5d6498e8baccb899cebb1c0b Mon Sep 17 00:00:00 2001
From: Nicolas Despres <nicolas.despres@gmail.com>
Date: Tue, 17 Dec 2024 06:58:33 +0100
Subject: [PATCH] Prioritize split along the longest edge by default.

Currently, `split-window-sensibly' prefer to try to split vertically
first disregarding the actual shape of the frame or the users
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 split 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 continue not be permitted
if the edge length is below the threshold.

* lisp/window.el (split-window-sensibly): Always prefer to try first the
longest edge instead of blindly trying to split vertically.  * etc/NEWS:
Add an entry for new variable `preferred-split-edge'.  *
doc/emacs/windows.texi: Document new variable `preferred-split-edge'.
---
 doc/emacs/windows.texi |  5 ++-
 etc/NEWS               |  6 ++++
 lisp/window.el         | 73 ++++++++++++++++++++++++++++--------------
 3 files changed, 59 insertions(+), 25 deletions(-)

diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index 69f24ec192f..9e67cb1e07d 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -511,6 +511,7 @@ Window Choice
 
 @vindex split-height-threshold
 @vindex split-width-threshold
+@vindex preferred-split-edge
 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 Choice
 @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 to split the vertical or horizontal edge first, is
+determined by the value of @code{preferred-split-edge}.
 
 @item
 Otherwise, display the buffer in a window previously showing it.
diff --git a/etc/NEWS b/etc/NEWS
index 4f74795043e..3338e95bcaf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -174,6 +174,12 @@ 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 'preferred-split-edge'.
+Users can now choose which edge (vertical or horizontal) is tried to be
+split first.  With this new setting, when the frame is in landscape shape
+for instance, Emacs could split horizontally before to split vertically.
+
 ** Frames
 
 +++
diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..db6affaf1dd 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7347,20 +7347,47 @@ window-splittable-p
 		      (* 2 (max window-min-height
 				(if mode-line-format 2 1))))))))))
 
+(defcustom preferred-split-edge 'vertical
+  "The edge that `split-window-sensibly' will try to split first.
+This order matter when both edges can be split according to
+`split-width-threshold' and `split-height-threshold'."
+  :type '(choice
+          (const :tag "Try to split vertically first (legacy behavior)"
+                 vertical)
+          (const :tag "Try to split horizontally first"
+                 horizontal)
+          (const :tag "Try to split along the longest edge first"
+                 longest))
+  :version "30.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.
+WINDOW defaults to the currently selected window.  If the threshold
+(`split-height-threshold' respectively `split-width-threshold')
+specifies an integer, WINDOW is at least that threshold lines tall
+(respectively wide) and can be split (vertically respectively
+horizontally).  If that fails, try to split along the other edge.  If
+this can't be done either and WINDOW is the only window on its frame,
+try to split WINDOW along the vertical edge disregarding any value
+specified by `split-height-threshold' respectively
+`split-width-threshold'. If that succeeds, return the lower window.
+Return nil otherwise.
+
+The edge that is tried first can be configured by setting
+`preferred-split-edge'.
 
 By default `display-buffer' routines call this function to split
 the largest or least recently used window.  To change the default
@@ -7380,14 +7407,14 @@ split-window-sensibly
 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 preferred-split-edge 'horizontal)
+             (and (eql preferred-split-edge '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
@@ -7405,10 +7432,8 @@ split-window-sensibly
                                 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.
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 19:53                     ` Eli Zaretskii
@ 2024-12-17  6:12                       ` Nicolas Desprès
  2024-12-17  7:40                         ` Juri Linkov
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-17  6:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Juri Linkov, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1611 bytes --]

On Mon, Dec 16, 2024 at 8:54 PM Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Juri Linkov <juri@linkov.net>
> > Cc: nicolas.despres@gmail.com,  emacs-devel@gnu.org
> > Date: Mon, 16 Dec 2024 21:14:46 +0200
> >
> > >> > If so, please augment the change by a user option which controls
> > >> > whether windows are split as they were before or according to the
> new
> > >> > algorithm.  We can then discuss whether the default will be the old
> > >> > behavior or the new one.
> > >>
> > >> There is already the existing option
> 'split-window-preferred-function'.
> > >> It could provide a choice of more values to select a predefined
> > >> behavior.
> > >
> > > We cannot ask users to write a function in order to get back old
> > > behavior.  Customizations via functions is not user-friendly enough
> > > for such simple tasks.
> >
> > I meant a choice from predefined functions.
>
> Which ones?  I don't see any.
>
> And how will we advertise this in a way that users affected by this
> change will discover it easily?  split-window-sensibly is not a
> command that users could look up, and split-window-preferred-function
> is called by display-buffer, so finding this information in order to
> use it for restoring previous behavior will not be easy.
>

'split-window-preferred-function' is well suited for a completely different
behavior.

Providing multiple functions for slightly different variants will most
likely duplicate code.
This patch already factors the code a bit.
I am more in favor of an option to choose the behavior of
`split-window-sensibly'.

[-- Attachment #2: Type: text/html, Size: 2721 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  6:12                       ` Nicolas Desprès
@ 2024-12-17  7:40                         ` Juri Linkov
  2024-12-17  8:35                           ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2024-12-17  7:40 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: martin rudalics, Eli Zaretskii, emacs-devel

> 'split-window-preferred-function' is well suited for a completely different
> behavior.

There is another aspect that still can't be customized.
The choice of the window to split is hard-coded
in 'display-buffer-pop-up-window'.  It's either
the largest window or lru:

  ;; Attempt to split largest or least recently used window.
  (setq window (or (window--try-to-split-window
                    (get-largest-window frame t) alist)
                   (window--try-to-split-window
                    (get-lru-window frame t) alist)))

Maybe another option needed here as well?



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  1:51             ` Liu Hui
@ 2024-12-17  7:43               ` Juri Linkov
  2024-12-17  8:27                 ` Nicolas Desprès
  2024-12-17  8:26               ` Nicolas Desprès
  1 sibling, 1 reply; 58+ messages in thread
From: Juri Linkov @ 2024-12-17  7:43 UTC (permalink / raw)
  To: Liu Hui; +Cc: Nicolas Desprès, emacs-devel

> I have the same problem when using emacs. Thank you for the patch.
>
> I think the main reason is that vertical split is always preferred
> when vertical and horizontal split are both feasible (i.e. width >
> split-width-threshold and height > split-height-threshold).
>
> So it seems unnecessary to compare the width and height. How about
> adding an option, e.g. split-window-preferred-direction

split-window-preferred-direction is a better option name indeed.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  1:51             ` Liu Hui
  2024-12-17  7:43               ` Juri Linkov
@ 2024-12-17  8:26               ` Nicolas Desprès
  1 sibling, 0 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-17  8:26 UTC (permalink / raw)
  To: Liu Hui; +Cc: emacs-devel, Juri Linkov

[-- Attachment #1: Type: text/plain, Size: 634 bytes --]

On Tue, Dec 17, 2024 at 2:51 AM Liu Hui <liuhui1610@gmail.com> wrote:

>
>
> 在 2024/12/16 19:56, Nicolas Desprès 写道:
>
>
[...]

So it seems unnecessary to compare the width and height. How about
> adding an option, e.g. split-window-preferred-direction, and change
> the condition as follows?
>
> if user prefers horizontal split
>      try to split horizontally, then try to split vertically
> else
>      try to split vertically, then try to split horizontally
>
>
I think the longest choice is still needed for setup with one frame on a
portrait screen and another one on a landscape screen.

-Nico

[-- Attachment #2: Type: text/html, Size: 1563 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  7:43               ` Juri Linkov
@ 2024-12-17  8:27                 ` Nicolas Desprès
  0 siblings, 0 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-17  8:27 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Liu Hui, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 310 bytes --]

On Tue, Dec 17, 2024 at 8:47 AM Juri Linkov <juri@linkov.net> wrote:
[...]


> > So it seems unnecessary to compare the width and height. How about
> > adding an option, e.g. split-window-preferred-direction
>
> split-window-preferred-direction is a better option name indeed.
>

Ok. I change it.

[-- Attachment #2: Type: text/html, Size: 865 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  7:40                         ` Juri Linkov
@ 2024-12-17  8:35                           ` Nicolas Desprès
  2024-12-17  9:02                             ` martin rudalics
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-17  8:35 UTC (permalink / raw)
  To: Juri Linkov; +Cc: martin rudalics, Eli Zaretskii, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 947 bytes --]

On Tue, Dec 17, 2024 at 8:47 AM Juri Linkov <juri@linkov.net> wrote:

> > 'split-window-preferred-function' is well suited for a completely
> different
> > behavior.
>
> There is another aspect that still can't be customized.
> The choice of the window to split is hard-coded
> in 'display-buffer-pop-up-window'.  It's either
> the largest window or lru:
>
>   ;; Attempt to split largest or least recently used window.
>   (setq window (or (window--try-to-split-window
>                     (get-largest-window frame t) alist)
>                    (window--try-to-split-window
>                     (get-lru-window frame t) alist)))
>
> Maybe another option needed here as well?
>

That's right, there is the same logic pattern that could be customized the
same way. But that should come in another patch. I could make one if people
agree.

What would be the variable name ? split-window-preferred-selection ?

-Nico

[-- Attachment #2: Type: text/html, Size: 1762 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [External] : Re: Prefer to split along the longest edge
  2024-12-16 17:15           ` [External] : " Drew Adams
@ 2024-12-17  8:39             ` Nicolas Desprès
  0 siblings, 0 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-17  8:39 UTC (permalink / raw)
  To: Drew Adams; +Cc: Juri Linkov, emacs-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 871 bytes --]

On Mon, Dec 16, 2024 at 6:15 PM Drew Adams <drew.adams@oracle.com> wrote:

> > Makes sense.  Then what about adding a new option that defines
> > the minimal number of columns each window should have after split?
> > With a name like 'split-columns-threshold'.
>
> (Caveat: not following this thread.)
>
> Just a comment that a name such as `*-threshold' doesn't
> tell you whether the threshold is a lower or upper bound.
>
> Usually, a word such as `min' or `max' in the name is
> more helpful.
>
> (Of course, regardless of the name, the doc string should
> anyway spell things out appropriately.)
>

I agree. It actually brings confusion to the original conversation.

In our case, more explicit names would be split-line-min and
split-column-min.

If people agree on that, I could make another patch defining new aliases.

Cheers,
-Nico

[-- Attachment #2: Type: text/html, Size: 1771 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-16 17:32             ` Juri Linkov
@ 2024-12-17  9:01               ` martin rudalics
  2024-12-17 13:32                 ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: martin rudalics @ 2024-12-17  9:01 UTC (permalink / raw)
  To: Juri Linkov, Nicolas Desprès; +Cc: emacs-devel

 >> It basically does that:
 >>
 >> if width > height:
 >>     try to split horizontally, then try to split vertically

The only thing I can say is that for some time people strongly opposed
the idea of splitting windows side by side by default.  It's possible
that this attitude has changed by now.

 >> else
 >>     try to split vertically, then try to split horizontally
 >> fallback to vertical split
 >
 > This makes sense, so Cc-ing Martin to confirm
 > if this is the right thing to do.

martin



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  8:35                           ` Nicolas Desprès
@ 2024-12-17  9:02                             ` martin rudalics
  2024-12-17  9:09                               ` Nicolas Desprès
  2024-12-17 13:34                               ` Eli Zaretskii
  0 siblings, 2 replies; 58+ messages in thread
From: martin rudalics @ 2024-12-17  9:02 UTC (permalink / raw)
  To: Nicolas Desprès, Juri Linkov; +Cc: Eli Zaretskii, emacs-devel

 > What would be the variable name ? split-window-preferred-selection ?

Why a variable name?  At least this should become an alist entry so an
application doesn't have to bind it separately.

martin



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  9:02                             ` martin rudalics
@ 2024-12-17  9:09                               ` Nicolas Desprès
  2024-12-17 13:34                               ` Eli Zaretskii
  1 sibling, 0 replies; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-17  9:09 UTC (permalink / raw)
  To: martin rudalics; +Cc: Juri Linkov, Eli Zaretskii, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 352 bytes --]

On Tue, Dec 17, 2024 at 10:02 AM martin rudalics <rudalics@gmx.at> wrote:

>  > What would be the variable name ? split-window-preferred-selection ?
>
> Why a variable name?  At least this should become an alist entry so an
> application doesn't have to bind it separately.
>

That's right. I did not think about the context of this change.

[-- Attachment #2: Type: text/html, Size: 869 bytes --]

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  6:06               ` Nicolas Desprès
@ 2024-12-17 12:52                 ` Eli Zaretskii
  2024-12-17 12:59                 ` Eli Zaretskii
  1 sibling, 0 replies; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-17 12:52 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: juri, emacs-devel

> From: Nicolas Desprès <nicolas.despres@gmail.com>
> Date: Tue, 17 Dec 2024 07:06:07 +0100
> Cc: juri@linkov.net, emacs-devel@gnu.org
> 
>  Last, but not least: for a contribution this size we'll need you to
>  assign copyright for your code to the FSF.  If you agree, I will send
>  you the form to fill and the instructions to start the paperwork of
>  assigning the copyright.
> 
> I agree.

Form sent off-list.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  6:06               ` Nicolas Desprès
  2024-12-17 12:52                 ` Eli Zaretskii
@ 2024-12-17 12:59                 ` Eli Zaretskii
  2024-12-17 13:12                   ` Robert Pluim
  1 sibling, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-17 12:59 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: juri, emacs-devel

> From: Nicolas Desprès <nicolas.despres@gmail.com>
> Date: Tue, 17 Dec 2024 07:06:07 +0100
> Cc: juri@linkov.net, emacs-devel@gnu.org
> 
> I have attached a new patch that should address all your remarks.

Thanks.

> @@ -519,7 +520,9 @@ Window Choice
>  @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
                                                             ^^
Our convention is to leave two spaces between sentences.  (The same is
true for the text in the commit log messages.)

> ++++
> +*** New user option 'preferred-split-edge'.
> +Users can now choose which edge (vertical or horizontal) is tried to be
> +split first.  With this new setting, when the frame is in landscape shape
> +for instance, Emacs could split horizontally before to split vertically.

This should say what is the default behavior.

> +(defcustom preferred-split-edge 'vertical
> +  "The edge that `split-window-sensibly' will try to split first.
> +This order matter when both edges can be split according to
> +`split-width-threshold' and `split-height-threshold'."

This doc string should explain the meaning of each value.  (Yes, I
know that the text which describes each option does, but that doesn't
help when the user reads the doc string shown by "C-h v", for
example.)

> +  :type '(choice
> +          (const :tag "Try to split vertically first (legacy behavior)"
> +                 vertical)
> +          (const :tag "Try to split horizontally first"
> +                 horizontal)
> +          (const :tag "Try to split along the longest edge first"
> +                 longest))
> +  :version "30.1"
     ^^^^^^^^^^^^^^
This should be "31.1".



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17 12:59                 ` Eli Zaretskii
@ 2024-12-17 13:12                   ` Robert Pluim
  2024-12-18 21:08                     ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: Robert Pluim @ 2024-12-17 13:12 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: Eli Zaretskii, juri, emacs-devel

>>>>> On Tue, 17 Dec 2024 14:59:34 +0200, Eli Zaretskii <eliz@gnu.org> said:

    >> +  :type '(choice
    >> +          (const :tag "Try to split vertically first (legacy behavior)"
    >> +                 vertical)

I donʼt think you need the parenthetical comment (especially as
'legacy' can be seen as somewhat pejorative).

    >> +          (const :tag "Try to split horizontally first"
    >> +                 horizontal)
    >> +          (const :tag "Try to split along the longest edge first"
    >> +                 longest))
    >> +  :version "30.1"
    Eli>      ^^^^^^^^^^^^^^
    Eli> This should be "31.1".

Please consider using `radio' instead of `choice'. I believe it looks
better for variables with only small number of options.

Robert
-- 



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  9:01               ` martin rudalics
@ 2024-12-17 13:32                 ` Eli Zaretskii
  0 siblings, 0 replies; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-17 13:32 UTC (permalink / raw)
  To: martin rudalics; +Cc: juri, nicolas.despres, emacs-devel

> Date: Tue, 17 Dec 2024 10:01:01 +0100
> Cc: emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  >> It basically does that:
>  >>
>  >> if width > height:
>  >>     try to split horizontally, then try to split vertically
> 
> The only thing I can say is that for some time people strongly opposed
> the idea of splitting windows side by side by default.  It's possible
> that this attitude has changed by now.

Not here, it didn't.  Maybe because I'm not in the widespread business
of making every frame full-screen, or even close.  But given a user
options, personal preferences can be easily accounted for.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17  9:02                             ` martin rudalics
  2024-12-17  9:09                               ` Nicolas Desprès
@ 2024-12-17 13:34                               ` Eli Zaretskii
  2024-12-18 10:05                                 ` martin rudalics
  1 sibling, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-17 13:34 UTC (permalink / raw)
  To: martin rudalics; +Cc: nicolas.despres, juri, emacs-devel

> Date: Tue, 17 Dec 2024 10:02:23 +0100
> Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > What would be the variable name ? split-window-preferred-selection ?
> 
> Why a variable name?  At least this should become an alist entry so an
> application doesn't have to bind it separately.

It could be both.  But I firmly object to make this be customizable
_only_ through display-buffer action alists, because that is even less
user-friendly than function values of defcustoms.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17 13:34                               ` Eli Zaretskii
@ 2024-12-18 10:05                                 ` martin rudalics
  2024-12-18 14:12                                   ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: martin rudalics @ 2024-12-18 10:05 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: nicolas.despres, juri, emacs-devel

 > It could be both.  But I firmly object to make this be customizable
 > _only_ through display-buffer action alists, because that is even less
 > user-friendly than function values of defcustoms.

If we make this and other display buffer options a defcustom too, we'd
have to specify the semantics of that defcustom.  In particular:

- Should the defcustom hold for any buffer to be displayed?

- Should it override what the calling program specifies in the ALIST
   argument.

- Would a 'display-buffer-alist' entry override it?

Once these have been resolved, we can easily add defcustoms for most
options that are currently only available via 'display-buffer-alist'.

martin




^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 10:05                                 ` martin rudalics
@ 2024-12-18 14:12                                   ` Eli Zaretskii
  2024-12-18 16:24                                     ` martin rudalics
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-18 14:12 UTC (permalink / raw)
  To: martin rudalics; +Cc: nicolas.despres, juri, emacs-devel

> Date: Wed, 18 Dec 2024 11:05:55 +0100
> Cc: nicolas.despres@gmail.com, juri@linkov.net, emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > It could be both.  But I firmly object to make this be customizable
>  > _only_ through display-buffer action alists, because that is even less
>  > user-friendly than function values of defcustoms.
> 
> If we make this and other display buffer options a defcustom too, we'd
> have to specify the semantics of that defcustom.  In particular:

To clarify: I was talking only about this particular toggle, not about
"other display-buffer options".  The difference is that those other
options already exist, so removing or redesigning them is not easy at
best, and thus probably isn't worth our while.

> - Should the defcustom hold for any buffer to be displayed?
> 
> - Should it override what the calling program specifies in the ALIST
>    argument.
> 
> - Would a 'display-buffer-alist' entry override it?
> 
> Once these have been resolved, we can easily add defcustoms for most
> options that are currently only available via 'display-buffer-alist'.

I don't necessarily see how the above questions are relevant to the
issue at hand.  AFAIU, the OP asked for a capability to tell Emacs to
split horizontally first instead of vertically.  My interpretation of
that is that this desire is global, for all the use cases.  So a
single global option seems appropriate, and my personal answer to the
above questions would be YES to the first one at least.  As for the
other two: can display-buffer-alist specify the splitting behavior
this today?  If not, I don't see why we should forcibly introduce such
a possibility, which will then require us to consider who can override
whom.  If display-buffer-alist cannot specify splitting, then the
problem with overriding doesn't exist.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 14:12                                   ` Eli Zaretskii
@ 2024-12-18 16:24                                     ` martin rudalics
  2024-12-18 16:55                                       ` Eli Zaretskii
  2024-12-18 17:25                                       ` Juri Linkov
  0 siblings, 2 replies; 58+ messages in thread
From: martin rudalics @ 2024-12-18 16:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: nicolas.despres, juri, emacs-devel

 > To clarify: I was talking only about this particular toggle, not about
 > "other display-buffer options".  The difference is that those other
 > options already exist, so removing or redesigning them is not easy at
 > best, and thus probably isn't worth our while.

Which _toggle_ do you mean?  The option we were talking about here is

   There is another aspect that still can't be customized.
   The choice of the window to split is hard-coded
   in 'display-buffer-pop-up-window'.  It's either
   the largest window or lru:

and the primary client of such an option would be probably the program
calling 'display-buffer' and not the user.

martin



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 16:24                                     ` martin rudalics
@ 2024-12-18 16:55                                       ` Eli Zaretskii
  2024-12-18 17:41                                         ` martin rudalics
  2024-12-18 17:25                                       ` Juri Linkov
  1 sibling, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-18 16:55 UTC (permalink / raw)
  To: martin rudalics; +Cc: nicolas.despres, juri, emacs-devel

> Date: Wed, 18 Dec 2024 17:24:58 +0100
> Cc: nicolas.despres@gmail.com, juri@linkov.net, emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > To clarify: I was talking only about this particular toggle, not about
>  > "other display-buffer options".  The difference is that those other
>  > options already exist, so removing or redesigning them is not easy at
>  > best, and thus probably isn't worth our while.
> 
> Which _toggle_ do you mean?

The option we were discussing, split-window-preferred-direction.

> The option we were talking about here is
> 
>    There is another aspect that still can't be customized.
>    The choice of the window to split is hard-coded
>    in 'display-buffer-pop-up-window'.  It's either
>    the largest window or lru:
> 
> and the primary client of such an option would be probably the program
> calling 'display-buffer' and not the user.

Sorry, I lost you: what does display-buffer-pop-up-window have to do
with the subject of this thread?  I'm probably missing something.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 16:24                                     ` martin rudalics
  2024-12-18 16:55                                       ` Eli Zaretskii
@ 2024-12-18 17:25                                       ` Juri Linkov
  1 sibling, 0 replies; 58+ messages in thread
From: Juri Linkov @ 2024-12-18 17:25 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, nicolas.despres, emacs-devel

>   There is another aspect that still can't be customized.
>   The choice of the window to split is hard-coded
>   in 'display-buffer-pop-up-window'.  It's either
>   the largest window or lru:
>
> and the primary client of such an option would be probably the program
> calling 'display-buffer' and not the user.

Adding a special alist entry makes sense.  For example:

  (nil (window-to-split . lru))
  (nil (window-to-split . largest))

and also

  (nil (split-direction . horizontal))
  (nil (split-direction . vertical))



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 16:55                                       ` Eli Zaretskii
@ 2024-12-18 17:41                                         ` martin rudalics
  2024-12-18 18:41                                           ` Eli Zaretskii
  2024-12-19  7:06                                           ` Juri Linkov
  0 siblings, 2 replies; 58+ messages in thread
From: martin rudalics @ 2024-12-18 17:41 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: nicolas.despres, juri, emacs-devel

 > Sorry, I lost you: what does display-buffer-pop-up-window have to do
 > with the subject of this thread?  I'm probably missing something.

'display-buffer-pop-up-window' calls 'window--try-to-split-window' which
calls 'split-window-preferred-function' whose default value is
'split-window-sensibly' - the function whose behavior we are talking
about here.  Presently, this is the only way 'split-window-sensibly'
gets called in the Emacs sources.

martin



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 17:41                                         ` martin rudalics
@ 2024-12-18 18:41                                           ` Eli Zaretskii
  2024-12-18 19:13                                             ` martin rudalics
  2024-12-19  7:06                                           ` Juri Linkov
  1 sibling, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-18 18:41 UTC (permalink / raw)
  To: martin rudalics; +Cc: nicolas.despres, juri, emacs-devel

> Date: Wed, 18 Dec 2024 18:41:19 +0100
> Cc: nicolas.despres@gmail.com, juri@linkov.net, emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  > Sorry, I lost you: what does display-buffer-pop-up-window have to do
>  > with the subject of this thread?  I'm probably missing something.
> 
> 'display-buffer-pop-up-window' calls 'window--try-to-split-window' which
> calls 'split-window-preferred-function' whose default value is
> 'split-window-sensibly' - the function whose behavior we are talking
> about here.  Presently, this is the only way 'split-window-sensibly'
> gets called in the Emacs sources.

And I'm saying my understanding of the feature request here was that
each such splitting will behave as the OP asked: try to split
horizontally first.  The user option that is being proposed will
control this behavior and allow to toggle between the current and the
new behavior.




^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 18:41                                           ` Eli Zaretskii
@ 2024-12-18 19:13                                             ` martin rudalics
  0 siblings, 0 replies; 58+ messages in thread
From: martin rudalics @ 2024-12-18 19:13 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: nicolas.despres, juri, emacs-devel

 > And I'm saying my understanding of the feature request here was that
 > each such splitting will behave as the OP asked: try to split
 > horizontally first.  The user option that is being proposed will
 > control this behavior and allow to toggle between the current and the
 > new behavior.

We are talking past each other.  What I wrote was about Juri's request
to choose the window to split.  You talk about the method to split that
window.

martin




^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-17 13:12                   ` Robert Pluim
@ 2024-12-18 21:08                     ` Nicolas Desprès
  2024-12-19  6:39                       ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-18 21:08 UTC (permalink / raw)
  To: Robert Pluim; +Cc: Eli Zaretskii, juri, emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 207 bytes --]

Thanks Robert and Eli for your review, and sorry for the delayed answer, it
has been pretty busy at work lately.

You'll find attached a new version of the patch that should address all
your remarks.

-Nico

[-- Attachment #1.2: Type: text/html, Size: 692 bytes --]

[-- Attachment #2: 0001-Prioritize-split-along-the-longest-edge-by-default.patch --]
[-- Type: application/octet-stream, Size: 8267 bytes --]

From 45e44ffcbe73e33c410a1012721cc9009b2c0561 Mon Sep 17 00:00:00 2001
From: Nicolas Despres <nicolas.despres@gmail.com>
Date: Wed, 18 Dec 2024 22:03:18 +0100
Subject: [PATCH] Prioritize split along the longest edge by default.

Currently, `split-window-sensibly' prefer 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 split 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 continue 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.
---
 doc/emacs/windows.texi |  5 ++-
 etc/NEWS               |  8 ++++
 lisp/window.el         | 85 ++++++++++++++++++++++++++++++------------
 3 files changed, 73 insertions(+), 25 deletions(-)

diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index 69f24ec192f..7a740920b3b 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -511,6 +511,7 @@ Window Choice
 
 @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 Choice
 @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 to split the vertical or horizontal edge first, is
+determined by the value of @code{split-window-preferred-direction}.
 
 @item
 Otherwise, display the buffer in a window previously showing it.
diff --git a/etc/NEWS b/etc/NEWS
index c5396b4774c..7acba9d7edf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -165,6 +165,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 which edge (vertical or horizontal) is tried to be
+split first.  With this new setting, when the frame is in landscape shape
+for instance, Emacs could split horizontally before to split vertically.
+The default setting preserves Emacs historical behavior to try to split
+vertically first.
+
 ** Frames
 
 +++
diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..c96b6c3d948 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7347,20 +7347,59 @@ window-splittable-p
 		      (* 2 (max window-min-height
 				(if mode-line-format 2 1))))))))))
 
+(defcustom split-window-preferred-direction 'vertical
+  "The edge that will be first tried when Emacs need to split a window.
+That order matters when both edges can be split according to
+`split-width-threshold' and `split-height-threshold'.
+When this variable is to `vertical' (the default) Emacs tries to split
+vertically first and then horizontally.  If set to `horizontal' it does
+the opposite. When set to `longest', it the first direction tried will
+depends on the frame shape: in landscape orientation it will be like
+`horizontal', but in portrait it will be like `vertical'.  Basically the
+longest edge is split first.
+
+If both `split-width-threshold' and `split-height-threshold' cannot be
+satisfied, Emacs will fallback to split vertically.
+
+See `split-window-preferred-function' for more control on 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.
+WINDOW defaults to the currently selected window.  If the threshold
+(`split-height-threshold' respectively `split-width-threshold')
+specifies an integer, WINDOW is at least that threshold lines tall
+(respectively wide) and can be split (vertically respectively
+horizontally).  If that fails, try to split along the other edge.  If
+this can't be done either and WINDOW is the only window on its frame,
+try to split WINDOW along the vertical edge disregarding any value
+specified by `split-height-threshold' respectively
+`split-width-threshold'.  If that succeeds, return the lower window.
+Return nil otherwise.
+
+The edge that is tried first can be configured by setting
+`split-window-preferred-direction'.
 
 By default `display-buffer' routines call this function to split
 the largest or least recently used window.  To change the default
@@ -7380,14 +7419,14 @@ split-window-sensibly
 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
@@ -7405,10 +7444,8 @@ split-window-sensibly
                                 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.
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 21:08                     ` Nicolas Desprès
@ 2024-12-19  6:39                       ` Eli Zaretskii
  2024-12-19  8:52                         ` martin rudalics
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-19  6:39 UTC (permalink / raw)
  To: Nicolas Desprès, martin rudalics; +Cc: rpluim, juri, emacs-devel

> From: Nicolas Desprès <nicolas.despres@gmail.com>
> Date: Wed, 18 Dec 2024 22:08:58 +0100
> Cc: Eli Zaretskii <eliz@gnu.org>, juri@linkov.net, emacs-devel@gnu.org
> 
> Thanks Robert and Eli for your review, and sorry for the delayed answer, it has been pretty busy at work
> lately.
> 
> You'll find attached a new version of the patch that should address all your remarks.

Thanks, a few minor nits for the documentation parts below.

> @@ -519,7 +520,9 @@ Window Choice
>  @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 to split the vertical or horizontal edge first, is
> +determined by the value of @code{split-window-preferred-direction}.

Instead of "tries to split the vertical or horizontal edge first", I'd
prefer a simpler "tries first to split vertically or horizontally".
The "edge" part might confuse some readers.

> ++++
> +*** New user option 'split-window-preferred-direction'.
> +Users can now choose which edge (vertical or horizontal) is tried to be
> +split first.

Same rewording here.  "Users can now choose in which direction Emacs
tries to split windows first: vertical or horizontal."

> +(defcustom split-window-preferred-direction 'vertical
> +  "The edge that will be first tried when Emacs need to split a window.

Likewise here: I'd replace "edge" with "direction" or "dimension".

> +When this variable is to `vertical' (the default) Emacs tries to split
                      ^^^^^
"is set to"

> +vertically first and then horizontally.  If set to `horizontal' it does
> +the opposite. When set to `longest', it the first direction tried will
               ^^
Two spaces there.  Also, please use "If set to", not "When set to", to
avoid potential confusion due to misinterpretation of "when" as
something time-related.

> +depends on the frame shape: in landscape orientation it will be like
> +`horizontal', but in portrait it will be like `vertical'.  Basically the
> +longest edge is split first.
   ^^^^^^^^^^^^
"longest dimension", perhaps? or "longest window dimension"?

> +If both `split-width-threshold' and `split-height-threshold' cannot be
> +satisfied, Emacs will fallback to split vertically.
                         ^^^^^^^^
"fall back", two words.  Also, given the effect of this new option, I
think we should say ".. will fall back to splitting vertically,
regardless of the value of this variable."  Otherwise, it is not
immediately clear how this sentence is related to this variable.

> +          (const :tag "Try to split along the longest edge first"

I'd use "the longest dimension" instead of "longest edge".

> +                                                   If the threshold
> +(`split-height-threshold' respectively `split-width-threshold')
> +specifies an integer, WINDOW is at least that threshold lines tall
> +(respectively wide) and can be split (vertically respectively
> +horizontally).

This sentence doesn't look right, and the doc string in general is
hard to read and understand, because it tries to say things too
concisely.  How about this variant:

 WINDOW defaults to the currently selected window.

 If the split-size threshold of the window dimension determined by
 `split-window-preferred-direction' specifies an integer, the
 corresponding dimension of WINDOW is at least that large, then first
 try splitting window in two along that dimension (one below the other
 if splitting vertically, side by side if splitting horizontally).
 The relevant threshold is `split-height-threshold' when splitting
 vertically, and `split-width-threshold' when splitting horizontally.
 If splitting along the preferred dimension fails, try splitting
 WINDOW along the other dimension.  If that also fails, and WINDOW is
 the only window on its frame, try splitting WINDOW vertically
 disregarding the value of `split-height-threshold'.

 If splitting succeeds, return the lower window if splitting
 vertically, the right one if splitting horizontally.  If splitting
 fails, return nil.

Martin, any comments or corrections to the above doc string?



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-18 17:41                                         ` martin rudalics
  2024-12-18 18:41                                           ` Eli Zaretskii
@ 2024-12-19  7:06                                           ` Juri Linkov
  1 sibling, 0 replies; 58+ messages in thread
From: Juri Linkov @ 2024-12-19  7:06 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, nicolas.despres, emacs-devel

>> Sorry, I lost you: what does display-buffer-pop-up-window have to do
>> with the subject of this thread?  I'm probably missing something.
>
> 'display-buffer-pop-up-window' calls 'window--try-to-split-window' which
> calls 'split-window-preferred-function' whose default value is
> 'split-window-sensibly' - the function whose behavior we are talking
> about here.  Presently, this is the only way 'split-window-sensibly'
> gets called in the Emacs sources.

Maybe instead of adding a new option 'split-window-preferred-direction',
another new option would be more general than 'split-window-preferred-function',
and will specify a function that defines a window to split and splits it:
either vertically or horizontally.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-19  6:39                       ` Eli Zaretskii
@ 2024-12-19  8:52                         ` martin rudalics
  2024-12-19  9:21                           ` Eli Zaretskii
  0 siblings, 1 reply; 58+ messages in thread
From: martin rudalics @ 2024-12-19  8:52 UTC (permalink / raw)
  To: Eli Zaretskii, Nicolas Desprès; +Cc: rpluim, juri, emacs-devel

 >   If the split-size threshold of the window dimension determined by
 >   `split-window-preferred-direction' specifies an integer, the
 >   corresponding dimension of WINDOW is at least that large, then first
 >   try splitting window in two along that dimension (one below the other
 >   if splitting vertically, side by side if splitting horizontally).
 >   The relevant threshold is `split-height-threshold' when splitting
 >   vertically, and `split-width-threshold' when splitting horizontally.
 >   If splitting along the preferred dimension fails, try splitting
 >   WINDOW along the other dimension.  If that also fails, and WINDOW is
 >   the only window on its frame, try splitting WINDOW vertically
 >   disregarding the value of `split-height-threshold'.
 >
 >   If splitting succeeds, return the lower window if splitting
 >   vertically, the right one if splitting horizontally.  If splitting
 >   fails, return nil.
 >
 > Martin, any comments or corrections to the above doc string?

It's still hard to read for me.  I'd write is as follows:

The variable `split-window-preferred-direction' prescribes an order of
directions in which Emacs should try to split WINDOW.  If that order
mandates to start 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 to start 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 attempts fail 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.

Then the doc-string of 'split-window-preferred-direction' should say
that its value implies an order of operations 'split-window-sensibly'
will try and that that order may depend on the orientation of the frame.
While the frame orientation is processed in 'split-window-sensibly', I
wouldn't mention it there to avoid describing it twice.

BTW the doc-string of 'split-window-preferred-direction' should also say
that it applies to 'split-window-sensibly' only and not to any other
functions that split windows.

martin



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-19  8:52                         ` martin rudalics
@ 2024-12-19  9:21                           ` Eli Zaretskii
  2024-12-19 16:20                             ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: Eli Zaretskii @ 2024-12-19  9:21 UTC (permalink / raw)
  To: martin rudalics; +Cc: nicolas.despres, rpluim, juri, emacs-devel

> Date: Thu, 19 Dec 2024 09:52:53 +0100
> Cc: rpluim@gmail.com, juri@linkov.net, emacs-devel@gnu.org
> From: martin rudalics <rudalics@gmx.at>
> 
>  >   If the split-size threshold of the window dimension determined by
>  >   `split-window-preferred-direction' specifies an integer, the
>  >   corresponding dimension of WINDOW is at least that large, then first
>  >   try splitting window in two along that dimension (one below the other
>  >   if splitting vertically, side by side if splitting horizontally).
>  >   The relevant threshold is `split-height-threshold' when splitting
>  >   vertically, and `split-width-threshold' when splitting horizontally.
>  >   If splitting along the preferred dimension fails, try splitting
>  >   WINDOW along the other dimension.  If that also fails, and WINDOW is
>  >   the only window on its frame, try splitting WINDOW vertically
>  >   disregarding the value of `split-height-threshold'.
>  >
>  >   If splitting succeeds, return the lower window if splitting
>  >   vertically, the right one if splitting horizontally.  If splitting
>  >   fails, return nil.
>  >
>  > Martin, any comments or corrections to the above doc string?
> 
> It's still hard to read for me.  I'd write is as follows:
> 
> The variable `split-window-preferred-direction' prescribes an order of
> directions in which Emacs should try to split WINDOW.  If that order
> mandates to start 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 to start 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 attempts fail 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.
> 
> Then the doc-string of 'split-window-preferred-direction' should say
> that its value implies an order of operations 'split-window-sensibly'
> will try and that that order may depend on the orientation of the frame.
> While the frame orientation is processed in 'split-window-sensibly', I
> wouldn't mention it there to avoid describing it twice.
> 
> BTW the doc-string of 'split-window-preferred-direction' should also say
> that it applies to 'split-window-sensibly' only and not to any other
> functions that split windows.

Thanks, this is fine by me.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-19  9:21                           ` Eli Zaretskii
@ 2024-12-19 16:20                             ` Nicolas Desprès
  2024-12-20  9:03                               ` martin rudalics
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-19 16:20 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: martin rudalics, rpluim, juri, emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 167 bytes --]

Hi,

Thank you all for your feedback.  My first attempt was to try to stick to
the original explanation.

Attached, the new version of the patch.

Best regards,
-Nico

[-- Attachment #1.2: Type: text/html, Size: 676 bytes --]

[-- Attachment #2: 0001-Prioritize-split-along-the-longest-edge-by-default.patch --]
[-- Type: application/octet-stream, Size: 8661 bytes --]

From 23c660e5b05dec7dedcc5d2e1ce9cad8fbc82452 Mon Sep 17 00:00:00 2001
From: Nicolas Despres <nicolas.despres@gmail.com>
Date: Thu, 19 Dec 2024 16:52:37 +0100
Subject: [PATCH] Prioritize split along the longest edge by default.

Currently, `split-window-sensibly' prefer 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 split 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 continue 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.
---
 doc/emacs/windows.texi |  5 ++-
 etc/NEWS               |  8 ++++
 lisp/window.el         | 90 +++++++++++++++++++++++++++++++-----------
 3 files changed, 78 insertions(+), 25 deletions(-)

diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index 69f24ec192f..1885e5a7f2e 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -511,6 +511,7 @@ Window Choice
 
 @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 Choice
 @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 frist 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.
diff --git a/etc/NEWS b/etc/NEWS
index c5396b4774c..5d4948fbfe3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -165,6 +165,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 to
+split vertically.  The default setting preserves Emacs historical
+behavior to try to split vertically first.
+
 ** Frames
 
 +++
diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..c7139bee893 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7347,20 +7347,64 @@ window-splittable-p
 		      (* 2 (max window-min-height
 				(if mode-line-format 2 1))))))))))
 
+(defcustom split-window-preferred-direction 'vertical
+  "The first direction tried when Emacs need to split a window.
+This variable control in which order `split-window-sensibly' will try to
+split the window.  That order specially matters when both dimension 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', it the first direction tried will
+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 on 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 to start 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 to start 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 attempts fail 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
@@ -7380,14 +7424,14 @@ split-window-sensibly
 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
@@ -7405,10 +7449,8 @@ split-window-sensibly
                                 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.
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-19 16:20                             ` Nicolas Desprès
@ 2024-12-20  9:03                               ` martin rudalics
  2024-12-20 14:43                                 ` Nicolas Desprès
  0 siblings, 1 reply; 58+ messages in thread
From: martin rudalics @ 2024-12-20  9:03 UTC (permalink / raw)
  To: Nicolas Desprès, Eli Zaretskii; +Cc: rpluim, juri, emacs-devel

 > Attached, the new version of the patch.

Thanks.  Please systematically do two things:

Instead of

"`split-window-sensibly' prefer to try to"
"Splitting continue"
"This variable control"

say

"`split-window-sensibly' prefers to try to"
"Splitting continues"
"This variable controls"

and so on.

And please make sure that two spaces follow each period, especially in
doc-strings.

Eli will take care of the remaining stylistic issues - his English is
decidedly better than mine.

Thanks, martin



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-20  9:03                               ` martin rudalics
@ 2024-12-20 14:43                                 ` Nicolas Desprès
  2024-12-20 15:05                                   ` Robert Pluim
  0 siblings, 1 reply; 58+ messages in thread
From: Nicolas Desprès @ 2024-12-20 14:43 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, rpluim, juri, emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 763 bytes --]

On Fri, Dec 20, 2024 at 10:03 AM martin rudalics <rudalics@gmx.at> wrote:

>  > Attached, the new version of the patch.
>
> Thanks.  Please systematically do two things:
>
> Instead of
>
> "`split-window-sensibly' prefer to try to"
> "Splitting continue"
>

Could not find those ones.

"This variable control"
>

Fixed


> say
>
> "`split-window-sensibly' prefers to try to"
> "Splitting continues"
> "This variable controls"
>
> and so on.
>
> And please make sure that two spaces follow each period, especially in
> doc-strings.
>

So sorry for those mistakes again.


> Eli will take care of the remaining stylistic issues - his English is
> decidedly better than mine.
>

and mine !

Thanks for your review.
-Nico

[-- Attachment #1.2: Type: text/html, Size: 2514 bytes --]

[-- Attachment #2: 0001-Prioritize-split-along-the-longest-edge-by-default.patch --]
[-- Type: application/octet-stream, Size: 8660 bytes --]

From 0f3576f9ce23b2e6608b1718301a621c9f153202 Mon Sep 17 00:00:00 2001
From: Nicolas Despres <nicolas.despres@gmail.com>
Date: Fri, 20 Dec 2024 15:41:38 +0100
Subject: [PATCH] Prioritize split along the longest edge by default.

Currently, `split-window-sensibly' prefer 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 split 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 continue 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.
---
 doc/emacs/windows.texi |  5 ++-
 etc/NEWS               |  8 ++++
 lisp/window.el         | 90 +++++++++++++++++++++++++++++++-----------
 3 files changed, 78 insertions(+), 25 deletions(-)

diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index 69f24ec192f..1885e5a7f2e 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -511,6 +511,7 @@ Window Choice
 
 @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 Choice
 @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 frist 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.
diff --git a/etc/NEWS b/etc/NEWS
index 9a7b320acdb..04435d74dff 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -183,6 +183,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 to
+split vertically.  The default setting preserves Emacs historical
+behavior to try to split vertically first.
+
 ** Frames
 
 +++
diff --git a/lisp/window.el b/lisp/window.el
index e9d57652ec6..d0242c55a2a 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7347,20 +7347,64 @@ window-splittable-p
 		      (* 2 (max window-min-height
 				(if mode-line-format 2 1))))))))))
 
+(defcustom split-window-preferred-direction 'vertical
+  "The first direction tried when Emacs need 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 dimension 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 will
+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 on 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 to start 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 to start 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 attempts fail 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
@@ -7380,14 +7424,14 @@ split-window-sensibly
 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
@@ -7405,10 +7449,8 @@ split-window-sensibly
                                 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.
-- 
2.47.1


^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-20 14:43                                 ` Nicolas Desprès
@ 2024-12-20 15:05                                   ` Robert Pluim
  2024-12-20 20:25                                     ` Stephen Berman
  0 siblings, 1 reply; 58+ messages in thread
From: Robert Pluim @ 2024-12-20 15:05 UTC (permalink / raw)
  To: Nicolas Desprès; +Cc: martin rudalics, Eli Zaretskii, juri, emacs-devel


Minor nits below

>>>>> On Fri, 20 Dec 2024 15:43:51 +0100, Nicolas Desprès <nicolas.despres@gmail.com> said:
    Nicolas> Thanks for your review.
    Nicolas> -Nico
    Nicolas> From 0f3576f9ce23b2e6608b1718301a621c9f153202 Mon Sep 17 00:00:00 2001
    Nicolas> From: Nicolas Despres <nicolas.despres@gmail.com>
    Nicolas> Date: Fri, 20 Dec 2024 15:41:38 +0100
    Nicolas> Subject: [PATCH] Prioritize split along the longest edge by default.

    Nicolas> Currently, `split-window-sensibly' prefer to try to split vertically

'prefers to'

    Nicolas> first disregarding the actual shape of the frame or the user

'first,'

    Nicolas> preferences.  This is a good default when Emacs is taller than wider.
    Nicolas> However, when Emacs is in full-screen (landscape screen layout) trying to

'),'
    Nicolas> split vertically may not be what the user expected since there is plenty

'expected,'

    Nicolas> of space available on the right.

    Nicolas> Typical scenario: Emacs is in landscape layout, one buffer is open in a
    Nicolas> window covering the entire frame.  Another buffer is opened in a second
    Nicolas> window (C-x 4 f). Both split are feasible but users may prefer the

'splits'

    Nicolas> horizontal one.

    Nicolas> This patch preserves the behavior of the `split-height-threshold' and
    Nicolas> `split-width-threshold' variables. Splitting continue not to be

'continues'

    Nicolas> permitted if the edge length is below the threshold.

    Nicolas> * lisp/window.el (split-window-sensibly): First tried split
    Nicolas> direction follows user preferences.
    Nicolas> * etc/NEWS: Add an entry for new variable
    Nicolas> `split-window-preferred-direction'.
    Nicolas> * doc/emacs/windows.texi: Document new variable.
    Nicolas> ---
    Nicolas>  doc/emacs/windows.texi |  5 ++-
    Nicolas>  etc/NEWS               |  8 ++++
    Nicolas>  lisp/window.el         | 90 +++++++++++++++++++++++++++++++-----------
    Nicolas>  3 files changed, 78 insertions(+), 25 deletions(-)

    Nicolas> diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
    Nicolas> index 69f24ec192f..1885e5a7f2e 100644
    Nicolas> --- a/doc/emacs/windows.texi
    Nicolas> +++ b/doc/emacs/windows.texi
    Nicolas> @@ -511,6 +511,7 @@ Window Choice
 
    Nicolas>  @vindex split-height-threshold
    Nicolas>  @vindex split-width-threshold
    Nicolas> +@vindex split-window-preferred-direction
    Nicolas>  The split can be either vertical or horizontal, depending on the
    Nicolas>  variables @code{split-height-threshold} and
    Nicolas>  @code{split-width-threshold}.  These variables should have integer
    Nicolas> @@ -519,7 +520,9 @@ Window Choice
    Nicolas>  @code{split-width-threshold} is smaller than the window's width, the
    Nicolas>  split puts the new window on the right.  If neither condition holds,
    Nicolas>  Emacs tries to split so that the new window is below---but only if the
    Nicolas> -window was not split before (to avoid excessive splitting).
    Nicolas> +window was not split before (to avoid excessive splitting).  Whether
    Nicolas> +Emacs tries frist to split vertically or horizontally, is

'first'

    Nicolas> +determined by the value of @code{split-window-preferred-direction}.
 
    Nicolas>  @item
    Nicolas>  Otherwise, display the buffer in a window previously showing it.
    Nicolas> diff --git a/etc/NEWS b/etc/NEWS
    Nicolas> index 9a7b320acdb..04435d74dff 100644
    Nicolas> --- a/etc/NEWS
    Nicolas> +++ b/etc/NEWS
    Nicolas> @@ -183,6 +183,14 @@ It has been obsolete since Emacs 30.1.  Use '(category . comint)' instead.
    Nicolas>  Another user option 'display-tex-shell-buffer-action' has been removed too
    Nicolas>  for which you can use '(category . tex-shell)'.
 
    Nicolas> ++++
    Nicolas> +*** New user option 'split-window-preferred-direction'.
    Nicolas> +Users can now choose in which direction Emacs tries to split first:
    Nicolas> +vertical or horizontal.  With this new setting, when the frame is in
    Nicolas> +landscape shape for instance, Emacs could split horizontally before to
    Nicolas> +split vertically.  The default setting preserves Emacs historical

'before splitting' instead of 'before to split'

    Nicolas> +behavior to try to split vertically first.
    Nicolas> +
    Nicolas>  ** Frames
 
    Nicolas>  +++
    Nicolas> diff --git a/lisp/window.el b/lisp/window.el
    Nicolas> index e9d57652ec6..d0242c55a2a 100644
    Nicolas> --- a/lisp/window.el
    Nicolas> +++ b/lisp/window.el
    Nicolas> @@ -7347,20 +7347,64 @@ window-splittable-p
    Nicolas>  		      (* 2 (max window-min-height
    Nicolas>  				(if mode-line-format 2 1))))))))))
 
    Nicolas> +(defcustom split-window-preferred-direction 'vertical
    Nicolas> +  "The first direction tried when Emacs need to split a window.

'needs'

    Nicolas> +This variable controls in which order `split-window-sensibly' will try to
    Nicolas> +split the window.  That order specially matters when both dimension of

'dimensions'

    Nicolas> +the frame are long enough to be split according to
    Nicolas> +`split-width-threshold' and `split-height-threshold'.  If this is set to
    Nicolas> +`vertical' (the default), `split-window-sensibly' tries to split
    Nicolas> +vertically first and then horizontally.  If set to `horizontal' it does
    Nicolas> +the opposite.  If set to `longest', the first direction tried will
    Nicolas> +depends on the frame shape: in landscape orientation it will be like

either 'depend', or drop the 'will'

    Nicolas> +`horizontal', but in portrait it will be like `vertical'.  Basically,
    Nicolas> +the longest of the two dimension is split first.
    Nicolas> +
    Nicolas> +If both `split-width-threshold' and `split-height-threshold' cannot be
    Nicolas> +satisfied, it will fallback to split vertically.
    Nicolas> +
    Nicolas> +See `split-window-preferred-function' for more control on the splitting

'control of'

    Nicolas> +strategy."
    Nicolas> +  :type '(radio
    Nicolas> +          (const :tag "Try to split vertically first"
    Nicolas> +                 vertical)
    Nicolas> +          (const :tag "Try to split horizontally first"
    Nicolas> +                 horizontal)
    Nicolas> +          (const :tag "Try to split along the longest edge first"
    Nicolas> +                 longest))
    Nicolas> +  :version "31.1"
    Nicolas> +  :group 'windows)
    Nicolas> +
    Nicolas> +(defun window--try-vertical-split (window)
    Nicolas> +  "Helper function for `split-window-sensibly'"
    Nicolas> +  (when (window-splittable-p window)
    Nicolas> +    (with-selected-window window
    Nicolas> +      (split-window-below))))
    Nicolas> +
    Nicolas> +(defun window--try-horizontal-split (window)
    Nicolas> +  "Helper function for `split-window-sensibly'"
    Nicolas> +  (when (window-splittable-p window t)
    Nicolas> +    (with-selected-window window
    Nicolas> +      (split-window-right))))
    Nicolas> +
    Nicolas>  (defun split-window-sensibly (&optional window)
    Nicolas>    "Split WINDOW in a way suitable for `display-buffer'.
    Nicolas> -WINDOW defaults to the currently selected window.
    Nicolas> -If `split-height-threshold' specifies an integer, WINDOW is at
    Nicolas> -least `split-height-threshold' lines tall and can be split
    Nicolas> -vertically, split WINDOW into two windows one above the other and
    Nicolas> -return the lower window.  Otherwise, if `split-width-threshold'
    Nicolas> -specifies an integer, WINDOW is at least `split-width-threshold'
    Nicolas> -columns wide and can be split horizontally, split WINDOW into two
    Nicolas> -windows side by side and return the window on the right.  If this
    Nicolas> -can't be done either and WINDOW is the only window on its frame,
    Nicolas> -try to split WINDOW vertically disregarding any value specified
    Nicolas> -by `split-height-threshold'.  If that succeeds, return the lower
    Nicolas> -window.  Return nil otherwise.
    Nicolas> +The variable `split-window-preferred-direction' prescribes an order of
    Nicolas> +directions in which Emacs should try to split WINDOW.  If that order
    Nicolas> +mandates to start with a vertical split and `split-height-threshold'

'starting' instead of 'to start', plus 'split,'

    Nicolas> +specifies an integer that is at least as large a WINDOW's height, split
    Nicolas> +WINDOW into two windows one below the other and return the lower one.
    Nicolas> +If that order mandates to start with a horizontal split and

same here

    Nicolas> +`split-width-threshold' specifies an integer that is at least as large
    Nicolas> +as WINDOW's width, split WINDOW into two windows side by side and return
    Nicolas> +the one on the right.
    Nicolas> +
    Nicolas> +In either case, if the first attempt to split WINDOW fails, try to split
    Nicolas> +the window in the other direction in the same manner as described above.
    Nicolas> +If that attempts fail too and WINDOW is the only window on its frame,

'attempt', plus 'too,'

    Nicolas> +try splitting WINDOW into two windows one below the other disregarding

'windows, one below the other,'

    Nicolas> +the value of `split-height-threshold' and return the window on the
    Nicolas> +bottom.
 
    Nicolas>  By default `display-buffer' routines call this function to split
    Nicolas>  the largest or least recently used window.  To change the default
    Nicolas> @@ -7380,14 +7424,14 @@ split-window-sensibly
    Nicolas>  know how `split-window-sensibly' determines whether WINDOW can be
    Nicolas>  split."
    Nicolas>    (let ((window (or window (selected-window))))
    Nicolas> -    (or (and (window-splittable-p window)
    Nicolas> -	     ;; Split window vertically.
    Nicolas> -	     (with-selected-window window
    Nicolas> -	       (split-window-below)))
    Nicolas> -	(and (window-splittable-p window t)
    Nicolas> -	     ;; Split window horizontally.
    Nicolas> -	     (with-selected-window window
    Nicolas> -	       (split-window-right)))
    Nicolas> +    (or (if (or
    Nicolas> +             (eql split-window-preferred-direction 'horizontal)
    Nicolas> +             (and (eql split-window-preferred-direction 'longest)
    Nicolas> +                  (> (frame-width) (frame-height))))
    Nicolas> +            (or (window--try-horizontal-split window)
    Nicolas> +                (window--try-vertical-split window))
    Nicolas> +          (or (window--try-vertical-split window)
    Nicolas> +              (window--try-horizontal-split window)))
    Nicolas>  	(and
    Nicolas>           ;; If WINDOW is the only usable window on its frame (it is
    Nicolas>           ;; the only one or, not being the only one, all the other
    Nicolas> @@ -7405,10 +7449,8 @@ split-window-sensibly
    Nicolas>                                  frame nil 'nomini)
    Nicolas>                t)))
    Nicolas>  	 (not (window-minibuffer-p window))
    Nicolas> -	 (let ((split-height-threshold 0))
    Nicolas> -	   (when (window-splittable-p window)
    Nicolas> -	     (with-selected-window window
    Nicolas> -	       (split-window-below))))))))
    Nicolas> +         (let ((split-height-threshold 0))
    Nicolas> +           (window--try-vertical-split window))))))
 
    Nicolas>  (defun window--try-to-split-window (window &optional alist)
    Nicolas>    "Try to split WINDOW.
    Nicolas> -- 
    Nicolas> 2.47.1



Robert
-- 



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: Prefer to split along the longest edge
  2024-12-20 15:05                                   ` Robert Pluim
@ 2024-12-20 20:25                                     ` Stephen Berman
  0 siblings, 0 replies; 58+ messages in thread
From: Stephen Berman @ 2024-12-20 20:25 UTC (permalink / raw)
  To: Robert Pluim
  Cc: Nicolas Desprès, martin rudalics, Eli Zaretskii, juri,
	emacs-devel

On Fri, 20 Dec 2024 16:05:42 +0100 Robert Pluim <rpluim@gmail.com> wrote:

> Minor nits below

You missed on nit:

>>>>>> On Fri, 20 Dec 2024 15:43:51 +0100, Nicolas Desprès
> <nicolas.despres@gmail.com> said:
>
>     Nicolas> +In either case, if the first attempt to split WINDOW fails, try
>     Nicolas> to split
>     Nicolas> +the window in the other direction in the same manner as
>     Nicolas> described above.
>     Nicolas> +If that attempts fail too and WINDOW is the only window on its frame,
>
> 'attempt', plus 'too,'

fail => fails

Steve Berman



^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2024-12-20 20:25 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-14 10:05 Prefer to split along the longest edge Nicolas Desprès
2024-12-14 11:30 ` Eli Zaretskii
2024-12-14 11:45   ` Nicolas Desprès
2024-12-14 12:34     ` Eli Zaretskii
2024-12-14 14:06       ` Nicolas Desprès
2024-12-14 14:55         ` Eli Zaretskii
2024-12-14 15:41           ` Nicolas Desprès
2024-12-14 17:16   ` martin rudalics
2024-12-14 17:33     ` Eli Zaretskii
2024-12-14 17:36     ` Eli Zaretskii
2024-12-14 18:35 ` Juri Linkov
2024-12-14 20:10   ` Nicolas Desprès
2024-12-15  7:34     ` Juri Linkov
2024-12-15  9:29       ` Nicolas Desprès
2024-12-16  7:55         ` Juri Linkov
2024-12-16 11:56           ` Nicolas Desprès
2024-12-16 17:14             ` Eli Zaretskii
2024-12-16 17:44               ` Juri Linkov
2024-12-16 19:07                 ` Eli Zaretskii
2024-12-16 19:14                   ` Juri Linkov
2024-12-16 19:53                     ` Eli Zaretskii
2024-12-17  6:12                       ` Nicolas Desprès
2024-12-17  7:40                         ` Juri Linkov
2024-12-17  8:35                           ` Nicolas Desprès
2024-12-17  9:02                             ` martin rudalics
2024-12-17  9:09                               ` Nicolas Desprès
2024-12-17 13:34                               ` Eli Zaretskii
2024-12-18 10:05                                 ` martin rudalics
2024-12-18 14:12                                   ` Eli Zaretskii
2024-12-18 16:24                                     ` martin rudalics
2024-12-18 16:55                                       ` Eli Zaretskii
2024-12-18 17:41                                         ` martin rudalics
2024-12-18 18:41                                           ` Eli Zaretskii
2024-12-18 19:13                                             ` martin rudalics
2024-12-19  7:06                                           ` Juri Linkov
2024-12-18 17:25                                       ` Juri Linkov
2024-12-17  6:06               ` Nicolas Desprès
2024-12-17 12:52                 ` Eli Zaretskii
2024-12-17 12:59                 ` Eli Zaretskii
2024-12-17 13:12                   ` Robert Pluim
2024-12-18 21:08                     ` Nicolas Desprès
2024-12-19  6:39                       ` Eli Zaretskii
2024-12-19  8:52                         ` martin rudalics
2024-12-19  9:21                           ` Eli Zaretskii
2024-12-19 16:20                             ` Nicolas Desprès
2024-12-20  9:03                               ` martin rudalics
2024-12-20 14:43                                 ` Nicolas Desprès
2024-12-20 15:05                                   ` Robert Pluim
2024-12-20 20:25                                     ` Stephen Berman
2024-12-16 17:32             ` Juri Linkov
2024-12-17  9:01               ` martin rudalics
2024-12-17 13:32                 ` Eli Zaretskii
2024-12-17  1:51             ` Liu Hui
2024-12-17  7:43               ` Juri Linkov
2024-12-17  8:27                 ` Nicolas Desprès
2024-12-17  8:26               ` Nicolas Desprès
2024-12-16 17:15           ` [External] : " Drew Adams
2024-12-17  8:39             ` Nicolas Desprès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).