moving: prevent the cursor sticking on or skipping over overwide tabs

When we've landed on a tab and we are moving down and the tab starts
before the current chunk, then push the index forward -- otherwise we
would not advance.  When instead we're moving up and the end of the
preceding row is on the same tab as the target column AND the end of
the current row is not on that same tab, then there is some character
on this row that we can put the cursor on, so push the index forward
-- otherwise we would skip a usable row.

This fixes https://savannah.gnu.org/bugs/?52125
and fixes https://savannah.gnu.org/bugs/?52139.
master
Benno Schulenberg 2017-09-30 21:48:05 +02:00
parent 4436815725
commit 7a3a45e6ac
1 changed files with 7 additions and 6 deletions

View File

@ -65,18 +65,19 @@ void get_edge_and_target(size_t *leftedge, size_t *target_column)
}
/* Return the index in line->data that corresponds to the given column on the
* chunk that starts at the given leftedge. If the index lands on a tab, and
* this tab starts on an earlier chunk, and the tab ends on this row OR we're
* going forward, then increment the index and recalculate leftedge. */
* chunk that starts at the given leftedge. If the target column has landed
* on a tab, prevent the cursor from falling back a row when moving forward,
* or from skipping a row when moving backward, by incrementing the index. */
size_t proper_x(filestruct *line, size_t *leftedge, bool forward,
size_t column, bool *shifted)
{
size_t index = actual_x(line->data, column);
#ifndef NANO_TINY
if (ISSET(SOFTWRAP) && line->data[index] == '\t' && (forward ||
*leftedge / tabsize < (*leftedge + editwincols) / tabsize) &&
*leftedge % tabsize != 0 && column < *leftedge + tabsize) {
if (ISSET(SOFTWRAP) && line->data[index] == '\t' &&
((forward && strnlenpt(line->data, index) < *leftedge) ||
(!forward && column / tabsize == (*leftedge - 1) / tabsize &&
column / tabsize < (*leftedge + editwincols - 1) / tabsize))) {
index++;
*leftedge = leftedge_for(strnlenpt(line->data, index), line);