Blob Blame History Raw
To: vim-dev@vim.org
Subject: Patch 7.1.236
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
------------

Patch 7.1.236
Problem:    When using 'incsearch' and 'hlsearch' a complicated pattern may
	    make Vim hang until CTRL-C is pressed.
Solution:   Add the 'redrawtime' option.
Files:	    runtime/doc/options.txt, src/ex_cmds.c, src/ex_docmd.c,
	    src/ex_getln.c, src/gui.c, src/misc1.c, src/normal.c,
	    src/option.c, src/quickfix.c, src/regexp.c, src/proto/regexp.pro,
	    src/proto/search.pro, src/search.c, src/screen.c,
	    src/option.h, src/spell.c, src/structs.h, src/syntax.c, src/tag.c,
	    src/vim.h


*** ../vim-7.1.235/runtime/doc/options.txt	Sun Aug 12 16:55:01 2007
--- runtime/doc/options.txt	Sat Jan 19 14:01:22 2008
***************
*** 3618,3623 ****
--- 3636,3642 ----
  	When you get bored looking at the highlighted matches, you can turn it
  	off with |:nohlsearch|.  As soon as you use a search command, the
  	highlighting comes back.
+ 	'redrawtime' specifies the maximum time spend on finding matches.
  	When the search pattern can match an end-of-line, Vim will try to
  	highlight all of the matched text.  However, this depends on where the
  	search starts.  This will be the first line in the window or the first
***************
*** 3851,3856 ****
--- 3870,3879 ----
  	original position when no match is found and when pressing <Esc>.  You
  	still need to finish the search command with <Enter> to move the
  	cursor to the match.
+ 	When compiled with the |+reltime| feature Vim only searches for about
+ 	half a second.  With a complicated pattern and/or a lot of text the
+ 	match may not be found.  This is to avoid that Vim hangs while you
+ 	are typing the pattern.
  	The highlighting can be set with the 'i' flag in 'highlight'.
  	See also: 'hlsearch'.
  	CTRL-L can be used to add one character from after the current match
***************
*** 5185,5190 ****
--- 5210,5227 ----
  	{not in Vi:}  When using the ":view" command the 'readonly' option is
  	set for the newly edited buffer.
  
+ 						*'redrawtime'* *'rdt'*
+ 'redrawtime' 'rdt'	number	(default 2000)
+ 			global
+ 			{not in Vi}
+ 			{only available when compiled with the |+reltime|
+ 			feature}
+ 	The time in milliseconds for redrawing the display.  This applies to
+ 	searching for patterns for 'hlsearch' and |:match| highlighting.
+ 	When redrawing takes more than this many milliseconds no further
+ 	matches will be highlighted.  This is used to avoid that Vim hangs
+ 	when using a very complicated pattern.
+ 
  						*'remap'* *'noremap'*
  'remap'			boolean	(default on)
  			global
*** ../vim-7.1.235/src/ex_cmds.c	Sun Jan 13 13:30:34 2008
--- src/ex_cmds.c	Sat Jan 19 13:04:28 2008
***************
*** 4446,4452 ****
  #endif
  		); ++lnum)
      {
! 	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
  	if (nmatch)
  	{
  	    colnr_T	copycol;
--- 4446,4453 ----
  #endif
  		); ++lnum)
      {
! 	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
! 							    (colnr_T)0, NULL);
  	if (nmatch)
  	{
  	    colnr_T	copycol;
***************
*** 4957,4963 ****
  			|| (do_ask && !re_lookbehind(regmatch.regprog))
  			|| nmatch_tl > 0
  			|| (nmatch = vim_regexec_multi(&regmatch, curwin,
! 				       curbuf, sub_firstlnum, matchcol)) == 0
  			|| regmatch.startpos[0].lnum > 0)
  		{
  		    if (new_start != NULL)
--- 4958,4965 ----
  			|| (do_ask && !re_lookbehind(regmatch.regprog))
  			|| nmatch_tl > 0
  			|| (nmatch = vim_regexec_multi(&regmatch, curwin,
! 							curbuf, sub_firstlnum,
! 							 matchcol, NULL)) == 0
  			|| regmatch.startpos[0].lnum > 0)
  		{
  		    if (new_start != NULL)
***************
*** 5022,5028 ****
  		    }
  		    if (nmatch == -1 && !lastone)
  			nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
