aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c50
-rw-r--r--src/nvim/search.c74
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/test_charsearch.in25
-rw-r--r--src/nvim/testdir/test_charsearch.ok3
-rw-r--r--src/nvim/version.c6
6 files changed, 137 insertions, 22 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index bf9a219e28..a5ab57785c 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -6599,6 +6599,7 @@ static struct fst {
{"getbufvar", 2, 3, f_getbufvar},
{"getchar", 0, 1, f_getchar},
{"getcharmod", 0, 0, f_getcharmod},
+ {"getcharsearch", 0, 0, f_getcharsearch},
{"getcmdline", 0, 0, f_getcmdline},
{"getcmdpos", 0, 0, f_getcmdpos},
{"getcmdtype", 0, 0, f_getcmdtype},
@@ -6725,6 +6726,7 @@ static struct fst {
{"serverstart", 0, 1, f_serverstart},
{"serverstop", 1, 1, f_serverstop},
{"setbufvar", 3, 3, f_setbufvar},
+ {"setcharsearch", 1, 1, f_setcharsearch},
{"setcmdpos", 1, 1, f_setcmdpos},
{"setline", 2, 2, f_setline},
{"setloclist", 2, 3, f_setloclist},
@@ -9304,6 +9306,20 @@ static void f_getcharmod(typval_T *argvars, typval_T *rettv)
}
/*
+ * "getcharsearch()" function
+ */
+static void f_getcharsearch(typval_T *argvars, typval_T *rettv)
+{
+ rettv_dict_alloc(rettv);
+
+ dict_T *dict = rettv->vval.v_dict;
+
+ dict_add_nr_str(dict, "char", 0L, last_csearch());
+ dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL);
+ dict_add_nr_str(dict, "until", last_csearch_until(), NULL);
+}
+
+/*
* "getcmdline()" function
*/
static void f_getcmdline(typval_T *argvars, typval_T *rettv)
@@ -14299,6 +14315,40 @@ static void f_setbufvar(typval_T *argvars, typval_T *rettv)
}
}
+static void f_setcharsearch(typval_T *argvars, typval_T *rettv)
+{
+ dict_T *d;
+ dictitem_T *di;
+ char_u *csearch;
+
+ if (argvars[0].v_type != VAR_DICT) {
+ EMSG(_(e_dictreq));
+ return;
+ }
+
+ if ((d = argvars[0].vval.v_dict) != NULL) {
+ csearch = get_dict_string(d, (char_u *)"char", FALSE);
+ if (csearch != NULL) {
+ if (enc_utf8) {
+ int pcc[MAX_MCO];
+ int c = utfc_ptr2char(csearch, pcc);
+ set_last_csearch(c, csearch, utfc_ptr2len(csearch));
+ }
+ else
+ set_last_csearch(PTR2CHAR(csearch),
+ csearch, MB_PTR2LEN(csearch));
+ }
+
+ di = dict_find(d, (char_u *)"forward", -1);
+ if (di != NULL)
+ set_csearch_direction(get_tv_number(&di->di_tv) ? FORWARD : BACKWARD);
+
+ di = dict_find(d, (char_u *)"until", -1);
+ if (di != NULL)
+ set_csearch_until(!!get_tv_number(&di->di_tv));
+ }
+}
+
/*
* "setcmdpos()" function
*/
diff --git a/src/nvim/search.c b/src/nvim/search.c
index f91ac3bb9c..f503994e73 100644
--- a/src/nvim/search.c
+++ b/src/nvim/search.c
@@ -108,6 +108,12 @@ static struct spat spats[2] =
static int last_idx = 0; /* index in spats[] for RE_LAST */
+static char_u lastc[2] = {NUL, NUL}; /* last character searched for */
+static int lastcdir = FORWARD; /* last direction of character search */
+static int last_t_cmd = TRUE; /* last search t_cmd */
+static char_u lastc_bytes[MB_MAXBYTES + 1];
+static int lastc_bytelen = 1; /* >1 for multi-byte char */
+
/* copy of spats[], for keeping the search patterns while executing autocmds */
static struct spat saved_spats[2];
static int saved_last_idx = 0;
@@ -327,7 +333,7 @@ int ignorecase(char_u *pat)
}
/*
- * Return TRUE if patter "pat" has an uppercase character.
+ * Return TRUE if pattern "pat" has an uppercase character.
*/
int pat_has_uppercase(char_u *pat)
{
@@ -357,6 +363,41 @@ int pat_has_uppercase(char_u *pat)
return FALSE;
}
+char_u *last_csearch(void)
+{
+ return lastc_bytes;
+}
+
+int last_csearch_forward(void)
+{
+ return lastcdir == FORWARD;
+}
+
+int last_csearch_until(void)
+{
+ return last_t_cmd == TRUE;
+}
+
+void set_last_csearch(int c, char_u *s, int len)
+{
+ *lastc = c;
+ lastc_bytelen = len;
+ if (len)
+ memcpy(lastc_bytes, s, len);
+ else
+ memset(lastc_bytes, 0, sizeof(lastc_bytes));
+}
+
+void set_csearch_direction(int cdir)
+{
+ lastcdir = cdir;
+}
+
+void set_csearch_until(int t_cmd)
+{
+ last_t_cmd = t_cmd;
+}
+
char_u *last_search_pat(void)
{
return spats[last_idx].pat;
@@ -1286,38 +1327,33 @@ int searchc(cmdarg_T *cap, int t_cmd)
int c = cap->nchar; /* char to search for */
int dir = cap->arg; /* TRUE for searching forward */
long count = cap->count1; /* repeat count */
- static int lastc = NUL; /* last character searched for */
- static int lastcdir; /* last direction of character search */
- static int last_t_cmd; /* last search t_cmd */
int col;
char_u *p;
int len;
int stop = TRUE;
- static char_u bytes[MB_MAXBYTES + 1];
- static int bytelen = 1; /* >1 for multi-byte char */
if (c != NUL) { /* normal search: remember args for repeat */
if (!KeyStuffed) { /* don't remember when redoing */
- lastc = c;
- lastcdir = dir;
- last_t_cmd = t_cmd;
- bytelen = (*mb_char2bytes)(c, bytes);
+ *lastc = c;
+ set_csearch_direction(dir);
+ set_csearch_until(t_cmd);
+ lastc_bytelen = (*mb_char2bytes)(c, lastc_bytes);
if (cap->ncharC1 != 0) {
- bytelen += (*mb_char2bytes)(cap->ncharC1, bytes + bytelen);
+ lastc_bytelen += (*mb_char2bytes)(cap->ncharC1, lastc_bytes + lastc_bytelen);
if (cap->ncharC2 != 0)
- bytelen += (*mb_char2bytes)(cap->ncharC2, bytes + bytelen);
+ lastc_bytelen += (*mb_char2bytes)(cap->ncharC2, lastc_bytes + lastc_bytelen);
}
}
} else { /* repeat previous search */
- if (lastc == NUL)
+ if (*lastc == NUL)
return FAIL;
if (dir) /* repeat in opposite direction */
dir = -lastcdir;
else
dir = lastcdir;
t_cmd = last_t_cmd;
- c = lastc;
- /* For multi-byte re-use last bytes[] and bytelen. */
+ c = *lastc;
+ /* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */
/* Force a move of at least one char, so ";" and "," will move the
* cursor, even if the cursor is right in front of char we are looking
@@ -1347,11 +1383,11 @@ int searchc(cmdarg_T *cap, int t_cmd)
return FAIL;
col -= (*mb_head_off)(p, p + col - 1) + 1;
}
- if (bytelen == 1) {
+ if (lastc_bytelen == 1) {
if (p[col] == c && stop)
break;
} else {
- if (memcmp(p + col, bytes, bytelen) == 0 && stop)
+ if (memcmp(p + col, lastc_bytes, lastc_bytelen) == 0 && stop)
break;
}
stop = TRUE;
@@ -1372,8 +1408,8 @@ int searchc(cmdarg_T *cap, int t_cmd)
col -= dir;
if (has_mbyte) {
if (dir < 0)
- /* Landed on the search char which is bytelen long */
- col += bytelen - 1;
+ /* Landed on the search char which is lastc_bytelen long */
+ col += lastc_bytelen - 1;
else
/* To previous char, which may be multi-byte. */
col -= (*mb_head_off)(p, p + col);
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index c97ffc2ced..6af8893800 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -27,6 +27,7 @@ SCRIPTS := test_eval.out \
test88.out \
test_listlbr.out \
test_breakindent.out \
+ test_charsearch.out \
test_close_count.out \
test_command_count.out \
diff --git a/src/nvim/testdir/test_charsearch.in b/src/nvim/testdir/test_charsearch.in
new file mode 100644
index 0000000000..5085cb39bc
--- /dev/null
+++ b/src/nvim/testdir/test_charsearch.in
@@ -0,0 +1,25 @@
+Test for character searches
+
+STARTTEST
+:so small.vim
+:" check that "fe" and ";" work
+/^X
+ylfep;;p,,p:
+:" check that save/restore works
+/^Y
+ylfep:let csave = getcharsearch()
+fip:call setcharsearch(csave)
+;p;p:
+:" check that setcharsearch() changes the settins.
+/^Z
+ylfep:call setcharsearch({'char': 'k'})
+;p:call setcharsearch({'forward': 0})
+$;p:call setcharseearch({'until'}: 1})
+;;p:
+:/^X/,$w! test.out
+:qa!
+ENDTEST
+
+Xabcdefghijkemnopqretuvwxyz
+Yabcdefghijkemnopqretuvwxyz
+Zabcdefghijkemnokqretkvwxyz
diff --git a/src/nvim/testdir/test_charsearch.ok b/src/nvim/testdir/test_charsearch.ok
new file mode 100644
index 0000000000..a0c90e24f9
--- /dev/null
+++ b/src/nvim/testdir/test_charsearch.ok
@@ -0,0 +1,3 @@
+XabcdeXfghijkeXmnopqreXtuvwxyz
+YabcdeYfghiYjkeYmnopqreYtuvwxyz
+ZabcdeZfghijkZemnokZqretkZvwxyz
diff --git a/src/nvim/version.c b/src/nvim/version.c
index d7038fd635..c79c9d0f38 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -71,9 +71,9 @@ static char *features[] = {
// clang-format off
static int included_patches[] = {
- //826,
+ 826,
//825,
- //824,
+ //824 NA
//823,
//822,
//821,
@@ -84,7 +84,7 @@ static int included_patches[] = {
//816,
//815,
//814,
- //813,
+ 813,
//812,
//811,
//810,