* First pass at some caching of caching color info. Right now it's only for

multi-line regexes but this may not be enough to increase performance.



git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@4351 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2009-01-25 07:25:17 +00:00
parent 0dc26dcd09
commit d47d8cd450
9 changed files with 115 additions and 28 deletions

View File

@ -1,4 +1,6 @@
2009-01-24 Chris Allegretta <chrisa@asty.org> 2009-01-24 Chris Allegretta <chrisa@asty.org>
* First pass at some caching of caching color info. Right now it's only for
multi-line regexes but this may not be enough to increase performance.
* Add interruptability to search functions. New functions enable_nodelay and * Add interruptability to search functions. New functions enable_nodelay and
disable_nodelay and changes to the routines to handle checking for pending disable_nodelay and changes to the routines to handle checking for pending
searches. Fixes Savnnah bug 24946: Need interrrupt for search. searches. Fixes Savnnah bug 24946: Need interrrupt for search.

View File

@ -105,11 +105,13 @@ void color_init(void)
/* Update the color information based on the current filename. */ /* Update the color information based on the current filename. */
void color_update(void) void color_update(void)
{ {
const syntaxtype *tmpsyntax; syntaxtype *tmpsyntax;
syntaxtype *defsyntax = NULL;
colortype *tmpcolor, *defcolor = NULL; colortype *tmpcolor, *defcolor = NULL;
assert(openfile != NULL); assert(openfile != NULL);
openfile->syntax = NULL;
openfile->colorstrings = NULL; openfile->colorstrings = NULL;
/* If we specified a syntax override string, use it. */ /* If we specified a syntax override string, use it. */
@ -121,8 +123,10 @@ void color_update(void)
for (tmpsyntax = syntaxes; tmpsyntax != NULL; for (tmpsyntax = syntaxes; tmpsyntax != NULL;
tmpsyntax = tmpsyntax->next) { tmpsyntax = tmpsyntax->next) {
if (strcmp(tmpsyntax->desc, syntaxstr) == 0) if (strcmp(tmpsyntax->desc, syntaxstr) == 0) {
openfile->syntax = tmpsyntax;
openfile->colorstrings = tmpsyntax->color; openfile->colorstrings = tmpsyntax->color;
}
if (openfile->colorstrings != NULL) if (openfile->colorstrings != NULL)
break; break;
@ -141,6 +145,7 @@ void color_update(void)
* extensions, which we've checked for elsewhere. Skip over * extensions, which we've checked for elsewhere. Skip over
* it here, but keep track of its color regexes. */ * it here, but keep track of its color regexes. */
if (strcmp(tmpsyntax->desc, "default") == 0) { if (strcmp(tmpsyntax->desc, "default") == 0) {
defsyntax = tmpsyntax;
defcolor = tmpsyntax->color; defcolor = tmpsyntax->color;
continue; continue;
} }
@ -159,8 +164,10 @@ void color_update(void)
/* Set colorstrings if we matched the extension /* Set colorstrings if we matched the extension
* regex. */ * regex. */
if (regexec(e->ext, openfile->filename, 0, NULL, if (regexec(e->ext, openfile->filename, 0, NULL,
0) == 0) 0) == 0) {
openfile->syntax = tmpsyntax;
openfile->colorstrings = tmpsyntax->color; openfile->colorstrings = tmpsyntax->color;
}
if (openfile->colorstrings != NULL) if (openfile->colorstrings != NULL)
break; break;
@ -200,8 +207,10 @@ void color_update(void)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Comparing header regex \"%s\" to fileage \"%s\"...\n", e->ext_regex, openfile->fileage->data); fprintf(stderr, "Comparing header regex \"%s\" to fileage \"%s\"...\n", e->ext_regex, openfile->fileage->data);
#endif #endif
if (regexec(e->ext, openfile->fileage->data, 0, NULL, 0) == 0) if (regexec(e->ext, openfile->fileage->data, 0, NULL, 0) == 0) {
openfile->syntax = tmpsyntax;
openfile->colorstrings = tmpsyntax->color; openfile->colorstrings = tmpsyntax->color;
}
if (openfile->colorstrings != NULL) if (openfile->colorstrings != NULL)
break; break;
@ -221,8 +230,10 @@ void color_update(void)
/* If we didn't get a syntax based on the file extension, and we /* If we didn't get a syntax based on the file extension, and we
* have a default syntax, use it. */ * have a default syntax, use it. */
if (openfile->colorstrings == NULL && defcolor != NULL) if (openfile->colorstrings == NULL && defcolor != NULL) {
openfile->syntax = defsyntax;
openfile->colorstrings = defcolor; openfile->colorstrings = defcolor;
}
for (tmpcolor = openfile->colorstrings; tmpcolor != NULL; for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
tmpcolor = tmpcolor->next) { tmpcolor = tmpcolor->next) {
@ -243,4 +254,30 @@ void color_update(void)
} }
} }
/* Reset multi line strings around a filestruct ptr, trying to be smart about stopping */
void reset_multis(filestruct *fileptr)
{
int i;
filestruct *oof;
for (i = 0; i < openfile->syntax->nmultis; i++) {
for (oof = fileptr->next; oof != NULL; oof = oof->next) {
if (oof->multiswatching == NULL)
continue;
if (oof->multiswatching[i] == FALSE)
oof->multiswatching[i] = TRUE;
else
break;
}
for (oof = fileptr->prev; oof != NULL; oof = oof->prev) {
if (oof->multiswatching == NULL)
continue;
if (oof->multiswatching[i] == FALSE)
oof->multiswatching[i] = TRUE;
else
break;
}
fileptr->multiswatching[i] = TRUE;
}
}
#endif /* ENABLE_COLOR */ #endif /* ENABLE_COLOR */

