changeset 1521:cc4fe241baa3 v7.1.236

updated for version 7.1-236
author vimboss
date Sat, 19 Jan 2008 14:59:58 +0000
parents cd6175cc27d9
children 710b52d02c4a
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/option.h src/proto/regexp.pro src/proto/search.pro src/quickfix.c src/regexp.c src/screen.c src/search.c src/spell.c src/structs.h src/syntax.c src/tag.c src/version.c src/vim.h
diffstat 21 files changed, 154 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3618,6 +3618,7 @@ A jump table for the options with a shor
 	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,6 +3852,10 @@ A jump table for the options with a shor
 	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,6 +5190,18 @@ A jump table for the options with a shor
 	{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
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -4446,7 +4446,8 @@ do_sub(eap)
 #endif
 		); ++lnum)
     {
-	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)0);
+	nmatch = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
+							    (colnr_T)0, NULL);
 	if (nmatch)
 	{
 	    colnr_T	copycol;
@@ -4957,7 +4958,8 @@ skip:
 			|| (do_ask && !re_lookbehind(regmatch.regprog))
 			|| nmatch_tl > 0
 			|| (nmatch = vim_regexec_multi(&regmatch, curwin,
-				       curbuf, sub_firstlnum, matchcol)) == 0
+							curbuf, sub_firstlnum,
+							 matchcol, NULL)) == 0
 			|| regmatch.startpos[0].lnum > 0)
 		{
 		    if (new_start != NULL)
@@ -5022,7 +5024,7 @@ skip:
 		    }
 		    if (nmatch == -1 && !lastone)
 			nmatch = vim_regexec_multi(&regmatch, curwin, curbuf,
-						     sub_firstlnum, matchcol);
+					       sub_firstlnum, matchcol, NULL);
 
 		    /*
 		     * 5. break if there isn't another match in this line
@@ -5252,7 +5254,8 @@ ex_global(eap)
     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);
+	match = vim_regexec_multi(&regmatch, curwin, curbuf, lnum,
+							    (colnr_T)0, NULL);
 	if ((type == 'g' && match) || (type == 'v' && !match))
 	{
 	    ml_setmarked(lnum);
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3931,7 +3931,8 @@ get_address(ptr, skip, to_other_file)
 				curwin->w_cursor.col = 0;
 			    searchcmdlen = 0;
 			    if (!do_search(NULL, c, cmd, 1L,
-				      SEARCH_HIS + SEARCH_MSG + SEARCH_START))
+					SEARCH_HIS + SEARCH_MSG + SEARCH_START,
+					NULL))
 			    {
 				curwin->w_cursor = pos;
 				cmd = NULL;
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1709,6 +1709,9 @@ cmdline_changed:
 	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,8 +1730,18 @@ cmdline_changed:
 		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);
+			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)
--- a/src/gui.c
+++ b/src/gui.c
@@ -5052,7 +5052,7 @@ gui_do_findrepl(flags, find_text, repl_t
 	/* Search for the next match. */
 	i = msg_scroll;
 	do_search(NULL, down ? '/' : '?', ga.ga_data, 1L,
-						    SEARCH_MSG + SEARCH_MARK);
+					      SEARCH_MSG + SEARCH_MARK, NULL);
 	msg_scroll = i;	    /* don't let an error message set msg_scroll */
     }
 
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -437,7 +437,8 @@ get_number_indent(lnum)
     {
 	regmatch.rmm_ic = FALSE;
 	regmatch.rmm_maxcol = 0;
-	if (vim_regexec_multi(&regmatch, curwin, curbuf, lnum, (colnr_T)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;
--- a/src/normal.c
+++ b/src/normal.c
@@ -6093,7 +6093,7 @@ normal_search(cap, dir, pat, opt)
     curwin->w_set_curswant = TRUE;
 
     i = do_search(cap->oap, dir, pat, cap->count1,
-				 opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG);
+			   opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, NULL);
     if (i == 0)
 	clearop(cap->oap);
     else
--- a/src/option.c
+++ b/src/option.c
@@ -1991,6 +1991,13 @@ static struct vimoption
     {"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}},
--- a/src/option.h
+++ b/src/option.h
@@ -633,6 +633,9 @@ EXTERN char_u	*p_path;	/* 'path' */
 #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)
--- a/src/proto/regexp.pro
+++ b/src/proto/regexp.pro
@@ -1,13 +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));
+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));
+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));
--- a/src/proto/search.pro
+++ b/src/proto/search.pro
@@ -11,7 +11,7 @@ void reset_search_dir __ARGS((void));
 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 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));
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -1803,7 +1803,8 @@ qf_jump(qi, dir, errornr, forceit)
 	    /* 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))
+	    if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
+							   SEARCH_KEEP, NULL))
 		curwin->w_cursor = save_cursor;
 	}
 
@@ -3159,7 +3160,7 @@ ex_vimgrep(eap)
 	    {
 		col = 0;
 		while (vim_regexec_multi(&regmatch, curwin, buf, lnum,
-								     col) > 0)
+							       col, NULL) > 0)
 		{
 		    ;
 		    if (qf_add_entry(qi, &prevp,
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -3040,7 +3040,7 @@ typedef struct
 } 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	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,7 +3284,7 @@ vim_regexec(rmp, line, col)
     ireg_icombine = FALSE;
 #endif
     ireg_maxcol = 0;
-    return (vim_regexec_both(line, col) != 0);
+    return (vim_regexec_both(line, col, NULL) != 0);
 }
 
 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) \
@@ -3308,7 +3308,7 @@ vim_regexec_nl(rmp, line, col)
     ireg_icombine = FALSE;
 #endif
     ireg_maxcol = 0;
-    return (vim_regexec_both(line, col) != 0);
+    return (vim_regexec_both(line, col, NULL) != 0);
 }
 #endif
 
@@ -3321,12 +3321,13 @@ vim_regexec_nl(rmp, line, col)
  * match otherwise.
  */
     long
