vim-patch:7.4.984

Problem:    searchpos() always starts searching in the first column, which is
            not what some people expect. (Brett Stahlman)
Solution:   Add the 'z' flag: start at the specified column.

ad4d8a192a
This commit is contained in:
watiko
2016-02-23 03:37:16 +09:00
parent 576c5f7b74
commit 4d5d76c086
6 changed files with 106 additions and 70 deletions

View File

@@ -5447,14 +5447,15 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
move. No error message is given. move. No error message is given.
{flags} is a String, which can contain these character flags: {flags} is a String, which can contain these character flags:
'b' search backward instead of forward 'b' search Backward instead of forward
'c' accept a match at the cursor position 'c' accept a match at the Cursor position
'e' move to the End of the match 'e' move to the End of the match
'n' do Not move the cursor 'n' do Not move the cursor
'p' return number of matching sub-pattern (see below) 'p' return number of matching sub-Pattern (see below)
's' set the ' mark at the previous location of the cursor 's' Set the ' mark at the previous location of the cursor
'w' wrap around the end of the file 'w' Wrap around the end of the file
'W' don't wrap around the end of the file 'W' don't Wrap around the end of the file
'z' start searching at the cursor column instead of Zero
If neither 'w' or 'W' is given, the 'wrapscan' option applies. If neither 'w' or 'W' is given, the 'wrapscan' option applies.
If the 's' flag is supplied, the ' mark is set, only if the If the 's' flag is supplied, the ' mark is set, only if the
@@ -5462,6 +5463,12 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
flag. flag.
'ignorecase', 'smartcase' and 'magic' are used. 'ignorecase', 'smartcase' and 'magic' are used.
When the 'z' flag is not given seaching always starts in
column zero and then matches before the cursor are skipped.
When the 'c' flag is present in 'cpo' the next search starts
after the match. Without the 'c' flag the next search starts
one column further.
When the {stopline} argument is given then the search stops When the {stopline} argument is given then the search stops
after searching this line. This is useful to restrict the after searching this line. This is useful to restrict the

View File

