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.
{flags} is a String, which can contain these character flags:
'b' search backward instead of forward
'c' accept a match at the cursor position
'b' search Backward instead of forward
'c' accept a match at the Cursor position
'e' move to the End of the match
'n' do Not move the cursor
'p' return number of matching sub-pattern (see below)
's' set the ' mark at the previous location of the cursor
'w' wrap around the end of the file
'W' don't wrap around the end of the file
'p' return number of matching sub-Pattern (see below)
's' Set the ' mark at the previous location of the cursor
'w' 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 the 's' flag is supplied, the ' mark is set, only if the
@@ -5462,6 +5463,12 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
flag.
'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
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_REPEAT 0x02 /* repeat to find outer pair */
#define SP_RETCOUNT 0x04 /* return matchcount */
#define SP_SETPCMARK 0x08 /* set previous context mark */
#define SP_START 0x10 /* accept match at start position */
#define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */
#define SP_END 0x40 /* leave cursor at end of match */
#define SP_NOMOVE 0x01 ///< don't move cursor
#define SP_REPEAT 0x02 ///< repeat to find outer pair
#define SP_RETCOUNT 0x04 ///< return matchcount
#define SP_SETPCMARK 0x08 ///< set previous context mark
#define SP_START 0x10 ///< accept match at start position
#define SP_SUBPAT 0x20 ///< return nr of matching sub-pattern
#define SP_END 0x40 ///< leave cursor at end of match
#define SP_COLUMN 0x80 ///< start at cursor column
/*
* Get flags for a search function.
@@ -14378,13 +14378,14 @@ static int get_search_arg(typval_T *varp, int *flagsp)
default: mask = 0;
if (flagsp != NULL)
switch (*flags) {
case 'c': mask = SP_START; break;
case 'e': mask = SP_END; break;
case 'm': mask = SP_RETCOUNT; break;
case 'n': mask = SP_NOMOVE; break;
case 'p': mask = SP_SUBPAT; break;
case 'r': mask = SP_REPEAT; break;
case 's': mask = SP_SETPCMARK; break;
case 'c': mask = SP_START; break;
case 'e': mask = SP_END; break;
case 'm': mask = SP_RETCOUNT; break;
case 'n': mask = SP_NOMOVE; break;
case 'p': mask = SP_SUBPAT; break;
case 'r': mask = SP_REPEAT; break;
case 's': mask = SP_SETPCMARK; break;
case 'z': mask = SP_COLUMN; break;
}
if (mask == 0) {
EMSG2(_(e_invarg2), flags);
@@ -14400,9 +14401,7 @@ static int get_search_arg(typval_T *varp, int *flagsp)
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)
{
int flags;
@@ -14423,10 +14422,15 @@ static int search_cmn(typval_T *argvars, pos_T *match_pos, int *flagsp)
if (dir == 0)
goto theend;
flags = *flagsp;
if (flags & SP_START)
if (flags & SP_START) {
options |= SEARCH_START;
if (flags & SP_END)
}
if (flags & SP_END) {
options |= SEARCH_END;
}
if (flags & SP_COLUMN) {
options |= SEARCH_COL;
}
/* Optional arguments: line number to stop searching and timeout. */
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;
}
/*
* lowest level search function.
* Search for 'count'th occurrence of pattern 'pat' in direction 'dir'.
* 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) == SEARCH_NFMSG don't give 'notfound' messages
* if (options & SEARCH_MSG) == SEARCH_MSG give all messages
* if (options & SEARCH_HIS) put search pattern in history
* if (options & SEARCH_END) return position at end of match
* if (options & SEARCH_START) accept match at pos itself
* if (options & SEARCH_KEEP) keep previous search pattern
* if (options & SEARCH_FOLD) match only once in a closed fold
* if (options & SEARCH_PEEK) check for typed char, cancel search
*
* Return FAIL (zero) for failure, non-zero for success.
* Returns the index of the first matching
* subpattern plus one; one if there was none.
*/
/// lowest level search function.
/// Search for 'count'th occurrence of pattern 'pat' in direction 'dir'.
/// 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) == SEARCH_NFMSG don't give 'notfound' messages
/// if (options & SEARCH_MSG) == SEARCH_MSG give all messages
/// if (options & SEARCH_HIS) put search pattern in history
/// if (options & SEARCH_END) return position at end of match
/// if (options & SEARCH_START) accept match at pos itself
/// if (options & SEARCH_KEEP) keep previous search pattern
/// if (options & SEARCH_FOLD) match only once in a closed fold
/// if (options & SEARCH_PEEK) check for typed char, cancel search
/// if (options & SEARCH_COL) start at pos->col instead of zero
///
/// @returns FAIL (zero) for failure, non-zero for success.
/// the index of the first matching
/// subpattern plus one; one if there was none.
int searchit(
win_T *win, /* window to search in, can be NULL for a
buffer without a window! */
@@ -571,16 +570,14 @@ int searchit(
if (tm != NULL && profile_passed_limit(*tm))
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,
lnum, (colnr_T)0,
tm
);
/* Abort searching on an error (e.g., out of stack). */
if (called_emsg)
lnum, col, tm);
// Abort searching on an error (e.g., out of stack).
if (called_emsg) {
break;
}
if (nmatched > 0) {
/* match may actually be in another line when using \zs */
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 == '/'));
}
/*
* 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)
{
int submatch;

View File

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