! 						     sub_firstlnum, matchcol);
  
  		    /*
  		     * 5. break if there isn't another match in this line
--- 5024,5030 ----
  		    }
  		    if (nmatch == -1 && !lastone)
  			nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
! 					       sub_firstlnum, matchcol, NULL);
  
  		    /*
  		     * 5. break if there isn't another match in this line
***************
*** 5252,5258 ****
      for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum)
      {
  	/* a match on this line? */
! 	match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
  	if ((type == 'g' && match) || (type == 'v' && !match))
  	{
  	    ml_setmarked(lnum);
--- 5254,5261 ----
      for (lnum = eap->line1; lnum <= eap->line2 && !got_int; ++lnum)
      {
  	/* a match on this line? */
! 	match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
! 							    (colnr_T)0, NULL);
  	if ((type == 'g' && match) || (type == 'v' && !match))
  	{
  	    ml_setmarked(lnum);
*** ../vim-7.1.235/src/ex_docmd.c	Sun Jan 13 17:11:25 2008
--- src/ex_docmd.c	Fri Jan 18 21:01:16 2008
***************
*** 3931,3937 ****
  				curwin->w_cursor.col = 0;
  			    searchcmdlen = 0;
  			    if (!do_search(NULL, c, cmd, 1L,
! 				      SEARCH_HIS + SEARCH_MSG + SEARCH_START))
  			    {
  				curwin->w_cursor = pos;
  				cmd = NULL;
--- 3931,3938 ----
  				curwin->w_cursor.col = 0;
  			    searchcmdlen = 0;
  			    if (!do_search(NULL, c, cmd, 1L,
! 					SEARCH_HIS + SEARCH_MSG + SEARCH_START,
! 					NULL))
  			    {
  				curwin->w_cursor = pos;
  				cmd = NULL;
*** ../vim-7.1.235/src/ex_getln.c	Fri Jan 18 13:15:32 2008
--- src/ex_getln.c	Fri Jan 18 21:34:42 2008
***************
*** 1709,1714 ****
--- 1709,1717 ----
  	if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
  	{
  	    pos_T	end_pos;
+ #ifdef FEAT_RELTIME
+ 	    proftime_T	tm;
+ #endif
  
  	    /* if there is a character waiting, search and redraw later */
  	    if (char_avail())
***************
*** 1727,1734 ****
  		cursor_off();		/* so the user knows we're busy */
  		out_flush();
  		++emsg_off;    /* So it doesn't beep if bad expr */
  		i = do_search(NULL, firstc, ccline.cmdbuff, count,
! 			SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK);
  		--emsg_off;
  		/* if interrupted while searching, behave like it failed */
  		if (got_int)
--- 1730,1747 ----
  		cursor_off();		/* so the user knows we're busy */
  		out_flush();
  		++emsg_off;    /* So it doesn't beep if bad expr */
+ #ifdef FEAT_RELTIME
+ 		/* Set the time limit to half a second. */
+ 		profile_setlimit(500L, &tm);
+ #endif
  		i = do_search(NULL, firstc, ccline.cmdbuff, count,
! 			SEARCH_KEEP + SEARCH_OPT + SEARCH_NOOF + SEARCH_PEEK,
! #ifdef FEAT_RELTIME
! 			&tm
! #else
! 			NULL
! #endif
! 			);
  		--emsg_off;
  		/* if interrupted while searching, behave like it failed */
  		if (got_int)
*** ../vim-7.1.235/src/gui.c	Thu Jan  3 16:14:25 2008
--- src/gui.c	Fri Jan 18 21:01:36 2008
***************
*** 5052,5058 ****
  	/* Search for the next match. */
  	i = msg_scroll;
  	do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
! 						    SEARCH_MSG + SEARCH_MARK);
  	msg_scroll = i;	    /* don't let an error message set msg_scroll */
      }
  
--- 5052,5058 ----
  	/* Search for the next match. */
  	i = msg_scroll;
  	do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
! 					      SEARCH_MSG + SEARCH_MARK, NULL);
  	msg_scroll = i;	    /* don't let an error message set msg_scroll */
      }
  
*** ../vim-7.1.235/src/misc1.c	Thu Jan  3 12:42:38 2008
--- src/misc1.c	Sat Jan 19 13:04:39 2008
***************
*** 437,443 ****
      {
  	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;
  	    pos.col = regmatch.endpos[0].col;
--- 437,444 ----
      {
  	regmatch.rmm_ic = FALSE;
  	regmatch.rmm_maxcol = 0;
! 	if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
! 							    (colnr_T)0, NULL))
  	{
  	    pos.lnum = regmatch.endpos[0].lnum + lnum;
  	    pos.col = regmatch.endpos[0].col;
*** ../vim-7.1.235/src/normal.c	Sat Jan 12 17:11:25 2008
--- src/normal.c	Fri Jan 18 21:01:47 2008
***************
*** 6093,6099 ****
      curwin->w_set_curswant = TRUE;
  
      i = do_search(cap->oap, dir, pat, cap->count1,
! 				 opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG);
      if (i == 0)
  	clearop(cap->oap);
      else
--- 6093,6099 ----
      curwin->w_set_curswant = TRUE;
  
      i = do_search(cap->oap, dir, pat, cap->count1,
! 			   opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL);
      if (i == 0)
  	clearop(cap->oap);
      else
*** ../vim-7.1.235/src/option.c	Tue Oct  2 20:40:01 2007
--- src/option.c	Sat Jan 19 13:44:33 2008
***************
*** 1991,1996 ****
--- 1991,2003 ----
      {"redraw",	    NULL,   P_BOOL|P_VI_DEF,
  			    (char_u *)NULL, PV_NONE,
  			    {(char_u *)FALSE, (char_u *)0L}},
+     {"redrawtime",  "rdt",  P_NUM|P_VI_DEF,
+ #ifdef FEAT_RELTIME
+ 			    (char_u *)&p_rdt, PV_NONE,
+ #else
+ 			    (char_u *)NULL, PV_NONE,
+ #endif
+ 			    {(char_u *)2000L, (char_u *)0L}},
      {"remap",	    NULL,   P_BOOL|P_VI_DEF,
  			    (char_u *)&p_remap, PV_NONE,
  			    {(char_u *)TRUE, (char_u *)0L}},
*** ../vim-7.1.235/src/quickfix.c	Sun Sep 30 14:00:41 2007
--- src/quickfix.c	Sat Jan 19 13:04:53 2008
***************
*** 1803,1809 ****
  	    /* Move the cursor to the first line in the buffer */
  	    save_cursor = curwin->w_cursor;
  	    curwin->w_cursor.lnum = 0;
! 	    if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1, SEARCH_KEEP))
  		curwin->w_cursor = save_cursor;
  	}
  
