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

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

bug#34038: 26.1; set-window-start sometimes fails to set window start


From: Alan Mackenzie
Subject: bug#34038: 26.1; set-window-start sometimes fails to set window start
Date: Fri, 11 Jan 2019 21:23:57 +0000
User-agent: Mutt/1.10.1 (2018-07-13)

Hello, Markus.

Your original form:

    (progn
      (goto-char (point-max))
      (insert "\n")
      (dotimes (x (window-height))
        (insert (format "%s\n" x)))
      (redisplay)
      (let ((b (buffer-string))
            (p (point)))
        (set-window-start nil p t)
        (read-key "Please press a key to continue.")
        (erase-buffer)
        (insert b)
        (set-window-start nil p t)))

On Fri, Jan 11, 2019 at 13:20:33 +0100, Markus Triska wrote:
> Eli Zaretskii <eliz@gnu.org> writes:

> > I think this happens because you call set-window-start with last
> > argument non-nil.  Doing that tells the display engine that the
> > window-start point is just a suggestion, not a hard requirement.

> In the documentation of set-window-start, the last argument is described
> as:

>     Optional third arg NOFORCE non-nil inhibits next redisplay from
>     overriding motion of point in order to display at this exact start.

> >From this text, this seems to be precisely what I need: I want to retain
> point at this exact place, and I only want to change the window start,
> not the point. In my use case, if I set this argument to "nil", then I
> get unexpected point motion. Is there a way to reliably set window point
> while at the same time preventing motion of point? I tried adding
> (redisplay) at strategic places in my code, and this seems to work
> somewhat better then, though at the cost of causing display flickering.

> Thank you and all the best!
> Markus

I've played with this for several hours, and my feeling, like yours, is
that there's a bug in there, somewhere.

If you set scroll-conservatively to a non-zero value, your form behaves
properly.  This suggests that the problem is in redisplay rather than
set-window-start itself.

If you remove the erase-buffer and insert forms from the form,
(replacing them with an (end-of-buffer)), again you get the desired
behaviour.

M-: (set-window-start nil (point-max) t) appears to behave correctly.

A bit of debugging output shows that after (erase-buffer), window-start
is already at 1, not the former point-max.  After (insert b),
window-start continues to be at 1.

erase-buffer and insert are doing something strange with internal
display variables.  I tried seeing if this was the w->force_start field
of the window structure (that's the field which gets set to true when
one calls set-window-start _without_ a non-nil NOFORCE, but doesn't get
cleared when NOFORCE is non-nil; I think only redisplay clears it).  But
this isn't it.

There might be a clue in the entry for set-window-start in the manual,
which says:

     If NOFORCE is non-`nil', and POSITION would place point off screen
     at the next redisplay, then redisplay computes a new window-start
     position that works well with point, and thus POSITION is not used.
 
.  This is pure speculation, but perhaps because the entire buffer is
currently off the screen, with point being on the empty last line,
redisplay is somehow thinking that point is off screen too.  If this is
the case, it would explain why redisplay scrolls the buffer to put point
on the middle window line.

-- 
Alan Mackenzie (Nuremberg, Germany).





reply via email to

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