Patch 8.1.1084
Problem:    Cannot delete a match from another window. (Paul Jolly)
Solution:   Add window ID argument to matchdelete(), clearmatches(),
            getmatches() and setmatches(). (Andy Massimino, closes #4178)
Files:      runtime/doc/eval.txt, src/evalfunc.c, src/testdir/test_match.vim

*** ../vim-8.1.1083/runtime/doc/eval.txt        2019-03-29 14:16:34.138861795 
+0100
--- runtime/doc/eval.txt        2019-03-30 17:50:40.288425654 +0100
***************
*** 2237,2243 ****
  changenr()                    Number  current change number
  char2nr({expr} [, {utf8}])    Number  ASCII/UTF8 value of first char in {expr}
  cindent({lnum})                       Number  C indent for line {lnum}
! clearmatches()                        none    clear all matches
  col({expr})                   Number  column nr of cursor or mark
  complete({startcol}, {matches}) none  set Insert mode completion
  complete_add({expr})          Number  add completion match
--- 2265,2271 ----
  changenr()                    Number  current change number
  char2nr({expr} [, {utf8}])    Number  ASCII/UTF8 value of first char in {expr}
  cindent({lnum})                       Number  C indent for line {lnum}
! clearmatches([{win}])         none    clear all matches
  col({expr})                   Number  column nr of cursor or mark
  complete({startcol}, {matches}) none  set Insert mode completion
  complete_add({expr})          Number  add completion match
***************
*** 2331,2337 ****
  getline({lnum})                       String  line {lnum} of current buffer
  getline({lnum}, {end})                List    lines {lnum} to {end} of 
current buffer
  getloclist({nr} [, {what}])   List    list of location list items
! getmatches()                  List    list of current matches
  getpid()                      Number  process ID of Vim
  getpos({expr})                        List    position of cursor, mark, etc.
  getqflist([{what}])           List    list of quickfix items
--- 2359,2365 ----
  getline({lnum})                       String  line {lnum} of current buffer
  getline({lnum}, {end})                List    lines {lnum} to {end} of 
current buffer
  getloclist({nr} [, {what}])   List    list of location list items
! getmatches([{win}])           List    list of current matches
  getpid()                      Number  process ID of Vim
  getpos({expr})                        List    position of cursor, mark, etc.
  getqflist([{what}])           List    list of quickfix items
***************
*** 2422,2428 ****
  matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
                                Number  highlight positions with {group}
  matcharg({nr})                        List    arguments of |:match|
! matchdelete({id})             Number  delete match identified by {id}
  matchend({expr}, {pat} [, {start} [, {count}]])
                                Number  position where {pat} ends in {expr}
  matchlist({expr}, {pat} [, {start} [, {count}]])
--- 2450,2456 ----
  matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
                                Number  highlight positions with {group}
  matcharg({nr})                        List    arguments of |:match|
! matchdelete({id} [, {win}])   Number  delete match identified by {id}
  matchend({expr}, {pat} [, {start} [, {count}]])
                                Number  position where {pat} ends in {expr}
  matchlist({expr}, {pat} [, {start} [, {count}]])
***************
*** 2528,2534 ****
  setline({lnum}, {line})               Number  set line {lnum} to {line}
  setloclist({nr}, {list} [, {action} [, {what}]])
                                Number  modify location list using {list}
! setmatches({list})            Number  restore a list of matches
  setpos({expr}, {list})                Number  set the {expr} position to 
{list}
  setqflist({list} [, {action} [, {what}]])
                                Number  modify quickfix list using {list}
--- 2556,2562 ----
  setline({lnum}, {line})               Number  set line {lnum} to {line}
  setloclist({nr}, {list} [, {action} [, {what}]])
                                Number  modify location list using {list}
! setmatches({list} [, {win}])  Number  restore a list of matches
  setpos({expr}, {list})                Number  set the {expr} position to 
{list}
  setqflist({list} [, {action} [, {what}]])
                                Number  modify quickfix list using {list}
***************
*** 3428,3436 ****
                feature, -1 is returned.
                See |C-indenting|.
  
! clearmatches()                                                *clearmatches()*
!               Clears all matches previously defined by |matchadd()| and the
!               |:match| commands.
  
                                                        *col()*
  col({expr})   The result is a Number, which is the byte index of the column
--- 3461,3471 ----
                feature, -1 is returned.
                See |C-indenting|.
  
! clearmatches([{win}])                                 *clearmatches()*
!               Clears all matches previously defined for the current window
!               by |matchadd()| and the |:match| commands.
!               If {win} is specified, use the window with this number or
!               window ID instead of the current window.
  
                                                        *col()*
  col({expr})   The result is a Number, which is the byte index of the column
***************
*** 4998,5008 ****
                                        |location-list-file-window| for more
                                        details.
  
! getmatches()                                          *getmatches()*
!               Returns a |List| with all matches previously defined by
!               |matchadd()| and the |:match| commands.  |getmatches()| is
!               useful in combination with |setmatches()|, as |setmatches()|
!               can restore a list of matches saved by |getmatches()|.
                Example: >
                        :echo getmatches()
  <                     [{'group': 'MyGroup1', 'pattern': 'TODO',
--- 5038,5049 ----
                                        |location-list-file-window| for more
                                        details.
  
! getmatches([{win}])                                   *getmatches()*
!               Returns a |List| with all matches previously defined for the
!               current window by |matchadd()| and the |:match| commands.
!               |getmatches()| is useful in combination with |setmatches()|,
!               as |setmatches()| can restore a list of matches saved by
!               |getmatches()|.
                Example: >
                        :echo getmatches()
  <                     [{'group': 'MyGroup1', 'pattern': 'TODO',
***************
*** 6303,6313 ****
--- 6349,6362 ----
                When {expr} is a |List| then this returns the index of the
                first item where {pat} matches.  Each item is used as a
                String, |Lists| and |Dictionaries| are used as echoed.
+ 
                Otherwise, {expr} is used as a String.  The result is a
                Number, which gives the index (byte offset) in {expr} where
                {pat} matches.
+ 
                A match at the first character or |List| item returns zero.
                If there is no match -1 is returned.
+ 
                For getting submatches see |matchlist()|.
                Example: >
                        :echo match("testing", "ing")   " results in 4
***************
*** 6359,6365 ****
                Defines a pattern to be highlighted in the current window (a
                "match").  It will be highlighted with {group}.  Returns an
                identification number (ID), which can be used to delete the
!               match using |matchdelete()|.
                Matching is case sensitive and magic, unless case sensitivity
                or magicness are explicitly overridden in {pattern}.  The
                'magic', 'smartcase' and 'ignorecase' options are not used.
--- 6408,6414 ----
                Defines a pattern to be highlighted in the current window (a
                "match").  It will be highlighted with {group}.  Returns an
                identification number (ID), which can be used to delete the
!               match using |matchdelete()|.  The ID is bound to the window.
                Matching is case sensitive and magic, unless case sensitivity
                or magicness are explicitly overridden in {pattern}.  The
                'magic', 'smartcase' and 'ignorecase' options are not used.
***************
*** 6455,6465 ****
                Highlighting matches using the |:match| commands are limited
                to three matches. |matchadd()| does not have this limitation.
  
! matchdelete({id})                            *matchdelete()* *E802* *E803*
                Deletes a match with ID {id} previously defined by |matchadd()|
                or one of the |:match| commands.  Returns 0 if successful,
                otherwise -1.  See example for |matchadd()|.  All matches can
                be deleted in one operation by |clearmatches()|.
  
  matchend({expr}, {pat} [, {start} [, {count}]])                       
*matchend()*
                Same as |match()|, but return the index of first character
--- 6504,6516 ----
                Highlighting matches using the |:match| commands are limited
                to three matches. |matchadd()| does not have this limitation.
  
! matchdelete({id} [, {win})                   *matchdelete()* *E802* *E803*
                Deletes a match with ID {id} previously defined by |matchadd()|
                or one of the |:match| commands.  Returns 0 if successful,
                otherwise -1.  See example for |matchadd()|.  All matches can
                be deleted in one operation by |clearmatches()|.
+               If {win} is specified, use the window with this number or
+               window ID instead of the current window.
  
  matchend({expr}, {pat} [, {start} [, {count}]])                       
*matchend()*
                Same as |match()|, but return the index of first character
***************
*** 7852,7861 ****
                only the items listed in {what} are set. Refer to |setqflist()|
                for the list of supported keys in {what}.
  
! setmatches({list})                                    *setmatches()*
!               Restores a list of matches saved by |getmatches()|.  Returns 0
!               if successful, otherwise -1.  All current matches are cleared
!               before the list is restored.  See example for |getmatches()|.
  
                                                        *setpos()*
  setpos({expr}, {list})
--- 7921,7933 ----
                only the items listed in {what} are set. Refer to |setqflist()|
                for the list of supported keys in {what}.
  
! setmatches({list} [, {win}])                          *setmatches()*
!               Restores a list of matches saved by |getmatches() for the
!               current window|.  Returns 0 if successful, otherwise -1.  All
!               current matches are cleared before the list is restored.  See
!               example for |getmatches()|.
!               If {win} is specified, use the window with this number or
!               window ID instead of the current window.
  
                                                        *setpos()*
  setpos({expr}, {list})
*** ../vim-8.1.1083/src/evalfunc.c      2019-03-30 14:26:15.268619122 +0100
--- src/evalfunc.c      2019-03-30 18:04:15.531433052 +0100
***************
*** 31,36 ****
--- 31,37 ----
  static char *e_listarg = N_("E686: Argument of %s must be a List");
  static char *e_listblobarg = N_("E899: Argument of %s must be a List or 
Blob");
  static char *e_stringreq = N_("E928: String required");
+ static char *e_invalwindow = N_("E957: Invalid window number");
  
  #ifdef FEAT_FLOAT
  static void f_abs(typval_T *argvars, typval_T *rettv);
***************
*** 590,596 ****
      {"changenr",      0, 0, f_changenr},
      {"char2nr",               1, 2, f_char2nr},
      {"cindent",               1, 1, f_cindent},
!     {"clearmatches",  0, 0, f_clearmatches},
      {"col",           1, 1, f_col},
  #if defined(FEAT_INS_EXPAND)
      {"complete",      2, 2, f_complete},
--- 591,597 ----
      {"changenr",      0, 0, f_changenr},
      {"char2nr",               1, 2, f_char2nr},
      {"cindent",               1, 1, f_cindent},
!     {"clearmatches",  0, 1, f_clearmatches},
      {"col",           1, 1, f_col},
  #if defined(FEAT_INS_EXPAND)
      {"complete",      2, 2, f_complete},
***************
*** 677,683 ****
      {"getjumplist",   0, 2, f_getjumplist},
      {"getline",               1, 2, f_getline},
      {"getloclist",    1, 2, f_getloclist},
!     {"getmatches",    0, 0, f_getmatches},
      {"getpid",                0, 0, f_getpid},
      {"getpos",                1, 1, f_getpos},
      {"getqflist",     0, 1, f_getqflist},
--- 678,684 ----
      {"getjumplist",   0, 2, f_getjumplist},
      {"getline",               1, 2, f_getline},
      {"getloclist",    1, 2, f_getloclist},
!     {"getmatches",    0, 1, f_getmatches},
      {"getpid",                0, 0, f_getpid},
      {"getpos",                1, 1, f_getpos},
      {"getqflist",     0, 1, f_getqflist},
***************
*** 761,767 ****
      {"matchadd",      2, 5, f_matchadd},
      {"matchaddpos",   2, 5, f_matchaddpos},
      {"matcharg",      1, 1, f_matcharg},
!     {"matchdelete",   1, 1, f_matchdelete},
      {"matchend",      2, 4, f_matchend},
      {"matchlist",     2, 4, f_matchlist},
      {"matchstr",      2, 4, f_matchstr},
--- 762,768 ----
      {"matchadd",      2, 5, f_matchadd},
      {"matchaddpos",   2, 5, f_matchaddpos},
      {"matcharg",      1, 1, f_matcharg},
!     {"matchdelete",   1, 2, f_matchdelete},
      {"matchend",      2, 4, f_matchend},
      {"matchlist",     2, 4, f_matchlist},
      {"matchstr",      2, 4, f_matchstr},
***************
*** 859,865 ****
      {"setfperm",      2, 2, f_setfperm},
      {"setline",               2, 2, f_setline},
      {"setloclist",    2, 4, f_setloclist},
!     {"setmatches",    1, 1, f_setmatches},
      {"setpos",                2, 2, f_setpos},
      {"setqflist",     1, 3, f_setqflist},
      {"setreg",                2, 3, f_setreg},
--- 860,866 ----
      {"setfperm",      2, 2, f_setfperm},
      {"setline",               2, 2, f_setline},
      {"setloclist",    2, 4, f_setloclist},
!     {"setmatches",    1, 2, f_setmatches},
      {"setpos",                2, 2, f_setpos},
      {"setqflist",     1, 3, f_setqflist},
      {"setreg",                2, 3, f_setreg},
***************
*** 2496,2501 ****
--- 2497,2519 ----
        rettv->vval.v_number = -1;
  }
  
+     static win_T *
+ get_optional_window(typval_T *argvars, int idx)
+ {
+     win_T   *win = curwin;
+ 
+     if (argvars[idx].v_type != VAR_UNKNOWN)
+     {
+       win = find_win_by_nr_or_id(&argvars[idx]);
+       if (win == NULL)
+       {
+           emsg(_(e_invalwindow));
+           return NULL;
+       }
+     }
+     return win;
+ }
+ 
  /*
   * "clearmatches()" function
   */
***************
*** 2503,2509 ****
  f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
  {
  #ifdef FEAT_SEARCH_EXTRA
!     clear_matches(curwin);
  #endif
  }
  
--- 2521,2530 ----
  f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
  {
  #ifdef FEAT_SEARCH_EXTRA
!     win_T   *win = get_optional_window(argvars, 0);
! 
!     if (win != NULL)
!       clear_matches(win);
  #endif
  }
  
***************
*** 5412,5471 ****
  {
  #ifdef FEAT_SEARCH_EXTRA
      dict_T    *dict;
!     matchitem_T       *cur = curwin->w_match_head;
      int               i;
  
!     if (rettv_list_alloc(rettv) == OK)
      {
!       while (cur != NULL)
        {
!           dict = dict_alloc();
!           if (dict == NULL)
!               return;
!           if (cur->match.regprog == NULL)
            {
!               /* match added with matchaddpos() */
!               for (i = 0; i < MAXPOSMATCH; ++i)
!               {
!                   llpos_T     *llpos;
!                   char        buf[6];
!                   list_T      *l;
  
!                   llpos = &cur->pos.pos[i];
!                   if (llpos->lnum == 0)
!                       break;
!                   l = list_alloc();
!                   if (l == NULL)
!                       break;
!                   list_append_number(l, (varnumber_T)llpos->lnum);
!                   if (llpos->col > 0)
!                   {
!                       list_append_number(l, (varnumber_T)llpos->col);
!                       list_append_number(l, (varnumber_T)llpos->len);
!                   }
!                   sprintf(buf, "pos%d", i + 1);
!                   dict_add_list(dict, buf, l);
                }
            }
!           else
!           {
!               dict_add_string(dict, "pattern", cur->pattern);
!           }
!           dict_add_string(dict, "group", syn_id2name(cur->hlg_id));
!           dict_add_number(dict, "priority", (long)cur->priority);
!           dict_add_number(dict, "id", (long)cur->id);
  # if defined(FEAT_CONCEAL)
!           if (cur->conceal_char)
!           {
!               char_u buf[MB_MAXBYTES + 1];
  
!               buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
!               dict_add_string(dict, "conceal", (char_u *)&buf);
!           }
! # endif
!           list_append_dict(rettv->vval.v_list, dict);
!           cur = cur->next;
        }
      }
  #endif
  }
--- 5433,5494 ----
  {
  #ifdef FEAT_SEARCH_EXTRA
      dict_T    *dict;
!     matchitem_T       *cur;
      int               i;
+     win_T     *win = get_optional_window(argvars, 0);
  
!     if (rettv_list_alloc(rettv) == FAIL || win == NULL)
!       return;
! 
!     cur = win->w_match_head;
!     while (cur != NULL)
      {
!       dict = dict_alloc();
!       if (dict == NULL)
!           return;
!       if (cur->match.regprog == NULL)
        {
!           /* match added with matchaddpos() */
!           for (i = 0; i < MAXPOSMATCH; ++i)
            {
!               llpos_T *llpos;
!               char    buf[6];
!               list_T  *l;
  
!               llpos = &cur->pos.pos[i];
!               if (llpos->lnum == 0)
!                   break;
!               l = list_alloc();
!               if (l == NULL)
!                   break;
!               list_append_number(l, (varnumber_T)llpos->lnum);
!               if (llpos->col > 0)
!               {
!                   list_append_number(l, (varnumber_T)llpos->col);
!                   list_append_number(l, (varnumber_T)llpos->len);
                }
+               sprintf(buf, "pos%d", i + 1);
+               dict_add_list(dict, buf, l);
            }
!       }
!       else
!       {
!           dict_add_string(dict, "pattern", cur->pattern);
!       }
!       dict_add_string(dict, "group", syn_id2name(cur->hlg_id));
!       dict_add_number(dict, "priority", (long)cur->priority);
!       dict_add_number(dict, "id", (long)cur->id);
  # if defined(FEAT_CONCEAL)
!       if (cur->conceal_char)
!       {
!           char_u buf[MB_MAXBYTES + 1];
  
!           buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
!           dict_add_string(dict, "conceal", (char_u *)&buf);
        }
+ # endif
+       list_append_dict(rettv->vval.v_list, dict);
+       cur = cur->next;
      }
  #endif
  }
***************
*** 8245,8251 ****
        *win = find_win_by_nr_or_id(&di->di_tv);
        if (*win == NULL)
        {
!           emsg(_("E957: Invalid window number"));
            return FAIL;
        }
      }
--- 8268,8274 ----
        *win = find_win_by_nr_or_id(&di->di_tv);
        if (*win == NULL)
        {
!           emsg(_(e_invalwindow));
            return FAIL;
        }
      }
***************
*** 8393,8399 ****
  f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
  {
  #ifdef FEAT_SEARCH_EXTRA
!     rettv->vval.v_number = match_delete(curwin,
                                       (int)tv_get_number(&argvars[0]), TRUE);
  #endif
  }
--- 8416,8427 ----
  f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
  {
  #ifdef FEAT_SEARCH_EXTRA
!     win_T   *win = get_optional_window(argvars, 1);
! 
!     if (win == NULL)
!       rettv->vval.v_number = -1;
!     else
!       rettv->vval.v_number = match_delete(win,
                                       (int)tv_get_number(&argvars[0]), TRUE);
  #endif
  }
***************
*** 11206,11211 ****
--- 11234,11240 ----
      listitem_T        *li;
      dict_T    *d;
      list_T    *s = NULL;
+     win_T     *win = get_optional_window(argvars, 1);
  
      rettv->vval.v_number = -1;
      if (argvars[0].v_type != VAR_LIST)
***************
*** 11213,11221 ****
        emsg(_(e_listreq));
        return;
      }
      if ((l = argvars[0].vval.v_list) != NULL)
      {
- 
        /* To some extent make sure that we are dealing with a list from
         * "getmatches()". */
        li = l->lv_first;
--- 11242,11252 ----
        emsg(_(e_listreq));
        return;
      }
+     if (win == NULL)
+       return;
+ 
      if ((l = argvars[0].vval.v_list) != NULL)
      {
        /* To some extent make sure that we are dealing with a list from
         * "getmatches()". */
        li = l->lv_first;
***************
*** 11239,11245 ****
            li = li->li_next;
        }
  
!       clear_matches(curwin);
        li = l->lv_first;
        while (li != NULL)
        {
--- 11270,11276 ----
            li = li->li_next;
        }
  
!       clear_matches(win);
        li = l->lv_first;
        while (li != NULL)
        {
***************
*** 11286,11298 ****
                              : NULL;
            if (i == 0)
            {
!               match_add(curwin, group,
                    dict_get_string(d, (char_u *)"pattern", FALSE),
                    priority, id, NULL, conceal);
            }
            else
            {
!               match_add(curwin, group, NULL, priority, id, s, conceal);
                list_unref(s);
                s = NULL;
            }
--- 11317,11329 ----
                              : NULL;
            if (i == 0)
            {
!               match_add(win, group,
                    dict_get_string(d, (char_u *)"pattern", FALSE),
                    priority, id, NULL, conceal);
            }
            else
            {
!               match_add(win, group, NULL, priority, id, s, conceal);
                list_unref(s);
                s = NULL;
            }
*** ../vim-8.1.1083/src/testdir/test_match.vim  2019-01-24 17:59:35.139217458 
+0100
--- src/testdir/test_match.vim  2019-03-30 17:48:06.817387861 +0100
***************
*** 205,210 ****
--- 205,223 ----
    call assert_equal(screenattr(1,2), screenattr(2,2))
    call assert_notequal(screenattr(1,2), screenattr(1,4))
  
+   let savematches = getmatches(winid)
+   let expect = [
+         \ {'group': 'Search', 'pattern': '4', 'priority': 10, 'id': 4},
+         \ {'group': 'Error', 'id': 5, 'priority': 10, 'pos1': [1, 2, 1], 
'pos2': [2, 2, 1]},
+         \]
+   call assert_equal(expect, savematches)
+ 
+   call clearmatches(winid)
+   call assert_equal([], getmatches(winid))
+ 
+   call setmatches(savematches, winid)
+   call assert_equal(expect, savematches)
+ 
    wincmd w
    bwipe!
    call clearmatches()
*** ../vim-8.1.1083/src/version.c       2019-03-30 17:28:11.920987602 +0100
--- src/version.c       2019-03-30 17:51:29.572116891 +0100
***************
*** 777,778 ****
--- 777,780 ----
  {   /* Add new patch number below this line */
+ /**/
+     1084,
  /**/


-- 
hundred-and-one symptoms of being an internet addict:
162. You go outside and look for a brightness knob to turn down the sun.

 /// 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].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui