diff --git a/ChangeLog b/ChangeLog
index cdc58d04e356cda49782e98fabb18ab14bfe335d..7918e73727ed3d069ed364f05c24a091ceb2d1b4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2009-02-05 Chris Allegretta <chrisa@asty.org>
+	* More color syntax speedups:  Determine in reset_multis() whether we really need to call
+	  edit_refresh().  Additional global var edit_refresh_needed() to hopefully reduce
+	  repeated calls to the function.  New helper funcs reset_multis_before() and 
+	  reset_multis_after().
+
+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.
+
 2009-01-29 Chris Allegretta <chrisa@asty.org>
 	* nano.c (move_to_filestruct) - properky initialize new fileage for multiswatching, sigh.
 	  Fix cut sefaults discovered by Mike Frysinger.
diff --git a/src/color.c b/src/color.c
index deac8b4ec36944c80706aeaa31c8ac9fad1546f3..2211ceb86112da19d3b6f8b37f3b6109b429c591 100644
--- a/src/color.c
+++ b/src/color.c
@@ -254,33 +254,68 @@ void color_update(void)
     }
 }
 
-/* Reset multi line strings around a filestruct ptr, trying to be smart about stopping */
-void reset_multis(filestruct *fileptr) 
+/* Reset the multicolor info cache for records for any lines which need
+   to be recalculated */
+void reset_multis_after(filestruct *fileptr, int mindex)
+{
+    filestruct *oof;
+    for (oof = fileptr->next; oof != NULL; oof = oof->next) {
+	if (oof->multidata == NULL)
+	    continue;
+	if (oof->multidata[mindex] != 0)
+	    oof->multidata[mindex] = -1;
+	else
+	    break;
+    }
+}
+
+void reset_multis_before(filestruct *fileptr, int mindex)
 {
-    int i;
     filestruct *oof;
+    for (oof = fileptr->prev; oof != NULL; oof = oof->prev) {
+	if (oof->multidata == NULL)
+	    continue;
+	if (oof->multidata[mindex] != 0)
+	    oof->multidata[mindex] = -1;
+	else
+	    break;
+    }
+}
+
+
+/* Reset multi line strings around a filestruct ptr, trying to be smart about stopping */
+void reset_multis(filestruct *fileptr)
+{
+    int nobegin, noend;
+    regmatch_t startmatch, endmatch;
+    const colortype *tmpcolor = openfile->colorstrings;
 
     if (!openfile->syntax)
 	return;
 
-    for (i = 0; i < openfile->syntax->nmultis; i++) {
-	for (oof = fileptr->next; oof != NULL; oof = oof->next) {
-	    if (oof->multidata == NULL)
+    for (; tmpcolor != NULL; tmpcolor = tmpcolor->next) {
+
+	/* If it's not a multi-line regex, amscray */
+	if (tmpcolor->end == NULL)
+	    continue;
+
+	/* Figure out where the first begin and end are to determine if
+	   things changed drastically for the precalculated multi values */
+        nobegin = regexec(tmpcolor->start, fileptr->data, 1, &startmatch, 0);
+        noend = regexec(tmpcolor->end, fileptr->data, 1, &endmatch, 0);
+	if (fileptr->multidata[tmpcolor->id] ==  CWHOLELINE) {
+	    if (nobegin && noend)
 		continue;
-	    if (oof->multidata[i] != 0)
-		oof->multidata[i] = -1;
-	    else
-		break;
+	} else if (fileptr->multidata[tmpcolor->id] & CBEGINBEFORE && !noend
+	  && (nobegin || endmatch.rm_eo > startmatch.rm_eo)) {
+	    reset_multis_after(fileptr, tmpcolor->id);
+	    continue;
 	}
-	for (oof = fileptr->prev; oof != NULL; oof = oof->prev) {
-	    if (oof->multidata == NULL)
-		continue;
-	    if (oof->multidata[i] == 0)
-		oof->multidata[i] = -1;
-	    else
-		break;
-	    }
-	fileptr->multidata[i] = -1;
+
+	/* If we got here assume the worst */
+	reset_multis_before(fileptr, tmpcolor->id);
+	reset_multis_after(fileptr, tmpcolor->id);
+	fileptr->multidata[tmpcolor->id] = -1;
     }
 }
 #endif /* ENABLE_COLOR */
diff --git a/src/global.c b/src/global.c
index ce68df57a6c57e82f48f9344d07b78a0aeaed85e..0c8e282a2cd2ed30de683c0c37f18bba06b45cc8 100644
--- a/src/global.c
+++ b/src/global.c
@@ -147,8 +147,13 @@ syntaxtype *syntaxes = NULL;
 	/* The global list of color syntaxes. */
 char *syntaxstr = NULL;
 	/* The color syntax name specified on the command line. */
+
 #endif
 
+bool edit_refresh_needed = NULL;
+	/* Did a command mangle enough of the buffer refresh that we 
+	   should repaint the screen */
+
 const shortcut *currshortcut;
 	/* The current shortcut list we're using. */
 int currmenu;
diff --git a/src/nano.c b/src/nano.c
index 36843188fc3b3b635f262be045b4530bad9181f5..3d3bbfe697de3542676d72def40320dd4f517086 100644
--- a/src/nano.c
+++ b/src/nano.c
@@ -32,6 +32,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <locale.h>
+#include <time.h>
 #ifdef ENABLE_UTF8
 #include <langinfo.h>
 #endif
@@ -1598,7 +1599,10 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
 				if (!f->viewok && openfile->syntax != NULL 
 					&& openfile->current->multidata && openfile->syntax->nmultis > 0) {
 				    reset_multis(openfile->current);
+				}
+				if (edit_refresh_needed) {
 				    edit_refresh();
+				    edit_refresh_needed = FALSE;
 				}
 #endif
 			    }
@@ -1871,9 +1875,10 @@ void do_output(char *output, size_t output_len, bool allow_cntrls)
 #ifdef ENABLE_COLOR
     reset_multis(openfile->current);
 #endif
-    if (do_refresh)
+    if (do_refresh) {
 	edit_refresh();
-    else
+	edit_refresh_needed = FALSE;
+    } else
 	update_line(openfile->current, openfile->current_x);
 }
 
