for (i = 0; i < openfile->syntax->nmultis; i++) {
for (oof = fileptr->next; oof != NULL; oof = oof->next) {
- if (oof->multiswatching == NULL)
+ if (oof->multidata == NULL)
continue;
- if (oof->multiswatching[i] == FALSE)
- oof->multiswatching[i] = TRUE;
+ if (oof->multidata[i] != 0)
+ oof->multidata[i] = -1;
else
break;
}
for (oof = fileptr->prev; oof != NULL; oof = oof->prev) {
- if (oof->multiswatching == NULL)
+ if (oof->multidata == NULL)
continue;
- if (oof->multiswatching[i] == FALSE)
- oof->multiswatching[i] = TRUE;
+ if (oof->multidata[i] == 0)
+ oof->multidata[i] = -1;
else
break;
}
- fileptr->multiswatching[i] = TRUE;
+ fileptr->multidata[i] = -1;
}
}
#endif /* ENABLE_COLOR */
#endif
#ifdef ENABLE_COLOR
- fileptr->multiswatching = NULL;
+ fileptr->multidata = NULL;
#endif
if (*first_line_ins) {
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
#ifdef ENABLE_COLOR
- newnode->multiswatching = NULL;
+ newnode->multidata = NULL;
#endif
return newnode;
dst->prev = src->prev;
dst->lineno = src->lineno;
#ifdef ENABLE_COLOR
- dst->multiswatching = NULL;
+ dst->multidata = NULL;
#endif
return dst;
free(fileptr->data);
#ifdef ENABLE_COLOR
- if (fileptr->multiswatching)
- free(fileptr->multiswatching);
+ if (fileptr->multidata)
+ free(fileptr->multidata);
#endif
free(fileptr);
openfile->filebot = openfile->fileage;
#ifdef ENABLE_COLOR
- openfile->fileage->multiswatching = NULL;
+ openfile->fileage->multidata = NULL;
#endif
/* Restore the current line and cursor position. If the mark begins
iso_me_harder_funcmap(s->scfunc);
#ifdef ENABLE_COLOR
if (!f->viewok && openfile->syntax != NULL
- && openfile->current->multiswatching && openfile->syntax->nmultis > 0) {
+ && openfile->current->multidata && openfile->syntax->nmultis > 0) {
reset_multis(openfile->current);
edit_refresh();
}
}
#endif /* !DISABLE_MOUSE */
+#ifdef ENABLE_COLOR
+/* Precalculate the multi-line start and end regex info so we can speed up
+ rendering (with any hope at all...) */
+void precalc_multicolorinfo(void)
+{
+ if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
+ const colortype *tmpcolor = openfile->colorstrings;
+ regmatch_t startmatch, endmatch;
+ filestruct *fileptr, *endptr;
+ time_t last_check = time(NULL), cur_check = 0;
+
+ /* Let us get keypresses to see if the user is trying to
+ start editing. We may want to throw up a statusbar
+ message before starting this later if it takes
+ too long to do this routine. For now silently
+ abort if they hit a key */
+ nodelay(edit, FALSE);
+
+ for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
+
+ /* If it's not a multi-line regex, amscray */
+ if (tmpcolor->end == NULL)
+ continue;
+
+ for (fileptr = openfile->fileage; fileptr != NULL; fileptr = fileptr->next) {
+ int startx = 0;
+
+ if (!fileptr->multidata)
+ fileptr->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
+
+ if ((cur_check = time(NULL)) - last_check > 1) {
+ last_check = cur_check;
+ if (wgetch(edit) != ERR)
+ goto precalc_cleanup;
+ }
+
+ fileptr->multidata[tmpcolor->id] = CNONE;
+ while (regexec(tmpcolor->start, &fileptr->data[startx], 1, &startmatch, 0) == 0) {
+ /* Look for end and start marking how many lines are encompassed
+ whcih should speed up rendering later */
+ startx += startmatch.rm_eo;
+
+ /* Look on this line first for end */
+ if (regexec(tmpcolor->end, &fileptr->data[startx], 1, &endmatch, 0) == 0) {
+ startx += endmatch.rm_eo;
+ fileptr->multidata[tmpcolor->id] |= CSTARTENDHERE;
+ continue;
+ }
+
+ /* Nice, we didn't find the end regex on this line. Let's start looking for it */
+ for (endptr = fileptr->next; endptr != NULL; endptr = endptr->next) {
+
+ /* Check for keyboard input again */
+ if ((cur_check = time(NULL)) - last_check > 1) {
+ last_check = cur_check;
+ if (wgetch(edit) != ERR)
+ goto precalc_cleanup;
+ }
+ if (regexec(tmpcolor->end, &endptr->data[startx], 1, &endmatch, 0) == 0)
+ break;
+ }
+
+ if (endptr == NULL)
+ break;
+
+ /* We found it, we found it, la la la la la. Mark all the
+ lines in between and the ends properly */
+ fileptr->multidata[tmpcolor->id] |= CENDAFTER;
+ for (fileptr = fileptr->next; fileptr != endptr; fileptr = fileptr->next) {
+ fileptr->multidata[tmpcolor->id] = CWHOLELINE;
+ }
+ endptr->multidata[tmpcolor->id] |= CBEGINBEFORE;
+ }
+ }
+ }
+ }
+precalc_cleanup:
+ nodelay(edit, FALSE);
+}
+#endif /* ENABLE_COLOR */
+
/* The user typed output_len multibyte characters. Add them to the edit
* buffer, filtering out all ASCII control characters if allow_cntrls is
* TRUE. */
fprintf(stderr, "Main: top and bottom win\n");
#endif
+#ifdef ENABLE_COLOR
+ if (openfile->syntax && openfile->syntax->nmultis > 0)
+ precalc_multicolorinfo();
+#endif
+
if (startline > 1 || startcol > 1)
do_gotolinecolumn(startline, startcol, FALSE, FALSE, FALSE,
FALSE);
struct syntaxtype *next;
/* Next syntax. */
} syntaxtype;
+
+#define CNONE (1<<0)
+ /* Yay, regex doesn't apply to this line at all! */
+#define CBEGINBEFORE (1<<1)
+ /* regex starts on an earlier line, ends on this one */
+#define CENDAFTER (1<<2)
+ /* regex sraers on this line and ends on a later one */
+#define CWHOLELINE (1<<3)
+ /* whole line engulfed by the regex start < me, end > me */
+#define CSTARTENDHERE (1<<4)
+ /* regex starts and ends within this line */
+#define CWTF (1<<5)
+ /* Something else */
+
#endif /* ENABLE_COLOR */
struct filestruct *prev;
/* Previous node. */
#ifdef ENABLE_COLOR
- bool *multiswatching; /* Array of which multi-line regexes apply to this line */
+ short *multidata; /* Array of which multi-line regexes apply to this line */
#endif
} filestruct;
const colortype *tmpcolor = openfile->colorstrings;
/* Set up multi-line color data for this line if it's not yet calculated */
- if (fileptr->multiswatching == NULL && openfile->syntax
+ if (fileptr->multidata == NULL && openfile->syntax
&& openfile->syntax->nmultis > 0) {
int i;
- fileptr->multiswatching = nmalloc(openfile->syntax->nmultis * sizeof(bool));
- for (i = 0; i < openfile->syntax->nmultis; i++)
- fileptr->multiswatching[i] = TRUE; /* Assue this applies until we know otherwise */
+ fileptr->multidata = nmalloc(openfile->syntax->nmultis * sizeof(short));
+ for (i = 0; i < openfile->syntax->nmultis; i++)
+ fileptr->multidata[i] = -1; /* Assue this applies until we know otherwise */
}
for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
int x_start;
}
k = startmatch.rm_eo;
}
- } else if (fileptr->multiswatching != NULL && fileptr->multiswatching[tmpcolor->id] == TRUE) {
+ } else if (fileptr->multidata != NULL && fileptr->multidata[tmpcolor->id] != 0) {
/* This is a multi-line regex. There are two steps.
* First, we have to see if the beginning of the line is
* colored by a start on an earlier line, and an end on
regoff_t start_col;
/* Where it starts in that line. */
const filestruct *end_line;
-
- fileptr->multiswatching[tmpcolor->id] = FALSE; /* until we find out otherwise */
+ short md = fileptr->multidata[tmpcolor->id];
+
+ if (md == -1)
+ fileptr->multidata[tmpcolor->id] = 0; /* until we find out otherwise */
+ else if (md == CNONE)
+ continue;
+ else if (md == CWHOLELINE) {
+ mvwaddnstr(edit, line, 0, converted, -1);
+ continue;
+ }
while (start_line != NULL && regexec(tmpcolor->start,
start_line->data, 1, &startmatch, 0) ==
* expanded location of the end of the match minus
* the expanded location of the beginning of the
* page. */
- if (end_line != fileptr)
+ if (end_line != fileptr) {
paintlen = -1;
- else
+ fileptr->multidata[tmpcolor->id] = CWHOLELINE;
+ } else {
paintlen = actual_x(converted,
strnlenpt(fileptr->data,
endmatch.rm_eo) - start);
-
+ fileptr->multidata[tmpcolor->id] = CBEGINBEFORE;
+ }
mvwaddnstr(edit, line, 0, converted, paintlen);
- fileptr->multiswatching[tmpcolor->id] = TRUE;
step_two:
/* Second step, we look for starts on this line. */
start_col = 0;
mvwaddnstr(edit, line, x_start,
converted + index, paintlen);
if (paintlen > 0)
- fileptr->multiswatching[tmpcolor->id] = TRUE;
+ fileptr->multidata[tmpcolor->id] = CSTARTENDHERE;
}
} else {
/* We painted to the end of the line, so
* don't bother checking any more
* starts. */
- fileptr->multiswatching[tmpcolor->id] = TRUE;
+ fileptr->multidata[tmpcolor->id] = CENDAFTER;
break;
}
}