nano

nano with my custom patches
git clone git://bsandro.tech/nano
Log | Files | Refs | README | LICENSE

commit 6bccedb3194633f4945eb4a7a81dcf7cc201cadc
parent b33a62af8ce8fe31a2689e896c5d64ff324c44f5
Author: Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
Date:   Thu, 14 May 2020 11:53:19 +0200

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>

Diffstat:
Msrc/cut.c | 8+++++---
Msrc/nano.c | 22+++++++++++++++++++++-
Msrc/nano.h | 4++++
Msrc/winio.c | 16+++++++++++++---
4 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/src/cut.c b/src/cut.c @@ -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 && diff --git a/src/nano.c b/src/nano.c @@ -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; } diff --git a/src/nano.h b/src/nano.h @@ -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; diff --git a/src/winio.c b/src/winio.c @@ -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. */