display: support the position indicator also when --softwrap is used

A new member ('chunk_nr') is added to each 'linestruct', to store
the serial number of the first chunk of that line, so that, when
softwrap is on, the scroll-bar thing can be computed relative to
chunks instead of relative to actual lines.

To guarantee that 'chunk_nr' is correctly synced, the buffer is
renumbered whenever the number of chunks in a line changes, and
also when softwrap is toggled on, and when buffers are switched.

Signed-off-by: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
master
Marco Diego Aurélio Mesquita 2020-05-14 11:53:19 +02:00 committed by Benno Schulenberg
parent b33a62af8c
commit 6bccedb319
4 changed files with 43 additions and 7 deletions

View File

@ -52,10 +52,12 @@ void do_deletion(undo_type action)
&openfile->current->data[openfile->current_x + charlen],
line_len - charlen + 1);
#ifndef NANO_TINY
/* If the number of screen rows that a softwrapped line occupies
* has changed, we need a full refresh. */
if (ISSET(SOFTWRAP) && extra_chunks_in(openfile->current) != old_amount)
/* When softwrapping and the number of chunks in the current line has
* changed, the chunks must be renumbered and the screen refreshed. */
if (ISSET(SOFTWRAP) && extra_chunks_in(openfile->current) != old_amount) {
renumber_from(openfile->current);
refresh_needed = TRUE;
}
/* Adjust the mark if it is after the cursor on the current line. */
if (openfile->mark == openfile->current &&

View File

@ -76,6 +76,9 @@ linestruct *make_new_node(linestruct *prevnode)
#endif
newnode->lineno = (prevnode) ? prevnode->lineno + 1 : 1;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
newnode->chunk_nr = (prevnode) ?
prevnode->chunk_nr + extra_chunks_in(prevnode) + 1 : 1;
newnode->has_anchor = FALSE;
#endif
@ -151,6 +154,7 @@ linestruct *copy_node(const linestruct *src)
#endif
dst->lineno = src->lineno;
#ifndef NANO_TINY
dst->chunk_nr = src->chunk_nr;
dst->has_anchor = FALSE;
#endif
@ -186,8 +190,21 @@ void renumber_from(linestruct *line)
{
ssize_t number = (line->prev == NULL) ? 0 : line->prev->lineno;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP) && line->prev == NULL) {
line->lineno = ++number;
line->chunk_nr = 1;
line = line->next;
}
#endif
while (line != NULL) {
line->lineno = ++number;
#ifndef NANO_TINY
if (ISSET(SOFTWRAP))
line->chunk_nr = line->prev->chunk_nr +
extra_chunks_in(line->prev) + 1;
#endif
line = line->next;
}
}
@ -1085,7 +1102,9 @@ void do_toggle(int flag)
signal_init();
break;
case SOFTWRAP:
if (!ISSET(SOFTWRAP))
if (ISSET(SOFTWRAP))
renumber_from(openfile->filetop);
else
openfile->firstcolumn = 0;
refresh_needed = TRUE;
break;
@ -1487,6 +1506,7 @@ void inject(char *burst, size_t count)
if (ISSET(SOFTWRAP) && ((openfile->current_y == editwinrows - 1 &&
chunk_for(xplustabs(), openfile->current) > original_row) ||
extra_chunks_in(openfile->current) != old_amount)) {
renumber_from(openfile->current);
refresh_needed = TRUE;
focusing = FALSE;
}

View File

@ -284,6 +284,10 @@ typedef struct linestruct {
/* The text of this line. */
ssize_t lineno;
/* The number of this line. */
#ifndef NANO_TINY
ssize_t chunk_nr;
/* The ordinal number of the first chunk in this line. */
#endif
struct linestruct *next;
/* Next node. */
struct linestruct *prev;

View File

@ -2954,7 +2954,16 @@ bool less_than_a_screenful(size_t was_lineno, size_t was_leftedge)
void draw_scrollbar(void)
{
int totalrows = openfile->filebot->lineno;
int lowest = ((openfile->edittop->lineno - 1) * editwinrows) / totalrows;
int first_row = openfile->edittop->lineno;
if (ISSET(SOFTWRAP)) {
totalrows = openfile->filebot->chunk_nr +
extra_chunks_in(openfile->filebot);
first_row = openfile->edittop->chunk_nr +
chunk_for(openfile->firstcolumn, openfile->edittop);
}
int lowest = ((first_row - 1) * editwinrows) / totalrows;
int highest = lowest + (editwinrows * editwinrows) / totalrows;
if (editwinrows > totalrows)
@ -3133,10 +3142,11 @@ size_t leftedge_for(size_t column, linestruct *line)
* has changed, because then the width of softwrapped chunks has changed. */
void ensure_firstcolumn_is_aligned(void)
{
if (ISSET(SOFTWRAP))
if (ISSET(SOFTWRAP)) {
openfile->firstcolumn = leftedge_for(openfile->firstcolumn,
openfile->edittop);
else
renumber_from(openfile->filetop);
} else
openfile->firstcolumn = 0;
/* If smooth scrolling is on, make sure the viewport doesn't center. */