From 2386984fd8b2c9f1340440d0ee9042b47d7cc446 Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Tue, 22 Aug 2017 16:17:23 -0500
Subject: [PATCH] moving: recalculate leftedge if current_x is pushed forward

---
 src/move.c  | 38 +++++++++++++++++++++++++++++---------
 src/winio.c |  8 +++++---
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/src/move.c b/src/move.c
index c044aadf..5940a418 100644
--- a/src/move.c
+++ b/src/move.c
@@ -66,15 +66,19 @@ void get_edge_and_target(size_t *leftedge, size_t *target_column)
 
 /* Return the index in text that corresponds to the given column on the chunk
  * starting on the given leftedge.  If the index is on a tab and this tab
- * starts on the preceding chunk, push the index one step forward. */
-size_t proper_x(const char *text, size_t leftedge, size_t column)
+ * starts on the preceding chunk, push the index one step forward and set
+ * shifted to TRUE. */
+size_t proper_x(const char *text, size_t leftedge, size_t column,
+		bool *shifted)
 {
     size_t index = actual_x(text, column);
 
 #ifndef NANO_TINY
     if (ISSET(SOFTWRAP) && text[index] == '\t' && leftedge % tabsize != 0 &&
-			column < leftedge + tabsize)
+			column < leftedge + tabsize) {
 	index++;
+	*shifted = TRUE;
+    }
 #endif
 
     return index;
@@ -104,19 +108,21 @@ void do_page_up(void)
 	return;
     }
 
-    openfile->placewewant = leftedge + target_column;
     openfile->current_x = actual_x(openfile->current->data,
 				actual_last_column(leftedge, target_column));
 
     /* Move the viewport so that the cursor stays immobile, if possible. */
     adjust_viewport(STATIONARY);
     refresh_needed = TRUE;
+
+    openfile->placewewant = leftedge + target_column;
 }
 
 /* Move down nearly one screenful. */
 void do_page_down(void)
 {
     int mustmove = (editwinrows < 3) ? 1 : editwinrows - 2;
+    bool shifted = FALSE;
     size_t leftedge, target_column;
 
     /* If we're not in smooth scrolling mode, put the cursor at the
@@ -137,13 +143,20 @@ void do_page_down(void)
 	return;
     }
 
-    openfile->placewewant = leftedge + target_column;
     openfile->current_x = proper_x(openfile->current->data, leftedge,
-				actual_last_column(leftedge, target_column));
+				actual_last_column(leftedge, target_column),
+				&shifted);
+
+    /* If proper_x() shifted current_x, the leftedge may have changed. */
+    if (shifted)
+	leftedge = leftedge_for(xplustabs(), openfile->current);
 
     /* Move the viewport so that the cursor stays immobile, if possible. */
     adjust_viewport(STATIONARY);
     refresh_needed = TRUE;
+
+    /* leftedge may have changed, so set placewewant now. */
+    openfile->placewewant = leftedge + target_column;
 }
 
 #ifndef DISABLE_JUSTIFY
@@ -358,12 +371,13 @@ void do_home(void)
     size_t was_column = xplustabs();
     bool moved_off_chunk = TRUE;
 #ifndef NANO_TINY
-    bool moved = FALSE;
+    bool moved = FALSE, shifted = FALSE;
     size_t leftedge = 0, leftedge_x = 0;
 
     if (ISSET(SOFTWRAP)) {
 	leftedge = leftedge_for(was_column, openfile->current);
-	leftedge_x = proper_x(openfile->current->data, leftedge, leftedge);
+	leftedge_x = proper_x(openfile->current->data, leftedge, leftedge,
+				&shifted);
     }
 
     if (ISSET(SMART_HOME)) {
@@ -494,6 +508,7 @@ void do_up(bool scroll_only)
 void do_down(bool scroll_only)
 {
     filestruct *was_current = openfile->current;
+    bool shifted = FALSE;
     size_t leftedge, target_column;
 
     get_edge_and_target(&leftedge, &target_column);
@@ -503,7 +518,12 @@ void do_down(bool scroll_only)
 	return;
 
     openfile->current_x = proper_x(openfile->current->data, leftedge,
-				actual_last_column(leftedge, target_column));
+				actual_last_column(leftedge, target_column),
+				&shifted);
+
+    /* If proper_x() shifted current_x, the leftedge may have changed. */
+    if (shifted)
+	leftedge = leftedge_for(xplustabs(), openfile->current);
 
     if (scroll_only)
 	edit_scroll(DOWNWARD, 1);
diff --git a/src/winio.c b/src/winio.c
index 0f9564c7..400bd9f6 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -3089,9 +3089,11 @@ size_t leftedge_for(size_t column, filestruct *line)
 {
     size_t leftedge;
 
-    get_chunk_and_edge(column, line, &leftedge);
-
-    return leftedge;
+    if (ISSET(SOFTWRAP)) {
+	get_chunk_and_edge(column, line, &leftedge);
+	return leftedge;
+    } else
+	return 0;
 }
 
 /* Return the row of the last softwrapped chunk of the given line, relative to
-- 
2.14.1

