bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#6671: moving point and scroll-conservatively


From: Eli Zaretskii
Subject: bug#6671: moving point and scroll-conservatively
Date: Thu, 24 Mar 2011 03:23:44 -0400

> From: Chong Yidong <cyd@stupidchicken.com>
> Date: Wed, 23 Mar 2011 23:58:27 -0400
> Cc: 6671@debbugs.gnu.org
> 
> After playing around with the "C-n in xdisp.c" testcase with the changes
> in revision 100619/100620 reverted, I think I know the problem.
> 
> In this test case, recentering seems to be triggered by redisplay-time
> fontification.  To demonstrat this, set fontification-functions to nil
> in xdisp.c, before initiating the C-n testcase.  For me, at least, the
> anomalous recentering then does not occur.

Sorry, but phenomenological explanations shouldn't be accepted in this
case.  We need specific evidence, and the only way to show that is by
adding the necessary tracing code and showing the results.

For example, I suggest to try introducing artificial delays (with
`nanosleep' or some such) into redisplay, and trying then, with
fontification-functions disabled.  You may find out (as I did at the
time) that fontification is just a trigger, not the cause itself; the
cause is more computations done during redisplay, which cause the
display engine bail out prematurely (unless you turn on
redisplay-dont-pause), which is yet another cause of recentering.

> The precise mechanism by which the fontification functions screw things
> up is by narrowing the buffer.  This is why, in last year's thread, the
> buffer's clip_changed flag was found to be set.  That forces recentering
> in redisplay_window (xdisp.c:14159).

Well, it shouldn't.  Instead of "fixing" the code by preventing this
flag to be set based on some heuristics, we should make the code DTRT
even if the flag is set (assuming that this indeed is the root cause
of the recentering in its all incarnations, which I'm not sure about).

Please note that I'm not convinced that the issue of fontification and
the clip_changed flag is relevant to the issue at hand.  Recentering
has more than one reason, so you could be seeing one of the other
ones.  We shouldn't mix them, if we want to remain sane and leave our
display code maintainable.

> So, a good fix might be to check whether redisplay-time fontification
> changes the buffer's restrictions, and, if so, reset the clip_changed
> flag.  That should make the 100619/100620 changes unnecessary.

Please don't revert these changes.  They took a lot of effort to
arrive at, and generally DTRT in a way that is easy to understand and
maintain.

The problem with performance for large moves of point is IMO
straightforward to fix: when point is "far away" (which could be set
back to those proverbial 10 screen lines), then, instead of moving one
line at a time, move to point in one go, and then compute the window
start so that point is at the proper place relative to window start.
That proper place depends on the variables that try_scrolling
considers already, like scroll-conservatively etc.  The problem is, it
considers them too early, before we realize that point is too far
away.  When we do realize that, we are already past the code that
computes the scroll according to those variables, and all we do is
punt and recenter.

So the fix would be to re-arrange the code in try_scrolling so that
the decision to move far away and the move itself are done _before_ we
consider the adjustments of window start according to the
scroll-related variables.

IOW, we are suffering from historical legacy in redisplay here.
Originally, Emacs always recentered.  Then the various scrolling
options were introduced, but the code is still structured so that it
eventually falls back on recentering.  We should change that so that
whatever happens, after catching up with point we compute the window
start according to user expectations expressed through the scroll-*
options.  That would eliminate the recentering fallback completely,
and finally put this issue to rest.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]