summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2015-12-28 19:20:36 +0100
committerBram Moolenaar <Bram@vim.org>2015-12-28 19:20:36 +0100
commitad4d8a192abf44b89371af87d70b971cd654b799 (patch)
treead7554b6a90c075cd2722259604c812842c22c7c
parenta60824308cd9bc192c5d38fc16cccfcf652b40f6 (diff)
patch 7.4.984v7.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.
-rw-r--r--runtime/doc/eval.txt21
-rw-r--r--src/eval.c6
-rw-r--r--src/search.c11
-rw-r--r--src/testdir/test_alot.vim1
-rw-r--r--src/testdir/test_searchpos.vim28
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h1
7 files changed, 59 insertions, 11 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index f59c7f4ebe..cb612caaaf 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 7.4. Last change: 2015 Dec 03
+*eval.txt* For Vim version 7.4. Last change: 2015 Dec 28
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -5228,14 +5228,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
@@ -5243,6 +5244,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
diff --git a/src/eval.c b/src/eval.c
index 2668f3db5b..a2d2939ba2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -16471,6 +16471,7 @@ f_reverse(argvars, rettv)
#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 */
static int get_search_arg __ARGS((typval_T *varp, int *flagsp));
@@ -16512,6 +16513,7 @@ get_search_arg(varp, flagsp)
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)
{
@@ -16530,7 +16532,7 @@ get_search_arg(varp, flagsp)
}
/*
- * Shared by search() and searchpos() functions
+ * Shared by search() and searchpos() functions.
*/
static int
search_cmn(argvars, match_pos, flagsp)
@@ -16562,6 +16564,8 @@ search_cmn(argvars, match_pos, flagsp)
options |= SEARCH_START;
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)
diff --git a/src/search.c b/src/search.c
index 74398e39e8..1145558a69 100644
--- a/src/search.c
+++ b/src/search.c
@@ -578,6 +578,7 @@ last_pat_prog(regmatch)
* 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
*
* Return FAIL (zero) for failure, non-zero for success.
* 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)
{
int found;
linenr_T lnum; /* no init to shut up Apollo cc */
+ colnr_T col;
regmmatch_T regmatch;
char_u *ptr;
colnr_T matchcol;
@@ -711,12 +713,14 @@ searchit(win, buf, pos, dir, pat, count, options, pat_use, stop_lnum, tm)
/*
* Look for a match somewhere in line "lnum".
*/
+ col = at_first_line && (options & SEARCH_COL) ? pos->col
+ : (colnr_T)0;
nmatched = vim_regexec_multi(&regmatch, win, buf,
- lnum, (colnr_T)0,
+ lnum, col,
#ifdef FEAT_RELTIME
- tm
+ tm
#else
- NULL
+ NULL
#endif
);
/* Abort searching on an error (e.g., out of stack). */
@@ -1098,6 +1102,7 @@ set_vv_searchforward()
/*
* Return the number of the first subpat that matched.
+ * Return zero if none of them matched.
*/
static int
first_submatch(rp)
diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim
index 21a524116b..f15a2dce2c 100644
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -2,5 +2,6 @@
" This makes testing go faster, since Vim doesn't need to restart.
source test_lispwords.vim
+source test_searchpos.vim
source test_sort.vim
source test_undolevels.vim
diff --git a/src/testdir/test_searchpos.vim b/src/testdir/test_searchpos.vim
new file mode 100644
index 0000000000..4a1e024ce7
--- /dev/null
+++ b/src/testdir/test_searchpos.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 67f8d77f09..5a5a59c8a6 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 984,
+/**/
983,
/**/
982,
diff --git a/src/vim.h b/src/vim.h
index 729c45a54d..11b9119f2e 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -930,6 +930,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname);
#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 find_ident_under_cursor() */
#define FIND_IDENT 1 /* find identifier (word) */