View File

@ -311,6 +311,10 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
fileptr->data[buf_len - 1] = '\0'; fileptr->data[buf_len - 1] = '\0';
#endif #endif
#ifdef ENABLE_COLOR
fileptr->multiswatching = NULL;
#endif
if (*first_line_ins) { if (*first_line_ins) {
/* Special case: We're inserting with the cursor on the first /* Special case: We're inserting with the cursor on the first
* line. */ * line. */

View File

@ -29,7 +29,7 @@
/* Move to the first line of the file. */ /* Move to the first line of the file. */
void do_first_line(void) void do_first_line(void)
{ {
const filestruct *current_save = openfile->current; filestruct *current_save = openfile->current;
size_t pww_save = openfile->placewewant; size_t pww_save = openfile->placewewant;
openfile->current = openfile->fileage; openfile->current = openfile->fileage;
@ -42,7 +42,7 @@ void do_first_line(void)
/* Move to the last line of the file. */ /* Move to the last line of the file. */
void do_last_line(void) void do_last_line(void)
{ {
const filestruct *current_save = openfile->current; filestruct *current_save = openfile->current;
size_t pww_save = openfile->placewewant; size_t pww_save = openfile->placewewant;
openfile->current = openfile->filebot; openfile->current = openfile->filebot;
@ -130,7 +130,7 @@ void do_page_down(void)
* afterwards. */ * afterwards. */
void do_para_begin(bool allow_update) void do_para_begin(bool allow_update)
{ {
const filestruct *current_save = openfile->current; filestruct *current_save = openfile->current;
const size_t pww_save = openfile->placewewant; const size_t pww_save = openfile->placewewant;
if (openfile->current != openfile->fileage) { if (openfile->current != openfile->fileage) {
@ -162,7 +162,7 @@ void do_para_begin_void(void)
* paragraph or isn't in a paragraph. */ * paragraph or isn't in a paragraph. */
void do_para_end(bool allow_update) void do_para_end(bool allow_update)
{ {
const filestruct *const current_save = openfile->current; filestruct *const current_save = openfile->current;
const size_t pww_save = openfile->placewewant; const size_t pww_save = openfile->placewewant;
while (openfile->current != openfile->filebot && while (openfile->current != openfile->filebot &&
@ -206,7 +206,7 @@ void do_para_end_void(void)
bool do_next_word(bool allow_punct, bool allow_update) bool do_next_word(bool allow_punct, bool allow_update)
{ {
size_t pww_save = openfile->placewewant; size_t pww_save = openfile->placewewant;
const filestruct *current_save = openfile->current; filestruct *current_save = openfile->current;
char *char_mb; char *char_mb;
int char_mb_len; int char_mb_len;
bool end_line = FALSE, started_on_word = FALSE; bool end_line = FALSE, started_on_word = FALSE;
@ -301,7 +301,7 @@ void do_next_word_void(void)
bool do_prev_word(bool allow_punct, bool allow_update) bool do_prev_word(bool allow_punct, bool allow_update)
{ {
size_t pww_save = openfile->placewewant; size_t pww_save = openfile->placewewant;
const filestruct *current_save = openfile->current; filestruct *current_save = openfile->current;
char *char_mb; char *char_mb;
int char_mb_len; int char_mb_len;
bool begin_line = FALSE, started_on_word = FALSE; bool begin_line = FALSE, started_on_word = FALSE;

View File

@ -68,8 +68,7 @@ filestruct *make_new_node(filestruct *prevnode)
newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1; newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
newnode->colors = NULL; newnode->multiswatching = NULL;
newnode->colorclean = FALSE;
#endif #endif
return newnode; return newnode;
@ -88,6 +87,9 @@ filestruct *copy_node(const filestruct *src)
dst->next = src->next; dst->next = src->next;
dst->prev = src->prev; dst->prev = src->prev;
dst->lineno = src->lineno; dst->lineno = src->lineno;
#ifdef ENABLE_COLOR
dst->multiswatching = NULL;
#endif
return dst; return dst;
} }
@ -124,6 +126,11 @@ void delete_node(filestruct *fileptr)
if (fileptr->data != NULL) if (fileptr->data != NULL)
free(fileptr->data); free(fileptr->data);
#ifdef ENABLE_COLOR
if (fileptr->multiswatching)
free(fileptr->multiswatching);
#endif
free(fileptr); free(fileptr);
} }
@ -1444,6 +1451,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
kbinput = (int *)nrealloc(kbinput, kbinput_len * kbinput = (int *)nrealloc(kbinput, kbinput_len *
sizeof(int)); sizeof(int));
kbinput[kbinput_len - 1] = input; kbinput[kbinput_len - 1] = input;
} }
} }
@ -1510,9 +1518,17 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
#ifndef NANO_TINY #ifndef NANO_TINY
if (s->scfunc == DO_TOGGLE) if (s->scfunc == DO_TOGGLE)
do_toggle(s->toggle); do_toggle(s->toggle);
else else {
#endif #endif
iso_me_harder_funcmap(s->scfunc); iso_me_harder_funcmap(s->scfunc);
#ifdef ENABLE_COLOR
if (!f->viewok && openfile->syntax != NULL
&& openfile->current->multiswatching && openfile->syntax->nmultis > 0) {
reset_multis(openfile->current);
edit_refresh();
}
#endif
}
} }
*finished = TRUE; *finished = TRUE;
break; break;
@ -1551,7 +1567,7 @@ int do_mouse(void)
bool sameline; bool sameline;
/* Did they click on the line with the cursor? If they /* Did they click on the line with the cursor? If they
* clicked on the cursor, we set the mark. */ * clicked on the cursor, we set the mark. */
const filestruct *current_save = openfile->current; filestruct *current_save = openfile->current;
size_t current_x_save = openfile->current_x; size_t current_x_save = openfile->current_x;
size_t pww_save = openfile->placewewant; size_t pww_save = openfile->placewewant;
@ -1688,6 +1704,8 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
openfile->placewewant = xplustabs(); openfile->placewewant = xplustabs();
reset_multis(openfile->current);
if (do_refresh) if (do_refresh)
edit_refresh(); edit_refresh();
else else

View File

@ -196,6 +196,8 @@ typedef struct colortype {
/* The compiled end (if any) of the regex string. */ /* The compiled end (if any) of the regex string. */
struct colortype *next; struct colortype *next;
/* Next set of colors. */ /* Next set of colors. */
int id;
/* basic id for assigning to lines later */
} colortype; } colortype;
typedef struct exttype { typedef struct exttype {
@ -216,6 +218,8 @@ typedef struct syntaxtype {
/* Regexes to match on the 'header' (1st line) of the file */ /* Regexes to match on the 'header' (1st line) of the file */
colortype *color; colortype *color;
/* The colors used in this syntax. */ /* The colors used in this syntax. */
int nmultis;
/* How many multi line strings this syntax has */
struct syntaxtype *next; struct syntaxtype *next;
/* Next syntax. */ /* Next syntax. */
} syntaxtype; } syntaxtype;
@ -233,8 +237,7 @@ typedef struct filestruct {
struct filestruct *prev; struct filestruct *prev;
/* Previous node. */ /* Previous node. */
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
colortype **colors; /* Will be a series of pointers to the colorstrings we're painting */ bool *multiswatching; /* Array of which multi-line regexes apply to this line */
bool colorclean; /* Did we do something to the line which necessitates recalculating the colors */
#endif #endif
} filestruct; } filestruct;
@ -328,6 +331,8 @@ typedef struct openfilestruct {
undo_type last_action; undo_type last_action;
#endif #endif
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
syntaxtype *syntax;
/* The syntax struct for this file, if any */
colortype *colorstrings; colortype *colorstrings;
/* The current file's associated colors. */ /* The current file's associated colors. */
#endif #endif

View File

@ -542,6 +542,7 @@ void parse_syntax(char *ptr);
void parse_include(char *ptr); void parse_include(char *ptr);
short color_to_short(const char *colorname, bool *bright); short color_to_short(const char *colorname, bool *bright);
void parse_colors(char *ptr, bool icase); void parse_colors(char *ptr, bool icase);
void reset_multis(filestruct *fileptr);
#endif #endif
void parse_rcfile(FILE *rcstream void parse_rcfile(FILE *rcstream
#ifdef ENABLE_COLOR #ifdef ENABLE_COLOR
@ -759,13 +760,13 @@ void statusbar(const char *msg, ...);
void bottombars(int menu); void bottombars(int menu);
void onekey(const char *keystroke, const char *desc, size_t len); void onekey(const char *keystroke, const char *desc, size_t len);
void reset_cursor(void); void reset_cursor(void);
void edit_draw(const filestruct *fileptr, const char *converted, int void edit_draw(filestruct *fileptr, const char *converted, int
line, size_t start); line, size_t start);
void update_line(const filestruct *fileptr, size_t index); void update_line(filestruct *fileptr, size_t index);
bool need_horizontal_update(size_t pww_save); bool need_horizontal_update(size_t pww_save);
bool need_vertical_update(size_t pww_save); bool need_vertical_update(size_t pww_save);
void edit_scroll(scroll_dir direction, ssize_t nlines); void edit_scroll(scroll_dir direction, ssize_t nlines);
void edit_redraw(const filestruct *old_current, size_t pww_save); void edit_redraw(filestruct *old_current, size_t pww_save);
void edit_refresh(void); void edit_refresh(void);
void edit_update(update_type location); void edit_update(update_type location);
void total_redraw(void); void total_redraw(void);

View File

@ -107,6 +107,7 @@ static exttype *endheader = NULL;
/* End of header list */ /* End of header list */
static colortype *endcolor = NULL; static colortype *endcolor = NULL;
/* The end of the color list for the current syntax. */ /* The end of the color list for the current syntax. */
#endif #endif
/* We have an error in some part of the rcfile. Print the error message /* We have an error in some part of the rcfile. Print the error message
@ -296,6 +297,7 @@ void parse_syntax(char *ptr)
endsyntax->extensions = NULL; endsyntax->extensions = NULL;
endsyntax->headers = NULL; endsyntax->headers = NULL;
endsyntax->next = NULL; endsyntax->next = NULL;
endsyntax->nmultis = 0;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Starting a new syntax type: \"%s\"\n", nameptr); fprintf(stderr, "Starting a new syntax type: \"%s\"\n", nameptr);
@ -716,6 +718,10 @@ void parse_colors(char *ptr, bool icase)
/* Save the ending regex string if it's valid. */ /* Save the ending regex string if it's valid. */
newcolor->end_regex = (nregcomp(fgstr, icase ? REG_ICASE : newcolor->end_regex = (nregcomp(fgstr, icase ? REG_ICASE :
0)) ? mallocstrcpy(NULL, fgstr) : NULL; 0)) ? mallocstrcpy(NULL, fgstr) : NULL;
/* Lame way to skip another static counter */
newcolor->id = endsyntax->nmultis;
endsyntax->nmultis++;
} }
} }
} }

View File

@ -2450,7 +2450,7 @@ void reset_cursor(void)
* character of this page. That is, the first character of converted * character of this page. That is, the first character of converted
* corresponds to character number actual_x(fileptr->data, start) of the * corresponds to character number actual_x(fileptr->data, start) of the
* line. */ * line. */
void edit_draw(const filestruct *fileptr, const char *converted, int void edit_draw(filestruct *fileptr, const char *converted, int
line, size_t start) line, size_t start)
{ {
#if !defined(NANO_TINY) || defined(ENABLE_COLOR) #if !defined(NANO_TINY) || defined(ENABLE_COLOR)
@ -2478,6 +2478,14 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) { if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) {
const colortype *tmpcolor = openfile->colorstrings; 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
&& 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 */
}
for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) { for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
int x_start; int x_start;
/* Starting column for mvwaddnstr. Zero-based. */ /* Starting column for mvwaddnstr. Zero-based. */
@ -2543,7 +2551,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
} }
k = startmatch.rm_eo; k = startmatch.rm_eo;
} }
} else { } else if (fileptr->multiswatching != NULL && fileptr->multiswatching[tmpcolor->id] == TRUE) {
/* This is a multi-line regex. There are two steps. /* This is a multi-line regex. There are two steps.
* First, we have to see if the beginning of the line is * First, we have to see if the beginning of the line is
* colored by a start on an earlier line, and an end on * colored by a start on an earlier line, and an end on
@ -2561,6 +2569,8 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
/* Where it starts in that line. */ /* Where it starts in that line. */
const filestruct *end_line; const filestruct *end_line;
fileptr->multiswatching[tmpcolor->id] = FALSE; /* until we find out otherwise */
while (start_line != NULL && regexec(tmpcolor->start, while (start_line != NULL && regexec(tmpcolor->start,
start_line->data, 1, &startmatch, 0) == start_line->data, 1, &startmatch, 0) ==
REG_NOMATCH) { REG_NOMATCH) {
@ -2631,7 +2641,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
endmatch.rm_eo) - start); endmatch.rm_eo) - start);
mvwaddnstr(edit, line, 0, converted, paintlen); mvwaddnstr(edit, line, 0, converted, paintlen);
fileptr->multiswatching[tmpcolor->id] = TRUE;
step_two: step_two:
/* Second step, we look for starts on this line. */ /* Second step, we look for starts on this line. */
start_col = 0; start_col = 0;
@ -2676,6 +2686,9 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
mvwaddnstr(edit, line, x_start, mvwaddnstr(edit, line, x_start,
converted + index, paintlen); converted + index, paintlen);
if (paintlen > 0)
fileptr->multiswatching[tmpcolor->id] = TRUE;
} }
} else { } else {
/* There is no end on this line. But we /* There is no end on this line. But we
@ -2696,6 +2709,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
/* We painted to the end of the line, so /* We painted to the end of the line, so
* don't bother checking any more * don't bother checking any more
* starts. */ * starts. */
fileptr->multiswatching[tmpcolor->id] = TRUE;
break; break;
} }
} }
@ -2785,7 +2799,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
/* Just update one line in the edit buffer. This is basically a wrapper /* Just update one line in the edit buffer. This is basically a wrapper
* for edit_draw(). The line will be displayed starting with * for edit_draw(). The line will be displayed starting with
* fileptr->data[index]. Likely arguments are current_x or zero. */ * fileptr->data[index]. Likely arguments are current_x or zero. */
void update_line(const filestruct *fileptr, size_t index) void update_line(filestruct *fileptr, size_t index)
{ {
int line; int line;
/* The line in the edit window that we want to update. */ /* The line in the edit window that we want to update. */
@ -2858,7 +2872,7 @@ bool need_vertical_update(size_t pww_save)
void edit_scroll(scroll_dir direction, ssize_t nlines) void edit_scroll(scroll_dir direction, ssize_t nlines)
{ {
bool do_redraw = need_vertical_update(0); bool do_redraw = need_vertical_update(0);
const filestruct *foo; filestruct *foo;
ssize_t i; ssize_t i;
/* Don't bother scrolling less than one line. */ /* Don't bother scrolling less than one line. */
@ -2953,11 +2967,11 @@ void edit_scroll(scroll_dir direction, ssize_t nlines)
/* Update any lines between old_current and current that need to be /* Update any lines between old_current and current that need to be
* updated. Use this if we've moved without changing any text. */ * updated. Use this if we've moved without changing any text. */
void edit_redraw(const filestruct *old_current, size_t pww_save) void edit_redraw(filestruct *old_current, size_t pww_save)
{ {
bool do_redraw = need_vertical_update(0) || bool do_redraw = need_vertical_update(0) ||
need_vertical_update(pww_save); need_vertical_update(pww_save);
const filestruct *foo = NULL; filestruct *foo = NULL;
/* If either old_current or current is offscreen, scroll the edit /* If either old_current or current is offscreen, scroll the edit
* window until it's onscreen and get out. */ * window until it's onscreen and get out. */
@ -3065,7 +3079,7 @@ void edit_redraw(const filestruct *old_current, size_t pww_save)
* if we've moved and changed text. */ * if we've moved and changed text. */
void edit_refresh(void) void edit_refresh(void)
{ {
const filestruct *foo; filestruct *foo;
int nlines; int nlines;
if (openfile->current->lineno < openfile->edittop->lineno || if (openfile->current->lineno < openfile->edittop->lineno ||