bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Emacs - Bugs mailing list

>> One case in which this behavior is not desirable is when completion
>> candidates are displayed with an overlay at the end of the buffer. When
>> this overlay is taller than max-mini-window-height, the prompt and the
>> user input so far disappear.  A simple example: M-: (setq
>> max-mini-window-height 1), M-x icomplete-mode, M-x a.
>
> You should update your recipe, because Eli's patch takes care of this
> case already.
>

Indeed, but this recipe is what exists in Emacs 27.1 and what most people
can try immediately.  The "problem" with Eli's patch is that it takes care
of 95% of the cases, and that the remaining 5% are more difficult to see,
yet are there.

>
> I'm not completely sure which case(s) you're thinking of now that Eli's
> patch handles the most common case we've seen so far.  But maybe the
> problem shows up when we have a minibuffer content that spans 2 lines,
> in which case the redisplay will choose to show the last line (assuming
> point is in the second line) plus icomplete's overlay rather whereas you
> presumably would want to see both lines from the minibuffer (and hence
> one line less from icomplete's overlay)?
>

Yes.  See the recipe in my previous mail.  If works with N lines, with N >
1.

>
> So a recipe could look something like:
>
>    src/emacs -Q --eval '(setq max-mini-window-height 2)' -f icomplete-mode
>    C-x C-f lisp/progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../
>
> where we see the whole of icomplete's overlay rather than seeing the
> whole of the minibuffer's actual content.
>

The problem is that such a recipe would only work with a not-too-wide
Emacs frame and a not-too-small default font.  For example, on my
computer, it does not demonstrate the problem.

>
> In general both are perfectly valid choices and which one is best
> depends on what is the intention behind the particular overlay and its
> relation to the minibuffer's content, so indeed the redisplay would need
> additional information in order to decide which behavior to choose.
>

I agree with you, which is why I think that ATM the best thing to do is
just to make such a choice possible.

>
>> The attached patch makes it possible to (selectively) choose to display
>> the _first_ lines of the minibuffer instead of its _last_ lines (which
>> is and remains the default behavior).
>
> Currently, the redisplay code focuses on making sure point is displayed.
> In the resize_mini_widow code we try to accommodate some extra desires,
> mostly in the form of giving more importance either to what's before
> point or what's after it.
>

I don't think this is precise enough, but OTOH it's very hard to precisely
define what happens.  Currently resize_mini_window() sets "start" to
max-mini-window-height lines before the end of the buffer (unless
resize-mini-windows is nil, in which case "start" is set to BOB).  The
redisplay code takes that value; if point is not between start and EOB it
overrides it, otherwise it displays the buffer between start and EOB.

>
>> The attached patch does not change the behavior of Emacs in any way,
>> unless the feature it introduces is used.
>
> I see the following potential problem with it: icomplete will likely
> want to set it globally, but that means it will also affect uses of the
> mini window where icomplete is not used.  Also, potential other users
> may encounter similar difficulties.
>

No, if you look at the patch its value is reset to nil whenever the
minibuffer is entered.  And the example I gave with icomplete is:

(add-hook 'icomplete-minibuffer-setup-hook (lambda () (setq start-display-at-beginning-of-minibuffer t)))

where icomplete-minibuffer-setup-hook is run during minibuffer setup if
(and only if) icomplete is active.  So the behavior with M-: for example
would not be affected.

>
> I don't have a patch to suggest, but I think ideally, I'd want clients
> like icomplete to tell the redisplay either something like "please
> display as much as possible of *this* chunk of text" or maybe "feel free
> not to display all of this overlay, it's not super important".
>

Yes, that's the point.  The patch I proposed tells redisplay "please
display as much as possible of the text between BOB and point", when the
current behavior tells redisplay "please display as much as possible of
the text between point and EOB".  Something more fine-grained would of
course be possible, but I don't think it is a good idea to implement a
feature when there is no clear need for it.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Stefan Monnier
>>    src/emacs -Q --eval '(setq max-mini-window-height 2)' -f icomplete-mode
>>    C-x C-f
>> lisp/progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../progmodes/../
>>
>> where we see the whole of icomplete's overlay rather than seeing the whole
>> of the minibuffer's actual content.
>>
>
> The problem is that such a recipe would only work with a not-too-wide Emacs
> frame and a not-too-small default font.  For example, on my computer, it
> does not demonstrate the problem.

Really?  Despite the `-Q`?  Is it using a proportional font?
How many columns wide is the frame?
Oh, wait, is it because you're running that Emacs session in a tty
rather than in a GUI?

>>> The attached patch does not change the behavior of Emacs in any way,
>>> unless the feature it introduces is used.
>> I see the following potential problem with it: icomplete will likely want
>> to set it globally, but that means it will also affect uses of the mini
>> window where icomplete is not used.  Also, potential other users may
>> encounter similar difficulties.
> No, if you look at the patch its value is reset to nil whenever the
> minibuffer is entered.

That still leaves the non-minibuffer uses of the mini window (i.e. the
echo area).

And of course, that will also result in the use of an incorrect value
when you exit a *nested* minibuffer (unless both minibuffers were using
the same value).

>> I don't have a patch to suggest, but I think ideally, I'd want clients
>> like icomplete to tell the redisplay either something like "please display
>> as much as possible of *this* chunk of text" or maybe "feel free not to
>> display all of this overlay, it's not super important".
>
> Yes, that's the point.  The patch I proposed tells redisplay "please display
> as much as possible of the text between BOB and point", when the current
> behavior tells redisplay "please display as much as possible of the text
> between point and EOB".  Something more fine-grained would of course be
> possible, but I don't think it is a good idea to implement a feature when
> there is no clear need for it.

I think what I was getting at is that this "request" should come from
the minibuffer's text rather than from a variable.


        Stefan




Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Emacs - Bugs mailing list

>
> Really?  Despite the `-Q`?  Is it using a proportional font?
> Oh, wait, is it because you're running that Emacs session in a tty rather than in a GUI?
>

Yes, yes, no, no ;-)

>
> How many columns wide is the frame?
>

167, Sir! ;-)

