Skip to content

Commit aff7491

Browse files
committed
patch 8.1.1084: cannot delete a match from another window
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)
1 parent 8bb41b3 commit aff7491

4 files changed

Lines changed: 129 additions & 66 deletions

File tree

runtime/doc/eval.txt

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 8.1. Last change: 2019 Mar 29
1+
*eval.txt* For Vim version 8.1. Last change: 2019 Mar 30
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -625,8 +625,11 @@ Functions that can be used with a Dictionary: >
625625
626626
1.5 Blobs ~
627627
*blob* *Blob* *Blobs* *E978*
628-
A Blob mostly behaves like a |List| of numbers, where the numbers have an
629-
8-bit value, from 0 to 255.
628+
A Blob is a binary object. It can be used to read an image from a file and
629+
send it over a channel, for example.
630+
631+
A Blob mostly behaves like a |List| of numbers, where each number has the
632+
value of an 8-bit byte, from 0 to 255.
630633

631634

632635
Blob creation ~
@@ -2262,7 +2265,7 @@ ch_status({handle} [, {options}])
22622265
changenr() Number current change number
22632266
char2nr({expr} [, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
22642267
cindent({lnum}) Number C indent for line {lnum}
2265-
clearmatches() none clear all matches
2268+
clearmatches([{win}]) none clear all matches
22662269
col({expr}) Number column nr of cursor or mark
22672270
complete({startcol}, {matches}) none set Insert mode completion
22682271
complete_add({expr}) Number add completion match
@@ -2356,7 +2359,7 @@ getjumplist([{winnr} [, {tabnr}]])
23562359
getline({lnum}) String line {lnum} of current buffer
23572360
getline({lnum}, {end}) List lines {lnum} to {end} of current buffer
23582361
getloclist({nr} [, {what}]) List list of location list items
2359-
getmatches() List list of current matches
2362+
getmatches([{win}]) List list of current matches
23602363
getpid() Number process ID of Vim
23612364
getpos({expr}) List position of cursor, mark, etc.
23622365
getqflist([{what}]) List list of quickfix items
@@ -2447,7 +2450,7 @@ matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
24472450
matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
24482451
Number highlight positions with {group}
24492452
matcharg({nr}) List arguments of |:match|
2450-
matchdelete({id}) Number delete match identified by {id}
2453+
matchdelete({id} [, {win}]) Number delete match identified by {id}
24512454
matchend({expr}, {pat} [, {start} [, {count}]])
24522455
Number position where {pat} ends in {expr}
24532456
matchlist({expr}, {pat} [, {start} [, {count}]])
@@ -2553,7 +2556,7 @@ setfperm({fname}, {mode}) Number set {fname} file permissions to {mode}
25532556
setline({lnum}, {line}) Number set line {lnum} to {line}
25542557
setloclist({nr}, {list} [, {action} [, {what}]])
25552558
Number modify location list using {list}
2556-
setmatches({list}) Number restore a list of matches
2559+
setmatches({list} [, {win}]) Number restore a list of matches
25572560
setpos({expr}, {list}) Number set the {expr} position to {list}
25582561
setqflist({list} [, {action} [, {what}]])
25592562
Number modify quickfix list using {list}
@@ -3444,6 +3447,10 @@ char2nr({expr} [, {utf8}]) *char2nr()*
34443447
< With {utf8} set to 1, always treat as utf-8 characters.
34453448
A combining character is a separate character.
34463449
|nr2char()| does the opposite.
3450+
To turn a string into a list of character numbers: >
3451+
let str = "ABC"
3452+
let list = map(split(str, '\zs'), {_, val -> char2nr(val)})
3453+
< Result: [65, 66, 67]
34473454

34483455
cindent({lnum}) *cindent()*
34493456
Get the amount of indent for line {lnum} according the C
@@ -3454,9 +3461,11 @@ cindent({lnum}) *cindent()*
34543461
feature, -1 is returned.
34553462
See |C-indenting|.
34563463

3457-
clearmatches() *clearmatches()*
3464+
clearmatches([{win}]) *clearmatches()*
34583465
Clears all matches previously defined for the current window
34593466
by |matchadd()| and the |:match| commands.
3467+
If {win} is specified, use the window with this number or
3468+
window ID instead of the current window.
34603469

34613470
*col()*
34623471
col({expr}) The result is a Number, which is the byte index of the column
@@ -5029,7 +5038,7 @@ getloclist({nr} [, {what}]) *getloclist()*
50295038
|location-list-file-window| for more
50305039
details.
50315040

5032-
getmatches() *getmatches()*
5041+
getmatches([{win}]) *getmatches()*
50335042
Returns a |List| with all matches previously defined for the
50345043
current window by |matchadd()| and the |:match| commands.
50355044
|getmatches()| is useful in combination with |setmatches()|,
@@ -6399,7 +6408,7 @@ matchadd({group}, {pattern} [, {priority} [, {id} [, {dict}]]])
63996408
Defines a pattern to be highlighted in the current window (a
64006409
"match"). It will be highlighted with {group}. Returns an
64016410
identification number (ID), which can be used to delete the
6402-
match using |matchdelete()|.
6411+
match using |matchdelete()|. The ID is bound to the window.
64036412
Matching is case sensitive and magic, unless case sensitivity
64046413
or magicness are explicitly overridden in {pattern}. The
64056414
'magic', 'smartcase' and 'ignorecase' options are not used.
@@ -6495,11 +6504,13 @@ matcharg({nr}) *matcharg()*
64956504
Highlighting matches using the |:match| commands are limited
64966505
to three matches. |matchadd()| does not have this limitation.
64976506

6498-
matchdelete({id}) *matchdelete()* *E802* *E803*
6507+
matchdelete({id} [, {win}) *matchdelete()* *E802* *E803*
64996508
Deletes a match with ID {id} previously defined by |matchadd()|
65006509
or one of the |:match| commands. Returns 0 if successful,
65016510
otherwise -1. See example for |matchadd()|. All matches can
65026511
be deleted in one operation by |clearmatches()|.
6512+
If {win} is specified, use the window with this number or
6513+
window ID instead of the current window.
65036514

65046515
matchend({expr}, {pat} [, {start} [, {count}]]) *matchend()*
65056516
Same as |match()|, but return the index of first character
@@ -6688,6 +6699,10 @@ nr2char({expr} [, {utf8}]) *nr2char()*
66886699
nr2char(10), because NULs are represented with newline
66896700
characters. nr2char(0) is a real NUL and terminates the
66906701
string, thus results in an empty string.
6702+
To turn a list of character numbers into a string: >
6703+
let list = [65, 66, 67]
6704+
let str = join(map(list, {_, val -> nr2char(val)}), '')
6705+
< Result: "ABC"
66916706

66926707
or({expr}, {expr}) *or()*
66936708
Bitwise OR on the two arguments. The arguments are converted
@@ -7906,11 +7921,13 @@ setloclist({nr}, {list} [, {action} [, {what}]]) *setloclist()*
79067921
only the items listed in {what} are set. Refer to |setqflist()|
79077922
for the list of supported keys in {what}.
79087923

7909-
setmatches({list}) *setmatches()*
7924+
setmatches({list} [, {win}]) *setmatches()*
79107925
Restores a list of matches saved by |getmatches() for the
79117926
current window|. Returns 0 if successful, otherwise -1. All
79127927
current matches are cleared before the list is restored. See
79137928
example for |getmatches()|.
7929+
If {win} is specified, use the window with this number or
7930+
window ID instead of the current window.
79147931

79157932
*setpos()*
79167933
setpos({expr}, {list})

src/evalfunc.c

Lines changed: 85 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
static char *e_listarg = N_("E686: Argument of %s must be a List");
3232
static char *e_listblobarg = N_("E899: Argument of %s must be a List or Blob");
3333
static char *e_stringreq = N_("E928: String required");
34+
static char *e_invalwindow = N_("E957: Invalid window number");
3435

3536
#ifdef FEAT_FLOAT
3637
static void f_abs(typval_T *argvars, typval_T *rettv);
@@ -590,7 +591,7 @@ static struct fst
590591
{"changenr", 0, 0, f_changenr},
591592
{"char2nr", 1, 2, f_char2nr},
592593
{"cindent", 1, 1, f_cindent},
593-
{"clearmatches", 0, 0, f_clearmatches},
594+
{"clearmatches", 0, 1, f_clearmatches},
594595
{"col", 1, 1, f_col},
595596
#if defined(FEAT_INS_EXPAND)
596597
{"complete", 2, 2, f_complete},
@@ -677,7 +678,7 @@ static struct fst
677678
{"getjumplist", 0, 2, f_getjumplist},
678679
{"getline", 1, 2, f_getline},
679680
{"getloclist", 1, 2, f_getloclist},
680-
{"getmatches", 0, 0, f_getmatches},
681+
{"getmatches", 0, 1, f_getmatches},
681682
{"getpid", 0, 0, f_getpid},
682683
{"getpos", 1, 1, f_getpos},
683684
{"getqflist", 0, 1, f_getqflist},
@@ -761,7 +762,7 @@ static struct fst
761762
{"matchadd", 2, 5, f_matchadd},
762763
{"matchaddpos", 2, 5, f_matchaddpos},
763764
{"matcharg", 1, 1, f_matcharg},
764-
{"matchdelete", 1, 1, f_matchdelete},
765+
{"matchdelete", 1, 2, f_matchdelete},
765766
{"matchend", 2, 4, f_matchend},
766767
{"matchlist", 2, 4, f_matchlist},
767768
{"matchstr", 2, 4, f_matchstr},
@@ -859,7 +860,7 @@ static struct fst
859860
{"setfperm", 2, 2, f_setfperm},
860861
{"setline", 2, 2, f_setline},
861862
{"setloclist", 2, 4, f_setloclist},
862-
{"setmatches", 1, 1, f_setmatches},
863+
{"setmatches", 1, 2, f_setmatches},
863864
{"setpos", 2, 2, f_setpos},
864865
{"setqflist", 1, 3, f_setqflist},
865866
{"setreg", 2, 3, f_setreg},
@@ -2496,14 +2497,34 @@ f_cindent(typval_T *argvars UNUSED, typval_T *rettv)
24962497
rettv->vval.v_number = -1;
24972498
}
24982499

2500+
static win_T *
2501+
get_optional_window(typval_T *argvars, int idx)
2502+
{
2503+
win_T *win = curwin;
2504+
2505+
if (argvars[idx].v_type != VAR_UNKNOWN)
2506+
{
2507+
win = find_win_by_nr_or_id(&argvars[idx]);
2508+
if (win == NULL)
2509+
{
2510+
emsg(_(e_invalwindow));
2511+
return NULL;
2512+
}
2513+
}
2514+
return win;
2515+
}
2516+
24992517
/*
25002518
* "clearmatches()" function
25012519
*/
25022520
static void
25032521
f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
25042522
{
25052523
#ifdef FEAT_SEARCH_EXTRA
2506-
clear_matches(curwin);
2524+
win_T *win = get_optional_window(argvars, 0);
2525+
2526+
if (win != NULL)
2527+
clear_matches(win);
25072528
#endif
25082529
}
25092530

@@ -5412,60 +5433,62 @@ f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
54125433
{
54135434
#ifdef FEAT_SEARCH_EXTRA
54145435
dict_T *dict;
5415-
matchitem_T *cur = curwin->w_match_head;
5436+
matchitem_T *cur;
54165437
int i;
5438+
win_T *win = get_optional_window(argvars, 0);
54175439

5418-
if (rettv_list_alloc(rettv) == OK)
5440+
if (rettv_list_alloc(rettv) == FAIL || win == NULL)
5441+
return;
5442+
5443+
cur = win->w_match_head;
5444+
while (cur != NULL)
54195445
{
5420-
while (cur != NULL)
5446+
dict = dict_alloc();
5447+
if (dict == NULL)
5448+
return;
5449+
if (cur->match.regprog == NULL)
54215450
{
5422-
dict = dict_alloc();
5423-
if (dict == NULL)
5424-
return;
5425-
if (cur->match.regprog == NULL)
5451+
/* match added with matchaddpos() */
5452+
for (i = 0; i < MAXPOSMATCH; ++i)
54265453
{
5427-
/* match added with matchaddpos() */
5428-
for (i = 0; i < MAXPOSMATCH; ++i)
5429-
{
5430-
llpos_T *llpos;
5431-
char buf[6];
5432-
list_T *l;
5454+
llpos_T *llpos;
5455+
char buf[6];
5456+
list_T *l;
54335457

5434-
llpos = &cur->pos.pos[i];
5435-
if (llpos->lnum == 0)
5436-
break;
5437-
l = list_alloc();
5438-
if (l == NULL)
5439-
break;
5440-
list_append_number(l, (varnumber_T)llpos->lnum);
5441-
if (llpos->col > 0)
5442-
{
5443-
list_append_number(l, (varnumber_T)llpos->col);
5444-
list_append_number(l, (varnumber_T)llpos->len);
5445-
}
5446-
sprintf(buf, "pos%d", i + 1);
5447-
dict_add_list(dict, buf, l);
5458+
llpos = &cur->pos.pos[i];
5459+
if (llpos->lnum == 0)
5460+
break;
5461+
l = list_alloc();
5462+
if (l == NULL)
5463+
break;
5464+
list_append_number(l, (varnumber_T)llpos->lnum);
5465+
if (llpos->col > 0)
5466+
{
5467+
list_append_number(l, (varnumber_T)llpos->col);
5468+
list_append_number(l, (varnumber_T)llpos->len);
54485469
}
5470+
sprintf(buf, "pos%d", i + 1);
5471+
dict_add_list(dict, buf, l);
54495472
}
5450-
else
5451-
{
5452-
dict_add_string(dict, "pattern", cur->pattern);
5453-
}
5454-
dict_add_string(dict, "group", syn_id2name(cur->hlg_id));
5455-
dict_add_number(dict, "priority", (long)cur->priority);
5456-
dict_add_number(dict, "id", (long)cur->id);
5473+
}
5474+
else
5475+
{
5476+
dict_add_string(dict, "pattern", cur->pattern);
5477+
}
5478+
dict_add_string(dict, "group", syn_id2name(cur->hlg_id));
5479+
dict_add_number(dict, "priority", (long)cur->priority);
5480+
dict_add_number(dict, "id", (long)cur->id);
54575481
# if defined(FEAT_CONCEAL)
5458-
if (cur->conceal_char)
5459-
{
5460-
char_u buf[MB_MAXBYTES + 1];
5482+
if (cur->conceal_char)
5483+
{
5484+
char_u buf[MB_MAXBYTES + 1];
54615485

5462-
buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
5463-
dict_add_string(dict, "conceal", (char_u *)&buf);
5464-
}
5465-
# endif
5466-
list_append_dict(rettv->vval.v_list, dict);
5467-
cur = cur->next;
5486+
buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL;
5487+
dict_add_string(dict, "conceal", (char_u *)&buf);
54685488
}
5489+
# endif
5490+
list_append_dict(rettv->vval.v_list, dict);
5491+
cur = cur->next;
54695492
}
54705493
#endif
54715494
}
@@ -8245,7 +8268,7 @@ matchadd_dict_arg(typval_T *tv, char_u **conceal_char, win_T **win)
82458268
*win = find_win_by_nr_or_id(&di->di_tv);
82468269
if (*win == NULL)
82478270
{
8248-
emsg(_("E957: Invalid window number"));
8271+
emsg(_(e_invalwindow));
82498272
return FAIL;
82508273
}
82518274
}
@@ -8393,7 +8416,12 @@ f_matcharg(typval_T *argvars UNUSED, typval_T *rettv)
83938416
f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
83948417
{
83958418
#ifdef FEAT_SEARCH_EXTRA
8396-
rettv->vval.v_number = match_delete(curwin,
8419+
win_T *win = get_optional_window(argvars, 1);
8420+
8421+
if (win == NULL)
8422+
rettv->vval.v_number = -1;
8423+
else
8424+
rettv->vval.v_number = match_delete(win,
83978425
(int)tv_get_number(&argvars[0]), TRUE);
83988426
#endif
83998427
}
@@ -11206,16 +11234,19 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1120611234
listitem_T *li;
1120711235
dict_T *d;
1120811236
list_T *s = NULL;
11237+
win_T *win = get_optional_window(argvars, 1);
1120911238

1121011239
rettv->vval.v_number = -1;
1121111240
if (argvars[0].v_type != VAR_LIST)
1121211241
{
1121311242
emsg(_(e_listreq));
1121411243
return;
1121511244
}
11245+
if (win == NULL)
11246+
return;
11247+
1121611248
if ((l = argvars[0].vval.v_list) != NULL)
1121711249
{
11218-
1121911250
/* To some extent make sure that we are dealing with a list from
1122011251
* "getmatches()". */
1122111252
li = l->lv_first;
@@ -11239,7 +11270,7 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1123911270
li = li->li_next;
1124011271
}
1124111272

11242-
clear_matches(curwin);
11273+
clear_matches(win);
1124311274
li = l->lv_first;
1124411275
while (li != NULL)
1124511276
{
@@ -11286,13 +11317,13 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
1128611317
: NULL;
1128711318
if (i == 0)
1128811319
{
11289-
match_add(curwin, group,
11320+
match_add(win, group,
1129011321
dict_get_string(d, (char_u *)"pattern", FALSE),
1129111322
priority, id, NULL, conceal);
1129211323
}
1129311324
else
1129411325
{
11295-
match_add(curwin, group, NULL, priority, id, s, conceal);
11326+
match_add(win, group, NULL, priority, id, s, conceal);
1129611327
list_unref(s);
1129711328
s = NULL;
1129811329
}

0 commit comments

Comments
 (0)