]>
Commit | Line | Data |
---|---|---|
6577e359 | 1 | To: vim-dev@vim.org |
2 | Subject: patch 7.1.040 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=ISO-8859-1 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.1.040 | |
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 | |
16 | ID. (Martin Toft) | |
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 | |
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 | -- | |
1837 | It is hard to understand how a cemetery raised its burial | |
1838 | cost 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 /// |