commit 24a64d37dde2cacacd52896a3d3ef1193ddd5757
parent a56a881c4b4864ad203060bae2c63208d6b041f6
Author: Benno Schulenberg <bensberg@telfort.nl>
Date: Sun, 20 Aug 2017 15:20:20 +0200
softwrap: properly move up and down over tabs that are split over rows
Also, move home to the first character after the tab if the current
chunk starts with a partial tab.
This fixes https://savannah.gnu.org/bugs/?51800.
Original-idea-by: David Lawrence Ramsey <pooka109@gmail.com>
Diffstat:
M | src/move.c | | | 44 | +++++++++++++++++++++++++++++--------------- |
1 file changed, 29 insertions(+), 15 deletions(-)
diff --git a/src/move.c b/src/move.c
@@ -62,6 +62,22 @@ 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)
+{
+ size_t index = actual_x(text, column);
+
+#ifndef NANO_TINY
+ if (ISSET(SOFTWRAP) && text[index] == '\t' &&
+ column < leftedge + leftedge % tabsize)
+ index++;
+#endif
+
+ return index;
+}
+
/* Move up nearly one screenful. */
void do_page_up(void)
{
@@ -72,13 +88,12 @@ void do_page_up(void)
* beginning of the top line of the edit window, as Pico does. */
if (!ISSET(SMOOTH_SCROLL)) {
openfile->current = openfile->edittop;
- openfile->placewewant = openfile->firstcolumn;
- openfile->current_x = actual_x(openfile->current->data,
- openfile->firstcolumn);
openfile->current_y = 0;
- }
- get_edge_and_target(&leftedge, &target_column);
+ leftedge = leftedge_for(openfile->firstcolumn, openfile->edittop);
+ target_column = 0;
+ } else
+ get_edge_and_target(&leftedge, &target_column);
/* Move up the required number of lines or chunks. If we can't, we're
* at the top of the file, so put the cursor there and get out. */
@@ -88,7 +103,7 @@ void do_page_up(void)
}
openfile->placewewant = leftedge + target_column;
- openfile->current_x = actual_x(openfile->current->data,
+ openfile->current_x = proper_x(openfile->current->data, leftedge,
actual_last_column(leftedge, target_column));
/* Move the viewport so that the cursor stays immobile, if possible. */
@@ -106,13 +121,12 @@ void do_page_down(void)
* beginning of the top line of the edit window, as Pico does. */
if (!ISSET(SMOOTH_SCROLL)) {
openfile->current = openfile->edittop;
- openfile->placewewant = openfile->firstcolumn;
- openfile->current_x = actual_x(openfile->current->data,
- openfile->firstcolumn);
openfile->current_y = 0;
- }
- get_edge_and_target(&leftedge, &target_column);
+ leftedge = leftedge_for(openfile->firstcolumn, openfile->edittop);
+ target_column = 0;
+ } else
+ get_edge_and_target(&leftedge, &target_column);
/* Move down the required number of lines or chunks. If we can't, we're
* at the bottom of the file, so put the cursor there and get out. */
@@ -122,7 +136,7 @@ void do_page_down(void)
}
openfile->placewewant = leftedge + target_column;
- openfile->current_x = actual_x(openfile->current->data,
+ openfile->current_x = proper_x(openfile->current->data, leftedge,
actual_last_column(leftedge, target_column));
/* Move the viewport so that the cursor stays immobile, if possible. */
@@ -347,7 +361,7 @@ void do_home(void)
if (ISSET(SOFTWRAP)) {
leftedge = leftedge_for(was_column, openfile->current);
- leftedge_x = actual_x(openfile->current->data, leftedge);
+ leftedge_x = proper_x(openfile->current->data, leftedge, leftedge);
}
if (ISSET(SMART_HOME)) {
@@ -463,7 +477,7 @@ void do_up(bool scroll_only)
return;
openfile->placewewant = leftedge + target_column;
- openfile->current_x = actual_x(openfile->current->data,
+ openfile->current_x = proper_x(openfile->current->data, leftedge,
actual_last_column(leftedge, target_column));
/* When the cursor was on the first line of the edit window (or when just
@@ -501,7 +515,7 @@ void do_down(bool scroll_only)
return;
openfile->placewewant = leftedge + target_column;
- openfile->current_x = actual_x(openfile->current->data,
+ openfile->current_x = proper_x(openfile->current->data, leftedge,
actual_last_column(leftedge, target_column));
/* When the cursor was on the last line of the edit window (or when just