Patch 8.2.0077
Problem:    settagstack() cannot truncate at current index.
Solution:   Add the "t" action. (Yegappan Lakshmanan, closes #5417)
Files:      runtime/doc/eval.txt, src/evalfunc.c, src/tag.c,
            src/testdir/test_tagjump.vim


*** ../vim-8.2.0076/runtime/doc/eval.txt        2019-12-29 13:56:28.692861883 
+0100
--- runtime/doc/eval.txt        2020-01-02 14:00:46.304513843 +0100
***************
*** 8775,8785 ****
                {nr} can be the window number or the |window-ID|.
  
                For a list of supported items in {dict}, refer to
!               |gettagstack()|
                                                        *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.
  
                Returns zero for success, -1 for failure.
  
--- 8774,8794 ----
                {nr} can be the window number or the |window-ID|.
  
                For a list of supported items in {dict}, refer to
!               |gettagstack()|. "curidx" takes effect before changing the tag
!               stack.
                                                        *E962*
!               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.
  
*** ../vim-8.2.0076/src/evalfunc.c      2019-12-31 21:27:09.555256491 +0100
--- src/evalfunc.c      2020-01-02 13:55:35.357727520 +0100
***************
*** 6776,6782 ****
        actstr = tv_get_string_chk(&argvars[2]);
        if (actstr == NULL)
            return;
!       if ((*actstr == 'r' || *actstr == 'a') && actstr[1] == NUL)
            action = *actstr;
        else
        {
--- 6776,6783 ----
        actstr = tv_get_string_chk(&argvars[2]);
        if (actstr == NULL)
            return;
!       if ((*actstr == 'r' || *actstr == 'a' || *actstr == 't')
!               && actstr[1] == NUL)
            action = *actstr;
        else
        {
*** ../vim-8.2.0076/src/tag.c   2019-12-05 21:25:49.000000000 +0100
--- src/tag.c   2020-01-02 13:55:35.357727520 +0100
***************
*** 4224,4236 ****
  
  /*
   * 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)
  {
      dictitem_T        *di;
!     list_T    *l;
  
  #ifdef FEAT_EVAL
      // not allowed to alter the tag stack entries from inside tagfunc
--- 4224,4239 ----
  
  /*
   * Set the tag stack entries of the specified window.
!  * '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 = NULL;
  
  #ifdef FEAT_EVAL
      // not allowed to alter the tag stack entries from inside tagfunc
***************
*** 4249,4264 ****
            return FAIL;
        }
        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)
-       tagstack_set_curidx(wp, (int)tv_get_number(&di->di_tv) - 1);
- 
      return OK;
  }
  #endif
--- 4252,4283 ----
            return FAIL;
        }
        l = di->di_tv.vval.v_list;
+     }
+ 
+     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;
      }
  
      return OK;
  }
  #endif
*** ../vim-8.2.0076/src/testdir/test_tagjump.vim        2019-12-01 
14:33:37.000000000 +0100
--- src/testdir/test_tagjump.vim        2020-01-02 13:55:35.357727520 +0100
***************
*** 348,353 ****
--- 348,375 ----
          \ {'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",
*** ../vim-8.2.0076/src/version.c       2020-01-01 17:44:53.534008534 +0100
--- src/version.c       2020-01-02 13:56:55.969412524 +0100
***************
*** 744,745 ****
--- 744,747 ----
  {   /* Add new patch number below this line */
+ /**/
+     77,
  /**/

-- 
TIM: To the north there lies a cave,  the cave of Caerbannog, wherein, carved
     in mystic runes, upon the very living rock, the last words of Olfin
     Bedwere of Rheged make plain the last resting place of the most Holy
     Grail.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202001021302.002D2lme025601%40masaka.moolenaar.net.

Raspunde prin e-mail lui