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.