From c9e9964207b0e375143a07e3d1b43d9b37251736 Mon Sep 17 00:00:00 2001
From: Benno Schulenberg <bensberg@justemail.net>
Date: Tue, 26 Jul 2016 11:47:53 +0200
Subject: [PATCH] screen: don't look at placewewant but at where we actually
 were and are

For horizontal scrolling, it is not the /desired/ column position that
is relevant for determining whether a line needs to be redrawn after a
cursor movement, but the /actual/ column positions before and after.

This fixes https://savannah.gnu.org/bugs/?48627,
and fixes https://savannah.gnu.org/bugs/?48629.
---
 src/move.c  | 33 ++++++++++++++++++++-------------
 src/proto.h |  2 +-
 src/winio.c | 11 ++++++-----
 3 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/src/move.c b/src/move.c
index a0104d92..76068426 100644
--- a/src/move.c
+++ b/src/move.c
@@ -368,7 +368,7 @@ void do_next_word_void(void)
  * if we are. */
 void do_home(void)
 {
-    size_t pww_save = openfile->placewewant;
+    size_t was_column = xplustabs();
 
 #ifndef NANO_TINY
     if (ISSET(SMART_HOME)) {
@@ -385,19 +385,19 @@ void do_home(void)
 
     openfile->placewewant = xplustabs();
 
-    if (need_screen_update(pww_save))
+    if (need_screen_update(was_column, openfile->placewewant))
 	update_line(openfile->current, openfile->current_x);
 }
 
 /* Move to the end of the current line. */
 void do_end(void)
 {
-    size_t pww_save = openfile->placewewant;
+    size_t was_column = xplustabs();
 
     openfile->current_x = strlen(openfile->current->data);
     openfile->placewewant = xplustabs();
 
-    if (need_screen_update(pww_save))
+    if (need_screen_update(was_column, openfile->placewewant))
 	update_line(openfile->current, openfile->current_x);
 }
 
@@ -405,6 +405,8 @@ void do_end(void)
  * scroll up one line without scrolling the cursor. */
 void do_up(bool scroll_only)
 {
+    size_t was_column = xplustabs();
+
     /* If we're at the top of the file, or if scroll_only is TRUE and
      * the top of the file is onscreen, get out. */
     if (openfile->current == openfile->fileage
@@ -440,10 +442,10 @@ void do_up(bool scroll_only)
     /* If we're not on the first line of the edit window, and the target
      * column is beyond the screen or the mark is on, redraw the prior
      * and current lines. */
-    if (openfile->current_y > 0 && need_screen_update(0)) {
+    if (need_screen_update(was_column, 0))
 	update_line(openfile->current->next, 0);
+    if (need_screen_update(0, xplustabs()))
 	update_line(openfile->current, openfile->current_x);
-    }
 }
 
 /* Move up one line. */
@@ -460,6 +462,7 @@ void do_down(bool scroll_only)
     int amount = 0, enough;
     filestruct *topline;
 #endif
+    size_t was_column = xplustabs();
 
     /* If we're at the bottom of the file, get out. */
     if (openfile->current == openfile->filebot)
@@ -522,10 +525,10 @@ void do_down(bool scroll_only)
     /* If we're not on the last line of the edit window, and the target
      * column is beyond the screen or the mark is on, redraw the prior
      * and current lines. */
-    if (openfile->current_y < editwinrows - 1 && need_screen_update(0)) {
+    if (need_screen_update(was_column, 0))
 	update_line(openfile->current->prev, 0);
+    if (need_screen_update(0, xplustabs()))
 	update_line(openfile->current, openfile->current_x);
-    }
 }
 
 /* Move down one line. */
@@ -551,7 +554,7 @@ void do_scroll_down(void)
 /* Move left one character. */
 void do_left(void)
 {
-    size_t pww_save = openfile->placewewant;
+    size_t was_column = xplustabs();
 
     if (openfile->current_x > 0)
 	openfile->current_x = move_mbleft(openfile->current->data,
@@ -563,14 +566,14 @@ void do_left(void)
 
     openfile->placewewant = xplustabs();
 
-    if (need_screen_update(pww_save))
+    if (need_screen_update(was_column, openfile->placewewant))
 	update_line(openfile->current, openfile->current_x);
 }
 
 /* Move right one character. */
 void do_right(void)
 {
-    size_t pww_save = openfile->placewewant;
+    size_t was_column = xplustabs();
 
     assert(openfile->current_x <= strlen(openfile->current->data));
 
@@ -578,12 +581,16 @@ void do_right(void)
 	openfile->current_x = move_mbright(openfile->current->data,
 						openfile->current_x);
     else if (openfile->current != openfile->filebot) {
-	do_down_void();
 	openfile->current_x = 0;
+	openfile->placewewant = 0;
+	if (need_screen_update(was_column, 0))
+	    update_line(openfile->current, 0);
+	do_down_void();
+	return;
     }
 
     openfile->placewewant = xplustabs();
 
-    if (need_screen_update(pww_save))
+    if (need_screen_update(was_column, openfile->placewewant))
 	update_line(openfile->current, openfile->current_x);
 }
diff --git a/src/proto.h b/src/proto.h
index 9d8ef8f6..eec6d157 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -785,7 +785,7 @@ void reset_cursor(void);
 void edit_draw(filestruct *fileptr, const char *converted, int
 	line, size_t start);
 int update_line(filestruct *fileptr, size_t index);
-bool need_screen_update(size_t pww_save);
+bool need_screen_update(const size_t old_column, const size_t new_column);
 void edit_scroll(scroll_dir direction, ssize_t nlines);
 void edit_redraw(filestruct *old_current);
 void edit_refresh(void);
diff --git a/src/winio.c b/src/winio.c
index 43a4f93a..12923c76 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -2604,14 +2604,14 @@ int update_line(filestruct *fileptr, size_t index)
 
 /* Return TRUE if we need an update after moving the cursor, and
  * FALSE otherwise.  We need an update if the mark is on, or if
- * pww_save and placewewant are on different pages. */
-bool need_screen_update(size_t pww_save)
+ * old_column and new_column are on different pages. */
+bool need_screen_update(const size_t old_column, const size_t new_column)
 {
     return
 #ifndef NANO_TINY
 	openfile->mark_set ||
 #endif
-	get_page_start(pww_save) != get_page_start(openfile->placewewant);
+	get_page_start(old_column) != get_page_start(new_column);
 }
 
 /* When edittop changes, try and figure out how many lines
@@ -2740,7 +2740,7 @@ void edit_scroll(scroll_dir direction, ssize_t nlines)
     for (i = nlines; i > 0 && foo != NULL; i--) {
 	if ((i == nlines && direction == DOWNWARD) || (i == 1 &&
 		direction == UPWARD)) {
-	    if (need_screen_update(0))
+	    if (need_screen_update(openfile->placewewant, 0))
 		update_line(foo, (foo == openfile->current) ?
 			openfile->current_x : 0);
 	} else
@@ -2786,7 +2786,8 @@ void edit_redraw(filestruct *old_current)
 
     /* Update current if we've changed page, or if it differs from
      * old_current and needs to be horizontally scrolled. */
-    if (need_screen_update(was_pww) || (old_current != openfile->current &&
+    if (need_screen_update(was_pww, openfile->placewewant) ||
+			(old_current != openfile->current &&
 			get_page_start(openfile->placewewant) > 0))
 	update_line(openfile->current, openfile->current_x);
 }
-- 
GitLab