>> No, if you look at the patch its value is reset to nil whenever the
>> minibuffer is entered.
>
> That still leaves the non-minibuffer uses of the mini window (i.e. the
> echo area).
>
> And of course, that will also result in the use of an incorrect value
> when you exit a *nested* minibuffer (unless both minibuffers were using
> the same value).
>
Thank you very much for the pointers, indeed I completely forgot about
these cases.  See the attached corrected patch, in which they are dealt
with.  I believe start_display_at_beginning_of_minibuffer how has the
value it should have whenever resize_mini_window() is called.

>>> I don't have a patch to suggest, but I think ideally, I'd want clients
>>> like icomplete to tell the redisplay either something like "please
>>> display as much as possible of *this* chunk of text" or maybe "feel
>>> free not to display all of this overlay, it's not super important".
>>
>> Yes, that's the point.  The patch I proposed tells redisplay "please
>> display as much as possible of the text between BOB and point", when
>> the current behavior tells redisplay "please display as much as
>> possible of the text between point and EOB".  Something more
>> fine-grained would of course be possible, but I don't think it is a
>> good idea to implement a feature when there is no clear need for it.
>
> I think what I was getting at is that this "request" should come from
> the minibuffer's text rather than from a variable.
>
If this were possible, it would be even better indeed.  An "importance"
text property, which would inform redisplay (?) of the relative importance
of the parts of the buffer.  But implementing this is several orders of
magnitude harder than implementing my proposal.

start-display-at-beginning-of-minibuffer.patch (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Stefan Monnier
>> Really?  Despite the `-Q`?  Is it using a proportional font?
>> Oh, wait, is it because you're running that Emacs session in a tty rather than in a GUI?
> Yes, yes, no, no ;-)
>> How many columns wide is the frame?
> 167, Sir! ;-)

How? why?


        Stefan




Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Emacs - Bugs mailing list

>>> Really?  Despite the `-Q`?  Is it using a proportional font?
>>> Oh, wait, is it because you're running that Emacs session in a tty rather than in a GUI?
>>
>> Yes, yes, no, no ;-)
>>
>>> How many columns wide is the frame?
>>
>> 167, Sir! ;-)
>
> How? why?
>

Simply because I asked my window manager to always maximize Emacs frames.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Stefan Monnier
> Simply because I asked my window manager to always maximize Emacs frames.

Aha!

Yet another loophole!
Thanks,


        Stefan




Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Emacs - Bugs mailing list

>> Simply because I asked my window manager to always maximize Emacs
>> frames.
>
> Aha!
>
> Yet another loophole!
>

