From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Robert Pluim Newsgroups: gmane.emacs.devel Subject: Re: Prefer to split along the longest edge Date: Fri, 20 Dec 2024 16:05:42 +0100 Message-ID: <874j2yv1h5.fsf@gmail.com> References: <87r06a3yfg.fsf@mail.linkov.net> <87zfkx2ydr.fsf@mail.linkov.net> <8734io2hac.fsf@mail.linkov.net> <86pllrpn2p.fsf@gnu.org> <86o71ao47d.fsf@gnu.org> <874j324fni.fsf@gmail.com> <86ttb0kwgt.fsf@gnu.org> <2aa16454-560c-4d3b-b3eb-e1b780d1b8d6@gmx.at> <86h670koyu.fsf@gnu.org> <4e108ba9-728e-429c-b366-449388497a1e@gmx.at> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="16170"; mail-complaints-to="usenet@ciao.gmane.io" Cc: martin rudalics , Eli Zaretskii , juri@linkov.net, emacs-devel@gnu.org To: Nicolas =?utf-8?Q?Despr=C3=A8s?= Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Dec 20 16:06:41 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tOeaP-00046Y-Ay for ged-emacs-devel@m.gmane-mx.org; Fri, 20 Dec 2024 16:06:41 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tOeZi-0003Ym-BW; Fri, 20 Dec 2024 10:05:58 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tOeZe-0003YP-SS for emacs-devel@gnu.org; Fri, 20 Dec 2024 10:05:56 -0500 Original-Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tOeZa-0008My-MW; Fri, 20 Dec 2024 10:05:54 -0500 Original-Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-4363ae65100so21805195e9.0; Fri, 20 Dec 2024 07:05:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1734707144; x=1735311944; darn=gnu.org; h=content-transfer-encoding:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:from:to:cc:subject:date:message-id :reply-to; bh=kLHMyIqW2MjFEVOeClueLibUMTFULRAeFLaOpfpczks=; b=QcbfJG0exLqgrjPuMJJFcl477Zm6cdSXs/Ofj5Hd7s7x2+u13Xbpe4HvMQvjXzFWfL xC4gH+qplI1Ya+B3kWlBHdk8rE4dwJDsy5hog35yvES46FdTFjhNJmoXGUa7MkRCYfrt X8JEAPwMQgo4tNbrAVEuEzbVcNlGbhNA7Qqplwl7Hp4dzAgreEjYUapS4ISRN2p1oa2F 698MruDoQFcLCqIg/9byVV5lpyt2wXpoljvOGiO8jMUyqKi0k9/f1PMaK2Hiz2M/wzqb Y/gEt5mypqI7EEZIDPEa1mRf4Mpg4FFkpB2ecszgCSd9ylY+tyaeUOxxFoe4pwBKjY1w Fc+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1734707144; x=1735311944; h=content-transfer-encoding:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kLHMyIqW2MjFEVOeClueLibUMTFULRAeFLaOpfpczks=; b=YvAGLnE3pFr8bx4zVhHFOTr8jPtsAPaP+O4DcOmLwB3ilVCVg3Al8DEq9wETrKHFCB R497pxncy7if87m/ae4Fudc6CBfClVMtrdybP1H0A1ZFv+eDKJvDKO4WD1Xd5gi+jZim r+YwWt/dbKvC/QVZaqrvZ8WbOfITK59iS2C4aaWXTO1+LtWJz4QloKiG6NKtLy9rC+2H Gfw61QaV4TldntGwGSImy/GZWTnmZSBkkmrBc6WuqnIAuCHKruHCfTXCsbGTrYGBB8ye wOhJq5JLNwCIsVzgQl50anoVa7gGprMpxqTlGrZlxaRNFbuIR/BupEUz0ol3svnriZxT 3Yrg== X-Forwarded-Encrypted: i=1; AJvYcCX+9v98MlG1FyTZAbcs+75fFhk5ILfHnBGkENEoa3V3SOgzwJdZanSv+vukxkgfzErPdRAGmT5RaZ1su8Q=@gnu.org, AJvYcCXQLfEh0cKyWEylkP6a569JV4MZ9MaxG0YxGZr8l4txNdqIIoxtkp7kaNnIOO/9TDypQKKO@gnu.org X-Gm-Message-State: AOJu0YxlU+GEGxngq222/QfyHXav5JK9R+yw8yPNSRrmuIcfT1qNgONQ xd0Yy8ImRyj0ROw7PejL5tKp6uwf5/2l1MgjZV7HHfEhOPktEdj5fVhwzA== X-Gm-Gg: ASbGncs/zVP0dSIpYnrgmLPSb/hLtN0w1UMgOaco+PAiUHOrLbKXQnQC+QIJzzwrvHX 4bezadTKfk6M+JCKGfQ2arijNlVZwU5v2VyWaJ/OlEhaSvKuo47i2O5p4hp5yNLMBcudTdYWsOr KtFks7/LKrPr+ddeFbs0JjKmd6gbj27CxekpZXev6yoL24rTOslfd2KnuGBv5Pq0ezr/J82xRqF 377mt4u+aFe8pSa+b5MlopuVUgQ9NcQ22XGY++Dn2Ov X-Google-Smtp-Source: AGHT+IHbRKXxGh04I44t0VL+HdQ2W4freE4OnjSJUNCC1qPC+x9dmyhPdYtofxEgcnVbF9n9vG4pJA== X-Received: by 2002:a05:600c:4f95:b0:428:d31:ef25 with SMTP id 5b1f17b1804b1-4366854c111mr32445385e9.12.1734707143492; Fri, 20 Dec 2024 07:05:43 -0800 (PST) Original-Received: from rltb ([2a01:e0a:3f3:fb51:83dc:73ec:49eb:d7b8]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4366112e780sm48053325e9.0.2024.12.20.07.05.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Dec 2024 07:05:42 -0800 (PST) In-Reply-To: ("Nicolas =?utf-8?Q?Despr=C3=A8s=22's?= message of "Fri, 20 Dec 2024 15:43:51 +0100") Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=rpluim@gmail.com; helo=mail-wm1-x32b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:326801 Archived-At: Minor nits below >>>>> On Fri, 20 Dec 2024 15:43:51 +0100, Nicolas Despr=C3=A8s said: Nicolas> Thanks for your review. Nicolas> -Nico Nicolas> From 0f3576f9ce23b2e6608b1718301a621c9f153202 Mon Sep 17 00:00= :00 2001 Nicolas> From: Nicolas Despres Nicolas> Date: Fri, 20 Dec 2024 15:41:38 +0100 Nicolas> Subject: [PATCH] Prioritize split along the longest edge by de= fault. Nicolas> Currently, `split-window-sensibly' prefer to try to split vert= ically '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-thresho= ld' 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 =20 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 in= teger Nicolas> @@ -519,7 +520,9 @@ Window Choice Nicolas> @code{split-width-threshold} is smaller than the window's wid= th, 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 on= ly 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-direc= tion}. =20 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. U= se '(category . comint)' instead. Nicolas> Another user option 'display-tex-shell-buffer-action' has bee= n removed too Nicolas> for which you can use '(category . tex-shell)'. =20 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 fram= e is in Nicolas> +landscape shape for instance, Emacs could split horizontally = before to Nicolas> +split vertically. The default setting preserves Emacs histor= ical 'before splitting' instead of 'before to split' Nicolas> +behavior to try to split vertically first. Nicolas> + Nicolas> ** Frames =20 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)))))))))) =20 Nicolas> +(defcustom split-window-preferred-direction 'vertical Nicolas> + "The first direction tried when Emacs need to split a windo= w. 'needs' Nicolas> +This variable controls in which order `split-window-sensibly'= will try to Nicolas> +split the window. That order specially matters when both dim= ension of 'dimensions' Nicolas> +the frame are long enough to be split according to Nicolas> +`split-width-threshold' and `split-height-threshold'. If thi= s is set to Nicolas> +`vertical' (the default), `split-window-sensibly' tries to sp= lit Nicolas> +vertically first and then horizontally. If set to `horizonta= l' 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'. Ba= sically, 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 fi= rst" 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-threshol= d' Nicolas> -specifies an integer, WINDOW is at least `split-width-thresho= ld' 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 fra= me, Nicolas> -try to split WINDOW vertically disregarding any value specifi= ed Nicolas> -by `split-height-threshold'. If that succeeds, return the lo= wer 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 tha= t order Nicolas> +mandates to start with a vertical split and `split-height-thr= eshold' 'starting' instead of 'to start', plus 'split,' Nicolas> +specifies an integer that is at least as large a WINDOW's hei= ght, split Nicolas> +WINDOW into two windows one below the other and return the lo= wer 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, t= ry to split Nicolas> +the window in the other direction in the same manner as descr= ibed above. Nicolas> +If that attempts fail too and WINDOW is the only window on it= s frame, 'attempt', plus 'too,' Nicolas> +try splitting WINDOW into two windows one below the other dis= regarding 'windows, one below the other,' Nicolas> +the value of `split-height-threshold' and return the window o= n the Nicolas> +bottom. =20 Nicolas> By default `display-buffer' routines call this function to sp= lit Nicolas> the largest or least recently used window. To change the def= ault Nicolas> @@ -7380,14 +7424,14 @@ split-window-sensibly Nicolas> know how `split-window-sensibly' determines whether WINDOW ca= n 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 'horizonta= l) Nicolas> + (and (eql split-window-preferred-direction 'long= est) 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)))))) =20 Nicolas> (defun window--try-to-split-window (window &optional alist) Nicolas> "Try to split WINDOW. Nicolas> --=20 Nicolas> 2.47.1 Robert --=20