diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 800983422ae6f527580caaf9e2748389d9c78f03..fe4a47102ebe9ea48c3da3a93e84ad8b8cb87598 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 7.0aa.  Last change: 2005 Jul 08
+*options.txt*	For Vim version 7.0aa.  Last change: 2005 Jul 11
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -6015,6 +6015,20 @@ A jump table for the options with a short description can be found at |Q_op|.
 			a buffer.  Otherwise: do not split, use current window.
 			Supported in |quickfix| commands that display errors.
 
+						*'synmaxcol'* *'smc'*
+'synmaxcol' 'smc'	number	(default 3000)
+			local to buffer
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	Maximum column in which to search for syntax items.  With longer lines
+	some parts may not be highlighted and following text may not be
+	highlighted correctly (e.g., when the start or end of a region is not
+	recognized because it is beyond 'synmaxcol').
+	This helps to avoid very slow redrawing for an XML file that is one
+	long line.
+	Set to zero to remove the limit.
+
 						*'syntax'* *'syn'*
 'syntax' 'syn'		string	(default empty)
 			local to buffer
@@ -6026,7 +6040,7 @@ A jump table for the options with a short description can be found at |Q_op|.
 	Otherwise this option does not always reflect the current syntax (the
 	b:current_syntax variable does).
 	This option is most useful in a modeline, for a file which syntax is
-	not automatically recognized.  Example, for in an IDL file: >
+	not automatically recognized.  Example, in an IDL file: >
 		/* vim: set syntax=idl : */
 <	To switch off syntax highlighting for the current file, use: >
 		:set syntax=OFF
diff --git a/runtime/doc/tags b/runtime/doc/tags
index b7f8aa7d1936aa60c296f3985519c78f687e2896..f3f13253200ab2e2e997bb49fb491b563b03050d 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -721,6 +721,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'smartcase'	options.txt	/*'smartcase'*
 'smartindent'	options.txt	/*'smartindent'*
 'smarttab'	options.txt	/*'smarttab'*
+'smc'	options.txt	/*'smc'*
 'smd'	options.txt	/*'smd'*
 'sn'	options.txt	/*'sn'*
 'so'	options.txt	/*'so'*
@@ -765,6 +766,7 @@ $VIMRUNTIME	starting.txt	/*$VIMRUNTIME*
 'sws'	options.txt	/*'sws'*
 'sxq'	options.txt	/*'sxq'*
 'syn'	options.txt	/*'syn'*
+'synmaxcol'	options.txt	/*'synmaxcol'*
 'syntax'	options.txt	/*'syntax'*
 't_#2'	term.txt	/*'t_#2'*
 't_#4'	term.txt	/*'t_#4'*
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 8e65ef64e253ef438b00f660fca4a2dc83a1db02..9554f56beb1c0ed095a2d66198b0c4ebe965cdb9 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Jul 09
+*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Jul 11
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -30,11 +30,6 @@ be worked on, but only if you sponsor Vim development.  See |sponsor|.
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-9   Editing a XML file with a long line is extremely slow.  Example file from
-    Randy Parker (Dec 13).  Editing the dictionaries for engspchk plugin with
-    syntax highlighting is also very slow.
-    Limit the searching for items to a few hundred characters?
-
 Add extra list of file locations.  Can be used with:
     :ltag	      list of matching tags, like :tselect
 
diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt
index 10a561ff1a9d3a2c774aec5a41e90f06b07a75ee..702f224016d657f5d201078fb627d96c693d4367 100644
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -1,4 +1,4 @@
-*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Jul 09
+*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Jul 11
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -311,6 +311,8 @@ Options: ~
 'spell'			switch spell checking on/off
 'spelllang'		languages to check spelling for
 'spellsuggest'		methods for spell suggestions
+'synmaxcol'		maximum column to look for syntax items; avoids very
+			slow redrawing when there are very long lines
 'verbosefile'		Log messages in a file.
 
 
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 5bd079ab24897aee5610116ace0a3624cf7f68c2..1192622544c7496ec853332904c1eb31a29d641c 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -4193,6 +4193,8 @@ ExpandGeneric(xp, regmatch, num_file, file, func)
 }
 
 # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
+static void * call_user_expand_func __ARGS((void *(*user_expand_func) __ARGS((char_u *, int, char_u **, int)), expand_T	*xp, int *num_file, char_u ***file));
+
 /*
  * call "user_expand_func()" to invoke a user defined VimL function and return
  * the result (either a string or a List).
diff --git a/src/globals.h b/src/globals.h
index 6bc9b1a5082df86a111d73606a406096d285c86b..72310bd27e953f188d0b2389f5c809a0592985ac 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -900,7 +900,6 @@ EXTERN int	termcap_active INIT(= FALSE);	/* set by starttermcap() */
 EXTERN int	cur_tmode INIT(= TMODE_COOK);	/* input terminal mode */
 EXTERN int	bangredo INIT(= FALSE);	    /* set to TRUE whith ! command */
 EXTERN int	searchcmdlen;		    /* length of previous search cmd */
