From: "Nicolas Desprès" <nicolas.despres@gmail.com>
To: Robert Pluim <rpluim@gmail.com>
Cc: Eli Zaretskii <eliz@gnu.org>, juri@linkov.net, emacs-devel@gnu.org
Subject: Re: Prefer to split along the longest edge
Date: Wed, 18 Dec 2024 22:08:58 +0100 [thread overview]
Message-ID: <CAPqtr1LX6OPi+jY+ufL=iBei824qUr_-X=uwniTsawy-0zL5zg@mail.gmail.com> (raw)
In-Reply-To: <874j324fni.fsf@gmail.com>
[-- 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
next prev parent reply other threads:[~2024-12-18 21:08 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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-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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAPqtr1LX6OPi+jY+ufL=iBei824qUr_-X=uwniTsawy-0zL5zg@mail.gmail.com' \
--to=nicolas.despres@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=juri@linkov.net \
--cc=rpluim@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).