-vim_regexec_multi(rmp, win, buf, lnum, col)
+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,7 +3347,7 @@ vim_regexec_multi(rmp, win, buf, lnum, c
 
     /* Need to switch to buffer "buf" to make vim_iswordc() work. */
     curbuf = buf;
-    r = vim_regexec_both(NULL, col);
+    r = vim_regexec_both(NULL, col, tm);
     curbuf = save_curbuf;
 
     return r;
@@ -3356,10 +3357,12 @@ vim_regexec_multi(rmp, win, buf, lnum, c
  * 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)
+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,6 +3505,9 @@ vim_regexec_both(line, col)
     }
     else
     {
+#ifdef FEAT_RELTIME
+	int tm_count = 0;
+#endif
 	/* Messy cases:  unanchored match. */
 	while (!got_int)
 	{
@@ -3550,6 +3556,15 @@ vim_regexec_both(line, col)
 	    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
 	}
     }
 
--- a/src/screen.c
+++ b/src/screen.c
@@ -848,11 +848,16 @@ win_update(wp)
 	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,6 +6467,10 @@ start_search_hl()
     {
 	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,6 +6596,14 @@ next_search_hl(win, shl, lnum, mincol)
     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,7 +6637,13 @@ next_search_hl(win, shl, lnum, mincol)
 	    matchcol = shl->rm.endpos[0].col;
 
 	shl->lnum = lnum;
-	nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol);
+	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. */
--- a/src/search.c
+++ b/src/search.c
@@ -606,7 +606,13 @@ searchit(win, buf, pos, dir, pat, count,
 		 * Look for a match somewhere in line "lnum".
 		 */
 		nmatched = vim_regexec_multi(&regmatch, win, buf,
-							    lnum, (colnr_T)0);
+						      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,9 +621,9 @@ searchit(win, buf, pos, dir, pat, count,
 		    /* match may actually be in another line when using \zs */
 		    matchpos = regmatch.startpos[0];
 		    endpos = regmatch.endpos[0];
-# ifdef FEAT_EVAL
+#ifdef FEAT_EVAL
 		    submatch = first_submatch(&regmatch);
-# endif
+#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,7 +699,13 @@ searchit(win, buf, pos, dir, pat, count,
 			    if (ptr[matchcol] == NUL
 				    || (nmatched = vim_regexec_multi(&regmatch,
 					      win, buf, lnum + matchpos.lnum,
-					      matchcol)) == 0)
+					      matchcol,
+#ifdef FEAT_RELTIME
+					      tm
+#else
+					      NULL
+#endif
+					      )) == 0)
 			    {
 				match_ok = FALSE;
 				break;
@@ -799,7 +811,13 @@ searchit(win, buf, pos, dir, pat, count,
 			    if (ptr[matchcol] == NUL
 				    || (nmatched = vim_regexec_multi(&regmatch,
 					      win, buf, lnum + matchpos.lnum,
-							      matchcol)) == 0)
+					      matchcol,
+#ifdef FEAT_RELTIME
+					      tm
+#else
+					      NULL
+#endif
+					    )) == 0)
 				break;
 
 			    /* Need to get the line pointer again, a
@@ -977,12 +995,13 @@ first_submatch(rp)
  * return 0 for failure, 1 for found, 2 for found and line offset added
  */
     int
