mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 08:18:17 +00:00
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:
@@ -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.
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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",
|
||||
|
Reference in New Issue
Block a user