Subject: bug#43519: 28.0.50; Overlay at end of minibuf hides minibuf's real content

From: Eli Zaretskii <[email-masked]>
Date: Mon, 21 Sep 2020 20:30:40 +0300

> Date: Mon, 21 Sep 2020 16:27:51 +0000
> From: Gregory Heytings <[email-masked]>
> cc: [email-masked], [email-masked]
> 
> > This bug was filed to request that Emacs behaves with overlay-string in 
> > the minibuffer prompt the same as with regular buffer text.
> 
> Hmmm...  no, this bug was filed after a discussion on emacs-devel (about 
> implementing vertical icomplete), and the problem is clearly stated by 
> Stefan: the prompt and user input so far disappear.

That's not my reading of the main argument, posted by Stefan in

  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=43519#17

Some quotes:

  I used `icomplete-mode` only as a vehicle to show the underlying
  behavior with a short recipe which exhibits a real-life problem.
  [...]
  This performs "display of text after point" in 2 different ways:
  - first by `insert`.
  - then with an overlay.
  The visual rendering of the text is the same, with the cursor at the
  same place.  When we do it with `insert` there is no horizontal
  scrolling, but when we do it with an overlay the text gets scrolled so
  the cursor is at `window-start`.

  `icomplete` needs the behavior to be the same as with `insert`, but it
  prefers to use an overlay to avoid some undesirable side-effects of
  modifying the actual text.

  So the question is: how to get the same behavior as what we'd get with
  `insert` but without actually modifying the buffer's contents?

My summary of the problem raised by Stefan:

  . icomplete is just an example that exhibits a more general issue
  . the more general issue is that the display after resizing the
    mini-window is different depending on whether it uses plain buffer
    text or an after-string overlay at EOB

If you use Stefan's recipe, but make the prompt much longer, like
this:

    (minibuffer-with-setup-hook
        (lambda ()
          (insert "hello")
          (let ((ol (make-overlay (point) (point)))
                (max-mini-window-height 1)
                (text "askdjfhaklsjdfhlkasjdfhklasdhflkasdhflkajsdhflkashdfkljahsdlfkjahsdlfkjhasldkfhalskdjfhalskdfhlaksdhfklasdhflkasdhflkasdhflkajsdhklajsdgh"))
            (save-excursion (insert text))
            (sit-for 2)
            (delete-region (point) (point-max))
            (put-text-property 0 1 'cursor t text)
            (overlay-put ol 'after-string text)
            (sit-for 2)
            (delete-overlay ol)))
      (read-string "totototototototototototototototototototototototototototototototototototototototototototototototototototo: "))

then in the 1st ("insert text") part of the recipe you will see only
the last part of the prompt.  Which is the long-standing behavior of
resizing mini-windows: if the mini-window cannot be enlarged enough to
show the entire text in it, we show its last part.

Stefan asked for the same behavior when an overlay with after-string
is used.  My suggestion (I hope) will do what he asks, or approximate
that as well as I think is possible under the current design of the
display code.

> Which is why my proposal is to not break anything, but only to give 
> applications the control of how what they insert in the minibuffer is 
> displayed.  A start_display_at_beginning_of_minibuffer variable that would 
> be reset in read_minibuf() and that an application could set in 
> minibuffer-setup-hook.  I don't understand why you would be opposed to 
> such a change.

Because it changes a long-standing behavior with inserting normal text
into the minibuffer.

> > That may or may not be a good idea, but it's a separate issue, so should 
> > be discussed separately
> 
> It's _not_ a separate issue, it's the issue at hand.

I disagree, and I explained above why.

> > (and in that separate discussion I will generally be opposed to the 
> > change you are proposing, because we had the current behavior for many 
> > years, and so changes like the one you propose run serious risk of 
> > breaking expectations of some package out there).
> >
> 
> Why would a change that does not change Emacs' behavior in any way except 
> if the user requests it "run serious risk of breaking expectations of some 
> package out there"?

This is not the user, this is a Lisp program that will do it.  The
behavior will change in that the user will be shown only the first
part of the text, as opposed to the last part we were showing until
now.  Maybe such a change in behavior is desirable (I'm not sure, and
I don't yet have a clear idea how will Lisp programs decide which
behavior to request), but it's a separate issue.