# HG changeset patch # User vimboss # Date 1199646456 0 # Node ID 29c09fa57168acd665a85ed5a210b48b60d0b5e2 # Parent 04265ffbda1f9b14729bc5d85069ff0711ce3744 updated for version 7.1-211 diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.1. Last change: 2008 Jan 04 +*eval.txt* For Vim version 7.1. Last change: 2008 Jan 06 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1733,14 +1733,15 @@ rename( {from}, {to}) Number rename (mo repeat( {expr}, {count}) String repeat {expr} {count} times resolve( {filename}) String get filename a shortcut points to reverse( {list}) List reverse {list} in-place -search( {pattern} [, {flags}]) Number search for {pattern} +search( {pattern} [, {flags} [, {stopline} [, {timeout}]]]) + Number search for {pattern} searchdecl({name} [, {global} [, {thisblock}]]) Number search for variable declaration -searchpair( {start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]]) +searchpair( {start}, {middle}, {end} [, {flags} [, {skip} [...]]]) Number search for other end of start/end pair -searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]]) +searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip} [...]]]) List search for other end of start/end pair -searchpos( {pattern} [, {flags} [, {stopline}]]) +searchpos( {pattern} [, {flags} [, {stopline} [, {timeout}]]]) List search for {pattern} server2client( {clientid}, {string}) Number send reply string @@ -4212,7 +4213,7 @@ reverse({list}) Reverse the order of ite If you want a list to remain unmodified make a copy first: > :let revlist = reverse(copy(mylist)) -search({pattern} [, {flags} [, {stopline}]]) *search()* +search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()* Search for regexp pattern {pattern}. The search starts at the cursor position (you can use |cursor()| to set it). @@ -4240,6 +4241,14 @@ search({pattern} [, {flags} [, {stopline let end = search('END', '', line("w$")) < When {stopline} is used and it is not zero this also implies that the search does not wrap around the end of the file. + A zero value is equal to not giving the argument. + + When the {timeout} argument is given the search stops when + more than this many milli seconds have passed. Thus when + {timeout} is 500 the search stops after half a second. + The value must not be negative. A zero value is like not + giving the argument. + {only available when compiled with the +reltime feature} If there is no match a 0 is returned and the cursor doesn't move. No error message is given. @@ -4302,7 +4311,8 @@ searchdecl({name} [, {global} [, {thisbl endif < *searchpair()* -searchpair({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]]) +searchpair({start}, {middle}, {end} [, {flags} [, {skip} + [, {stopline} [, {timeout}]]]]) Search for the match of a nested start-end pair. This can be used to find the "endif" that matches an "if", while other if/endif pairs in between are ignored. @@ -4337,7 +4347,7 @@ searchpair({start}, {middle}, {end} [, { When evaluating {skip} causes an error the search is aborted and -1 returned. - For {stopline} see |search()|. + For {stopline} and {timeout} see |search()|. The value of 'ignorecase' is used. 'magic' is ignored, the patterns are used like it's on. @@ -4383,7 +4393,8 @@ searchpair({start}, {middle}, {end} [, { \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string"') < *searchpairpos()* -searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [, {stopline}]]]) +searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} + [, {stopline} [, {timeout}]]]]) Same as searchpair(), but returns a |List| with the line and column position of the match. The first element of the |List| is the line number and the second element is the byte index of @@ -4394,7 +4405,7 @@ searchpairpos({start}, {middle}, {end} [ < See |match-parens| for a bigger and more useful example. -searchpos({pattern} [, {flags} [, {stopline}]]) *searchpos()* +searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *searchpos()* Same as |search()|, but returns a |List| with the line and column position of the match. The first element of the |List| is the line number and the second element is the byte index of diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim --- a/runtime/plugin/matchparen.vim +++ b/runtime/plugin/matchparen.vim @@ -1,6 +1,6 @@ " Vim plugin for showing matching parens " Maintainer: Bram Moolenaar -" Last Change: 2007 Aug 8 +" Last Change: 2008 Jan 06 " Exit quickly when: " - this plugin was already loaded (or disabled) @@ -111,7 +111,12 @@ function! s:Highlight_Matching_Pair() \ '=~? "string\\|character\\|singlequote\\|comment"' execute 'if' s_skip '| let s_skip = 0 | endif' - let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline) + try + " Limit the search time to 500 msec to avoid a hang on very long lines. + let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline, 500) + catch /E118/ + let [m_lnum, m_col] = searchpairpos(c, '', c2, s_flags, s_skip, stopline) + endtry if before > 0 call winrestview(save_cursor) diff --git a/src/edit.c b/src/edit.c --- a/src/edit.c +++ b/src/edit.c @@ -4062,7 +4062,7 @@ ins_compl_get_exp(ini) found_new_match = searchit(NULL, ins_buf, pos, compl_direction, compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, - RE_LAST, (linenr_T)0); + RE_LAST, (linenr_T)0, NULL); --msg_silent; if (!compl_started) { diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -7213,11 +7213,11 @@ static struct fst {"repeat", 2, 2, f_repeat}, {"resolve", 1, 1, f_resolve}, {"reverse", 1, 1, f_reverse}, - {"search", 1, 3, f_search}, + {"search", 1, 4, f_search}, {"searchdecl", 1, 3, f_searchdecl}, - {"searchpair", 3, 6, f_searchpair}, - {"searchpairpos", 3, 6, f_searchpairpos}, - {"searchpos", 1, 3, f_searchpos}, + {"searchpair", 3, 7, f_searchpair}, + {"searchpairpos", 3, 7, f_searchpairpos}, + {"searchpos", 1, 4, f_searchpos}, {"server2client", 2, 2, f_server2client}, {"serverlist", 0, 0, f_serverlist}, {"setbufvar", 3, 3, f_setbufvar}, @@ -14020,6 +14020,10 @@ search_cmn(argvars, match_pos, flagsp) int dir; int retval = 0; /* default: FAIL */ long lnum_stop = 0; + proftime_T tm; +#ifdef FEAT_RELTIME + long time_limit = 0; +#endif int options = SEARCH_KEEP; int subpatnum; @@ -14033,14 +14037,26 @@ search_cmn(argvars, match_pos, flagsp) if (flags & SP_END) options |= SEARCH_END; - /* Optional extra argument: line number to stop searching. */ - if (argvars[1].v_type != VAR_UNKNOWN - && argvars[2].v_type != VAR_UNKNOWN) + /* Optional arguments: line number to stop searching and timeout. */ + if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { lnum_stop = get_tv_number_chk(&argvars[2], NULL); if (lnum_stop < 0) goto theend; - } +#ifdef FEAT_RELTIME + if (argvars[3].v_type != VAR_UNKNOWN) + { + time_limit = get_tv_number_chk(&argvars[3], NULL); + if (time_limit < 0) + goto theend; + } +#endif + } + +#ifdef FEAT_RELTIME + /* Set the time limit, if there is one. */ + profile_setlimit(time_limit, &tm); +#endif /* * This function does not accept SP_REPEAT and SP_RETCOUNT flags. @@ -14057,7 +14073,7 @@ search_cmn(argvars, match_pos, flagsp) pos = save_cursor = curwin->w_cursor; subpatnum = searchit(curwin, curbuf, &pos, dir, pat, 1L, - options, RE_SEARCH, (linenr_T)lnum_stop); + options, RE_SEARCH, (linenr_T)lnum_stop, &tm); if (subpatnum != FAIL) { if (flags & SP_SUBPAT) @@ -14147,6 +14163,7 @@ searchpair_cmn(argvars, match_pos) char_u nbuf3[NUMBUFLEN]; int retval = 0; /* default: FAIL */ long lnum_stop = 0; + long time_limit = 0; /* Get the three pattern arguments: start, middle, end. */ spat = get_tv_string_chk(&argvars[0]); @@ -14182,13 +14199,21 @@ searchpair_cmn(argvars, match_pos) lnum_stop = get_tv_number_chk(&argvars[5], NULL); if (lnum_stop < 0) goto theend; +#ifdef FEAT_RELTIME + if (argvars[6].v_type != VAR_UNKNOWN) + { + time_limit = get_tv_number_chk(&argvars[6], NULL); + if (time_limit < 0) + goto theend; + } +#endif } } if (skip == NULL) goto theend; /* type error */ retval = do_searchpair(spat, mpat, epat, dir, skip, flags, - match_pos, lnum_stop); + match_pos, lnum_stop, time_limit); theend: p_ws = save_p_ws; @@ -14240,7 +14265,8 @@ f_searchpairpos(argvars, rettv) * Returns 0 or -1 for no match, */ long -do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, lnum_stop) +do_searchpair(spat, mpat, epat, dir, skip, flags, match_pos, + lnum_stop, time_limit) char_u *spat; /* start pattern */ char_u *mpat; /* middle pattern */ char_u *epat; /* end pattern */ @@ -14249,6 +14275,7 @@ do_searchpair(spat, mpat, epat, dir, ski int flags; /* SP_SETPCMARK and other SP_ values */ pos_T *match_pos; linenr_T lnum_stop; /* stop at this line if not zero */ + long time_limit; /* stop after this many msec */ { char_u *save_cpo; char_u *pat, *pat2 = NULL, *pat3 = NULL; @@ -14263,11 +14290,17 @@ do_searchpair(spat, mpat, epat, dir, ski int nest = 1; int err; int options = SEARCH_KEEP; + proftime_T tm; /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ save_cpo = p_cpo; p_cpo = (char_u *)""; +#ifdef FEAT_RELTIME + /* Set the time limit, if there is one. */ + profile_setlimit(time_limit, &tm); +#endif + /* Make two search patterns: start/end (pat2, for in nested pairs) and * start/middle/end (pat3, for the top pair). */ pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); @@ -14291,7 +14324,7 @@ do_searchpair(spat, mpat, epat, dir, ski for (;;) { n = searchit(curwin, curbuf, &pos, dir, pat, 1L, - options, RE_SEARCH, lnum_stop); + options, RE_SEARCH, lnum_stop, &tm); if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) /* didn't find it or found the first match again: FAIL */ break; diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -895,19 +895,61 @@ profile_msg(tm) sprintf(buf, "%10.6lf", (double)tm->QuadPart / (double)fr.QuadPart); # else sprintf(buf, "%3ld.%06ld", (long)tm->tv_sec, (long)tm->tv_usec); -#endif +# endif return buf; } -# endif /* FEAT_PROFILE || FEAT_RELTIME */ - -# if defined(FEAT_PROFILE) || defined(PROTO) /* - * Functions for profiling. + * Put the time "msec" past now in "tm". */ -static void script_do_profile __ARGS((scriptitem_T *si)); -static void script_dump_profile __ARGS((FILE *fd)); -static proftime_T prof_wait_time; + void +profile_setlimit(msec, tm) + long msec; + proftime_T *tm; +{ + if (msec <= 0) /* no limit */ + profile_zero(tm); + else + { +# ifdef WIN3264 + LARGE_INTEGER fr; + + QueryPerformanceCounter(tm); + QueryPerformanceFrequency(&fr); + tm->QuadPart += (double)msec / 1000.0 * (double)fr.QuadPart; +# else + long usec; + + gettimeofday(tm, NULL); + usec = (long)tm->tv_usec + (long)msec * 1000; + tm->tv_usec = usec % 1000000L; + tm->tv_sec += usec / 1000000L; +# endif + } +} + +/* + * Return TRUE if the current time is past "tm". + */ + int +profile_passed_limit(tm) + proftime_T *tm; +{ + proftime_T now; + +# ifdef WIN3264 + if (tm->QuadPart == 0) /* timer was not set */ + return FALSE; + QueryPerformanceCounter(&now); + return (now.QuadPart > tm->QuadPart); +# else + if (tm->tv_sec == 0) /* timer was not set */ + return FALSE; + gettimeofday(&now, NULL); + return (now.tv_sec > tm->tv_sec + || (now.tv_sec == tm->tv_sec && now.tv_usec > tm->tv_usec)); +# endif +} /* * Set the time in "tm" to zero. @@ -924,6 +966,16 @@ profile_zero(tm) # endif } +# endif /* FEAT_PROFILE || FEAT_RELTIME */ + +# if defined(FEAT_PROFILE) || defined(PROTO) +/* + * Functions for profiling. + */ +static void script_do_profile __ARGS((scriptitem_T *si)); +static void script_dump_profile __ARGS((FILE *fd)); +static proftime_T prof_wait_time; + /* * Add the time "tm2" to "tm". */ diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3979,7 +3979,7 @@ get_address(ptr, skip, to_other_file) *cmd == '?' ? BACKWARD : FORWARD, (char_u *)"", 1L, SEARCH_MSG + SEARCH_START, - i, (linenr_T)0) != FAIL) + i, (linenr_T)0, NULL) != FAIL) lnum = pos.lnum; else { diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -4194,7 +4194,7 @@ find_decl(ptr, len, locally, thisblock, for (;;) { t = searchit(curwin, curbuf, &curwin->w_cursor, FORWARD, - pat, 1L, searchflags, RE_LAST, (linenr_T)0); + pat, 1L, searchflags, RE_LAST, (linenr_T)0, NULL); if (curwin->w_cursor.lnum >= old_pos.lnum) t = FAIL; /* match after start is failure too */ diff --git a/src/proto/eval.pro b/src/proto/eval.pro --- a/src/proto/eval.pro +++ b/src/proto/eval.pro @@ -54,7 +54,7 @@ char_u *get_dict_string __ARGS((dict_T * long get_dict_number __ARGS((dict_T *d, char_u *key)); char_u *get_function_name __ARGS((expand_T *xp, int idx)); char_u *get_expr_name __ARGS((expand_T *xp, int idx)); -long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop)); +long do_searchpair __ARGS((char_u *spat, char_u *mpat, char_u *epat, int dir, char_u *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit)); void set_vim_var_nr __ARGS((int idx, long val)); long get_vim_var_nr __ARGS((int idx)); char_u *get_vim_var_str __ARGS((int idx)); diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro --- a/src/proto/ex_cmds2.pro +++ b/src/proto/ex_cmds2.pro @@ -14,6 +14,8 @@ void profile_start __ARGS((proftime_T *t void profile_end __ARGS((proftime_T *tm)); void profile_sub __ARGS((proftime_T *tm, proftime_T *tm2)); char *profile_msg __ARGS((proftime_T *tm)); +void profile_setlimit __ARGS((long msec, proftime_T *tm)); +int profile_passed_limit __ARGS((proftime_T *tm)); void profile_zero __ARGS((proftime_T *tm)); void profile_add __ARGS((proftime_T *tm, proftime_T *tm2)); void profile_self __ARGS((proftime_T *self, proftime_T *total, proftime_T *children)); diff --git a/src/proto/search.pro b/src/proto/search.pro --- a/src/proto/search.pro +++ b/src/proto/search.pro @@ -10,7 +10,7 @@ char_u *last_search_pat __ARGS((void)); 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)); +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)); diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -494,8 +494,9 @@ last_pat_prog(regmatch) * When FEAT_EVAL is defined, returns the index of the first matching * subpattern plus one; one if there was none. */ +/*ARGSUSED*/ int -searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum) +searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm) win_T *win; /* window to search in; can be NULL for a buffer without a window! */ buf_T *buf; @@ -506,6 +507,7 @@ searchit(win, buf, pos, dir, pat, count, int options; int pat_use; /* which pattern to use when "pat" is empty */ linenr_T stop_lnum; /* stop after this line number when != 0 */ + proftime_T *tm; /* timeout limit or NULL */ { int found; linenr_T lnum; /* no init to shut up Apollo cc */ @@ -594,6 +596,11 @@ searchit(win, buf, pos, dir, pat, count, if (stop_lnum != 0 && (dir == FORWARD ? lnum > stop_lnum : lnum < stop_lnum)) break; +#ifdef FEAT_RELTIME + /* Stop after passing the "tm" time limit. */ + if (tm != NULL && profile_passed_limit(tm)) + break; +#endif /* * Look for a match somewhere in line "lnum". @@ -1249,7 +1256,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); + RE_LAST, (linenr_T)0, NULL); if (dircp != NULL) *dircp = dirc; /* restore second '/' or '?' for normal_cmd() */ @@ -3780,7 +3787,7 @@ again: if (do_searchpair((char_u *)"<[^ \t>/!]\\+\\%(\\_s\\_[^>]\\{-}[^/]>\\|$\\|\\_s\\=>\\)", (char_u *)"", (char_u *)"]*>", BACKWARD, (char_u *)"", 0, - NULL, (linenr_T)0) <= 0) + NULL, (linenr_T)0, 0L) <= 0) { curwin->w_cursor = old_pos; goto theend; @@ -3814,7 +3821,7 @@ again: sprintf((char *)epat, "\\c", len, p); r = do_searchpair(spat, (char_u *)"", epat, FORWARD, (char_u *)"", - 0, NULL, (linenr_T)0); + 0, NULL, (linenr_T)0, 0L); vim_free(spat); vim_free(epat); diff --git a/src/version.c b/src/version.c --- 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 */ /**/ + 211, +/**/ 210, /**/ 209,