mirror of git://git.sv.gnu.org/nano.git
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.
This commit is contained in:
parent
bb81932422
commit
49d8b99e4f
21
src/cut.c
21
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
24
src/nano.c
24
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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
|
|
25
src/text.c
25
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. */
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
10
src/winio.c
10
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue