diff --git a/ChangeLog b/ChangeLog
index 3af262b0a5ebda4e206fd059d8d84403676048e6..86fd49b3c02229b38114472cb65bbe7a68a24d2f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,6 @@
 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
 	  disable_nodelay and changes to the routines to handle checking for pending
 	  searches.  Fixes Savnnah bug 24946: Need interrrupt for search.
diff --git a/src/color.c b/src/color.c
index 353a5bafec55d3d607bc1bb43606fc06ba96287f..d59c3d5dc145d2229564049f80056d1263719f4d 100644
--- a/src/color.c
+++ b/src/color.c
@@ -105,11 +105,13 @@ void color_init(void)
 /* Update the color information based on the current filename. */
 void color_update(void)
 {
-    const syntaxtype *tmpsyntax;
+    syntaxtype *tmpsyntax;
+    syntaxtype *defsyntax = NULL;
     colortype *tmpcolor, *defcolor = NULL;
 
     assert(openfile != NULL);
 
+    openfile->syntax = NULL;
     openfile->colorstrings = NULL;
 
     /* If we specified a syntax override string, use it. */
@@ -121,8 +123,10 @@ void color_update(void)
 
 	for (tmpsyntax = syntaxes; tmpsyntax != NULL;
 		tmpsyntax = tmpsyntax->next) {
-	    if (strcmp(tmpsyntax->desc, syntaxstr) == 0)
+	    if (strcmp(tmpsyntax->desc, syntaxstr) == 0) {
+		openfile->syntax = tmpsyntax;
 		openfile->colorstrings = tmpsyntax->color;
+	    }
 
 	    if (openfile->colorstrings != NULL)
 		break;
@@ -141,6 +145,7 @@ void color_update(void)
 	     * extensions, which we've checked for elsewhere.  Skip over
 	     * it here, but keep track of its color regexes. */
 	    if (strcmp(tmpsyntax->desc, "default") == 0) {
+		defsyntax = tmpsyntax;
 		defcolor = tmpsyntax->color;
 		continue;
 	    }
@@ -159,8 +164,10 @@ void color_update(void)
 		/* Set colorstrings if we matched the extension
 		 * regex. */
 		if (regexec(e->ext, openfile->filename, 0, NULL,
-			0) == 0)
+			0) == 0) {
+		    openfile->syntax = tmpsyntax;
 		    openfile->colorstrings = tmpsyntax->color;
+		}
 
 		if (openfile->colorstrings != NULL)
 		    break;
@@ -200,8 +207,10 @@ void color_update(void)
 #ifdef DEBUG
 		fprintf(stderr, "Comparing header regex \"%s\" to fileage \"%s\"...\n", e->ext_regex, openfile->fileage->data);
 #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;
+		    }
 
 		    if (openfile->colorstrings != NULL)
 			break;
@@ -221,8 +230,10 @@ void color_update(void)
 
     /* If we didn't get a syntax based on the file extension, and we
      * have a default syntax, use it. */
