patch 7.4.1649
Problem:    The matchit plugin needs to be copied to be used.
Solution:   Put the matchit plugin in an optional package.
diff --git a/runtime/macros/README.txt b/runtime/macros/README.txt
index ce61cd3..f599c0a 100644
--- a/runtime/macros/README.txt
+++ b/runtime/macros/README.txt
@@ -15,8 +15,6 @@
 
 justify.vim		user function for justifying text
 
-matchit.vim + matchit.txt  make % match if-fi, HTML tags, and much more
-
 less.sh + less.vim	make Vim work like less (or more)
 
 shellmenu.vim		menus for editing shell scripts in the GUI version
@@ -26,5 +24,9 @@
 editexisting.vim	when editing a file that is already edited with
 			another Vim instance
 
-This one is only for Unix.  It can be found in the extra archive:
+This one is only for Unix.
 file_select.vim		macros that make a handy file selector
+
+The matchit plugin has been moved to an optional package.  To load it put this
+line in your vimrc file:
+	:packadd matchit
diff --git a/runtime/macros/matchit.txt b/runtime/macros/matchit.txt
deleted file mode 100644
index 8a3a96e..0000000
--- a/runtime/macros/matchit.txt
+++ /dev/null
@@ -1,406 +0,0 @@
-*matchit.txt*   Extended "%" matching
-
-For instructions on installing this file, type
-	:help matchit-install
-inside Vim.
-
-For Vim version 6.3.  Last change:  2007 Aug 29
-
-
-		  VIM REFERENCE MANUAL    by Benji Fisher
-
-*matchit* *matchit.vim*
-
-1. Extended matching with "%"				|matchit-intro|
-2. Activation						|matchit-activate|
-3. Configuration					|matchit-configure|
-4. Supporting a New Language				|matchit-newlang|
-5. Known Bugs and Limitations				|matchit-bugs|
-
-The functionality mentioned here is a plugin, see |add-plugin|.
-This plugin is only available if 'compatible' is not set.
-You can avoid loading this plugin by setting the "loaded_matchit" variable
-in your |vimrc| file: >
-	:let loaded_matchit = 1
-
-{Vi does not have any of this}
-
-==============================================================================
-1. Extended matching with "%"				*matchit-intro*
-
-							*matchit-%*
-%	Cycle forward through matching groups, such as "if", "else", "endif",
-	as specified by |b:match_words|.
-
-							*g%* *v_g%* *o_g%*
-g%	Cycle backwards through matching groups, as specified by
-	|b:match_words|.  For example, go from "if" to "endif" to "else".
-
-							*[%* *v_[%* *o_[%*
-[%	Go to [count] previous unmatched group, as specified by
-	|b:match_words|.  Similar to |[{|.
-
-							*]%* *v_]%* *o_]%*
-]%	Go to [count] next unmatched group, as specified by
-	|b:match_words|.  Similar to |]}|.
-
-							*v_a%*
-a%	In Visual mode, select the matching group, as specified by
-	|b:match_words|, containing the cursor.  Similar to |v_a[|.
-	A [count] is ignored, and only the first character of the closing
-	pattern is selected.
-
-In Vim, as in plain vi, the percent key, |%|, jumps the cursor from a brace,
-bracket, or paren to its match.  This can be configured with the 'matchpairs'
-option.  The matchit plugin extends this in several ways:
-
-	    You can match whole words, such as "if" and "endif", not just
-	single characters.  You can also specify a |regular-expression|.
-	    You can define groups with more than two words, such as "if",
-	"else", "endif".  Banging on the "%" key will cycle from the "if" to
-	the first "else", the next "else", ..., the closing "endif", and back
-	to the opening "if".  Nested structures are skipped.  Using |g%| goes
-	in the reverse direction.
-	    By default, words inside comments and strings are ignored, unless
-	the cursor is inside a comment or string when you type "%".  If the
-	only thing you want to do is modify the behavior of "%" so that it
-	behaves this way, you do not have to define |b:match_words|, since the
-	script uses the 'matchpairs' option as well as this variable.
-
-See |matchit-details| for details on what the script does, and |b:match_words|
-for how to specify matching patterns.
-
-MODES:			*matchit-modes* *matchit-v_%* *matchit-o_%*
-
-Mostly, % and related motions (|g%| and |[%| and |]%|) work just like built-in
-|motion| commands in |Operator-pending| and |Visual| modes.  However, you
-cannot make these motions |linewise| or |characterwise|, since the |:omap|s
-that define them start with "v" in order to make the default behavior
-inclusive.  (See |o_v|.)  In other words, "dV%" will not work.  The
-work-around is to go through Visual mode:  "V%d" will work.
-
-LANGUAGES:					*matchit-languages*
-
-Currently, the following languages are supported:  Ada, ASP with VBS, Csh,
-DTD, Entity, Essbase, Fortran, HTML, JSP (same as HTML), LaTeX, Lua, Pascal,
-SGML, Shell, Tcsh, Vim, XML.  Other languages may already have support via
-the default |filetype-plugin|s in the standard vim distribution.
-
-To support a new language, see |matchit-newlang| below.
-
-DETAILS:				*matchit-details* *matchit-parse*
-
-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
-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
-example, "\(foo\|bar\):end\1" is parsed to yield
-"\(foo\|bar\):end\(foo\|bar\)".  This can get tricky, especially if there are
-nested groups.  If debugging is turned on, the parsed version is saved as
-|b:match_pat|.
-
-							*matchit-choose*
-Next, the script looks for a word on the current line that matches the pattern
-just constructed.  It includes the patterns from the 'matchpairs' option.
-The goal is to do what you expect, which turns out to be a little complicated.
-The script follows these rules:
-
-	Insist on a match that ends on or after the cursor.
-	Prefer a match that includes the cursor position (that is, one that
-		starts on or before the cursor).
-	Prefer a match that starts as close to the cursor as possible.
-	If more than one pattern in |b:match_words| matches, choose the one
-		that is listed first.
-
-Examples:
-
-	Suppose you >
-		:let b:match_words = '<:>,<tag>:</tag>'
-<	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
-	also matches.  If the cursor is on the "t", however, then '<tag>' is
-	preferred, because this matches a bit of text containing the cursor.
-	If the two groups of patterns were reversed then '<' would never be
-	preferred.
-
-	Suppose you >
-		:let b:match_words = 'if:end if'
-<	(Note the space!) and hit "%" with the cursor at the end of "end if".
-	Then "if" matches, which is probably not what you want, but if the
-	cursor starts on the "end " then "end if" is chosen.  (You can avoid
-	this problem by using a more complicated pattern.)
-
-If there is no match, the cursor does not move.  (Before version 1.13 of the
-script, it would fall back on the usual behavior of |%|).  If debugging is
-turned on, the matched bit of text is saved as |b:match_match| and the cursor
-column of the start of the match is saved as |b:match_col|.
-
-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
-saved as |b:match_ini| (the first pattern) and |b:match_tail| (the rest).  If
-there are |backref|s then, in addition, the matching pattern is saved as
-|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
-|b:match_match| and substituted into each pattern in the matching group.
-
-The script decides whether to search forwards or backwards and chooses
-arguments for the |searchpair()| function.  Then, the cursor is moved to the
-start of the match, and |searchpair()| is called.  By default, matching
-structures inside strings and comments are ignored.  This can be changed by
-setting |b:match_skip|.
-
-==============================================================================
-2. Activation						*matchit-activate*
-
-You can use this script as a plugin, by copying it to your plugin directory.
-See |add-global-plugin| for instructions.  You can also add a line to your
-|vimrc| file, such as >
-	:source $VIMRUNTIME/macros/matchit.vim
-or >
-	:runtime macros/matchit.vim
-Either way, the script should start working the next time you start up Vim.
-
-(Earlier versions of the script did nothing unless a |buffer-variable| named
-|b:match_words| was defined.  Even earlier versions contained autocommands
-that set this variable for various file types.  Now, |b:match_words| is
-defined in many of the default |filetype-plugin|s instead.)
-
-For a new language, you can add autocommands to the script or to your vimrc
-file, but the recommended method is to add a line such as >
-	let b:match_words = '\<foo\>:\<bar\>'
-to the |filetype-plugin| for your language.  See |b:match_words| below for how
-this variable is interpreted.
-
-TROUBLESHOOTING					*matchit-troubleshoot*
-
-The script should work in most installations of Vim.  It may not work if Vim
-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
-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
-defined automatically.
-
-==============================================================================
-3. Configuration					*matchit-configure*
-
-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
-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
-can be defined in the |filetype-plugin| or autocommand that defines
-|b:match_words| or "on the fly."
-
-The main variable is |b:match_words|.  It is described in the section below on
-supporting a new language.
-
-				*MatchError* *matchit-hl* *matchit-highlight*
-MatchError is the highlight group for error messages from the script.  By
-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,
-if you use the GUI version of Vim and your command line is normally white, you
-can do >
-	:hi MatchError guifg=white guibg=white
-<
-						*b:match_ignorecase*
-If you >
-	:let b:match_ignorecase = 1
-then matchit.vim acts as if 'ignorecase' is set: for example, "end" and "END"
-are equivalent.  If you >
-	:let b:match_ignorecase = 0
-then matchit.vim treats "end" and "END" differently.  (There will be no
-b:match_infercase option unless someone requests it.)
-
-						*b:match_debug*
-Define b:match_debug if you want debugging information to be saved.  See
-|matchit-debug|, below.
-
-						*b:match_skip*
-If b:match_skip is defined, it is passed as the skip argument to
-|searchpair()|.  This controls when matching structures are skipped, or
-ignored.  By default, they are ignored inside comments and strings, as
-determined by the |syntax| mechanism.  (If syntax highlighting is turned off,
-nothing is skipped.)  You can set b:match_skip to a string, which evaluates to
-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
-supported by matchit.vim:
-	s:foo becomes (current syntax item) =~ foo
-	S:foo becomes (current syntax item) !~ foo
-	r:foo becomes (line before cursor) =~ foo
-	R:foo becomes (line before cursor) !~ foo
-(The "s" is meant to suggest "syntax", and the "r" is meant to suggest
-"regular expression".)
-
-Examples:
-
-	You can get the default behavior with >
-		:let b:match_skip = 's:comment\|string'
-<
-	If you want to skip matching structures unless they are at the start
-	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
-	the normal syntax checking will not be done if you set b:match_skip.
-
-	In LaTeX, since "%" is used as the comment character, you can >
-		:let b:match_skip = 'r:%'
-<	Unfortunately, this will skip anything after "\%", an escaped "%".  To
-	allow for this, and also "\\%" (an excaped backslash followed by the
-	comment character) you can >
-		:let b:match_skip = 'r:\(^\|[^\\]\)\(\\\\\)*%'
-<
-	See the $VIMRUNTIME/ftplugin/vim.vim for an example that uses both
-	syntax and a regular expression.
-
-==============================================================================
-4. Supporting a New Language				*matchit-newlang*
-							*b:match_words*
-In order for matchit.vim to support a new language, you must define a suitable
-pattern for |b:match_words|.  You may also want to set some of the
-|matchit-configure| variables, as described above.  If your language has a
-complicated syntax, or many keywords, you will need to know something about
-Vim's |regular-expression|s.
-
-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
-list of patterns (regular expressions).  Commas and backslashes that are part
-of a pattern should be escaped with backslashes ('\:' and '\,').  It is OK to
-have only one group; the effect is undefined if a group has only one pattern.
-A simple example is >
-	:let b:match_words = '\<if\>:\<endif\>,'
-		\ . '\<while\>:\<continue\>:\<break\>:\<endwhile\>'
-(In Vim regular expressions, |\<| and |\>| denote word boundaries.  Thus "if"
-matches the end of "endif" but "\<if\>" does not.)  Then banging on the "%"
-key will bounce the cursor between "if" and the matching "endif"; and from
-"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
-(single quotes) as above:  '\<if\>' rather than "\\<if\\>" and so on.
-
-Exception:  If the ":" character does not appear in b:match_words, then it is
-treated as an expression to be evaluated.  For example, >
-	:let b:match_words = 'GetMatchWords()'
-allows you to define a function.  This can return a different string depending
-on the current syntax, for example.
-
-Once you have defined the appropriate value of |b:match_words|, you will
-probably want to have this set automatically each time you edit the
-appropriate file type.  The recommended way to do this is by adding the
-definition to a |filetype-plugin| file.
-
-Tips: Be careful that your initial pattern does not match your final pattern.
-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
-possible).  See |\{-|.  For example, in the string "<tag>label</tag>", "<.*>"
-matches the whole string whereas "<.\{-}>" and "<[^>]*>" match "<tag>" and
-"</tag>".
-
-				*matchit-spaces* *matchit-s:notend*
-If "if" is to be paired with "end if" (Note the space!) then word boundaries
-are not enough.  Instead, define a regular expression s:notend that will match
-anything but "end" and use it as follows: >
-	:let s:notend = '\%(\<end\s\+\)\@<!'
-	:let b:match_words = s:notend . '\<if\>:\<end\s\+if\>'
-<							*matchit-s:sol*
-This is a simplified version of what is done for Ada.  The s:notend is a
-|script-variable|.  Similarly, you may want to define a start-of-line regular
-expression >
-	:let s:sol = '\%(^\|;\)\s*'
-if keywords are only recognized after the start of a line or after a
-semicolon (;), with optional white space.
-
-					*matchit-backref* *matchit-\1*
-In any group, the expressions |\1|, |\2|, ..., |\9| refer to parts of the
-INITIAL pattern enclosed in |\(|escaped parentheses|\)|.  These are referred
-to as back references, or backrefs.  For example, >
-	:let b:match_words = '\<b\(o\+\)\>:\(h\)\1\>'
-means that "bo" pairs with "ho" and "boo" pairs with "hoo" and so on.  Note
-that "\1" does not refer to the "\(h\)" in this example.  If you have
-"\(nested \(parentheses\)\) then "\d" refers to the d-th "\(" and everything
-up to and including the matching "\)":  in "\(nested\(parentheses\)\)", "\1"
-refers to everything and "\2" refers to "\(parentheses\)".  If you use a
-variable such as |s:notend| or |s:sol| in the previous paragraph then remember
-to count any "\(" patterns in this variable.  You do not have to count groups
-defined by |\%(\)|.
-
-It should be possible to resolve back references from any pattern in the
-group.  For example, >
-	:let b:match_words = '\(foo\)\(bar\):more\1:and\2:end\1\2'
-would not work because "\2" cannot be determined from "morefoo" and "\1"
-cannot be determined from "andbar".  On the other hand, >
-	:let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
-should work (and have the same effect as "foobar:barfoo:endfoobar"), although
-this has not been thoroughly tested.
-
-You can use |zero-width| patterns such as |\@<=| and |\zs|.  (The latter has
-not been thouroughly tested in matchit.vim.)  For example, if the keyword "if"
-must occur at the start of the line, with optional white space, you might use
-the pattern "\(^\s*\)\@<=if" so that the cursor will end on the "i" instead of
-at the start of the line.  For another example, if HTML had only one tag then
-one could >
-	:let b:match_words = '<:>,<\@<=tag>:<\@<=/tag>'
-so that "%" can bounce between matching "<" and ">" pairs or (starting on
-"tag" or "/tag") between matching tags.  Without the |\@<=|, the script would
-bounce from "tag" to the "<" in "</tag>", and another "%" would not take you
-back to where you started.
-
-DEBUGGING				*matchit-debug* *:MatchDebug*
-
-If you are having trouble figuring out the appropriate definition of
-|b:match_words| then you can take advantage of the same information I use when
-debugging the script.  This is especially true if you are not sure whether
-your patterns or my script are at fault!  To make this more convenient, I have
-made the command :MatchDebug, which defines the variable |b:match_debug| and
-creates a Matchit menu.  This menu makes it convenient to check the values of
-the variables described below.  You will probably also want to read
-|matchit-details| above.
-
-Defining the variable |b:match_debug| causes the script to set the following
-variables, each time you hit the "%" key.  Several of these are only defined
-if |b:match_words| includes |backref|s.
-
-							*b:match_pat*
-The b:match_pat variable is set to |b:match_words| with |backref|s parsed.
-							*b:match_match*
-The b:match_match variable is set to the bit of text that is recognized as a
-match.
-							*b:match_col*
-The b:match_col variable is set to the cursor column of the start of the
-matching text.
-							*b:match_wholeBR*
-The b:match_wholeBR variable is set to the comma-separated group of patterns
-that matches, with |backref|s unparsed.
-							*b:match_iniBR*
-The b:match_iniBR variable is set to the first pattern in |b:match_wholeBR|.
-							*b:match_ini*
-The b:match_ini variable is set to the first pattern in |b:match_wholeBR|,
-with |backref|s resolved from |b:match_match|.
-							*b:match_tail*
-The b:match_tail variable is set to the remaining patterns in
-|b:match_wholeBR|, with |backref|s resolved from |b:match_match|.
-							*b:match_word*
-The b:match_word variable is set to the pattern from |b:match_wholeBR| that
-matches |b:match_match|.
-							*b:match_table*
-The back reference '\'.d refers to the same thing as '\'.b:match_table[d] in
-|b:match_word|.
-
-==============================================================================
-5. Known Bugs and Limitations				*matchit-bugs*
-
-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:
diff --git a/runtime/macros/matchit.vim b/runtime/macros/matchit.vim
deleted file mode 100644
index 70867b1..0000000
--- a/runtime/macros/matchit.vim
+++ /dev/null
@@ -1,813 +0,0 @@
-"  matchit.vim: (global plugin) Extended "%" matching
-"  Last Change: Fri Jan 25 10:00 AM 2008 EST
-"  Maintainer:  Benji Fisher PhD   <benji@member.AMS.org>
-"  Version:     1.13.2, for Vim 6.3+
-"  URL:		http://www.vim.org/script.php?script_id=39
-
-" Documentation:
-"  The documentation is in a separate file, matchit.txt .
-
-" Credits:
-"  Vim editor by Bram Moolenaar (Thanks, Bram!)
-"  Original script and design by Raul Segura Acevedo
-"  Support for comments by Douglas Potts
-"  Support for back references and other improvements by Benji Fisher
-"  Support for many languages by Johannes Zellner
-"  Suggestions for improvement, bug reports, and support for additional
-"  languages by Jordi-Albert Batalla, Neil Bird, Servatius Brandt, Mark
-"  Collett, Stephen Wall, Dany St-Amant, Yuheng Xie, and Johannes Zellner.
-
-" Debugging:
-"  If you'd like to try the built-in debugging commands...
-"   :MatchDebug      to activate debugging for the current buffer
-"  This saves the values of several key script variables as buffer-local
-"  variables.  See the MatchDebug() function, below, for details.
-
-" TODO:  I should think about multi-line patterns for b:match_words.
-"   This would require an option:  how many lines to scan (default 1).
-"   This would be useful for Python, maybe also for *ML.
-" TODO:  Maybe I should add a menu so that people will actually use some of
-"   the features that I have implemented.
-" TODO:  Eliminate the MultiMatch function.  Add yet another argument to
-"   Match_wrapper() instead.
-" TODO:  Allow :let b:match_words = '\(\(foo\)\(bar\)\):\3\2:end\1'
-" TODO:  Make backrefs safer by using '\V' (very no-magic).
-" TODO:  Add a level of indirection, so that custom % scripts can use my
-"   work but extend it.
-
-" allow user to prevent loading
-" and prevent duplicate loading
-if exists("loaded_matchit") || &cp
-  finish
-endif
-let loaded_matchit = 1
-let s:last_mps = ""
-let s:last_words = ":"
-
-let s:save_cpo = &cpo
-set cpo&vim
-
-nnoremap <silent> %  :<C-U>call <SID>Match_wrapper('',1,'n') <CR>
-nnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'n') <CR>
-vnoremap <silent> %  :<C-U>call <SID>Match_wrapper('',1,'v') <CR>m'gv``
-vnoremap <silent> g% :<C-U>call <SID>Match_wrapper('',0,'v') <CR>m'gv``
-onoremap <silent> %  v:<C-U>call <SID>Match_wrapper('',1,'o') <CR>
-onoremap <silent> g% v:<C-U>call <SID>Match_wrapper('',0,'o') <CR>
-
-" Analogues of [{ and ]} using matching patterns:
-nnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "n") <CR>
-nnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W",  "n") <CR>
-vmap [% <Esc>[%m'gv``
-vmap ]% <Esc>]%m'gv``
-" vnoremap <silent> [% :<C-U>call <SID>MultiMatch("bW", "v") <CR>m'gv``
-" vnoremap <silent> ]% :<C-U>call <SID>MultiMatch("W",  "v") <CR>m'gv``
-onoremap <silent> [% v:<C-U>call <SID>MultiMatch("bW", "o") <CR>
-onoremap <silent> ]% v:<C-U>call <SID>MultiMatch("W",  "o") <CR>
-
-" text object:
-vmap a% <Esc>[%v]%
-
-" Auto-complete mappings:  (not yet "ready for prime time")
-" TODO Read :help write-plugin for the "right" way to let the user
-" specify a key binding.
-"   let g:match_auto = '<C-]>'
-"   let g:match_autoCR = '<C-CR>'
-" if exists("g:match_auto")
-"   execute "inoremap " . g:match_auto . ' x<Esc>"=<SID>Autocomplete()<CR>Pls'
-" endif
-" if exists("g:match_autoCR")
-"   execute "inoremap " . g:match_autoCR . ' <CR><C-R>=<SID>Autocomplete()<CR>'
-" endif
-" if exists("g:match_gthhoh")
-"   execute "inoremap " . g:match_gthhoh . ' <C-O>:call <SID>Gthhoh()<CR>'
-" endif " gthhoh = "Get the heck out of here!"
-
-let s:notslash = '\\\@<!\%(\\\\\)*'
-
-function! s:Match_wrapper(word, forward, mode) range
-  " In s:CleanUp(), :execute "set" restore_options .
-  let restore_options = (&ic ? " " : " no") . "ignorecase"
-  if exists("b:match_ignorecase")
-    let &ignorecase = b:match_ignorecase
-  endif
-  let restore_options = " ve=" . &ve . restore_options
-  set ve=
-  " If this function was called from Visual mode, make sure that the cursor
-  " is at the correct end of the Visual range:
-  if a:mode == "v"
-    execute "normal! gv\<Esc>"
-  endif
-  " In s:CleanUp(), we may need to check whether the cursor moved forward.
-  let startline = line(".")
-  let startcol = col(".")
-  " Use default behavior if called with a count.
-  if v:count
-    exe "normal! " . v:count . "%"
-    return s:CleanUp(restore_options, a:mode, startline, startcol)
-  end
-
-  " First step:  if not already done, set the script variables
-  "   s:do_BR	flag for whether there are backrefs
-  "   s:pat	parsed version of b:match_words
-  "   s:all	regexp based on s:pat and the default groups
-  "
-  if !exists("b:match_words") || b:match_words == ""
-    let match_words = ""
-    " Allow b:match_words = "GetVimMatchWords()" .
-  elseif b:match_words =~ ":"
-    let match_words = b:match_words
-  else
-    execute "let match_words =" b:match_words
-  endif
-" Thanks to Preben "Peppe" Guldberg and Bram Moolenaar for this suggestion!
-  if (match_words != s:last_words) || (&mps != s:last_mps) ||
-    \ exists("b:match_debug")
-    let s:last_words = match_words
-    let s:last_mps = &mps
-    " The next several lines were here before
-    " BF started messing with this script.
-    " quote the special chars in 'matchpairs', replace [,:] with \| and then
-    " append the builtin pairs (/*, */, #if, #ifdef, #else, #elif, #endif)
-    " let default = substitute(escape(&mps, '[$^.*~\\/?]'), '[,:]\+',
-    "  \ '\\|', 'g').'\|\/\*\|\*\/\|#if\>\|#ifdef\>\|#else\>\|#elif\>\|#endif\>'
-    let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
-      \ '\/\*:\*\/,#\s*if\%(def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
-    " s:all = pattern with all the keywords
-    let match_words = match_words . (strlen(match_words) ? "," : "") . default
-    if match_words !~ s:notslash . '\\\d'
-      let s:do_BR = 0
-      let s:pat = match_words
-    else
-      let s:do_BR = 1
-      let s:pat = s:ParseWords(match_words)
-    endif
-    let s:all = substitute(s:pat, s:notslash . '\zs[,:]\+', '\\|', 'g')
-    let s:all = '\%(' . s:all . '\)'
-    " let s:all = '\%(' . substitute(s:all, '\\\ze[,:]', '', 'g') . '\)'
-    if exists("b:match_debug")
-      let b:match_pat = s:pat
-    endif
-  endif
-
-  " Second step:  set the following local variables:
-  "     matchline = line on which the cursor started
-  "     curcol    = number of characters before match
-  "     prefix    = regexp for start of line to start of match
-  "     suffix    = regexp for end of match to end of line
-  " Require match to end on or after the cursor and prefer it to
-  " start on or before the cursor.
-  let matchline = getline(startline)
-  if a:word != ''
-    " word given
-    if a:word !~ s:all
-      echohl WarningMsg|echo 'Missing rule for word:"'.a:word.'"'|echohl NONE
-      return s:CleanUp(restore_options, a:mode, startline, startcol)
-    endif
-    let matchline = a:word
-    let curcol = 0
-    let prefix = '^\%('
-    let suffix = '\)$'
-  " Now the case when "word" is not given
-  else	" Find the match that ends on or after the cursor and set curcol.
-    let regexp = s:Wholematch(matchline, s:all, startcol-1)
-    let curcol = match(matchline, regexp)
-    " If there is no match, give up.
-    if curcol == -1
-      return s:CleanUp(restore_options, a:mode, startline, startcol)
-    endif
-    let endcol = matchend(matchline, regexp)
-    let suf = strlen(matchline) - endcol
-    let prefix = (curcol ? '^.*\%'  . (curcol + 1) . 'c\%(' : '^\%(')
-    let suffix = (suf ? '\)\%' . (endcol + 1) . 'c.*$'  : '\)$')
-  endif
-  if exists("b:match_debug")
-    let b:match_match = matchstr(matchline, regexp)
-    let b:match_col = curcol+1
-  endif
-
-  " Third step:  Find the group and single word that match, and the original
-  " (backref) versions of these.  Then, resolve the backrefs.
-  " Set the following local variable:
-  " group = colon-separated list of patterns, one of which matches
-  "       = ini:mid:fin or ini:fin
-  "
-  " Reconstruct the version with unresolved backrefs.
-  let patBR = substitute(match_words.',',
-    \ s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
-  let patBR = substitute(patBR, s:notslash.'\zs:\{2,}', ':', 'g')
-  " Now, set group and groupBR to the matching group: 'if:endif' or
-  " 'while:endwhile' or whatever.  A bit of a kluge:  s:Choose() returns
-  " group . "," . groupBR, and we pick it apart.
-  let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
-  let i = matchend(group, s:notslash . ",")
-  let groupBR = strpart(group, i)
-  let group = strpart(group, 0, i-1)
-  " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
-  if s:do_BR " Do the hard part:  resolve those backrefs!
-    let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
-  endif
-  if exists("b:match_debug")
-    let b:match_wholeBR = groupBR
-    let i = matchend(groupBR, s:notslash . ":")
-    let b:match_iniBR = strpart(groupBR, 0, i-1)
-  endif
-
-  " Fourth step:  Set the arguments for searchpair().
-  let i = matchend(group, s:notslash . ":")
-  let j = matchend(group, '.*' . s:notslash . ":")
-  let ini = strpart(group, 0, i-1)
-  let mid = substitute(strpart(group, i,j-i-1), s:notslash.'\zs:', '\\|', 'g')
-  let fin = strpart(group, j)
-  "Un-escape the remaining , and : characters.
-  let ini = substitute(ini, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
-  let mid = substitute(mid, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
-  let fin = substitute(fin, s:notslash . '\zs\\\(:\|,\)', '\1', 'g')
-  " searchpair() requires that these patterns avoid \(\) groups.
-  let ini = substitute(ini, s:notslash . '\zs\\(', '\\%(', 'g')
-  let mid = substitute(mid, s:notslash . '\zs\\(', '\\%(', 'g')
-  let fin = substitute(fin, s:notslash . '\zs\\(', '\\%(', 'g')
-  " Set mid.  This is optimized for readability, not micro-efficiency!
-  if a:forward && matchline =~ prefix . fin . suffix
-    \ || !a:forward && matchline =~ prefix . ini . suffix
-    let mid = ""
-  endif
-  " Set flag.  This is optimized for readability, not micro-efficiency!
-  if a:forward && matchline =~ prefix . fin . suffix
-    \ || !a:forward && matchline !~ prefix . ini . suffix
-    let flag = "bW"
-  else
-    let flag = "W"
-  endif
-  " Set skip.
-  if exists("b:match_skip")
-    let skip = b:match_skip
-  elseif exists("b:match_comment") " backwards compatibility and testing!
-    let skip = "r:" . b:match_comment
-  else
-    let skip = 's:comment\|string'
-  endif
-  let skip = s:ParseSkip(skip)
-  if exists("b:match_debug")
-    let b:match_ini = ini
-    let b:match_tail = (strlen(mid) ? mid.'\|' : '') . fin
-  endif
-
-  " Fifth step:  actually start moving the cursor and call searchpair().
-  " Later, :execute restore_cursor to get to the original screen.
-  let restore_cursor = virtcol(".") . "|"
-  normal! g0
-  let restore_cursor = line(".") . "G" .  virtcol(".") . "|zs" . restore_cursor
-  normal! H
-  let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
-  execute restore_cursor
-  call cursor(0, curcol + 1)
-  " normal! 0
-  " if curcol
-  "   execute "normal!" . curcol . "l"
-  " endif
-  if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
-    let skip = "0"
-  else
-    execute "if " . skip . "| let skip = '0' | endif"
-  endif
-  let sp_return = searchpair(ini, mid, fin, flag, skip)
-  let final_position = "call cursor(" . line(".") . "," . col(".") . ")"
-  " Restore cursor position and original screen.
-  execute restore_cursor
-  normal! m'
-  if sp_return > 0
-    execute final_position
-  endif
-  return s:CleanUp(restore_options, a:mode, startline, startcol, mid.'\|'.fin)
-endfun
-
-" Restore options and do some special handling for Operator-pending mode.
-" The optional argument is the tail of the matching group.
-fun! s:CleanUp(options, mode, startline, startcol, ...)
-  execute "set" a:options
-  " Open folds, if appropriate.
-  if a:mode != "o"
-    if &foldopen =~ "percent"
-      normal! zv
-    endif
-    " In Operator-pending mode, we want to include the whole match
-    " (for example, d%).
-    " This is only a problem if we end up moving in the forward direction.
-  elseif (a:startline < line(".")) ||
-	\ (a:startline == line(".") && a:startcol < col("."))
-    if a:0
-      " Check whether the match is a single character.  If not, move to the
-      " end of the match.
-      let matchline = getline(".")
-      let currcol = col(".")
-      let regexp = s:Wholematch(matchline, a:1, currcol-1)
-      let endcol = matchend(matchline, regexp)
-      if endcol > currcol  " This is NOT off by one!
-	call cursor(0, endcol)
-      endif
-    endif " a:0
-  endif " a:mode != "o" && etc.
-  return 0
-endfun
-
-" Example (simplified HTML patterns):  if
-"   a:groupBR	= '<\(\k\+\)>:</\1>'
-"   a:prefix	= '^.\{3}\('
-"   a:group	= '<\(\k\+\)>:</\(\k\+\)>'
-"   a:suffix	= '\).\{2}$'
-"   a:matchline	=  "123<tag>12" or "123</tag>12"
-" then extract "tag" from a:matchline and return "<tag>:</tag>" .
-fun! s:InsertRefs(groupBR, prefix, group, suffix, matchline)
-  if a:matchline !~ a:prefix .
-    \ substitute(a:group, s:notslash . '\zs:', '\\|', 'g') . a:suffix
-    return a:group
-  endif
-  let i = matchend(a:groupBR, s:notslash . ':')
-  let ini = strpart(a:groupBR, 0, i-1)
-  let tailBR = strpart(a:groupBR, i)
-  let word = s:Choose(a:group, a:matchline, ":", "", a:prefix, a:suffix,
-    \ a:groupBR)
-  let i = matchend(word, s:notslash . ":")
-  let wordBR = strpart(word, i)
-  let word = strpart(word, 0, i-1)
-  " Now, a:matchline =~ a:prefix . word . a:suffix
-  if wordBR != ini
-    let table = s:Resolve(ini, wordBR, "table")
-  else
-    " let table = "----------"
-    let table = ""
-    let d = 0
-    while d < 10
-      if tailBR =~ s:notslash . '\\' . d
-	" let table[d] = d
-	let table = table . d
-      else
-	let table = table . "-"
-      endif
-      let d = d + 1
-    endwhile
-  endif
-  let d = 9
-  while d
-    if table[d] != "-"
-      let backref = substitute(a:matchline, a:prefix.word.a:suffix,
-	\ '\'.table[d], "")
-	" Are there any other characters that should be escaped?
-      let backref = escape(backref, '*,:')
-      execute s:Ref(ini, d, "start", "len")
-      let ini = strpart(ini, 0, start) . backref . strpart(ini, start+len)
-      let tailBR = substitute(tailBR, s:notslash . '\zs\\' . d,
-	\ escape(backref, '\\&'), 'g')
-    endif
-    let d = d-1
-  endwhile
-  if exists("b:match_debug")
-    if s:do_BR
-      let b:match_table = table
-      let b:match_word = word
-    else
-      let b:match_table = ""
-      let b:match_word = ""
-    endif
-  endif
-  return ini . ":" . tailBR
-endfun
-
-" Input a comma-separated list of groups with backrefs, such as
-"   a:groups = '\(foo\):end\1,\(bar\):end\1'
-" and return a comma-separated list of groups with backrefs replaced:
-"   return '\(foo\):end\(foo\),\(bar\):end\(bar\)'
-fun! s:ParseWords(groups)
-  let groups = substitute(a:groups.",", s:notslash.'\zs[,:]*,[,:]*', ',', 'g')
-  let groups = substitute(groups, s:notslash . '\zs:\{2,}', ':', 'g')
-  let parsed = ""
-  while groups =~ '[^,:]'
-    let i = matchend(groups, s:notslash . ':')
-    let j = matchend(groups, s:notslash . ',')
-    let ini = strpart(groups, 0, i-1)
-    let tail = strpart(groups, i, j-i-1) . ":"
-    let groups = strpart(groups, j)
-    let parsed = parsed . ini
-    let i = matchend(tail, s:notslash . ':')
-    while i != -1
-      " In 'if:else:endif', ini='if' and word='else' and then word='endif'.
-      let word = strpart(tail, 0, i-1)
-      let tail = strpart(tail, i)
-      let i = matchend(tail, s:notslash . ':')
-      let parsed = parsed . ":" . s:Resolve(ini, word, "word")
-    endwhile " Now, tail has been used up.
-    let parsed = parsed . ","
-  endwhile " groups =~ '[^,:]'
-  let parsed = substitute(parsed, ',$', '', '')
-  return parsed
-endfun
-
-" TODO I think this can be simplified and/or made more efficient.
-" TODO What should I do if a:start is out of range?
-" Return a regexp that matches all of a:string, such that
-" matchstr(a:string, regexp) represents the match for a:pat that starts
-" as close to a:start as possible, before being preferred to after, and
-" ends after a:start .
-" Usage:
-" let regexp = s:Wholematch(getline("."), 'foo\|bar', col(".")-1)
-" let i      = match(getline("."), regexp)
-" let j      = matchend(getline("."), regexp)
-" let match  = matchstr(getline("."), regexp)
-fun! s:Wholematch(string, pat, start)
-  let group = '\%(' . a:pat . '\)'
-  let prefix = (a:start ? '\(^.*\%<' . (a:start + 2) . 'c\)\zs' : '^')
-  let len = strlen(a:string)
-  let suffix = (a:start+1 < len ? '\(\%>'.(a:start+1).'c.*$\)\@=' : '$')
-  if a:string !~ prefix . group . suffix
-    let prefix = ''
-  endif
-  return prefix . group . suffix
-endfun
-
-" No extra arguments:  s:Ref(string, d) will
-" find the d'th occurrence of '\(' and return it, along with everything up
-" to and including the matching '\)'.
-" One argument:  s:Ref(string, d, "start") returns the index of the start
-" of the d'th '\(' and any other argument returns the length of the group.
-" Two arguments:  s:Ref(string, d, "foo", "bar") returns a string to be
-" executed, having the effect of
-"   :let foo = s:Ref(string, d, "start")
-"   :let bar = s:Ref(string, d, "len")
-fun! s:Ref(string, d, ...)
-  let len = strlen(a:string)
-  if a:d == 0
-    let start = 0
-  else
-    let cnt = a:d
-    let match = a:string
-    while cnt
-      let cnt = cnt - 1
-      let index = matchend(match, s:notslash . '\\(')
-      if index == -1
-	return ""
-      endif
-      let match = strpart(match, index)
-    endwhile
-    let start = len - strlen(match)
-    if a:0 == 1 && a:1 == "start"
-      return start - 2
-    endif
-    let cnt = 1
-    while cnt
-      let index = matchend(match, s:notslash . '\\(\|\\)') - 1
-      if index == -2
-	return ""
-      endif
-      " Increment if an open, decrement if a ')':
-      let cnt = cnt + (match[index]=="(" ? 1 : -1)  " ')'
-      " let cnt = stridx('0(', match[index]) + cnt
-      let match = strpart(match, index+1)
-    endwhile
-    let start = start - 2
-    let len = len - start - strlen(match)
-  endif
-  if a:0 == 1
-    return len
-  elseif a:0 == 2
-    return "let " . a:1 . "=" . start . "| let " . a:2 . "=" . len
-  else
-    return strpart(a:string, start, len)
-  endif
-endfun
-
-" Count the number of disjoint copies of pattern in string.
-" If the pattern is a literal string and contains no '0' or '1' characters
-" then s:Count(string, pattern, '0', '1') should be faster than
-" s:Count(string, pattern).
-fun! s:Count(string, pattern, ...)
-  let pat = escape(a:pattern, '\\')
-  if a:0 > 1
-    let foo = substitute(a:string, '[^'.a:pattern.']', "a:1", "g")
-    let foo = substitute(a:string, pat, a:2, "g")
-    let foo = substitute(foo, '[^' . a:2 . ']', "", "g")
-    return strlen(foo)
-  endif
-  let result = 0
-  let foo = a:string
-  let index = matchend(foo, pat)
-  while index != -1
-    let result = result + 1
-    let foo = strpart(foo, index)
-    let index = matchend(foo, pat)
-  endwhile
-  return result
-endfun
-
-" s:Resolve('\(a\)\(b\)', '\(c\)\2\1\1\2') should return table.word, where
-" word = '\(c\)\(b\)\(a\)\3\2' and table = '-32-------'.  That is, the first
-" '\1' in target is replaced by '\(a\)' in word, table[1] = 3, and this
-" indicates that all other instances of '\1' in target are to be replaced
-" by '\3'.  The hard part is dealing with nesting...
-" Note that ":" is an illegal character for source and target,
-" unless it is preceded by "\".
-fun! s:Resolve(source, target, output)
-  let word = a:target
-  let i = matchend(word, s:notslash . '\\\d') - 1
-  let table = "----------"
-  while i != -2 " There are back references to be replaced.
-    let d = word[i]
-    let backref = s:Ref(a:source, d)
-    " The idea is to replace '\d' with backref.  Before we do this,
-    " replace any \(\) groups in backref with :1, :2, ... if they
-    " correspond to the first, second, ... group already inserted
-    " into backref.  Later, replace :1 with \1 and so on.  The group
-    " number w+b within backref corresponds to the group number
-    " s within a:source.
-    " w = number of '\(' in word before the current one
-    let w = s:Count(
-    \ substitute(strpart(word, 0, i-1), '\\\\', '', 'g'), '\(', '1')
-    let b = 1 " number of the current '\(' in backref
-    let s = d " number of the current '\(' in a:source
-    while b <= s:Count(substitute(backref, '\\\\', '', 'g'), '\(', '1')
-    \ && s < 10
-      if table[s] == "-"
-	if w + b < 10
-	  " let table[s] = w + b
-	  let table = strpart(table, 0, s) . (w+b) . strpart(table, s+1)
-	endif
-	let b = b + 1
-	let s = s + 1
-      else
-	execute s:Ref(backref, b, "start", "len")
-	let ref = strpart(backref, start, len)
-	let backref = strpart(backref, 0, start) . ":". table[s]
-	\ . strpart(backref, start+len)
-	let s = s + s:Count(substitute(ref, '\\\\', '', 'g'), '\(', '1')
-      endif
-    endwhile
-    let word = strpart(word, 0, i-1) . backref . strpart(word, i+1)
-    let i = matchend(word, s:notslash . '\\\d') - 1
-  endwhile
-  let word = substitute(word, s:notslash . '\zs:', '\\', 'g')
-  if a:output == "table"
-    return table
-  elseif a:output == "word"
-    return word
-  else
-    return table . word
-  endif
-endfun
-
-" Assume a:comma = ",".  Then the format for a:patterns and a:1 is
-"   a:patterns = "<pat1>,<pat2>,..."
-"   a:1 = "<alt1>,<alt2>,..."
-" If <patn> is the first pattern that matches a:string then return <patn>
-" if no optional arguments are given; return <patn>,<altn> if a:1 is given.
-fun! s:Choose(patterns, string, comma, branch, prefix, suffix, ...)
-  let tail = (a:patterns =~ a:comma."$" ? a:patterns : a:patterns . a:comma)
-  let i = matchend(tail, s:notslash . a:comma)
-  if a:0
-    let alttail = (a:1 =~ a:comma."$" ? a:1 : a:1 . a:comma)
-    let j = matchend(alttail, s:notslash . a:comma)
-  endif
-  let current = strpart(tail, 0, i-1)
-  if a:branch == ""
-    let currpat = current
-  else
-    let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
-  endif
-  while a:string !~ a:prefix . currpat . a:suffix
-    let tail = strpart(tail, i)
-    let i = matchend(tail, s:notslash . a:comma)
-    if i == -1
-      return -1
-    endif
-    let current = strpart(tail, 0, i-1)
-    if a:branch == ""
-      let currpat = current
-    else
-      let currpat = substitute(current, s:notslash . a:branch, '\\|', 'g')
-    endif
-    if a:0
-      let alttail = strpart(alttail, j)
-      let j = matchend(alttail, s:notslash . a:comma)
-    endif
-  endwhile
-  if a:0
-    let current = current . a:comma . strpart(alttail, 0, j-1)
-  endif
-  return current
-endfun
-
-" Call this function to turn on debugging information.  Every time the main
-" script is run, buffer variables will be saved.  These can be used directly
-" or viewed using the menu items below.
-if !exists(":MatchDebug")
-  command! -nargs=0 MatchDebug call s:Match_debug()
-endif
-
-fun! s:Match_debug()
-  let b:match_debug = 1	" Save debugging information.
-  " pat = all of b:match_words with backrefs parsed
-  amenu &Matchit.&pat	:echo b:match_pat<CR>
-  " match = bit of text that is recognized as a match
-  amenu &Matchit.&match	:echo b:match_match<CR>
-  " curcol = cursor column of the start of the matching text
-  amenu &Matchit.&curcol	:echo b:match_col<CR>
-  " wholeBR = matching group, original version
-  amenu &Matchit.wh&oleBR	:echo b:match_wholeBR<CR>
-  " iniBR = 'if' piece, original version
-  amenu &Matchit.ini&BR	:echo b:match_iniBR<CR>
-  " ini = 'if' piece, with all backrefs resolved from match
-  amenu &Matchit.&ini	:echo b:match_ini<CR>
-  " tail = 'else\|endif' piece, with all backrefs resolved from match
-  amenu &Matchit.&tail	:echo b:match_tail<CR>
-  " fin = 'endif' piece, with all backrefs resolved from match
-  amenu &Matchit.&word	:echo b:match_word<CR>
-  " '\'.d in ini refers to the same thing as '\'.table[d] in word.
-  amenu &Matchit.t&able	:echo '0:' . b:match_table . ':9'<CR>
-endfun
-
-" Jump to the nearest unmatched "(" or "if" or "<tag>" if a:spflag == "bW"
-" or the nearest unmatched "</tag>" or "endif" or ")" if a:spflag == "W".
-" Return a "mark" for the original position, so that
-"   let m = MultiMatch("bW", "n") ... execute m
-" will return to the original position.  If there is a problem, do not
-" move the cursor and return "", unless a count is given, in which case
-" go up or down as many levels as possible and again return "".
-" TODO This relies on the same patterns as % matching.  It might be a good
-" idea to give it its own matching patterns.
-fun! s:MultiMatch(spflag, mode)
-  if !exists("b:match_words") || b:match_words == ""
-    return ""
-  end
-  let restore_options = (&ic ? "" : "no") . "ignorecase"
-  if exists("b:match_ignorecase")
-    let &ignorecase = b:match_ignorecase
-  endif
-  let startline = line(".")
-  let startcol = col(".")
-
-  " First step:  if not already done, set the script variables
-  "   s:do_BR	flag for whether there are backrefs
-  "   s:pat	parsed version of b:match_words
-  "   s:all	regexp based on s:pat and the default groups
-  " This part is copied and slightly modified from s:Match_wrapper().
-  let default = escape(&mps, '[$^.*~\\/?]') . (strlen(&mps) ? "," : "") .
-    \ '\/\*:\*\/,#\s*if\%(def\)\=:#\s*else\>:#\s*elif\>:#\s*endif\>'
-  " Allow b:match_words = "GetVimMatchWords()" .
-  if b:match_words =~ ":"
-    let match_words = b:match_words
-  else
-    execute "let match_words =" b:match_words
-  endif
-  if (match_words != s:last_words) || (&mps != s:last_mps) ||
-    \ exists("b:match_debug")
-    let s:last_words = match_words
-    let s:last_mps = &mps
-    if match_words !~ s:notslash . '\\\d'
-      let s:do_BR = 0
-      let s:pat = match_words
-    else
-      let s:do_BR = 1
-      let s:pat = s:ParseWords(match_words)
-    endif
-    let s:all = '\%(' . substitute(s:pat . (strlen(s:pat)?",":"") . default,
-      \	'[,:]\+','\\|','g') . '\)'
-    if exists("b:match_debug")
-      let b:match_pat = s:pat
-    endif
-  endif
-
-  " Second step:  figure out the patterns for searchpair()
-  " and save the screen, cursor position, and 'ignorecase'.
-  " - TODO:  A lot of this is copied from s:Match_wrapper().
-  " - maybe even more functionality should be split off
-  " - into separate functions!
-  let cdefault = (s:pat =~ '[^,]$' ? "," : "") . default
-  let open =  substitute(s:pat . cdefault,
-	\ s:notslash . '\zs:.\{-}' . s:notslash . ',', '\\),\\(', 'g')
-  let open =  '\(' . substitute(open, s:notslash . '\zs:.*$', '\\)', '')
-  let close = substitute(s:pat . cdefault,
-	\ s:notslash . '\zs,.\{-}' . s:notslash . ':', '\\),\\(', 'g')
-  let close = substitute(close, '^.\{-}' . s:notslash . ':', '\\(', '') . '\)'
-  if exists("b:match_skip")
-    let skip = b:match_skip
-  elseif exists("b:match_comment") " backwards compatibility and testing!
-    let skip = "r:" . b:match_comment
-  else
-    let skip = 's:comment\|string'
-  endif
-  let skip = s:ParseSkip(skip)
-  " let restore_cursor = line(".") . "G" . virtcol(".") . "|"
-  " normal! H
-  " let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
-  let restore_cursor = virtcol(".") . "|"
-  normal! g0
-  let restore_cursor = line(".") . "G" .  virtcol(".") . "|zs" . restore_cursor
-  normal! H
-  let restore_cursor = "normal!" . line(".") . "Gzt" . restore_cursor
-  execute restore_cursor
-
-  " Third step: call searchpair().
-  " Replace '\('--but not '\\('--with '\%(' and ',' with '\|'.
-  let openpat =  substitute(open, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
-  let openpat = substitute(openpat, ',', '\\|', 'g')
-  let closepat = substitute(close, '\(\\\@<!\(\\\\\)*\)\@<=\\(', '\\%(', 'g')
-  let closepat = substitute(closepat, ',', '\\|', 'g')
-  if skip =~ 'synID' && !(has("syntax") && exists("g:syntax_on"))
-    let skip = '0'
-  else
-    execute "if " . skip . "| let skip = '0' | endif"
-  endif
-  mark '
-  let level = v:count1
-  while level
-    if searchpair(openpat, '', closepat, a:spflag, skip) < 1
-      call s:CleanUp(restore_options, a:mode, startline, startcol)
-      return ""
-    endif
-    let level = level - 1
-  endwhile
-
-  " Restore options and return a string to restore the original position.
-  call s:CleanUp(restore_options, a:mode, startline, startcol)
-  return restore_cursor
-endfun
-
-" Search backwards for "if" or "while" or "<tag>" or ...
-" and return "endif" or "endwhile" or "</tag>" or ... .
-" For now, this uses b:match_words and the same script variables
-" as s:Match_wrapper() .  Later, it may get its own patterns,
-" either from a buffer variable or passed as arguments.
-" fun! s:Autocomplete()
-"   echo "autocomplete not yet implemented :-("
-"   if !exists("b:match_words") || b:match_words == ""
-"     return ""
-"   end
-"   let startpos = s:MultiMatch("bW")
-"
-"   if startpos == ""
-"     return ""
-"   endif
-"   " - TODO:  figure out whether 'if' or '<tag>' matched, and construct
-"   " - the appropriate closing.
-"   let matchline = getline(".")
-"   let curcol = col(".") - 1
-"   " - TODO:  Change the s:all argument if there is a new set of match pats.
-"   let regexp = s:Wholematch(matchline, s:all, curcol)
-"   let suf = strlen(matchline) - matchend(matchline, regexp)
-"   let prefix = (curcol ? '^.\{'  . curcol . '}\%(' : '^\%(')
-"   let suffix = (suf ? '\).\{' . suf . '}$'  : '\)$')
-"   " Reconstruct the version with unresolved backrefs.
-"   let patBR = substitute(b:match_words.',', '[,:]*,[,:]*', ',', 'g')
-"   let patBR = substitute(patBR, ':\{2,}', ':', "g")
-"   " Now, set group and groupBR to the matching group: 'if:endif' or
-"   " 'while:endwhile' or whatever.
-"   let group = s:Choose(s:pat, matchline, ",", ":", prefix, suffix, patBR)
-"   let i = matchend(group, s:notslash . ",")
-"   let groupBR = strpart(group, i)
-"   let group = strpart(group, 0, i-1)
-"   " Now, matchline =~ prefix . substitute(group,':','\|','g') . suffix
-"   if s:do_BR
-"     let group = s:InsertRefs(groupBR, prefix, group, suffix, matchline)
-"   endif
-" " let g:group = group
-"
-"   " - TODO:  Construct the closing from group.
-"   let fake = "end" . expand("<cword>")
-"   execute startpos
-"   return fake
-" endfun
-
-" Close all open structures.  "Get the heck out of here!"
-" fun! s:Gthhoh()
-"   let close = s:Autocomplete()
-"   while strlen(close)
-"     put=close
-"     let close = s:Autocomplete()
-"   endwhile
-" endfun
-
-" Parse special strings as typical skip arguments for searchpair():
-"   s:foo becomes (current syntax item) =~ foo
-"   S:foo becomes (current syntax item) !~ foo
-"   r:foo becomes (line before cursor) =~ foo
-"   R:foo becomes (line before cursor) !~ foo
-fun! s:ParseSkip(str)
-  let skip = a:str
-  if skip[1] == ":"
-    if skip[0] == "s"
-      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') =~? '" .
-	\ strpart(skip,2) . "'"
-    elseif skip[0] == "S"
-      let skip = "synIDattr(synID(line('.'),col('.'),1),'name') !~? '" .
-	\ strpart(skip,2) . "'"
-    elseif skip[0] == "r"
-      let skip = "strpart(getline('.'),0,col('.'))=~'" . strpart(skip,2). "'"
-    elseif skip[0] == "R"
-      let skip = "strpart(getline('.'),0,col('.'))!~'" . strpart(skip,2). "'"
-    endif
-  endif
-  return skip
-endfun
-
-let &cpo = s:save_cpo
-unlet s:save_cpo
-
-" vim:sts=2:sw=2: