Subject: bug#18739: 24.3; Request for a hook to be provided when scrolling will move the cursor

From: Eli Zaretskii <[email-masked]>
Date: Fri, 17 Oct 2014 09:38:38 +0300

> From: Stefan Monnier <[email-masked]>
> Cc: [email-masked],  [email-masked]
> Date: Thu, 16 Oct 2014 17:24:43 -0400
> 
> > Those few more times are in direct contradiction to the definition you
> > suggested.  If you don't care about that, what would be the purpose of
> > the definition?
> 
> To know when you can be sure that it should be called and when it might
> not be called.  Most of our hooks that react to changes (like
> window-configuration-change-hook, menu-bar-update-hook, ...) have the
> property that they may be called unnecessarily.  As long as it's not too
> frequent, it shouldn't be a problem.  It's still useful to know when it
> should be run and when it shouldn't, so that when we find a bug we can
> tell whether it's in the hook function or in the caller of the hook.

I'm not sure I get your point.  But if you mean to say something that
is already said in the doc string, i.e.

  List of functions to call before redisplaying a window with scrolling.
  [...] Note that these functions are also called by `set-window-buffer'.

then I'm okay with that.

> > Sorry, I'm lost.  I no longer understand what "consistency" is being
> > praised here.  For that matter, I probably don't understand what you
> > mean by window-start "modified" and "unmodified", as you seem to
> > employ contradicting meanings: one when the marker moves but points to
> > the same text, the other when it doesn't move, but points to a
> > different text.
> 
> Maybe I misunderstood your examples, but by "marker moves" I mean that
> something has done a set-marker: changes to marker-position due to
> insertion/deletion of text doesn't count as moving the marker.

If you insert text at the beginning of a line whose first character
was the window-start, then according to the above definition the
marker _will_ move, because Emacs will likely reset it to the new
beginning of the line, or maybe even to one of the following lines
(the latter if point moves out of the view as result of the
insertion).

> AFAICT all your examples indicate that window-scroll-functions is called
> if and only if the marker is moved (plus a few spurious calls where we
> didn't realize that the change was really a no-op).

I don't like this "conclusion", because it can be interpreted as
meaning that moving the window-start marker _causes_
window-scroll-functions to be called.  But actually, there's no
causality here; both movement of window-start and a call to
window-scroll-functions are side effects of Emacs scrolling the
window in some sense.

> >> Playing with it, I see that this code is triggered very rarely.
> > As it should be.  It is mainly meant for scrolling commands.
> 
> By "rarely" I meant, "rarely even while scrolling".  The only "normal"
> case where it seems to be triggered is if I scroll by moving the
> scrollbar's thumb.

That's not my reading of the code.  (Not sure why it matters, though.)

> >> `scroll-up' doesn't go through this at all.
> > scroll-up calls window_scroll, which calls window_scroll_pixel_based,
> > which does set the force_start flag of the window, and thus does
> > trigger this portion of redisplay_window.
> 
> But by the time redisplay happens, window_scroll_pixel_based has already
> moved point within the viewport, so the redisplay itself doesn't
> change point (tho there might be corner cases where
> window_scroll_pixel_based ends up putting point outside the viewport,
> of course).

If the window's force_start flag is set when redisplay is entered,
then my reading of the code is that window-scroll-functions will be
called even if point doesn't have to move.  And that's okay, because
this is how scrolling commands cause window-scroll-functions to be
called.  You will even see comments to that effect in window.c.

Again, I'm not sure why it is important whether the hook is called
frequently or not in some situation where it has to be called.

> > The force_start flag is _the_ way by which scrolling commands work:
> > they tell redisplay to heed to what they did.
> 
> Yes, but the force_start flag rarely causes point to be moved, in
> my experience.

Maybe so, but (a) I again don't understand why the frequency matters,
and (b) my reading of the code is that the hook will be called even if
point doesn't need to be repositioned.  The hook should be called to
reflect the fact that we scrolled, even if point didn't move.

> >> There might be others.
> > Should be mostly (or only) scrolling commands.
> 
> I'm not sure I understand.  If I want to catch all (i.e. exhaustively)
> cases where scrolling moves point, do you think that catching the
> redisplay_window case plus the window_scroll_pixel/line_based cases is
> all that's needed?

Yes, I think so.