Hmm...  Given the popularity (among a certain kind of users) of tiling
window managers and the popularity (among a much larger kind of users) of
using fullscreen apps, I don't think Emacs can expect to fully control the
size of its frame.  But indeed I see what you mean, ideally emacs -Q
should give a frame of the same size everywhere.  So it could perhaps make
sense to try to do something like:

(set-frame-width nil 80)
(set-frame-height nil 40)

(which works for me) at the end of the initialization process with "-q" or
"-Q".



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Emacs - Bugs mailing list
In reply to this post by Stefan Monnier

To illustrate the need for this feature, I attach four screenshots taken
under the exact same conditions.

- "vanilla.png" is what a user would see without changing any default
(after pressing TAB to display the completion candidates): the prompt,
their input, and completion candidates in a *Completions* buffer above the
minibuffer

- "master-icomplete-vertical-after-tab.png" is what a user would see with
icomplete-mode activated and (setq icomplete-separator "\n") after having
completed the last directory name with a TAB: the prompt and their input
is completely hidden

- "master-icomplete-vertical-after-tab-tab.png" is what a user would see
after pressing TAB a second time; note the "ng/" before point, which was
hidden after pressing TAB for the first time and is now visible again

- "patched-icomplete-vertical.png" is what a user would see with the
proposed patch