-    if (openfile->colorstrings == NULL && defcolor != NULL)
+    if (openfile->colorstrings == NULL && defcolor != NULL) {
+	openfile->syntax = defsyntax;
 	openfile->colorstrings = defcolor;
+    }
 
     for (tmpcolor = openfile->colorstrings; tmpcolor != NULL;
 	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 */
diff --git a/src/files.c b/src/files.c
index 08c7d3a42fc1d01da487495e6a03fa4c2f5ffcb9..10c3a798bfed6bc5e118b80458a26eaf1d6e6fa8 100644
--- a/src/files.c
+++ b/src/files.c
@@ -311,6 +311,10 @@ filestruct *read_line(char *buf, filestruct *prevnode, bool
 	fileptr->data[buf_len - 1] = '\0';
 #endif
 
+#ifdef ENABLE_COLOR
+	fileptr->multiswatching = NULL;
+#endif
+
     if (*first_line_ins) {
 	/* Special case: We're inserting with the cursor on the first
 	 * line. */
diff --git a/src/move.c b/src/move.c
index 05892e0318b66eb876c035896e9a9a94214ccdaf..531a48cbff2ba0a610bece130cc5439aea6a014d 100644
--- a/src/move.c
+++ b/src/move.c
@@ -29,7 +29,7 @@
 /* Move to the first line of the file. */
 void do_first_line(void)
 {
-    const filestruct *current_save = openfile->current;
+    filestruct *current_save = openfile->current;
     size_t pww_save = openfile->placewewant;
 
     openfile->current = openfile->fileage;
@@ -42,7 +42,7 @@ void do_first_line(void)
 /* Move to the last line of the file. */
 void do_last_line(void)
 {
-    const filestruct *current_save = openfile->current;
+    filestruct *current_save = openfile->current;
     size_t pww_save = openfile->placewewant;
 
     openfile->current = openfile->filebot;
@@ -130,7 +130,7 @@ void do_page_down(void)
  * afterwards. */
 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;
 
     if (openfile->current != openfile->fileage) {
@@ -162,7 +162,7 @@ void do_para_begin_void(void)
  * paragraph or isn't in a paragraph. */
 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;
 
     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)
 {
     size_t pww_save = openfile->placewewant;
-    const filestruct *current_save = openfile->current;
+    filestruct *current_save = openfile->current;
     char *char_mb;
     int char_mb_len;
     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)
 {
     size_t pww_save = openfile->placewewant;
-    const filestruct *current_save = openfile->current;
+    filestruct *current_save = openfile->current;
     char *char_mb;
     int char_mb_len;
     bool begin_line = FALSE, started_on_word = FALSE;
diff --git a/src/nano.c b/src/nano.c
index 8fa7f8eb7261766f183083e95349e330de8ebaaf..1eff99e0c7c728d4b811f9892b0ef078a69dd50d 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -68,8 +68,7 @@ filestruct *make_new_node(filestruct *prevnode)
     newnode->lineno = (prevnode != NULL) ? prevnode->lineno + 1 : 1;
 
 #ifdef ENABLE_COLOR
-    newnode->colors = NULL;
-    newnode->colorclean = FALSE;
+    newnode->multiswatching = NULL;
 #endif
 
     return newnode;
@@ -88,6 +87,9 @@ filestruct *copy_node(const filestruct *src)
     dst->next = src->next;
     dst->prev = src->prev;
     dst->lineno = src->lineno;
+#ifdef ENABLE_COLOR
+    dst->multiswatching = NULL;
+#endif
 
     return dst;
 }
@@ -124,6 +126,11 @@ void delete_node(filestruct *fileptr)
     if (fileptr->data != NULL)
 	free(fileptr->data);
 
+#ifdef ENABLE_COLOR
+    if (fileptr->multiswatching)
+	free(fileptr->multiswatching);
+#endif
+
     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 *
 			sizeof(int));
 		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
 			    if (s->scfunc ==  DO_TOGGLE)
 				do_toggle(s->toggle);
-			    else
+			    else {
 #endif
 				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;
 		    break;
@@ -1551,7 +1567,7 @@ int do_mouse(void)
 	bool sameline;
 	    /* Did they click on the line with the cursor?  If they
 	     * 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 pww_save = openfile->placewewant;
 
@@ -1688,6 +1704,8 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
 
     openfile->placewewant = xplustabs();
 
+
+    reset_multis(openfile->current);
     if (do_refresh)
 	edit_refresh();
     else
diff --git a/src/nano.h b/src/nano.h
index 7accb1045d1cd6fd9d64cf127bdf6485505e0013..203cb40239c777de76594391d3bed1c4f9554e67 100644
--- a/src/nano.h
+++ b/src/nano.h
@@ -196,6 +196,8 @@ typedef struct colortype {
 	/* The compiled end (if any) of the regex string. */
     struct colortype *next;
 	/* Next set of colors. */
+     int id;
+	/* basic id for assigning to lines later */
 } colortype;
 
 typedef struct exttype {
@@ -216,6 +218,8 @@ typedef struct syntaxtype {
 	/* Regexes to match on the 'header' (1st line) of the file */
     colortype *color;
 	/* The colors used in this syntax. */
+    int nmultis;
+	/* How many multi line strings this syntax has */
     struct syntaxtype *next;
 	/* Next syntax. */
 } syntaxtype;
@@ -233,8 +237,7 @@ typedef struct filestruct {
     struct filestruct *prev;
 	/* Previous node. */
 #ifdef ENABLE_COLOR
-    colortype **colors;		/* Will be a series of pointers to the colorstrings we're painting */
-    bool colorclean;		/* Did we do something to the line which necessitates recalculating the colors */
+    bool *multiswatching;		/* Array of which multi-line regexes apply to this line */
 #endif
 } filestruct;
 
@@ -328,6 +331,8 @@ typedef struct openfilestruct {
     undo_type last_action;
 #endif
 #ifdef ENABLE_COLOR
+    syntaxtype *syntax;
+	/* The  syntax struct for this file, if any */
     colortype *colorstrings;
 	/* The current file's associated colors. */
 #endif
diff --git a/src/proto.h b/src/proto.h
index ec9b5f4b32f9a64f7f4601369121282ba59e7f59..628f90b1b2b180f55f3edfdb4f988785e61d53cb 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -542,6 +542,7 @@ void parse_syntax(char *ptr);
 void parse_include(char *ptr);
 short color_to_short(const char *colorname, bool *bright);
 void parse_colors(char *ptr, bool icase);
+void reset_multis(filestruct *fileptr);
 #endif
 void parse_rcfile(FILE *rcstream
 #ifdef ENABLE_COLOR
@@ -759,13 +760,13 @@ void statusbar(const char *msg, ...);
 void bottombars(int menu);
 void onekey(const char *keystroke, const char *desc, size_t len);
 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);
-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_vertical_update(size_t pww_save);
 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_update(update_type location);
 void total_redraw(void);
diff --git a/src/rcfile.c b/src/rcfile.c
index 05ba82d95dd5bdd6ea6d412e9f0ae22df975b8d5..a12c80143dd3fd012a32d412cb801a505813a831 100644
--- a/src/rcfile.c
+++ b/src/rcfile.c
@@ -107,6 +107,7 @@ static exttype *endheader = NULL;
 	/* End of header list */
 static colortype *endcolor = NULL;
 	/* The end of the color list for the current syntax. */
+
 #endif
 
 /* 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->headers = NULL;
     endsyntax->next = NULL;
+    endsyntax->nmultis = 0;
 
 #ifdef DEBUG
     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. */
 	    newcolor->end_regex = (nregcomp(fgstr, icase ? REG_ICASE :
 		0)) ? mallocstrcpy(NULL, fgstr) : NULL;
+
+	    /* Lame way to skip another static counter */
+            newcolor->id = endsyntax->nmultis;
+            endsyntax->nmultis++;
 	}
     }
 }
diff --git a/src/winio.c b/src/winio.c
index b14dbccddb16e950cc9298a1575291ed9c69c93b..d0e67781072349aca9b3469dbb95e04651887df5 100644
--- a/src/winio.c
+++ b/src/winio.c
@@ -2450,7 +2450,7 @@ void reset_cursor(void)
  * character of this page.  That is, the first character of converted
  * corresponds to character number actual_x(fileptr->data, start) of the
  * line. */
-void edit_draw(const filestruct *fileptr, const char *converted, int
+void edit_draw(filestruct *fileptr, const char *converted, int
 	line, size_t start)
 {
 #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)) {
 	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) {
 	    int x_start;
 		/* Starting column for mvwaddnstr.  Zero-based. */
@@ -2543,7 +2551,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
 		    }
 		    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.
 		 * First, we have to see if the beginning of the line is
 		 * 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. */
 		const filestruct *end_line;
 
+		fileptr->multiswatching[tmpcolor->id] = FALSE; /* until we find out otherwise */
+
 		while (start_line != NULL && regexec(tmpcolor->start,
 			start_line->data, 1, &startmatch, 0) ==
 			REG_NOMATCH) {
@@ -2631,7 +2641,7 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
 				endmatch.rm_eo) - start);
 
 		    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;
@@ -2676,6 +2686,9 @@ void edit_draw(const filestruct *fileptr, const char *converted, int
 
 				mvwaddnstr(edit, line, x_start,
 					converted + index, paintlen);
+				if (paintlen > 0)
+				    fileptr->multiswatching[tmpcolor->id] = TRUE;
+
 			    }
 			} else {
 			    /* 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
 				 * don't bother checking any more
 				 * starts. */
+				fileptr->multiswatching[tmpcolor->id] = TRUE;
 				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
  * for edit_draw().  The line will be displayed starting with
  * 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;
 	/* 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)
 {
     bool do_redraw = need_vertical_update(0);
-    const filestruct *foo;
+    filestruct *foo;
     ssize_t i;
 
     /* 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
  * 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) ||
 	need_vertical_update(pww_save);
-    const filestruct *foo = NULL;
+    filestruct *foo = NULL;
 
     /* If either old_current or current is offscreen, scroll the edit
      * 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. */
 void edit_refresh(void)
 {
-    const filestruct *foo;
+    filestruct *foo;
     int nlines;
 
     if (openfile->current->lineno < openfile->edittop->lineno ||