painting: colorize text also after an unterminated start match
This does not waste time looking for an end match, which is especially wasteful when there is none. Also, it makes the coloring behavior more consistent: any start match will cause coloring of the subsequent text, no matter whether the user is in the middle of the file or near the end.
Этот коммит содержится в:
родитель
18ba7f60c1
Коммит
51bd04b541
16
src/color.c
16
src/color.c
@ -261,7 +261,7 @@ void check_the_multis(linestruct *line)
|
||||
if (line->multidata[ink->id] == NOTHING) {
|
||||
if (!astart)
|
||||
continue;
|
||||
} else if (line->multidata[ink->id] & (WHOLELINE|WOULDBE)) {
|
||||
} else if (line->multidata[ink->id] == WHOLELINE) {
|
||||
/* Ensure that a detected start match is not actually an end match. */
|
||||
if (!anend && (!astart || regexec(ink->end, line->data, 1,
|
||||
&endmatch, 0) != 0))
|
||||
@ -350,21 +350,17 @@ void precalc_multicolorinfo(void)
|
||||
1, &endmatch, 0) != 0)
|
||||
tailline = tailline->next;
|
||||
|
||||
/* When there is no end match, mark relevant lines as such. */
|
||||
if (tailline == NULL) {
|
||||
for (; line->next != NULL; line = line->next)
|
||||
line->multidata[ink->id] = WOULDBE;
|
||||
line->multidata[ink->id] = WOULDBE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We found it, we found it, la lala lala. Mark the lines. */
|
||||
line->multidata[ink->id] = STARTSHERE;
|
||||
|
||||
// Note that this also advances the line in the main loop.
|
||||
for (line = line->next; line != tailline; line = line->next)
|
||||
line->multidata[ink->id] = WHOLELINE;
|
||||
|
||||
if (tailline == NULL) {
|
||||
line = openfile->filebot;
|
||||
break;
|
||||
}
|
||||
|
||||
tailline->multidata[ink->id] = ENDSHERE;
|
||||
|
||||
/* Look for a possible new start after the end match. */
|
||||
|
@ -170,8 +170,6 @@
|
||||
/* The start regex matches on an earlier line, the end regex on this one. */
|
||||
#define JUSTONTHIS (1<<5)
|
||||
/* Both the start and end regexes match within this line. */
|
||||
#define WOULDBE (1<<6)
|
||||
/* An unpaired start match is on or before this line. */
|
||||
#endif
|
||||
|
||||
/* Basic control codes. */
|
||||
|
53
src/winio.c
53
src/winio.c
@ -2543,8 +2543,6 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
|
||||
/* The match positions of a single-line regex. */
|
||||
const linestruct *start_line = line->prev;
|
||||
/* The first line before line that matches 'start'. */
|
||||
linestruct *end_line = line;
|
||||
/* The line that matches 'end'. */
|
||||
regmatch_t startmatch, endmatch;
|
||||
/* The match positions of the start and end regexes. */
|
||||
|
||||
@ -2602,8 +2600,7 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
|
||||
* it tells us about the situation so far, and thus what to do here. */
|
||||
if (row > 0 && start_line != NULL && start_line->multidata != NULL) {
|
||||
if (start_line->multidata[varnish->id] == WHOLELINE ||
|
||||
start_line->multidata[varnish->id] == STARTSHERE ||
|
||||
start_line->multidata[varnish->id] == WOULDBE)
|
||||
start_line->multidata[varnish->id] == STARTSHERE)
|
||||
goto seek_an_end;
|
||||
if (start_line->multidata[varnish->id] == NOTHING ||
|
||||
start_line->multidata[varnish->id] == ENDSHERE ||
|
||||
@ -2660,31 +2657,8 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
|
||||
}
|
||||
|
||||
seek_an_end:
|
||||
/* We've already checked that there is no end between the start
|
||||
* and the current line. But is there an end after the start
|
||||
* at all? Because we don't paint unterminated starts. */
|
||||
if (row == 0) {
|
||||
while (end_line != NULL && regexec(varnish->end, end_line->data,
|
||||
1, &endmatch, 0) == REG_NOMATCH)
|
||||
end_line = end_line->next;
|
||||
} else if (regexec(varnish->end, line->data, 1, &endmatch, 0) != 0)
|
||||
end_line = line->next;
|
||||
|
||||
/* If there is no end, there is nothing to paint. */
|
||||
if (end_line == NULL) {
|
||||
line->multidata[varnish->id] = WOULDBE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If it was already determined that there is no end... */
|
||||
if (end_line != line && line->prev == start_line && line->prev->multidata &&
|
||||
line->prev->multidata[varnish->id] == WOULDBE) {
|
||||
line->multidata[varnish->id] = WOULDBE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If the end is on a later line, paint whole line, and be done. */
|
||||
if (end_line != line) {
|
||||
/* If there is no end on this line, paint whole line, and be done. */
|
||||
if (regexec(varnish->end, line->data, 1, &endmatch, 0) == REG_NOMATCH) {
|
||||
wattron(midwin, varnish->attributes);
|
||||
mvwaddnstr(midwin, row, margin, converted, -1);
|
||||
wattroff(midwin, varnish->attributes);
|
||||
@ -2746,33 +2720,12 @@ void draw_row(int row, const char *converted, linestruct *line, size_t from_col)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* There is no end on this line. But maybe on later lines? */
|
||||
end_line = line->next;
|
||||
|
||||
while (end_line && regexec(varnish->end, end_line->data,
|
||||
0, NULL, 0) == REG_NOMATCH)
|
||||
end_line = end_line->next;
|
||||
|
||||
/* If there is no end, we're done with this regex. */
|
||||
if (end_line == NULL) {
|
||||
line->multidata[varnish->id] = WOULDBE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Paint the rest of the line, and we're done. */
|
||||
wattron(midwin, varnish->attributes);
|
||||
mvwaddnstr(midwin, row, margin + start_col, thetext, -1);
|
||||
wattroff(midwin, varnish->attributes);
|
||||
|
||||
line->multidata[varnish->id] = STARTSHERE;
|
||||
|
||||
if (end_line->multidata == NULL) {
|
||||
end_line->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
|
||||
for (short item = 0; item < openfile->syntax->nmultis; item++)
|
||||
end_line->multidata[item] = 0;
|
||||
}
|
||||
end_line->multidata[varnish->id] = ENDSHERE;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user