painting: make use of the multidata of the preceding line

When painting a line, the multidata of the line /before/ it is valid
in most cases: it was determined just a moment ago.  And it tells us
all we need to know: whether there is an unpaired start match before
the current line or not.

The only exception is when painting the first line of the screen:
the multidata of the line before it might be stale.  So for the
first screen line we will always have to do some backtracking.
But that is left for later.

This fixes https://savannah.gnu.org/bugs/?50121.
master
Benno Schulenberg 2017-01-23 14:41:25 +01:00
parent fb8fdcaa0a
commit b3bcc8eeac
2 changed files with 22 additions and 4 deletions

View File

@ -370,6 +370,9 @@ void reset_multis(filestruct *fileptr, bool force)
} }
} }
refresh_needed = TRUE;
return;
/* If we got here, things have changed. */ /* If we got here, things have changed. */
reset_multis_for_id(fileptr, ink->id); reset_multis_for_id(fileptr, ink->id);

View File

@ -2420,6 +2420,22 @@ void edit_draw(filestruct *fileptr, const char *converted,
regmatch_t startmatch, endmatch; regmatch_t startmatch, endmatch;
/* The match positions of the start and end regexes. */ /* The match positions of the start and end regexes. */
/* First check the multidata of the preceding line -- it tells
* us about the situation so far, and thus what to do here. */
if (start_line != NULL && start_line->multidata != NULL) {
if (start_line->multidata[varnish->id] == CWHOLELINE ||
start_line->multidata[varnish->id] == CENDAFTER) {
fileptr->multidata[varnish->id] = CNONE;
goto seek_an_end;
}
if (start_line->multidata[varnish->id] == CNONE ||
start_line->multidata[varnish->id] == CBEGINBEFORE ||
start_line->multidata[varnish->id] == CSTARTENDHERE) {
fileptr->multidata[varnish->id] = CNONE;
goto step_two;
}
}
/* First see if the multidata was maybe already calculated. */ /* First see if the multidata was maybe already calculated. */
if (fileptr->multidata[varnish->id] == CNONE) if (fileptr->multidata[varnish->id] == CNONE)
goto tail_of_loop; goto tail_of_loop;
@ -2440,10 +2456,8 @@ void edit_draw(filestruct *fileptr, const char *converted,
/* There is no precalculated multidata, or it is CENDAFTER or /* There is no precalculated multidata, or it is CENDAFTER or
* CSTARTENDHERE. In all cases, find out what to paint. */ * CSTARTENDHERE. In all cases, find out what to paint. */
/* When the multidata is unitialized, assume CNONE until one /* Assume nothing gets painted until proven otherwise below. */
* of the steps below concludes otherwise. */ fileptr->multidata[varnish->id] = CNONE;
if (fileptr->multidata[varnish->id] == -1)
fileptr->multidata[varnish->id] = CNONE;
/* First check if the beginning of the line is colored by a /* First check if the beginning of the line is colored by a
* start on an earlier line, and an end on this line or later. * start on an earlier line, and an end on this line or later.
@ -2500,6 +2514,7 @@ void edit_draw(filestruct *fileptr, const char *converted,
} }
/* Indeed, there is a start without an end on that line. */ /* Indeed, there is a start without an end on that line. */
seek_an_end:
/* We've already checked that there is no end between the start /* We've already checked that there is no end between the start
* and the current line. But is there an end after the start * and the current line. But is there an end after the start
* at all? We don't paint unterminated starts. */ * at all? We don't paint unterminated starts. */