--- 1803,1810 ----
  	    /* Move the cursor to the first line in the buffer */
  	    save_cursor = curwin->w_cursor;
  	    curwin->w_cursor.lnum = 0;
! 	    if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
! 							   SEARCH_KEEP, NULL))
  		curwin->w_cursor = save_cursor;
  	}
  
***************
*** 3159,3165 ****
  	    {
  		col = 0;
  		while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
! 								     col) > 0)
  		{
  		    ;
  		    if (qf_add_entry(qi, &prevp,
--- 3160,3166 ----
  	    {
  		col = 0;
  		while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
! 							       col, NULL) > 0)
  		{
  		    ;
  		    if (qf_add_entry(qi, &prevp,
*** ../vim-7.1.235/src/regexp.c	Fri Jan 18 20:36:40 2008
--- src/regexp.c	Sat Jan 19 15:18:12 2008
***************
*** 3040,3046 ****
  } save_se_T;
  
  static char_u	*reg_getline __ARGS((linenr_T lnum));
! static long	vim_regexec_both __ARGS((char_u *line, colnr_T col));
  static long	regtry __ARGS((regprog_T *prog, colnr_T col));
  static void	cleanup_subexpr __ARGS((void));
  #ifdef FEAT_SYN_HL
--- 3040,3046 ----
  } save_se_T;
  
  static char_u	*reg_getline __ARGS((linenr_T lnum));
! static long	vim_regexec_both __ARGS((char_u *line, colnr_T col, proftime_T *tm));
  static long	regtry __ARGS((regprog_T *prog, colnr_T col));
  static void	cleanup_subexpr __ARGS((void));
  #ifdef FEAT_SYN_HL
***************
*** 3284,3290 ****
      ireg_icombine = FALSE;
  #endif
      ireg_maxcol = 0;
!     return (vim_regexec_both(line, col) != 0);
  }
  
  #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
--- 3284,3290 ----
      ireg_icombine = FALSE;
  #endif
      ireg_maxcol = 0;
!     return (vim_regexec_both(line, col, NULL) != 0);
  }
  
  #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
***************
*** 3308,3314 ****
      ireg_icombine = FALSE;
  #endif
      ireg_maxcol = 0;
!     return (vim_regexec_both(line, col) != 0);
  }
  #endif
  
