all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Steven Allen via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 72323@debbugs.gnu.org, storm@cua.dk
Subject: bug#72323: 31.0.50; line-move unconditionally resets vscroll to 0
Date: Sat, 27 Jul 2024 13:10:03 -0700	[thread overview]
Message-ID: <87v80qha04.fsf@stebalien.com> (raw)
In-Reply-To: <86ikwq1z92.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 2610 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> Cc: "Kim F. Storm" <storm@cua.dk>
>> Date: Sat, 27 Jul 2024 10:57:44 -0700
>> From:  Steven Allen via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>> 
>> Fixing home/end (beginning of line, end of line) case seems trivial:
>> don't call `line-move' in these cases (or have `line-move' short-circuit
>> when `arg' is 0). However, even after reading all the comments about
>> scrolling images, I'm still not sure why it's necessary to reset vscroll
>> to 0.
>
> Because otherwise what line-move does cannot be described in sensible
> terms.  If vscroll is not reset, then what would be the reference for
> such a "line move"?  By its very definition, line-move moves N screen
> lines wrt the line which was its starting point, but with vscroll
> non-zero that starting point could be anywhere.

I'm a bit confused because vscroll is about scrolling the window and
`line-move' is about moving point (only incidentally scrolling the
window if the point leaves it). Clearly `set-window-start' needs to
reset `vscroll', but I'm not sure I understand why `line-move' does.

Is this about detecting the correct column?

> In addition, when we move to another screen line, the value of vscroll
> cannot be meaningfully kept, because its meaning is tightly coupled to
> the screen line where it was applied.  In essence, vscroll is a trick
> to allow display of a tall display element (image, text using a large
> fonts, etc.) in a window whose height is too small to show all of the
> display element at once.
>
>> After commenting this line out, I can't tell a difference, even
>> when scrolling images with and without `auto-window-vscroll' and
>> `try-vscroll'.
>
> line-move is not just for scrolling across images, it is also about
> scrolling across tall text lines and other display elements.  In any
> case, asking for removal of that reset is a non-starter, for the
> reasons explained above, so it isn't going to happen.  The solution
> for any Lisp program that doesn't want vscroll to be rest is not to
> call line-move.

Now that I do more testing, I can see how removing that line breaks
`line-move' although I'm still not sure why.

Would it be acceptable to restore the vertical scroll position as long
as `line-move' hasn't otherwise scrolled the screen? See attached patch.

>> I was hoping Kim could shed some light on this.
>
> I'd be thrilled to hear from Kim, but I'm as guilty of the code in
> line-move as he is, so "blame" me if you want.

Ah, sorry, should have gone back further in the blame history.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Restore-vertical-scroll-offset-after-line-move.patch --]
[-- Type: text/x-patch, Size: 5336 bytes --]

From 2f028e30b2e5ba3a3cd9fd2ecaeaff7c3d02b62f Mon Sep 17 00:00:00 2001
From: Steven Allen <steven@stebalien.com>
Date: Sat, 27 Jul 2024 12:54:31 -0700
Subject: [PATCH] Restore vertical-scroll offset after line-move

Restore the vertical-scroll offset after moving lines unless the window
was otherwise scrolled and/or altering the vertical scroll would move
the point off-screen.

