From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#12170: save-excursion fails boundary case with recenter Date: Sat, 11 Aug 2012 14:11:23 +0300 Message-ID: <83sjbtd6p0.fsf@gnu.org> References: <000001cd7696$b0e93d60$12bbb820$@com> <5024D593.7080305@gmx.at> <003601cd76fd$b21cd590$165680b0$@com> <50251EED.3010804@gmx.at> <83393uefkw.fsf@gnu.org> <502626AD.1080505@gmx.at> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org X-Trace: dough.gmane.org 1344683514 11476 80.91.229.3 (11 Aug 2012 11:11:54 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 11 Aug 2012 11:11:54 +0000 (UTC) Cc: 12170@debbugs.gnu.org, wbrodie@panix.com To: martin rudalics Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Aug 11 13:11:54 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1T09bf-0002Bj-Sv for geb-bug-gnu-emacs@m.gmane.org; Sat, 11 Aug 2012 13:11:48 +0200 Original-Received: from localhost ([::1]:43185 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T09be-0000wd-Sc for geb-bug-gnu-emacs@m.gmane.org; Sat, 11 Aug 2012 07:11:46 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:58558) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T09bb-0000wU-Mo for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 07:11:45 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T09ba-0000eL-Ar for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 07:11:43 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:38745) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T09ba-0000eF-7J for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 07:11:42 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1T09je-0003nw-DF for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 07:20:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 11 Aug 2012 11:20:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 12170 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 12170-submit@debbugs.gnu.org id=B12170.134468398114585 (code B ref 12170); Sat, 11 Aug 2012 11:20:02 +0000 Original-Received: (at 12170) by debbugs.gnu.org; 11 Aug 2012 11:19:41 +0000 Original-Received: from localhost ([127.0.0.1]:48291 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1T09jI-0003nB-MU for submit@debbugs.gnu.org; Sat, 11 Aug 2012 07:19:41 -0400 Original-Received: from mtaout23.012.net.il ([80.179.55.175]:49291) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1T09jE-0003mw-Ss for 12170@debbugs.gnu.org; Sat, 11 Aug 2012 07:19:38 -0400 Original-Received: from conversion-daemon.a-mtaout23.012.net.il by a-mtaout23.012.net.il (HyperSendmail v2007.08) id <0M8L00D0089R0A00@a-mtaout23.012.net.il> for 12170@debbugs.gnu.org; Sat, 11 Aug 2012 14:11:14 +0300 (IDT) Original-Received: from HOME-C4E4A596F7 ([87.69.4.28]) by a-mtaout23.012.net.il (HyperSendmail v2007.08) with ESMTPA id <0M8L00CBO8EPW940@a-mtaout23.012.net.il>; Sat, 11 Aug 2012 14:11:14 +0300 (IDT) In-reply-to: <502626AD.1080505@gmx.at> X-012-Sender: halo1@inter.net.il X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:63034 Archived-At: > Date: Sat, 11 Aug 2012 11:32:29 +0200 > From: martin rudalics > CC: wbrodie@panix.com, 12170@debbugs.gnu.org > > >> (defun f (n) > >> (save-this-window-excursion (forward-line (- n)) (recenter 0))) > >> > >> (let ((buffer (switch-to-buffer "foo")) > >> (height (1- (window-height (get-buffer-window "foo"))))) > >> (insert-char 10 (* height 2)) > >> (let ((pt (point))) > >> (f height) > >> (redisplay) > >> (message "height %s old %s new %s" height pt (point))))) > >> > >> so I'd suspect the culprit somewhere in redisplay_window's code > > > > By saying "culprit" you mean you think this is a bug? > > I suppose so, yes. > > > I think Stefan > > explained why it isn't. > > With the OP's last recipe, `point' moves to the position implied by the > `recenter' call. With the `save-this-window-excursion' macro I gave, > `point' moves to the position implied by that macro instead and the > position implied by the `recenter' call is ignored. So here something > unexplained happens. Your recipe also calls set-window-point, which moves point on its own, and also does this: /* We have to make sure that redisplay updates the window to show the new value of point. */ if (!EQ (window, selected_window)) ++windows_or_buffers_changed; The windows_or_buffers_changed flag will force a thorough redisplay. Given this, do we still have something unexplained? > If we wanted to document the current behavior, we'd have to tell users > that if they call any of the window-related movement functions like > `recenter', `move-to-window-line', or `set-window-start' with a nil > NOFORCE argument, then `point' may move after the next redisplay in > order to honor the window start position implied by the last of these > functions executed. Do you agree so far? I guess. > If you agree, then we'd have to explain why a subsequent invocation of > `set-window-start' with NOFORCE t can override the setting of the window > start position implied by the last invocation of one of the functions > mentioned above. You didn't just call set-window-start, you also called set-window-point. If I remove that second call, the result of your code is very different, and the window start position as the macro set it is still in effect when control is returned. > >> w->force_start 1 will cause redisplay to honor the start position set up > >> by `recenter' > > > > Only if point will be visible when window is displayed starting at > > startp. > > I completely miss you here. I meant this code: w->optional_new_start = 0; start_display (&it, w, startp); move_it_to (&it, PT, 0, it.last_visible_y, -1, MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); if (IT_CHARPOS (it) == PT) w->force_start = 1; /* IT may overshoot PT if text at PT is invisible. */ else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT) w->force_start = 1; It only sets the force_start flag if displaying the window starting at startp will show point visible inside the window. The call to move_it_to moves in a simulated display lines, and stops either at point or at the last pixel position visible in the window, whichever happens first. The subsequent test that IT_CHARPOS (it) == PT verifies that it stopped at point and not because it reached the end of the text displayed in the window. Ergo, sometimes setting the window start position will not be honored. That's what the comment above all this means when it says: /* If someone specified a new starting point but did not insist, check whether it can be used. */ "Did not insist" means that whoever set w->optional_new_start did not also set w->force_start. The "check whether it can be used" part describes what I just explained. > > Not sure there's a lesson here to learn, but set-window-start sets the > > w->force_start flag unconditionally, > > IMHO > > if (NILP (noforce)) > w->force_start = 1; > > means "conditionally". Right. So my current theory is that set-window-point is what makes the difference.