From 2d50c4f257e4caf8367916c2390f0bdb80204a8d Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@justemail.net>
Date: Fri, 15 Apr 2016 14:39:54 +0200
Subject: [PATCH] softwrap: adjust for current_x when computing the amount to
 scroll

The number of lines to scroll is: the y position of the start of the
current line, plus the extra lines that this line occupies, plus the
extra lines that the next line occupies, plus one, minus the y position
of the last window line.

The y position of the start of the current line is current_y -
xplustabs() / COLS, the extra lines are strlenpt(data) / COLS,
and the y position of the last window line is editwinrows - 1.

Note that we first compute the amount to scroll before actually moving
to the next line, because we need the current value of current_x, not
the one that it will have in the next line.  The placewewant value is
not good either, because it might be beyond where we actually are.

This fixes https://savannah.gnu.org/bugs/?47665.
---
 src/move.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/move.c b/src/move.c
index 21bb3262..77ed490d 100644
--- a/src/move.c
+++ b/src/move.c
@@ -451,16 +451,12 @@ void do_down(
 		openfile->current->lineno - openfile->edittop->lineno);
     assert(openfile->current->next != NULL);
 
-    /* Move the current line of the edit window down. */
-    openfile->current = openfile->current->next;
-    openfile->current_x = actual_x(openfile->current->data,
-	openfile->placewewant);
-
 #ifndef NANO_TINY
     if (ISSET(SOFTWRAP)) {
-	/* Compute the amount to scroll. */
-	amount = (strlenpt(openfile->current->data) / COLS + openfile->current_y + 2
-		 + strlenpt(openfile->current->prev->data) / COLS - editwinrows);
+	/* Compute the number of lines to scroll. */
+	amount = strlenpt(openfile->current->data) / COLS - xplustabs() / COLS +
+			strlenpt(openfile->current->next->data) / COLS +
+			openfile->current_y - editwinrows + 2;
 	topline = openfile->edittop;
 	/* Reduce the amount when there are overlong lines at the top. */
 	for (enough = 1; enough < amount; enough++) {
@@ -474,6 +470,11 @@ void do_down(
     }
 #endif
 
+    /* Move to the next line in the file. */
+    openfile->current = openfile->current->next;
+    openfile->current_x = actual_x(openfile->current->data,
+					openfile->placewewant);
+
     /* If scroll_only is FALSE and if we're on the last line of the
      * edit window, scroll the edit window down one line if we're in
      * smooth scrolling mode, or down half a page if we're not.  If
-- 
GitLab