* lisp/simple.el (line-move): restore `window-vscroll' when
appropriate (Bug#72323).
---
 lisp/simple.el | 85 ++++++++++++++++++++++++++++----------------------
 1 file changed, 48 insertions(+), 37 deletions(-)

diff --git a/lisp/simple.el b/lisp/simple.el
index a9f8b5845d8..71ae175d198 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -7930,43 +7930,54 @@ line-move
                    ;; doesn't have very long lines.
                    (long-line-optimizations-p)))
 		 (line-move-partial arg noerror))
-      (set-window-vscroll nil 0 t)
-      (if (and line-move-visual
-	       ;; Display-based column are incompatible with goal-column.
-	       (not goal-column)
-               ;; Lines aren't truncated.
-               (not
-                (and
-                 (or truncate-lines (truncated-partial-width-window-p))
-                 (long-line-optimizations-p)))
-	       ;; When the text in the window is scrolled to the left,
-	       ;; display-based motion doesn't make sense (because each
-	       ;; logical line occupies exactly one screen line).
-	       (not (> (window-hscroll) 0))
-	       ;; Likewise when the text _was_ scrolled to the left
-	       ;; when the current run of vertical motion commands
-	       ;; started.
-	       (not (and (memq last-command
-			       `(next-line previous-line ,this-command))
-			 auto-hscroll-mode
-			 (numberp temporary-goal-column)
-			 (>= temporary-goal-column
-			    (- (window-width) hscroll-margin)))))
-	  (prog1 (line-move-visual arg noerror)
-	    ;; If we moved into a tall line, set vscroll to make
-	    ;; scrolling through tall images more smooth.
-	    (let ((lh (line-pixel-height))
-		  (edges (window-inside-pixel-edges))
-		  (dlh (default-line-height))
-		  winh)
-	      (setq winh (- (nth 3 edges) (nth 1 edges) 1))
-	      (if (and (< arg 0)
-		       (< (point) (window-start))
-		       (> lh winh))
-		  (set-window-vscroll
-		   nil
-		   (- lh dlh) t))))
-	(line-move-1 arg noerror)))))
+      (let ((initial-vscroll (window-vscroll nil t))
+            (initial-window-start (window-start)))
+            (set-window-vscroll nil 0 t)
+            (prog1
+                (if (and line-move-visual
+                         ;; Display-based column are incompatible with goal-column.
+                         (not goal-column)
+                         ;; Lines aren't truncated.
+                         (not
+                          (and
+                           (or truncate-lines (truncated-partial-width-window-p))
+                           (long-line-optimizations-p)))
+                         ;; When the text in the window is scrolled to the left,
+                         ;; display-based motion doesn't make sense (because each
+                         ;; logical line occupies exactly one screen line).
+                         (not (> (window-hscroll) 0))
+                         ;; Likewise when the text _was_ scrolled to the left
+                         ;; when the current run of vertical motion commands
+                         ;; started.
+                         (not (and (memq last-command
+                                         `(next-line previous-line ,this-command))
+                                   auto-hscroll-mode
+                                   (numberp temporary-goal-column)
+                                   (>= temporary-goal-column
+                                       (- (window-width) hscroll-margin)))))
+                    (prog1 (line-move-visual arg noerror)
+                      ;; If we moved into a tall line, set vscroll to make
+                      ;; scrolling through tall images more smooth.
+                      (let ((lh (line-pixel-height))
+                            (edges (window-inside-pixel-edges))
+                            (dlh (default-line-height))
+                            winh)
+                        (setq winh (- (nth 3 edges) (nth 1 edges) 1))
+                        (if (and (< arg 0)
+                                 (< (point) (window-start))
+                                 (> lh winh))
+                            (set-window-vscroll
+                             nil
+                             (- lh dlh) t))))
+                  (line-move-1 arg noerror))
+              ;; Restore the vscroll position, if any.
+              (when (and (not (zerop initial-vscroll))
+                         ;; But not if scrolling would hide the point.
+                         (< initial-vscroll (cdr (posn-x-y (posn-at-point))))
+                         ;; Or if line-move otherwise scrolled the window.
+                         (= initial-window-start (window-start))
+                         (zerop (window-vscroll nil t)))
+                (set-window-vscroll nil initial-vscroll t)))))))
 
 ;; Display-based alternative to line-move-1.
 ;; Arg says how many lines to move.  The value is t if we can move the
-- 
2.45.2


  reply	other threads:[~2024-07-27 20:10 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-27 17:57 bug#72323: 31.0.50; line-move unconditionally resets vscroll to 0 Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-07-27 18:11 ` Eli Zaretskii
2024-07-27 20:10   ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-07-28  4:50     ` Eli Zaretskii
2024-07-28 20:07       ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-07-28 20:10         ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-07-29 11:14           ` Eli Zaretskii
2024-07-29 11:12         ` Eli Zaretskii
2024-07-29 14:30           ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 17:42             ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 17:38           ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 18:21             ` Eli Zaretskii
2024-08-18 18:40               ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 19:01                 ` Eli Zaretskii
2024-08-18 22:17                   ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-19 11:06                     ` Eli Zaretskii
2024-08-19 17:30                       ` Steven Allen via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-09-30  0:51                         ` Stefan Kangas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87v80qha04.fsf@stebalien.com \
    --to=bug-gnu-emacs@gnu.org \
    --cc=72323@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    --cc=steven@stebalien.com \
    --cc=storm@cua.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.