• R/O
  • SSH

vim: Commit

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

Revisão22886f3d882d231a528dcc012c23e54180c8248c (tree)
Hora2007-07-27 05:58:42
Autorvimboss
Commitervimboss

Mensagem de Log

updated for version 7.1-040

Mudança Sumário

Diff

diff -r f26d0c74a329 -r 22886f3d882d runtime/doc/eval.txt
--- a/runtime/doc/eval.txt Wed Jul 25 20:56:39 2007 +0000
+++ b/runtime/doc/eval.txt Thu Jul 26 20:58:42 2007 +0000
@@ -1,4 +1,4 @@
1-*eval.txt* For Vim version 7.1. Last change: 2007 Jul 11
1+*eval.txt* For Vim version 7.1. Last change: 2007 Jul 25
22
33
44 VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1557,6 +1557,7 @@
15571557 changenr() Number current change number
15581558 char2nr( {expr}) Number ASCII value of first char in {expr}
15591559 cindent( {lnum}) Number C indent for line {lnum}
1560+clearmatches() None clear all matches
15601561 col( {expr}) Number column nr of cursor or mark
15611562 complete({startcol}, {matches}) String set Insert mode completion
15621563 complete_add( {expr}) Number add completion match
@@ -1622,6 +1623,7 @@
16221623 getline( {lnum}) String line {lnum} of current buffer
16231624 getline( {lnum}, {end}) List lines {lnum} to {end} of current buffer
16241625 getloclist({nr}) List list of location list items
1626+getmatches() List list of current matches
16251627 getpos( {expr}) List position of cursor, mark, etc.
16261628 getqflist() List list of quickfix items
16271629 getreg( [{regname} [, 1]]) String contents of register
@@ -1676,7 +1678,10 @@
16761678 String check for mappings matching {name}
16771679 match( {expr}, {pat}[, {start}[, {count}]])
16781680 Number position where {pat} matches in {expr}
1681+matchadd( {group}, {pattern}[, {priority}[, {id}]])
1682+ Number highlight {pattern} with {group}
16791683 matcharg( {nr}) List arguments of |:match|
1684+matchdelete( {id}) Number delete match identified by {id}
16801685 matchend( {expr}, {pat}[, {start}[, {count}]])
16811686 Number position where {pat} ends in {expr}
16821687 matchlist( {expr}, {pat}[, {start}[, {count}]])
@@ -1731,6 +1736,7 @@
17311736 setline( {lnum}, {line}) Number set line {lnum} to {line}
17321737 setloclist( {nr}, {list}[, {action}])
17331738 Number modify location list using {list}
1739+setmatches( {list}) Number restore a list of matches
17341740 setpos( {expr}, {list}) none set the {expr} position to {list}
17351741 setqflist( {list}[, {action}]) Number modify quickfix list using {list}
17361742 setreg( {n}, {v}[, {opt}]) Number set register to value and type
@@ -2012,6 +2018,10 @@
20122018 feature, -1 is returned.
20132019 See |C-indenting|.
20142020
2021+clearmatches() *clearmatches()*
2022+ Clears all matches previously defined by |matchadd()| and the
2023+ |:match| commands.
2024+
20152025 *col()*
20162026 col({expr}) The result is a Number, which is the byte index of the column
20172027 position given with {expr}. The accepted positions are:
@@ -2918,6 +2928,28 @@
29182928 returned. For an invalid window number {nr}, an empty list is
29192929 returned. Otherwise, same as getqflist().
29202930
2931+getmatches() *getmatches()*
2932+ Returns a |List| with all matches previously defined by
2933+ |matchadd()| and the |:match| commands. |getmatches()| is
2934+ useful in combination with |setmatches()|, as |setmatches()|
2935+ can restore a list of matches saved by |getmatches()|.
2936+ Example: >
2937+ :echo getmatches()
2938+< [{'group': 'MyGroup1', 'pattern': 'TODO',
2939+ 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
2940+ 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
2941+ :let m = getmatches()
2942+ :call clearmatches()
2943+ :echo getmatches()
2944+< [] >
2945+ :call setmatches(m)
2946+ :echo getmatches()
2947+< [{'group': 'MyGroup1', 'pattern': 'TODO',
2948+ 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
2949+ 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
2950+ :unlet m
2951+<
2952+
29212953 getqflist() *getqflist()*
29222954 Returns a list with all the current quickfix errors. Each
29232955 list item is a dictionary with these entries:
@@ -3622,6 +3654,44 @@
36223654 the pattern. 'smartcase' is NOT used. The matching is always
36233655 done like 'magic' is set and 'cpoptions' is empty.
36243656
3657+ *matchadd()* *E798* *E799* *E801*
3658+matchadd({group}, {pattern}[, {priority}[, {id}]])
3659+ Defines a pattern to be highlighted in the current window (a
3660+ "match"). It will be highlighted with {group}. Returns an
3661+ identification number (ID), which can be used to delete the
3662+ match using |matchdelete()|.
3663+
3664+ The optional {priority} argument assigns a priority to the
3665+ match. A match with a high priority will have its
3666+ highlighting overrule that of a match with a lower priority.
3667+ A priority is specified as an integer (negative numbers are no
3668+ exception). If the {priority} argument is not specified, the
3669+ default priority is 10. The priority of 'hlsearch' is zero,
3670+ hence all matches with a priority greater than zero will
3671+ overrule it. Syntax highlighting (see 'syntax') is a separate
3672+ mechanism, and regardless of the chosen priority a match will
3673+ always overrule syntax highlighting.
3674+
3675+ The optional {id} argument allows the request for a specific
3676+ match ID. If a specified ID is already taken, an error
3677+ message will appear and the match will not be added. An ID
3678+ is specified as a positive integer (zero excluded). IDs 1, 2
3679+ and 3 are reserved for |:match|, |:2match| and |:3match|,
3680+ respectively. If the {id} argument is not specified,
3681+ |matchadd()| automatically chooses a free ID.
3682+
3683+ The number of matches is not limited, as it is the case with
3684+ the |:match| commands.
3685+
3686+ Example: >
3687+ :highlight MyGroup ctermbg=green guibg=green
3688+ :let m = matchadd("MyGroup", "TODO")
3689+< Deletion of the pattern: >
3690+ :call matchdelete(m)
3691+
3692+< A list of matches defined by |matchadd()| and |:match| are
3693+ available from |getmatches()|. All matches can be deleted in
3694+ one operation by |clearmatches()|.
36253695
36263696 matcharg({nr}) *matcharg()*
36273697 Selects the {nr} match item, as set with a |:match|,
@@ -3631,8 +3701,15 @@
36313701 The pattern used.
36323702 When {nr} is not 1, 2 or 3 returns an empty |List|.
36333703 When there is no match item set returns ['', ''].
3634- This is usef to save and restore a |:match|.
3635-
3704+ This is useful to save and restore a |:match|.
3705+ Highlighting matches using the |:match| commands are limited
3706+ to three matches. |matchadd()| does not have this limitation.
3707+
3708+matchdelete({id}) *matchdelete()* *E802* *E803*
3709+ Deletes a match with ID {id} previously defined by |matchadd()|
3710+ or one of the |:match| commands. Returns 0 if succesfull,
3711+ otherwise -1. See example for |matchadd()|. All matches can
3712+ be deleted in one operation by |clearmatches()|.
36363713
36373714 matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()*
36383715 Same as match(), but return the index of first character after
@@ -4385,7 +4462,13 @@
43854462 When {nr} is zero the current window is used. For a location
43864463 list window, the displayed location list is modified. For an
43874464 invalid window number {nr}, -1 is returned.
4388- Otherwise, same as setqflist().
4465+ Otherwise, same as |setqflist()|.
4466+ Also see |location-list|.
4467+
4468+setmatches({list}) *setmatches()*
4469+ Restores a list of matches saved by |getmatches()|. Returns 0
4470+ if succesfull, otherwise -1. All current matches are cleared
4471+ before the list is restored. See example for |getmatches()|.
43894472
43904473 *setpos()*
43914474 setpos({expr}, {list})
diff -r f26d0c74a329 -r 22886f3d882d runtime/doc/pattern.txt
--- a/runtime/doc/pattern.txt Wed Jul 25 20:56:39 2007 +0000
+++ b/runtime/doc/pattern.txt Thu Jul 26 20:58:42 2007 +0000
@@ -1212,7 +1212,10 @@
12121212 {group} must exist at the moment this command is executed.
12131213
12141214 The {group} highlighting still applies when a character is
1215- to be highlighted for 'hlsearch'.
1215+ to be highlighted for 'hlsearch', as the highlighting for
1216+ matches is given higher priority than that of 'hlsearch'.
1217+ Syntax highlighting (see 'syntax') is also overruled by
1218+ matches.
12161219
12171220 Note that highlighting the last used search pattern with
12181221 'hlsearch' is used in all windows, while the pattern defined
@@ -1226,8 +1229,15 @@
12261229 display you may get unexpected results. That is because Vim
12271230 looks for a match in the line where redrawing starts.
12281231
1229- Also see |matcharg()|, it returns the highlight group and
1230- pattern of a previous :match command.
1232+ Also see |matcharg()|and |getmatches()|. The former returns
1233+ the highlight group and pattern of a previous |:match|
1234+ command. The latter returns a list with highlight groups and
1235+ patterns defined by both |matchadd()| and |:match|.
1236+
1237+ Highlighting matches using |:match| are limited to three
1238+ matches (aside from |:match|, |:2match| and |:3match|are
1239+ available). |matchadd()| does not have this limitation and in
1240+ addition makes it possible to prioritize matches.
12311241
12321242 Another example, which highlights all characters in virtual
12331243 column 72 and more: >
diff -r f26d0c74a329 -r 22886f3d882d runtime/doc/usr_41.txt
--- a/runtime/doc/usr_41.txt Wed Jul 25 20:56:39 2007 +0000
+++ b/runtime/doc/usr_41.txt Thu Jul 26 20:58:42 2007 +0000
@@ -763,13 +763,22 @@
763763 foldtextresult() get the text displayed for a closed fold
764764
765765 Syntax and highlighting:
766+ clearmatches() clear all matches defined by |matchadd()| and
767+ the |:match| commands
768+ getmatches() get all matches defined by |matchadd()| and
769+ the |:match| commands
766770 hlexists() check if a highlight group exists
767771 hlID() get ID of a highlight group
768772 synID() get syntax ID at a specific position
769773 synIDattr() get a specific attribute of a syntax ID
770774 synIDtrans() get translated syntax ID
771775 diff_hlID() get highlight ID for diff mode at a position
776+ matchadd() define a pattern to highlight (a "match")
772777 matcharg() get info about |:match| arguments
778+ matchdelete() delete a match defined by |matchadd()| or a
779+ |:match| command
780+ setmatches() restore a list of matches saved by
781+ |getmatches()|
773782
774783 Spelling:
775784 spellbadword() locate badly spelled word at or after cursor
diff -r f26d0c74a329 -r 22886f3d882d src/eval.c
--- a/src/eval.c Wed Jul 25 20:56:39 2007 +0000
+++ b/src/eval.c Thu Jul 26 20:58:42 2007 +0000
@@ -475,6 +475,7 @@
475475 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
476476 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
477477 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
478+static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
478479 static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
479480 #if defined(FEAT_INS_EXPAND)
480481 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
@@ -529,6 +530,7 @@
529530 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
530531 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
531532 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
533+static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
532534 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
533535 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
534536 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
@@ -577,7 +579,9 @@
577579 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
578580 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
579581 static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
582+static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
580583 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
584+static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
581585 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
582586 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
583587 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
@@ -618,6 +622,7 @@
618622 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
619623 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
620624 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
625+static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
621626 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
622627 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
623628 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
@@ -7046,6 +7051,7 @@
70467051 {"changenr", 0, 0, f_changenr},
70477052 {"char2nr", 1, 1, f_char2nr},
70487053 {"cindent", 1, 1, f_cindent},
7054+ {"clearmatches", 0, 0, f_clearmatches},
70497055 {"col", 1, 1, f_col},
70507056 #if defined(FEAT_INS_EXPAND)
70517057 {"complete", 2, 2, f_complete},
@@ -7102,6 +7108,7 @@
71027108 {"getftype", 1, 1, f_getftype},
71037109 {"getline", 1, 2, f_getline},
71047110 {"getloclist", 1, 1, f_getqflist},
7111+ {"getmatches", 0, 0, f_getmatches},
71057112 {"getpos", 1, 1, f_getpos},
71067113 {"getqflist", 0, 0, f_getqflist},
71077114 {"getreg", 0, 2, f_getreg},
@@ -7152,7 +7159,9 @@
71527159 {"maparg", 1, 3, f_maparg},
71537160 {"mapcheck", 1, 3, f_mapcheck},
71547161 {"match", 2, 4, f_match},
7162+ {"matchadd", 2, 4, f_matchadd},
71557163 {"matcharg", 1, 1, f_matcharg},
7164+ {"matchdelete", 1, 1, f_matchdelete},
71567165 {"matchend", 2, 4, f_matchend},
71577166 {"matchlist", 2, 4, f_matchlist},
71587167 {"matchstr", 2, 4, f_matchstr},
@@ -7193,6 +7202,7 @@
71937202 {"setcmdpos", 1, 1, f_setcmdpos},
71947203 {"setline", 2, 2, f_setline},
71957204 {"setloclist", 2, 3, f_setloclist},
7205+ {"setmatches", 1, 1, f_setmatches},
71967206 {"setpos", 2, 2, f_setpos},
71977207 {"setqflist", 1, 2, f_setqflist},
71987208 {"setreg", 2, 3, f_setreg},
@@ -8243,6 +8253,20 @@
82438253 }
82448254
82458255 /*
8256+ * "clearmatches()" function
8257+ */
8258+/*ARGSUSED*/
8259+ static void
8260+f_clearmatches(argvars, rettv)
8261+ typval_T *argvars;
8262+ typval_T *rettv;
8263+{
8264+#ifdef FEAT_SEARCH_EXTRA
8265+ clear_matches(curwin);
8266+#endif
8267+}
8268+
8269+/*
82468270 * "col(string)" function
82478271 */
82488272 static void
@@ -10278,6 +10302,40 @@
1027810302 }
1027910303
1028010304 /*
10305+ * "getmatches()" function
10306+ */
10307+/*ARGSUSED*/
10308+ static void
10309+f_getmatches(argvars, rettv)
10310+ typval_T *argvars;
10311+ typval_T *rettv;
10312+{
10313+#ifdef FEAT_SEARCH_EXTRA
10314+ dict_T *dict;
10315+ matchitem_T *cur = curwin->w_match_head;
10316+
10317+ rettv->vval.v_number = 0;
10318+
10319+ if (rettv_list_alloc(rettv) == OK)
10320+ {
10321+ while (cur != NULL)
10322+ {
10323+ dict = dict_alloc();
10324+ if (dict == NULL)
10325+ return;
10326+ ++dict->dv_refcount;
10327+ dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
10328+ dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
10329+ dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
10330+ dict_add_nr_str(dict, "id", (long)cur->id, NULL);
10331+ list_append_dict(rettv->vval.v_list, dict);
10332+ cur = cur->next;
10333+ }
10334+ }
10335+#endif
10336+}
10337+
10338+/*
1028110339 * "getpos(string)" function
1028210340 */
1028310341 static void
@@ -12448,6 +12506,42 @@
1244812506 }
1244912507
1245012508 /*
12509+ * "matchadd()" function
12510+ */
12511+ static void
12512+f_matchadd(argvars, rettv)
12513+ typval_T *argvars;
12514+ typval_T *rettv;
12515+{
12516+#ifdef FEAT_SEARCH_EXTRA
12517+ char_u buf[NUMBUFLEN];
12518+ char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */
12519+ char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */
12520+ int prio = 10; /* default priority */
12521+ int id = -1;
12522+ int error = FALSE;
12523+
12524+ rettv->vval.v_number = -1;
12525+
12526+ if (grp == NULL || pat == NULL)
12527+ return;
12528+ if (argvars[2].v_type != VAR_UNKNOWN)
12529+ prio = get_tv_number_chk(&argvars[2], &error);
12530+ if (argvars[3].v_type != VAR_UNKNOWN)
12531+ id = get_tv_number_chk(&argvars[3], &error);
12532+ if (error == TRUE)
12533+ return;
12534+ if (id >= 1 && id <= 3)
12535+ {
12536+ EMSGN("E798: ID is reserved for \":match\": %ld", id);
12537+ return;
12538+ }
12539+
12540+ rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
12541+#endif
12542+}
12543+
12544+/*
1245112545 * "matcharg()" function
1245212546 */
1245312547 static void
@@ -12458,17 +12552,39 @@
1245812552 if (rettv_list_alloc(rettv) == OK)
1245912553 {
1246012554 #ifdef FEAT_SEARCH_EXTRA
12461- int mi = get_tv_number(&argvars[0]);
12462-
12463- if (mi >= 1 && mi <= 3)
12464- {
12465- list_append_string(rettv->vval.v_list,
12466- syn_id2name(curwin->w_match_id[mi - 1]), -1);
12467- list_append_string(rettv->vval.v_list,
12468- curwin->w_match_pat[mi - 1], -1);
12469- }
12470-#endif
12471- }
12555+ int id = get_tv_number(&argvars[0]);
12556+ matchitem_T *m;
12557+
12558+ if (id >= 1 && id <= 3)
12559+ {
12560+ if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
12561+ {
12562+ list_append_string(rettv->vval.v_list,
12563+ syn_id2name(m->hlg_id), -1);
12564+ list_append_string(rettv->vval.v_list, m->pattern, -1);
12565+ }
12566+ else
12567+ {
12568+ list_append_string(rettv->vval.v_list, NUL, -1);
12569+ list_append_string(rettv->vval.v_list, NUL, -1);
12570+ }
12571+ }
12572+#endif
12573+ }
12574+}
12575+
12576+/*
12577+ * "matchdelete()" function
12578+ */
12579+ static void
12580+f_matchdelete(argvars, rettv)
12581+ typval_T *argvars;
12582+ typval_T *rettv;
12583+{
12584+#ifdef FEAT_SEARCH_EXTRA
12585+ rettv->vval.v_number = match_delete(curwin,
12586+ (int)get_tv_number(&argvars[0]), TRUE);
12587+#endif
1247212588 }
1247312589
1247412590 /*
@@ -14509,6 +14625,66 @@
1450914625 }
1451014626
1451114627 /*
14628+ * "setmatches()" function
14629+ */
14630+ static void
14631+f_setmatches(argvars, rettv)
14632+ typval_T *argvars;
14633+ typval_T *rettv;
14634+{
14635+#ifdef FEAT_SEARCH_EXTRA
14636+ list_T *l;
14637+ listitem_T *li;
14638+ dict_T *d;
14639+
14640+ rettv->vval.v_number = -1;
14641+ if (argvars[0].v_type != VAR_LIST)
14642+ {
14643+ EMSG(_(e_listreq));
14644+ return;
14645+ }
14646+ if ((l = argvars[0].vval.v_list) != NULL)
14647+ {
14648+
14649+ /* To some extent make sure that we are dealing with a list from
14650+ * "getmatches()". */
14651+ li = l->lv_first;
14652+ while (li != NULL)
14653+ {
14654+ if (li->li_tv.v_type != VAR_DICT
14655+ || (d = li->li_tv.vval.v_dict) == NULL)
14656+ {
14657+ EMSG(_(e_invarg));
14658+ return;
14659+ }
14660+ if (!(dict_find(d, (char_u *)"group", -1) != NULL
14661+ && dict_find(d, (char_u *)"pattern", -1) != NULL
14662+ && dict_find(d, (char_u *)"priority", -1) != NULL
14663+ && dict_find(d, (char_u *)"id", -1) != NULL))
14664+ {
14665+ EMSG(_(e_invarg));
14666+ return;
14667+ }
14668+ li = li->li_next;
14669+ }
14670+
14671+ clear_matches(curwin);
14672+ li = l->lv_first;
14673+ while (li != NULL)
14674+ {
14675+ d = li->li_tv.vval.v_dict;
14676+ match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
14677+ get_dict_string(d, (char_u *)"pattern", FALSE),
14678+ (int)get_dict_number(d, (char_u *)"priority"),
14679+ (int)get_dict_number(d, (char_u *)"id"));
14680+ li = li->li_next;
14681+ }
14682+ rettv->vval.v_number = 0;
14683+ }
14684+#endif
14685+}
14686+
14687+/*
1451214688 * "setpos()" function
1451314689 */
1451414690 /*ARGSUSED*/
diff -r f26d0c74a329 -r 22886f3d882d src/ex_docmd.c
--- a/src/ex_docmd.c Wed Jul 25 20:56:39 2007 +0000
+++ b/src/ex_docmd.c Thu Jul 26 20:58:42 2007 +0000
@@ -10817,12 +10817,13 @@
1081710817 exarg_T *eap;
1081810818 {
1081910819 char_u *p;
10820+ char_u *g;
1082010821 char_u *end;
1082110822 int c;
10822- int mi;
10823+ int id;
1082310824
1082410825 if (eap->line2 <= 3)
10825- mi = eap->line2 - 1;
10826+ id = eap->line2;
1082610827 else
1082710828 {
1082810829 EMSG(e_invcmd);
@@ -10831,13 +10832,7 @@
1083110832
1083210833 /* First clear any old pattern. */
1083310834 if (!eap->skip)
10834- {
10835- vim_free(curwin->w_match[mi].regprog);
10836- curwin->w_match[mi].regprog = NULL;
10837- vim_free(curwin->w_match_pat[mi]);
10838- curwin->w_match_pat[mi] = NULL;
10839- redraw_later(SOME_VALID); /* always need a redraw */
10840- }
10835+ match_delete(curwin, id, FALSE);
1084110836
1084210837 if (ends_excmd(*eap->arg))
1084310838 end = eap->arg;
@@ -10848,15 +10843,7 @@
1084810843 {
1084910844 p = skiptowhite(eap->arg);
1085010845 if (!eap->skip)
10851- {
10852- curwin->w_match_id[mi] = syn_namen2id(eap->arg,
10853- (int)(p - eap->arg));
10854- if (curwin->w_match_id[mi] == 0)
10855- {
10856- EMSG2(_(e_nogroup), eap->arg);
10857- return;
10858- }
10859- }
10846+ g = vim_strnsave(eap->arg, (int)(p - eap->arg));
1086010847 p = skipwhite(p);
1086110848 if (*p == NUL)
1086210849 {
@@ -10880,14 +10867,8 @@
1088010867
1088110868 c = *end;
1088210869 *end = NUL;
10883- curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
10884- if (curwin->w_match[mi].regprog == NULL)
10885- {
10886- EMSG2(_(e_invarg2), p);
10887- *end = c;
10888- return;
10889- }
10890- curwin->w_match_pat[mi] = vim_strsave(p + 1);
10870+ match_add(curwin, g, p + 1, 10, id);
10871+ vim_free(g);
1089110872 *end = c;
1089210873 }
1089310874 }
diff -r f26d0c74a329 -r 22886f3d882d src/proto/window.pro
--- a/src/proto/window.pro Wed Jul 25 20:56:39 2007 +0000
+++ b/src/proto/window.pro Thu Jul 26 20:58:42 2007 +0000
@@ -59,4 +59,8 @@
5959 int only_one_window __ARGS((void));
6060 void check_lnums __ARGS((int do_curwin));
6161 int win_hasvertsplit __ARGS((void));
62+int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
63+int match_delete __ARGS((win_T *wp, int id, int perr));
64+void clear_matches __ARGS((win_T *wp));
65+matchitem_T *get_match __ARGS((win_T *wp, int id));
6266 /* vim: set ft=c : */
diff -r f26d0c74a329 -r 22886f3d882d src/screen.c
--- a/src/screen.c Wed Jul 25 20:56:39 2007 +0000
+++ b/src/screen.c Thu Jul 26 20:58:42 2007 +0000
@@ -100,27 +100,7 @@
100100 static int screen_cur_row, screen_cur_col; /* last known cursor position */
101101
102102 #ifdef FEAT_SEARCH_EXTRA
103-/*
104- * Struct used for highlighting 'hlsearch' matches for the last use search
105- * pattern or a ":match" item.
106- * For 'hlsearch' there is one pattern for all windows. For ":match" there is
107- * a different pattern for each window.
108- */
109-typedef struct
110-{
111- regmmatch_T rm; /* points to the regexp program; contains last found
112- match (may continue in next line) */
113- buf_T *buf; /* the buffer to search for a match */
114- linenr_T lnum; /* the line to search for a match */
115- int attr; /* attributes to be used for a match */
116- int attr_cur; /* attributes currently active in win_line() */
117- linenr_T first_lnum; /* first lnum to search for multi-line pat */
118- colnr_T startcol; /* in win_line() points to char where HL starts */
119- colnr_T endcol; /* in win_line() points to char where HL ends */
120-} match_T;
121-
122103 static match_T search_hl; /* used for 'hlsearch' highlight matching */
123-static match_T match_hl[3]; /* used for ":match" highlight matching */
124104 #endif
125105
126106 #ifdef FEAT_FOLDING
@@ -155,6 +135,7 @@
155135 static void redraw_custum_statusline __ARGS((win_T *wp));
156136 #endif
157137 #ifdef FEAT_SEARCH_EXTRA
138+#define SEARCH_HL_PRIORITY 0
158139 static void start_search_hl __ARGS((void));
159140 static void end_search_hl __ARGS((void));
160141 static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
@@ -787,6 +768,7 @@
787768 w_topline got smaller a bit */
788769 #endif
789770 #ifdef FEAT_SEARCH_EXTRA
771+ matchitem_T *cur; /* points to the match list */
790772 int top_to_mod = FALSE; /* redraw above mod_top */
791773 #endif
792774
@@ -848,18 +830,20 @@
848830 #endif
849831
850832 #ifdef FEAT_SEARCH_EXTRA
851- /* Setup for ":match" and 'hlsearch' highlighting. Disable any previous
833+ /* Setup for match and 'hlsearch' highlighting. Disable any previous
852834 * match */
853- for (i = 0; i < 3; ++i)
854- {
855- match_hl[i].rm = wp->w_match[i];
856- if (wp->w_match_id[i] == 0)
857- match_hl[i].attr = 0;
835+ cur = wp->w_match_head;
836+ while (cur != NULL)
837+ {
838+ cur->hl.rm = cur->match;
839+ if (cur->hlg_id == 0)
840+ cur->hl.attr = 0;
858841 else
859- match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
860- match_hl[i].buf = buf;
861- match_hl[i].lnum = 0;
862- match_hl[i].first_lnum = 0;
842+ cur->hl.attr = syn_id2attr(cur->hlg_id);
843+ cur->hl.buf = buf;
844+ cur->hl.lnum = 0;
845+ cur->hl.first_lnum = 0;
846+ cur = cur->next;
863847 }
864848 search_hl.buf = buf;
865849 search_hl.lnum = 0;
@@ -923,19 +907,25 @@
923907 * change in one line may make the Search highlighting in a
924908 * previous line invalid. Simple solution: redraw all visible
925909 * lines above the change.
926- * Same for a ":match" pattern.
910+ * Same for a match pattern.
927911 */
928912 if (search_hl.rm.regprog != NULL
929913 && re_multiline(search_hl.rm.regprog))
930914 top_to_mod = TRUE;
931915 else
932- for (i = 0; i < 3; ++i)
933- if (match_hl[i].rm.regprog != NULL
934- && re_multiline(match_hl[i].rm.regprog))
916+ {
917+ cur = wp->w_match_head;
918+ while (cur != NULL)
919+ {
920+ if (cur->match.regprog != NULL
921+ && re_multiline(cur->match.regprog))
935922 {
936923 top_to_mod = TRUE;
937924 break;
938925 }
926+ cur = cur->next;
927+ }
928+ }
939929 #endif
940930 }
941931 #ifdef FEAT_FOLDING
@@ -2626,10 +2616,13 @@
26262616 int line_attr = 0; /* atrribute for the whole line */
26272617 #endif
26282618 #ifdef FEAT_SEARCH_EXTRA
2629- match_T *shl; /* points to search_hl or match_hl */
2630-#endif
2631-#if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
2632- int i;
2619+ matchitem_T *cur; /* points to the match list */
2620+ match_T *shl; /* points to search_hl or a match */
2621+ int shl_flag; /* flag to indicate whether search_hl
2622+ has been processed or not */
2623+ int prevcol_hl_flag; /* flag to indicate whether prevcol
2624+ equals startcol of search_hl or one
2625+ of the matches */
26332626 #endif
26342627 #ifdef FEAT_ARABIC
26352628 int prev_c = 0; /* previous Arabic character */
@@ -3074,12 +3067,20 @@
30743067
30753068 #ifdef FEAT_SEARCH_EXTRA
30763069 /*
3077- * Handle highlighting the last used search pattern and ":match".
3078- * Do this for both search_hl and match_hl[3].
3070+ * Handle highlighting the last used search pattern and matches.
3071+ * Do this for both search_hl and the match list.
30793072 */
3080- for (i = 3; i >= 0; --i)
3081- {
3082- shl = (i == 3) ? &search_hl : &match_hl[i];
3073+ cur = wp->w_match_head;
3074+ shl_flag = FALSE;
3075+ while (cur != NULL || shl_flag == FALSE)
3076+ {
3077+ if (shl_flag == FALSE)
3078+ {
3079+ shl = &search_hl;
3080+ shl_flag = TRUE;
3081+ }
3082+ else
3083+ shl = &cur->hl;
30833084 shl->startcol = MAXCOL;
30843085 shl->endcol = MAXCOL;
30853086 shl->attr_cur = 0;
@@ -3122,6 +3123,8 @@
31223123 area_highlighting = TRUE;
31233124 }
31243125 }
3126+ if (shl != &search_hl && cur != NULL)
3127+ cur = cur->next;
31253128 }
31263129 #endif
31273130
@@ -3388,13 +3391,24 @@
33883391 * After end, check for start/end of next match.
33893392 * When another match, have to check for start again.
33903393 * Watch out for matching an empty string!
3391- * Do this first for search_hl, then for match_hl, so that
3392- * ":match" overrules 'hlsearch'.
3394+ * Do this for 'search_hl' and the match list (ordered by
3395+ * priority).
33933396 */
33943397 v = (long)(ptr - line);
3395- for (i = 3; i >= 0; --i)
3396- {
3397- shl = (i == 3) ? &search_hl : &match_hl[i];
3398+ cur = wp->w_match_head;
3399+ shl_flag = FALSE;
3400+ while (cur != NULL || shl_flag == FALSE)
3401+ {
3402+ if (shl_flag == FALSE
3403+ && ((cur != NULL
3404+ && cur->priority > SEARCH_HL_PRIORITY)
3405+ || cur == NULL))
3406+ {
3407+ shl = &search_hl;
3408+ shl_flag = TRUE;
3409+ }
3410+ else
3411+ shl = &cur->hl;
33983412 while (shl->rm.regprog != NULL)
33993413 {
34003414 if (shl->startcol != MAXCOL
@@ -3442,17 +3456,32 @@
34423456 }
34433457 break;
34443458 }
3445- }
3446-
3447- /* ":match" highlighting overrules 'hlsearch' */
3448- for (i = 0; i <= 3; ++i)
3449- if (i == 3)
3450- search_attr = search_hl.attr_cur;
3451- else if (match_hl[i].attr_cur != 0)
3459+ if (shl != &search_hl && cur != NULL)
3460+ cur = cur->next;
3461+ }
3462+
3463+ /* Use attributes from match with highest priority among
3464+ * 'search_hl' and the match list. */
3465+ search_attr = search_hl.attr_cur;
3466+ cur = wp->w_match_head;
3467+ shl_flag = FALSE;
3468+ while (cur != NULL || shl_flag == FALSE)
3469+ {
3470+ if (shl_flag == FALSE
3471+ && ((cur != NULL
3472+ && cur->priority > SEARCH_HL_PRIORITY)
3473+ || cur == NULL))
34523474 {
3453- search_attr = match_hl[i].attr_cur;
3454- break;
3475+ shl = &search_hl;
3476+ shl_flag = TRUE;
34553477 }
3478+ else
3479+ shl = &cur->hl;
3480+ if (shl->attr_cur != 0)
3481+ search_attr = shl->attr_cur;
3482+ if (shl != &search_hl && cur != NULL)
3483+ cur = cur->next;
3484+ }
34563485 }
34573486 #endif
34583487
@@ -3613,6 +3642,8 @@
36133642 * Draw it as a space with a composing char. */
36143643 if (utf_iscomposing(mb_c))
36153644 {
3645+ int i;
3646+
36163647 for (i = Screen_mco - 1; i > 0; --i)
36173648 u8cc[i] = u8cc[i - 1];
36183649 u8cc[0] = mb_c;
@@ -4256,14 +4287,29 @@
42564287 * highlight match at end of line. If it's beyond the last
42574288 * char on the screen, just overwrite that one (tricky!) Not
42584289 * needed when a '$' was displayed for 'list'. */
4290+#ifdef FEAT_SEARCH_EXTRA
4291+ prevcol_hl_flag = FALSE;
4292+ if (prevcol == (long)search_hl.startcol)
4293+ prevcol_hl_flag = TRUE;
4294+ else
4295+ {
4296+ cur = wp->w_match_head;
4297+ while (cur != NULL)
4298+ {
4299+ if (prevcol == (long)cur->hl.startcol)
4300+ {
4301+ prevcol_hl_flag = TRUE;
4302+ break;
4303+ }
4304+ cur = cur->next;
4305+ }
4306+ }
4307+#endif
42594308 if (lcs_eol == lcs_eol_one
42604309 && ((area_attr != 0 && vcol == fromcol && c == NUL)
42614310 #ifdef FEAT_SEARCH_EXTRA
42624311 /* highlight 'hlsearch' match at end of line */
4263- || ((prevcol == (long)search_hl.startcol
4264- || prevcol == (long)match_hl[0].startcol
4265- || prevcol == (long)match_hl[1].startcol
4266- || prevcol == (long)match_hl[2].startcol)
4312+ || (prevcol_hl_flag == TRUE
42674313 # if defined(LINE_ATTR)
42684314 && did_line_attr <= 1
42694315 # endif
@@ -4304,15 +4350,27 @@
43044350 #ifdef FEAT_SEARCH_EXTRA
43054351 if (area_attr == 0)
43064352 {
4307- for (i = 0; i <= 3; ++i)
4353+ /* Use attributes from match with highest priority among
4354+ * 'search_hl' and the match list. */
4355+ char_attr = search_hl.attr;
4356+ cur = wp->w_match_head;
4357+ shl_flag = FALSE;
4358+ while (cur != NULL || shl_flag == FALSE)
43084359 {
4309- if (i == 3)
4310- char_attr = search_hl.attr;
4311- else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
4360+ if (shl_flag == FALSE
4361+ && ((cur != NULL
4362+ && cur->priority > SEARCH_HL_PRIORITY)
4363+ || cur == NULL))
43124364 {
4313- char_attr = match_hl[i].attr;
4314- break;
4365+ shl = &search_hl;
4366+ shl_flag = TRUE;
43154367 }
4368+ else
4369+ shl = &cur->hl;
4370+ if ((ptr - line) - 1 == (long)shl->startcol)
4371+ char_attr = shl->attr;
4372+ if (shl != &search_hl && cur != NULL)
4373+ cur = cur->next;
43164374 }
43174375 }
43184376 #endif
@@ -4462,6 +4520,8 @@
44624520 {
44634521 if (mb_utf8)
44644522 {
4523+ int i;
4524+
44654525 ScreenLinesUC[off] = mb_c;
44664526 if ((c & 0xff) == 0)
44674527 ScreenLines[off] = 0x80; /* avoid storing zero */
@@ -6320,7 +6380,7 @@
63206380
63216381 #ifdef FEAT_SEARCH_EXTRA
63226382 /*
6323- * Prepare for 'searchhl' highlighting.
6383+ * Prepare for 'hlsearch' highlighting.
63246384 */
63256385 static void
63266386 start_search_hl()
@@ -6333,7 +6393,7 @@
63336393 }
63346394
63356395 /*
6336- * Clean up for 'searchhl' highlighting.
6396+ * Clean up for 'hlsearch' highlighting.
63376397 */
63386398 static void
63396399 end_search_hl()
@@ -6353,18 +6413,28 @@
63536413 win_T *wp;
63546414 linenr_T lnum;
63556415 {
6356- match_T *shl; /* points to search_hl or match_hl */
6416+ matchitem_T *cur; /* points to the match list */
6417+ match_T *shl; /* points to search_hl or a match */
6418+ int shl_flag; /* flag to indicate whether search_hl
6419+ has been processed or not */
63576420 int n;
6358- int i;
63596421
63606422 /*
63616423 * When using a multi-line pattern, start searching at the top
63626424 * of the window or just after a closed fold.
6363- * Do this both for search_hl and match_hl[3].
6425+ * Do this both for search_hl and the match list.
63646426 */
6365- for (i = 3; i >= 0; --i)
6366- {
6367- shl = (i == 3) ? &search_hl : &match_hl[i];
6427+ cur = wp->w_match_head;
6428+ shl_flag = FALSE;
6429+ while (cur != NULL || shl_flag == FALSE)
6430+ {
6431+ if (shl_flag == FALSE)
6432+ {
6433+ shl = &search_hl;
6434+ shl_flag = TRUE;
6435+ }
6436+ else
6437+ shl = &cur->hl;
63686438 if (shl->rm.regprog != NULL
63696439 && shl->lnum == 0
63706440 && re_multiline(shl->rm.regprog))
@@ -6399,11 +6469,13 @@
63996469 }
64006470 }
64016471 }
6472+ if (shl != &search_hl && cur != NULL)
6473+ cur = cur->next;
64026474 }
64036475 }
64046476
64056477 /*
6406- * Search for a next 'searchl' or ":match" match.
6478+ * Search for a next 'hlsearch' or match.
64076479 * Uses shl->buf.
64086480 * Sets shl->lnum and shl->rm contents.
64096481 * Note: Assumes a previous match is always before "lnum", unless
@@ -6413,7 +6485,7 @@
64136485 static void
64146486 next_search_hl(win, shl, lnum, mincol)
64156487 win_T *win;
6416- match_T *shl; /* points to search_hl or match_hl */
6488+ match_T *shl; /* points to search_hl or a match */
64176489 linenr_T lnum;
64186490 colnr_T mincol; /* minimal column for a match */
64196491 {
@@ -6481,7 +6553,7 @@
64816553 /* Error while handling regexp: stop using this regexp. */
64826554 if (shl == &search_hl)
64836555 {
6484- /* don't free the regprog in match_hl[], it's a copy */
6556+ /* don't free regprog in the match list, it's a copy */
64856557 vim_free(shl->rm.regprog);
64866558 no_hlsearch = TRUE;
64876559 }
diff -r f26d0c74a329 -r 22886f3d882d src/structs.h
--- a/src/structs.h Wed Jul 25 20:56:39 2007 +0000
+++ b/src/structs.h Thu Jul 26 20:58:42 2007 +0000
@@ -1694,6 +1694,41 @@
16941694 #define FR_COL 2 /* frame with a column of windows */
16951695
16961696 /*
1697+ * Struct used for highlighting 'hlsearch' matches, matches defined by
1698+ * ":match" and matches defined by match functions.
1699+ * For 'hlsearch' there is one pattern for all windows. For ":match" and the
1700+ * match functions there is a different pattern for each window.
1701+ */
1702+typedef struct
1703+{
1704+ regmmatch_T rm; /* points to the regexp program; contains last found
1705+ match (may continue in next line) */
1706+ buf_T *buf; /* the buffer to search for a match */
1707+ linenr_T lnum; /* the line to search for a match */
1708+ int attr; /* attributes to be used for a match */
1709+ int attr_cur; /* attributes currently active in win_line() */
1710+ linenr_T first_lnum; /* first lnum to search for multi-line pat */
1711+ colnr_T startcol; /* in win_line() points to char where HL starts */
1712+ colnr_T endcol; /* in win_line() points to char where HL ends */
1713+} match_T;
1714+
1715+/*
1716+ * matchitem_T provides a linked list for storing match items for ":match" and
1717+ * the match functions.
1718+ */
1719+typedef struct matchitem matchitem_T;
1720+struct matchitem
1721+{
1722+ matchitem_T *next;
1723+ int id; /* match ID */
1724+ int priority; /* match priority */
1725+ char_u *pattern; /* pattern to highlight */
1726+ int hlg_id; /* highlight group ID */
1727+ regmmatch_T match; /* regexp program for pattern */
1728+ match_T hl; /* struct for doing the actual highlighting */
1729+};
1730+
1731+/*
16971732 * Structure which contains all information that belongs to a window
16981733 *
16991734 * All row numbers are relative to the start of the window, except w_winrow.
@@ -1934,9 +1969,8 @@
19341969 #endif
19351970
19361971 #ifdef FEAT_SEARCH_EXTRA
1937- regmmatch_T w_match[3]; /* regexp programs for ":match" */
1938- char_u *(w_match_pat[3]); /* patterns for ":match" */
1939- int w_match_id[3]; /* highlight IDs for ":match" */
1972+ matchitem_T *w_match_head; /* head of match list */
1973+ int w_next_match_id; /* next match ID */
19401974 #endif
19411975
19421976 /*
diff -r f26d0c74a329 -r 22886f3d882d src/syntax.c
--- a/src/syntax.c Wed Jul 25 20:56:39 2007 +0000
+++ b/src/syntax.c Thu Jul 26 20:58:42 2007 +0000
@@ -8504,7 +8504,7 @@
85048504 syn_id2name(id)
85058505 int id;
85068506 {
8507- if (id <= 0 || id >= highlight_ga.ga_len)
8507+ if (id <= 0 || id > highlight_ga.ga_len)
85088508 return (char_u *)"";
85098509 return HL_TABLE()[id - 1].sg_name;
85108510 }
diff -r f26d0c74a329 -r 22886f3d882d src/testdir/Makefile
--- a/src/testdir/Makefile Wed Jul 25 20:56:39 2007 +0000
+++ b/src/testdir/Makefile Thu Jul 26 20:58:42 2007 +0000
@@ -1,5 +1,5 @@
11 #
2-# Makefile to run al tests for Vim
2+# Makefile to run all tests for Vim
33 #
44
55 VIMPROG = ../vim
@@ -15,7 +15,7 @@
1515 test43.out test44.out test45.out test46.out test47.out \
1616 test48.out test49.out test51.out test52.out test53.out \
1717 test54.out test55.out test56.out test57.out test58.out \
18- test59.out test60.out test61.out test62.out
18+ test59.out test60.out test61.out test62.out test63.out
1919
2020 SCRIPTS_GUI = test16.out
2121
diff -r f26d0c74a329 -r 22886f3d882d src/testdir/test63.in
--- a/src/testdir/test63.in Wed Jul 25 20:56:39 2007 +0000
+++ b/src/testdir/test63.in Thu Jul 26 20:58:42 2007 +0000
@@ -0,0 +1,157 @@
1+Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
2+"matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
3+
4+STARTTEST
5+:so small.vim
6+:" --- Check that "matcharg()" returns the correct group and pattern if a match
7+:" --- is defined.
8+:let @r = "*** Test 1: "
9+:highlight MyGroup1 ctermbg=red
10+:highlight MyGroup2 ctermbg=green
11+:highlight MyGroup3 ctermbg=blue
12+:match MyGroup1 /TODO/
13+:2match MyGroup2 /FIXME/
14+:3match MyGroup3 /XXX/
15+:if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
16+: let @r .= "OK\n"
17+:else
18+: let @r .= "FAILED\n"
19+:endif
20+:" --- Check that "matcharg()" returns an empty list if the argument is not 1,
21+:" --- 2 or 3 (only 0 and 4 are tested).
22+:let @r .= "*** Test 2: "
23+:if matcharg(0) == [] && matcharg(4) == []
24+: let @r .= "OK\n"
25+:else
26+: let @r .= "FAILED\n"
27+:endif
28+:" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
29+:let @r .= "*** Test 3: "
30+:match
31+:2match
32+:3match
33+:if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
34+: let @r .= "OK\n"
35+:else
36+: let @r .= "FAILED\n"
37+:endif
38+:" --- Check that "matchadd()" and "getmatches()" agree on added matches and
39+:" --- that default values apply.
40+:let @r .= "*** Test 4: "
41+:let m1 = matchadd("MyGroup1", "TODO")
42+:let m2 = matchadd("MyGroup2", "FIXME", 42)
43+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
44+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 4}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 42, 'id': 5}, {'group': 'MyGroup3', 'pattern': 'XXX', 'priority': 60, 'id': 17}]
45+: let @r .= "OK\n"
46+:else
47+: let @r .= "FAILED\n"
48+:endif
49+:" --- Check that "matchdelete()" deletes the matches defined in the previous
50+:" --- test correctly.
51+:let @r .= "*** Test 5: "
52+:call matchdelete(m1)
53+:call matchdelete(m2)
54+:call matchdelete(m3)
55+:unlet m1
56+:unlet m2
57+:unlet m3
58+:if getmatches() == []
59+: let @r .= "OK\n"
60+:else
61+: let @r .= "FAILED\n"
62+:endif
63+:" --- Check that "matchdelete()" returns 0 if succesfull and otherwise -1.
64+:let @r .= "*** Test 6: "
65+:let m = matchadd("MyGroup1", "TODO")
66+:let r1 = matchdelete(m)
67+:let r2 = matchdelete(42)
68+:if r1 == 0 && r2 == -1
69+: let @r .= "OK\n"
70+:else
71+: let @r .= "FAILED\n"
72+:endif
73+:unlet m
74+:unlet r1
75+:unlet r2
76+:" --- Check that "clearmatches()" clears all matches defined by ":match" and
77+:" --- "matchadd()".
78+:let @r .= "*** Test 7: "
79+:let m1 = matchadd("MyGroup1", "TODO")
80+:let m2 = matchadd("MyGroup2", "FIXME", 42)
81+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
82+:match MyGroup1 /COFFEE/
83+:2match MyGroup2 /HUMPPA/
84+:3match MyGroup3 /VIM/
85+:call clearmatches()
86+:if getmatches() == []
87+: let @r .= "OK\n"
88+:else
89+: let @r .= "FAILED\n"
90+:endif
91+:unlet m1
92+:unlet m2
93+:unlet m3
94+:" --- Check that "setmatches()" restores a list of matches saved by
95+:" --- "getmatches()" without changes. (Matches with equal priority must also
96+:" --- remain in the same order.)
97+:let @r .= "*** Test 8: "
98+:let m1 = matchadd("MyGroup1", "TODO")
99+:let m2 = matchadd("MyGroup2", "FIXME", 42)
100+:let m3 = matchadd("MyGroup3", "XXX", 60, 17)
101+:match MyGroup1 /COFFEE/
102+:2match MyGroup2 /HUMPPA/
103+:3match MyGroup3 /VIM/
104+:let ml = getmatches()
105+:call clearmatches()
106+:call setmatches(ml)
107+:if getmatches() == ml
108+: let @r .= "OK\n"
109+:else
110+: let @r .= "FAILED\n"
111+:endif
112+:call clearmatches()
113+:unlet m1
114+:unlet m2
115+:unlet m3
116+:unlet ml
117+:" --- Check that "setmatches()" will not add two matches with the same ID. The
118+:" --- expected behaviour (for now) is to add the first match but not the
119+:" --- second and to return 0 (even though it is a matter of debate whether
120+:" --- this can be considered succesfull behaviour).
121+:let @r .= "*** Test 9: "
122+:let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
123+:if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
124+: let @r .= "OK\n"
125+:else
126+: let @r .= "FAILED\n"
127+:endif
128+:call clearmatches()
129+:unlet r1
130+:" --- Check that "setmatches()" returns 0 if succesfull and otherwise -1.
131+:" --- (A range of valid and invalid input values are tried out to generate the
132+:" --- return values.)
133+:let @r .= "*** Test 10: "
134+:let rs1 = setmatches([])
135+:let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
136+:call clearmatches()
137+:let rf1 = setmatches(0)
138+:let rf2 = setmatches([0])
139+:let rf3 = setmatches([{'wrong key': 'wrong value'}])
140+:if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
141+: let @r .= "OK\n"
142+:else
143+: let @r .= "FAILED\n"
144+:endif
145+:unlet rs1
146+:unlet rs2
147+:unlet rf1
148+:unlet rf2
149+:unlet rf3
150+:highlight clear MyGroup1
151+:highlight clear MyGroup2
152+:highlight clear MyGroup3
153+G"rp
154+:/^Results/,$wq! test.out
155+ENDTEST
156+
157+Results of test63:
diff -r f26d0c74a329 -r 22886f3d882d src/testdir/test63.ok
--- a/src/testdir/test63.ok Wed Jul 25 20:56:39 2007 +0000
+++ b/src/testdir/test63.ok Thu Jul 26 20:58:42 2007 +0000
@@ -0,0 +1,11 @@
1+Results of test63:
2+*** Test 1: OK
3+*** Test 2: OK
4+*** Test 3: OK
5+*** Test 4: OK
6+*** Test 5: OK
7+*** Test 6: OK
8+*** Test 7: OK
9+*** Test 8: OK
10+*** Test 9: OK
11+*** Test 10: OK
diff -r f26d0c74a329 -r 22886f3d882d src/version.c
--- a/src/version.c Wed Jul 25 20:56:39 2007 +0000
+++ b/src/version.c Thu Jul 26 20:58:42 2007 +0000
@@ -667,6 +667,8 @@
667667 static int included_patches[] =
668668 { /* Add new patch number below this line */
669669 /**/
670+ 40,
671+/**/
670672 39,
671673 /**/
672674 38,
diff -r f26d0c74a329 -r 22886f3d882d src/window.c
--- a/src/window.c Wed Jul 25 20:56:39 2007 +0000
+++ b/src/window.c Thu Jul 26 20:58:42 2007 +0000
@@ -75,6 +75,7 @@
7575 static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
7676
7777 #endif /* FEAT_WINDOWS */
78+
7879 static win_T *win_alloc __ARGS((win_T *after));
7980 static void win_new_height __ARGS((win_T *, int));
8081
@@ -4128,6 +4129,10 @@
41284129 #ifdef FEAT_AUTOCMD
41294130 --autocmd_block;
41304131 #endif
4132+#ifdef FEAT_SEARCH_EXTRA
4133+ newwin->w_match_head = NULL;
4134+ newwin->w_next_match_id = 4;
4135+#endif
41314136 }
41324137 return newwin;
41334138 }
@@ -4185,11 +4190,11 @@
41854190 vim_free(wp->w_tagstack[i].tagname);
41864191
41874192 vim_free(wp->w_localdir);
4193+
41884194 #ifdef FEAT_SEARCH_EXTRA
4189- vim_free(wp->w_match[0].regprog);
4190- vim_free(wp->w_match[1].regprog);
4191- vim_free(wp->w_match[2].regprog);
4192-#endif
4195+ clear_matches(wp);
4196+#endif
4197+
41934198 #ifdef FEAT_JUMPLIST
41944199 free_jumplist(wp);
41954200 #endif
@@ -6174,3 +6179,173 @@
61746179 return FALSE;
61756180 }
61766181 #endif
6182+
6183+#if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
6184+/*
6185+ * Add match to the match list of window 'wp'. The pattern 'pat' will be
6186+ * highligted with the group 'grp' with priority 'prio'.
6187+ * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
6188+ * If no particular ID is desired, -1 must be specified for 'id'.
6189+ * Return ID of added match, -1 on failure.
6190+ */
6191+ int
6192+match_add(wp, grp, pat, prio, id)
6193+ win_T *wp;
6194+ char_u *grp;
6195+ char_u *pat;
6196+ int prio;
6197+ int id;
6198+{
6199+ matchitem_T *cur;
6200+ matchitem_T *prev;
6201+ matchitem_T *m;
6202+ int hlg_id;
6203+ regmmatch_T match;
6204+
6205+ if (*grp == NUL || *pat == NUL)
6206+ return -1;
6207+ if (id < -1 || id == 0)
6208+ {
6209+ EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
6210+ return -1;
6211+ }
6212+ if (id != -1)
6213+ {
6214+ cur = wp->w_match_head;
6215+ while (cur != NULL)
6216+ {
6217+ if (cur->id == id)
6218+ {
6219+ EMSGN("E801: ID already taken: %ld", id);
6220+ return -1;
6221+ }
6222+ cur = cur->next;
6223+ }
6224+ }
6225+ if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
6226+ {
6227+ EMSG2(_(e_nogroup), grp);
6228+ return -1;
6229+ }
6230+ if ((match.regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
6231+ {
6232+ EMSG2(_(e_invarg2), pat);
6233+ return -1;
6234+ }
6235+
6236+ /* Find available match ID. */
6237+ while (id == -1)
6238+ {
6239+ cur = wp->w_match_head;
6240+ while (cur != NULL && cur->id != wp->w_next_match_id)
6241+ cur = cur->next;
6242+ if (cur == NULL)
6243+ id = wp->w_next_match_id;
6244+ wp->w_next_match_id++;
6245+ }
6246+
6247+ /* Build new match. */
6248+ m = (matchitem_T *)alloc(sizeof(matchitem_T));
6249+ m->id = id;
6250+ m->priority = prio;
6251+ m->pattern = vim_strsave(pat);
6252+ m->hlg_id = hlg_id;
6253+ m->match.regprog = match.regprog;
6254+
6255+ /* Insert new match. The match list is in ascending order with regard to
6256+ * the match priorities. */
6257+ cur = wp->w_match_head;
6258+ prev = cur;
6259+ while (cur != NULL && prio >= cur->priority)
6260+ {
6261+ prev = cur;
6262+ cur = cur->next;
6263+ }
6264+ if (cur == prev)
6265+ wp->w_match_head = m;
6266+ else
6267+ prev->next = m;
6268+ m->next = cur;
6269+
6270+ redraw_later(SOME_VALID);
6271+ return id;
6272+}
6273+
6274+/*
6275+ * Delete match with ID 'id' in the match list of window 'wp'.
6276+ * Print error messages if 'perr' is TRUE.
6277+ */
6278+ int
6279+match_delete(wp, id, perr)
6280+ win_T *wp;
6281+ int id;
6282+ int perr;
6283+{
6284+ matchitem_T *cur = wp->w_match_head;
6285+ matchitem_T *prev = cur;
6286+
6287+ if (id < 1)
6288+ {
6289+ if (perr == TRUE)
6290+ EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
6291+ id);
6292+ return -1;
6293+ }
6294+ while (cur != NULL && cur->id != id)
6295+ {
6296+ prev = cur;
6297+ cur = cur->next;
6298+ }
6299+ if (cur == NULL)
6300+ {
6301+ if (perr == TRUE)
6302+ EMSGN("E803: ID not found: %ld", id);
6303+ return -1;
6304+ }
6305+ if (cur == prev)
6306+ wp->w_match_head = cur->next;
6307+ else
6308+ prev->next = cur->next;
6309+ vim_free(cur->match.regprog);
6310+ vim_free(cur->pattern);
6311+ vim_free(cur);
6312+ redraw_later(SOME_VALID);
6313+ return 0;
6314+}
6315+
6316+/*
6317+ * Delete all matches in the match list of window 'wp'.
6318+ */
6319+ void
6320+clear_matches(wp)
6321+ win_T *wp;
6322+{
6323+ matchitem_T *m;
6324+
6325+ while (wp->w_match_head != NULL)
6326+ {
6327+ m = wp->w_match_head->next;
6328+ vim_free(wp->w_match_head->match.regprog);
6329+ vim_free(wp->w_match_head->pattern);
6330+ vim_free(wp->w_match_head);
6331+ wp->w_match_head = m;
6332+ }
6333+ redraw_later(SOME_VALID);
6334+}
6335+
6336+/*
6337+ * Get match from ID 'id' in window 'wp'.
6338+ * Return NULL if match not found.
6339+ */
6340+ matchitem_T *
6341+get_match(wp, id)
6342+ win_T *wp;
6343+ int id;
6344+{
6345+ matchitem_T *cur = wp->w_match_head;
6346+
6347+ while (cur != NULL && cur->id != id)
6348+ cur = cur->next;
6349+ return cur;
6350+}
6351+#endif
Show on old repository browser