@@ -14345,14 +14345,14 @@ static void f_reverse(typval_T *argvars, typval_T *rettv)
} }
} }
#define SP_NOMOVE 0x01 /* don't move cursor */ #define SP_NOMOVE 0x01 ///< don't move cursor
#define SP_REPEAT 0x02 /* repeat to find outer pair */ #define SP_REPEAT 0x02 ///< repeat to find outer pair
#define SP_RETCOUNT 0x04 /* return matchcount */ #define SP_RETCOUNT 0x04 ///< return matchcount
#define SP_SETPCMARK 0x08 /* set previous context mark */ #define SP_SETPCMARK 0x08 ///< set previous context mark
#define SP_START 0x10 /* accept match at start position */ #define SP_START 0x10 ///< accept match at start position
#define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ #define SP_SUBPAT 0x20 ///< return nr of matching sub-pattern
#define SP_END 0x40 /* leave cursor at end of match */ #define SP_END 0x40 ///< leave cursor at end of match
#define SP_COLUMN 0x80 ///< start at cursor column
/* /*
* Get flags for a search function. * Get flags for a search function.
@@ -14378,13 +14378,14 @@ static int get_search_arg(typval_T *varp, int *flagsp)
default: mask = 0; default: mask = 0;
if (flagsp != NULL) if (flagsp != NULL)
switch (*flags) { switch (*flags) {
case 'c': mask = SP_START; break; case 'c': mask = SP_START; break;
case 'e': mask = SP_END; break; case 'e': mask = SP_END; break;
case 'm': mask = SP_RETCOUNT; break; case 'm': mask = SP_RETCOUNT; break;
case 'n': mask = SP_NOMOVE; break; case 'n': mask = SP_NOMOVE; break;
case 'p': mask = SP_SUBPAT; break; case 'p': mask = SP_SUBPAT; break;
case 'r': mask = SP_REPEAT; break; case 'r': mask = SP_REPEAT; break;
case 's': mask = SP_SETPCMARK; break; case 's': mask = SP_SETPCMARK; break;
case 'z': mask = SP_COLUMN; break;
} }
if (mask == 0) { if (mask == 0) {
EMSG2(_(e_invarg2), flags); EMSG2(_(e_invarg2), flags);
@@ -14400,9 +14401,7 @@ static int get_search_arg(typval_T *varp, int *flagsp)
return dir; return dir;
} }
/* // Shared by search() and searchpos() functions.
* Shared by search() and searchpos() functions
*/
static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp) static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
{ {
int flags; int flags;
@@ -14423,10 +14422,15 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
if (dir == 0) if (dir == 0)
goto theend; goto theend;
flags = *flagsp; flags = *flagsp;
if (flags & SP_START) if (flags & SP_START) {
options |= SEARCH_START; options |= SEARCH_START;
if (flags & SP_END) }
if (flags & SP_END) {
options |= SEARCH_END; options |= SEARCH_END;
}
if (flags & SP_COLUMN) {
options |= SEARCH_COL;
}
/* Optional arguments: line number to stop searching and timeout. */ /* Optional arguments: line number to stop searching and timeout. */
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) { if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) {

View File

@@ -453,25 +453,24 @@ void last_pat_prog(regmmatch_T *regmatch)
--emsg_off; --emsg_off;
} }
/* /// lowest level search function.
* lowest level search function. /// Search for 'count'th occurrence of pattern 'pat' in direction 'dir'.
* Search for 'count'th occurrence of pattern 'pat' in direction 'dir'. /// Start at position 'pos' and return the found position in 'pos'.
* Start at position 'pos' and return the found position in 'pos'. ///
* /// if (options & SEARCH_MSG) == 0 don't give any messages
* if (options & SEARCH_MSG) == 0 don't give any messages /// if (options & SEARCH_MSG) == SEARCH_NFMSG don't give 'notfound' messages
* if (options & SEARCH_MSG) == SEARCH_NFMSG don't give 'notfound' messages /// if (options & SEARCH_MSG) == SEARCH_MSG give all messages
* if (options & SEARCH_MSG) == SEARCH_MSG give all messages /// if (options & SEARCH_HIS) put search pattern in history
* if (options & SEARCH_HIS) put search pattern in history /// if (options & SEARCH_END) return position at end of match
* if (options & SEARCH_END) return position at end of match /// if (options & SEARCH_START) accept match at pos itself
* if (options & SEARCH_START) accept match at pos itself /// if (options & SEARCH_KEEP) keep previous search pattern
* if (options & SEARCH_KEEP) keep previous search pattern /// if (options & SEARCH_FOLD) match only once in a closed fold
* if (options & SEARCH_FOLD) match only once in a closed fold /// if (options & SEARCH_PEEK) check for typed char, cancel search
* if (options & SEARCH_PEEK) check for typed char, cancel search /// if (options & SEARCH_COL) start at pos->col instead of zero
* ///
* Return FAIL (zero) for failure, non-zero for success. /// @returns FAIL (zero) for failure, non-zero for success.
* Returns the index of the first matching /// the index of the first matching
* subpattern plus one; one if there was none. /// subpattern plus one; one if there was none.
*/
int searchit( int searchit(
win_T *win, /* window to search in, can be NULL for a win_T *win, /* window to search in, can be NULL for a
buffer without a window! */ buffer without a window! */
@@ -571,16 +570,14 @@ int searchit(
if (tm != NULL && profile_passed_limit(*tm)) if (tm != NULL && profile_passed_limit(*tm))
break; break;
/* // Look for a match somewhere in line "lnum".
* Look for a match somewhere in line "lnum". colnr_T col = at_first_line && (options & SEARCH_COL) ? pos->col : 0;
*/
nmatched = vim_regexec_multi(&regmatch, win, buf, nmatched = vim_regexec_multi(&regmatch, win, buf,
lnum, (colnr_T)0, lnum, col, tm);
tm // Abort searching on an error (e.g., out of stack).
); if (called_emsg) {
/* Abort searching on an error (e.g., out of stack). */
if (called_emsg)
break; break;
}
if (nmatched > 0) { if (nmatched > 0) {
/* match may actually be in another line when using \zs */ /* match may actually be in another line when using \zs */
matchpos = regmatch.startpos[0]; matchpos = regmatch.startpos[0];
@@ -881,9 +878,8 @@ static void set_vv_searchforward(void)
set_vim_var_nr(VV_SEARCHFORWARD, (long)(spats[0].off.dir == '/')); set_vim_var_nr(VV_SEARCHFORWARD, (long)(spats[0].off.dir == '/'));
} }
/* // Return the number of the first subpat that matched.
* Return the number of the first subpat that matched. // Return zero if none of them matched.
*/
static int first_submatch(regmmatch_T *rp) static int first_submatch(regmmatch_T *rp)
{ {
int submatch; int submatch;

View File

@@ -15,19 +15,20 @@
#define ACTION_SHOW_ALL 4 #define ACTION_SHOW_ALL 4
#define ACTION_EXPAND 5 #define ACTION_EXPAND 5
/* Values for 'options' argument in do_search() and searchit() */ // Values for 'options' argument in do_search() and searchit()
#define SEARCH_REV 0x01 /* go in reverse of previous dir. */ #define SEARCH_REV 0x01 ///< go in reverse of previous dir.
#define SEARCH_ECHO 0x02 /* echo the search command and handle options */ #define SEARCH_ECHO 0x02 ///< echo the search command and handle options
#define SEARCH_MSG 0x0c /* give messages (yes, it's not 0x04) */ #define SEARCH_MSG 0x0c ///< give messages (yes, it's not 0x04)
#define SEARCH_NFMSG 0x08 /* give all messages except not found */ #define SEARCH_NFMSG 0x08 ///< give all messages except not found
#define SEARCH_OPT 0x10 /* interpret optional flags */ #define SEARCH_OPT 0x10 ///< interpret optional flags
#define SEARCH_HIS 0x20 /* put search pattern in history */ #define SEARCH_HIS 0x20 ///< put search pattern in history
#define SEARCH_END 0x40 /* put cursor at end of match */ #define SEARCH_END 0x40 ///< put cursor at end of match
#define SEARCH_NOOF 0x80 /* don't add offset to position */ #define SEARCH_NOOF 0x80 ///< don't add offset to position
#define SEARCH_START 0x100 /* start search without col offset */ #define SEARCH_START 0x100 ///< start search without col offset
#define SEARCH_MARK 0x200 /* set previous context mark */ #define SEARCH_MARK 0x200 ///< set previous context mark
#define SEARCH_KEEP 0x400 /* keep previous search pattern */ #define SEARCH_KEEP 0x400 ///< keep previous search pattern
#define SEARCH_PEEK 0x800 /* peek for typed char, cancel search */ #define SEARCH_PEEK 0x800 ///< peek for typed char, cancel search
#define SEARCH_COL 0x1000 ///< start at specified column instead of zero
/* Values for flags argument for findmatchlimit() */ /* Values for flags argument for findmatchlimit() */
#define FM_BACKWARD 0x01 /* search backwards */ #define FM_BACKWARD 0x01 /* search backwards */

View File

@@ -0,0 +1,28 @@
" Tests for searchpos()
func Test_searchpos()
new one
0put ='1a3'
1put ='123xyz'
call cursor(1, 1)
call assert_equal([1, 1, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
call cursor(1, 2)
call assert_equal([2, 1, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
set cpo-=c
call cursor(1, 2)
call assert_equal([1, 2, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
call cursor(1, 3)
call assert_equal([1, 3, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
" Now with \zs, first match is in column 0, "a" is matched.
call cursor(1. 3)
call assert_equal([2, 4, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcW'))
" With z flag start at cursor column, don't see the "a".
call cursor(1. 3)
call assert_equal([2, 4, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcWz'))
set cpo+=c
" close the window
q!
endfunc

View File

@@ -306,7 +306,7 @@ static int included_patches[] = {
// 987 NA // 987 NA
// 986 NA // 986 NA
// 985 NA // 985 NA
// 984, 984,
// 983, // 983,
// 982 NA // 982 NA
981, 981,