diff --git a/ChangeLog b/ChangeLog index 8fc4c718..b7f05133 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2012-02-05 Chris Allegretta + * src/*: Fix overlapping strings highlighting each other. new variables in edit_draw + (slmatcharray, pbegin, paintok), new logic (with repeated setting od values in the + array but its BFI after all). FIXME: Need to create a new 'overlap' + * src/*: Fix a silly issue with the argument to nregcomp, as it's confusing to the caller + * src/nano.h: Change the color types to a compiler macro (COLORWIDTH), may not actually + even be worth doing, but someday who knows how wide a color curses implementation might + be, and maybe we'll even start checking for it in autoconf! + GNU nano 2.3.1 - 2011.05.10 2011-05-10 Chris Allegretta * text.c (do_enter): Only increment totsize by the auto-indented amount, size the previous line's size was diff --git a/src/nano.h b/src/nano.h index 25ee321e..6db8447c 100644 --- a/src/nano.h +++ b/src/nano.h @@ -190,10 +190,11 @@ typedef enum { } undo_type; #ifdef ENABLE_COLOR +#define COLORWIDTH short typedef struct colortype { - short fg; + COLORWIDTH fg; /* This syntax's foreground color. */ - short bg; + COLORWIDTH bg; /* This syntax's background color. */ bool bright; /* Is this color A_BOLD? */ @@ -212,7 +213,9 @@ typedef struct colortype { /* The compiled end (if any) of the regex string. */ struct colortype *next; /* Next set of colors. */ - int id; + bool overlap; + /* Is it acceptable for other regexes to overlap this one? */ + int id; /* basic id for assigning to lines later */ } colortype; diff --git a/src/proto.h b/src/proto.h index 9ce39d9c..aeb409db 100644 --- a/src/proto.h +++ b/src/proto.h @@ -551,7 +551,7 @@ char *parse_next_word(char *ptr); char *parse_argument(char *ptr); #ifdef ENABLE_COLOR char *parse_next_regex(char *ptr); -bool nregcomp(const char *regex, int eflags); +bool nregcomp(const char *regex, int cflags); void parse_syntax(char *ptr); void parse_magic_syntax(char *ptr); void parse_include(char *ptr); diff --git a/src/rcfile.c b/src/rcfile.c index 36f86301..8c62cf5b 100644 --- a/src/rcfile.c +++ b/src/rcfile.c @@ -225,11 +225,11 @@ char *parse_next_regex(char *ptr) /* Compile the regular expression regex to see if it's valid. Return * TRUE if it is, or FALSE otherwise. */ -bool nregcomp(const char *regex, int eflags) +bool nregcomp(const char *regex, int cflags) { regex_t preg; const char *r = fixbounds(regex); - int rc = regcomp(&preg, r, REG_EXTENDED | eflags); + int rc = regcomp(&preg, r, REG_EXTENDED | cflags); if (rc != 0) { size_t len = regerror(rc, &preg, NULL, 0); @@ -666,9 +666,9 @@ void parse_include(char *ptr) /* Return the short value corresponding to the color named in colorname, * and set bright to TRUE if that color is bright. */ -short color_to_short(const char *colorname, bool *bright) +COLORWIDTH color_to_short(const char *colorname, bool *bright) { - short mcolor = -1; + COLORWIDTH mcolor = -1; assert(colorname != NULL && bright != NULL); @@ -708,7 +708,7 @@ short color_to_short(const char *colorname, bool *bright) * as case insensitive. */ void parse_colors(char *ptr, bool icase) { - short fg, bg; + COLORWIDTH fg, bg; bool bright = FALSE, no_fgcolor = FALSE; char *fgstr; @@ -858,7 +858,7 @@ void parse_colors(char *ptr, bool icase) 0)) ? mallocstrcpy(NULL, fgstr) : NULL; /* Lame way to skip another static counter */ - newcolor->id = endsyntax->nmultis; + newcolor->id = endsyntax->nmultis; endsyntax->nmultis++; } } diff --git a/src/winio.c b/src/winio.c index fd239225..6d3c0578 100644 --- a/src/winio.c +++ b/src/winio.c @@ -2490,14 +2490,29 @@ void edit_draw(filestruct *fileptr, const char *converted, int * them. */ if (openfile->colorstrings != NULL && !ISSET(NO_COLOR_SYNTAX)) { const colortype *tmpcolor = openfile->colorstrings; + int i, coloruid = 0; /* We need a unique color ID now */ + static filestruct *lastptr = NULL; + static COLORWIDTH *slmatcharray = NULL; + /* Array to track how much we've painted of the line for single line matches */ + + if (lastptr != fileptr || start == 0) { + if (slmatcharray != NULL) + free(slmatcharray); + slmatcharray = (COLORWIDTH *)nmalloc(strlenpt(fileptr->data) * sizeof(COLORWIDTH)); + + /* Init slmatcharray */ + for (i = 0; i < strlenpt(fileptr->data); i++) + slmatcharray[i] = -1; + } + /* Set up multi-line color data for this line if it's not yet calculated */ if (fileptr->multidata == NULL && openfile->syntax && openfile->syntax->nmultis > 0) { - int i; fileptr->multidata = (short *) nmalloc(openfile->syntax->nmultis * sizeof(short)); - for (i = 0; i < openfile->syntax->nmultis; i++) + 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; @@ -2512,6 +2527,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int regmatch_t endmatch; /* Match position for end_regex. */ + coloruid++; if (tmpcolor->bright) wattron(edit, A_BOLD); wattron(edit, COLOR_PAIR(tmpcolor->pairnum)); @@ -2519,7 +2535,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int * that there is a match. Also, rm_eo is the first * non-matching character after the match. */ - /* First case, tmpcolor is a single-line expression. */ + /* First case,tmpcolor is a single-line expression. */ if (tmpcolor->end == NULL) { size_t k = 0; @@ -2528,6 +2544,8 @@ void edit_draw(filestruct *fileptr, const char *converted, int * want to ignore them, so that we can highlight e.g. C * strings correctly. */ while (k < endpos) { + bool paintok = TRUE; + /* Note the fifth parameter to regexec(). It says * not to match the beginning-of-line character * unless k is zero. If regexec() returns @@ -2537,6 +2555,8 @@ void edit_draw(filestruct *fileptr, const char *converted, int &startmatch, (k == 0) ? 0 : REG_NOTBOL) == REG_NOMATCH) break; + + /* Translate the match to the beginning of the * line. */ startmatch.rm_so += k; @@ -2547,6 +2567,8 @@ void edit_draw(filestruct *fileptr, const char *converted, int startmatch.rm_eo++; else if (startmatch.rm_so < endpos && startmatch.rm_eo > startpos) { + size_t pbegin = strnlenpt(fileptr->data, startmatch.rm_so); + x_start = (startmatch.rm_so <= startpos) ? 0 : strnlenpt(fileptr->data, startmatch.rm_so) - start; @@ -2559,10 +2581,25 @@ void edit_draw(filestruct *fileptr, const char *converted, int assert(0 <= x_start && 0 <= paintlen); - mvwaddnstr(edit, line, x_start, converted + + /* Check that the match is not preceeded by another previous + (single line) match before proceeding to paint it */ + if (slmatcharray[pbegin] != -1 && slmatcharray[pbegin] != coloruid) + paintok = FALSE; + + if (paintok == TRUE) { + int p; + + mvwaddnstr(edit, line, x_start, converted + index, paintlen); + for (p = pbegin; p < pbegin + (startmatch.rm_eo - startmatch.rm_so); p++) { + slmatcharray[p] = coloruid; /* Add to our match array for the proper length */ + } + } } - k = startmatch.rm_eo; + if (paintok) + k = startmatch.rm_eo; + else + k = startmatch.rm_so + 1; } } else if (fileptr->multidata != NULL && fileptr->multidata[tmpcolor->id] != CNONE) { /* This is a multi-line regex. There are two steps. @@ -2749,6 +2786,7 @@ void edit_draw(filestruct *fileptr, const char *converted, int wattroff(edit, A_BOLD); wattroff(edit, COLOR_PAIR(tmpcolor->pairnum)); } + lastptr = fileptr; } #endif /* ENABLE_COLOR */