--- 3308,3314 ----
      ireg_icombine = FALSE;
  #endif
      ireg_maxcol = 0;
!     return (vim_regexec_both(line, col, NULL) != 0);
  }
  #endif
  
***************
*** 3321,3332 ****
   * match otherwise.
   */
      long
! vim_regexec_multi(rmp, win, buf, lnum, col)
      regmmatch_T	*rmp;
      win_T	*win;		/* window in which to search or NULL */
      buf_T	*buf;		/* buffer in which to search */
      linenr_T	lnum;		/* nr of line to start looking for match */
      colnr_T	col;		/* column to start looking for match */
  {
      long	r;
      buf_T	*save_curbuf = curbuf;
--- 3321,3333 ----
   * match otherwise.
   */
      long
! vim_regexec_multi(rmp, win, buf, lnum, col, tm)
      regmmatch_T	*rmp;
      win_T	*win;		/* window in which to search or NULL */
      buf_T	*buf;		/* buffer in which to search */
      linenr_T	lnum;		/* nr of line to start looking for match */
      colnr_T	col;		/* column to start looking for match */
+     proftime_T	*tm;		/* timeout limit or NULL */
  {
      long	r;
      buf_T	*save_curbuf = curbuf;
***************
*** 3346,3352 ****
  
      /* Need to switch to buffer "buf" to make vim_iswordc() work. */
      curbuf = buf;
!     r = vim_regexec_both(NULL, col);
      curbuf = save_curbuf;
  
      return r;
--- 3347,3353 ----
  
      /* Need to switch to buffer "buf" to make vim_iswordc() work. */
      curbuf = buf;
!     r = vim_regexec_both(NULL, col, tm);
      curbuf = save_curbuf;
  
      return r;
***************
*** 3356,3365 ****
   * Match a regexp against a string ("line" points to the string) or multiple
   * lines ("line" is NULL, use reg_getline()).
   */
      static long
! vim_regexec_both(line, col)
      char_u	*line;
      colnr_T	col;		/* column to start looking for match */
  {
      regprog_T	*prog;
      char_u	*s;
--- 3357,3368 ----
   * Match a regexp against a string ("line" points to the string) or multiple
   * lines ("line" is NULL, use reg_getline()).
   */
+ /*ARGSUSED*/
      static long
! vim_regexec_both(line, col, tm)
      char_u	*line;
      colnr_T	col;		/* column to start looking for match */
+     proftime_T	*tm;		/* timeout limit or NULL */
  {
      regprog_T	*prog;
      char_u	*s;
***************
*** 3502,3507 ****
--- 3505,3513 ----
      }
      else
      {
+ #ifdef FEAT_RELTIME
+ 	int tm_count = 0;
+ #endif
  	/* Messy cases:  unanchored match. */
  	while (!got_int)
  	{
***************
*** 3550,3555 ****
--- 3556,3570 ----
  	    else
  #endif
  		++col;
+ #ifdef FEAT_RELTIME
+ 	    /* Check for timeout once in a twenty times to avoid overhead. */
+ 	    if (tm != NULL && ++tm_count == 20)
+ 	    {
+ 		tm_count = 0;
+ 		if (profile_passed_limit(tm))
+ 		    break;
+ 	    }
+ #endif
  	}
      }
  
*** ../vim-7.1.235/src/proto/regexp.pro	Sat May  5 19:42:08 2007
--- src/proto/regexp.pro	Sat Jan 19 13:14:09 2008
***************
*** 1,13 ****
  /* regexp.c */
- void free_regexp_stuff __ARGS((void));
  int re_multiline __ARGS((regprog_T *prog));
  int re_lookbehind __ARGS((regprog_T *prog));
  char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp));
  regprog_T *vim_regcomp __ARGS((char_u *expr, int re_flags));
  int vim_regcomp_had_eol __ARGS((void));
  int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
  int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
! long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col));
  reg_extmatch_T *ref_extmatch __ARGS((reg_extmatch_T *em));
  void unref_extmatch __ARGS((reg_extmatch_T *em));
  char_u *regtilde __ARGS((char_u *source, int magic));