vanilla.png (67K) Download Attachment
master-icomplete-vertical-after-tab.png (38K) Download Attachment
master-icomplete-vertical-after-tab-tab.png (83K) Download Attachment
patched-icomplete-vertical.png (47K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Eli Zaretskii
In reply to this post by Emacs - Bugs mailing list
> Cc: [hidden email]
> Date: Wed, 23 Sep 2020 19:46:18 +0000
> From: Gregory Heytings via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <[hidden email]>
>
> >> The attached patch does not change the behavior of Emacs in any way,
> >> unless the feature it introduces is used.
> >
> > I see the following potential problem with it: icomplete will likely
> > want to set it globally, but that means it will also affect uses of the
> > mini window where icomplete is not used.  Also, potential other users
> > may encounter similar difficulties.
>
> No, if you look at the patch its value is reset to nil whenever the
> minibuffer is entered.  And the example I gave with icomplete is:
>
> (add-hook 'icomplete-minibuffer-setup-hook (lambda () (setq start-display-at-beginning-of-minibuffer t)))
>
> where icomplete-minibuffer-setup-hook is run during minibuffer setup if
> (and only if) icomplete is active.  So the behavior with M-: for example
> would not be affected.

There are more callers of resize_mini_widow than just those.  It is
not safe to assume that this can be handled only inside read_minibuf.

So I agree with Stefan that the text inserted into the minibuffer
should itself indicate to the display engine that it wants to be
displayed starting at BOB.  That way we don't have to worry about
inadvertently affecting other users of the mini-window.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Eli Zaretskii
In reply to this post by Emacs - Bugs mailing list
> Cc: [hidden email]
> Date: Wed, 23 Sep 2020 22:47:05 +0000
> From: Gregory Heytings via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <[hidden email]>
>
> > I think what I was getting at is that this "request" should come from
> > the minibuffer's text rather than from a variable.
>
> If this were possible, it would be even better indeed.  An "importance"
> text property, which would inform redisplay (?) of the relative importance
> of the parts of the buffer.  But implementing this is several orders of
> magnitude harder than implementing my proposal.

Actually testing for a certain text property in resize_mini_window
should be quite simple.  We do similar things elsewhere in the display
code.  So I see no reason to avoid that.  It would definitely resolve
any issues with inadvertently affecting unrelated users of the
mini-window.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Emacs - Bugs mailing list
In reply to this post by Eli Zaretskii

>
> There are more callers of resize_mini_widow than just those.  It is not
> safe to assume that this can be handled only inside read_minibuf.
>

Please have a look at my corrected patch.  It handles this inside
read_minibuf() *and* read_minibuf_unwind(), which AFAICS should make the
change to start_display_at_beginning_of_minibuffer last only for the time
it should last.  If that's not the case, could you please provide a
recipe?  I'm willing to improve the patch a second time if it's necessary.

>
> So I agree with Stefan that the text inserted into the minibuffer should
> itself indicate to the display engine that it wants to be displayed
> starting at BOB.  That way we don't have to worry about inadvertently
> affecting other users of the mini-window.
>

That's a possibility indeed, and I agree that it would be even better, but
as I said this is several orders of magnitude harder to implement, and
unlikely to happen in a near future.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Eli Zaretskii
In reply to this post by Emacs - Bugs mailing list
> Date: Thu, 24 Sep 2020 08:06:37 +0000
> From: Gregory Heytings <[hidden email]>
> cc: [hidden email]
>
> - "master-icomplete-vertical-after-tab.png" is what a user would see with
> icomplete-mode activated and (setq icomplete-separator "\n") after having
> completed the last directory name with a TAB: the prompt and their input
> is completely hidden

Thanks, this subtle issue should now be fixed on master.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Eli Zaretskii
> Date: Thu, 24 Sep 2020 14:52:38 +0000
> From: Gregory Heytings <[hidden email]>
> cc: [hidden email], [hidden email]
>
> >> - "master-icomplete-vertical-after-tab.png" is what a user would see
> >> with icomplete-mode activated and (setq icomplete-separator "\n") after
> >> having completed the last directory name with a TAB: the prompt and
> >> their input is completely hidden
> >
> > Thanks, this subtle issue should now be fixed on master.
>
> It is not, the only difference is that instead of "the prompt and their
> input is completely hidden" one should now write "the prompt and the
> largest part of their input is completely hidden".

I mean the issue with the prompt being hidden after one TAB, but
appear after another TAB.

All the rest is just the consequence of the current policy to show the
last part of the stuff in the mini-window.  (Note that with your
changes, one of the candidates isn't shown in the mini-window.)

There might be a misunderstanding here: I'm not claiming that the
changes I made yesterday and today are supposed to produce the same
effect as your proposed patch.  I'm just making the display with
overlay-string behave (as much as possible) like display with normal
buffer text, that's all.  Per bug#43519.  I'm not saying that my
changes implement the feature you are asking for here.

> Again, could you please provide a recipe which would demonstrate a problem
> with the technique I propose?

I already explained why your design is problematic.  And so did
Stefan.  So I don't see why a recipe would be needed.

Implementation of such a feature should use text and/or overlay
properties to communicate the intent to the display code.  That would
be much cleaner and safer.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Stefan Monnier
In reply to this post by Emacs - Bugs mailing list
>>> Simply because I asked my window manager to always maximize Emacs frames.
>> Aha!
>> Yet another loophole!
> Hmm...  Given the popularity (among a certain kind of users) of tiling
> window managers and the popularity (among a much larger kind of users) of
> using fullscreen apps, I don't think Emacs can expect to fully control the
> size of its frame.  But indeed I see what you mean, ideally emacs -Q should
> give a frame of the same size everywhere.  So it could perhaps make sense to
> try to do something like:
>
> (set-frame-width nil 80)
> (set-frame-height nil 40)
>
> (which works for me) at the end of the initialization process with "-q" or
>  "-Q".

I definitely wouldn't want that for `-q`.

It might make sense in this case for `-Q`, but I'm not sure it's a good
tradeoff since we also want `emacs -Q` to mean something like "run with
no special configuration".

So maybe a better option is for the recipe to specify the frame's width.


        Stefan




Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Stefan Monnier
In reply to this post by Eli Zaretskii
> So I agree with Stefan that the text inserted into the minibuffer
> should itself indicate to the display engine that it wants to be
> displayed starting at BOB.  That way we don't have to worry about
> inadvertently affecting other users of the mini-window.

It might be difficult/inconvenient to have the info directly in the
text, tho.  Having it in a variable is not great (one of the
problems with it is that it depends on things like point so it's really
more "per-window" whereas variables are "per-buffer"), tho for the case
of minibuffers at least those buffers are normally never shown in more
than one window.

How 'bout using a window-parameter whose value should be an overlay
indicating the "area of focus", and then only obey this parameter if:
- the overlay is in the buffer that's being displayed.
- and window-point is lies within this overlay.

One more thing: there's a good argument to make that icomplete-vertical
should list the completions *above* the minibuffer's prompt rather than
below (so as not to affect the positions of the minibuffer's prompt so
much).  But in that case, the part of the overlay's after/before string
(when too long) which should be truncated (when the mini-window is too
small) is the beginning, whereas IIUC the current redisplay is unable to
display "the end" of an overlay's after/before string unless it also
shows its beginning.


        Stefan




Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Eli Zaretskii
Ping!

> Date: Thu, 24 Sep 2020 19:54:36 +0300
> From: Eli Zaretskii <[hidden email]>
> Cc: [hidden email], [hidden email]
>
> > From: Stefan Monnier <[hidden email]>
> > Cc: Gregory Heytings <[hidden email]>,  [hidden email]
> > Date: Thu, 24 Sep 2020 12:40:59 -0400
> >
> > > So I agree with Stefan that the text inserted into the minibuffer
> > > should itself indicate to the display engine that it wants to be
> > > displayed starting at BOB.  That way we don't have to worry about
> > > inadvertently affecting other users of the mini-window.
> >
> > It might be difficult/inconvenient to have the info directly in the
> > text, tho.
>
> I don't think I see why it would be difficult/inconvenient.  Can you
> explain?
>
> > How 'bout using a window-parameter whose value should be an overlay
> > indicating the "area of focus", and then only obey this parameter if:
> > - the overlay is in the buffer that's being displayed.
> > - and window-point is lies within this overlay.
>
> This sounds like the same idea of a text property, only with an
> overlay and a more complicated test for applicability.  When I said
> "text property", I meant both text and overlay property, so if you
> think your proposal above is less difficult/inconvenient, then using
> just an overlay would be even simpler, no?  Or what am I missing?
>
> > One more thing: there's a good argument to make that icomplete-vertical
> > should list the completions *above* the minibuffer's prompt rather than
> > below (so as not to affect the positions of the minibuffer's prompt so
> > much).  But in that case, the part of the overlay's after/before string
> > (when too long) which should be truncated (when the mini-window is too
> > small) is the beginning, whereas IIUC the current redisplay is unable to
> > display "the end" of an overlay's after/before string unless it also
> > shows its beginning.
>
> Yes, we cannot start a window's display in the middle of an overlay
> string.
>
> In general, display and overlay strings were not intended for 75%
> (maybe more) of the uses they get nowadays, and it shows.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Eli Zaretskii
> From: Stefan Monnier <[hidden email]>
> Cc: [hidden email],  [hidden email]
> Date: Sun, 27 Sep 2020 17:52:21 -0400
>
> >> This sounds like the same idea of a text property, only with an
> >> overlay and a more complicated test for applicability.  When I said
> >> "text property", I meant both text and overlay property, so if you
> >> think your proposal above is less difficult/inconvenient, then using
> >> just an overlay would be even simpler, no?  Or what am I missing?
>
> My motivation was to solve the issue of finding the relevant overlay.
> But yes, we could also just try and find "the overlay that covers point
> and which has a non-nil `scroll-focus` property".  We'll just have to be
> careful to properly handle the case where point is exactly at
> `overlay-start` or `overlay-end`.

I actually thought about putting the text property or overlay on the
first character of the text inserted into the minibuffer, something
that can be done in a minibuffer-setup-hook.  This way, it will be
easy to find.  Of course, having that on any other part of the text
will not make the job much harder, either.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Stefan Monnier
> I actually thought about putting the text property or overlay on the
> first character of the text inserted into the minibuffer,

I don't understand what data you intend to put this way.
The overlay I proposed carries fundamentally 2 pieces of info: the
beginning position and the end position of the "scroll focus".
So if it needs to cover the first char, you can't use `overlay-start` to
carry the first info.


        Stefan




Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Eli Zaretskii
> From: Stefan Monnier <[hidden email]>
> Cc: [hidden email],  [hidden email]
> Date: Mon, 28 Sep 2020 09:24:34 -0400
>
> > I actually thought about putting the text property or overlay on the
> > first character of the text inserted into the minibuffer,
>
> I don't understand what data you intend to put this way.

Just "start at BOB" indication.

> The overlay I proposed carries fundamentally 2 pieces of info: the
> beginning position and the end position of the "scroll focus".

We could still put this on the first character, and have the value of
the property be a cons cell with these two positions, no?

IOW, the information doesn't have to be on the characters which it
describes.



Reply | Threaded
Open this post in threaded view
|

bug#43572: Feature request: make it possible to choose whether the first lines of the minibuffer should be displayed instead of the last ones

Stefan Monnier
>> The overlay I proposed carries fundamentally 2 pieces of info: the
>> beginning position and the end position of the "scroll focus".
> We could still put this on the first character,

Indeed, that's an option, but it doesn't seem particularly handy.
Not necessarily worse than a window-property or a buffer-local value,
admittedly.

> and have the value of the property be a cons cell with these two
> positions, no?

An overlay is a handy abstraction for "pair of two positions in the same
buffer", with extra niceties such as the `evaporate` property.


        Stefan