]> granicus.if.org Git - vim/commitdiff
patch 8.1.1084: cannot delete a match from another window v8.1.1084
authorBram Moolenaar <Bram@vim.org>
Sat, 30 Mar 2019 17:11:49 +0000 (18:11 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 30 Mar 2019 17:11:49 +0000 (18:11 +0100)
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)

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

index a01c4db38ed5afac59ee00b05191c3ff183e3e1c..e9592bb687ad49b2bf8e1e2bfc2595d6175f32c7 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 8.1.  Last change: 2019 Mar 29
+*eval.txt*     For Vim version 8.1.  Last change: 2019 Mar 30
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -625,8 +625,11 @@ Functions that can be used with a Dictionary: >
 
 1.5 Blobs ~
                                                *blob* *Blob* *Blobs* *E978*
-A Blob mostly behaves like a |List| of numbers, where the numbers have an
-8-bit value, from 0 to 255.
+A Blob is a binary object.  It can be used to read an image from a file and
+send it over a channel, for example.
+
+A Blob mostly behaves like a |List| of numbers, where each number has the
+value of an 8-bit byte, from 0 to 255.
 
 
 Blob creation ~
@@ -2262,7 +2265,7 @@ ch_status({handle} [, {options}])
 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
+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
@@ -2356,7 +2359,7 @@ getjumplist([{winnr} [, {tabnr}]])
 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
+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
@@ -2447,7 +2450,7 @@ matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
 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}
+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}]])
@@ -2553,7 +2556,7 @@ setfperm({fname}, {mode}) Number  set {fname} file permissions to {mode}
 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
+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}
@@ -3444,6 +3447,10 @@ char2nr({expr} [, {utf8}])                                       *char2nr()*
 <              With {utf8} set to 1, always treat as utf-8 characters.
                A combining character is a separate character.
                |nr2char()| does the opposite.
+               To turn a string into a list of character numbers: >
+                   let str = "ABC"
+                   let list = map(split(str, '\zs'), {_, val -> char2nr(val)})
+<              Result: [65, 66, 67]
 
 cindent({lnum})                                                *cindent()*
                Get the amount of indent for line {lnum} according the C
@@ -3454,9 +3461,11 @@ cindent({lnum})                                          *cindent()*
                feature, -1 is returned.
                See |C-indenting|.
 
-clearmatches()                                         *clearmatches()*
+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
@@ -5029,7 +5038,7 @@ getloclist({nr} [, {what}])                               *getloclist()*
                                        |location-list-file-window| for more
                                        details.
 
-getmatches()                                           *getmatches()*
+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()|,
@@ -6399,7 +6408,7 @@ matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
                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()|.
+               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.
@@ -6495,11 +6504,13 @@ matcharg({nr})                                                  *matcharg()*
                Highlighting matches using the |:match| commands are limited
                to three matches. |matchadd()| does not have this limitation.
 
-matchdelete({id})                             *matchdelete()* *E802* *E803*
+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
@@ -6688,6 +6699,10 @@ nr2char({expr} [, {utf8}])                               *nr2char()*
                nr2char(10), because NULs are represented with newline
                characters.  nr2char(0) is a real NUL and terminates the
                string, thus results in an empty string.
+               To turn a list of character numbers into a string: >
+                   let list = [65, 66, 67]
+                   let str = join(map(list, {_, val -> nr2char(val)}), '')
+<              Result: "ABC"
 
 or({expr}, {expr})                                     *or()*
                Bitwise OR on the two arguments.  The arguments are converted
@@ -7906,11 +7921,13 @@ setloclist({nr}, {list} [, {action} [, {what}]])                *setloclist()*
                only the items listed in {what} are set. Refer to |setqflist()|
                for the list of supported keys in {what}.
 
-setmatches({list})                                     *setmatches()*
+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})
index 30f98eb6638296c598c304e9eae9acf9f69d284d..524031e0cd37d6f0f8679b96535d3755786f102f 100644 (file)
@@ -31,6 +31,7 @@
 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,7 +591,7 @@ static struct fst
     {"changenr",       0, 0, f_changenr},
     {"char2nr",                1, 2, f_char2nr},
     {"cindent",                1, 1, f_cindent},
-    {"clearmatches",   0, 0, f_clearmatches},
+    {"clearmatches",   0, 1, f_clearmatches},
     {"col",            1, 1, f_col},
 #if defined(FEAT_INS_EXPAND)
     {"complete",       2, 2, f_complete},
@@ -677,7 +678,7 @@ static struct fst
     {"getjumplist",    0, 2, f_getjumplist},
     {"getline",                1, 2, f_getline},
     {"getloclist",     1, 2, f_getloclist},
