| version 1.1, 2003/11/03 16:15:40 |
version 1.2, 2005/03/09 20:33:03 |
|
|
| *matchit.txt* Extended "%" matching
|
*matchit.txt* Extended "%" matching |
|
|
|
| For instructions on installing this file, type
|
For instructions on installing this file, type |
| :help add-local-help
|
:help matchit-install |
| inside Vim.
|
inside Vim. |
|
|
|
| For Vim version 6.1. Last change: 2002 May 15
|
For Vim version 6.3. Last change: 2004 May 12 |
|
|
|
|
|
|
| VIM REFERENCE MANUAL by Benji Fisher
|
VIM REFERENCE MANUAL by Benji Fisher |
|
|
|
| *matchit* *matchit.vim*
|
*matchit* *matchit.vim* |
|
|
|
| 1. Extended matching with "%" |matchit-intro|
|
1. Extended matching with "%" |matchit-intro| |
| 2. Activation |matchit-activate|
|
2. Activation |matchit-activate| |
| 3. Configuration |matchit-configure|
|
3. Configuration |matchit-configure| |
| 4. Supporting a New Language |matchit-newlang|
|
4. Supporting a New Language |matchit-newlang| |
| 5. Known Bugs and Limitations |matchit-bugs|
|
5. Known Bugs and Limitations |matchit-bugs| |
|
|
|
| The functionality mentioned here is a plugin, see |add-plugin|.
|
The functionality mentioned here is a plugin, see |add-plugin|. |
| This plugin is only available if 'compatible' is not set.
|
This plugin is only available if 'compatible' is not set. |
| You can avoid loading this plugin by setting the "loaded_matchit" variable
|
You can avoid loading this plugin by setting the "loaded_matchit" variable |
| in your |vimrc| file: >
|
in your |vimrc| file: > |
| :let loaded_matchit = 1
|
:let loaded_matchit = 1 |
|
|
|
| {Vi does not have any of this}
|
{Vi does not have any of this} |
|
|
|
| ==============================================================================
|
============================================================================== |
| 1. Extended matching with "%" *matchit-intro*
|
1. Extended matching with "%" *matchit-intro* |
|
|
|
| *matchit-%*
|
*matchit-%* |
| % Cycle forward through matching groups, such as "if", "else", "endif",
|
% Cycle forward through matching groups, such as "if", "else", "endif", |
| as specified by |b:match_words|.
|
as specified by |b:match_words|. |
|
|
|
| *g%*
|
*g%* *v_g%* *o_g%* |
| g% Cycle backwards through matching groups, as specified by
|
g% Cycle backwards through matching groups, as specified by |
| |b:match_words|. For example, go from "endif" to "else" to "if".
|
|b:match_words|. For example, go from "endif" to "else" to "if". |
|
|
|
| *[%*
|
*[%* *v_[%* *o_[%* |
| [% Go to [count] previous unmatched group, as specified by
|
[% Go to [count] previous unmatched group, as specified by |
| |b:match_words|. Similar to |[{|.
|
|b:match_words|. Similar to |[{|. |
|
|
|
| *]%*
|
*]%* *v_]%* *o_]%* |
| ]% Go to [count] next unmatched group, as specified by
|
]% Go to [count] next unmatched group, as specified by |
| |b:match_words|. Similar to |]}|.
|
|b:match_words|. Similar to |]}|. |
|
|
|
|
|
*v_a%* |
| In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace,
|
a% In Visual mode, select the matching group, as specified by |
| bracket, or paren to its match. This can be configured with the 'matchpairs'
|
|b:match_words|, containing the cursor. Similar to |v_a[|. |
| option. The matchit plugin extends this in several ways:
|
A [count] is ignored, and only the first character of the closing |
|
|
pattern is selected. |
| You can match whole words, such as "if" and "endif", not just
|
|
| single characters. You can also specify a |regular-expression|.
|
In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace, |
| You can define groups with more than two words, such as "if",
|
bracket, or paren to its match. This can be configured with the 'matchpairs' |
| "else", "endif". Banging on the "%" key will cycle from the "if" to
|
option. The matchit plugin extends this in several ways: |
| the first "else", the next "else", ..., the closing "endif", and back
|
|
| to the opening "if". Nested structures are skipped. Using |g%| goes
|
You can match whole words, such as "if" and "endif", not just |
| in the reverse direction.
|
single characters. You can also specify a |regular-expression|. |
| By default, words inside comments and strings are ignored, unless
|
You can define groups with more than two words, such as "if", |
| the cursor is inside a comment or string when you type "%". If the
|
"else", "endif". Banging on the "%" key will cycle from the "if" to |
| only thing you want to do is modify the behavior of "%" so that it
|
the first "else", the next "else", ..., the closing "endif", and back |
| behaves this way, you can >
|
to the opening "if". Nested structures are skipped. Using |g%| goes |
| :let b:match_words = &matchpairs
|
in the reverse direction. |
| <
|
By default, words inside comments and strings are ignored, unless |
| See |matchit-details| for details on what the script does, and |b:match_words|
|
the cursor is inside a comment or string when you type "%". If the |
| for how to specify matching patterns.
|
only thing you want to do is modify the behavior of "%" so that it |
|
|
behaves this way, you can > |
| MODES: *matchit-modes* *matchit-v_%* *matchit-o_%*
|
:let b:match_words = &matchpairs |
|
|
< |
| Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in
|
See |matchit-details| for details on what the script does, and |b:match_words| |
| |motion| commands in |Operator-pending| and |Visual| modes. However, you
|
for how to specify matching patterns. |
| cannot make these motions |linewise| or |characterwise|, since the |:omap|s
|
|
| that define them start with "v" in order to make the default behavior
|
MODES: *matchit-modes* *matchit-v_%* *matchit-o_%* |
| inclusive. (See |o_v|.) In other words, "dV%" will not work. The
|
|
| work-around is to go through Visual mode: "V%d" will work.
|
Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in |
|
|
|motion| commands in |Operator-pending| and |Visual| modes. However, you |
| LANGUAGES: *matchit-languages*
|
cannot make these motions |linewise| or |characterwise|, since the |:omap|s |
|
|
that define them start with "v" in order to make the default behavior |
| Currently, the following languages are supported: Ada, ASP with VBS, Csh,
|
inclusive. (See |o_v|.) In other words, "dV%" will not work. The |
| DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal,
|
work-around is to go through Visual mode: "V%d" will work. |
| SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via
|
|
| |filetype-plugin|s.
|
LANGUAGES: *matchit-languages* |
|
|
|
| To support a new language, see |matchit-newlang| below.
|
Currently, the following languages are supported: Ada, ASP with VBS, Csh, |
|
|
DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal, |
| DETAILS: *matchit-details* *matchit-parse*
|
SGML, Shell, Tcsh, Vim, XML. Other languages may already have support via |
|
|
|filetype-plugin|s. |
| Here is an outline of what matchit.vim does each time you hit the "%" key. If
|
|
| there are |backref|s in |b:match_words| then the first step is to produce a
|
To support a new language, see |matchit-newlang| below. |
| version in which these back references have been eliminated; if there are no
|
|
| |backref|s then this step is skipped. This step is called parsing. For
|
DETAILS: *matchit-details* *matchit-parse* |
| example, "\(foo\|bar\):end\1" is parsed to yield
|
|
| "\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are
|
Here is an outline of what matchit.vim does each time you hit the "%" key. If |
| nested groups. If debugging is turned on, the parsed version is saved as
|
there are |backref|s in |b:match_words| then the first step is to produce a |
| |b:match_pat|.
|
version in which these back references have been eliminated; if there are no |
|
|
|backref|s then this step is skipped. This step is called parsing. For |
| *matchit-choose*
|
example, "\(foo\|bar\):end\1" is parsed to yield |
| Next, the script looks for a word on the current line that matches the pattern
|
"\(foo\|bar\):end\(foo\|bar\)". This can get tricky, especially if there are |
| just constructed. It includes the patterns from the 'matchpairs' option.
|
nested groups. If debugging is turned on, the parsed version is saved as |
| The goal is to do what you expect, which turns out to be a little complicated.
|
|b:match_pat|. |
| The script follows these rules:
|
|
|
|
*matchit-choose* |
| Insist on a match that ends on or after the cursor.
|
Next, the script looks for a word on the current line that matches the pattern |
| Prefer a match that includes the cursor position (that is, one that
|
just constructed. It includes the patterns from the 'matchpairs' option. |
| starts on or before the cursor).
|
The goal is to do what you expect, which turns out to be a little complicated. |
| Prefer a match that starts as close to the cursor as possible.
|
The script follows these rules: |
| Prefer a match in |b:match_words| to a match in 'matchpairs'.
|
|
| If more than one pattern in |b:match_words| matches, choose the one
|
Insist on a match that ends on or after the cursor. |
| that is listed first.
|
Prefer a match that includes the cursor position (that is, one that |
|
|
starts on or before the cursor). |
| Examples:
|
Prefer a match that starts as close to the cursor as possible. |
|
|
Prefer a match in |b:match_words| to a match in 'matchpairs'. |
| Suppose you >
|
If more than one pattern in |b:match_words| matches, choose the one |
| :let b:match_words = '<:>,<tag>:</tag>'
|
that is listed first. |
| < and hit "%" with the cursor on or before the "<" in "a <tag> is born".
|
|
| The pattern '<' comes first, so it is preferred over '<tag>', which
|
Examples: |
| also matches. If the cursor is on the "t", however, then '<tag>' is
|
|
| preferred, because this matches a bit of text containing the cursor.
|
Suppose you > |
| If the two groups of patterns were reversed then '<' would never be
|
:let b:match_words = '<:>,<tag>:</tag>' |
| preferred.
|
< and hit "%" with the cursor on or before the "<" in "a <tag> is born". |
|
|
The pattern '<' comes first, so it is preferred over '<tag>', which |
| Suppose you >
|
also matches. If the cursor is on the "t", however, then '<tag>' is |
| :let b:match_words = 'if:end if'
|
preferred, because this matches a bit of text containing the cursor. |
| < (Note the space!) and hit "%" with the cursor at the end of "end if".
|
If the two groups of patterns were reversed then '<' would never be |
| Then "if" matches, which is probably not what you want, but if the
|
preferred. |
| cursor starts on the "end " then "end if" is chosen. (You can avoid
|
|
| this problem by using a more complicated pattern.)
|
Suppose you > |
|
|
:let b:match_words = 'if:end if' |
| If there is no match, the script falls back on the usual behavior of |%|. If
|
< (Note the space!) and hit "%" with the cursor at the end of "end if". |
| debugging is turned on, the matched bit of text is saved as |b:match_match|
|
Then "if" matches, which is probably not what you want, but if the |
| and the cursor column of the start of the match is saved as |b:match_col|.
|
cursor starts on the "end " then "end if" is chosen. (You can avoid |
|
|
this problem by using a more complicated pattern.) |
| Next, the script looks through |b:match_words| (original and parsed versions)
|
|
| for the group and pattern that match. If debugging is turned on, the group is
|
If there is no match, the script falls back on the usual behavior of |%|. If |
| saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If
|
debugging is turned on, the matched bit of text is saved as |b:match_match| |
| there are |backref|s then, in addition, the matching pattern is saved as
|
and the cursor column of the start of the match is saved as |b:match_col|. |
| |b:match_word| and a table of translations is saved as |b:match_table|. If
|
|
| there are |backref|s, these are determined from the matching pattern and
|
Next, the script looks through |b:match_words| (original and parsed versions) |
| |b:match_match| and substituted into each pattern in the matching group.
|
for the group and pattern that match. If debugging is turned on, the group is |
|
|
saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest). If |
| The script decides whether to search forwards or backwards and chooses
|
there are |backref|s then, in addition, the matching pattern is saved as |
| arguments for the |searchpair()| function. Then, the cursor is moved to the
|
|b:match_word| and a table of translations is saved as |b:match_table|. If |
| start of the match, and |searchpair()| is called. By default, matching
|
there are |backref|s, these are determined from the matching pattern and |
| structures inside strings and comments are ignored. This can be changed by
|
|b:match_match| and substituted into each pattern in the matching group. |
| setting |b:match_skip|.
|
|
|
|
The script decides whether to search forwards or backwards and chooses |
| ==============================================================================
|
arguments for the |searchpair()| function. Then, the cursor is moved to the |
| 2. Activation *matchit-activate*
|
start of the match, and |searchpair()| is called. By default, matching |
|
|
structures inside strings and comments are ignored. This can be changed by |
| You can use this script as a plugin, by copying it to your plugin directory.
|
setting |b:match_skip|. |
| See |add-global-plugin| for instructions. You can also add a line to your
|
|
| |vimrc| file, such as >
|
============================================================================== |
| :source $VIMRUNTIME/macros/matchit.vim
|
2. Activation *matchit-activate* |
| or >
|
|
| :runtime macros/matchit.vim
|
You can use this script as a plugin, by copying it to your plugin directory. |
| Either way, the script should start working the next time you start up Vim.
|
See |add-global-plugin| for instructions. You can also add a line to your |
|
|
|vimrc| file, such as > |
| The script does nothing unless it finds a |buffer-variable| named
|
:source $VIMRUNTIME/macros/matchit.vim |
| |b:match_words|. The script contains autocommands that set this variable for
|
or > |
| various file types: see |matchit-languages| above. For a new language, you
|
:runtime macros/matchit.vim |
| can add autocommands to the script or to your vimrc file, but the recommended
|
Either way, the script should start working the next time you start up Vim. |
| method is to add a line such as >
|
|
| let b:match_words = '\<foo\>:\<bar\>'
|
The script does nothing unless it finds a |buffer-variable| named |
| to the |filetype-plugin| for your language. See |b:match_words| below for how
|
|b:match_words|. The script contains autocommands that set this variable for |
| this variable is interpreted.
|
various file types: see |matchit-languages| above. For a new language, you |
|
|
can add autocommands to the script or to your vimrc file, but the recommended |
| TROUBLESHOOTING *matchit-troubleshoot*
|
method is to add a line such as > |
|
|
let b:match_words = '\<foo\>:\<bar\>' |
| The script should work in most installations of Vim. It may not work if Vim
|
to the |filetype-plugin| for your language. See |b:match_words| below for how |
| was compiled with a minimal feature set, for example if the |+syntax| option
|
this variable is interpreted. |
| was not enabled. If your Vim has support for syntax compiled in, but you do
|
|
| not have |syntax| highlighting turned on, matchit.vim should work, but it may
|
TROUBLESHOOTING *matchit-troubleshoot* |
| fail to skip matching groups in comments and strings. If the |filetype|
|
|
| mechanism is turned off, the |b:match_words| variable will probably not be
|
The script should work in most installations of Vim. It may not work if Vim |
| defined automatically.
|
was compiled with a minimal feature set, for example if the |+syntax| option |
|
|
was not enabled. If your Vim has support for syntax compiled in, but you do |
| ==============================================================================
|
not have |syntax| highlighting turned on, matchit.vim should work, but it may |
| 3. Configuration *matchit-configure*
|
fail to skip matching groups in comments and strings. If the |filetype| |
|
|
mechanism is turned off, the |b:match_words| variable will probably not be |
| There are several variables that govern the behavior of matchit.vim. Note
|
defined automatically. |
| that these are variables local to the buffer, not options, so use |:let| to
|
|
| define them, not |:set|. Some of these variables have values that matter; for
|
============================================================================== |
| others, it only matters whether the variable has been defined. All of these
|
3. Configuration *matchit-configure* |
| can be defined in the |filetype-plugin| or autocommand that defines
|
|
| |b:match_words| or "on the fly."
|
There are several variables that govern the behavior of matchit.vim. Note |
|
|
that these are variables local to the buffer, not options, so use |:let| to |
| The main variable is |b:match_words|. It is described in the section below on
|
define them, not |:set|. Some of these variables have values that matter; for |
| supporting a new language.
|
others, it only matters whether the variable has been defined. All of these |
|
|
can be defined in the |filetype-plugin| or autocommand that defines |
| *b:match_ignorecase*
|
|b:match_words| or "on the fly." |
| If you >
|
|
| :let b:match_ignorecase = 1
|
The main variable is |b:match_words|. It is described in the section below on |
| then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END"
|
supporting a new language. |
| are equivalent. If you >
|
|
| :let b:match_ignorecase = 0
|
*MatchError* *matchit-hl* *matchit-highlight* |
| then matchit.vim treats "end" and "END" differently. (There will be no
|
MatchError is the highlight group for error messages from the script. By |
| b:match_infercase option unless someone requests it.)
|
default, it is linked to WarningMsg. If you do not want to be bothered by |
|
|
error messages, you can define this to be something invisible. For example, |
| *b:match_debug*
|
if you use the GUI version of Vim and your command line is normally white, you |
| Define b:match_debug if you want debugging information to be saved. See
|
can do > |
| |matchit-debug|, below.
|
:hi MatchError guifg=white guibg=white |
|
|
< |
| *b:match_skip*
|
*b:match_ignorecase* |
| If b:match_skip is defined, it is passed as the skip argument to
|
If you > |
| |searchpair()|. This controls when matching structures are skipped, or
|
:let b:match_ignorecase = 1 |
| ignored. By default, they are ignored inside comments and strings, as
|
then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END" |
| determined by the |syntax| mechanism. (If syntax highlighting is turned off,
|
are equivalent. If you > |
| nothing is skipped.) You can set b:match_skip to a string, which evaluates to
|
:let b:match_ignorecase = 0 |
| a non-zero, numerical value if the match is to be skipped or zero if the match
|
then matchit.vim treats "end" and "END" differently. (There will be no |
| should not be skipped. In addition, the following special values are
|
b:match_infercase option unless someone requests it.) |
| supported by matchit.vim:
|
|
| s:foo becomes (current syntax item) =~ foo
|
*b:match_debug* |
| S:foo becomes (current syntax item) !~ foo
|
Define b:match_debug if you want debugging information to be saved. See |
| r:foo becomes (line before cursor) =~ foo
|
|matchit-debug|, below. |
| R:foo becomes (line before cursor) !~ foo
|
|
| (The "s" is meant to suggest "syntax", and the "r" is meant to suggest
|
*b:match_skip* |
| "regular expression".)
|
If b:match_skip is defined, it is passed as the skip argument to |
|
|
|searchpair()|. This controls when matching structures are skipped, or |
| Examples:
|
ignored. By default, they are ignored inside comments and strings, as |
|
|
determined by the |syntax| mechanism. (If syntax highlighting is turned off, |
| You can get the default behavior with >
|
nothing is skipped.) You can set b:match_skip to a string, which evaluates to |
| :let b:match_skip = 's:comment\|string'
|
a non-zero, numerical value if the match is to be skipped or zero if the match |
| <
|
should not be skipped. In addition, the following special values are |
| If you want to skip matching structures unless they are at the start
|
supported by matchit.vim: |
| of the line (ignoring whitespace) then you can >
|
s:foo becomes (current syntax item) =~ foo |
| :let b:match_skip = 'R:^\s*'
|
S:foo becomes (current syntax item) !~ foo |
| < Do not do this if strings or comments can span several lines, since
|
r:foo becomes (line before cursor) =~ foo |
| the normal syntax checking will not be done if you set b:match_skip.
|
R:foo becomes (line before cursor) !~ foo |
|
|
(The "s" is meant to suggest "syntax", and the "r" is meant to suggest |
| In LaTeX, since "%" is used as the comment character, you can >
|
"regular expression".) |
| :let b:match_skip = 'r:%'
|
|
| < Unfortunately, this will skip anything after "\%", an escaped "%". To
|
Examples: |
| allow for this, and also "\\%" (an excaped backslash followed by the
|
|
| comment character) you can >
|
You can get the default behavior with > |
| :let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%'
|
:let b:match_skip = 's:comment\|string' |
| <
|
< |
| See the $VIMRUNTIME/syntax/vim.vim for an example that uses both
|
If you want to skip matching structures unless they are at the start |
| syntax and a regular expression.
|
of the line (ignoring whitespace) then you can > |
|
|
:let b:match_skip = 'R:^\s*' |
| ==============================================================================
|
< Do not do this if strings or comments can span several lines, since |
| 4. Supporting a New Language *matchit-newlang*
|
the normal syntax checking will not be done if you set b:match_skip. |
| *b:match_words*
|
|
| In order for matchit.vim to support a new language, you must define a suitable
|
In LaTeX, since "%" is used as the comment character, you can > |
| pattern for |b:match_words|. You may also want to set some of the
|
:let b:match_skip = 'r:%' |
| |matchit-configure| variables, as described above. If your language has a
|
< Unfortunately, this will skip anything after "\%", an escaped "%". To |
| complicated syntax, or many keywords, you will need to know something about
|
allow for this, and also "\\%" (an excaped backslash followed by the |
| Vim's |regular-expression|s.
|
comment character) you can > |
|
|
:let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%' |
| The format for |b:match_words| is similar to that of the 'matchpairs' option:
|
< |
| it is a comma (,)-separated list of groups; each group is a colon(:)-separated
|
See the $VIMRUNTIME/syntax/vim.vim for an example that uses both |
| list of patterns (regular expressions). It is OK to have only one group; the
|
syntax and a regular expression. |
| effect is undefined if a group has only one pattern. A simple example is >
|
|
| :let b:match_words = '\<if\>:\<endif\>,'
|
============================================================================== |
| \ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>'
|
4. Supporting a New Language *matchit-newlang* |
| (In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if"
|
*b:match_words* |
| matches the end of "endif" but "\<if\>" does not.) Then banging on the "%"
|
In order for matchit.vim to support a new language, you must define a suitable |
| key will bounce the cursor between "if" and the matching "endif"; and from
|
pattern for |b:match_words|. You may also want to set some of the |
| "while" to any matching "continue" or "break", then to the matching "endwhile"
|
|matchit-configure| variables, as described above. If your language has a |
| and back to the "while". It is almost always easier to use |literal-string|s
|
complicated syntax, or many keywords, you will need to know something about |
| (single quotes) as above: '\<if\>' rather than "\\<if\\>" and so on.
|
Vim's |regular-expression|s. |
|
|
|
| Exception: If the ":" character does not appear in b:match_words, then it is
|
The format for |b:match_words| is similar to that of the 'matchpairs' option: |
| treated as an expression to be evaluated. For example, >
|
it is a comma (,)-separated list of groups; each group is a colon(:)-separated |
| :let b:match_words = 'GetMatchWords()'
|
list of patterns (regular expressions). It is OK to have only one group; the |
| allows you to define a function. This can return a different string depending
|
effect is undefined if a group has only one pattern. A simple example is > |
| on the current syntax, for example.
|
:let b:match_words = '\<if\>:\<endif\>,' |
|
|
\ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>' |
| Once you have defined the appropriate value of |b:match_words|, you will
|
(In Vim regular expressions, |\<| and |\>| denote word boundaries. Thus "if" |
| probably want to have this set automatically each time you edit the
|
matches the end of "endif" but "\<if\>" does not.) Then banging on the "%" |
| appropriate file type. The recommended way to do this is by adding the
|
key will bounce the cursor between "if" and the matching "endif"; and from |
| definition to a |filetype-plugin| file.
|
"while" to any matching "continue" or "break", then to the matching "endwhile" |
|
|
and back to the "while". It is almost always easier to use |literal-string|s |
| Tips: Be careful that your initial pattern does not match your final pattern.
|
(single quotes) as above: '\<if\>' rather than "\\<if\\>" and so on. |
| See the example above for the use of word-boundary expressions. It is usually
|
|
| better to use ".\{-}" (as many as necessary) instead of ".*" (as many as
|
Exception: If the ":" character does not appear in b:match_words, then it is |
| possible). See |\{-|. For example, in the string "<tag>label</tag>", "<.*>"
|
treated as an expression to be evaluated. For example, > |
| matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and
|
:let b:match_words = 'GetMatchWords()' |
| "</tag>".
|
allows you to define a function. This can return a different string depending |
|
|
on the current syntax, for example. |
| *matchit-spaces* *matchit-s:notend*
|
|
| If "if" is to be paired with "end if" (Note the space!) then word boundaries
|
Once you have defined the appropriate value of |b:match_words|, you will |
| are not enough. Instead, define a regular expression s:notend that will match
|
probably want to have this set automatically each time you edit the |
| anything but "end" and use it as follows: >
|
appropriate file type. The recommended way to do this is by adding the |
| :let s:notend = '\%(\<end\s\+\)\@<!'
|
definition to a |filetype-plugin| file. |
| :let b:match_words = s:notend . '\<if\>:\<end\s\+if\>'
|
|
| This is a simplified version of what is done for Ada. The s:notend is a
|
Tips: Be careful that your initial pattern does not match your final pattern. |
| |script-variable|. Similarly, you may want *matchit-s:sol*
|
See the example above for the use of word-boundary expressions. It is usually |
| to define a start-of-line regular expression >
|
better to use ".\{-}" (as many as necessary) instead of ".*" (as many as |
| :let s:sol = '\%(^\|;\)\s*'
|
possible). See |\{-|. For example, in the string "<tag>label</tag>", "<.*>" |
| if keywords are only recognized after the start of a line or after a
|
matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and |
| semicolon (;), with optional white space.
|
"</tag>". |
|
|
|
| *matchit-backref* *matchit-\1*
|
*matchit-spaces* *matchit-s:notend* |
| In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the
|
If "if" is to be paired with "end if" (Note the space!) then word boundaries |
| INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred
|
are not enough. Instead, define a regular expression s:notend that will match |
| to as back references, or backrefs. For example, >
|
anything but "end" and use it as follows: > |
| :let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>'
|
:let s:notend = '\%(\<end\s\+\)\@<!' |
| means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note
|
:let b:match_words = s:notend . '\<if\>:\<end\s\+if\>' |
| that "\1" does not refer to the "\(h\)" in this example. If you have
|
< *matchit-s:sol* |
| "\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything
|
This is a simplified version of what is done for Ada. The s:notend is a |
| up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1"
|
|script-variable|. Similarly, you may want to define a start-of-line regular |
| refers to everything and "\2" refers to "\(parentheses\)". If you use a
|
expression > |
| variable such as |s:notend| or |s:sol| in the previous paragraph then remember
|
:let s:sol = '\%(^\|;\)\s*' |
| to count any "\(" patterns in this variable. You do not have to count groups
|
if keywords are only recognized after the start of a line or after a |
| defined by |\%(\)|.
|
semicolon (;), with optional white space. |
|
|
|
| It should be possible to resolve back references from any pattern in the
|
*matchit-backref* *matchit-\1* |
| group. For example, >
|
In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the |
| :let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2'
|
INITIAL pattern enclosed in |\(|escaped parentheses|\)|. These are referred |
| would not work because "\2" cannot be determined from "morefoo" and "\1"
|
to as back references, or backrefs. For example, > |
| cannot be determined from "andbar". On the other hand, >
|
:let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>' |
| :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
|
means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on. Note |
| should work (and have the same effect as "foobar:barfoo:endfoobar"), although
|
that "\1" does not refer to the "\(h\)" in this example. If you have |
| this has not been thoroughly tested.
|
"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything |
|
|
up to and including the matching "\)": in "\(nested\(parentheses\)\)", "\1" |
| You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has
|
refers to everything and "\2" refers to "\(parentheses\)". If you use a |
| not been thouroughly tested in matchit.vim.) For example, if the keyword "if"
|
variable such as |s:notend| or |s:sol| in the previous paragraph then remember |
| must occur at the start of the line, with optional white space, you might use
|
to count any "\(" patterns in this variable. You do not have to count groups |
| the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of
|
defined by |\%(\)|. |
| at the start of the line. For another example, if HTML had only one tag then
|
|
| one could >
|
It should be possible to resolve back references from any pattern in the |
| :let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>'
|
group. For example, > |
| so that "%" can bounce between matching "<" and ">" pairs or (starting on
|
:let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2' |
| "tag" or "/tag") between matching tags. Without the |\@<=|, the script would
|
would not work because "\2" cannot be determined from "morefoo" and "\1" |
| bounce from "tag" to the "<" in "</tag>", and another "%" would not take you
|
cannot be determined from "andbar". On the other hand, > |
| back to where you started.
|
:let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1' |
|
|
should work (and have the same effect as "foobar:barfoo:endfoobar"), although |
| DEBUGGING *matchit-debug* *:MatchDebug*
|
this has not been thoroughly tested. |
|
|
|
| If you are having trouble figuring out the appropriate definition of
|
You can use |zero-width| patterns such as |\@<=| and |\zs|. (The latter has |
| |b:match_words| then you can take advantage of the same information I use when
|
not been thouroughly tested in matchit.vim.) For example, if the keyword "if" |
| debugging the script. This is especially true if you are not sure whether
|
must occur at the start of the line, with optional white space, you might use |
| your patterns or my script are at fault! To make this more convenient, I have
|
the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of |
| made the command :MatchDebug, which defines the variable |b:match_debug| and
|
at the start of the line. For another example, if HTML had only one tag then |
| creates a Matchit menu. This menu makes it convenient to check the values of
|
one could > |
| the variables described below. You will probably also want to read
|
:let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>' |
| |matchit-details| above.
|
so that "%" can bounce between matching "<" and ">" pairs or (starting on |
|
|
"tag" or "/tag") between matching tags. Without the |\@<=|, the script would |
| Defining the variable |b:match_debug| causes the script to set the following
|
bounce from "tag" to the "<" in "</tag>", and another "%" would not take you |
| variables, each time you hit the "%" key. Several of these are only defined
|
back to where you started. |
| if |b:match_words| includes |backref|s.
|
|
|
|
DEBUGGING *matchit-debug* *:MatchDebug* |
| *b:match_pat*
|
|
| The b:match_pat variable is set to |b:match_words| with |backref|s parsed.
|
If you are having trouble figuring out the appropriate definition of |
| *b:match_match*
|
|b:match_words| then you can take advantage of the same information I use when |
| The b:match_match variable is set to the bit of text that is recognized as a
|
debugging the script. This is especially true if you are not sure whether |
| match.
|
your patterns or my script are at fault! To make this more convenient, I have |
| *b:match_col*
|
made the command :MatchDebug, which defines the variable |b:match_debug| and |
| The b:match_col variable is set to the cursor column of the start of the
|
creates a Matchit menu. This menu makes it convenient to check the values of |
| matching text.
|
the variables described below. You will probably also want to read |
| *b:match_wholeBR*
|
|matchit-details| above. |
| The b:match_wholeBR variable is set to the comma-separated group of patterns
|
|
| that matches, with |backref|s unparsed.
|
Defining the variable |b:match_debug| causes the script to set the following |
| *b:match_iniBR*
|
variables, each time you hit the "%" key. Several of these are only defined |
| The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|.
|
if |b:match_words| includes |backref|s. |
| *b:match_ini*
|
|
| The b:match_ini variable is set to the first pattern in |b:match_wholeBR|,
|
*b:match_pat* |
| with |backref|s resolved from |b:match_match|.
|
The b:match_pat variable is set to |b:match_words| with |backref|s parsed. |
| *b:match_tail*
|
*b:match_match* |
| The b:match_tail variable is set to the remaining patterns in
|
The b:match_match variable is set to the bit of text that is recognized as a |
| |b:match_wholeBR|, with |backref|s resolved from |b:match_match|.
|
match. |
| *b:match_word*
|
*b:match_col* |
| The b:match_word variable is set to the pattern from |b:match_wholeBR| that
|
The b:match_col variable is set to the cursor column of the start of the |
| matches |b:match_match|.
|
matching text. |
| *b:match_table*
|
*b:match_wholeBR* |
| The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in
|
The b:match_wholeBR variable is set to the comma-separated group of patterns |
| |b:match_word|.
|
that matches, with |backref|s unparsed. |
|
|
*b:match_iniBR* |
| ==============================================================================
|
The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|. |
| 5. Known Bugs and Limitations *matchit-bugs*
|
*b:match_ini* |
|
|
The b:match_ini variable is set to the first pattern in |b:match_wholeBR|, |
| Just because I know about a bug does not mean that it is on my todo list. I
|
with |backref|s resolved from |b:match_match|. |
| try to respond to reports of bugs that cause real problems. If it does not
|
*b:match_tail* |
| cause serious problems, or if there is a work-around, a bug may sit there for
|
The b:match_tail variable is set to the remaining patterns in |
| a while. Moral: if a bug (known or not) bothers you, let me know.
|
|b:match_wholeBR|, with |backref|s resolved from |b:match_match|. |
|
|
*b:match_word* |
| Changes such as "d%" cannot be repeated with |.|. This seems to be a
|
The b:match_word variable is set to the pattern from |b:match_wholeBR| that |
| fundamental limitation of user-defined motions.
|
matches |b:match_match|. |
|
|
*b:match_table* |
| It would be nice if "\0" were recognized as the entire pattern. That is, it
|
The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in |
| would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may
|
|b:match_word|. |
| try to implement this in a future version. (This is not so easy to arrange as
|
|
| you might think!)
|
============================================================================== |
|
|
5. Known Bugs and Limitations *matchit-bugs* |
| ==============================================================================
|
|
| vim:tw=78:fo=tcq2:
|
Just because I know about a bug does not mean that it is on my todo list. I |
| |
try to respond to reports of bugs that cause real problems. If it does not |
| |
cause serious problems, or if there is a work-around, a bug may sit there for |
| |
a while. Moral: if a bug (known or not) bothers you, let me know. |
| |
|
| |
The various |:vmap|s defined in the script (%, |g%|, |[%|, |]%|, |a%|) may |
| |
have undesired effects in Select mode |Select-mode-mapping|. At least, if you |
| |
want to replace the selection with any character in "ag%[]" there will be a |
| |
pause of |'updatetime'| first. |
| |
|
| |
It would be nice if "\0" were recognized as the entire pattern. That is, it |
| |
would be nice if "foo:\end\0" had the same effect as "\(foo\):\end\1". I may |
| |
try to implement this in a future version. (This is not so easy to arrange as |
| |
you might think!) |
| |
|
| |
============================================================================== |
| |
vim:tw=78:fo=tcq2: |