diff options
author | James McCoy <vega.james@gmail.com> | 2015-08-19 21:53:52 -0400 |
---|---|---|
committer | James McCoy <vega.james@gmail.com> | 2015-08-20 10:32:25 -0400 |
commit | f6f28c18e5824b13f4a20a481a9f350f0e652e9b (patch) | |
tree | 32a5dd8a94ae9891d9e3d3f65abdb14f75c8f108 /src | |
parent | 08bae4533704120199c188eb3cfac2b6ba4096c0 (diff) | |
download | rneovim-f6f28c18e5824b13f4a20a481a9f350f0e652e9b.tar.gz rneovim-f6f28c18e5824b13f4a20a481a9f350f0e652e9b.tar.bz2 rneovim-f6f28c18e5824b13f4a20a481a9f350f0e652e9b.zip |
7.4.813
patch 7.4.813
Problem: It is not possible to save and restore character search state.
Solution: Add getcharsearch() and setcharsearch(). (James McCoy)
https://github.com/vim/vim/releases/tag/v7.4.813
https://github.com/vim/vim/releases/tag/v7.4.826
Signed-off-by: James McCoy <vega.james@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.c | 50 | ||||
-rw-r--r-- | src/nvim/search.c | 74 | ||||
-rw-r--r-- | src/nvim/testdir/Makefile | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_charsearch.in | 25 | ||||
-rw-r--r-- | src/nvim/testdir/test_charsearch.ok | 3 | ||||
-rw-r--r-- | src/nvim/version.c | 6 |
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, |