-    {"getmatches",     0, 0, f_getmatches},
+    {"getmatches",     0, 1, f_getmatches},
     {"getpid",         0, 0, f_getpid},
     {"getpos",         1, 1, f_getpos},
     {"getqflist",      0, 1, f_getqflist},
@@ -761,7 +762,7 @@ static struct fst
     {"matchadd",       2, 5, f_matchadd},
     {"matchaddpos",    2, 5, f_matchaddpos},
     {"matcharg",       1, 1, f_matcharg},
-    {"matchdelete",    1, 1, f_matchdelete},
+    {"matchdelete",    1, 2, f_matchdelete},
     {"matchend",       2, 4, f_matchend},
     {"matchlist",      2, 4, f_matchlist},
     {"matchstr",       2, 4, f_matchstr},
@@ -859,7 +860,7 @@ static struct fst
     {"setfperm",       2, 2, f_setfperm},
     {"setline",                2, 2, f_setline},
     {"setloclist",     2, 4, f_setloclist},
-    {"setmatches",     1, 1, f_setmatches},
+    {"setmatches",     1, 2, f_setmatches},
     {"setpos",         2, 2, f_setpos},
     {"setqflist",      1, 3, f_setqflist},
     {"setreg",         2, 3, f_setreg},
@@ -2496,6 +2497,23 @@ f_cindent(typval_T *argvars UNUSED, typval_T *rettv)
        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,7 +2521,10 @@ f_cindent(typval_T *argvars UNUSED, typval_T *rettv)
 f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
 {
 #ifdef FEAT_SEARCH_EXTRA
-    clear_matches(curwin);
+    win_T   *win = get_optional_window(argvars, 0);
+
+    if (win != NULL)
+       clear_matches(win);
 #endif
 }
 
@@ -5412,60 +5433,62 @@ f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
 {
 #ifdef FEAT_SEARCH_EXTRA
     dict_T     *dict;
-    matchitem_T        *cur = curwin->w_match_head;
+    matchitem_T        *cur;
     int                i;
+    win_T      *win = get_optional_window(argvars, 0);
 
-    if (rettv_list_alloc(rettv) == OK)
+    if (rettv_list_alloc(rettv) == FAIL || win == NULL)
+       return;
+
+    cur = win->w_match_head;
+    while (cur != NULL)
     {
-       while (cur != NULL)
+       dict = dict_alloc();
+       if (dict == NULL)
+           return;
+       if (cur->match.regprog == NULL)
        {
-           dict = dict_alloc();
-           if (dict == NULL)
-               return;
-           if (cur->match.regprog == NULL)
+           /* match added with matchaddpos() */
+           for (i = 0; i < MAXPOSMATCH; ++i)
            {
-               /* match added with matchaddpos() */
-               for (i = 0; i < MAXPOSMATCH; ++i)
-               {
-                   llpos_T     *llpos;
-                   char        buf[6];
-                   list_T      *l;
+               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);
+               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);
+       }
+       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];
+       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;
+           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,7 +8268,7 @@ matchadd_dict_arg(typval_T *tv, char_u **conceal_char, win_T **win)
        *win = find_win_by_nr_or_id(&di->di_tv);
        if (*win == NULL)
        {
-           emsg(_("E957: Invalid window number"));
+           emsg(_(e_invalwindow));
            return FAIL;
        }
     }
@@ -8393,7 +8416,12 @@ f_matcharg(typval_T *argvars UNUSED, typval_T *rettv)
 f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
 {
 #ifdef FEAT_SEARCH_EXTRA
-    rettv->vval.v_number = match_delete(curwin,
+    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,6 +11234,7 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     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,9 +11242,11 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
        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,7 +11270,7 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
            li = li->li_next;
        }
 
-       clear_matches(curwin);
+       clear_matches(win);
        li = l->lv_first;
        while (li != NULL)
        {
@@ -11286,13 +11317,13 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
                              : NULL;
            if (i == 0)
            {
-               match_add(curwin, group,
+               match_add(win, group,
                    dict_get_string(d, (char_u *)"pattern", FALSE),
                    priority, id, NULL, conceal);
            }
            else
            {
-               match_add(curwin, group, NULL, priority, id, s, conceal);
+               match_add(win, group, NULL, priority, id, s, conceal);
                list_unref(s);
                s = NULL;
            }
index 94bca9ad38ad42c4c10c6a08515e150c23f36c58..51c901689e6e0160d0de0ce42fa71507c05977d8 100644 (file)
@@ -205,6 +205,19 @@ func Test_matchaddpos_otherwin()
   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()
index c267a20daf308615a821e106bfa8e27e7771ad87..74fa0bd55f83d620c191a8b7753d870c6ee0b1ea 100644 (file)
@@ -775,6 +775,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1084,
 /**/
     1083,
 /**/