nano

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

commit 49d8b99e4f174b40bc05f42bf7d7d6a919df302b
parent bb8193242220ad28d191244e1dd6f6ae862b0cdf
Author: Benno Schulenberg <bensberg@telfort.nl>
Date:   Wed, 21 Apr 2021 16:27:36 +0200

softwrap: avoid time-consuming computations, to burden large files less

Whenever softwrap was toggled on or line numbers were toggled on/off or
the window was resized, the extra rows per line needed to be recomputed
for ALL the lines.  For large files with many long lines this was too
costly.

(This change causes the indicator to have an incorrect size when there
are many softwrapped chunks onscreen, but that will be addressed later.)

This fixes https://savannah.gnu.org/bugs/?60429.

Problem existed since version 5.0, since the indicator was introduced.

Diffstat:
Msrc/cut.c | 21++-------------------
Msrc/definitions.h | 4----
Msrc/files.c | 3+--
Msrc/nano.c | 24++++--------------------
Msrc/prototypes.h | 1-
Msrc/search.c | 4----
Msrc/text.c | 25-------------------------
Msrc/utils.c | 3---
Msrc/winio.c | 10----------
9 files changed, 7 insertions(+), 88 deletions(-)

diff --git a/src/cut.c b/src/cut.c @@ -34,7 +34,7 @@ void do_deletion(undo_type action) int charlen = char_length(openfile->current->data + openfile->current_x); size_t line_len = strlen(openfile->current->data + openfile->current_x); #ifndef NANO_TINY - size_t old_amount = openfile->current->extrarows; + size_t old_amount = extra_chunks_in(openfile->current); /* If the type of action changed or the cursor moved to a different * line, create a new undo item, otherwise update the existing item. */ @@ -52,8 +52,7 @@ void do_deletion(undo_type action) /* When softwrapping, recompute the number of chunks in the line, * and schedule a refresh if the number changed. */ if (ISSET(SOFTWRAP)) { - openfile->current->extrarows = extra_chunks_in(openfile->current); - if (openfile->current->extrarows != old_amount) + if (extra_chunks_in(openfile->current) != old_amount) refresh_needed = TRUE; } @@ -94,10 +93,6 @@ void do_deletion(undo_type action) unlink_node(joining); -#ifndef NANO_TINY - if (ISSET(SOFTWRAP)) - openfile->current->extrarows = extra_chunks_in(openfile->current); -#endif /* Two lines were joined, so do a renumbering and refresh the screen. */ renumber_from(openfile->current); refresh_needed = TRUE; @@ -336,9 +331,6 @@ void extract_segment(linestruct *top, size_t top_x, linestruct *bot, size_t bot_ #ifndef NANO_TINY openfile->current->has_anchor = was_anchored; - if (ISSET(SOFTWRAP)) - openfile->current->extrarows = extra_chunks_in(openfile->current); - if (post_marked || same_line) openfile->mark = openfile->current; if (post_marked) @@ -391,10 +383,6 @@ void ingraft_buffer(linestruct *topline) } if (topline != botline) { -#ifndef NANO_TINY - /* First compute the softwrapped chunks for each line in the graft. */ - compute_the_extra_rows_per_line_from(topline); -#endif /* When inserting at end-of-buffer, update the relevant pointer. */ if (line->next == NULL) openfile->filebot = botline; @@ -427,11 +415,6 @@ void ingraft_buffer(linestruct *topline) openfile->mark_x += length - xpos; } else if (mark_follows) openfile->mark_x += extralen; - - if (ISSET(SOFTWRAP)) { - line->extrarows = extra_chunks_in(line); - openfile->current->extrarows = extra_chunks_in(openfile->current); - } #endif delete_node(topline); diff --git a/src/definitions.h b/src/definitions.h @@ -438,10 +438,6 @@ typedef struct linestruct { /* The text of this line. */ ssize_t lineno; /* The number of this line. */ -#ifndef NANO_TINY - ssize_t extrarows; - /* The extra rows that this line occupies when softwrapping. */ -#endif struct linestruct *next; /* Next node. */ struct linestruct *prev; diff --git a/src/files.c b/src/files.c @@ -545,9 +545,8 @@ void redecorate_after_switch(void) #ifndef NANO_TINY /* While in a different buffer, the effective width of the screen may - * have changed, so make sure that the softwrapped chunks per line and + * have changed, so make sure that * the starting column for the first row get corresponding values. */ - compute_the_extra_rows_per_line_from(openfile->filetop); ensure_firstcolumn_is_aligned(); #endif diff --git a/src/nano.c b/src/nano.c @@ -76,7 +76,6 @@ linestruct *make_new_node(linestruct *prevnode) #endif newnode->lineno = (prevnode) ? prevnode->lineno + 1 : 1; #ifndef NANO_TINY - newnode->extrarows = -2; /* Bad value, to make it easier to find bugs. */ newnode->has_anchor = FALSE; #endif @@ -152,7 +151,6 @@ linestruct *copy_node(const linestruct *src) #endif dst->lineno = src->lineno; #ifndef NANO_TINY - dst->extrarows = src->extrarows; dst->has_anchor = FALSE; #endif @@ -1006,14 +1004,6 @@ void handle_sigwinch(int signal) the_window_resized = TRUE; } -/* Compute and store how many extra rows each line needs when softwrapping. */ -void compute_the_extra_rows_per_line_from(linestruct *fromline) -{ - if (ISSET(SOFTWRAP)) - for (linestruct *line = fromline; line != NULL; line = line->next) - line->extrarows = extra_chunks_in(line); -} - /* Reinitialize and redraw the screen completely. */ void regenerate_screen(void) { @@ -1056,7 +1046,6 @@ void regenerate_screen(void) /* If we have an open buffer, redraw the contents of the subwindows. */ if (openfile) { - compute_the_extra_rows_per_line_from(openfile->filetop); ensure_firstcolumn_is_aligned(); draw_all_subwindows(); } @@ -1082,9 +1071,7 @@ void do_toggle(int flag) break; #endif case SOFTWRAP: - if (ISSET(SOFTWRAP)) - compute_the_extra_rows_per_line_from(openfile->filetop); - else + if (!ISSET(SOFTWRAP)) openfile->firstcolumn = 0; refresh_needed = TRUE; break; @@ -1246,9 +1233,7 @@ void confirm_margin(void) editwincols = COLS - margin - thebar; #ifndef NANO_TINY - /* Recompute the softwrapped chunks for each line in the buffer, - * and ensure a proper starting column for the first screen row. */ - compute_the_extra_rows_per_line_from(openfile->filetop); + /* Ensure a proper starting column for the first screen row. */ ensure_firstcolumn_is_aligned(); focusing = keep_focus; #endif @@ -1414,7 +1399,7 @@ void inject(char *burst, size_t count) linestruct *thisline = openfile->current; size_t datalen = strlen(thisline->data); #ifndef NANO_TINY - size_t old_amount = openfile->current->extrarows; + size_t old_amount = extra_chunks_in(openfile->current); size_t original_row = 0; if (ISSET(SOFTWRAP)) { @@ -1484,8 +1469,7 @@ void inject(char *burst, size_t count) * or we were on the last row of the edit window and moved to a new chunk, * we need a full refresh. */ if (ISSET(SOFTWRAP)) { - openfile->current->extrarows = extra_chunks_in(openfile->current); - if (openfile->current->extrarows != old_amount || + if (extra_chunks_in(openfile->current) != old_amount || (openfile->current_y == editwinrows - 1 && chunk_for(xplustabs(), openfile->current) > original_row)) { refresh_needed = TRUE; diff --git a/src/prototypes.h b/src/prototypes.h @@ -409,7 +409,6 @@ void block_sigwinch(bool blockit); #endif #ifndef NANO_TINY void handle_sigwinch(int signal); -void compute_the_extra_rows_per_line_from(linestruct *fromline); void regenerate_screen(void); void do_toggle(int flag); #endif diff --git a/src/search.c b/src/search.c @@ -665,10 +665,6 @@ ssize_t do_replace_loop(const char *needle, bool whole_word_only, free(openfile->current->data); openfile->current->data = copy; -#ifndef NANO_TINY - if (ISSET(SOFTWRAP)) - openfile->current->extrarows = extra_chunks_in(openfile->current); -#endif set_modified(); as_an_at = TRUE; numreplaced++; diff --git a/src/text.c b/src/text.c @@ -103,9 +103,6 @@ void indent_a_line(linestruct *line, char *indentation) openfile->totsize += indent_len; - if (ISSET(SOFTWRAP)) - line->extrarows = extra_chunks_in(line); - /* Compensate for the change in the current line. */ if (line == openfile->mark && openfile->mark_x > 0) openfile->mark_x += indent_len; @@ -234,9 +231,6 @@ void unindent_a_line(linestruct *line, size_t indent_len) openfile->totsize -= indent_len; - if (ISSET(SOFTWRAP)) - line->extrarows = extra_chunks_in(line); - /* Adjust the positions of mark and cursor, when they are affected. */ compensate_leftward(line, indent_len); } @@ -426,10 +420,6 @@ void do_comment(void) * store undo data when a line changed. */ for (line = top; line != bot->next; line = line->next) { if (comment_line(action, line, comment_seq)) { -#ifndef NANO_TINY - if (ISSET(SOFTWRAP)) - line->extrarows = extra_chunks_in(line); -#endif update_multiline_undo(line->lineno, ""); } } @@ -573,8 +563,6 @@ void do_undo(void) break; } line->data[u->tail_x] = '\0'; - if (ISSET(SOFTWRAP)) - line->extrarows = extra_chunks_in(line); intruder = make_new_node(line); intruder->data = copy_of(u->strdata); splice_node(line, intruder); @@ -676,9 +664,6 @@ void do_undo(void) openfile->mark = NULL; openfile->placewewant = xplustabs(); - if (ISSET(SOFTWRAP)) - openfile->current->extrarows = extra_chunks_in(openfile->current); - openfile->totsize = u->wassize; /* When at the point where the file was last saved, unset "Modified". */ @@ -725,8 +710,6 @@ void do_redo(void) case ENTER: redidmsg = _("line break"); line->data[u->head_x] = '\0'; - if (ISSET(SOFTWRAP)) - line->extrarows = extra_chunks_in(line); intruder = make_new_node(line); intruder->data = copy_of(u->strdata); splice_node(line, intruder); @@ -841,9 +824,6 @@ void do_redo(void) openfile->mark = NULL; openfile->placewewant = xplustabs(); - if (ISSET(SOFTWRAP)) - openfile->current->extrarows = extra_chunks_in(openfile->current); - openfile->totsize = u->newsize; /* When at the point where the file was last saved, unset "Modified". */ @@ -907,11 +887,6 @@ void do_enter(void) openfile->mark = newnode; openfile->mark_x += extra - openfile->current_x; } - - if (ISSET(SOFTWRAP)) { - openfile->current->extrarows = extra_chunks_in(openfile->current); - newnode->extrarows = extra_chunks_in(newnode); - } #endif /* Insert the newly created line after the current one and renumber. */ diff --git a/src/utils.c b/src/utils.c @@ -429,9 +429,6 @@ void new_magicline(void) openfile->filebot->next = make_new_node(openfile->filebot); openfile->filebot->next->data = copy_of(""); openfile->filebot = openfile->filebot->next; -#ifndef NANO_TINY - openfile->filebot->extrarows = 0; -#endif openfile->totsize++; } diff --git a/src/winio.c b/src/winio.c @@ -3057,16 +3057,6 @@ void draw_scrollbar(void) { int totalrows = openfile->filebot->lineno; int first_row = openfile->edittop->lineno; - - if (ISSET(SOFTWRAP)) { - for (linestruct *ln = openfile->filetop; ln != openfile->edittop; ln = ln->next) - first_row += ln->extrarows; - first_row += chunk_for(openfile->firstcolumn, openfile->edittop); - - for (linestruct *ln = openfile->filetop; ln != NULL; ln = ln->next) - totalrows += ln->extrarows; - } - int lowest = ((first_row - 1) * editwinrows) / totalrows; int highest = lowest + (editwinrows * editwinrows) / totalrows;