Skip to content

Commit ad4d8a1

Browse files
committed
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.
1 parent a608243 commit ad4d8a1

File tree

7 files changed

+59
-11
lines changed

7 files changed

+59
-11
lines changed

runtime/doc/eval.txt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 7.4. Last change: 2015 Dec 03
1+
*eval.txt* For Vim version 7.4. Last change: 2015 Dec 28
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -5228,21 +5228,28 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
52285228
move. No error message is given.
52295229

52305230
{flags} is a String, which can contain these character flags:
5231-
'b' search backward instead of forward
5232-
'c' accept a match at the cursor position
5231+
'b' search Backward instead of forward
5232+
'c' accept a match at the Cursor position
52335233
'e' move to the End of the match
52345234
'n' do Not move the cursor
5235-
'p' return number of matching sub-pattern (see below)
5236-
's' set the ' mark at the previous location of the cursor
5237-
'w' wrap around the end of the file
5238-
'W' don't wrap around the end of the file
5235+
'p' return number of matching sub-Pattern (see below)
5236+
's' Set the ' mark at the previous location of the cursor
5237+
'w' Wrap around the end of the file
5238+
'W' don't Wrap around the end of the file
5239+
'z' start searching at the cursor column instead of zero
52395240
If neither 'w' or 'W' is given, the 'wrapscan' option applies.
52405241

52415242
If the 's' flag is supplied, the ' mark is set, only if the
52425243
cursor is moved. The 's' flag cannot be combined with the 'n'
52435244
flag.
52445245

52455246
'ignorecase', 'smartcase' and 'magic' are used.
5247+
5248+
When the 'z' flag is not given seaching always starts in
5249+
column zero and then matches before the cursor are skipped.
5250+
When the 'c' flag is present in 'cpo' the next search starts
5251+
after the match. Without the 'c' flag the next search starts
5252+
one column further.
52465253

52475254
When the {stopline} argument is given then the search stops
52485255
after searching this line. This is useful to restrict the

src/eval.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16471,6 +16471,7 @@ f_reverse(argvars, rettv)
1647116471
#define SP_START 0x10 /* accept match at start position */
1647216472
#define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */
1647316473
#define SP_END 0x40 /* leave cursor at end of match */
16474+
#define SP_COLUMN 0x80 /* start at cursor column */
1647416475

1647516476
static int get_search_arg __ARGS((typval_T *varp, int *flagsp));
1647616477

@@ -16512,6 +16513,7 @@ get_search_arg(varp, flagsp)
1651216513
case 'p': mask = SP_SUBPAT; break;
1651316514
case 'r': mask = SP_REPEAT; break;
1651416515
case 's': mask = SP_SETPCMARK; break;
16516+
case 'z': mask = SP_COLUMN; break;
1651516517
}
1651616518
if (mask == 0)
1651716519
{
@@ -16530,7 +16532,7 @@ get_search_arg(varp, flagsp)
1653016532
}
1653116533

1653216534
/*
16533-
* Shared by search() and searchpos() functions
16535+
* Shared by search() and searchpos() functions.
1653416536
*/
1653516537
static int
1653616538
search_cmn(argvars, match_pos, flagsp)
@@ -16562,6 +16564,8 @@ search_cmn(argvars, match_pos, flagsp)
1656216564
options |= SEARCH_START;
1656316565
if (flags & SP_END)
1656416566
options |= SEARCH_END;
16567+
if (flags & SP_COLUMN)
16568+
options |= SEARCH_COL;
1656516569

1656616570
/* Optional arguments: line number to stop searching and timeout. */
1656716571
if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN)

src/search.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,7 @@ last_pat_prog(regmatch)
578578
* if (options & SEARCH_KEEP) keep previous search pattern
579579
* if (options & SEARCH_FOLD) match only once in a closed fold
580580
* if (options & SEARCH_PEEK) check for typed char, cancel search
581+
* if (options & SEARCH_COL) start at pos->col instead of zero
581582
*
582583
* Return FAIL (zero) for failure, non-zero for success.
583584
* When FEAT_EVAL is defined, returns the index of the first matching
@@ -599,6 +600,7 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm)
599600
{
600601
int found;
601602
linenr_T lnum; /* no init to shut up Apollo cc */
603+
colnr_T col;
602604
regmmatch_T regmatch;
603605
char_u *ptr;
604606
colnr_T matchcol;
@@ -711,12 +713,14 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm)
711713
/*
712714
* Look for a match somewhere in line "lnum".
713715
*/
716+
col = at_first_line && (options & SEARCH_COL) ? pos->col
717+
: (colnr_T)0;
714718
nmatched = vim_regexec_multi(&regmatch, win, buf,
715-
lnum, (colnr_T)0,
719+
lnum, col,
716720
#ifdef FEAT_RELTIME
717-
tm
721+
tm
718722
#else
719-
NULL
723+
NULL
720724
#endif
721725
);
722726
/* Abort searching on an error (e.g., out of stack). */
@@ -1098,6 +1102,7 @@ set_vv_searchforward()
10981102

10991103
/*
11001104
* Return the number of the first subpat that matched.
1105+
* Return zero if none of them matched.
11011106
*/
11021107
static int
11031108
first_submatch(rp)

src/testdir/test_alot.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
" This makes testing go faster, since Vim doesn't need to restart.
33

44
source test_lispwords.vim
5+
source test_searchpos.vim
56
source test_sort.vim
67
source test_undolevels.vim

src/testdir/test_searchpos.vim

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
" Tests for searchpos()
2+
3+
func Test_searchpos()
4+
new one
5+
0put ='1a3'
6+
1put ='123xyz'
7+
call cursor(1, 1)
8+
call assert_equal([1, 1, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
9+
call cursor(1, 2)
10+
call assert_equal([2, 1, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
11+
set cpo-=c
12+
call cursor(1, 2)
13+
call assert_equal([1, 2, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
14+
call cursor(1, 3)
15+
call assert_equal([1, 3, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW'))
16+
17+
" Now with \zs, first match is in column 0, "a" is matched.
18+
call cursor(1. 3)
19+
call assert_equal([2, 4, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcW'))
20+
" With z flag start at cursor column, don't see the "a".
21+
call cursor(1. 3)
22+
call assert_equal([2, 4, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcWz'))
23+
24+
set cpo+=c
25+
" close the window
26+
q!
27+
28+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ static char *(features[]) =
741741

742742
static int included_patches[] =
743743
{ /* Add new patch number below this line */
744+
/**/
745+
984,
744746
/**/
745747
983,
746748
/**/

src/vim.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
930930
#define SEARCH_MARK 0x200 /* set previous context mark */
931931
#define SEARCH_KEEP 0x400 /* keep previous search pattern */
932932
#define SEARCH_PEEK 0x800 /* peek for typed char, cancel search */
933+
#define SEARCH_COL 0x1000 /* start at specified column instead of zero */
933934

934935
/* Values for find_ident_under_cursor() */
935936
#define FIND_IDENT 1 /* find identifier (word) */

0 commit comments

Comments
 (0)