emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Prefer to split along the longest edge


From: Robert Pluim
Subject: Re: Prefer to split along the longest edge
Date: Fri, 20 Dec 2024 16:05:42 +0100

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
-- 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]