7
|
1 *matchit.txt* Extended "%" matching
|
|
2
|
|
3 For instructions on installing this file, type
|
|
4 :help matchit-install
|
|
5 inside Vim.
|
|
6
|
799
|
7 For Vim version 6.3. Last change: 2006 Feb 23
|
7
|
8
|
|
9
|
|
10 VIM REFERENCE MANUAL by Benji Fisher
|
|
11
|
|
12 *matchit* *matchit.vim*
|
|
13
|
|
14 1. Extended matching with "%" |matchit-intro|
|
|
15 2. Activation |matchit-activate|
|
|
16 3. Configuration |matchit-configure|
|
|
17 4. Supporting a New Language |matchit-newlang|
|
|
18 5. Known Bugs and Limitations |matchit-bugs|
|
|
19
|
|
20 The functionality mentioned here is a plugin, see |add-plugin|.
|
|
21 This plugin is only available if 'compatible' is not set.
|
|
22 You can avoid loading this plugin by setting the "loaded_matchit" variable
|
|
23 in your |vimrc| file: >
|
|
24 :let loaded_matchit = 1
|
|
25
|
|
26 {Vi does not have any of this}
|
|
27
|
|
28 ==============================================================================
|
|
29 1. Extended matching with "%" *matchit-intro*
|
|
30
|
|
31 *matchit-%*
|
|
32 % Cycle forward through matching groups, such as "if", "else", "endif",
|
|
33 as specified by |b:match_words|.
|
|
34
|
|
35 *g%* *v_g%* *o_g%*
|
|
36 g% Cycle backwards through matching groups, as specified by
|
|
37 |b:match_words|. For example, go from "endif" to "else" to "if".
|
|
38
|
|
39 *[%* *v_[%* *o_[%*
|
|
40 [% Go to [count] previous unmatched group, as specified by
|
|
41 |b:match_words|. Similar to |[{|.
|
|
42
|
|
43 *]%* *v_]%* *o_]%*
|
|
44 ]% Go to [count] next unmatched group, as specified by
|
|
45 |b:match_words|. Similar to |]}|.
|
|
46
|
|
47 *v_a%*
|
|
48 a% In Visual mode, select the matching group, as specified by
|
|
49 |b:match_words|, containing the cursor. Similar to |v_a[|.
|
|
50 A [count] is ignored, and only the first character of the closing
|
|
51 pattern is selected.
|
|
52
|
|
53 In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace,
|
|
54 bracket, or paren to its match. This can be configured with the 'matchpairs'
|
|
55 option. The matchit plugin extends this in several ways:
|
|
56
|
|
57 You can match whole words, such as "if" and "endif", not just
|
|
58 single characters. You can also specify a |regular-expression|.
|
|
59 You can define groups with more than two words, such as "if",
|
|
60 "else", "endif". Banging on the "%" key will cycle from the "if" to
|
|
61 the first "else", the next "else", ..., the closing "endif", and back
|
|
62 to the opening "if". Nested structures are skipped. Using |g%| goes
|
|
63 in the reverse direction.
|
|
64 By default, words inside comments and strings are ignored, unless
|
|
65 the cursor is inside a comment or string when you type "%". If the
|
|
66 only thing you want to do is modify the behavior of "%" so that it
|
|
67 behaves this way, you can >
|
|
68 :let b:match_words = &matchpairs
|
|
69 <
|
|
70 See |matchit-details| for details on what the script does, and |b:match_words|
|
|
71 for how to specify matching patterns.
|
|
72
|
|
73 MODES: *matchit-modes* *matchit-v_%* *matchit-o_%*
|
|
74
|
|
75 Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in
|
|
76 |motion| commands in |Operator-pending| and |Visual| modes. However, you
|
|
77 cannot make these motions |linewise| or |characterwise|, since the |:omap|s
|
|
78 that define them start with "v" in order to make the default behavior
|
|
79 inclusive. (See |o_v|.) In other words, "dV%" will not work. The
|
|
80 work-around is to go through Visual mode: "V%d" will work.
|
|
81
|
|
82 LANGUAGES: *matchit-languages*
|
|
83
|
|
84 Currently, the following languages are supported: Ada, ASP with VBS, Csh,
|
|
85 DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal,
|
|
86 SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via
|
|
87 |filetype-plugin|s.
|
|
88
|
|
89 To support a new language, see |matchit-newlang| below.
|
|
90
|
|
91 DETAILS: *matchit-details* *matchit-parse*
|
|
92
|
|
93 Here is an outline of what matchit.vim does each time you hit the "%" key. If
|
|
94 there are |backref|s in |b:match_words| then the first step is to produce a
|
|
95 version in which these back references have been eliminated; if there are no
|
|
96 |backref|s then this step is skipped. This step is called parsing. For
|
|
97 example, "\(foo\|bar\):end\1" is parsed to yield
|
|
98 "\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are
|
|
99 nested groups. If debugging is turned on, the parsed version is saved as
|
|
100 |b:match_pat|.
|
|
101
|
|
102 *matchit-choose*
|
|
103 Next, the script looks for a word on the current line that matches the pattern
|
|
104 just constructed. It includes the patterns from the 'matchpairs' option.
|
|
105 The goal is to do what you expect, which turns out to be a little complicated.
|
|
106 The script follows these rules:
|
|
107
|
|
108 Insist on a match that ends on or after the cursor.
|
|
109 Prefer a match that includes the cursor position (that is, one that
|
|
110 starts on or before the cursor).
|
|
111 Prefer a match that starts as close to the cursor as possible.
|
|
112 Prefer a match in |b:match_words| to a match in 'matchpairs'.
|
|
113 If more than one pattern in |b:match_words| matches, choose the one
|
|
114 that is listed first.
|
|
115
|
|
116 Examples:
|
|
117
|
|
118 Suppose you >
|
|
119 :let b:match_words = '<:>,<tag>:</tag>'
|
|
120 < and hit "%" with the cursor on or before the "<" in "a <tag> is born".
|
|
121 The pattern '<' comes first, so it is preferred over '<tag>', which
|
|
122 also matches. If the cursor is on the "t", however, then '<tag>' is
|
|
123 preferred, because this matches a bit of text containing the cursor.
|
|
124 If the two groups of patterns were reversed then '<' would never be
|
|
125 preferred.
|
|
126
|
|
127 Suppose you >
|
|
128 :let b:match_words = 'if:end if'
|
|
129 < (Note the space!) and hit "%" with the cursor at the end of "end if".
|
|
130 Then "if" matches, which is probably not what you want, but if the
|
|
131 cursor starts on the "end " then "end if" is chosen. (You can avoid
|
|
132 this problem by using a more complicated pattern.)
|
|
133
|
|
134 If there is no match, the script falls back on the usual behavior of |%|. If
|
|
135 debugging is turned on, the matched bit of text is saved as |b:match_match|
|
|
136 and the cursor column of the start of the match is saved as |b:match_col|.
|
|
137
|
|
138 Next, the script looks through |b:match_words| (original and parsed versions)
|
|
139 for the group and pattern that match. If debugging is turned on, the group is
|
|
140 saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If
|
|
141 there are |backref|s then, in addition, the matching pattern is saved as
|
|
142 |b:match_word| and a table of translations is saved as |b:match_table|. If
|
|
143 there are |backref|s, these are determined from the matching pattern and
|
|
144 |b:match_match| and substituted into each pattern in the matching group.
|
|
145
|
|
146 The script decides whether to search forwards or backwards and chooses
|
|
147 arguments for the |searchpair()| function. Then, the cursor is moved to the
|
|
148 start of the match, and |searchpair()| is called. By default, matching
|
|
149 structures inside strings and comments are ignored. This can be changed by
|
|
150 setting |b:match_skip|.
|
|
151
|
|
152 ==============================================================================
|
|
153 2. Activation *matchit-activate*
|
|
154
|
|
155 You can use this script as a plugin, by copying it to your plugin directory.
|
|
156 See |add-global-plugin| for instructions. You can also add a line to your
|
|
157 |vimrc| file, such as >
|
|
158 :source $VIMRUNTIME/macros/matchit.vim
|
|
159 or >
|
|
160 :runtime macros/matchit.vim
|
|
161 Either way, the script should start working the next time you start up Vim.
|
|
162
|
|
163 The script does nothing unless it finds a |buffer-variable| named
|
|
164 |b:match_words|. The script contains autocommands that set this variable for
|
|
165 various file types: see |matchit-languages| above. For a new language, you
|
|
166 can add autocommands to the script or to your vimrc file, but the recommended
|
|
167 method is to add a line such as >
|
|
168 let b:match_words = '\<foo\>:\<bar\>'
|
|
169 to the |filetype-plugin| for your language. See |b:match_words| below for how
|
|
170 this variable is interpreted.
|
|
171
|
|
172 TROUBLESHOOTING *matchit-troubleshoot*
|
|
173
|
|
174 The script should work in most installations of Vim. It may not work if Vim
|
|
175 was compiled with a minimal feature set, for example if the |+syntax| option
|
|
176 was not enabled. If your Vim has support for syntax compiled in, but you do
|
|
177 not have |syntax| highlighting turned on, matchit.vim should work, but it may
|
|
178 fail to skip matching groups in comments and strings. If the |filetype|
|
|
179 mechanism is turned off, the |b:match_words| variable will probably not be
|
|
180 defined automatically.
|
|
181
|
|
182 ==============================================================================
|
|
183 3. Configuration *matchit-configure*
|
|
184
|
|
185 There are several variables that govern the behavior of matchit.vim. Note
|
|
186 that these are variables local to the buffer, not options, so use |:let| to
|
|
187 define them, not |:set|. Some of these variables have values that matter; for
|
|
188 others, it only matters whether the variable has been defined. All of these
|
|
189 can be defined in the |filetype-plugin| or autocommand that defines
|
|
190 |b:match_words| or "on the fly."
|
|
191
|
|
192 The main variable is |b:match_words|. It is described in the section below on
|
|
193 supporting a new language.
|
|
194
|
|
195 *MatchError* *matchit-hl* *matchit-highlight*
|
|
196 MatchError is the highlight group for error messages from the script. By
|
|
197 default, it is linked to WarningMsg. If you do not want to be bothered by
|
|
198 error messages, you can define this to be something invisible. For example,
|
|
199 if you use the GUI version of Vim and your command line is normally white, you
|
|
200 can do >
|
|
201 :hi MatchError guifg=white guibg=white
|
|
202 <
|
|
203 *b:match_ignorecase*
|
|
204 If you >
|
|
205 :let b:match_ignorecase = 1
|
|
206 then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END"
|
|
207 are equivalent. If you >
|
|
208 :let b:match_ignorecase = 0
|
|
209 then matchit.vim treats "end" and "END" differently. (There will be no
|
|
210 b:match_infercase option unless someone requests it.)
|
|
211
|
|
212 *b:match_debug*
|
|
213 Define b:match_debug if you want debugging information to be saved. See
|
|
214 |matchit-debug|, below.
|
|
215
|
|
216 *b:match_skip*
|
|
217 If b:match_skip is defined, it is passed as the skip argument to
|
|
218 |searchpair()|. This controls when matching structures are skipped, or
|
|
219 ignored. By default, they are ignored inside comments and strings, as
|
|
220 determined by the |syntax| mechanism. (If syntax highlighting is turned off,
|
|
221 nothing is skipped.) You can set b:match_skip to a string, which evaluates to
|
|
222 a non-zero, numerical value if the match is to be skipped or zero if the match
|
|
223 should not be skipped. In addition, the following special values are
|
|
224 supported by matchit.vim:
|
|
225 s:foo becomes (current syntax item) =~ foo
|
|
226 S:foo becomes (current syntax item) !~ foo
|
|
227 r:foo becomes (line before cursor) =~ foo
|
|
228 R:foo becomes (line before cursor) !~ foo
|
|
229 (The "s" is meant to suggest "syntax", and the "r" is meant to suggest
|
|
230 "regular expression".)
|
|
231
|
|
232 Examples:
|
|
233
|
|
234 You can get the default behavior with >
|
|
235 :let b:match_skip = 's:comment\|string'
|
|
236 <
|
|
237 If you want to skip matching structures unless they are at the start
|
|
238 of the line (ignoring whitespace) then you can >
|
|
239 :let b:match_skip = 'R:^\s*'
|
|
240 < Do not do this if strings or comments can span several lines, since
|
|
241 the normal syntax checking will not be done if you set b:match_skip.
|
|
242
|
|
243 In LaTeX, since "%" is used as the comment character, you can >
|
|
244 :let b:match_skip = 'r:%'
|
|
245 < Unfortunately, this will skip anything after "\%", an escaped "%". To
|
|
246 allow for this, and also "\\%" (an excaped backslash followed by the
|
|
247 comment character) you can >
|
|
248 :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%'
|
|
249 <
|
799
|
250 See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both
|
7
|
251 syntax and a regular expression.
|
|
252
|
|
253 ==============================================================================
|
|
254 4. Supporting a New Language *matchit-newlang*
|
|
255 *b:match_words*
|
|
256 In order for matchit.vim to support a new language, you must define a suitable
|
|
257 pattern for |b:match_words|. You may also want to set some of the
|
|
258 |matchit-configure| variables, as described above. If your language has a
|
|
259 complicated syntax, or many keywords, you will need to know something about
|
|
260 Vim's |regular-expression|s.
|
|
261
|
|
262 The format for |b:match_words| is similar to that of the 'matchpairs' option:
|
|
263 it is a comma (,)-separated list of groups; each group is a colon(:)-separated
|
799
|
264 list of patterns (regular expressions). Commas and backslashes that are part
|
|
265 of a pattern should be escaped with backslashes ('\:' and '\,'). It is OK to
|
|
266 have only one group; the effect is undefined if a group has only one pattern.
|
|
267 A simple example is >
|
7
|
268 :let b:match_words = '\<if\>:\<endif\>,'
|
|
269 \ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>'
|
|
270 (In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if"
|
|
271 matches the end of "endif" but "\<if\>" does not.) Then banging on the "%"
|
|
272 key will bounce the cursor between "if" and the matching "endif"; and from
|
|
273 "while" to any matching "continue" or "break", then to the matching "endwhile"
|
|
274 and back to the "while". It is almost always easier to use |literal-string|s
|
|
275 (single quotes) as above: '\<if\>' rather than "\\<if\\>" and so on.
|
|
276
|
|
277 Exception: If the ":" character does not appear in b:match_words, then it is
|
|
278 treated as an expression to be evaluated. For example, >
|
|
279 :let b:match_words = 'GetMatchWords()'
|
|
280 allows you to define a function. This can return a different string depending
|
|
281 on the current syntax, for example.
|
|
282
|
|
283 Once you have defined the appropriate value of |b:match_words|, you will
|
|
284 probably want to have this set automatically each time you edit the
|
|
285 appropriate file type. The recommended way to do this is by adding the
|
|
286 definition to a |filetype-plugin| file.
|
|
287
|
|
288 Tips: Be careful that your initial pattern does not match your final pattern.
|
|
289 See the example above for the use of word-boundary expressions. It is usually
|
|
290 better to use ".\{-}" (as many as necessary) instead of ".*" (as many as
|
|
291 possible). See |\{-|. For example, in the string "<tag>label</tag>", "<.*>"
|
|
292 matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and
|
|
293 "</tag>".
|
|
294
|
|
295 *matchit-spaces* *matchit-s:notend*
|
|
296 If "if" is to be paired with "end if" (Note the space!) then word boundaries
|
|
297 are not enough. Instead, define a regular expression s:notend that will match
|
|
298 anything but "end" and use it as follows: >
|
|
299 :let s:notend = '\%(\<end\s\+\)\@<!'
|
|
300 :let b:match_words = s:notend . '\<if\>:\<end\s\+if\>'
|
|
301 < *matchit-s:sol*
|
|
302 This is a simplified version of what is done for Ada. The s:notend is a
|
|
303 |script-variable|. Similarly, you may want to define a start-of-line regular
|
|
304 expression >
|
|
305 :let s:sol = '\%(^\|;\)\s*'
|
|
306 if keywords are only recognized after the start of a line or after a
|
|
307 semicolon (;), with optional white space.
|
|
308
|
|
309 *matchit-backref* *matchit-\1*
|
|
310 In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the
|
|
311 INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred
|
|
312 to as back references, or backrefs. For example, >
|
|
313 :let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>'
|
|
314 means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note
|
|
315 that "\1" does not refer to the "\(h\)" in this example. If you have
|
|
316 "\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything
|
|
317 up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1"
|
|
318 refers to everything and "\2" refers to "\(parentheses\)". If you use a
|
|
319 variable such as |s:notend| or |s:sol| in the previous paragraph then remember
|
|
320 to count any "\(" patterns in this variable. You do not have to count groups
|
|
321 defined by |\%(\)|.
|
|
322
|
|
323 It should be possible to resolve back references from any pattern in the
|
|
324 group. For example, >
|
|
325 :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2'
|
|
326 would not work because "\2" cannot be determined from "morefoo" and "\1"
|
|
327 cannot be determined from "andbar". On the other hand, >
|
|
328 :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
|
|
329 should work (and have the same effect as "foobar:barfoo:endfoobar"), although
|
|
330 this has not been thoroughly tested.
|
|
331
|
|
332 You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has
|
|
333 not been thouroughly tested in matchit.vim.) For example, if the keyword "if"
|
|
334 must occur at the start of the line, with optional white space, you might use
|
|
335 the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of
|
|
336 at the start of the line. For another example, if HTML had only one tag then
|
|
337 one could >
|
|
338 :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>'
|
|
339 so that "%" can bounce between matching "<" and ">" pairs or (starting on
|
|
340 "tag" or "/tag") between matching tags. Without the |\@<=|, the script would
|
|
341 bounce from "tag" to the "<" in "</tag>", and another "%" would not take you
|
|
342 back to where you started.
|
|
343
|
|
344 DEBUGGING *matchit-debug* *:MatchDebug*
|
|
345
|
|
346 If you are having trouble figuring out the appropriate definition of
|
|
347 |b:match_words| then you can take advantage of the same information I use when
|
|
348 debugging the script. This is especially true if you are not sure whether
|
|
349 your patterns or my script are at fault! To make this more convenient, I have
|
|
350 made the command :MatchDebug, which defines the variable |b:match_debug| and
|
|
351 creates a Matchit menu. This menu makes it convenient to check the values of
|
|
352 the variables described below. You will probably also want to read
|
|
353 |matchit-details| above.
|
|
354
|
|
355 Defining the variable |b:match_debug| causes the script to set the following
|
|
356 variables, each time you hit the "%" key. Several of these are only defined
|
|
357 if |b:match_words| includes |backref|s.
|
|
358
|
|
359 *b:match_pat*
|
|
360 The b:match_pat variable is set to |b:match_words| with |backref|s parsed.
|
|
361 *b:match_match*
|
|
362 The b:match_match variable is set to the bit of text that is recognized as a
|
|
363 match.
|
|
364 *b:match_col*
|
|
365 The b:match_col variable is set to the cursor column of the start of the
|
|
366 matching text.
|
|
367 *b:match_wholeBR*
|
|
368 The b:match_wholeBR variable is set to the comma-separated group of patterns
|
|
369 that matches, with |backref|s unparsed.
|
|
370 *b:match_iniBR*
|
|
371 The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|.
|
|
372 *b:match_ini*
|
|
373 The b:match_ini variable is set to the first pattern in |b:match_wholeBR|,
|
|
374 with |backref|s resolved from |b:match_match|.
|
|
375 *b:match_tail*
|
|
376 The b:match_tail variable is set to the remaining patterns in
|
|
377 |b:match_wholeBR|, with |backref|s resolved from |b:match_match|.
|
|
378 *b:match_word*
|
|
379 The b:match_word variable is set to the pattern from |b:match_wholeBR| that
|
|
380 matches |b:match_match|.
|
|
381 *b:match_table*
|
|
382 The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in
|
|
383 |b:match_word|.
|
|
384
|
|
385 ==============================================================================
|
|
386 5. Known Bugs and Limitations *matchit-bugs*
|
|
387
|
|
388 Just because I know about a bug does not mean that it is on my todo list. I
|
|
389 try to respond to reports of bugs that cause real problems. If it does not
|
|
390 cause serious problems, or if there is a work-around, a bug may sit there for
|
|
391 a while. Moral: if a bug (known or not) bothers you, let me know.
|
|
392
|
|
393 The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may
|
|
394 have undesired effects in Select mode |Select-mode-mapping|. At least, if you
|
|
395 want to replace the selection with any character in "ag%[]" there will be a
|
|
396 pause of |'updatetime'| first.
|
|
397
|
|
398 It would be nice if "\0" were recognized as the entire pattern. That is, it
|
|
399 would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may
|
|
400 try to implement this in a future version. (This is not so easy to arrange as
|
|
401 you might think!)
|
|
402
|
|
403 ==============================================================================
|
|
404 vim:tw=78:fo=tcq2:
|