blob: 768afd5725a0af8750b81e5b6b65c6f31549926b [file] [log] [blame]
Bram Moolenaarf75a9632005-09-13 21:20:47 +00001" Vim completion script
2" Language: XHTML 1.0 Strict
3" Maintainer: Mikolaj Machowski ( mikmach AT wp DOT pl )
Bram Moolenaar09df3122006-01-23 22:23:09 +00004" Last Change: 2006 Jan 22
Bram Moolenaarf75a9632005-09-13 21:20:47 +00005
6function! htmlcomplete#CompleteTags(findstart, base)
7 if a:findstart
8 " locate the start of the word
9 let line = getline('.')
10 let start = col('.') - 1
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000011 let compl_begin = col('.') - 2
12 while start >= 0 && line[start - 1] =~ '\(\k\|[:.-]\)'
13 let start -= 1
Bram Moolenaarf75a9632005-09-13 21:20:47 +000014 endwhile
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000015 if start >= 0 && line[start - 1] =~ '&'
16 let b:entitiescompl = 1
17 let b:compl_context = ''
18 return start
19 endif
20 let stylestart = searchpair('<style\>', '', '<\/style\>', "bnW")
21 let styleend = searchpair('<style\>', '', '<\/style\>', "nW")
22 if stylestart != 0 && styleend != 0
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +000023 let curpos = line('.')
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000024 if stylestart <= curpos && styleend >= curpos
25 let start = col('.') - 1
26 let b:csscompl = 1
27 while start >= 0 && line[start - 1] =~ '\(\k\|-\)'
28 let start -= 1
29 endwhile
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +000030 endif
31 endif
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000032 if !exists("b:csscompl")
33 let b:compl_context = getline('.')[0:(compl_begin)]
Bram Moolenaar09df3122006-01-23 22:23:09 +000034 let b:compl_context = matchstr(b:compl_context, '.*\zs<.*')
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000035 else
36 let b:compl_context = getline('.')[0:compl_begin]
37 endif
Bram Moolenaarf75a9632005-09-13 21:20:47 +000038 return start
39 else
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000040 " Initialize base return lists
41 let res = []
42 let res2 = []
43 " a:base is very short - we need context
44 let context = b:compl_context
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +000045 " Check if we should do CSS completion inside of <style> tag
46 if exists("b:csscompl")
47 unlet! b:csscompl
Bram Moolenaar09df3122006-01-23 22:23:09 +000048 let context = b:compl_context
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000049 return csscomplete#CompleteCSS(0, context)
Bram Moolenaar09df3122006-01-23 22:23:09 +000050 else
51 if len(b:compl_context) == 0 && !exists("b:entitiescompl")
52 return []
53 endif
54 let context = matchstr(b:compl_context, '.\zs.*')
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +000055 endif
Bram Moolenaar09df3122006-01-23 22:23:09 +000056 unlet! b:compl_context
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000057 " Make entities completion
58 if exists("b:entitiescompl")
59 unlet! b:entitiescompl
60
Bram Moolenaara5792f52005-11-23 21:25:05 +000061 if !exists("g:xmldata_xhtml10s")
62 runtime! autoload/xml/xhtml10s.vim
63 endif
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000064
Bram Moolenaara5792f52005-11-23 21:25:05 +000065 let entities = g:xmldata_xhtml10s['vimxmlentities']
66
Bram Moolenaar09df3122006-01-23 22:23:09 +000067 if len(a:base) == 1
68 for m in entities
69 if m =~ '^'.a:base
70 call add(res, m.';')
71 endif
72 endfor
73 return res
74 else
75 for m in entities
76 if m =~? '^'.a:base
77 call add(res, m.';')
78 elseif m =~? a:base
79 call add(res2, m.';')
80 endif
81 endfor
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000082
Bram Moolenaar09df3122006-01-23 22:23:09 +000083 return res + res2
84 endif
85
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000086
87 endif
88 if context =~ '>'
89 " Generally if context contains > it means we are outside of tag and
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +000090 " should abandon action - with one exception: <style> span { bo
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +000091 if context =~ 'style[^>]\{-}>[^<]\{-}$'
92 return csscomplete#CompleteCSS(0, context)
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +000093 else
94 return []
95 endif
96 endif
Bram Moolenaar09df3122006-01-23 22:23:09 +000097 "if context !~ '<$'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +000098
Bram Moolenaarf75a9632005-09-13 21:20:47 +000099 " Set attribute groups
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000100 let coreattrs = ["id", "class", "style", "title"]
101 let i18n = ["lang", "xml:lang", "dir=\"ltr\" ", "dir=\"rtl\" "]
102 let events = ["onclick", "ondblclick", "onmousedown", "onmouseup", "onmousemove",
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000103 \ "onmouseover", "onmouseout", "onkeypress", "onkeydown", "onkeyup"]
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000104 let focus = ["accesskey", "tabindex", "onfocus", "onblur"]
105 let coregroup = coreattrs + i18n + events
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000106 " find tags matching with "context"
107 " If context contains > it means we are already outside of tag and we
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000108 " should abandon action
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000109 " If context contains white space it is attribute.
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000110 " It could be also value of attribute...
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000111 " We have to get first word to offer
112 " proper completions
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000113 if context == ''
114 let tag = ''
115 else
116 let tag = split(context)[0]
117 endif
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000118 " Get last word, it should be attr name
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000119 let attr = matchstr(context, '.*\s\zs.*')
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000120 " Possible situations where any prediction would be difficult:
121 " 1. Events attributes
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000122 if context =~ '\s'
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000123 " Sort out style, class, and on* cases
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000124 if context =~ "\\(on[a-z]*\\|id\\|style\\|class\\)\\s*=\\s*[\"']"
125 if context =~ "\\(id\\|class\\)\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"
126 if context =~ "class\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000127 let search_for = "class"
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000128 elseif context =~ "id\\s*=\\s*[\"'][a-zA-Z0-9_ -]*$"
Bram Moolenaar1e015462005-09-25 22:16:38 +0000129 let search_for = "id"
130 endif
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000131 " Handle class name completion
132 " 1. Find lines of <link stylesheet>
133 " 1a. Check file for @import
134 " 2. Extract filename(s?) of stylesheet,
135 call cursor(1,1)
136 let head = getline(search('<head\>'), search('<\/head>'))
137 let headjoined = join(copy(head), ' ')
138 if headjoined =~ '<style'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000139 " Remove possibly confusing CSS operators
Bram Moolenaar1e015462005-09-25 22:16:38 +0000140 let stylehead = substitute(headjoined, '+>\*[,', ' ', 'g')
141 if search_for == 'class'
142 let styleheadlines = split(stylehead)
143 let headclasslines = filter(copy(styleheadlines), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")
144 else
145 let stylesheet = split(headjoined, '[{}]')
146 " Get all lines which fit id syntax
147 let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")
148 " Filter out possible color definitions
149 call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")
150 " Filter out complex border definitions
151 call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")
152 let templines = join(classlines, ' ')
153 let headclasslines = split(templines)
154 call filter(headclasslines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")
155 endif
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000156 let internal = 1
157 else
158 let internal = 0
159 endif
160 let styletable = []
161 let secimportfiles = []
162 let filestable = filter(copy(head), "v:val =~ '\\(@import\\|link.*stylesheet\\)'")
163 for line in filestable
164 if line =~ "@import"
165 let styletable += [matchstr(line, "import\\s\\+\\(url(\\)\\?[\"']\\?\\zs\\f\\+\\ze")]
166 elseif line =~ "<link"
167 let styletable += [matchstr(line, "href\\s*=\\s*[\"']\\zs\\f\\+\\ze")]
168 endif
169 endfor
Bram Moolenaar1e015462005-09-25 22:16:38 +0000170 for file in styletable
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000171 if filereadable(file)
172 let stylesheet = readfile(file)
173 let secimport = filter(copy(stylesheet), "v:val =~ '@import'")
174 if len(secimport) > 0
175 for line in secimport
Bram Moolenaar1e015462005-09-25 22:16:38 +0000176 let secfile = matchstr(line, "import\\s\\+\\(url(\\)\\?[\"']\\?\\zs\\f\\+\\ze")
177 let secfile = fnamemodify(file, ":p:h").'/'.secfile
178 let secimportfiles += [secfile]
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000179 endfor
180 endif
181 endif
182 endfor
183 let cssfiles = styletable + secimportfiles
184 let classes = []
185 for file in cssfiles
186 if filereadable(file)
187 let stylesheet = readfile(file)
Bram Moolenaar1e015462005-09-25 22:16:38 +0000188 let stylefile = join(stylesheet, ' ')
189 let stylefile = substitute(stylefile, '+>\*[,', ' ', 'g')
190 if search_for == 'class'
191 let stylesheet = split(stylefile)
192 let classlines = filter(copy(stylesheet), "v:val =~ '\\([a-zA-Z0-9:]\\+\\)\\?\\.[a-zA-Z0-9_-]\\+'")
193 else
194 let stylesheet = split(stylefile, '[{}]')
195 " Get all lines which fit id syntax
196 let classlines = filter(copy(stylesheet), "v:val =~ '#[a-zA-Z0-9_-]\\+'")
197 " Filter out possible color definitions
198 call filter(classlines, "v:val !~ ':\\s*#[a-zA-Z0-9_-]\\+'")
199 " Filter out complex border definitions
200 call filter(classlines, "v:val !~ '\\(none\\|hidden\\|dotted\\|dashed\\|solid\\|double\\|groove\\|ridge\\|inset\\|outset\\)\\s*#[a-zA-Z0-9_-]\\+'")
201 let templines = join(classlines, ' ')
202 let stylelines = split(templines)
203 let classlines = filter(stylelines, "v:val =~ '#[a-zA-Z0-9_-]\\+'")
204
205 endif
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000206 endif
207 " We gathered classes definitions from all external files
208 let classes += classlines
209 endfor
210 if internal == 1
211 let classes += headclasslines
212 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000213
214 if search_for == 'class'
215 let elements = {}
216 for element in classes
217 if element =~ '^\.'
218 let class = matchstr(element, '^\.\zs[a-zA-Z][a-zA-Z0-9_-]*\ze')
219 let class = substitute(class, ':.*', '', '')
220 if has_key(elements, 'common')
221 let elements['common'] .= ' '.class
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000222 else
Bram Moolenaar1e015462005-09-25 22:16:38 +0000223 let elements['common'] = class
224 endif
225 else
226 let class = matchstr(element, '[a-zA-Z1-6]*\.\zs[a-zA-Z][a-zA-Z0-9_-]*\ze')
227 let tagname = tolower(matchstr(element, '[a-zA-Z1-6]*\ze.'))
228 if tagname != ''
229 if has_key(elements, tagname)
230 let elements[tagname] .= ' '.class
231 else
232 let elements[tagname] = class
233 endif
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000234 endif
235 endif
Bram Moolenaar1e015462005-09-25 22:16:38 +0000236 endfor
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000237
Bram Moolenaar1e015462005-09-25 22:16:38 +0000238 if has_key(elements, tag) && has_key(elements, 'common')
239 let values = split(elements[tag]." ".elements['common'])
240 elseif has_key(elements, tag) && !has_key(elements, 'common')
241 let values = split(elements[tag])
242 elseif !has_key(elements, tag) && has_key(elements, 'common')
243 let values = split(elements['common'])
244 else
245 return []
246 endif
247
248 elseif search_for == 'id'
249 " Find used IDs
250 " 1. Catch whole file
251 let filelines = getline(1, line('$'))
252 " 2. Find lines with possible id
253 let used_id_lines = filter(filelines, 'v:val =~ "id\\s*=\\s*[\"''][a-zA-Z0-9_-]\\+"')
254 " 3a. Join all filtered lines
255 let id_string = join(used_id_lines, ' ')
256 " 3b. And split them to be sure each id is in separate item
257 let id_list = split(id_string, 'id\s*=\s*')
258 " 4. Extract id values
259 let used_id = map(id_list, 'matchstr(v:val, "[\"'']\\zs[a-zA-Z0-9_-]\\+\\ze")')
260 let joined_used_id = ','.join(used_id, ',').','
261
262 let allvalues = map(classes, 'matchstr(v:val, ".*#\\zs[a-zA-Z0-9_-]\\+")')
263
264 let values = []
265
266 for element in classes
267 if joined_used_id !~ ','.element.','
268 let values += [element]
269 endif
270
271 endfor
272
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000273 endif
274
275 " We need special version of sbase
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000276 let classbase = matchstr(context, ".*[\"']")
Bram Moolenaar1e015462005-09-25 22:16:38 +0000277 let classquote = matchstr(classbase, '.$')
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000278
279 let entered_class = matchstr(attr, ".*=\\s*[\"']\\zs.*")
280
281 for m in sort(values)
282 if m =~? '^'.entered_class
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000283 call add(res, m . classquote)
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000284 elseif m =~? entered_class
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000285 call add(res2, m . classquote)
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000286 endif
287 endfor
288
289 return res + res2
290
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000291 elseif context =~ "style\\s*=\\s*[\"'][^\"']*$"
292 return csscomplete#CompleteCSS(0, context)
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000293
294 endif
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000295 let stripbase = matchstr(context, ".*\\(on[a-z]*\\|style\\|class\\)\\s*=\\s*[\"']\\zs.*")
296 " Now we have context stripped from all chars up to style/class.
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000297 " It may fail with some strange style value combinations.
298 if stripbase !~ "[\"']"
299 return []
300 endif
301 endif
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000302 " If attr contains =\s*[\"'] we catched value of attribute
303 if attr =~ "=\s*[\"']"
304 " Let do attribute specific completion
305 let attrname = matchstr(attr, '.*\ze\s*=')
306 let entered_value = matchstr(attr, ".*=\\s*[\"']\\zs.*")
307 let values = []
308 if attrname == 'media'
309 let values = ["screen", "tty", "tv", "projection", "handheld", "print", "braille", "aural", "all"]
310 elseif attrname == 'xml:space'
311 let values = ["preserve"]
312 elseif attrname == 'shape'
Bram Moolenaar8349fd72005-10-12 20:52:20 +0000313 let values = ["rect", "circle", "poly", "default"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000314 elseif attrname == 'valuetype'
315 let values = ["data", "ref", "object"]
316 elseif attrname == 'method'
317 let values = ["get", "post"]
Bram Moolenaar4c903f92005-09-14 21:32:32 +0000318 elseif attrname == 'dir'
319 let values = ["ltr", "rtl"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000320 elseif attrname == 'frame'
321 let values = ["void", "above", "below", "hsides", "lhs", "rhs", "vsides", "box", "border"]
322 elseif attrname == 'rules'
323 let values = ["none", "groups", "rows", "all"]
324 elseif attrname == 'align'
325 let values = ["left", "center", "right", "justify", "char"]
326 elseif attrname == 'valign'
327 let values = ["top", "middle", "bottom", "baseline"]
328 elseif attrname == 'scope'
329 let values = ["row", "col", "rowgroup", "colgroup"]
330 elseif attrname == 'href'
331 " Now we are looking for local anchors defined by name or id
332 if entered_value =~ '^#'
333 let file = join(getline(1, line('$')), ' ')
334 " Split it be sure there will be one id/name element in
335 " item, it will be also first word [a-zA-Z0-9_-] in element
336 let oneelement = split(file, "\\(meta \\)\\@<!\\(name\\|id\\)\\s*=\\s*[\"']")
337 for i in oneelement
338 let values += ['#'.matchstr(i, "^[a-zA-Z][a-zA-Z0-9%_-]*")]
339 endfor
340 endif
341 elseif attrname == 'type'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000342 if context =~ '^input'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000343 let values = ["text", "password", "checkbox", "radio", "submit", "reset", "file", "hidden", "image", "button"]
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000344 elseif context =~ '^button'
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000345 let values = ["button", "submit", "reset"]
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000346 elseif context =~ '^style'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000347 let values = ["text/css"]
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000348 elseif context =~ '^script'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000349 let values = ["text/javascript"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000350 endif
351 else
352 return []
353 endif
354
355 if len(values) == 0
356 return []
357 endif
358
359 " We need special version of sbase
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000360 let attrbase = matchstr(context, ".*[\"']")
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000361 let attrquote = matchstr(attrbase, '.$')
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000362
363 for m in values
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000364 " This if is needed to not offer all completions as-is
365 " alphabetically but sort them. Those beginning with entered
366 " part will be as first choices
367 if m =~ '^'.entered_value
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000368 call add(res, m . attrquote.' ')
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000369 elseif m =~ entered_value
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000370 call add(res2, m . attrquote.' ')
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000371 endif
372 endfor
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000373
374 return res + res2
375
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000376 endif
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000377 " Shorten context to not include last word
378 let sbase = matchstr(context, '.*\ze\s.*')
379 if tag =~ '^\(abbr\|acronym\|address\|b\|bdo\|big\|caption\|cite\|code\|dd\|dfn\|div\|dl\|dt\|em\|fieldset\|h\d\|hr\|i\|kbd\|li\|noscript\|ol\|p\|samp\|small\|span\|strong\|sub\|sup\|tt\|ul\|var\)$'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000380 let attrs = coregroup
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000381 elseif tag == 'a'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000382 let attrs = coregroup + focus + ["charset", "type", "name", "href", "hreflang", "rel", "rev", "shape", "coords"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000383 elseif tag == 'area'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000384 let attrs = coregroup + focus + ["shape", "coords", "href", "nohref", "alt"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000385 elseif tag == 'base'
386 let attrs = ["href", "id"]
387 elseif tag == 'blockquote'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000388 let attrs = coregroup + ["cite"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000389 elseif tag == 'body'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000390 let attrs = coregroup + ["onload", "onunload"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000391 elseif tag == 'br'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000392 let attrs = coreattrs
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000393 elseif tag == 'button'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000394 let attrs = coregroup + focus + ["name", "value", "type"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000395 elseif tag == '^\(col\|colgroup\)$'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000396 let attrs = coregroup + ["span", "width", "align", "char", "charoff", "valign"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000397 elseif tag =~ '^\(del\|ins\)$'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000398 let attrs = coregroup + ["cite", "datetime"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000399 elseif tag == 'form'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000400 let attrs = coregroup + ["action", "method=\"get\" ", "method=\"post\" ", "enctype", "onsubmit", "onreset", "accept", "accept-charset"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000401 elseif tag == 'head'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000402 let attrs = i18n + ["id", "profile"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000403 elseif tag == 'html'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000404 let attrs = i18n + ["id", "xmlns"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000405 elseif tag == 'img'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000406 let attrs = coregroup + ["src", "alt", "longdesc", "height", "width", "usemap", "ismap"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000407 elseif tag == 'input'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000408 let attrs = coregroup + ["type", "name", "value", "checked", "disabled", "readonly", "size", "maxlength", "src", "alt", "usemap", "onselect", "onchange", "accept"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000409 elseif tag == 'label'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000410 let attrs = coregroup + ["for", "accesskey", "onfocus", "onblur"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000411 elseif tag == 'legend'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000412 let attrs = coregroup + ["accesskey"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000413 elseif tag == 'link'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000414 let attrs = coregroup + ["charset", "href", "hreflang", "type", "rel", "rev", "media"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000415 elseif tag == 'map'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000416 let attrs = i18n + events + ["id", "class", "style", "title", "name"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000417 elseif tag == 'meta'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000418 let attrs = i18n + ["id", "http-equiv", "content", "scheme", "name"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000419 elseif tag == 'title'
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000420 let attrs = i18n + ["id"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000421 elseif tag == 'object'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000422 let attrs = coregroup + ["declare", "classid", "codebase", "data", "type", "codetype", "archive", "standby", "height", "width", "usemap", "name", "tabindex"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000423 elseif tag == 'optgroup'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000424 let attrs = coregroup + ["disbled", "label"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000425 elseif tag == 'option'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000426 let attrs = coregroup + ["disbled", "selected", "value", "label"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000427 elseif tag == 'param'
428 let attrs = ["id", "name", "value", "valuetype", "type"]
429 elseif tag == 'pre'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000430 let attrs = coregroup + ["xml:space"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000431 elseif tag == 'q'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000432 let attrs = coregroup + ["cite"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000433 elseif tag == 'script'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000434 let attrs = ["id", "charset", "type=\"text/javascript\"", "type", "src", "defer", "xml:space"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000435 elseif tag == 'select'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000436 let attrs = coregroup + ["name", "size", "multiple", "disabled", "tabindex", "onfocus", "onblur", "onchange"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000437 elseif tag == 'style'
Bram Moolenaar1e015462005-09-25 22:16:38 +0000438 let attrs = coreattrs + ["id", "type=\"text/css\"", "type", "media", "title", "xml:space"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000439 elseif tag == 'table'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000440 let attrs = coregroup + ["summary", "width", "border", "frame", "rules", "cellspacing", "cellpadding"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000441 elseif tag =~ '^\(thead\|tfoot\|tbody\|tr\)$'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000442 let attrs = coregroup + ["align", "char", "charoff", "valign"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000443 elseif tag == 'textarea'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000444 let attrs = coregroup + ["name", "rows", "cols", "disabled", "readonly", "onselect", "onchange"]
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000445 elseif tag =~ '^\(th\|td\)$'
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000446 let attrs = coregroup + ["abbr", "headers", "scope", "rowspan", "colspan", "align", "char", "charoff", "valign"]
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000447 else
448 return []
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000449 endif
450
451 for m in sort(attrs)
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000452 if m =~ '^'.attr
453 if m =~ '^\(ismap\|defer\|declare\|nohref\|checked\|disabled\|selected\|readonly\)$' || m =~ '='
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000454 call add(res, m)
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000455 else
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000456 call add(res, m.'="')
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000457 endif
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000458 elseif m =~ attr
459 if m =~ '^\(ismap\|defer\|declare\|nohref\|checked\|disabled\|selected\|readonly\)$' || m =~ '='
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000460 call add(res2, m)
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000461 else
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000462 call add(res2, m.'="')
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000463 endif
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000464 endif
465 endfor
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000466
467 return res + res2
468
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000469 endif
Bram Moolenaar4c903f92005-09-14 21:32:32 +0000470 " Close tag
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000471 let b:unaryTagsStack = "base meta link hr br param img area input col"
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000472 if context =~ '^\/'
Bram Moolenaara5792f52005-11-23 21:25:05 +0000473 let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000474 return [opentag.">"]
Bram Moolenaar4c903f92005-09-14 21:32:32 +0000475 endif
476 " Deal with tag completion.
Bram Moolenaara5792f52005-11-23 21:25:05 +0000477 let opentag = xmlcomplete#GetLastOpenTag("b:unaryTagsStack")
Bram Moolenaar09df3122006-01-23 22:23:09 +0000478 if opentag == ''
479 " Hack for sometimes failing GetLastOpenTag.
480 " As far as I tested fail isn't GLOT fault but problem
481 " of invalid document - not properly closed tags and other mish-mash.
482 " If returns empty string assume <body>. Safe bet.
483 let opentag = 'body'
484 endif
Bram Moolenaar4c903f92005-09-14 21:32:32 +0000485
Bram Moolenaara5792f52005-11-23 21:25:05 +0000486 if !exists("g:xmldata_xhtml10s")
487 runtime! autoload/xml/xhtml10s.vim
Bram Moolenaar4c903f92005-09-14 21:32:32 +0000488 endif
489
Bram Moolenaara5792f52005-11-23 21:25:05 +0000490 let tags = g:xmldata_xhtml10s[opentag][0]
491
Bram Moolenaarcef9dcc2005-12-06 19:50:41 +0000492 for m in sort(tags)
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000493 if m =~ '^'.context
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000494 call add(res, m)
Bram Moolenaard5cdbeb2005-10-10 20:59:28 +0000495 elseif m =~ context
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000496 call add(res2, m)
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000497 endif
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000498 endfor
499
Bram Moolenaarbfd8fc02005-09-20 23:22:24 +0000500 return res + res2
Bram Moolenaar6b730e12005-09-16 21:47:57 +0000501
Bram Moolenaarf75a9632005-09-13 21:20:47 +0000502 endif
503endfunction