--- 1,13 ----
  /* regexp.c */
  int re_multiline __ARGS((regprog_T *prog));
  int re_lookbehind __ARGS((regprog_T *prog));
  char_u *skip_regexp __ARGS((char_u *startp, int dirc, int magic, char_u **newp));
  regprog_T *vim_regcomp __ARGS((char_u *expr, int re_flags));
  int vim_regcomp_had_eol __ARGS((void));
+ void free_regexp_stuff __ARGS((void));
  int vim_regexec __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
  int vim_regexec_nl __ARGS((regmatch_T *rmp, char_u *line, colnr_T col));
! long vim_regexec_multi __ARGS((regmmatch_T *rmp, win_T *win, buf_T *buf, linenr_T lnum, colnr_T col, proftime_T *tm));
  reg_extmatch_T *ref_extmatch __ARGS((reg_extmatch_T *em));
  void unref_extmatch __ARGS((reg_extmatch_T *em));
  char_u *regtilde __ARGS((char_u *source, int magic));
*** ../vim-7.1.235/src/proto/search.pro	Sun Jan  6 20:05:36 2008
--- src/proto/search.pro	Fri Jan 18 21:03:49 2008
***************
*** 11,17 ****
  void set_last_search_pat __ARGS((char_u *s, int idx, int magic, int setlast));
  void last_pat_prog __ARGS((regmmatch_T *regmatch));
  int searchit __ARGS((win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm));
! int do_search __ARGS((oparg_T *oap, int dirc, char_u *pat, long count, int options));
  int search_for_exact_line __ARGS((buf_T *buf, pos_T *pos, int dir, char_u *pat));
  int searchc __ARGS((cmdarg_T *cap, int t_cmd));
  pos_T *findmatch __ARGS((oparg_T *oap, int initc));
--- 11,17 ----
  void set_last_search_pat __ARGS((char_u *s, int idx, int magic, int setlast));
  void last_pat_prog __ARGS((regmmatch_T *regmatch));
  int searchit __ARGS((win_T *win, buf_T *buf, pos_T *pos, int dir, char_u *pat, long count, int options, int pat_use, linenr_T stop_lnum, proftime_T *tm));
! int do_search __ARGS((oparg_T *oap, int dirc, char_u *pat, long count, int options, proftime_T *tm));
  int search_for_exact_line __ARGS((buf_T *buf, pos_T *pos, int dir, char_u *pat));
  int searchc __ARGS((cmdarg_T *cap, int t_cmd));
  pos_T *findmatch __ARGS((oparg_T *oap, int initc));
*** ../vim-7.1.235/src/search.c	Sun Jan  6 20:05:36 2008
--- src/search.c	Sat Jan 19 13:13:25 2008
***************
*** 606,612 ****
  		 * Look for a match somewhere in line "lnum".
  		 */
  		nmatched = vim_regexec_multi(&regmatch, win, buf,
! 							    lnum, (colnr_T)0);
  		/* Abort searching on an error (e.g., out of stack). */
  		if (called_emsg)
  		    break;
--- 606,618 ----
  		 * Look for a match somewhere in line "lnum".
  		 */
  		nmatched = vim_regexec_multi(&regmatch, win, buf,
! 						      lnum, (colnr_T)0,
! #ifdef FEAT_RELTIME
! 						      tm
! #else
! 						      NULL
! #endif
! 						      );
  		/* Abort searching on an error (e.g., out of stack). */
  		if (called_emsg)
  		    break;
