aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2016-04-25 04:17:45 -0400
committerJustin M. Keyes <justinkz@gmail.com>2016-04-25 04:17:45 -0400
commitef205c3851fda637af49b5517bee60e6a62275ed (patch)
treea413274a5d7de9e1553ea475659dbad62e5ec0b8
parent6f980346864251d2ed86d85c63fd6ec375e21edc (diff)
parent9e3ebb67119438d46eaceac739aca88880177060 (diff)
downloadrneovim-ef205c3851fda637af49b5517bee60e6a62275ed.tar.gz
rneovim-ef205c3851fda637af49b5517bee60e6a62275ed.tar.bz2
rneovim-ef205c3851fda637af49b5517bee60e6a62275ed.zip
Merge pull request #4325 from watiko/vim-7.4.984
vim-patch:7.4.{984,1093}
-rw-r--r--runtime/doc/eval.txt19
-rw-r--r--src/nvim/eval.c58
-rw-r--r--src/nvim/search.c56
-rw-r--r--src/nvim/search.h27
-rw-r--r--src/nvim/version.c4
-rw-r--r--test/functional/legacy/searchpos_spec.lua35
6 files changed, 122 insertions, 77 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index f6bdde2d39..e341a2247a 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -5548,14 +5548,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
@@ -5563,6 +5564,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/nvim/eval.c b/src/nvim/eval.c
index a68d09575b..9553c7a7ed 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8304,12 +8304,12 @@ static void f_cscope_connection(typval_T *argvars, typval_T *rettv)
rettv->vval.v_number = cs_connection(num, dbpath, prepend);
}
-/*
- * "cursor(lnum, col)" function
- *
- * Moves the cursor to the specified line and column.
- * Returns 0 when the position could be set, -1 otherwise.
- */
+/// "cursor(lnum, col)" function, or
+/// "cursor(list)"
+///
+/// Moves the cursor to the specified line and column.
+///
+/// @returns 0 when the position could be set, -1 otherwise.
static void f_cursor(typval_T *argvars, typval_T *rettv)
{
long line, col;
@@ -8321,8 +8321,10 @@ static void f_cursor(typval_T *argvars, typval_T *rettv)
colnr_T curswant = -1;
if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL) {
+ EMSG(_(e_invarg));
return;
}
+
line = pos.lnum;
col = pos.col;
coladd = pos.coladd;
@@ -13536,14 +13538,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.
@@ -13569,13 +13571,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);
@@ -13591,9 +13594,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;
@@ -13614,10 +13615,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) {
diff --git a/src/nvim/search.c b/src/nvim/search.c
index fffae1ecb2..faf70472bf 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -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;
diff --git a/src/nvim/search.h b/src/nvim/search.h
index 6947f79d49..d4e40cb287 100644
--- a/src/nvim/search.h
+++ b/src/nvim/search.h
@@ -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 */
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 84d5342a80..e07c4a242a 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -584,7 +584,7 @@ static int included_patches[] = {
// 1096,
// 1095 NA
// 1094,
- // 1093,
+ 1093,
// 1092,
// 1091,
// 1090,
@@ -693,7 +693,7 @@ static int included_patches[] = {
// 987 NA
// 986 NA
// 985 NA
- // 984,
+ 984,
// 983,
// 982 NA
981,
diff --git a/test/functional/legacy/searchpos_spec.lua b/test/functional/legacy/searchpos_spec.lua
new file mode 100644
index 0000000000..1c9b1ccee6
--- /dev/null
+++ b/test/functional/legacy/searchpos_spec.lua
@@ -0,0 +1,35 @@
+local helpers = require('test.functional.helpers')
+local call = helpers.call
+local clear = helpers.clear
+local execute = helpers.execute
+local eq = helpers.eq
+local eval = helpers.eval
+local insert = helpers.insert
+
+describe('searchpos', function()
+ before_each(clear)
+
+ it('is working', function()
+ insert([[
+ 1a3
+ 123xyz]])
+
+ call('cursor', 1, 1)
+ eq({1, 1, 2}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+ call('cursor', 1, 2)
+ eq({2, 1, 1}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+
+ execute('set cpo-=c')
+ call('cursor', 1, 2)
+ eq({1, 2, 2}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+ call('cursor', 1, 3)
+ eq({1, 3, 1}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')]]))
+
+ -- Now with \zs, first match is in column 0, "a" is matched.
+ call('cursor', 1, 3)
+ eq({2, 4, 2}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcW')]]))
+ -- With z flag start at cursor column, don't see the "a".
+ call('cursor', 1, 3)
+ eq({2, 4, 1}, eval([[searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcWz')]]))
+ end)
+end)