-EXTERN int	reg_syn INIT(= 0);	    /* vim_regexec() used for syntax */
 #ifdef FEAT_SYN_HL
 EXTERN int	reg_do_extmatch INIT(= 0);  /* Used when compiling regexp:
 					     * REX_SET to allow \z\(...\),
diff --git a/src/misc1.c b/src/misc1.c
index 9154b964523f7c23b20c4ebdbb5a58f47c619c63..29be8e50a5e089da55942d81743fa273ac0e04bf 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -400,6 +400,7 @@ get_number_indent(lnum)
     if (regmatch.regprog != NULL)
     {
 	regmatch.rmm_ic = FALSE;
+	regmatch.rmm_maxcol = 0;
 	if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0))
 	{
 	    pos.lnum = regmatch.endpos[0].lnum + lnum;
diff --git a/src/option.c b/src/option.c
index 9a3cee11ca76ca65cf71ee369551aa9f8759556e..ab0740dd438b9d55f1e74a91c7234602bbc0416b 100644
--- a/src/option.c
+++ b/src/option.c
@@ -129,6 +129,7 @@ typedef enum
     , PV_SUA
     , PV_SW
     , PV_SWF
+    , PV_SMC
     , PV_SYN
     , PV_TAGS
     , PV_TS
@@ -235,6 +236,7 @@ static char_u	*p_sua;
 static long	p_sw;
 static int	p_swf;
 #ifdef FEAT_SYN_HL
+static long	p_smc;
 static char_u	*p_syn;
 static char_u	*p_spc;
 static char_u	*p_spf;
@@ -2115,6 +2117,15 @@ static struct vimoption
     {"switchbuf",   "swb",  P_STRING|P_VI_DEF|P_COMMA|P_NODUP,
 			    (char_u *)&p_swb, PV_NONE,
 			    {(char_u *)"", (char_u *)0L}},
+    {"synmaxcol",   "smc",  P_NUM|P_VI_DEF|P_RBUF,
+#ifdef FEAT_SYN_HL
+			    (char_u *)&p_smc, PV_SMC,
+			    {(char_u *)3000L, (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    },
     {"syntax",	    "syn",  P_STRING|P_ALLOCED|P_VI_DEF|P_NOGLOB|P_NFNAME,
 #ifdef FEAT_SYN_HL
 			    (char_u *)&p_syn, PV_SYN,
@@ -8445,6 +8456,7 @@ get_varp(p)
 #endif
 	case PV_SWF:	return (char_u *)&(curbuf->b_p_swf);
 #ifdef FEAT_SYN_HL
+	case PV_SMC:	return (char_u *)&(curbuf->b_p_smc);
 	case PV_SYN:	return (char_u *)&(curbuf->b_p_syn);
 	case PV_SPC:	return (char_u *)&(curbuf->b_p_spc);
 	case PV_SPF:	return (char_u *)&(curbuf->b_p_spf);
@@ -8761,6 +8773,7 @@ buf_copy_options(buf, flags)
 #ifdef FEAT_SYN_HL
 	    /* Don't copy 'syntax', it must be set */
 	    buf->b_p_syn = empty_option;
+	    buf->b_p_smc = p_smc;
 	    buf->b_p_spc = vim_strsave(p_spc);
 	    (void)compile_cap_prog(buf);
 	    buf->b_p_spf = vim_strsave(p_spf);
diff --git a/src/quickfix.c b/src/quickfix.c
index 5de1e11e16ae45ba619cdd61263ab62c55efbee0..281cac8689e548adb1fed26f7c788a21f5543a62 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -2399,6 +2399,7 @@ ex_vimgrep(eap)
     if (regmatch.regprog == NULL)
 	goto theend;
     regmatch.rmm_ic = p_ic;