-do_search(oap, dirc, pat, count, options)
+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,7 +1275,7 @@ do_search(oap, dirc, pat, count, options
 		       (SEARCH_KEEP + SEARCH_PEEK + SEARCH_HIS
 			+ SEARCH_MSG + SEARCH_START
 			+ ((pat != NULL && *pat == ';') ? 0 : SEARCH_NOOF))),
-		RE_LAST, (linenr_T)0, NULL);
+		RE_LAST, (linenr_T)0, tm);
 
 	if (dircp != NULL)
 	    *dircp = dirc;	/* restore second '/' or '?' for normal_cmd() */
--- a/src/spell.c
+++ b/src/spell.c
@@ -10343,7 +10343,7 @@ ex_spellrepall(eap)
     curwin->w_cursor.lnum = 0;
     while (!got_int)
     {
-	if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP) == 0
+	if (do_search(NULL, '/', frompat, 1L, SEARCH_KEEP, NULL) == 0
 						   || u_save_cursor() == FAIL)
 	    break;
 
--- a/src/structs.h
+++ b/src/structs.h
@@ -1717,6 +1717,9 @@ typedef struct
     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;
 
 /*
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -3097,7 +3097,7 @@ syn_regexec(rmp, lnum, col)
     colnr_T	col;
 {
     rmp->rmm_maxcol = syn_buf->b_p_smc;
-    if (vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col) > 0)
+    if (vim_regexec_multi(rmp, syn_win, syn_buf, lnum, col, NULL) > 0)
     {
 	rmp->startpos[0].lnum += lnum;
 	rmp->endpos[0].lnum += lnum;
--- a/src/tag.c
+++ b/src/tag.c
@@ -3191,7 +3191,8 @@ jumpto_tag(lbuf, forceit, keep_help)
 #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))
+	    if (do_search(NULL, pbuf[0], pbuf + 1, (long)1,
+							search_options, NULL))
 		retval = OK;
 	    else
 	    {
@@ -3203,7 +3204,7 @@ jumpto_tag(lbuf, forceit, keep_help)
 		 */
 		p_ic = TRUE;
 		if (!do_search(NULL, pbuf[0], pbuf + 1, (long)1,
-							      search_options))
+							search_options, NULL))
 		{
 		    /*
 		     * Failed to find pattern, take a guess: "^func  ("
@@ -3213,13 +3214,14 @@ jumpto_tag(lbuf, forceit, keep_help)
 		    cc = *tagp.tagname_end;
 		    *tagp.tagname_end = NUL;
 		    sprintf((char *)pbuf, "^%s\\s\\*(", tagp.tagname);
-		    if (!do_search(NULL, '/', pbuf, (long)1, search_options))
+		    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))
+							search_options, NULL))
 			    found = 0;
 		    }
 		    *tagp.tagname_end = cc;
--- a/src/version.c
+++ b/src/version.c
@@ -667,6 +667,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    236,
+/**/
     235,
 /**/
     234,
--- a/src/vim.h
+++ b/src/vim.h
@@ -1550,6 +1550,16 @@ int vim_memcmp __ARGS((void *, void *, s
 # 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 */
@@ -1762,16 +1772,6 @@ typedef int VimClipboard;	/* This is req
 # 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 */
 #include "proto.h"	    /* function prototypes */