0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

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 #5417)
This commit is contained in:
Bram Moolenaar 2020-01-02 14:02:16 +01:00
parent 955f4e6f36
commit 271fa08a35
5 changed files with 66 additions and 12 deletions

View File

@ -8774,11 +8774,21 @@ settagstack({nr}, {dict} [, {action}]) *settagstack()*
{nr} can be the window number or the |window-ID|. {nr} can be the window number or the |window-ID|.
For a list of supported items in {dict}, refer to For a list of supported items in {dict}, refer to
|gettagstack()| |gettagstack()|. "curidx" takes effect before changing the tag
stack.
*E962* *E962*
If {action} is not present or is set to 'r', then the tag How the tag stack is modified depends on the {action}
stack is replaced. If {action} is set to 'a', then new entries argument:
from {dict} are pushed onto the tag stack. - 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. Returns zero for success, -1 for failure.

View File

@ -6776,7 +6776,8 @@ f_settagstack(typval_T *argvars, typval_T *rettv)
actstr = tv_get_string_chk(&argvars[2]); actstr = tv_get_string_chk(&argvars[2]);
if (actstr == NULL) if (actstr == NULL)
return; return;
if ((*actstr == 'r' || *actstr == 'a') && actstr[1] == NUL) if ((*actstr == 'r' || *actstr == 'a' || *actstr == 't')
&& actstr[1] == NUL)
action = *actstr; action = *actstr;
else else
{ {

View File

@ -4224,13 +4224,16 @@ tagstack_set_curidx(win_T *wp, int curidx)
/* /*
* Set the tag stack entries of the specified window. * Set the tag stack entries of the specified window.
* 'action' is set to either 'a' for append or 'r' for replace. * 'action' is set to one of:
* 'a' for append
* 'r' for replace
* 't' for truncate
*/ */
int int
set_tagstack(win_T *wp, dict_T *d, int action) set_tagstack(win_T *wp, dict_T *d, int action)
{ {
dictitem_T *di; dictitem_T *di;
list_T *l; list_T *l = NULL;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
// not allowed to alter the tag stack entries from inside tagfunc // not allowed to alter the tag stack entries from inside tagfunc
@ -4249,16 +4252,32 @@ set_tagstack(win_T *wp, dict_T *d, int action)
return FAIL; return FAIL;
} }
l = di->di_tv.vval.v_list; l = di->di_tv.vval.v_list;
if (action == 'r')
tagstack_clear(wp);
tagstack_push_items(wp, l);
} }
if ((di = dict_find(d, (char_u *)"curidx", -1)) != NULL) if ((di = dict_find(d, (char_u *)"curidx", -1)) != NULL)
tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1); tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1);
if (action == 't') // truncate the stack
{
taggy_T *tagstack = wp->w_tagstack;
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; return OK;
} }
#endif #endif

View File

@ -348,6 +348,28 @@ func Test_getsettagstack()
\ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a') \ {'items' : [{'tagname' : 'abc', 'from' : [1, 10, 1, 0]}]}, 'a')
call assert_equal('abc', gettagstack().items[19].tagname) 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 " Tag with multiple matches
call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//", call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
\ "two\tXfile1\t1", \ "two\tXfile1\t1",

View File

@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
77,
/**/ /**/
76, 76,
/**/ /**/