" Vim filetype plugin file utility " Language: * (various) " Maintainer: Dave Silvia " Date: 6/30/2004 " The start of match (b:SOM) default is: " '\<' " The end of match (b:EOM) default is: " '\>' " " If you want to use some other start/end of match, just assign the " value to the b:SOM|EOM variable in your filetype script. " " SEE: :h pattern.txt " :h pattern-searches " :h regular-expression " :h matchit let s:myName=expand(":t") " matchit.vim not loaded -- don't do anyting if !exists("loaded_matchit") echomsg s:myName.": matchit.vim not loaded -- finishing without loading" finish endif " already been here -- don't redefine if exists("*AppendMatchGroup") finish endif " Function To Build b:match_words " The following function, 'AppendMatchGroup', helps to increase " readability of your filetype script if you choose to use matchit. " It also precludes many construction errors, reducing the " construction to simply invoking the function with the match words. " As an example, let's take the ubiquitous if/then/else/endif type " of construct. This is how the entry in your filetype script would look. " " " source the AppendMatchGroup function file " runtime ftplugin/AppendMatchGroup.vim " " " fill b:match_words " call AppendMatchGroup('if,then,else,endif') " " And the b:match_words constructed would look like: " " \:\:\:\ " " Use of AppendMatchGroup makes your filetype script is a little " less busy and a lot more readable. Additionally, it " checks three critical things: " " 1) Do you have at least 2 entries in your match group. " " 2) Does the buffer variable 'b:match_words' exist? if not, create it. " " 3) If the buffer variable 'b:match_words' does exist, is the last " character a ','? If not, add it before appending. " " You should now be able to match 'if/then/else/endif' in succession " in your source file, in just about any construction you may have " chosen for them. " " To add another group, simply call 'AppendMatchGroup again. E.G.: " " call AppendMatchGroup('while,do,endwhile') function AppendMatchGroup(mwordList) let List=a:mwordList let Comma=match(List,',') if Comma == -1 || Comma == strlen(List)-1 echoerr "Must supply a comma separated list of at least 2 entries." echoerr "Supplied list: <".List.">" return endif let listEntryBegin=0 let listEntryEnd=Comma let listEntry=strpart(List,listEntryBegin,listEntryEnd-listEntryBegin) let List=strpart(List,Comma+1) let Comma=match(List,',') " if listEntry is all spaces || List is empty || List is all spaces if (match(listEntry,'\s\+') == 0 && match(listEntry,'\S\+') == -1) \ || List == '' || (match(List,'\s\+') == 0 && match(List,'\S\+') == -1) echoerr "Can't use all spaces for an entry <".listEntry.">" echoerr "Remaining supplied list: <".List.">" return endif if !exists("b:SOM") let b:SOM='\<' endif if !exists("b:EOM") let b:EOM='\>' endif if !exists("b:match_words") let b:match_words='' endif if b:match_words != '' && match(b:match_words,',$') == -1 let b:match_words=b:match_words.',' endif " okay, all set add first entry in this list let b:match_words=b:match_words.b:SOM.listEntry.b:EOM.':' while Comma != -1 let listEntryEnd=Comma let listEntry=strpart(List,listEntryBegin,listEntryEnd-listEntryBegin) let List=strpart(List,Comma+1) let Comma=match(List,',') " if listEntry is all spaces if match(listEntry,'\s\+') == 0 && match(listEntry,'\S\+') == -1 echoerr "Can't use all spaces for an entry <".listEntry."> - skipping" echoerr "Remaining supplied list: <".List.">" continue endif let b:match_words=b:match_words.b:SOM.listEntry.b:EOM.':' endwhile let listEntry=List let b:match_words=b:match_words.b:SOM.listEntry.b:EOM endfunction " TODO: Write a wrapper to handle multiple groups in one function call. " Don't see a lot of utility in this as it would undoubtedly warrant " continuation lines in the filetype script and it would be a toss " up as to which is more readable: individual calls one to a line or " a single call with continuation lines. I vote for the former.