2009-02-02 Chris Allegretta <chrisa@asty.org>
* New color precalculation code for mult-line regexes. New function precalc_multicolorinfo(), new structure multidata for keeping track of where regexes start/stop. More performance improvements forthcoming. git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4362 35c25a1d-7b9e-4130-9fde-d3aeb78583b8master
parent
ecc245ccca
commit
364763f4d1
14
src/color.c
14
src/color.c
|
@ -265,22 +265,22 @@ void reset_multis(filestruct *fileptr)
|
|||
|
||||
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 */
|
||||
|
|
|
@ -312,7 +312,7 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
|
|||
#endif
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
fileptr->multiswatching = NULL;
|
||||
fileptr->multidata = NULL;
|
||||
#endif
|
||||
|
||||
if (*first_line_ins) {
|
||||
|
|
98
src/nano.c
98
src/nano.c
|
@ -68,7 +68,7 @@ filestruct *make_new_node(filestruct *prevnode)
|
|||
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
newnode->multiswatching = NULL;
|
||||
newnode->multidata = NULL;
|
||||
#endif
|
||||
|
||||
return newnode;
|
||||
|
@ -88,7 +88,7 @@ filestruct *copy_node(const filestruct *src)
|
|||
dst->prev = src->prev;
|
||||
dst->lineno = src->lineno;
|
||||
#ifdef ENABLE_COLOR
|
||||
dst->multiswatching = NULL;
|
||||
dst->multidata = NULL;
|
||||
#endif
|
||||
|
||||
return dst;
|
||||
|
@ -127,8 +127,8 @@ void delete_node(filestruct *fileptr)
|
|||
free(fileptr->data);
|
||||
|
||||
#ifdef ENABLE_COLOR
|
||||
if (fileptr->multiswatching)
|
||||
free(fileptr->multiswatching);
|
||||
if (fileptr->multidata)
|
||||
free(fileptr->multidata);
|
||||
#endif
|
||||
|
||||
free(fileptr);
|
||||
|
@ -369,7 +369,7 @@ void move_to_filestruct(filestruct **file_top, filestruct **file_bot,
|
|||
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
|
||||
|
@ -1596,7 +1596,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
|
|||
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();
|
||||
}
|
||||
|
@ -1675,6 +1675,87 @@ int do_mouse(void)
|
|||
}
|
||||
#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. */
|
||||
|
@ -2373,6 +2454,11 @@ int main(int argc, char **argv)
|
|||
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);
|
||||
|
|
16
src/nano.h
16
src/nano.h
|
@ -223,6 +223,20 @@ typedef struct syntaxtype {
|
|||
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 */
|
||||
|
||||
|
||||
|
@ -237,7 +251,7 @@ typedef struct filestruct {
|
|||
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;
|
||||
|
||||
|
|
33
src/winio.c
33
src/winio.c
|
@ -2479,12 +2479,12 @@ void edit_draw(filestruct *fileptr, const char *converted, int
|
|||
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;
|
||||
|
@ -2551,7 +2551,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
|
|||
}
|
||||
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
|
||||
|
@ -2568,8 +2568,16 @@ void edit_draw(filestruct *fileptr, const char *converted, int
|
|||
regoff_t start_col;
|
||||
/* Where it starts in that line. */
|
||||
const filestruct *end_line;
|
||||
short md = fileptr->multidata[tmpcolor->id];
|
||||
|
||||
fileptr->multiswatching[tmpcolor->id] = FALSE; /* until we find out otherwise */
|
||||
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) ==
|
||||
|
@ -2633,15 +2641,16 @@ void edit_draw(filestruct *fileptr, const char *converted, int
|
|||
* 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;
|
||||
|
@ -2687,7 +2696,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
|
|||
mvwaddnstr(edit, line, x_start,
|
||||
converted + index, paintlen);
|
||||
if (paintlen > 0)
|
||||
fileptr->multiswatching[tmpcolor->id] = TRUE;
|
||||
fileptr->multidata[tmpcolor->id] = CSTARTENDHERE;
|
||||
|
||||
}
|
||||
} else {
|
||||
|
@ -2709,7 +2718,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int
|
|||
/* 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue