]> git.wh0rd.org Git - nano.git/commitdiff
- General - Added multiple-line regex support. Format in .nanorc is start=regex...
authorChris Allegretta <chrisa@asty.org>
Sat, 19 Jan 2002 16:52:34 +0000 (16:52 +0000)
committerChris Allegretta <chrisa@asty.org>
Sat, 19 Jan 2002 16:52:34 +0000 (16:52 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1021 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
nano.h
nanorc.sample
rcfile.c
winio.c

index b69005d687db52f431d0505bed722a0e71d909e3..ac77f825a6d3a6d0fbecc01843d07a4f5011ab8a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,10 @@ CVS code -
        - Better partial word checking code. New function 
          search.c:is_whole_word(), changes to findnextstr(), 
          and nano.c:do_int_spell_fix() (Rocco Corsi).
+       - Added multiple-line regex support.  Format in .nanorc is
+         start="regex" end="regex".  Cleaned up nanorc:parse_colors(),
+         added parse_next_regex(), changes to edit_add in winio.c(), 
+         changes to colortype, cleaning up some old cruft. 
 - color.c:
   do_colorinit()
        - Moved some comments and braces around so color can work 
@@ -39,6 +43,7 @@ CVS code -
   General
        - Took silly variables being passed everywhere like lineno and
          filename and made them static variables.
+       - Re-indented.
   rcfile_error()
        - Now automatically prpends the "error in line blah at foo"
          message to error messages.
diff --git a/nano.h b/nano.h
index 7947fe875e8809405e48d88c1980b6e784900ec4..26e10a6e9fcce69b966b0de7b8244a6e9eea3501 100644 (file)
--- a/nano.h
+++ b/nano.h
@@ -122,12 +122,12 @@ typedef struct rcoption {
 #define COLORSTRNUM 16
 
 typedef struct colortype {
-    int fg;
-    int bg;
-    int bright;
-    int pairnum;
-    char *start;
-    char *end;
+    int fg;                    /* fg color */
+    int bg;                    /* bg color */
+    int bright;                        /* Is this color A_BOLD? */
+    int pairnum;               /* Color pair number used for this fg/bg */
+    char *start;               /* Start (or all) of the regex string */
+    char *end;                 /* End of the regex string */
     struct colortype *next;
 } colortype;
 
index 8a40fc8313a0c43207d5a5e6222c777d19f82b81..78628bd34cfd3cec503fb5a264d11ee0da271005 100644 (file)
@@ -27,7 +27,7 @@
 # set fill -8
 
 # Use this tab size instead of the default
-# set tabsize 8
+# set tabsize 4
 
 # Use this spelling checker instead of the default one
 # set speller aspell
 
 #
 # Color setup
-# Format: color foreground,background regex [regex...]
+# Format: color foreground,background "regex" ["regex"...]
 #
 # Legal colors are: white, black, red, blue, green, yellow, purple, cyan
 # You may use the prefix "bright" to mean a stronger color highlight
 #
+# To use multi-line regexes use the start="regex" end="regex" format.
+#
 # If your system supports transparency, not specifying a background
 # color will use a transparent color.  If you don't want this, be sure
 # to set the background color to black or white.
 #
-#color brightred float\  char\  int\  void\  NULL [A-Z_]\{2,\} static
-#color brightred [\ ]struct ^struct if\  while[\ \n\(] do[\ \n\(] else[\ \n] case\ switch\ break;
-#color brightcyan #define #include #ifn*def #endif #elif #else
+#color brightred "float " "char " "int " "void "  "NULL" "[A-Z_]\{2,\}" 
+#color brightred "static" "const" "[\ ]struct" "^struct" "if " "while[\ \n\(]" 
+#color brightred "do[\ \n\(]" "else[\ \n]" "case " "switch " "break;"
+#color brightcyan "#define" "#include" "#ifn*def" "#endif" "#elif" "#else"
 
-# You will in general want your comments and strings to come last, because
-# syntax highlighting rules will be applied in the order they are read in
+#You will in general want your comments and strings to come last, becase
+#syntax highlighting rules will be applied in the order they are read in
 
-#color brightyellow <.*> ".*"
-#color brightblue /\*.**/
-# multi-line comment hack
-#color brightblue /\*.* [^\/][^\*]*\*\/ ^.*\*+*\**$ ^\ *\*\{1,\}\/$  \/\/.*
+#color brightyellow "<.*[^=\ ]*>" "\".*\""
+#color brightblue "//.*"
+#color brightblue start="/\*.*" end="\*/"
index ca2320f7b7fe90e11b2e08a180156010eea69939..2021c0fdfc588eed07b9d929d22ff9ec81152e03 100644 (file)
--- a/rcfile.c
+++ b/rcfile.c
 #endif
 
 #ifndef DISABLE_WRAPJUSTIFY
-    #define NUM_RCOPTS 19
+#define NUM_RCOPTS 19
 #else
-    #define NUM_RCOPTS 18
+#define NUM_RCOPTS 18
 #endif
 
 /* Static stuff for the nanorc file */
-rcoption rcopts[NUM_RCOPTS] = 
-{
-{"regexp", USE_REGEXP},
-{"const", CONSTUPDATE},
-{"autoindent", AUTOINDENT},
-{"cut", CUT_TO_END},
-{"nofollow", FOLLOW_SYMLINKS},
-{"mouse", USE_MOUSE},
-{"operatingdir", 0},
-{"pico", PICO_MODE},
-{"tabsize", 0},
+rcoption rcopts[NUM_RCOPTS] = {
+    {"regexp", USE_REGEXP},
+    {"const", CONSTUPDATE},
+    {"autoindent", AUTOINDENT},
+    {"cut", CUT_TO_END},
+    {"nofollow", FOLLOW_SYMLINKS},
+    {"mouse", USE_MOUSE},
+    {"operatingdir", 0},
+    {"pico", PICO_MODE},
+    {"tabsize", 0},
 
 #ifndef DISABLE_WRAPJUSTIFY
-{"fill", 0},
+    {"fill", 0},
 #endif
 
-{"speller", 0},
-{"tempfile", TEMP_OPT},
-{"view", VIEW_MODE},
-{"nowrap", NO_WRAP}, 
-{"nohelp", NO_HELP}, 
-{"suspend", SUSPEND},
-{"multibuffer", MULTIBUFFER},
-{"smooth", SMOOTHSCROLL},
-{"keypad", ALT_KEYPAD}};
+    {"speller", 0},
+    {"tempfile", TEMP_OPT},
+    {"view", VIEW_MODE},
+    {"nowrap", NO_WRAP},
+    {"nohelp", NO_HELP},
+    {"suspend", SUSPEND},
+    {"multibuffer", MULTIBUFFER},
+    {"smooth", SMOOTHSCROLL},
+    {"keypad", ALT_KEYPAD}
+};
 
 static int errors = 0;
 static int lineno = 0;
@@ -89,8 +89,7 @@ void rcfile_error(char *msg, ...)
     va_end(ap);
     fprintf(stderr, _("\nPress return to continue starting nano\n"));
 
-    while (getchar() != '\n')
-       ;
+    while (getchar() != '\n');
 
 }
 
@@ -113,12 +112,27 @@ void rcfile_msg(char *msg, ...)
 /* Parse the next word from the string.  Returns NULL if we hit EOL */
 char *parse_next_word(char *ptr)
 {
-    char *prev = " ";
+    while (*ptr != ' ' && *ptr != '\t' && *ptr != '\n' && *ptr != '\0')
+       ptr++;
+
+    if (*ptr == '\0')
+       return NULL;
+
+    /* Null terminate and advance ptr */
+    *ptr++ = 0;
+
+    while ((*ptr == ' ' || *ptr == '\t') && *ptr != '\0')
+       ptr++;
+
+    return ptr;
+}
 
-    while ((*ptr != ' ' || *prev == '\\')
-          && *ptr != '\t' && *ptr != '\n' && *ptr != '\0') {
+char *parse_next_regex(char *ptr)
+{
+    char prev = ' ';
+    while ((*ptr != '"' || prev == '\\') && *ptr != '\n' && *ptr != '\0') {
+       prev = *ptr;
        ptr++;
-       prev = ptr;
     }
 
     if (*ptr == '\0')
@@ -131,9 +145,10 @@ char *parse_next_word(char *ptr)
        ptr++;
 
     return ptr;
+
 }
 
-int colortoint(char *colorname, int *bright) 
+int colortoint(char *colorname, int *bright)
 {
     int mcolor = 0;
 
@@ -144,7 +159,7 @@ int colortoint(char *colorname, int *bright)
        *bright = 1;
        colorname += 6;
     }
-    
+
     if (!strcasecmp(colorname, "green"))
        mcolor += COLOR_GREEN;
     else if (!strcasecmp(colorname, "red"))
@@ -162,10 +177,10 @@ int colortoint(char *colorname, int *bright)
     else if (!strcasecmp(colorname, "black"))
        mcolor += COLOR_BLACK;
     else {
-        rcfile_error(_("color %s not understood.\n"
-               "Valid colors are \"green\", \"red\", \"blue\", \n"
-               "\"white\", \"yellow\", \"cyan\", \"magenta\" and \n"
-               "\"black\", with the optional prefix \"bright\".\n"));
+       rcfile_error(_("color %s not understood.\n"
+                      "Valid colors are \"green\", \"red\", \"blue\", \n"
+                      "\"white\", \"yellow\", \"cyan\", \"magenta\" and \n"
+                      "\"black\", with the optional prefix \"bright\".\n"));
        exit(1);
     }
 
@@ -175,11 +190,10 @@ int colortoint(char *colorname, int *bright)
 
 #ifdef ENABLE_COLOR
 /* Parse the color stuff into the colorstrings array */
-void parse_colors(FILE *rcstream, char *buf, char *ptr)
+void parse_colors(FILE * rcstream, char *buf, char *ptr)
 {
-    int i = 0, fg, bg, bright = 0, loopdone = 0;
-    int expectend = 0;                 /* Do we expect an end= line? */
-    char prev = '\\';
+    int fg, bg, bright = 0;
+    int expectend = 0;         /* Do we expect an end= line? */
     char *tmp = NULL, *beginning, *fgstr, *bgstr;
     colortype *tmpcolor = NULL;
 
@@ -201,113 +215,101 @@ void parse_colors(FILE *rcstream, char *buf, char *ptr)
     bg = colortoint(bgstr, &bright);
 
     /* Now the fun part, start adding regexps to individual strings
-       in the colorstrings array, woo! */
+       in the colorstrings array, woo! */
 
-    if (!strncasecmp(ptr, "start=", 6)) {
-       ptr += 6;
-       expectend = 1;
-    }
+    while (*ptr != '\0') {
 
-    i = 0;
-    beginning = ptr;
-    while (*ptr != '\0' && !loopdone) {
-       switch (*ptr) {
-       case '\n':
-           *ptr = ' ';
-       case ' ':
-           if (prev != '\\') {
-               /* This is the end of the regex, uh I guess.
-                  Add it to the colorstrings array for this color */   
-
-               if (i == 0) {
-                   rcfile_error(_("regex length must be > 0"));
-                   continue;
-               }
-               
-               tmp = NULL;
-               tmp = charalloc(i + 1);
-               strncpy(tmp, beginning, i);
-               tmp[i] = '\0';
-
-               /* Get rid of the leading space */
-               ptr = parse_next_word(ptr);
-               if (ptr == NULL)
-                   return;
-
-               if (colorstrings == NULL) {
-                   colorstrings = nmalloc(sizeof(colortype));
-                   colorstrings->fg = fg;
-                   colorstrings->bg = bg;
-                   colorstrings->bright = bright;
-                   colorstrings->start = tmp;
-                   colorstrings->next = NULL;
-                   tmpcolor = colorstrings;
+       while (*ptr == ' ')
+           ptr++;
+
+       if (*ptr == '\n' || *ptr == '\0')
+           break;
+
+       if (!strncasecmp(ptr, "start=", 6)) {
+           ptr += 6;
+           expectend = 1;
+       }
+
+       if (*ptr != '"') {
+           rcfile_error(_("regex strings must begin and end with a \" character\n"));
+           continue;
+       }
+       ptr++;
 
+       beginning = ptr;
+       ptr = parse_next_regex(ptr);
+
+       tmp = NULL;
+       tmp = mallocstrcpy(tmp, beginning);
+
+       if (colorstrings == NULL) {
+           colorstrings = nmalloc(sizeof(colortype));
+           colorstrings->fg = fg;
+           colorstrings->bg = bg;
+           colorstrings->bright = bright;
+           colorstrings->start = tmp;
+           colorstrings->next = NULL;
+           tmpcolor = colorstrings;
 #ifdef DEBUG
-                   fprintf(stderr, "Starting a new colorstring for fg %d bg %d\n", fg, bg);
-                   fprintf(stderr, "string val=%s\n", tmp);
+           fprintf(stderr,
+                   "Starting a new colorstring for fg %d bg %d\n",
+                   fg, bg);
+           fprintf(stderr, "string val=%s\n", tmp);
 #endif
 
-               } else {
-                   for (tmpcolor = colorstrings; tmpcolor->next != NULL;
-                         tmpcolor = tmpcolor->next)
-                       ;
+       } else {
+           for (tmpcolor = colorstrings;
+                tmpcolor->next != NULL; tmpcolor = tmpcolor->next);
 #ifdef DEBUG
-                   fprintf(stderr, "Adding new entry for fg %d bg %d\n", fg, bg);
-                   fprintf(stderr, "string val=%s\n", tmp);
+           fprintf(stderr, "Adding new entry for fg %d bg %d\n", fg, bg);
+           fprintf(stderr, "string val=%s\n", tmp);
 #endif
 
-                   tmpcolor->next = nmalloc(sizeof(colortype));
-                   tmpcolor->next->fg = fg;
-                   tmpcolor->next->bg = bg;
-                   tmpcolor->next->bright = bright;
-                   tmpcolor->next->start = tmp;
-                   tmpcolor->next->next = NULL;
-                   tmpcolor = tmpcolor->next;
-               }
+           tmpcolor->next = nmalloc(sizeof(colortype));
+           tmpcolor->next->fg = fg;
+           tmpcolor->next->bg = bg;
+           tmpcolor->next->bright = bright;
+           tmpcolor->next->start = tmp;
+           tmpcolor->next->next = NULL;
+           tmpcolor = tmpcolor->next;
+       }
 
-               i = 0;
-               beginning = ptr;
+       if (expectend) {
+           if (ptr == NULL || strncasecmp(ptr, "end=", 4)) {
+               rcfile_error(_
+                            ("\n\t\"start=\" requires a corresponding \"end=\""));
+               return;
+           }
 
-               if (expectend)
-                   loopdone = 1;
+           ptr += 4;
 
-               break;
+           if (*ptr != '"') {
+               rcfile_error(_
+                            ("regex strings must begin and end with a \" character\n"));
+               continue;
            }
-           /* Else drop through to the default case */         
-       default:
-           i++;
-           prev = *ptr;
            ptr++;
-           break;
-       }
-    }
 
-    if (expectend) {
-       if (ptr == NULL || strncasecmp(ptr, "end=", 4)) {
-           rcfile_error(
-               _("\n\t\"start=\" requires a corresponding \"end=\""));
-           return;
-       }
 
-       ptr += 4;
-       beginning = ptr;
-       ptr = parse_next_word(ptr);
+           beginning = ptr;
+           ptr = parse_next_regex(ptr);
 #ifdef DEBUG
-       fprintf(stderr, "For end part, beginning = \"%s\"\n", beginning);
+           fprintf(stderr, "For end part, beginning = \"%s\"\n",
+                   beginning);
 #endif
-       tmp = NULL;
-       tmp = mallocstrcpy(tmp, beginning);
-       tmpcolor->end = tmp;
-
-    }
+           tmp = NULL;
+           tmp = mallocstrcpy(tmp, beginning);
+           tmpcolor->end = tmp;
 
+       } else
+           tmpcolor->end = NULL;
 
+    }
 }
-#endif /* ENABLE_COLOR */
+#endif                         /* ENABLE_COLOR */
 
 /* Parse the RC file, once it has been opened successfully */
-void parse_rcfile(FILE *rcstream)
+void parse_rcfile(FILE * rcstream)
 {
     char *buf, *ptr, *keyword, *option;
     int set = 0, i;
@@ -316,8 +318,8 @@ void parse_rcfile(FILE *rcstream)
     while (fgets(buf, 1023, rcstream) > 0) {
        lineno++;
        ptr = buf;
-       while ((*ptr == ' ' || *ptr == '\t') && 
-               (*ptr != '\n' && *ptr != '\0'))
+       while ((*ptr == ' ' || *ptr == '\t') &&
+              (*ptr != '\n' && *ptr != '\0'))
            ptr++;
 
        if (*ptr == '\n' || *ptr == '\0')
@@ -327,7 +329,7 @@ void parse_rcfile(FILE *rcstream)
 #ifdef DEBUG
            fprintf(stderr, _("parse_rcfile: Read a comment\n"));
 #endif
-           continue;   /* Skip past commented lines */
+           continue;           /* Skip past commented lines */
        }
 
        /* Else skip to the next space */
@@ -344,7 +346,7 @@ void parse_rcfile(FILE *rcstream)
 #ifdef ENABLE_COLOR
        else if (!strcasecmp(keyword, "color"))
            parse_colors(rcstream, buf, ptr);
-#endif /* ENABLE_COLOR */
+#endif                         /* ENABLE_COLOR */
        else {
            rcfile_msg(_("command %s not understood"), keyword);
            continue;
@@ -356,28 +358,28 @@ void parse_rcfile(FILE *rcstream)
 
        if (set != 0) {
            for (i = 0; i <= NUM_RCOPTS - 1; i++) {
-               if (!strcasecmp(option, rcopts[i].name)) {
+               if (!strcasecmp(option, rcopts[i].name)) {
 #ifdef DEBUG
-                   fprintf(stderr, _("parse_rcfile: Parsing option %s\n"), 
-                               rcopts[i].name);
+                   fprintf(stderr, _("parse_rcfile: Parsing option %s\n"),
+                           rcopts[i].name);
 #endif
                    if (set == 1 || rcopts[i].flag == FOLLOW_SYMLINKS) {
-                       if (
-                           !strcasecmp(rcopts[i].name, "operatingdir") ||
+                       if (!strcasecmp(rcopts[i].name, "operatingdir") ||
                            !strcasecmp(rcopts[i].name, "tabsize") ||
 #ifndef DISABLE_WRAPJUSTIFY
-                           !strcasecmp(rcopts[i].name, "fill") || 
+                           !strcasecmp(rcopts[i].name, "fill") ||
 #endif
 #ifndef DISABLE_SPELLER
                            !strcasecmp(rcopts[i].name, "speller")
 #else
-                               0
+                           0
 #endif
-                          ) {
+                           ) {
 
                            if (*ptr == '\n' || *ptr == '\0') {
-                               rcfile_error(_("option %s requires an argument"),
-                                               rcopts[i].name);
+                               rcfile_error(_
+                                            ("option %s requires an argument"),
+                                            rcopts[i].name);
                                continue;
                            }
                            option = ptr;
@@ -386,36 +388,42 @@ void parse_rcfile(FILE *rcstream)
 #ifndef DISABLE_WRAPJUSTIFY
 
                                if ((i = atoi(option)) < MIN_FILL_LENGTH) {
-                                   rcfile_error(
-               _("requested fill size %d too small"), i);
-                               }
-                               else
-                                    fill = i;
+                                   rcfile_error(_
+                                                ("requested fill size %d too small"),
+                                                i);
+                               else
+                                   fill = i;
 #endif
-                           } else if (!strcasecmp(rcopts[i].name, "tabsize")) {
-                               if ((i = atoi(option)) <= 0) {
-                                       rcfile_error(
-                                       _("requested tab size %d too small"), i);
-                               } else {
-                                       tabsize = i;
-                               }
+                           } else
+                               if (!strcasecmp(rcopts[i].name, "tabsize"))
+                           {
+                               if ((i = atoi(option)) <= 0) {
+                                   rcfile_error(_
+                                                ("requested tab size %d too small"),
+                                                i);
+                               } else {
+                                   tabsize = i;
+                               }
                            } else {
 #ifndef DISABLE_SPELLER
-                               alt_speller = charalloc(strlen(option) + 1);
-                               strcpy(alt_speller, option);
+                               alt_speller =
+                                   charalloc(strlen(option) + 1);
+                               strcpy(alt_speller, option);
 #endif
                            }
-                       } else 
+                       } else
                            SET(rcopts[i].flag);
 #ifdef DEBUG
-                       fprintf(stderr, _("set flag %d!\n"), rcopts[i].flag);
+                       fprintf(stderr, _("set flag %d!\n"),
+                               rcopts[i].flag);
 #endif
                    } else {
                        UNSET(rcopts[i].flag);
 #ifdef DEBUG
-                       fprintf(stderr, _("unset flag %d!\n"), rcopts[i].flag);
+                       fprintf(stderr, _("unset flag %d!\n"),
+                               rcopts[i].flag);
 #endif
-                  }                    
+                   }
                }
            }
        }
@@ -448,7 +456,7 @@ void do_rcfile(void)
        if (errno != ENOENT)
            rcfile_error(unable, errno);
        return;
-   }
+    }
 
     if ((rcstream = fopen(nanorc, "r")) == NULL) {
        rcfile_error(unable, strerror(errno));
@@ -461,5 +469,4 @@ void do_rcfile(void)
 }
 
 
-#endif /* ENABLE_NANORC */
-
+#endif                         /* ENABLE_NANORC */
diff --git a/winio.c b/winio.c
index 2e109561c40d320d6636ffe8bfcb9dc080ae1b92..38824d04f515554e92cfbf10c35a3460f9da1fed 100644 (file)
--- a/winio.c
+++ b/winio.c
@@ -774,10 +774,10 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
 #ifdef ENABLE_COLOR
     colortype *tmpcolor = NULL;
     int k, paintlen;
+    filestruct *e, *s;
+    regoff_t ematch, smatch;
 #endif
 
-
-
     /* Just paint the string in any case (we'll add color or reverse on
        just the text that needs it */
     mvwaddnstr(edit, yval, 0, &fileptr->data[start],
@@ -788,44 +788,145 @@ void edit_add(filestruct * fileptr, int yval, int start, int virt_cur_x,
        for (tmpcolor = colorstrings; tmpcolor != NULL;
             tmpcolor = tmpcolor->next) {
 
-           k = start;
-           regcomp(&search_regexp, tmpcolor->start, 0);
-           while (!regexec(&search_regexp, &fileptr->data[k], 1,
-                           regmatches, 0)) {
+           if (tmpcolor->end == NULL) {
 
-               if (regmatches[0].rm_eo - regmatches[0].rm_so < 1) {
-                   statusbar("Refusing 0 length regex match");
-                   break;
-               }
+               /* First, highlight all single-line regexes */
+               k = start;
+               regcomp(&search_regexp, tmpcolor->start, 0);
+               while (!regexec(&search_regexp, &fileptr->data[k], 1,
+                               regmatches, 0)) {
+
+                   if (regmatches[0].rm_eo - regmatches[0].rm_so < 1) {
+                       statusbar("Refusing 0 length regex match");
+                       break;
+                   }
 #ifdef DEBUG
-               fprintf(stderr, "Match! (%d chars) \"%s\"\n",
-                       regmatches[0].rm_eo - regmatches[0].rm_so,
-                       &fileptr->data[k + regmatches[0].rm_so]);
+                   fprintf(stderr, "Match! (%d chars) \"%s\"\n",
+                           regmatches[0].rm_eo - regmatches[0].rm_so,
+                           &fileptr->data[k + regmatches[0].rm_so]);
 #endif
-               if (regmatches[0].rm_so < COLS - 1) {
-                   if (tmpcolor->bright)
-                       wattron(edit, A_BOLD);
-                   wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
+                   if (regmatches[0].rm_so < COLS - 1) {
+                       if (tmpcolor->bright)
+                           wattron(edit, A_BOLD);
+                       wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
+
+                       if (regmatches[0].rm_eo + k <= COLS)
+                           paintlen =
+                               regmatches[0].rm_eo - regmatches[0].rm_so;
+                       else
+                           paintlen = COLS - k - regmatches[0].rm_so - 1;
+
+                       mvwaddnstr(edit, yval, regmatches[0].rm_so + k,
+                                  &fileptr->data[k + regmatches[0].rm_so],
+                                  paintlen);
+
+                   }
 
-                   if (regmatches[0].rm_eo + k <= COLS)
-                       paintlen =
-                           regmatches[0].rm_eo - regmatches[0].rm_so;
-                   else
-                       paintlen = COLS - k - regmatches[0].rm_so - 1;
+                   if (tmpcolor->bright)
+                       wattroff(edit, A_BOLD);
+                   wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
 
-                   mvwaddnstr(edit, yval, regmatches[0].rm_so + k,
-                              &fileptr->data[k + regmatches[0].rm_so],
-                              paintlen);
+                   k += regmatches[0].rm_eo;
 
+               }
+           }
+           /* Now, if there's an 'end' somewhere below, and a 'start'
+              somewhere above, things get really fun.  We have to look
+              down for an end, make sure there's not a start before 
+              the end after us, and then look up for a start, 
+              and see if there's an end after the start, before us :) */
+           else {
 
+               s = fileptr;
+               while (s != NULL) {
+                   regcomp(&search_regexp, tmpcolor->start, 0);
+                   if (!regexec
+                       (&search_regexp, s->data, 1, regmatches, 0))
+                       break;
+                   s = s->prev;
                }
 
-               if (tmpcolor->bright)
-                   wattroff(edit, A_BOLD);
-               wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
+               if (s != NULL) {
+                   /* We found a start, mark it */
+                   smatch = regmatches[0].rm_so;
+
+                   e = s;
+                   while (e != NULL && e != fileptr) {
+                       regcomp(&search_regexp, tmpcolor->end, 0);
+                       if (!regexec
+                           (&search_regexp, e->data, 1, regmatches, 0))
+                           break;
+                       e = e->next;
+                   }
+
+                   if (e != fileptr)
+                       continue;       /* There's an end before us */
+                   else {      /* Keep looking for an end */
+                       while (e != NULL) {
+                           regcomp(&search_regexp, tmpcolor->end, 0);
+                           if (!regexec
+                               (&search_regexp, e->data, 1, regmatches,
+                                0))
+                               break;
+                           e = e->next;
+                       }
+
+                       if (e == NULL)
+                           continue;   /* There's no start before the end :) */
+                       else {  /* Okay, we found an end, mark it! */
+                           ematch = regmatches[0].rm_eo;
+
+                           while (e != NULL) {
+                               regcomp(&search_regexp, tmpcolor->end, 0);
+                               if (!regexec
+                                   (&search_regexp, e->data, 1,
+                                    regmatches, 0))
+                                   break;
+                               e = e->next;
+                           }
+
+                           if (e == NULL)
+                               continue;       /* No end, oh well :) */
+
+                           /* Didn't find another end, we must be in the 
+                              middle of a highlighted bit */
+
+                           if (tmpcolor->bright)
+                               wattron(edit, A_BOLD);
+
+                           wattron(edit, COLOR_PAIR(tmpcolor->pairnum));
+
+                           if (s == fileptr && e == fileptr)
+                               mvwaddnstr(edit, yval, start + smatch, 
+                                       &fileptr->data[start + smatch],
+                                       ematch - smatch);
+                           else if (s == fileptr)
+                               mvwaddnstr(edit, yval, start + smatch, 
+                                       &fileptr->data[start + smatch],
+                                       COLS - smatch);
+                           else if (e == fileptr)
+                               mvwaddnstr(edit, yval, start, 
+                                       &fileptr->data[start],
+                                       ematch - start);
+                           else
+                               mvwaddnstr(edit, yval, start, 
+                                       &fileptr->data[start],
+                                       COLS);
+
+                           if (tmpcolor->bright)
+                               wattroff(edit, A_BOLD);
+
+                           wattroff(edit, COLOR_PAIR(tmpcolor->pairnum));
+
+                       }
+
+                   }
+
+                   /* Else go to the next string, yahoo! =) */
+               }
 
-               k += regmatches[0].rm_eo;
            }
+
        }
 #endif                         /* ENABLE_COLOR */
 #ifndef NANO_SMALL