***************
*** 615,623 ****
  		    /* match may actually be in another line when using \zs */
  		    matchpos = regmatch.startpos[0];
  		    endpos = regmatch.endpos[0];
! # ifdef FEAT_EVAL
  		    submatch = first_submatch(&regmatch);
! # endif
  		    /* Line me be past end of buffer for "\n\zs". */
  		    if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
  			ptr = (char_u *)"";
--- 621,629 ----
  		    /* match may actually be in another line when using \zs */
  		    matchpos = regmatch.startpos[0];
  		    endpos = regmatch.endpos[0];
! #ifdef FEAT_EVAL
  		    submatch = first_submatch(&regmatch);
! #endif
  		    /* Line me be past end of buffer for "\n\zs". */
  		    if (lnum + matchpos.lnum > buf->b_ml.ml_line_count)
  			ptr = (char_u *)"";
***************
*** 693,699 ****
  			    if (ptr[matchcol] == NUL
  				    || (nmatched = vim_regexec_multi(&regmatch,
  					      win, buf, lnum + matchpos.lnum,
! 					      matchcol)) == 0)
  			    {
  				match_ok = FALSE;
  				break;
--- 699,711 ----
  			    if (ptr[matchcol] == NUL
  				    || (nmatched = vim_regexec_multi(&regmatch,
  					      win, buf, lnum + matchpos.lnum,
! 					      matchcol,
! #ifdef FEAT_RELTIME
! 					      tm
! #else
! 					      NULL
! #endif
! 					      )) == 0)
  			    {
  				match_ok = FALSE;
  				break;
***************
*** 799,805 ****
  			    if (ptr[matchcol] == NUL
  				    || (nmatched = vim_regexec_multi(&regmatch,
  					      win, buf, lnum + matchpos.lnum,
! 							      matchcol)) == 0)
  				break;
  
  			    /* Need to get the line pointer again, a
--- 811,823 ----
  			    if (ptr[matchcol] == NUL
  				    || (nmatched = vim_regexec_multi(&regmatch,
  					      win, buf, lnum + matchpos.lnum,
! 					      matchcol,
! #ifdef FEAT_RELTIME
! 					      tm
! #else
! 					      NULL
! #endif
! 					    )) == 0)
  				break;
  
  			    /* Need to get the line pointer again, a
***************
*** 977,988 ****
   * return 0 for failure, 1 for found, 2 for found and line offset added
   */
      int
! do_search(oap, dirc, pat, count, options)
      oparg_T	    *oap;	/* can be NULL */
      int		    dirc;	/* '/' or '?' */
      char_u	   *pat;
      long	    count;
      int		    options;
  {
      pos_T	    pos;	/* position of the last match */
      char_u	    *searchstr;
--- 995,1007 ----
   * return 0 for failure, 1 for found, 2 for found and line offset added
   */
      int
! do_search(oap, dirc, pat, count, options, tm)
      oparg_T	    *oap;	/* can be NULL */
      int		    dirc;	/* '/' or '?' */
      char_u	   *pat;
      long	    count;
      int		    options;
+     proftime_T	    *tm;	/* timeout limit or NULL */
  {
      pos_T	    pos;	/* position of the last match */
      char_u	    *searchstr;
***************
*** 1256,1262 ****
  		       (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
  			+ SEARCH_MSG + SEARCH_START
  			+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
! 		RE_LAST, (linenr_T)0, NULL);
  
  	if (dircp != NULL)
  	    *dircp = dirc;	/* restore second '/' or '?' for normal_cmd() */
--- 1275,1281 ----
  		       (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
  			+ SEARCH_MSG + SEARCH_START
  			+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
! 		RE_LAST, (linenr_T)0, tm);
  
  	if (dircp != NULL)
  	    *dircp = dirc;	/* restore second '/' or '?' for normal_cmd() */
*** ../vim-7.1.235/src/screen.c	Sat Jan 12 16:45:25 2008
--- src/screen.c	Sat Jan 19 13:52:29 2008
***************
*** 848,858 ****
--- 848,863 ----
  	cur->hl.buf = buf;
  	cur->hl.lnum = 0;
  	cur->hl.first_lnum = 0;
+ # ifdef FEAT_RELTIME
+ 	/* Set the time limit to 'redrawtime'. */
+ 	profile_setlimit(p_rdt, &(cur->hl.tm));
+ # endif
  	cur = cur->next;
      }
      search_hl.buf = buf;
      search_hl.lnum = 0;
      search_hl.first_lnum = 0;
+     /* time limit is set at the toplevel, for all windows */
  #endif
  
  #ifdef FEAT_LINEBREAK
***************
*** 6462,6467 ****
--- 6467,6476 ----
      {
  	last_pat_prog(&search_hl.rm);
  	search_hl.attr = hl_attr(HLF_L);
+ # ifdef FEAT_RELTIME
+ 	/* Set the time limit to 'redrawtime'. */
+ 	profile_setlimit(p_rdt, &search_hl.tm);
+ # endif
      }
  }
  
***************
*** 6587,6592 ****
--- 6596,6609 ----
      called_emsg = FALSE;
      for (;;)
      {
+ #ifdef FEAT_RELTIME
+ 	/* Stop searching after passing the time limit. */
+ 	if (profile_passed_limit(&(shl->tm)))
+ 	{
+ 	    shl->lnum = 0;		/* no match found in time */
+ 	    break;
+ 	}
+ #endif
  	/* Three situations:
  	 * 1. No useful previous match: search from start of line.
  	 * 2. Not Vi compatible or empty match: continue at next character.
***************
*** 6620,6626 ****
  	    matchcol = shl->rm.endpos[0].col;
  
  	shl->lnum = lnum;
! 	nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol);
  	if (called_emsg)
  	{
  	    /* Error while handling regexp: stop using this regexp. */
--- 6637,6649 ----
  	    matchcol = shl->rm.endpos[0].col;
  
  	shl->lnum = lnum;
! 	nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol,
! #ifdef FEAT_RELTIME
! 		&(shl->tm)
! #else
! 		NULL
! #endif
! 		);
  	if (called_emsg)
  	{
  	    /* Error while handling regexp: stop using this regexp. */
*** ../vim-7.1.235/src/option.h	Thu May 10 20:34:47 2007
--- src/option.h	Sat Jan 19 13:45:51 2008
***************
*** 633,638 ****
--- 633,641 ----
  #ifdef FEAT_SEARCHPATH
  EXTERN char_u	*p_cdpath;	/* 'cdpath' */
  #endif
+ #ifdef FEAT_RELTIME
+ EXTERN long	p_rdt;		/* 'redrawtime' */
+ #endif
  EXTERN int	p_remap;	/* 'remap' */
  EXTERN long	p_report;	/* 'report' */
  #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
*** ../vim-7.1.235/src/spell.c	Sat Jan 12 16:45:25 2008
--- src/spell.c	Fri Jan 18 21:02:47 2008
***************
*** 10343,10349 ****
      curwin->w_cursor.lnum = 0;
      while (!got_int)
      {
! 	if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP) == 0
  						   || u_save_cursor() == FAIL)
  	    break;
  
--- 10343,10349 ----
      curwin->w_cursor.lnum = 0;
      while (!got_int)
      {
! 	if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
  						   || u_save_cursor() == FAIL)
  	    break;
  
*** ../vim-7.1.235/src/structs.h	Mon Oct  1 22:53:27 2007
--- src/structs.h	Fri Jan 18 21:18:53 2008
***************
*** 1717,1722 ****
--- 1717,1725 ----
      linenr_T	first_lnum;	/* first lnum to search for multi-line pat */
      colnr_T	startcol; /* in win_line() points to char where HL starts */
      colnr_T	endcol;	 /* in win_line() points to char where HL ends */
+ #ifdef FEAT_RELTIME
+     proftime_T	tm;	/* for a time limit */
+ #endif
  } match_T;
  
  /*
*** ../vim-7.1.235/src/syntax.c	Sun Jan 13 17:39:29 2008
--- src/syntax.c	Sat Jan 19 13:13:49 2008
***************
*** 3097,3103 ****
      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;
  	rmp->endpos[0].lnum += lnum;
--- 3097,3103 ----
      colnr_T	col;
  {
      rmp->rmm_maxcol = syn_buf->b_p_smc;
!     if (vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL) > 0)
      {
  	rmp->startpos[0].lnum += lnum;
  	rmp->endpos[0].lnum += lnum;
*** ../vim-7.1.235/src/tag.c	Thu May 10 19:44:07 2007
--- src/tag.c	Fri Jan 18 21:03:41 2008
***************
*** 3191,3197 ****
  #endif
  	    save_lnum = curwin->w_cursor.lnum;
  	    curwin->w_cursor.lnum = 0;	/* start search before first line */
! 	    if (do_search(NULL, pbuf[0], pbuf + 1, (long)1, search_options))
  		retval = OK;
  	    else
  	    {
--- 3191,3198 ----
  #endif
  	    save_lnum = curwin->w_cursor.lnum;
  	    curwin->w_cursor.lnum = 0;	/* start search before first line */
! 	    if (do_search(NULL, pbuf[0], pbuf + 1, (long)1,
! 							search_options, NULL))
  		retval = OK;
  	    else
  	    {
***************
*** 3203,3209 ****
  		 */
  		p_ic = TRUE;
  		if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
! 							      search_options))
  		{
  		    /*
  		     * Failed to find pattern, take a guess: "^func  ("
--- 3204,3210 ----
  		 */
  		p_ic = TRUE;
  		if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
! 							search_options, NULL))
  		{
  		    /*
  		     * Failed to find pattern, take a guess: "^func  ("
***************
*** 3213,3225 ****
  		    cc = *tagp.tagname_end;
  		    *tagp.tagname_end = NUL;
  		    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
! 		    if (!do_search(NULL, '/', pbuf, (long)1, search_options))
  		    {
  			/* Guess again: "^char * \<func  (" */
  			sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
  								tagp.tagname);
  			if (!do_search(NULL, '/', pbuf, (long)1,
! 							      search_options))
  			    found = 0;
  		    }
  		    *tagp.tagname_end = cc;
