4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=ISO-8859-1
7 Content-Transfer-Encoding: 8bit
11 Problem: ":match" only supports three matches.
12 Solution: Add functions clearmatches(), getmatches(), matchadd(),
13 matchdelete() and setmatches(). Changed the data structures for
14 this. A small bug in syntax.c is fixed, so newly created
15 highlight groups can have their name resolved correctly from their
17 Files: runtime/doc/eval.txt, runtime/doc/pattern.txt,
18 runtime/doc/usr_41.txt, src/eval.c, src/ex_docmd.c,
19 src/proto/window.pro, src/screen.c, src/structs.h, src/syntax.c,
20 src/testdir/Makefile, src/testdir/test63.in,
21 src/testdir/test63.ok, src/window.c
24 *** ../vim-7.1.039/runtime/doc/eval.txt Tue Jul 17 16:31:15 2007
25 --- runtime/doc/eval.txt Wed Jul 25 21:05:56 2007
28 ! *eval.txt* For Vim version 7.1. Last change: 2007 Jul 11
31 VIM REFERENCE MANUAL by Bram Moolenaar
33 ! *eval.txt* For Vim version 7.1. Last change: 2007 Jul 25
36 VIM REFERENCE MANUAL by Bram Moolenaar
40 changenr() Number current change number
41 char2nr( {expr}) Number ASCII value of first char in {expr}
42 cindent( {lnum}) Number C indent for line {lnum}
43 + clearmatches() None clear all matches
44 col( {expr}) Number column nr of cursor or mark
45 complete({startcol}, {matches}) String set Insert mode completion
46 complete_add( {expr}) Number add completion match
50 getline( {lnum}) String line {lnum} of current buffer
51 getline( {lnum}, {end}) List lines {lnum} to {end} of current buffer
52 getloclist({nr}) List list of location list items
53 + getmatches() List list of current matches
54 getpos( {expr}) List position of cursor, mark, etc.
55 getqflist() List list of quickfix items
56 getreg( [{regname} [, 1]]) String contents of register
60 String check for mappings matching {name}
61 match( {expr}, {pat}[, {start}[, {count}]])
62 Number position where {pat} matches in {expr}
63 + matchadd( {group}, {pattern}[, {priority}[, {id}]])
64 + Number highlight {pattern} with {group}
65 matcharg( {nr}) List arguments of |:match|
66 + matchdelete( {id}) Number delete match identified by {id}
67 matchend( {expr}, {pat}[, {start}[, {count}]])
68 Number position where {pat} ends in {expr}
69 matchlist( {expr}, {pat}[, {start}[, {count}]])
73 setline( {lnum}, {line}) Number set line {lnum} to {line}
74 setloclist( {nr}, {list}[, {action}])
75 Number modify location list using {list}
76 + setmatches( {list}) Number restore a list of matches
77 setpos( {expr}, {list}) none set the {expr} position to {list}
78 setqflist( {list}[, {action}]) Number modify quickfix list using {list}
79 setreg( {n}, {v}[, {opt}]) Number set register to value and type
83 feature, -1 is returned.
86 + clearmatches() *clearmatches()*
87 + Clears all matches previously defined by |matchadd()| and the
91 col({expr}) The result is a Number, which is the byte index of the column
92 position given with {expr}. The accepted positions are:
96 returned. For an invalid window number {nr}, an empty list is
97 returned. Otherwise, same as getqflist().
99 + getmatches() *getmatches()*
100 + Returns a |List| with all matches previously defined by
101 + |matchadd()| and the |:match| commands. |getmatches()| is
102 + useful in combination with |setmatches()|, as |setmatches()|
103 + can restore a list of matches saved by |getmatches()|.
106 + < [{'group': 'MyGroup1', 'pattern': 'TODO',
107 + 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
108 + 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
109 + :let m = getmatches()
110 + :call clearmatches()
113 + :call setmatches(m)
115 + < [{'group': 'MyGroup1', 'pattern': 'TODO',
116 + 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
117 + 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
121 getqflist() *getqflist()*
122 Returns a list with all the current quickfix errors. Each
123 list item is a dictionary with these entries:
127 the pattern. 'smartcase' is NOT used. The matching is always
128 done like 'magic' is set and 'cpoptions' is empty.
130 + *matchadd()* *E798* *E799* *E801*
131 + matchadd({group}, {pattern}[, {priority}[, {id}]])
132 + Defines a pattern to be highlighted in the current window (a
133 + "match"). It will be highlighted with {group}. Returns an
134 + identification number (ID), which can be used to delete the
135 + match using |matchdelete()|.
137 + The optional {priority} argument assigns a priority to the
138 + match. A match with a high priority will have its
139 + highlighting overrule that of a match with a lower priority.
140 + A priority is specified as an integer (negative numbers are no
141 + exception). If the {priority} argument is not specified, the
142 + default priority is 10. The priority of 'hlsearch' is zero,
143 + hence all matches with a priority greater than zero will
144 + overrule it. Syntax highlighting (see 'syntax') is a separate
145 + mechanism, and regardless of the chosen priority a match will
146 + always overrule syntax highlighting.
148 + The optional {id} argument allows the request for a specific
149 + match ID. If a specified ID is already taken, an error
150 + message will appear and the match will not be added. An ID
151 + is specified as a positive integer (zero excluded). IDs 1, 2
152 + and 3 are reserved for |:match|, |:2match| and |:3match|,
153 + respectively. If the {id} argument is not specified,
154 + |matchadd()| automatically chooses a free ID.
156 + The number of matches is not limited, as it is the case with
157 + the |:match| commands.
160 + :highlight MyGroup ctermbg=green guibg=green
161 + :let m = matchadd("MyGroup", "TODO")
162 + < Deletion of the pattern: >
163 + :call matchdelete(m)
165 + < A list of matches defined by |matchadd()| and |:match| are
166 + available from |getmatches()|. All matches can be deleted in
167 + one operation by |clearmatches()|.
169 matcharg({nr}) *matcharg()*
170 Selects the {nr} match item, as set with a |:match|,
174 When {nr} is not 1, 2 or 3 returns an empty |List|.
175 When there is no match item set returns ['', ''].
176 ! This is usef to save and restore a |:match|.
179 matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()*
180 Same as match(), but return the index of first character after
183 When {nr} is not 1, 2 or 3 returns an empty |List|.
184 When there is no match item set returns ['', ''].
185 ! This is useful to save and restore a |:match|.
186 ! Highlighting matches using the |:match| commands are limited
187 ! to three matches. |matchadd()| does not have this limitation.
189 ! matchdelete({id}) *matchdelete()* *E802* *E803*
190 ! Deletes a match with ID {id} previously defined by |matchadd()|
191 ! or one of the |:match| commands. Returns 0 if succesfull,
192 ! otherwise -1. See example for |matchadd()|. All matches can
193 ! be deleted in one operation by |clearmatches()|.
195 matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()*
196 Same as match(), but return the index of first character after
199 When {nr} is zero the current window is used. For a location
200 list window, the displayed location list is modified. For an
201 invalid window number {nr}, -1 is returned.
202 ! Otherwise, same as setqflist().
205 setpos({expr}, {list})
207 When {nr} is zero the current window is used. For a location
208 list window, the displayed location list is modified. For an
209 invalid window number {nr}, -1 is returned.
210 ! Otherwise, same as |setqflist()|.
211 ! Also see |location-list|.
213 ! setmatches({list}) *setmatches()*
214 ! Restores a list of matches saved by |getmatches()|. Returns 0
215 ! if succesfull, otherwise -1. All current matches are cleared
216 ! before the list is restored. See example for |getmatches()|.
219 setpos({expr}, {list})
220 *** ../vim-7.1.039/runtime/doc/pattern.txt Sat May 12 16:57:31 2007
221 --- runtime/doc/pattern.txt Tue Jul 24 15:47:01 2007
224 {group} must exist at the moment this command is executed.
226 The {group} highlighting still applies when a character is
227 ! to be highlighted for 'hlsearch'.
229 Note that highlighting the last used search pattern with
230 'hlsearch' is used in all windows, while the pattern defined
232 {group} must exist at the moment this command is executed.
234 The {group} highlighting still applies when a character is
235 ! to be highlighted for 'hlsearch', as the highlighting for
236 ! matches is given higher priority than that of 'hlsearch'.
237 ! Syntax highlighting (see 'syntax') is also overruled by
240 Note that highlighting the last used search pattern with
241 'hlsearch' is used in all windows, while the pattern defined
244 display you may get unexpected results. That is because Vim
245 looks for a match in the line where redrawing starts.
247 ! Also see |matcharg()|, it returns the highlight group and
248 ! pattern of a previous :match command.
250 Another example, which highlights all characters in virtual
251 column 72 and more: >
253 display you may get unexpected results. That is because Vim
254 looks for a match in the line where redrawing starts.
256 ! Also see |matcharg()|and |getmatches()|. The former returns
257 ! the highlight group and pattern of a previous |:match|
258 ! command. The latter returns a list with highlight groups and
259 ! patterns defined by both |matchadd()| and |:match|.
261 ! Highlighting matches using |:match| are limited to three
262 ! matches (aside from |:match|, |:2match| and |:3match|are
263 ! available). |matchadd()| does not have this limitation and in
264 ! addition makes it possible to prioritize matches.
266 Another example, which highlights all characters in virtual
267 column 72 and more: >
268 *** ../vim-7.1.039/runtime/doc/usr_41.txt Sat May 12 15:54:55 2007
269 --- runtime/doc/usr_41.txt Tue Jul 24 15:47:01 2007
273 foldtextresult() get the text displayed for a closed fold
275 Syntax and highlighting:
276 + clearmatches() clear all matches defined by |matchadd()| and
277 + the |:match| commands
278 + getmatches() get all matches defined by |matchadd()| and
279 + the |:match| commands
280 hlexists() check if a highlight group exists
281 hlID() get ID of a highlight group
282 synID() get syntax ID at a specific position
283 synIDattr() get a specific attribute of a syntax ID
284 synIDtrans() get translated syntax ID
285 diff_hlID() get highlight ID for diff mode at a position
286 + matchadd() define a pattern to highlight (a "match")
287 matcharg() get info about |:match| arguments
288 + matchdelete() delete a match defined by |matchadd()| or a
290 + setmatches() restore a list of matches saved by
294 spellbadword() locate badly spelled word at or after cursor
295 *** ../vim-7.1.039/src/eval.c Tue Jul 24 14:32:44 2007
296 --- src/eval.c Tue Jul 24 20:40:52 2007
300 static void f_changenr __ARGS((typval_T *argvars, typval_T *rettv));
301 static void f_char2nr __ARGS((typval_T *argvars, typval_T *rettv));
302 static void f_cindent __ARGS((typval_T *argvars, typval_T *rettv));
303 + static void f_clearmatches __ARGS((typval_T *argvars, typval_T *rettv));
304 static void f_col __ARGS((typval_T *argvars, typval_T *rettv));
305 #if defined(FEAT_INS_EXPAND)
306 static void f_complete __ARGS((typval_T *argvars, typval_T *rettv));
310 static void f_getftime __ARGS((typval_T *argvars, typval_T *rettv));
311 static void f_getftype __ARGS((typval_T *argvars, typval_T *rettv));
312 static void f_getline __ARGS((typval_T *argvars, typval_T *rettv));
313 + static void f_getmatches __ARGS((typval_T *argvars, typval_T *rettv));
314 static void f_getpos __ARGS((typval_T *argvars, typval_T *rettv));
315 static void f_getqflist __ARGS((typval_T *argvars, typval_T *rettv));
316 static void f_getreg __ARGS((typval_T *argvars, typval_T *rettv));
320 static void f_maparg __ARGS((typval_T *argvars, typval_T *rettv));
321 static void f_mapcheck __ARGS((typval_T *argvars, typval_T *rettv));
322 static void f_match __ARGS((typval_T *argvars, typval_T *rettv));
323 + static void f_matchadd __ARGS((typval_T *argvars, typval_T *rettv));
324 static void f_matcharg __ARGS((typval_T *argvars, typval_T *rettv));
325 + static void f_matchdelete __ARGS((typval_T *argvars, typval_T *rettv));
326 static void f_matchend __ARGS((typval_T *argvars, typval_T *rettv));
327 static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
328 static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
332 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv));
333 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv));
334 static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv));
335 + static void f_setmatches __ARGS((typval_T *argvars, typval_T *rettv));
336 static void f_setpos __ARGS((typval_T *argvars, typval_T *rettv));
337 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv));
338 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv));
342 {"changenr", 0, 0, f_changenr},
343 {"char2nr", 1, 1, f_char2nr},
344 {"cindent", 1, 1, f_cindent},
345 + {"clearmatches", 0, 0, f_clearmatches},
346 {"col", 1, 1, f_col},
347 #if defined(FEAT_INS_EXPAND)
348 {"complete", 2, 2, f_complete},
352 {"getftype", 1, 1, f_getftype},
353 {"getline", 1, 2, f_getline},
354 {"getloclist", 1, 1, f_getqflist},
355 + {"getmatches", 0, 0, f_getmatches},
356 {"getpos", 1, 1, f_getpos},
357 {"getqflist", 0, 0, f_getqflist},
358 {"getreg", 0, 2, f_getreg},
362 {"maparg", 1, 3, f_maparg},
363 {"mapcheck", 1, 3, f_mapcheck},
364 {"match", 2, 4, f_match},
365 + {"matchadd", 2, 4, f_matchadd},
366 {"matcharg", 1, 1, f_matcharg},
367 + {"matchdelete", 1, 1, f_matchdelete},
368 {"matchend", 2, 4, f_matchend},
369 {"matchlist", 2, 4, f_matchlist},
370 {"matchstr", 2, 4, f_matchstr},
374 {"setcmdpos", 1, 1, f_setcmdpos},
375 {"setline", 2, 2, f_setline},
376 {"setloclist", 2, 3, f_setloclist},
377 + {"setmatches", 1, 1, f_setmatches},
378 {"setpos", 2, 2, f_setpos},
379 {"setqflist", 1, 2, f_setqflist},
380 {"setreg", 2, 3, f_setreg},
387 + * "clearmatches()" function
391 + f_clearmatches(argvars, rettv)
395 + #ifdef FEAT_SEARCH_EXTRA
396 + clear_matches(curwin);
401 * "col(string)" function
410 + * "getmatches()" function
414 + f_getmatches(argvars, rettv)
418 + #ifdef FEAT_SEARCH_EXTRA
420 + matchitem_T *cur = curwin->w_match_head;
422 + rettv->vval.v_number = 0;
424 + if (rettv_list_alloc(rettv) == OK)
426 + while (cur != NULL)
428 + dict = dict_alloc();
431 + ++dict->dv_refcount;
432 + dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
433 + dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
434 + dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
435 + dict_add_nr_str(dict, "id", (long)cur->id, NULL);
436 + list_append_dict(rettv->vval.v_list, dict);
444 * "getpos(string)" function
453 + * "matchadd()" function
456 + f_matchadd(argvars, rettv)
460 + #ifdef FEAT_SEARCH_EXTRA
461 + char_u buf[NUMBUFLEN];
462 + char_u *grp = get_tv_string_buf_chk(&argvars[0], buf); /* group */
463 + char_u *pat = get_tv_string_buf_chk(&argvars[1], buf); /* pattern */
464 + int prio = 10; /* default priority */
468 + rettv->vval.v_number = -1;
470 + if (grp == NULL || pat == NULL)
472 + if (argvars[2].v_type != VAR_UNKNOWN)
473 + prio = get_tv_number_chk(&argvars[2], &error);
474 + if (argvars[3].v_type != VAR_UNKNOWN)
475 + id = get_tv_number_chk(&argvars[3], &error);
478 + if (id >= 1 && id <= 3)
480 + EMSGN("E798: ID is reserved for \":match\": %ld", id);
484 + rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
489 * "matcharg()" function
494 if (rettv_list_alloc(rettv) == OK)
496 #ifdef FEAT_SEARCH_EXTRA
497 ! int mi = get_tv_number(&argvars[0]);
499 ! if (mi >= 1 && mi <= 3)
501 ! list_append_string(rettv->vval.v_list,
502 ! syn_id2name(curwin->w_match_id[mi - 1]), -1);
503 ! list_append_string(rettv->vval.v_list,
504 ! curwin->w_match_pat[mi - 1], -1);
511 * "matchend()" function
515 if (rettv_list_alloc(rettv) == OK)
517 #ifdef FEAT_SEARCH_EXTRA
518 ! int id = get_tv_number(&argvars[0]);
521 ! if (id >= 1 && id <= 3)
523 ! if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
525 ! list_append_string(rettv->vval.v_list,
526 ! syn_id2name(m->hlg_id), -1);
527 ! list_append_string(rettv->vval.v_list, m->pattern, -1);
531 ! list_append_string(rettv->vval.v_list, NUL, -1);
532 ! list_append_string(rettv->vval.v_list, NUL, -1);
540 + * "matchdelete()" function
543 + f_matchdelete(argvars, rettv)
547 + #ifdef FEAT_SEARCH_EXTRA
548 + rettv->vval.v_number = match_delete(curwin,
549 + (int)get_tv_number(&argvars[0]), TRUE);
554 * "matchend()" function
560 win = find_win_by_nr(&argvars[0], NULL);
562 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
566 + * "setmatches()" function
569 + f_setmatches(argvars, rettv)
573 + #ifdef FEAT_SEARCH_EXTRA
578 + rettv->vval.v_number = -1;
579 + if (argvars[0].v_type != VAR_LIST)
581 + EMSG(_(e_listreq));
584 + if ((l = argvars[0].vval.v_list) != NULL)
587 + /* To some extent make sure that we are dealing with a list from
588 + * "getmatches()". */
592 + if (li->li_tv.v_type != VAR_DICT
593 + || (d = li->li_tv.vval.v_dict) == NULL)
598 + if (!(dict_find(d, (char_u *)"group", -1) != NULL
599 + && dict_find(d, (char_u *)"pattern", -1) != NULL
600 + && dict_find(d, (char_u *)"priority", -1) != NULL
601 + && dict_find(d, (char_u *)"id", -1) != NULL))
609 + clear_matches(curwin);
613 + d = li->li_tv.vval.v_dict;
614 + match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
615 + get_dict_string(d, (char_u *)"pattern", FALSE),
616 + (int)get_dict_number(d, (char_u *)"priority"),
617 + (int)get_dict_number(d, (char_u *)"id"));
620 + rettv->vval.v_number = 0;
626 *** ../vim-7.1.039/src/ex_docmd.c Tue Jul 24 14:32:44 2007
627 --- src/ex_docmd.c Tue Jul 24 15:47:01 2007
638 ! mi = eap->line2 - 1;
659 /* First clear any old pattern. */
662 ! vim_free(curwin->w_match[mi].regprog);
663 ! curwin->w_match[mi].regprog = NULL;
664 ! vim_free(curwin->w_match_pat[mi]);
665 ! curwin->w_match_pat[mi] = NULL;
666 ! redraw_later(SOME_VALID); /* always need a redraw */
669 if (ends_excmd(*eap->arg))
673 /* First clear any old pattern. */
675 ! match_delete(curwin, id, FALSE);
677 if (ends_excmd(*eap->arg))
682 p = skiptowhite(eap->arg);
685 ! curwin->w_match_id[mi] = syn_namen2id(eap->arg,
686 ! (int)(p - eap->arg));
687 ! if (curwin->w_match_id[mi] == 0)
689 ! EMSG2(_(e_nogroup), eap->arg);
698 p = skiptowhite(eap->arg);
700 ! g = vim_strnsave(eap->arg, (int)(p - eap->arg));
709 ! curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
710 ! if (curwin->w_match[mi].regprog == NULL)
712 ! EMSG2(_(e_invarg2), p);
716 ! curwin->w_match_pat[mi] = vim_strsave(p + 1);
724 ! match_add(curwin, g, p + 1, 10, id);
729 *** ../vim-7.1.039/src/proto/window.pro Sat May 5 19:52:36 2007
730 --- src/proto/window.pro Tue Jul 24 16:38:19 2007
734 int only_one_window __ARGS((void));
735 void check_lnums __ARGS((int do_curwin));
736 int win_hasvertsplit __ARGS((void));
737 + int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
738 + int match_delete __ARGS((win_T *wp, int id, int perr));
739 + void clear_matches __ARGS((win_T *wp));
740 + matchitem_T *get_match __ARGS((win_T *wp, int id));
741 /* vim: set ft=c : */
742 *** ../vim-7.1.039/src/screen.c Tue Jun 19 17:49:12 2007
743 --- src/screen.c Thu Jul 26 21:55:40 2007
746 static int screen_cur_row, screen_cur_col; /* last known cursor position */
748 #ifdef FEAT_SEARCH_EXTRA
750 - * Struct used for highlighting 'hlsearch' matches for the last use search
751 - * pattern or a ":match" item.
752 - * For 'hlsearch' there is one pattern for all windows. For ":match" there is
753 - * a different pattern for each window.
757 - regmmatch_T rm; /* points to the regexp program; contains last found
758 - match (may continue in next line) */
759 - buf_T *buf; /* the buffer to search for a match */
760 - linenr_T lnum; /* the line to search for a match */
761 - int attr; /* attributes to be used for a match */
762 - int attr_cur; /* attributes currently active in win_line() */
763 - linenr_T first_lnum; /* first lnum to search for multi-line pat */
764 - colnr_T startcol; /* in win_line() points to char where HL starts */
765 - colnr_T endcol; /* in win_line() points to char where HL ends */
768 static match_T search_hl; /* used for 'hlsearch' highlight matching */
769 - static match_T match_hl[3]; /* used for ":match" highlight matching */
777 static void redraw_custum_statusline __ARGS((win_T *wp));
779 #ifdef FEAT_SEARCH_EXTRA
780 + #define SEARCH_HL_PRIORITY 0
781 static void start_search_hl __ARGS((void));
782 static void end_search_hl __ARGS((void));
783 static void prepare_search_hl __ARGS((win_T *wp, linenr_T lnum));
787 w_topline got smaller a bit */
789 #ifdef FEAT_SEARCH_EXTRA
790 + matchitem_T *cur; /* points to the match list */
791 int top_to_mod = FALSE; /* redraw above mod_top */
798 #ifdef FEAT_SEARCH_EXTRA
799 ! /* Setup for ":match" and 'hlsearch' highlighting. Disable any previous
801 ! for (i = 0; i < 3; ++i)
803 ! match_hl[i].rm = wp->w_match[i];
804 ! if (wp->w_match_id[i] == 0)
805 ! match_hl[i].attr = 0;
807 ! match_hl[i].attr = syn_id2attr(wp->w_match_id[i]);
808 ! match_hl[i].buf = buf;
809 ! match_hl[i].lnum = 0;
810 ! match_hl[i].first_lnum = 0;
817 #ifdef FEAT_SEARCH_EXTRA
818 ! /* Setup for match and 'hlsearch' highlighting. Disable any previous
820 ! cur = wp->w_match_head;
821 ! while (cur != NULL)
823 ! cur->hl.rm = cur->match;
824 ! if (cur->hlg_id == 0)
827 ! cur->hl.attr = syn_id2attr(cur->hlg_id);
830 ! cur->hl.first_lnum = 0;
837 * change in one line may make the Search highlighting in a
838 * previous line invalid. Simple solution: redraw all visible
839 * lines above the change.
840 ! * Same for a ":match" pattern.
842 if (search_hl.rm.regprog != NULL
843 && re_multiline(search_hl.rm.regprog))
846 ! for (i = 0; i < 3; ++i)
847 ! if (match_hl[i].rm.regprog != NULL
848 ! && re_multiline(match_hl[i].rm.regprog))
857 * change in one line may make the Search highlighting in a
858 * previous line invalid. Simple solution: redraw all visible
859 * lines above the change.
860 ! * Same for a match pattern.
862 if (search_hl.rm.regprog != NULL
863 && re_multiline(search_hl.rm.regprog))
867 ! cur = wp->w_match_head;
868 ! while (cur != NULL)
870 ! if (cur->match.regprog != NULL
871 ! && re_multiline(cur->match.regprog))
884 int line_attr = 0; /* atrribute for the whole line */
886 #ifdef FEAT_SEARCH_EXTRA
887 ! match_T *shl; /* points to search_hl or match_hl */
889 ! #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
893 int prev_c = 0; /* previous Arabic character */
895 int line_attr = 0; /* atrribute for the whole line */
897 #ifdef FEAT_SEARCH_EXTRA
898 ! matchitem_T *cur; /* points to the match list */
899 ! match_T *shl; /* points to search_hl or a match */
900 ! int shl_flag; /* flag to indicate whether search_hl
901 ! has been processed or not */
902 ! int prevcol_hl_flag; /* flag to indicate whether prevcol
903 ! equals startcol of search_hl or one
907 int prev_c = 0; /* previous Arabic character */
911 #ifdef FEAT_SEARCH_EXTRA
913 ! * Handle highlighting the last used search pattern and ":match".
914 ! * Do this for both search_hl and match_hl[3].
916 ! for (i = 3; i >= 0; --i)
918 ! shl = (i == 3) ? &search_hl : &match_hl[i];
919 shl->startcol = MAXCOL;
920 shl->endcol = MAXCOL;
924 #ifdef FEAT_SEARCH_EXTRA
926 ! * Handle highlighting the last used search pattern and matches.
927 ! * Do this for both search_hl and the match list.
929 ! cur = wp->w_match_head;
931 ! while (cur != NULL || shl_flag == FALSE)
933 ! if (shl_flag == FALSE)
940 shl->startcol = MAXCOL;
941 shl->endcol = MAXCOL;
946 area_highlighting = TRUE;
949 + if (shl != &search_hl && cur != NULL)
956 * After end, check for start/end of next match.
957 * When another match, have to check for start again.
958 * Watch out for matching an empty string!
959 ! * Do this first for search_hl, then for match_hl, so that
960 ! * ":match" overrules 'hlsearch'.
962 v = (long)(ptr - line);
963 ! for (i = 3; i >= 0; --i)
965 ! shl = (i == 3) ? &search_hl : &match_hl[i];
966 while (shl->rm.regprog != NULL)
968 if (shl->startcol != MAXCOL
970 * After end, check for start/end of next match.
971 * When another match, have to check for start again.
972 * Watch out for matching an empty string!
973 ! * Do this for 'search_hl' and the match list (ordered by
976 v = (long)(ptr - line);
977 ! cur = wp->w_match_head;
979 ! while (cur != NULL || shl_flag == FALSE)
981 ! if (shl_flag == FALSE
983 ! && cur->priority > SEARCH_HL_PRIORITY)
991 while (shl->rm.regprog != NULL)
993 if (shl->startcol != MAXCOL
1001 ! /* ":match" highlighting overrules 'hlsearch' */
1002 ! for (i = 0; i <= 3; ++i)
1004 ! search_attr = search_hl.attr_cur;
1005 ! else if (match_hl[i].attr_cur != 0)
1007 ! search_attr = match_hl[i].attr_cur;
1017 + if (shl != &search_hl && cur != NULL)
1021 ! /* Use attributes from match with highest priority among
1022 ! * 'search_hl' and the match list. */
1023 ! search_attr = search_hl.attr_cur;
1024 ! cur = wp->w_match_head;
1026 ! while (cur != NULL || shl_flag == FALSE)
1028 ! if (shl_flag == FALSE
1030 ! && cur->priority > SEARCH_HL_PRIORITY)
1038 + if (shl->attr_cur != 0)
1039 + search_attr = shl->attr_cur;
1040 + if (shl != &search_hl && cur != NULL)
1049 * Draw it as a space with a composing char. */
1050 if (utf_iscomposing(mb_c))
1054 for (i = Screen_mco - 1; i > 0; --i)
1055 u8cc[i] = u8cc[i - 1];
1059 * highlight match at end of line. If it's beyond the last
1060 * char on the screen, just overwrite that one (tricky!) Not
1061 * needed when a '$' was displayed for 'list'. */
1062 if (lcs_eol == lcs_eol_one
1063 && ((area_attr != 0 && vcol == fromcol && c == NUL)
1064 #ifdef FEAT_SEARCH_EXTRA
1065 /* highlight 'hlsearch' match at end of line */
1066 ! || ((prevcol == (long)search_hl.startcol
1067 ! || prevcol == (long)match_hl[0].startcol
1068 ! || prevcol == (long)match_hl[1].startcol
1069 ! || prevcol == (long)match_hl[2].startcol)
1070 # if defined(LINE_ATTR)
1071 && did_line_attr <= 1
1074 * highlight match at end of line. If it's beyond the last
1075 * char on the screen, just overwrite that one (tricky!) Not
1076 * needed when a '$' was displayed for 'list'. */
1077 + #ifdef FEAT_SEARCH_EXTRA
1078 + prevcol_hl_flag = FALSE;
1079 + if (prevcol == (long)search_hl.startcol)
1080 + prevcol_hl_flag = TRUE;
1083 + cur = wp->w_match_head;
1084 + while (cur != NULL)
1086 + if (prevcol == (long)cur->hl.startcol)
1088 + prevcol_hl_flag = TRUE;
1095 if (lcs_eol == lcs_eol_one
1096 && ((area_attr != 0 && vcol == fromcol && c == NUL)
1097 #ifdef FEAT_SEARCH_EXTRA
1098 /* highlight 'hlsearch' match at end of line */
1099 ! || (prevcol_hl_flag == TRUE
1100 # if defined(LINE_ATTR)
1101 && did_line_attr <= 1
1105 #ifdef FEAT_SEARCH_EXTRA
1108 ! for (i = 0; i <= 3; ++i)
1111 ! char_attr = search_hl.attr;
1112 ! else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
1114 ! char_attr = match_hl[i].attr;
1121 #ifdef FEAT_SEARCH_EXTRA
1124 ! /* Use attributes from match with highest priority among
1125 ! * 'search_hl' and the match list. */
1126 ! char_attr = search_hl.attr;
1127 ! cur = wp->w_match_head;
1129 ! while (cur != NULL || shl_flag == FALSE)
1131 ! if (shl_flag == FALSE
1133 ! && cur->priority > SEARCH_HL_PRIORITY)
1141 + if ((ptr - line) - 1 == (long)shl->startcol)
1142 + char_attr = shl->attr;
1143 + if (shl != &search_hl && cur != NULL)
1156 ScreenLinesUC[off] = mb_c;
1157 if ((c & 0xff) == 0)
1158 ScreenLines[off] = 0x80; /* avoid storing zero */
1162 #ifdef FEAT_SEARCH_EXTRA
1164 ! * Prepare for 'searchhl' highlighting.
1170 #ifdef FEAT_SEARCH_EXTRA
1172 ! * Prepare for 'hlsearch' highlighting.
1181 ! * Clean up for 'searchhl' highlighting.
1189 ! * Clean up for 'hlsearch' highlighting.
1198 ! match_T *shl; /* points to search_hl or match_hl */
1203 * When using a multi-line pattern, start searching at the top
1204 * of the window or just after a closed fold.
1205 ! * Do this both for search_hl and match_hl[3].
1207 ! for (i = 3; i >= 0; --i)
1209 ! shl = (i == 3) ? &search_hl : &match_hl[i];
1210 if (shl->rm.regprog != NULL
1212 && re_multiline(shl->rm.regprog))
1217 ! matchitem_T *cur; /* points to the match list */
1218 ! match_T *shl; /* points to search_hl or a match */
1219 ! int shl_flag; /* flag to indicate whether search_hl
1220 ! has been processed or not */
1224 * When using a multi-line pattern, start searching at the top
1225 * of the window or just after a closed fold.
1226 ! * Do this both for search_hl and the match list.
1228 ! cur = wp->w_match_head;
1230 ! while (cur != NULL || shl_flag == FALSE)
1232 ! if (shl_flag == FALSE)
1239 if (shl->rm.regprog != NULL
1241 && re_multiline(shl->rm.regprog))
1251 ! * Search for a next 'searchl' or ":match" match.
1253 * Sets shl->lnum and shl->rm contents.
1254 * Note: Assumes a previous match is always before "lnum", unless
1259 + if (shl != &search_hl && cur != NULL)
1265 ! * Search for a next 'hlsearch' or match.
1267 * Sets shl->lnum and shl->rm contents.
1268 * Note: Assumes a previous match is always before "lnum", unless
1272 next_search_hl(win, shl, lnum, mincol)
1274 ! match_T *shl; /* points to search_hl or match_hl */
1276 colnr_T mincol; /* minimal column for a match */
1280 next_search_hl(win, shl, lnum, mincol)
1282 ! match_T *shl; /* points to search_hl or a match */
1284 colnr_T mincol; /* minimal column for a match */
1288 /* Error while handling regexp: stop using this regexp. */
1289 if (shl == &search_hl)
1291 ! /* don't free the regprog in match_hl[], it's a copy */
1292 vim_free(shl->rm.regprog);
1296 /* Error while handling regexp: stop using this regexp. */
1297 if (shl == &search_hl)
1299 ! /* don't free regprog in the match list, it's a copy */
1300 vim_free(shl->rm.regprog);
1303 *** ../vim-7.1.039/src/structs.h Thu May 10 20:32:30 2007
1304 --- src/structs.h Wed Jul 25 21:08:46 2007
1308 #define FR_COL 2 /* frame with a column of windows */
1311 + * Struct used for highlighting 'hlsearch' matches, matches defined by
1312 + * ":match" and matches defined by match functions.
1313 + * For 'hlsearch' there is one pattern for all windows. For ":match" and the
1314 + * match functions there is a different pattern for each window.
1318 + regmmatch_T rm; /* points to the regexp program; contains last found
1319 + match (may continue in next line) */
1320 + buf_T *buf; /* the buffer to search for a match */
1321 + linenr_T lnum; /* the line to search for a match */
1322 + int attr; /* attributes to be used for a match */
1323 + int attr_cur; /* attributes currently active in win_line() */
1324 + linenr_T first_lnum; /* first lnum to search for multi-line pat */
1325 + colnr_T startcol; /* in win_line() points to char where HL starts */
1326 + colnr_T endcol; /* in win_line() points to char where HL ends */
1330 + * matchitem_T provides a linked list for storing match items for ":match" and
1331 + * the match functions.
1333 + typedef struct matchitem matchitem_T;
1336 + matchitem_T *next;
1337 + int id; /* match ID */
1338 + int priority; /* match priority */
1339 + char_u *pattern; /* pattern to highlight */
1340 + int hlg_id; /* highlight group ID */
1341 + regmmatch_T match; /* regexp program for pattern */
1342 + match_T hl; /* struct for doing the actual highlighting */
1346 * Structure which contains all information that belongs to a window
1348 * All row numbers are relative to the start of the window, except w_winrow.
1353 #ifdef FEAT_SEARCH_EXTRA
1354 ! regmmatch_T w_match[3]; /* regexp programs for ":match" */
1355 ! char_u *(w_match_pat[3]); /* patterns for ":match" */
1356 ! int w_match_id[3]; /* highlight IDs for ":match" */
1363 #ifdef FEAT_SEARCH_EXTRA
1364 ! matchitem_T *w_match_head; /* head of match list */
1365 ! int w_next_match_id; /* next match ID */
1369 *** ../vim-7.1.039/src/syntax.c Tue Jul 24 14:32:44 2007
1370 --- src/syntax.c Tue Jul 24 15:47:01 2007
1376 ! if (id <= 0 || id >= highlight_ga.ga_len)
1377 return (char_u *)"";
1378 return HL_TABLE()[id - 1].sg_name;
1384 ! if (id <= 0 || id > highlight_ga.ga_len)
1385 return (char_u *)"";
1386 return HL_TABLE()[id - 1].sg_name;
1388 *** ../vim-7.1.039/src/testdir/Makefile Sun Apr 30 20:48:47 2006
1389 --- src/testdir/Makefile Tue Jul 24 15:34:33 2007
1393 ! # Makefile to run al tests for Vim
1399 ! # Makefile to run all tests for Vim
1405 test43.out test44.out test45.out test46.out test47.out \
1406 test48.out test49.out test51.out test52.out test53.out \
1407 test54.out test55.out test56.out test57.out test58.out \
1408 ! test59.out test60.out test61.out test62.out
1410 SCRIPTS_GUI = test16.out
1413 test43.out test44.out test45.out test46.out test47.out \
1414 test48.out test49.out test51.out test52.out test53.out \
1415 test54.out test55.out test56.out test57.out test58.out \
1416 ! test59.out test60.out test61.out test62.out test63.out
1418 SCRIPTS_GUI = test16.out
1420 *** ../vim-7.1.039/src/testdir/test63.in Tue Jul 24 16:45:02 2007
1421 --- src/testdir/test63.in Tue Jul 24 15:32:30 2007
1425 + Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
1426 + "matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
1430 + :" --- Check that "matcharg()" returns the correct group and pattern if a match
1431 + :" --- is defined.
1432 + :let @r = "*** Test 1: "
1433 + :highlight MyGroup1 ctermbg=red
1434 + :highlight MyGroup2 ctermbg=green
1435 + :highlight MyGroup3 ctermbg=blue
1436 + :match MyGroup1 /TODO/
1437 + :2match MyGroup2 /FIXME/
1438 + :3match MyGroup3 /XXX/
1439 + :if matcharg(1) == ['MyGroup1', 'TODO'] && matcharg(2) == ['MyGroup2', 'FIXME'] && matcharg(3) == ['MyGroup3', 'XXX']
1440 + : let @r .= "OK\n"
1442 + : let @r .= "FAILED\n"
1444 + :" --- Check that "matcharg()" returns an empty list if the argument is not 1,
1445 + :" --- 2 or 3 (only 0 and 4 are tested).
1446 + :let @r .= "*** Test 2: "
1447 + :if matcharg(0) == [] && matcharg(4) == []
1448 + : let @r .= "OK\n"
1450 + : let @r .= "FAILED\n"
1452 + :" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
1453 + :let @r .= "*** Test 3: "
1457 + :if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
1458 + : let @r .= "OK\n"
1460 + : let @r .= "FAILED\n"
1462 + :" --- Check that "matchadd()" and "getmatches()" agree on added matches and
1463 + :" --- that default values apply.
1464 + :let @r .= "*** Test 4: "
1465 + :let m1 = matchadd("MyGroup1", "TODO")
1466 + :let m2 = matchadd("MyGroup2", "FIXME", 42)
1467 + :let m3 = matchadd("MyGroup3", "XXX", 60, 17)
1468 + :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}]
1469 + : let @r .= "OK\n"
1471 + : let @r .= "FAILED\n"
1473 + :" --- Check that "matchdelete()" deletes the matches defined in the previous
1474 + :" --- test correctly.
1475 + :let @r .= "*** Test 5: "
1476 + :call matchdelete(m1)
1477 + :call matchdelete(m2)
1478 + :call matchdelete(m3)
1482 + :if getmatches() == []
1483 + : let @r .= "OK\n"
1485 + : let @r .= "FAILED\n"
1487 + :" --- Check that "matchdelete()" returns 0 if succesfull and otherwise -1.
1488 + :let @r .= "*** Test 6: "
1489 + :let m = matchadd("MyGroup1", "TODO")
1490 + :let r1 = matchdelete(m)
1491 + :let r2 = matchdelete(42)
1492 + :if r1 == 0 && r2 == -1
1493 + : let @r .= "OK\n"
1495 + : let @r .= "FAILED\n"
1500 + :" --- Check that "clearmatches()" clears all matches defined by ":match" and
1501 + :" --- "matchadd()".
1502 + :let @r .= "*** Test 7: "
1503 + :let m1 = matchadd("MyGroup1", "TODO")
1504 + :let m2 = matchadd("MyGroup2", "FIXME", 42)
1505 + :let m3 = matchadd("MyGroup3", "XXX", 60, 17)
1506 + :match MyGroup1 /COFFEE/
1507 + :2match MyGroup2 /HUMPPA/
1508 + :3match MyGroup3 /VIM/
1509 + :call clearmatches()
1510 + :if getmatches() == []
1511 + : let @r .= "OK\n"
1513 + : let @r .= "FAILED\n"
1518 + :" --- Check that "setmatches()" restores a list of matches saved by
1519 + :" --- "getmatches()" without changes. (Matches with equal priority must also
1520 + :" --- remain in the same order.)
1521 + :let @r .= "*** Test 8: "
1522 + :let m1 = matchadd("MyGroup1", "TODO")
1523 + :let m2 = matchadd("MyGroup2", "FIXME", 42)
1524 + :let m3 = matchadd("MyGroup3", "XXX", 60, 17)
1525 + :match MyGroup1 /COFFEE/
1526 + :2match MyGroup2 /HUMPPA/
1527 + :3match MyGroup3 /VIM/
1528 + :let ml = getmatches()
1529 + :call clearmatches()
1530 + :call setmatches(ml)
1531 + :if getmatches() == ml
1532 + : let @r .= "OK\n"
1534 + : let @r .= "FAILED\n"
1536 + :call clearmatches()
1541 + :" --- Check that "setmatches()" will not add two matches with the same ID. The
1542 + :" --- expected behaviour (for now) is to add the first match but not the
1543 + :" --- second and to return 0 (even though it is a matter of debate whether
1544 + :" --- this can be considered succesfull behaviour).
1545 + :let @r .= "*** Test 9: "
1546 + :let r1 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}, {'group': 'MyGroup2', 'pattern': 'FIXME', 'priority': 10, 'id': 1}])
1547 + :if getmatches() == [{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}] && r1 == 0
1548 + : let @r .= "OK\n"
1550 + : let @r .= "FAILED\n"
1552 + :call clearmatches()
1554 + :" --- Check that "setmatches()" returns 0 if succesfull and otherwise -1.
1555 + :" --- (A range of valid and invalid input values are tried out to generate the
1556 + :" --- return values.)
1557 + :let @r .= "*** Test 10: "
1558 + :let rs1 = setmatches([])
1559 + :let rs2 = setmatches([{'group': 'MyGroup1', 'pattern': 'TODO', 'priority': 10, 'id': 1}])
1560 + :call clearmatches()
1561 + :let rf1 = setmatches(0)
1562 + :let rf2 = setmatches([0])
1563 + :let rf3 = setmatches([{'wrong key': 'wrong value'}])
1564 + :if rs1 == 0 && rs2 == 0 && rf1 == -1 && rf2 == -1 && rf3 == -1
1565 + : let @r .= "OK\n"
1567 + : let @r .= "FAILED\n"
1574 + :highlight clear MyGroup1
1575 + :highlight clear MyGroup2
1576 + :highlight clear MyGroup3
1578 + :/^Results/,$wq! test.out
1581 + Results of test63:
1582 *** ../vim-7.1.039/src/testdir/test63.ok Tue Jul 24 16:45:02 2007
1583 --- src/testdir/test63.ok Tue Jul 24 15:32:30 2007
1587 + Results of test63:
1598 *** ../vim-7.1.039/src/window.c Thu May 10 18:42:26 2007
1599 --- src/window.c Tue Jul 24 20:38:58 2007
1603 static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
1605 #endif /* FEAT_WINDOWS */
1607 static win_T *win_alloc __ARGS((win_T *after));
1608 static void win_new_height __ARGS((win_T *, int));
1616 + #ifdef FEAT_SEARCH_EXTRA
1617 + newwin->w_match_head = NULL;
1618 + newwin->w_next_match_id = 4;
1625 vim_free(wp->w_tagstack[i].tagname);
1627 vim_free(wp->w_localdir);
1628 #ifdef FEAT_SEARCH_EXTRA
1629 ! vim_free(wp->w_match[0].regprog);
1630 ! vim_free(wp->w_match[1].regprog);
1631 ! vim_free(wp->w_match[2].regprog);
1633 #ifdef FEAT_JUMPLIST
1637 vim_free(wp->w_tagstack[i].tagname);
1639 vim_free(wp->w_localdir);
1641 #ifdef FEAT_SEARCH_EXTRA
1642 ! clear_matches(wp);
1645 #ifdef FEAT_JUMPLIST
1657 + #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
1659 + * Add match to the match list of window 'wp'. The pattern 'pat' will be
1660 + * highligted with the group 'grp' with priority 'prio'.
1661 + * Optionally, a desired ID 'id' can be specified (greater than or equal to 1).
1662 + * If no particular ID is desired, -1 must be specified for 'id'.
1663 + * Return ID of added match, -1 on failure.
1666 + match_add(wp, grp, pat, prio, id)
1674 + matchitem_T *prev;
1677 + regmmatch_T match;
1679 + if (*grp == NUL || *pat == NUL)
1681 + if (id < -1 || id == 0)
1683 + EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
1688 + cur = wp->w_match_head;
1689 + while (cur != NULL)
1691 + if (cur->id == id)
1693 + EMSGN("E801: ID already taken: %ld", id);
1699 + if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
1701 + EMSG2(_(e_nogroup), grp);
1704 + if ((match.regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
1706 + EMSG2(_(e_invarg2), pat);
1710 + /* Find available match ID. */
1713 + cur = wp->w_match_head;
1714 + while (cur != NULL && cur->id != wp->w_next_match_id)
1717 + id = wp->w_next_match_id;
1718 + wp->w_next_match_id++;
1721 + /* Build new match. */
1722 + m = (matchitem_T *)alloc(sizeof(matchitem_T));
1724 + m->priority = prio;
1725 + m->pattern = vim_strsave(pat);
1726 + m->hlg_id = hlg_id;
1727 + m->match.regprog = match.regprog;
1729 + /* Insert new match. The match list is in ascending order with regard to
1730 + * the match priorities. */
1731 + cur = wp->w_match_head;
1733 + while (cur != NULL && prio >= cur->priority)
1739 + wp->w_match_head = m;
1744 + redraw_later(SOME_VALID);
1749 + * Delete match with ID 'id' in the match list of window 'wp'.
1750 + * Print error messages if 'perr' is TRUE.
1753 + match_delete(wp, id, perr)
1758 + matchitem_T *cur = wp->w_match_head;
1759 + matchitem_T *prev = cur;
1764 + EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
1768 + while (cur != NULL && cur->id != id)
1776 + EMSGN("E803: ID not found: %ld", id);
1780 + wp->w_match_head = cur->next;
1782 + prev->next = cur->next;
1783 + vim_free(cur->match.regprog);
1784 + vim_free(cur->pattern);
1786 + redraw_later(SOME_VALID);
1791 + * Delete all matches in the match list of window 'wp'.
1799 + while (wp->w_match_head != NULL)
1801 + m = wp->w_match_head->next;
1802 + vim_free(wp->w_match_head->match.regprog);
1803 + vim_free(wp->w_match_head->pattern);
1804 + vim_free(wp->w_match_head);
1805 + wp->w_match_head = m;
1807 + redraw_later(SOME_VALID);
1811 + * Get match from ID 'id' in window 'wp'.
1812 + * Return NULL if match not found.
1819 + matchitem_T *cur = wp->w_match_head;
1821 + while (cur != NULL && cur->id != id)
1826 *** ../vim-7.1.039/src/version.c Wed Jul 25 22:55:22 2007
1827 --- src/version.c Thu Jul 26 22:50:54 2007
1831 { /* Add new patch number below this line */
1837 It is hard to understand how a cemetery raised its burial
1838 cost and blamed it on the cost of living.
1840 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
1841 /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
1842 \\\ download, build and distribute -- http://www.A-A-P.org ///
1843 \\\ help me help AIDS victims -- http://ICCF-Holland.org ///