1" Vim filetype plugin file utility
2" Language:    * (various)
3" Maintainer:  Dave Silvia <dsilvia@mchsi.com>
4" Date:        6/30/2004
5
6" The start of match (b:SOM) default is:
7"       '\<'
8" The end of match (b:EOM) default is:
9"       '\>'
10"
11" If you want to use some other start/end of match, just assign the
12" value to the b:SOM|EOM variable in your filetype script.
13"
14" SEE: :h pattern.txt
15"      :h pattern-searches
16"      :h regular-expression
17"      :h matchit
18
19let s:myName=expand("<sfile>:t")
20
21" matchit.vim not loaded -- don't do anyting
22if !exists("loaded_matchit")
23	echomsg s:myName.": matchit.vim not loaded -- finishing without loading"
24	finish
25endif
26
27" already been here -- don't redefine
28if exists("*AppendMatchGroup")
29	finish
30endif
31
32" Function To Build b:match_words
33" The following function, 'AppendMatchGroup', helps to increase
34" readability of your filetype script if you choose to use matchit.
35" It also precludes many construction errors, reducing the
36" construction to simply invoking the function with the match words.
37" As an example, let's take the ubiquitous if/then/else/endif type
38" of construct.  This is how the entry in your filetype script would look.
39"
40"     " source the AppendMatchGroup function file
41"     runtime ftplugin/AppendMatchGroup.vim
42"
43"     " fill b:match_words
44"     call AppendMatchGroup('if,then,else,endif')
45"
46" And the b:match_words constructed would look like:
47"
48"     \<if\>:\<then\>:\<else\>:\<endif\>
49" 
50" Use of AppendMatchGroup makes your filetype script is a little
51" less busy and a lot more readable.  Additionally, it
52" checks three critical things:
53"
54"      1)  Do you have at least 2 entries in your match group.
55"
56"      2)  Does the buffer variable 'b:match_words' exist?  if not, create it.
57"
58"      3)  If the buffer variable 'b:match_words' does exist, is the last
59"          character a ','?  If not, add it before appending.
60" 
61" You should now be able to match 'if/then/else/endif' in succession
62" in your source file, in just about any construction you may have
63" chosen for them.
64"
65" To add another group, simply call 'AppendMatchGroup again.  E.G.:
66"
67"      call AppendMatchGroup('while,do,endwhile')
68
69function AppendMatchGroup(mwordList)
70	let List=a:mwordList
71	let Comma=match(List,',')
72	if Comma == -1 || Comma == strlen(List)-1
73		echoerr "Must supply a comma separated list of at least 2 entries."
74		echoerr "Supplied list: <".List.">"
75		return
76	endif
77	let listEntryBegin=0
78	let listEntryEnd=Comma
79	let listEntry=strpart(List,listEntryBegin,listEntryEnd-listEntryBegin)
80	let List=strpart(List,Comma+1)
81	let Comma=match(List,',')
82	" if listEntry is all spaces || List is empty || List is all spaces
83	if (match(listEntry,'\s\+') == 0 && match(listEntry,'\S\+') == -1)
84			\ || List == '' || (match(List,'\s\+') == 0 && match(List,'\S\+') == -1)
85		echoerr "Can't use all spaces for an entry <".listEntry.">"
86		echoerr "Remaining supplied list: <".List.">"
87		return
88	endif
89
90	if !exists("b:SOM")
91		let b:SOM='\<'
92	endif
93	if !exists("b:EOM")
94		let b:EOM='\>'
95	endif
96	if !exists("b:match_words")
97		let b:match_words=''
98	endif
99	if b:match_words != '' && match(b:match_words,',$') == -1
100		let b:match_words=b:match_words.','
101	endif
102	" okay, all set add first entry in this list
103	let b:match_words=b:match_words.b:SOM.listEntry.b:EOM.':'
104	while Comma != -1
105		let listEntryEnd=Comma
106		let listEntry=strpart(List,listEntryBegin,listEntryEnd-listEntryBegin)
107		let List=strpart(List,Comma+1)
108		let Comma=match(List,',')
109		" if listEntry is all spaces
110		if match(listEntry,'\s\+') == 0 && match(listEntry,'\S\+') == -1
111			echoerr "Can't use all spaces for an entry <".listEntry."> - skipping"
112			echoerr "Remaining supplied list: <".List.">"
113			continue
114		endif
115		let b:match_words=b:match_words.b:SOM.listEntry.b:EOM.':'
116	endwhile
117	let listEntry=List
118	let b:match_words=b:match_words.b:SOM.listEntry.b:EOM
119endfunction
120
121" TODO:  Write a wrapper to handle multiple groups in one function call.
122"        Don't see a lot of utility in this as it would undoubtedly warrant
123"        continuation lines in the filetype script and it would be a toss
124"        up as to which is more readable: individual calls one to a line or
125"        a single call with continuation lines.  I vote for the former.
126