From 4d7735c8f99051f8868bbdffd5c42e81b353cb5d Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Wed, 22 Feb 2017 12:59:32 -0600
Subject: [PATCH] softwrap: in do_mouse(), keep the cursor before a softwrap
 breakpoint

Add the new function actual_last_column() to accomplish this.
---
 src/nano.c  |  2 +-
 src/proto.h |  1 +
 src/winio.c | 28 ++++++++++++++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/nano.c b/src/nano.c
index 5b1a160e..63ef707b 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -1775,7 +1775,7 @@ int do_mouse(void)
 	    go_forward_chunks(row_count, &openfile->current, &leftedge);
 
 	openfile->current_x = actual_x(openfile->current->data,
-					leftedge + mouse_col);
+				actual_last_column(leftedge, mouse_col));
 
 #ifndef NANO_TINY
 	/* Clicking where the cursor is toggles the mark, as does clicking
diff --git a/src/proto.h b/src/proto.h
index 4e66b8e3..aabca6ab 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -665,6 +665,7 @@ void edit_scroll(scroll_dir direction, int nrows);
 #ifndef NANO_TINY
 size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
 				bool *end_of_line);
+size_t actual_last_column(size_t leftedge, size_t column);
 size_t get_chunk(filestruct *line, size_t column, size_t *leftedge);
 size_t get_chunk_row(filestruct *line, size_t column);
 size_t get_chunk_leftedge(filestruct *line, size_t column);
diff --git a/src/winio.c b/src/winio.c
index e1adccb1..c8e8cc77 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -3028,6 +3028,34 @@ size_t get_softwrap_breakpoint(const char *text, size_t leftedge,
     return (editwincols > 2) ? prev_column : column - 1;
 }
 
+/* When in softwrap mode, and the given column is on or after the breakpoint of
+ * a softwrapped chunk, shift it back to the last column before the breakpoint.
+ * The given column is relative to the given leftedge in current.  The returned
+ * column is relative to the start of the text. */
+size_t actual_last_column(size_t leftedge, size_t column)
+{
+#ifndef NANO_TINY
+    if (ISSET(SOFTWRAP)) {
+	size_t end_col;
+	bool last_chunk;
+
+	end_col = get_softwrap_breakpoint(openfile->current->data, leftedge,
+						&last_chunk) - leftedge;
+
+	/* If we're not on the last chunk, we're one column past the end of
+	 * the row.  Shifting back one column might put us in the middle of
+	  * a multi-column character, but actual_x() will fix that later. */
+	if (!last_chunk)
+	    end_col--;
+
+	if (column > end_col)
+	    column = end_col;
+    }
+#endif
+
+    return leftedge + column;
+}
+
 /* Get the row of the softwrapped chunk of the given line that column is on,
  * relative to the first row (zero-based), and return it.  If leftedge isn't
  * NULL, return the leftmost column of the chunk in it. */
-- 
GitLab