Subject: bug#20189: 25.0.50; Feature request: Alternative split-window-sensibly functions

From: Eli Zaretskii <[email-masked]>
Date: Wed, 25 Mar 2015 19:25:59 +0200

> From: Tassilo Horn <[email-masked]>
> Cc: [email-masked]
> Date: Wed, 25 Mar 2015 08:00:34 +0100
> 
> > 'split-window-sensibly' is documented to "split WINDOW in a way
> > suitable for 'display-buffer'".  Are you talking about the same use
> > case, i.e. are you talking about some command that invoked
> > 'display-buffer'?  Or are you talking about some different use case?
>
> Yes, I'm talking about display-buffer.  This is a test case:
> 
> --8<---------------cut here---------------start------------->8---
> (defun test-display-buffer ()
>   (interactive)
>   (display-buffer (get-buffer-create "ONE"))
>   (display-buffer (get-buffer-create "TWO")))
> --8<---------------cut here---------------end--------------->8---
>
> If your screen is as large that your emacs frame/window is taller than
> `split-height-threshold' (80 lines), then the first split will be a
> vertical one.  E.g., do emacs -Q, eval the above function in *scratch*,
> and then M-x it.  You end up with 3 windows: one wide window on top
> showing *scratch*, the lower half contains two side-by-side windows.

I don't see how we can judge "sensibility" of what display-buffer does
without knowing which command(s) invoked it.  Users don't invoke
display-buffer directly, and the commands that do differ widely in the
amount and dimensions of text they display and subsequent use of the
displayed stuff.

As a simple example, a command that calls display-buffer could prepare
text that is best shown in a 100x10 window (think about some columnar
display), in which case it doesn't make sense to prefer 80-column wide
side-by-side windows that you seem to prefer.

> That's not too sensible when one assumes that most buffers are at most
> 80 columns wide but have many lines.  If the first split was a
> horizontal split, you'd have more buffer contents on your screen.

As you see from your own description, the "sensibility" depends quite
a lot on the preferred dimensions and the nature of the text to be
displayed.  I'm not at all sure we can find a "one size fits all"
strategy, at least not without examining the text itself, something
split-window-sensibly doesn't do, AFAIK.

> > This is not clear from your description, since it lacks the context in
> > which your needs are different.
> 
> The context is having a big enough screen where both a vertical and a
> horizontal split would be possible initially.

No, I meant the commands that invoked display-buffer -- they are the
most important context for "sensibility" of the split.

> > If we are willing to produce long-lived splits automatically, then the
> > 2 thresholds are IMO not enough for "sensible" behavior of any kind;
> > what is missing is 2 more parameters that provide the desired (as
> > opposed to minimal) height and width of a window.  These parameters
> > are implicitly present in your description, but you never explicitly
> > name them.
> 
> Yeah, exactly.  I personally defined them to be
> 
>   (/ split-{width,height}-threshold 2)
> 
> although I think the preferred height is usually "as high as possible"
> or "exactly as high to fit the buffer contents".

Once again, I think this depends on the text to be displayed.  If we
want to have a split-window function that does not consult the text to
be displayed, the only way to go is IMO to parameterize the problem
space, and make the function accept these parameters and DTRT for each
combination.

> >> (1) That version would prefer horizontal splits as above.
> >> 
> >> (2) I want either horizontal or vertical splitting but not both, i.e.,
> >>     the layout should always be Nx1 or 1xN windows.
> >> 
> >> (3) A window may get split horizontally not if it's wider/taller than
> >>     `split-width-threshold'/`split-height-threshold' but instead when
> >>     its width/height *after* the split followed by `balance-windows'
> >>     is larger than or equal to (/ split-{width,height}-threshold 2).
> >> 
> >> (4) The single-window exception of `split-height-threshold' still
> >>     holds, so in frames with just one window a vertical split is
> >>     performed even though that window is actually too small according
> >>     to the rules above.
> >
> > Maybe I misunderstand, but doesn't (2) contradict (1)?
> 
> No.  (1) is meant for the initial split case, i.e., when there's just
> one window.  If that's splittable both vertically and horizontally, I
> prefer a horizontal split.

That's a far cry from what you wrote in (1).

> > And why is (1) a good idea anyway?  Why not have a more optimal split,
> > whereby (for example) the larger dimension is preferred?
> 
> IMO, a vertial split which produces windows which are much larger than
> 80 columns is useless to me because usually buffer contents are at most
> 80 columns wide so you have tons of empty space next to the contents.

If the horizontal dimension of the initial widow to be split is larger
than the vertical one, then the rule I propose will always do what you
want for the first couple of splits.  After that, I see no reason to
prefer splitting, say, a 120x80 window into 2 60x80 windows instead of
into 2 120x40 windows.

> Ok, there might be a situation where my single window contains a buffer
> with very wide contents.  Let's say in that case, the optimal window
> split function would determine that a vertical split is better.  With my
> usage habits, I'd still say its wrong because chances are almost certain
> that I'll switch buffers sooner or later, and the buffer being switched
> to is most probably at most 80 columns wide again.

You do see how this line of reasoning is deeply specific to your
habits, don't you?  Which means there cannot be on strategy that fits
all of us.

> There might be some "dynamic" window adaption manager which computes an
> optimal window configuration after every `set-window-buffer'.  But I'm
> not sure if that is feasible and provides a good user experience.

We need to define the strategy for such an optimization first, then we
can reason about whether users will like it, and how to customize it
to user needs.

> > As for (3), such a criterion is IMO a good idea only if we actually
> > balance the windows as part of the split.  Otherwise, you will have
> > adverse effects when the window to be split is very narrow, but some
> > of its peers are wide.
> 
> Yes, in my last mail I've hacked a split function which does exactly
> that.

But actually balancing windows would be a bad idea for some users of
display-buffer, at least in my eyes.  A typical example is the
*Compilation* buffer and its ilk: I generally want them to keep their
small size, not to steal screen estate from my editing windows.
Similarly with *Help* etc.

> >> When I use a frame of size 80x82 instead, I'd end up with 2 vertical
> >> windows
> >
> > And this is good because?...
> 
> Exactly because of the reason you state below.  The frame/window isn't
> wide enough to have 2 side-by-side windows with at least 80 columns
> each, so that's the case where I favor vertical over horizontal
> splitting.

That's because you think about displaying some program text there, or
similar.  But what if the text to be displayed there is much more
narrow, or even adapts itself dynamically to the window dimensions,
like the *Completions* buffer?