]> git.pld-linux.org Git - packages/vim.git/blame - 7.1.040
- updated to 0.7.5
[packages/vim.git] / 7.1.040
CommitLineData
6577e359 1To: vim-dev@vim.org
2Subject: patch 7.1.040
3Fcc: outbox
4From: Bram Moolenaar <Bram@moolenaar.net>
5Mime-Version: 1.0
6Content-Type: text/plain; charset=ISO-8859-1
7Content-Transfer-Encoding: 8bit
8------------
9
10Patch 7.1.040
11Problem: ":match" only supports three matches.
12Solution: 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
16 ID. (Martin Toft)
17Files: 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
22
23
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
26***************
27*** 1,4 ****
28! *eval.txt* For Vim version 7.1. Last change: 2007 Jul 11
29
30
31 VIM REFERENCE MANUAL by Bram Moolenaar
32--- 1,4 ----
33! *eval.txt* For Vim version 7.1. Last change: 2007 Jul 25
34
35
36 VIM REFERENCE MANUAL by Bram Moolenaar
37***************
38*** 1557,1562 ****
39--- 1557,1563 ----
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
47***************
48*** 1622,1627 ****
49--- 1623,1629 ----
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
57***************
58*** 1676,1682 ****
59--- 1678,1687 ----
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}]])
70***************
71*** 1731,1736 ****
72--- 1736,1742 ----
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
80***************
81*** 2012,2017 ****
82--- 2018,2027 ----
83 feature, -1 is returned.
84 See |C-indenting|.
85
86+ clearmatches() *clearmatches()*
87+ Clears all matches previously defined by |matchadd()| and the
88+ |:match| commands.
89+
90 *col()*
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:
93***************
94*** 2918,2923 ****
95--- 2928,2955 ----
96 returned. For an invalid window number {nr}, an empty list is
97 returned. Otherwise, same as getqflist().
98
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()|.
104+ Example: >
105+ :echo 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()
111+ :echo getmatches()
112+ < [] >
113+ :call setmatches(m)
114+ :echo getmatches()
115+ < [{'group': 'MyGroup1', 'pattern': 'TODO',
116+ 'priority': 10, 'id': 1}, {'group': 'MyGroup2',
117+ 'pattern': 'FIXME', 'priority': 10, 'id': 2}] >
118+ :unlet m
119+ <
120+
121 getqflist() *getqflist()*
122 Returns a list with all the current quickfix errors. Each
123 list item is a dictionary with these entries:
124***************
125*** 3622,3627 ****
126--- 3654,3697 ----
127 the pattern. 'smartcase' is NOT used. The matching is always
128 done like 'magic' is set and 'cpoptions' is empty.
129
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()|.
136+
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.
147+
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.
155+
156+ The number of matches is not limited, as it is the case with
157+ the |:match| commands.
158+
159+ Example: >
160+ :highlight MyGroup ctermbg=green guibg=green
161+ :let m = matchadd("MyGroup", "TODO")
162+ < Deletion of the pattern: >
163+ :call matchdelete(m)
164+
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()|.
168
169 matcharg({nr}) *matcharg()*
170 Selects the {nr} match item, as set with a |:match|,
171***************
172*** 3631,3638 ****
173 The pattern used.
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|.
177!
178
179 matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()*
180 Same as match(), but return the index of first character after
181--- 3701,3715 ----
182 The pattern used.
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.
188!
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()|.
194
195 matchend({expr}, {pat}[, {start}[, {count}]]) *matchend()*
196 Same as match(), but return the index of first character after
197***************
198*** 4385,4391 ****
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().
203
204 *setpos()*
205 setpos({expr}, {list})
206--- 4462,4474 ----
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|.
212!
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()|.
217
218 *setpos()*
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
222***************
223*** 1212,1218 ****
224 {group} must exist at the moment this command is executed.
225
226 The {group} highlighting still applies when a character is
227! to be highlighted for 'hlsearch'.
228
229 Note that highlighting the last used search pattern with
230 'hlsearch' is used in all windows, while the pattern defined
231--- 1212,1221 ----
232 {group} must exist at the moment this command is executed.
233
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
238! matches.
239
240 Note that highlighting the last used search pattern with
241 'hlsearch' is used in all windows, while the pattern defined
242***************
243*** 1226,1233 ****
244 display you may get unexpected results. That is because Vim
245 looks for a match in the line where redrawing starts.
246
247! Also see |matcharg()|, it returns the highlight group and
248! pattern of a previous :match command.
249
250 Another example, which highlights all characters in virtual
251 column 72 and more: >
252--- 1229,1243 ----
253 display you may get unexpected results. That is because Vim
254 looks for a match in the line where redrawing starts.
255
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|.
260!
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.
265
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
270***************
271*** 763,775 ****
272--- 763,784 ----
273 foldtextresult() get the text displayed for a closed fold
274
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
289+ |:match| command
290+ setmatches() restore a list of matches saved by
291+ |getmatches()|
292
293 Spelling:
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
297***************
298*** 475,480 ****
299--- 475,481 ----
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));
307***************
308*** 529,534 ****
309--- 530,536 ----
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));
317***************
318*** 577,583 ****
319--- 579,587 ----
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));
329***************
330*** 618,623 ****
331--- 622,628 ----
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));
339***************
340*** 7046,7051 ****
341--- 7051,7057 ----
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},
349***************
350*** 7102,7107 ****
351--- 7108,7114 ----
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},
359***************
360*** 7152,7158 ****
361--- 7159,7167 ----
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},
371***************
372*** 7193,7198 ****
373--- 7202,7208 ----
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},
381***************
382*** 8243,8248 ****
383--- 8253,8272 ----
384 }
385
386 /*
387+ * "clearmatches()" function
388+ */
389+ /*ARGSUSED*/
390+ static void
391+ f_clearmatches(argvars, rettv)
392+ typval_T *argvars;
393+ typval_T *rettv;
394+ {
395+ #ifdef FEAT_SEARCH_EXTRA
396+ clear_matches(curwin);
397+ #endif
398+ }
399+
400+ /*
401 * "col(string)" function
402 */
403 static void
404***************
405*** 10278,10283 ****
406--- 10302,10341 ----
407 }
408
409 /*
410+ * "getmatches()" function
411+ */
412+ /*ARGSUSED*/
413+ static void
414+ f_getmatches(argvars, rettv)
415+ typval_T *argvars;
416+ typval_T *rettv;
417+ {
418+ #ifdef FEAT_SEARCH_EXTRA
419+ dict_T *dict;
420+ matchitem_T *cur = curwin->w_match_head;
421+
422+ rettv->vval.v_number = 0;
423+
424+ if (rettv_list_alloc(rettv) == OK)
425+ {
426+ while (cur != NULL)
427+ {
428+ dict = dict_alloc();
429+ if (dict == NULL)
430+ return;
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);
437+ cur = cur->next;
438+ }
439+ }
440+ #endif
441+ }
442+
443+ /*
444 * "getpos(string)" function
445 */
446 static void
447***************
448*** 12448,12453 ****
449--- 12506,12547 ----
450 }
451
452 /*
453+ * "matchadd()" function
454+ */
455+ static void
456+ f_matchadd(argvars, rettv)
457+ typval_T *argvars;
458+ typval_T *rettv;
459+ {
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 */
465+ int id = -1;
466+ int error = FALSE;
467+
468+ rettv->vval.v_number = -1;
469+
470+ if (grp == NULL || pat == NULL)
471+ return;
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);
476+ if (error == TRUE)
477+ return;
478+ if (id >= 1 && id <= 3)
479+ {
480+ EMSGN("E798: ID is reserved for \":match\": %ld", id);
481+ return;
482+ }
483+
484+ rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
485+ #endif
486+ }
487+
488+ /*
489 * "matcharg()" function
490 */
491 static void
492***************
493*** 12458,12477 ****
494 if (rettv_list_alloc(rettv) == OK)
495 {
496 #ifdef FEAT_SEARCH_EXTRA
497! int mi = get_tv_number(&argvars[0]);
498
499! if (mi >= 1 && mi <= 3)
500 {
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);
505 }
506 #endif
507 }
508 }
509
510 /*
511 * "matchend()" function
512 */
513 static void
514--- 12552,12593 ----
515 if (rettv_list_alloc(rettv) == OK)
516 {
517 #ifdef FEAT_SEARCH_EXTRA
518! int id = get_tv_number(&argvars[0]);
519! matchitem_T *m;
520
521! if (id >= 1 && id <= 3)
522 {
523! if ((m = (matchitem_T *)get_match(curwin, id)) != NULL)
524! {
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);
528! }
529! else
530! {
531! list_append_string(rettv->vval.v_list, NUL, -1);
532! list_append_string(rettv->vval.v_list, NUL, -1);
533! }
534 }
535 #endif
536 }
537 }
538
539 /*
540+ * "matchdelete()" function
541+ */
542+ static void
543+ f_matchdelete(argvars, rettv)
544+ typval_T *argvars;
545+ typval_T *rettv;
546+ {
547+ #ifdef FEAT_SEARCH_EXTRA
548+ rettv->vval.v_number = match_delete(curwin,
549+ (int)get_tv_number(&argvars[0]), TRUE);
550+ #endif
551+ }
552+
553+ /*
554 * "matchend()" function
555 */
556 static void
557***************
558*** 14506,14511 ****
559--- 14622,14687 ----
560 win = find_win_by_nr(&argvars[0], NULL);
561 if (win != NULL)
562 set_qf_ll_list(win, &argvars[1], &argvars[2], rettv);
563+ }
564+
565+ /*
566+ * "setmatches()" function
567+ */
568+ static void
569+ f_setmatches(argvars, rettv)
570+ typval_T *argvars;
571+ typval_T *rettv;
572+ {
573+ #ifdef FEAT_SEARCH_EXTRA
574+ list_T *l;
575+ listitem_T *li;
576+ dict_T *d;
577+
578+ rettv->vval.v_number = -1;
579+ if (argvars[0].v_type != VAR_LIST)
580+ {
581+ EMSG(_(e_listreq));
582+ return;
583+ }
584+ if ((l = argvars[0].vval.v_list) != NULL)
585+ {
586+
587+ /* To some extent make sure that we are dealing with a list from
588+ * "getmatches()". */
589+ li = l->lv_first;
590+ while (li != NULL)
591+ {
592+ if (li->li_tv.v_type != VAR_DICT
593+ || (d = li->li_tv.vval.v_dict) == NULL)
594+ {
595+ EMSG(_(e_invarg));
596+ return;
597+ }
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))
602+ {
603+ EMSG(_(e_invarg));
604+ return;
605+ }
606+ li = li->li_next;
607+ }
608+
609+ clear_matches(curwin);
610+ li = l->lv_first;
611+ while (li != NULL)
612+ {
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"));
618+ li = li->li_next;
619+ }
620+ rettv->vval.v_number = 0;
621+ }
622+ #endif
623 }
624
625 /*
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
628***************
629*** 10817,10828 ****
630 exarg_T *eap;
631 {
632 char_u *p;
633 char_u *end;
634 int c;
635! int mi;
636
637 if (eap->line2 <= 3)
638! mi = eap->line2 - 1;
639 else
640 {
641 EMSG(e_invcmd);
642--- 10817,10829 ----
643 exarg_T *eap;
644 {
645 char_u *p;
646+ char_u *g;
647 char_u *end;
648 int c;
649! int id;
650
651 if (eap->line2 <= 3)
652! id = eap->line2;
653 else
654 {
655 EMSG(e_invcmd);
656***************
657*** 10831,10843 ****
658
659 /* First clear any old pattern. */
660 if (!eap->skip)
661! {
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 */
667! }
668
669 if (ends_excmd(*eap->arg))
670 end = eap->arg;
671--- 10832,10838 ----
672
673 /* First clear any old pattern. */
674 if (!eap->skip)
675! match_delete(curwin, id, FALSE);
676
677 if (ends_excmd(*eap->arg))
678 end = eap->arg;
679***************
680*** 10848,10862 ****
681 {
682 p = skiptowhite(eap->arg);
683 if (!eap->skip)
684! {
685! curwin->w_match_id[mi] = syn_namen2id(eap->arg,
686! (int)(p - eap->arg));
687! if (curwin->w_match_id[mi] == 0)
688! {
689! EMSG2(_(e_nogroup), eap->arg);
690! return;
691! }
692! }
693 p = skipwhite(p);
694 if (*p == NUL)
695 {
696--- 10843,10849 ----
697 {
698 p = skiptowhite(eap->arg);
699 if (!eap->skip)
700! g = vim_strnsave(eap->arg, (int)(p - eap->arg));
701 p = skipwhite(p);
702 if (*p == NUL)
703 {
704***************
705*** 10880,10893 ****
706
707 c = *end;
708 *end = NUL;
709! curwin->w_match[mi].regprog = vim_regcomp(p + 1, RE_MAGIC);
710! if (curwin->w_match[mi].regprog == NULL)
711! {
712! EMSG2(_(e_invarg2), p);
713! *end = c;
714! return;
715! }
716! curwin->w_match_pat[mi] = vim_strsave(p + 1);
717 *end = c;
718 }
719 }
720--- 10867,10874 ----
721
722 c = *end;
723 *end = NUL;
724! match_add(curwin, g, p + 1, 10, id);
725! vim_free(g);
726 *end = c;
727 }
728 }
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
731***************
732*** 59,62 ****
733--- 59,66 ----
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
744***************
745*** 100,126 ****
746 static int screen_cur_row, screen_cur_col; /* last known cursor position */
747
748 #ifdef FEAT_SEARCH_EXTRA
749- /*
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.
754- */
755- typedef struct
756- {
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 */
766- } match_T;
767-
768 static match_T search_hl; /* used for 'hlsearch' highlight matching */
769- static match_T match_hl[3]; /* used for ":match" highlight matching */
770 #endif
771
772 #ifdef FEAT_FOLDING
773--- 100,106 ----
774***************
775*** 155,160 ****
776--- 135,141 ----
777 static void redraw_custum_statusline __ARGS((win_T *wp));
778 #endif
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));
784***************
785*** 787,792 ****
786--- 768,774 ----
787 w_topline got smaller a bit */
788 #endif
789 #ifdef FEAT_SEARCH_EXTRA
790+ matchitem_T *cur; /* points to the match list */
791 int top_to_mod = FALSE; /* redraw above mod_top */
792 #endif
793
794***************
795*** 848,865 ****
796 #endif
797
798 #ifdef FEAT_SEARCH_EXTRA
799! /* Setup for ":match" and 'hlsearch' highlighting. Disable any previous
800 * match */
801! for (i = 0; i < 3; ++i)
802 {
803! match_hl[i].rm = wp->w_match[i];
804! if (wp->w_match_id[i] == 0)
805! match_hl[i].attr = 0;
806 else
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;
811 }
812 search_hl.buf = buf;
813 search_hl.lnum = 0;
814--- 830,849 ----
815 #endif
816
817 #ifdef FEAT_SEARCH_EXTRA
818! /* Setup for match and 'hlsearch' highlighting. Disable any previous
819 * match */
820! cur = wp->w_match_head;
821! while (cur != NULL)
822 {
823! cur->hl.rm = cur->match;
824! if (cur->hlg_id == 0)
825! cur->hl.attr = 0;
826 else
827! cur->hl.attr = syn_id2attr(cur->hlg_id);
828! cur->hl.buf = buf;
829! cur->hl.lnum = 0;
830! cur->hl.first_lnum = 0;
831! cur = cur->next;
832 }
833 search_hl.buf = buf;
834 search_hl.lnum = 0;
835***************
836*** 923,941 ****
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.
841 */
842 if (search_hl.rm.regprog != NULL
843 && re_multiline(search_hl.rm.regprog))
844 top_to_mod = TRUE;
845 else
846! for (i = 0; i < 3; ++i)
847! if (match_hl[i].rm.regprog != NULL
848! && re_multiline(match_hl[i].rm.regprog))
849 {
850 top_to_mod = TRUE;
851 break;
852 }
853 #endif
854 }
855 #ifdef FEAT_FOLDING
856--- 907,931 ----
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.
861 */
862 if (search_hl.rm.regprog != NULL
863 && re_multiline(search_hl.rm.regprog))
864 top_to_mod = TRUE;
865 else
866! {
867! cur = wp->w_match_head;
868! while (cur != NULL)
869! {
870! if (cur->match.regprog != NULL
871! && re_multiline(cur->match.regprog))
872 {
873 top_to_mod = TRUE;
874 break;
875 }
876+ cur = cur->next;
877+ }
878+ }
879 #endif
880 }
881 #ifdef FEAT_FOLDING
882***************
883*** 2626,2635 ****
884 int line_attr = 0; /* atrribute for the whole line */
885 #endif
886 #ifdef FEAT_SEARCH_EXTRA
887! match_T *shl; /* points to search_hl or match_hl */
888! #endif
889! #if defined(FEAT_SEARCH_EXTRA) || defined(FEAT_MBYTE)
890! int i;
891 #endif
892 #ifdef FEAT_ARABIC
893 int prev_c = 0; /* previous Arabic character */
894--- 2634,2646 ----
895 int line_attr = 0; /* atrribute for the whole line */
896 #endif
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
904! of the matches */
905 #endif
906 #ifdef FEAT_ARABIC
907 int prev_c = 0; /* previous Arabic character */
908***************
909*** 3074,3085 ****
910
911 #ifdef FEAT_SEARCH_EXTRA
912 /*
913! * Handle highlighting the last used search pattern and ":match".
914! * Do this for both search_hl and match_hl[3].
915 */
916! for (i = 3; i >= 0; --i)
917 {
918! shl = (i == 3) ? &search_hl : &match_hl[i];
919 shl->startcol = MAXCOL;
920 shl->endcol = MAXCOL;
921 shl->attr_cur = 0;
922--- 3085,3104 ----
923
924 #ifdef FEAT_SEARCH_EXTRA
925 /*
926! * Handle highlighting the last used search pattern and matches.
927! * Do this for both search_hl and the match list.
928 */
929! cur = wp->w_match_head;
930! shl_flag = FALSE;
931! while (cur != NULL || shl_flag == FALSE)
932 {
933! if (shl_flag == FALSE)
934! {
935! shl = &search_hl;
936! shl_flag = TRUE;
937! }
938! else
939! shl = &cur->hl;
940 shl->startcol = MAXCOL;
941 shl->endcol = MAXCOL;
942 shl->attr_cur = 0;
943***************
944*** 3122,3127 ****
945--- 3141,3148 ----
946 area_highlighting = TRUE;
947 }
948 }
949+ if (shl != &search_hl && cur != NULL)
950+ cur = cur->next;
951 }
952 #endif
953
954***************
955*** 3388,3400 ****
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'.
961 */
962 v = (long)(ptr - line);
963! for (i = 3; i >= 0; --i)
964! {
965! shl = (i == 3) ? &search_hl : &match_hl[i];
966 while (shl->rm.regprog != NULL)
967 {
968 if (shl->startcol != MAXCOL
969--- 3409,3432 ----
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
974! * priority).
975 */
976 v = (long)(ptr - line);
977! cur = wp->w_match_head;
978! shl_flag = FALSE;
979! while (cur != NULL || shl_flag == FALSE)
980! {
981! if (shl_flag == FALSE
982! && ((cur != NULL
983! && cur->priority > SEARCH_HL_PRIORITY)
984! || cur == NULL))
985! {
986! shl = &search_hl;
987! shl_flag = TRUE;
988! }
989! else
990! shl = &cur->hl;
991 while (shl->rm.regprog != NULL)
992 {
993 if (shl->startcol != MAXCOL
994***************
995*** 3442,3458 ****
996 }
997 break;
998 }
999 }
1000
1001! /* ":match" highlighting overrules 'hlsearch' */
1002! for (i = 0; i <= 3; ++i)
1003! if (i == 3)
1004! search_attr = search_hl.attr_cur;
1005! else if (match_hl[i].attr_cur != 0)
1006 {
1007! search_attr = match_hl[i].attr_cur;
1008! break;
1009 }
1010 }
1011 #endif
1012
1013--- 3474,3505 ----
1014 }
1015 break;
1016 }
1017+ if (shl != &search_hl && cur != NULL)
1018+ cur = cur->next;
1019 }
1020
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;
1025! shl_flag = FALSE;
1026! while (cur != NULL || shl_flag == FALSE)
1027! {
1028! if (shl_flag == FALSE
1029! && ((cur != NULL
1030! && cur->priority > SEARCH_HL_PRIORITY)
1031! || cur == NULL))
1032 {
1033! shl = &search_hl;
1034! shl_flag = TRUE;
1035 }
1036+ else
1037+ shl = &cur->hl;
1038+ if (shl->attr_cur != 0)
1039+ search_attr = shl->attr_cur;
1040+ if (shl != &search_hl && cur != NULL)
1041+ cur = cur->next;
1042+ }
1043 }
1044 #endif
1045
1046***************
1047*** 3613,3618 ****
1048--- 3660,3667 ----
1049 * Draw it as a space with a composing char. */
1050 if (utf_iscomposing(mb_c))
1051 {
1052+ int i;
1053+
1054 for (i = Screen_mco - 1; i > 0; --i)
1055 u8cc[i] = u8cc[i - 1];
1056 u8cc[0] = mb_c;
1057***************
1058*** 4256,4269 ****
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
1072 # endif
1073--- 4305,4333 ----
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;
1081+ else
1082+ {
1083+ cur = wp->w_match_head;
1084+ while (cur != NULL)
1085+ {
1086+ if (prevcol == (long)cur->hl.startcol)
1087+ {
1088+ prevcol_hl_flag = TRUE;
1089+ break;
1090+ }
1091+ cur = cur->next;
1092+ }
1093+ }
1094+ #endif
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
1102 # endif
1103***************
1104*** 4304,4318 ****
1105 #ifdef FEAT_SEARCH_EXTRA
1106 if (area_attr == 0)
1107 {
1108! for (i = 0; i <= 3; ++i)
1109! {
1110! if (i == 3)
1111! char_attr = search_hl.attr;
1112! else if ((ptr - line) - 1 == (long)match_hl[i].startcol)
1113 {
1114! char_attr = match_hl[i].attr;
1115! break;
1116 }
1117 }
1118 }
1119 #endif
1120--- 4368,4394 ----
1121 #ifdef FEAT_SEARCH_EXTRA
1122 if (area_attr == 0)
1123 {
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;
1128! shl_flag = FALSE;
1129! while (cur != NULL || shl_flag == FALSE)
1130! {
1131! if (shl_flag == FALSE
1132! && ((cur != NULL
1133! && cur->priority > SEARCH_HL_PRIORITY)
1134! || cur == NULL))
1135 {
1136! shl = &search_hl;
1137! shl_flag = TRUE;
1138 }
1139+ else
1140+ shl = &cur->hl;
1141+ if ((ptr - line) - 1 == (long)shl->startcol)
1142+ char_attr = shl->attr;
1143+ if (shl != &search_hl && cur != NULL)
1144+ cur = cur->next;
1145 }
1146 }
1147 #endif
1148***************
1149*** 4462,4467 ****
1150--- 4538,4545 ----
1151 {
1152 if (mb_utf8)
1153 {
1154+ int i;
1155+
1156 ScreenLinesUC[off] = mb_c;
1157 if ((c & 0xff) == 0)
1158 ScreenLines[off] = 0x80; /* avoid storing zero */
1159***************
1160*** 6320,6326 ****
1161
1162 #ifdef FEAT_SEARCH_EXTRA
1163 /*
1164! * Prepare for 'searchhl' highlighting.
1165 */
1166 static void
1167 start_search_hl()
1168--- 6398,6404 ----
1169
1170 #ifdef FEAT_SEARCH_EXTRA
1171 /*
1172! * Prepare for 'hlsearch' highlighting.
1173 */
1174 static void
1175 start_search_hl()
1176***************
1177*** 6333,6339 ****
1178 }
1179
1180 /*
1181! * Clean up for 'searchhl' highlighting.
1182 */
1183 static void
1184 end_search_hl()
1185--- 6411,6417 ----
1186 }
1187
1188 /*
1189! * Clean up for 'hlsearch' highlighting.
1190 */
1191 static void
1192 end_search_hl()
1193***************
1194*** 6353,6370 ****
1195 win_T *wp;
1196 linenr_T lnum;
1197 {
1198! match_T *shl; /* points to search_hl or match_hl */
1199 int n;
1200- int i;
1201
1202 /*
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].
1206 */
1207! for (i = 3; i >= 0; --i)
1208 {
1209! shl = (i == 3) ? &search_hl : &match_hl[i];
1210 if (shl->rm.regprog != NULL
1211 && shl->lnum == 0
1212 && re_multiline(shl->rm.regprog))
1213--- 6431,6458 ----
1214 win_T *wp;
1215 linenr_T lnum;
1216 {
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 */
1221 int n;
1222
1223 /*
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.
1227 */
1228! cur = wp->w_match_head;
1229! shl_flag = FALSE;
1230! while (cur != NULL || shl_flag == FALSE)
1231 {
1232! if (shl_flag == FALSE)
1233! {
1234! shl = &search_hl;
1235! shl_flag = TRUE;
1236! }
1237! else
1238! shl = &cur->hl;
1239 if (shl->rm.regprog != NULL
1240 && shl->lnum == 0
1241 && re_multiline(shl->rm.regprog))
1242***************
1243*** 6399,6409 ****
1244 }
1245 }
1246 }
1247 }
1248 }
1249
1250 /*
1251! * Search for a next 'searchl' or ":match" match.
1252 * Uses shl->buf.
1253 * Sets shl->lnum and shl->rm contents.
1254 * Note: Assumes a previous match is always before "lnum", unless
1255--- 6487,6499 ----
1256 }
1257 }
1258 }
1259+ if (shl != &search_hl && cur != NULL)
1260+ cur = cur->next;
1261 }
1262 }
1263
1264 /*
1265! * Search for a next 'hlsearch' or match.
1266 * Uses shl->buf.
1267 * Sets shl->lnum and shl->rm contents.
1268 * Note: Assumes a previous match is always before "lnum", unless
1269***************
1270*** 6413,6419 ****
1271 static void
1272 next_search_hl(win, shl, lnum, mincol)
1273 win_T *win;
1274! match_T *shl; /* points to search_hl or match_hl */
1275 linenr_T lnum;
1276 colnr_T mincol; /* minimal column for a match */
1277 {
1278--- 6503,6509 ----
1279 static void
1280 next_search_hl(win, shl, lnum, mincol)
1281 win_T *win;
1282! match_T *shl; /* points to search_hl or a match */
1283 linenr_T lnum;
1284 colnr_T mincol; /* minimal column for a match */
1285 {
1286***************
1287*** 6481,6487 ****
1288 /* Error while handling regexp: stop using this regexp. */
1289 if (shl == &search_hl)
1290 {
1291! /* don't free the regprog in match_hl[], it's a copy */
1292 vim_free(shl->rm.regprog);
1293 no_hlsearch = TRUE;
1294 }
1295--- 6571,6577 ----
1296 /* Error while handling regexp: stop using this regexp. */
1297 if (shl == &search_hl)
1298 {
1299! /* don't free regprog in the match list, it's a copy */
1300 vim_free(shl->rm.regprog);
1301 no_hlsearch = TRUE;
1302 }
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
1305***************
1306*** 1694,1699 ****
1307--- 1694,1734 ----
1308 #define FR_COL 2 /* frame with a column of windows */
1309
1310 /*
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.
1315+ */
1316+ typedef struct
1317+ {
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 */
1327+ } match_T;
1328+
1329+ /*
1330+ * matchitem_T provides a linked list for storing match items for ":match" and
1331+ * the match functions.
1332+ */
1333+ typedef struct matchitem matchitem_T;
1334+ struct matchitem
1335+ {
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 */
1343+ };
1344+
1345+ /*
1346 * Structure which contains all information that belongs to a window
1347 *
1348 * All row numbers are relative to the start of the window, except w_winrow.
1349***************
1350*** 1934,1942 ****
1351 #endif
1352
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" */
1357 #endif
1358
1359 /*
1360--- 1969,1976 ----
1361 #endif
1362
1363 #ifdef FEAT_SEARCH_EXTRA
1364! matchitem_T *w_match_head; /* head of match list */
1365! int w_next_match_id; /* next match ID */
1366 #endif
1367
1368 /*
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
1371***************
1372*** 8504,8510 ****
1373 syn_id2name(id)
1374 int id;
1375 {
1376! if (id <= 0 || id >= highlight_ga.ga_len)
1377 return (char_u *)"";
1378 return HL_TABLE()[id - 1].sg_name;
1379 }
1380--- 8504,8510 ----
1381 syn_id2name(id)
1382 int id;
1383 {
1384! if (id <= 0 || id > highlight_ga.ga_len)
1385 return (char_u *)"";
1386 return HL_TABLE()[id - 1].sg_name;
1387 }
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
1390***************
1391*** 1,5 ****
1392 #
1393! # Makefile to run al tests for Vim
1394 #
1395
1396 VIMPROG = ../vim
1397--- 1,5 ----
1398 #
1399! # Makefile to run all tests for Vim
1400 #
1401
1402 VIMPROG = ../vim
1403***************
1404*** 15,21 ****
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
1409
1410 SCRIPTS_GUI = test16.out
1411
1412--- 15,21 ----
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
1417
1418 SCRIPTS_GUI = test16.out
1419
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
1422***************
1423*** 0 ****
1424--- 1,157 ----
1425+ Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
1426+ "matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
1427+
1428+ STARTTEST
1429+ :so small.vim
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"
1441+ :else
1442+ : let @r .= "FAILED\n"
1443+ :endif
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"
1449+ :else
1450+ : let @r .= "FAILED\n"
1451+ :endif
1452+ :" --- Check that "matcharg()" returns ['', ''] if a match is not defined.
1453+ :let @r .= "*** Test 3: "
1454+ :match
1455+ :2match
1456+ :3match
1457+ :if matcharg(1) == ['', ''] && matcharg(2) == ['', ''] && matcharg(3) == ['', '']
1458+ : let @r .= "OK\n"
1459+ :else
1460+ : let @r .= "FAILED\n"
1461+ :endif
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"
1470+ :else
1471+ : let @r .= "FAILED\n"
1472+ :endif
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)
1479+ :unlet m1
1480+ :unlet m2
1481+ :unlet m3
1482+ :if getmatches() == []
1483+ : let @r .= "OK\n"
1484+ :else
1485+ : let @r .= "FAILED\n"
1486+ :endif
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"
1494+ :else
1495+ : let @r .= "FAILED\n"
1496+ :endif
1497+ :unlet m
1498+ :unlet r1
1499+ :unlet r2
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"
1512+ :else
1513+ : let @r .= "FAILED\n"
1514+ :endif
1515+ :unlet m1
1516+ :unlet m2
1517+ :unlet m3
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"
1533+ :else
1534+ : let @r .= "FAILED\n"
1535+ :endif
1536+ :call clearmatches()
1537+ :unlet m1
1538+ :unlet m2
1539+ :unlet m3
1540+ :unlet ml
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"
1549+ :else
1550+ : let @r .= "FAILED\n"
1551+ :endif
1552+ :call clearmatches()
1553+ :unlet r1
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"
1566+ :else
1567+ : let @r .= "FAILED\n"
1568+ :endif
1569+ :unlet rs1
1570+ :unlet rs2
1571+ :unlet rf1
1572+ :unlet rf2
1573+ :unlet rf3
1574+ :highlight clear MyGroup1
1575+ :highlight clear MyGroup2
1576+ :highlight clear MyGroup3
1577+ G"rp
1578+ :/^Results/,$wq! test.out
1579+ ENDTEST
1580+
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
1584***************
1585*** 0 ****
1586--- 1,11 ----
1587+ Results of test63:
1588+ *** Test 1: OK
1589+ *** Test 2: OK
1590+ *** Test 3: OK
1591+ *** Test 4: OK
1592+ *** Test 5: OK
1593+ *** Test 6: OK
1594+ *** Test 7: OK
1595+ *** Test 8: OK
1596+ *** Test 9: OK
1597+ *** Test 10: OK
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
1600***************
1601*** 75,80 ****
1602--- 75,81 ----
1603 static win_T *restore_snapshot_rec __ARGS((frame_T *sn, frame_T *fr));
1604
1605 #endif /* FEAT_WINDOWS */
1606+
1607 static win_T *win_alloc __ARGS((win_T *after));
1608 static void win_new_height __ARGS((win_T *, int));
1609
1610***************
1611*** 4128,4133 ****
1612--- 4129,4138 ----
1613 #ifdef FEAT_AUTOCMD
1614 --autocmd_block;
1615 #endif
1616+ #ifdef FEAT_SEARCH_EXTRA
1617+ newwin->w_match_head = NULL;
1618+ newwin->w_next_match_id = 4;
1619+ #endif
1620 }
1621 return newwin;
1622 }
1623***************
1624*** 4185,4195 ****
1625 vim_free(wp->w_tagstack[i].tagname);
1626
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);
1632 #endif
1633 #ifdef FEAT_JUMPLIST
1634 free_jumplist(wp);
1635 #endif
1636--- 4190,4200 ----
1637 vim_free(wp->w_tagstack[i].tagname);
1638
1639 vim_free(wp->w_localdir);
1640+
1641 #ifdef FEAT_SEARCH_EXTRA
1642! clear_matches(wp);
1643 #endif
1644+
1645 #ifdef FEAT_JUMPLIST
1646 free_jumplist(wp);
1647 #endif
1648***************
1649*** 6172,6176 ****
1650--- 6177,6351 ----
1651 return TRUE;
1652
1653 return FALSE;
1654+ }
1655+ #endif
1656+
1657+ #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
1658+ /*
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.
1664+ */
1665+ int
1666+ match_add(wp, grp, pat, prio, id)
1667+ win_T *wp;
1668+ char_u *grp;
1669+ char_u *pat;
1670+ int prio;
1671+ int id;
1672+ {
1673+ matchitem_T *cur;
1674+ matchitem_T *prev;
1675+ matchitem_T *m;
1676+ int hlg_id;
1677+ regmmatch_T match;
1678+
1679+ if (*grp == NUL || *pat == NUL)
1680+ return -1;
1681+ if (id < -1 || id == 0)
1682+ {
1683+ EMSGN("E799: Invalid ID: %ld (must be greater than or equal to 1)", id);
1684+ return -1;
1685+ }
1686+ if (id != -1)
1687+ {
1688+ cur = wp->w_match_head;
1689+ while (cur != NULL)
1690+ {
1691+ if (cur->id == id)
1692+ {
1693+ EMSGN("E801: ID already taken: %ld", id);
1694+ return -1;
1695+ }
1696+ cur = cur->next;
1697+ }
1698+ }
1699+ if ((hlg_id = syn_namen2id(grp, STRLEN(grp))) == 0)
1700+ {
1701+ EMSG2(_(e_nogroup), grp);
1702+ return -1;
1703+ }
1704+ if ((match.regprog = vim_regcomp(pat, RE_MAGIC)) == NULL)
1705+ {
1706+ EMSG2(_(e_invarg2), pat);
1707+ return -1;
1708+ }
1709+
1710+ /* Find available match ID. */
1711+ while (id == -1)
1712+ {
1713+ cur = wp->w_match_head;
1714+ while (cur != NULL && cur->id != wp->w_next_match_id)
1715+ cur = cur->next;
1716+ if (cur == NULL)
1717+ id = wp->w_next_match_id;
1718+ wp->w_next_match_id++;
1719+ }
1720+
1721+ /* Build new match. */
1722+ m = (matchitem_T *)alloc(sizeof(matchitem_T));
1723+ m->id = id;
1724+ m->priority = prio;
1725+ m->pattern = vim_strsave(pat);
1726+ m->hlg_id = hlg_id;
1727+ m->match.regprog = match.regprog;
1728+
1729+ /* Insert new match. The match list is in ascending order with regard to
1730+ * the match priorities. */
1731+ cur = wp->w_match_head;
1732+ prev = cur;
1733+ while (cur != NULL && prio >= cur->priority)
1734+ {
1735+ prev = cur;
1736+ cur = cur->next;
1737+ }
1738+ if (cur == prev)
1739+ wp->w_match_head = m;
1740+ else
1741+ prev->next = m;
1742+ m->next = cur;
1743+
1744+ redraw_later(SOME_VALID);
1745+ return id;
1746+ }
1747+
1748+ /*
1749+ * Delete match with ID 'id' in the match list of window 'wp'.
1750+ * Print error messages if 'perr' is TRUE.
1751+ */
1752+ int
1753+ match_delete(wp, id, perr)
1754+ win_T *wp;
1755+ int id;
1756+ int perr;
1757+ {
1758+ matchitem_T *cur = wp->w_match_head;
1759+ matchitem_T *prev = cur;
1760+
1761+ if (id < 1)
1762+ {
1763+ if (perr == TRUE)
1764+ EMSGN("E802: Invalid ID: %ld (must be greater than or equal to 1)",
1765+ id);
1766+ return -1;
1767+ }
1768+ while (cur != NULL && cur->id != id)
1769+ {
1770+ prev = cur;
1771+ cur = cur->next;
1772+ }
1773+ if (cur == NULL)
1774+ {
1775+ if (perr == TRUE)
1776+ EMSGN("E803: ID not found: %ld", id);
1777+ return -1;
1778+ }
1779+ if (cur == prev)
1780+ wp->w_match_head = cur->next;
1781+ else
1782+ prev->next = cur->next;
1783+ vim_free(cur->match.regprog);
1784+ vim_free(cur->pattern);
1785+ vim_free(cur);
1786+ redraw_later(SOME_VALID);
1787+ return 0;
1788+ }
1789+
1790+ /*
1791+ * Delete all matches in the match list of window 'wp'.
1792+ */
1793+ void
1794+ clear_matches(wp)
1795+ win_T *wp;
1796+ {
1797+ matchitem_T *m;
1798+
1799+ while (wp->w_match_head != NULL)
1800+ {
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;
1806+ }
1807+ redraw_later(SOME_VALID);
1808+ }
1809+
1810+ /*
1811+ * Get match from ID 'id' in window 'wp'.
1812+ * Return NULL if match not found.
1813+ */
1814+ matchitem_T *
1815+ get_match(wp, id)
1816+ win_T *wp;
1817+ int id;
1818+ {
1819+ matchitem_T *cur = wp->w_match_head;
1820+
1821+ while (cur != NULL && cur->id != id)
1822+ cur = cur->next;
1823+ return cur;
1824 }
1825 #endif
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
1828***************
1829*** 668,669 ****
1830--- 668,671 ----
1831 { /* Add new patch number below this line */
1832+ /**/
1833+ 40,
1834 /**/
1835
1836--
1837It is hard to understand how a cemetery raised its burial
1838cost and blamed it on the cost of living.
1839
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 ///
This page took 0.310921 seconds and 4 git commands to generate.