diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-01-29 20:44:23 -0500 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-01-29 21:00:11 -0500 |
commit | 31f31b40a8af67a3a55e85fa5dfa63d5a5999acc (patch) | |
tree | 705f39a1649e74e8fd0b107f2f5dca9349bc4bb1 | |
parent | f719b8898ba8aa18f0411be1924eea132a3b103e (diff) | |
download | rneovim-31f31b40a8af67a3a55e85fa5dfa63d5a5999acc.tar.gz rneovim-31f31b40a8af67a3a55e85fa5dfa63d5a5999acc.tar.bz2 rneovim-31f31b40a8af67a3a55e85fa5dfa63d5a5999acc.zip |
vim-patch:8.2.0077: settagstack() cannot truncate at current index
Problem: settagstack() cannot truncate at current index.
Solution: Add the "t" action. (Yegappan Lakshmanan, closes vim/vim#5417)
https://github.com/vim/vim/commit/271fa08a35b8d320d3a40db4ddae83b698fdd4fb
-rw-r--r-- | runtime/doc/eval.txt | 18 | ||||
-rw-r--r-- | src/nvim/eval.c | 3 | ||||
-rw-r--r-- | src/nvim/tag.c | 34 | ||||
-rw-r--r-- | src/nvim/testdir/test_tagjump.vim | 22 |
4 files changed, 64 insertions, 13 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 69b8b3cf39..e0ce83f8d2 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -7550,11 +7550,21 @@ settagstack({nr}, {dict} [, {action}]) *settagstack()* {nr} can be the window number or the |window-ID|. For a list of supported items in {dict}, refer to - |gettagstack()| + |gettagstack()|. "curidx" takes effect before changing the tag + stack. *E962* - If {action} is not present or is set to 'r', then the tag - stack is replaced. If {action} is set to 'a', then new entries - from {dict} are pushed onto the tag stack. + How the tag stack is modified depends on the {action} + argument: + - If {action} is not present or is set to 'r', then the tag + stack is replaced. + - If {action} is set to 'a', then new entries from {dict} are + pushed (added) onto the tag stack. + - If {action} is set to 't', then all the entries from the + current entry in the tag stack or "curidx" in {dict} are + removed and then new entries are pushed to the stack. + + The current index is set to one after the length of the tag + stack after the modification. Returns zero for success, -1 for failure. diff --git a/src/nvim/eval.c b/src/nvim/eval.c index b3cc3282d5..47c094f49d 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -16242,7 +16242,8 @@ static void f_settagstack(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (actstr == NULL) { return; } - if ((*actstr == 'r' || *actstr == 'a') && actstr[1] == NUL) { + if ((*actstr == 'r' || *actstr == 'a' || *actstr == 't') + && actstr[1] == NUL) { action = *actstr; } else { EMSG2(_(e_invact2), actstr); diff --git a/src/nvim/tag.c b/src/nvim/tag.c index a412ed0276..07f29977aa 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -3378,11 +3378,15 @@ static void tagstack_set_curidx(win_T *wp, int curidx) } // Set the tag stack entries of the specified window. -// 'action' is set to either 'a' for append or 'r' for replace. -int set_tagstack(win_T *wp, dict_T *d, int action) +// 'action' is set to one of: +// 'a' for append +// 'r' for replace +// 't' for truncate +int set_tagstack(win_T *wp, const dict_T *d, int action) + FUNC_ATTR_NONNULL_ARG(1) { dictitem_T *di; - list_T *l; + list_T *l = NULL; // not allowed to alter the tag stack entries from inside tagfunc if (tfu_in_use) { @@ -3395,16 +3399,30 @@ int set_tagstack(win_T *wp, dict_T *d, int action) return FAIL; } l = di->di_tv.vval.v_list; + } - if (action == 'r') { + if ((di = tv_dict_find(d, "curidx", -1)) != NULL) { + tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1); + } + if (action == 't') { // truncate the stack + taggy_T *const tagstack = wp->w_tagstack; + const int tagstackidx = wp->w_tagstackidx; + int tagstacklen = wp->w_tagstacklen; + // delete all the tag stack entries above the current entry + while (tagstackidx < tagstacklen) { + tagstack_clear_entry(&tagstack[--tagstacklen]); + } + wp->w_tagstacklen = tagstacklen; + } + + if (l != NULL) { + if (action == 'r') { // replace the stack tagstack_clear(wp); } tagstack_push_items(wp, l); - } - - if ((di = tv_dict_find(d, "curidx", -1)) != NULL) { - tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1); + // set the current index after the last entry + wp->w_tagstackidx = wp->w_tagstacklen; } return OK; diff --git a/src/nvim/testdir/test_tagjump.vim b/src/nvim/testdir/test_tagjump.vim index fe98ef1ae2..5fd71d8bfc 100644 --- a/src/nvim/testdir/test_tagjump.vim +++ b/src/nvim/testdir/test_tagjump.vim @@ -340,6 +340,28 @@ func Test_getsettagstack() \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a') call assert_equal('abc', gettagstack().items[19].tagname) + " truncate the tag stack + call settagstack(1, + \ {'curidx' : 9, + \ 'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't') + let t = gettagstack() + call assert_equal(9, t.length) + call assert_equal(10, t.curidx) + + " truncate the tag stack without pushing any new items + call settagstack(1, {'curidx' : 5}, 't') + let t = gettagstack() + call assert_equal(4, t.length) + call assert_equal(5, t.curidx) + + " truncate an empty tag stack and push new items + call settagstack(1, {'items' : []}) + call settagstack(1, + \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 't') + let t = gettagstack() + call assert_equal(1, t.length) + call assert_equal(2, t.curidx) + " Tag with multiple matches call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", \ "two\tXfile1\t1", |