diff --git a/src/proto.h b/src/proto.h
index 628f90b1b2b180f55f3edfdb4f988785e61d53cb..0e9622759d3d714ce22911a774cb9a3340e77d2e 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -100,6 +100,7 @@ extern syntaxtype *syntaxes;
 extern char *syntaxstr;
 #endif
 
+extern bool edit_refresh_needed;
 extern const shortcut *currshortcut;
 extern int currmenu;
 
diff --git a/src/text.c b/src/text.c
index 4483ec11697f2539ea49c5ef9bf4a5e5810ebe10..83ef8e057196c1d19a6da3f11c21040b8135e3c4 100644
--- a/src/text.c
+++ b/src/text.c
@@ -148,7 +148,7 @@ void do_delete(void)
 #endif
 
     if (do_refresh)
-	edit_refresh();
+	edit_refresh_needed = TRUE;
     else
 	update_line(openfile->current, openfile->current_x);
 }
@@ -346,7 +346,7 @@ void do_indent(ssize_t cols)
 	set_modified();
 
 	/* Update the screen. */
-	edit_refresh();
+	edit_refresh_needed = TRUE;
     }
 }
 
@@ -423,7 +423,7 @@ void redo_cut(undo *u) {
 	openfile->mark_set = FALSE;
         openfile->mark_begin = NULL;
         openfile->mark_begin_x = 0;
-	edit_refresh();
+	edit_refresh_needed = TRUE;
 }
 
 /* Undo the last thing(s) we did */
@@ -714,7 +714,7 @@ void do_enter(void)
 
     openfile->placewewant = xplustabs();
 
-    edit_refresh();
+    edit_refresh_needed = TRUE;
 }
 
 #ifndef NANO_TINY
@@ -1956,7 +1956,7 @@ void do_justify(bool full_justify)
 		last_par_line = openfile->filebot;
 		break;
 	    } else {
-		edit_refresh();
+		edit_refresh_needed = TRUE;
 		return;
 	    }
 	}
@@ -2268,7 +2268,7 @@ void do_justify(bool full_justify)
 
 	    if (!openfile->modified)
 		titlebar(NULL);
-	    edit_refresh();
+	    edit_refresh_needed = TRUE;
 	}
     } else {
 	unget_kbinput(kbinput, meta_key, func_key);
@@ -2621,7 +2621,7 @@ const char *do_int_speller(const char *tempfile_name)
 
     free(read_buff);
     search_replace_abort();
-    edit_refresh();
+    edit_refresh_needed = TRUE;
 
     /* Process the end of the spell process. */
     waitpid(pid_spell, &spell_status, 0);