From 49d8b99e4f174b40bc05f42bf7d7d6a919df302b Mon Sep 17 00:00:00 2001 From: Benno Schulenberg Date: Wed, 21 Apr 2021 16:27:36 +0200 Subject: [PATCH] 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. --- src/cut.c | 21 ++------------------- src/definitions.h | 4 ---- src/files.c | 3 +-- src/nano.c | 24 ++++-------------------- src/prototypes.h | 1 - src/search.c | 4 ---- src/text.c | 25 ------------------------- src/utils.c | 3 --- src/winio.c | 10 ---------- 9 files changed, 7 insertions(+), 88 deletions(-) diff --git a/src/cut.c b/src/cut.c index 722ba82e..a51f2156 100644 --- 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 index b0037bb0..a1dff3ca 100644 --- 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 index 629fe13e..0ddd03cf 100644 --- 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 index 4c644c3c..92319dc6 100644 --- 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 index 4523c398..a697b43f 100644 --- 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 index a3a94bb4..2a5e11c5 100644 --- 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 index b8cc00d3..cfb75a1f 100644 --- 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 index 768d7ed0..09abe336 100644 --- 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 index 32b6fa8c..e4b4867a 100644 --- 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;