Subject: bug#76186: 31.0.50; (recenter 0) sometimes does not recenter as expected

From: Eli Zaretskii <[email-masked]>
Date: Sat, 22 Feb 2025 16:05:19 +0200

> From: Stephen Berman <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Sat, 22 Feb 2025 14:46:34 +0100
> 
> On Sat, 22 Feb 2025 15:32:28 +0200 Eli Zaretskii <[email-masked]> wrote:
> 
> > Thanks.  I'm afraid I'm none the wiser, because I see none of the
> > phenomena you describe on my system.  Whatever I do, the test always
> > runs to completion, and the last screen shows point at EOB.
> 
> By "runs to completion" I suppose you mean 501 iterations (or whatever
> you set n to)?

Yes.

> In this case is the message as above, with window-start
> and point-max identical, or does the message show them differing?

The former.

> The latter would be unexpected unless the loop stopped before 501
> (or n) iterations.

I don't see that.

> > Some parts of what you describe seem to indicate that the problem is
> > not with 'recenter' itself, but with the following redisplay cycle,
> > which, for some reason, considers the window-start position
> > inappropriate and recenters point on display.  But I have no idea why,
> > and it is impossible to debug this when the problem happens as part of
> > 500 iterations.
> 
> I agree, and the apparent ineffectiveness of Edebug in this case is also
> frustrating.  I could try using gdb with the test configuration where I
> consistly get the "unexpected recentering" after one iteration; can you
> suggest where to set the break point and any other input that may be
> helpful?

'recenter' takes effect in two parts: first Emacs determines where to
put window-start, and then redisplay redraws the window according to
that.

The first part is in window.c, in Frecenter, where we have this:

  /* Set the new window start.  */
  set_marker_both (w->start, w->contents, charpos, bytepos);

So first we should determine whether this code determines the
window-start point as expected.  If not, the reason is inside the
implementation of 'recenter'.

The second part is in xdisp.c:redisplay_window, where it attempts to
obey the optional_new_start flag of the window.  It starts here:

  /* If someone specified a new starting point but did not insist,
     check whether it can be used.  */
  if ((w->optional_new_start || window_frozen_p (w))
      && CHARPOS (startp) >= BEGV
      && CHARPOS (startp) <= ZV)
    {
      ptrdiff_t it_charpos;

      w->optional_new_start = false;

This code should set the w->force_start flag.  Does it?  If not, what
prevents that?

Next, we have this:

 force_start:

  /* Handle case where place to start displaying has been specified,
     unless the specified location is outside the accessible range.  */
  if (w->force_start)
    {

The code after this tries to use the specified window-start point, and
the question is: why it eventually rejects it (as what you see seems
to suggest)?

HTH

P.S. It could be that the problem is entirely elsewhere, so don't be
surprised if you step through all of that code and find that Emacs
does indeed succeed to use the window-start point the scenario expects
it to use.

Thanks.