--- 3214,3227 ----
  		    cc = *tagp.tagname_end;
  		    *tagp.tagname_end = NUL;
  		    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
! 		    if (!do_search(NULL, '/', pbuf, (long)1,
! 							search_options, NULL))
  		    {
  			/* Guess again: "^char * \<func  (" */
  			sprintf((char *)pbuf, "^\\[#a-zA-Z_]\\.\\*\\<%s\\s\\*(",
  								tagp.tagname);
  			if (!do_search(NULL, '/', pbuf, (long)1,
! 							search_options, NULL))
  			    found = 0;
  		    }
  		    *tagp.tagname_end = cc;
*** ../vim-7.1.235/src/vim.h	Sat Jan  5 13:34:01 2008
--- src/vim.h	Fri Jan 18 21:29:22 2008
***************
*** 1550,1555 ****
--- 1550,1565 ----
  # define MB_MAXBYTES	21
  #endif
  
+ #if (defined(FEAT_PROFILE) || defined(FEAT_RELTIME)) && !defined(PROTO)
+ # ifdef WIN3264
+ typedef LARGE_INTEGER proftime_T;
+ # else
+ typedef struct timeval proftime_T;
+ # endif
+ #else
+ typedef int proftime_T;	    /* dummy for function prototypes */
+ #endif
+ 
  /* Include option.h before structs.h, because the number of window-local and
   * buffer-local options is used there. */
  #include "option.h"	    /* options and default values */
***************
*** 1760,1775 ****
  # include <io.h>	    /* for access() */
  
  # define stat(a,b) (access(a,0) ? -1 : stat(a,b))
- #endif
- 
- #if (defined(FEAT_PROFILE) || defined(FEAT_RELTIME)) && !defined(PROTO)
- # ifdef WIN3264
- typedef LARGE_INTEGER proftime_T;
- # else
- typedef struct timeval proftime_T;
- # endif
- #else
- typedef int proftime_T;	    /* dummy for function prototypes */
  #endif
  
  #include "ex_cmds.h"	    /* Ex command defines */
--- 1770,1775 ----
*** ../vim-7.1.235/src/version.c	Fri Jan 18 20:36:40 2008
--- src/version.c	Sat Jan 19 15:19:48 2008
***************
*** 668,669 ****
--- 668,671 ----
  {   /* Add new patch number below this line */
+ /**/
+     236,
  /**/

-- 
Every time I lose weight, it finds me again!

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///