From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: martin rudalics Newsgroups: gmane.emacs.bugs Subject: bug#12170: save-excursion fails boundary case with recenter Date: Sat, 11 Aug 2012 16:22:39 +0200 Message-ID: <50266AAF.4000504@gmx.at> 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> <83sjbtd6p0.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1344695035 25336 80.91.229.3 (11 Aug 2012 14:23:55 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 11 Aug 2012 14:23:55 +0000 (UTC) Cc: 12170@debbugs.gnu.org, wbrodie@panix.com To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Aug 11 16:23:53 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 1T0CbS-0008MX-Rf for geb-bug-gnu-emacs@m.gmane.org; Sat, 11 Aug 2012 16:23:47 +0200 Original-Received: from localhost ([::1]:53511 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T0CbS-00065p-0G for geb-bug-gnu-emacs@m.gmane.org; Sat, 11 Aug 2012 10:23:46 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:47256) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T0CbP-00065X-NT for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 10:23:44 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1T0CbN-0008Fl-DM for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 10:23:43 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:39905) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1T0CbN-0008Ff-9b for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 10:23:41 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1T0CjS-0000kH-AL for bug-gnu-emacs@gnu.org; Sat, 11 Aug 2012 10:32:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: martin rudalics Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 11 Aug 2012 14:32: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.13446954752804 (code B ref 12170); Sat, 11 Aug 2012 14:32:02 +0000 Original-Received: (at 12170) by debbugs.gnu.org; 11 Aug 2012 14:31:15 +0000 Original-Received: from localhost ([127.0.0.1]:49451 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1T0Cig-0000jA-P7 for submit@debbugs.gnu.org; Sat, 11 Aug 2012 10:31:15 -0400 Original-Received: from mailout-de.gmx.net ([213.165.64.22]:42208) by debbugs.gnu.org with smtp (Exim 4.72) (envelope-from ) id 1T0Cid-0000j1-P9 for 12170@debbugs.gnu.org; Sat, 11 Aug 2012 10:31:12 -0400 Original-Received: (qmail invoked by alias); 11 Aug 2012 14:22:49 -0000 Original-Received: from 62-47-59-168.adsl.highway.telekom.at (EHLO [62.47.59.168]) [62.47.59.168] by mail.gmx.net (mp010) with SMTP; 11 Aug 2012 16:22:49 +0200 X-Authenticated: #14592706 X-Provags-ID: V01U2FsdGVkX1/ijFsPrHjiJPQHnmLaT0W3SBL1I+7CPAB6A6ycTR 3CoKrg3jMdfW3l In-Reply-To: <83sjbtd6p0.fsf@gnu.org> X-Y-GMX-Trusted: 0 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:63036 Archived-At: > 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? Yes, because `set-window-point' doesn't set windows_or_buffers_changed in the case at hand since the window is the selected window. Or am I missing something? >> 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. But `set-window-point' should be equivalent to `goto-char' here because the window is the selected window. >> >> 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. I believe you. But it remains a mystery to me why `set-window-point' should make a difference here. As a matter of fact, if I do (progn (defmacro save-this-window-excursion (&rest body) "..." (let ((start (make-symbol "start")) (point (make-symbol "point"))) `(let ((,start (copy-marker (window-start))) (,point (copy-marker (window-point)))) (save-selected-window (progn ,@body)) (set-window-start (selected-window) ,start t) (with-current-buffer (window-buffer (selected-window)) (goto-char ,point))))) (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))))) I get the same results as with `set-window-point'. IMHO the `set-window-start' call makes the difference but I don't understand why. martin