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)
271fa08a35
This commit is contained in:
Jan Edmund Lazo
2020-01-29 20:44:23 -05:00
parent f719b8898b
commit 31f31b40a8
4 changed files with 65 additions and 14 deletions

View File

@@ -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);

View File

@@ -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,17 +3399,31 @@ int set_tagstack(win_T *wp, dict_T *d, int action)
return FAIL;
}
l = di->di_tv.vval.v_list;
if (action == 'r') {
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);
}
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);
// set the current index after the last entry
wp->w_tagstackidx = wp->w_tagstacklen;
}
return OK;
}

View File

@@ -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",