+    regmatch.rmm_maxcol = 0;
 
     p = skipwhite(p);
     if (*p == NUL)
diff --git a/src/regexp.c b/src/regexp.c
index dd0b1530a55ebeeb9113f4ecfa6d71e9d0c1f5ac..ae1bfd12fecaa9d77bed5baa0b97e3b0d01c8038 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -866,8 +866,8 @@ skip_anyof(p)
     int		l;
 #endif
 
-    cpo_lit = (!reg_syn && vim_strchr(p_cpo, CPO_LITERAL) != NULL);
-    cpo_bsl = (!reg_syn && vim_strchr(p_cpo, CPO_BACKSL) != NULL);
+    cpo_lit = vim_strchr(p_cpo, CPO_LITERAL) != NULL;
+    cpo_bsl = vim_strchr(p_cpo, CPO_BACKSL) != NULL;
 
     if (*p == '^')	/* Complement of range. */
 	++p;
@@ -1573,8 +1573,8 @@ regatom(flagp)
     int		    extra = 0;
 
     *flagp = WORST;		/* Tentatively. */
-    cpo_lit = (!reg_syn && vim_strchr(p_cpo, CPO_LITERAL) != NULL);
-    cpo_bsl = (!reg_syn && vim_strchr(p_cpo, CPO_BACKSL) != NULL);
+    cpo_lit = vim_strchr(p_cpo, CPO_LITERAL) != NULL;
+    cpo_bsl = vim_strchr(p_cpo, CPO_BACKSL) != NULL;
 
     c = getchr();
     switch (c)
@@ -3043,6 +3043,12 @@ static int	ireg_ic;
 static int	ireg_icombine;
 #endif
 
+/*
+ * Copy of "rmm_maxcol": maximum column to search for a match.  Zero when
+ * there is no maximum.
+ */
+static int	ireg_maxcol;
+
 /*
  * Sometimes need to save a copy of a line.  Since alloc()/free() is very
  * slow, we keep one allocated piece of memory and only re-allocate it when
@@ -3203,6 +3209,7 @@ vim_regexec(rmp, line, col)
 #ifdef FEAT_MBYTE
     ireg_icombine = FALSE;
 #endif
+    ireg_maxcol = 0;
     return (vim_regexec_both(line, col) != 0);
 }
 
@@ -3226,6 +3233,7 @@ vim_regexec_nl(rmp, line, col)
 #ifdef FEAT_MBYTE
     ireg_icombine = FALSE;
 #endif
+    ireg_maxcol = 0;
     return (vim_regexec_both(line, col) != 0);
 }
 #endif
@@ -3260,6 +3268,7 @@ vim_regexec_multi(rmp, win, buf, lnum, col)
 #ifdef FEAT_MBYTE
     ireg_icombine = FALSE;
 #endif
+    ireg_maxcol = rmp->rmm_maxcol;
 
     /* Need to switch to buffer "buf" to make vim_iswordc() work. */
     curbuf = buf;
@@ -3317,6 +3326,10 @@ vim_regexec_both(line, col)
     if (prog_magic_wrong())
 	goto theend;
 
+    /* If the start column is past the maximum column: no need to try. */
+    if (ireg_maxcol > 0 && col >= ireg_maxcol)
+	goto theend;
+
     /* If pattern contains "\c" or "\C": overrule value of ireg_ic */
     if (prog->regflags & RF_ICASE)
 	ireg_ic = TRUE;
@@ -3428,6 +3441,13 @@ vim_regexec_both(line, col)
 		col = (int)(s - regline);
 	    }
 
+	    /* Check for maximum column to try. */
+	    if (ireg_maxcol > 0 && col >= ireg_maxcol)
+	    {
+		retval = 0;
+		break;
+	    }
+
 	    retval = regtry(prog, col);
 	    if (retval > 0)
 		break;
diff --git a/src/regexp.h b/src/regexp.h
index 15611ed8185dc4c4a50cf99da88ec85c06dc52eb..fee6cc45032623dd52dd893b2b62fdf59f6aaf24 100644
--- a/src/regexp.h
+++ b/src/regexp.h
@@ -64,6 +64,7 @@ typedef struct
     lpos_T		startpos[NSUBEXP];
     lpos_T		endpos[NSUBEXP];
     int			rmm_ic;
