]> granicus.if.org Git - vim/commitdiff
patch 8.2.0077: settagstack() cannot truncate at current index v8.2.0077
authorBram Moolenaar <Bram@vim.org>
Thu, 2 Jan 2020 13:02:16 +0000 (14:02 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 2 Jan 2020 13:02:16 +0000 (14:02 +0100)
Problem:    settagstack() cannot truncate at current index.
Solution:   Add the "t" action. (Yegappan Lakshmanan, closes #5417)

runtime/doc/eval.txt
src/evalfunc.c
src/tag.c
src/testdir/test_tagjump.vim
src/version.c

index f06a7276238f4863899b7d7b748bfe042d351d55..dceae48ea50ccd910c33f4e379579901f5084d0a 100644 (file)
@@ -8774,11 +8774,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.
 
index 489ab424a941ea8011487035934bbb6670d56dd5..af43fb96ec9136f44c26299022a5435b5decdb89 100644 (file)
@@ -6776,7 +6776,8 @@ f_settagstack(typval_T *argvars, typval_T *rettv)
        actstr = tv_get_string_chk(&argvars[2]);
        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
        {
index c00f5fb72384950fc6a58c0d9e0e89e8ab42c66e..4f897fa607234e8313cff0df2527b31ae47a2787 100644 (file)
--- a/src/tag.c
+++ b/src/tag.c
@@ -4224,13 +4224,16 @@ 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.
+ * 'action' is set to one of:
+ *     'a' for append
+ *     'r' for replace
+ *     't' for truncate
  */
     int
 set_tagstack(win_T *wp, dict_T *d, int action)
 {
     dictitem_T *di;
-    list_T     *l;
+    list_T     *l = NULL;
 
 #ifdef FEAT_EVAL
     // 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;
        }
        l = di->di_tv.vval.v_list;
+    }
 
-       if (action == 'r')
+    if ((di = dict_find(d, (char_u *)"curidx", -1)) != NULL)
+       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;
     }
 
-    if ((di = dict_find(d, (char_u *)"curidx", -1)) != NULL)
-       tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1);
-
     return OK;
 }
 #endif
index 14ba1f78ddb6640a9390e4e8f1967f31fa94d197..8d32883da207541dd224a4af45ce992b78c7c5a8 100644 (file)
@@ -348,6 +348,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",
index 263ffb012580d6c0b9d0d14a7d47aa4b812749cf..118dad505b6f5087423750d0f609c4b499251edd 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    77,
 /**/
     76,
 /**/