+    int			rmm_maxcol;	/* when not zero: maximum column */
 } regmmatch_T;
 
 /*
diff --git a/src/search.c b/src/search.c
index 034d9c4a8c9485163e189a0dbda014bf2794f119..84fcbab0cb10adc588b4af00d65d648c5844e6ff 100644
--- a/src/search.c
+++ b/src/search.c
@@ -215,6 +215,7 @@ search_regcomp(pat, pat_save, pat_use, options, regmatch)
     }
 
     regmatch->rmm_ic = ignorecase(pat);
+    regmatch->rmm_maxcol = 0;
     regmatch->regprog = vim_regcomp(pat, magic ? RE_MAGIC : 0);
     if (regmatch->regprog == NULL)
 	return FAIL;
diff --git a/src/structs.h b/src/structs.h
index 7e144447d606cf43e00d7aa2681156efe4ae4433..b7f39febfd6b749624b03d57e329436152668c25 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1344,6 +1344,7 @@ struct file_buffer
 #endif
     int		b_p_swf;	/* 'swapfile' */
 #ifdef FEAT_SYN_HL
+    long	b_p_smc;	/* 'synmaxcol' */
     char_u	*b_p_syn;	/* 'syntax' */
     char_u	*b_p_spc;	/* 'spellcapcheck' */
     regprog_T	*b_cap_prog;	/* program for 'spellcapcheck' */
diff --git a/src/syntax.c b/src/syntax.c
index 6639df0b8cf33e6cd8d76cdf2f756ff19b2e71a7..4ecec9b38e8d21aad5193ad719e3e3e8deb4bd78 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -463,8 +463,6 @@ syntax_start(wp, lnum)
     int		dist;
     static int	changedtick = 0;	/* remember the last change ID */
 
-    reg_syn = TRUE;	/* let vim_regexec() know we're using syntax */
-
     /*
      * After switching buffers, invalidate current_state.
      * Also do this when a change was made, the current state may be invalid
@@ -483,7 +481,7 @@ syntax_start(wp, lnum)
      */
     syn_stack_alloc();
     if (syn_buf->b_sst_array == NULL)
-	goto theend;		/* out of memory */
+	return;		/* out of memory */
     syn_buf->b_sst_lasttick = display_tick;
 
     /*
@@ -607,9 +605,6 @@ syntax_start(wp, lnum)
     }
 
     syn_start_line();
-
-theend:
-    reg_syn = FALSE;
 }
 
 /*
@@ -1604,8 +1599,6 @@ syntax_check_changed(lnum)
     int		retval = TRUE;
     synstate_T	*sp;
 
-    reg_syn = TRUE;	/* let vim_regexec() know we're using syntax */
-
     /*
      * Check the state stack when:
      * - lnum is just below the previously syntaxed line.
@@ -1639,8 +1632,6 @@ syntax_check_changed(lnum)
 	}
     }
 
-    reg_syn = FALSE;
-
     return retval;
 }
 
@@ -1707,8 +1698,6 @@ get_syntax_attr(col, can_spell)
     if (syn_buf->b_sst_array == NULL)
 	return 0;
 
-    reg_syn = TRUE;	/* let vim_regexec() know we're using syntax */
-
     /* Make sure current_state is valid */
     if (INVALID_STATE(&current_state))
 	validate_current_state();
@@ -1722,7 +1711,6 @@ get_syntax_attr(col, can_spell)
 	++current_col;
     }
 
-    reg_syn = FALSE;
     return attr;
 }
 
@@ -2999,7 +2987,7 @@ syn_getcurline()
 }
 
 /*
- * Call vim_regexec() to match in syn_buf.
+ * Call vim_regexec() to find a match with "rmp" in "syn_buf".
  * Returns TRUE when there is a match.
  */
     static int
@@ -3008,6 +2996,7 @@ syn_regexec(rmp, lnum, col)
     linenr_T	lnum;
     colnr_T	col;
 {
+    rmp->rmm_maxcol = syn_buf->b_p_smc;
     if (vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col) > 0)
     {
 	rmp->startpos[0].lnum += lnum;
diff --git a/src/version.h b/src/version.h
index bff24b2127d728342952343f1247772a5fce80dd..9031d953cd1f79ac83fd7b96957e5efbc158b47a 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 9)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 9, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 11)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 11, compiled "