Mercurial > vim
comparison runtime/indent/html.vim @ 4869:a5352e73dc00
Update runtime files.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 12 Jun 2013 21:29:15 +0200 |
parents | e63691e7c504 |
children | 78c318784090 |
comparison
equal
deleted
inserted
replaced
4868:f2f15e432db6 | 4869:a5352e73dc00 |
---|---|
1 " Description: html indenter | 1 " Vim indent script for HTML |
2 " Author: Johannes Zellner <johannes@zellner.org> | 2 " General: "{{{ |
3 " Last Change: Mo, 05 Jun 2006 22:32:41 CEST | 3 " File: html.vim (Vimscript #2075) |
4 " Restoring 'cpo' and 'ic' added by Bram 2006 May 5 | 4 " Author: Andy Wokula <anwoku@yahoo.de> |
5 " Globals: g:html_indent_tags -- indenting tags | 5 " Last Change: 2013 Jun 12 |
6 " g:html_indent_strict -- inhibit 'O O' elements | 6 " Rev Days: 9 |
7 " g:html_indent_strict_table -- inhibit 'O -' elements | 7 " Version: 0.8 |
8 | 8 " Vim Version: Vim7 |
9 " Only load this indent file when no other was loaded. | 9 " Description: |
10 " Improved version of the distributed html indent script, faster on a | |
11 " range of lines. | |
12 " | |
13 " Credits: | |
14 " indent/html.vim (2006 Jun 05) from J. Zellner | |
15 " indent/css.vim (2006 Dec 20) from N. Weibull | |
16 " | |
17 " History: | |
18 " 2011 Sep 09 added HTML5 tags (thx to J. Zuckerman) | |
19 " }}} | |
20 | |
21 " Init Folklore, check user settings (2nd time ++) "{{{ | |
10 if exists("b:did_indent") | 22 if exists("b:did_indent") |
11 finish | 23 finish |
12 endif | 24 endif |
13 let b:did_indent = 1 | 25 let b:did_indent = 1 |
14 | 26 |
15 | 27 setlocal indentexpr=HtmlIndent() |
16 " [-- local settings (must come before aborting the script) --] | 28 setlocal indentkeys=o,O,<Return>,<>>,{,},!^F |
17 setlocal indentexpr=HtmlIndentGet(v:lnum) | 29 |
18 setlocal indentkeys=o,O,*<Return>,<>>,{,} | 30 let b:indent = {"lnum": -1} |
19 | 31 let b:undo_indent = "set inde< indk<| unlet b:indent" |
20 | 32 |
21 if exists('g:html_indent_tags') | 33 " Load Once: |
22 unlet g:html_indent_tags | 34 if exists("*HtmlIndent") |
35 call HtmlIndent_CheckUserSettings() | |
36 finish | |
23 endif | 37 endif |
24 | |
25 " [-- helper function to assemble tag list --] | |
26 fun! <SID>HtmlIndentPush(tag) | |
27 if exists('g:html_indent_tags') | |
28 let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag | |
29 else | |
30 let g:html_indent_tags = a:tag | |
31 endif | |
32 endfun | |
33 | |
34 | |
35 " [-- <ELEMENT ? - - ...> --] | |
36 call <SID>HtmlIndentPush('a') | |
37 call <SID>HtmlIndentPush('abbr') | |
38 call <SID>HtmlIndentPush('acronym') | |
39 call <SID>HtmlIndentPush('address') | |
40 call <SID>HtmlIndentPush('b') | |
41 call <SID>HtmlIndentPush('bdo') | |
42 call <SID>HtmlIndentPush('big') | |
43 call <SID>HtmlIndentPush('blockquote') | |
44 call <SID>HtmlIndentPush('button') | |
45 call <SID>HtmlIndentPush('caption') | |
46 call <SID>HtmlIndentPush('center') | |
47 call <SID>HtmlIndentPush('cite') | |
48 call <SID>HtmlIndentPush('code') | |
49 call <SID>HtmlIndentPush('colgroup') | |
50 call <SID>HtmlIndentPush('del') | |
51 call <SID>HtmlIndentPush('dfn') | |
52 call <SID>HtmlIndentPush('dir') | |
53 call <SID>HtmlIndentPush('div') | |
54 call <SID>HtmlIndentPush('dl') | |
55 call <SID>HtmlIndentPush('em') | |
56 call <SID>HtmlIndentPush('fieldset') | |
57 call <SID>HtmlIndentPush('font') | |
58 call <SID>HtmlIndentPush('form') | |
59 call <SID>HtmlIndentPush('frameset') | |
60 call <SID>HtmlIndentPush('h1') | |
61 call <SID>HtmlIndentPush('h2') | |
62 call <SID>HtmlIndentPush('h3') | |
63 call <SID>HtmlIndentPush('h4') | |
64 call <SID>HtmlIndentPush('h5') | |
65 call <SID>HtmlIndentPush('h6') | |
66 call <SID>HtmlIndentPush('i') | |
67 call <SID>HtmlIndentPush('iframe') | |
68 call <SID>HtmlIndentPush('ins') | |
69 call <SID>HtmlIndentPush('kbd') | |
70 call <SID>HtmlIndentPush('label') | |
71 call <SID>HtmlIndentPush('legend') | |
72 call <SID>HtmlIndentPush('map') | |
73 call <SID>HtmlIndentPush('menu') | |
74 call <SID>HtmlIndentPush('noframes') | |
75 call <SID>HtmlIndentPush('noscript') | |
76 call <SID>HtmlIndentPush('object') | |
77 call <SID>HtmlIndentPush('ol') | |
78 call <SID>HtmlIndentPush('optgroup') | |
79 " call <SID>HtmlIndentPush('pre') | |
80 call <SID>HtmlIndentPush('q') | |
81 call <SID>HtmlIndentPush('s') | |
82 call <SID>HtmlIndentPush('samp') | |
83 call <SID>HtmlIndentPush('script') | |
84 call <SID>HtmlIndentPush('select') | |
85 call <SID>HtmlIndentPush('small') | |
86 call <SID>HtmlIndentPush('span') | |
87 call <SID>HtmlIndentPush('strong') | |
88 call <SID>HtmlIndentPush('style') | |
89 call <SID>HtmlIndentPush('sub') | |
90 call <SID>HtmlIndentPush('sup') | |
91 call <SID>HtmlIndentPush('table') | |
92 call <SID>HtmlIndentPush('textarea') | |
93 call <SID>HtmlIndentPush('title') | |
94 call <SID>HtmlIndentPush('tt') | |
95 call <SID>HtmlIndentPush('u') | |
96 call <SID>HtmlIndentPush('ul') | |
97 call <SID>HtmlIndentPush('var') | |
98 | |
99 | |
100 " [-- <ELEMENT ? O O ...> --] | |
101 if !exists('g:html_indent_strict') | |
102 call <SID>HtmlIndentPush('body') | |
103 call <SID>HtmlIndentPush('head') | |
104 call <SID>HtmlIndentPush('html') | |
105 call <SID>HtmlIndentPush('tbody') | |
106 endif | |
107 | |
108 | |
109 " [-- <ELEMENT ? O - ...> --] | |
110 if !exists('g:html_indent_strict_table') | |
111 call <SID>HtmlIndentPush('th') | |
112 call <SID>HtmlIndentPush('td') | |
113 call <SID>HtmlIndentPush('tr') | |
114 call <SID>HtmlIndentPush('tfoot') | |
115 call <SID>HtmlIndentPush('thead') | |
116 endif | |
117 | |
118 delfun <SID>HtmlIndentPush | |
119 | 38 |
120 let s:cpo_save = &cpo | 39 let s:cpo_save = &cpo |
121 set cpo-=C | 40 set cpo-=C |
122 | 41 "}}} |
123 " [-- count indent-increasing tags of line a:lnum --] | 42 |
124 fun! <SID>HtmlIndentOpen(lnum, pattern) | 43 func! HtmlIndent_CheckUserSettings() "{{{ |
125 let s = substitute('x'.getline(a:lnum), | 44 if exists("g:html_indent_inctags") |
126 \ '.\{-}\(\(<\)\('.a:pattern.'\)\>\)', "\1", 'g') | 45 call s:AddITags(split(g:html_indent_inctags, ",")) |
127 let s = substitute(s, "[^\1].*$", '', '') | 46 endif |
128 return strlen(s) | 47 if exists("g:html_indent_autotags") |
129 endfun | 48 call s:RemoveITags(split(g:html_indent_autotags, ",")) |
130 | 49 endif |
131 " [-- count indent-decreasing tags of line a:lnum --] | 50 |
132 fun! <SID>HtmlIndentClose(lnum, pattern) | 51 let indone = {"zero": 0 |
133 let s = substitute('x'.getline(a:lnum), | 52 \,"auto": "indent(prevnonblank(v:lnum-1))" |
134 \ '.\{-}\(\(<\)/\('.a:pattern.'\)\>>\)', "\1", 'g') | 53 \,"inc": "b:indent.blocktagind + &shiftwidth"} |
135 let s = substitute(s, "[^\1].*$", '', '') | 54 if exists("g:html_indent_script1") |
136 return strlen(s) | 55 let s:js1indent = get(indone, g:html_indent_script1, indone.zero) |
137 endfun | 56 endif |
138 | 57 if exists("g:html_indent_style1") |
139 " [-- count indent-increasing '{' of (java|css) line a:lnum --] | 58 let s:css1indent = get(indone, g:html_indent_style1, indone.zero) |
140 fun! <SID>HtmlIndentOpenAlt(lnum) | 59 endif |
141 return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) | 60 endfunc "}}} |
142 endfun | 61 |
143 | 62 " Init Script Vars "{{{ |
144 " [-- count indent-decreasing '}' of (java|css) line a:lnum --] | 63 let s:usestate = 1 |
145 fun! <SID>HtmlIndentCloseAlt(lnum) | 64 let s:css1indent = 0 |
146 return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) | 65 let s:js1indent = 0 |
147 endfun | 66 " not to be changed: |
148 | 67 let s:endtags = [0,0,0,0,0,0,0,0] " some places unused |
149 " [-- return the sum of indents respecting the syntax of a:lnum --] | 68 let s:newstate = {} |
150 fun! <SID>HtmlIndentSum(lnum, style) | 69 let s:countonly = 0 |
151 if a:style == match(getline(a:lnum), '^\s*</') | 70 "}}} |
152 if a:style == match(getline(a:lnum), '^\s*</\<\('.g:html_indent_tags.'\)\>') | 71 func! s:AddITags(taglist) "{{{ |
153 let open = <SID>HtmlIndentOpen(a:lnum, g:html_indent_tags) | 72 for itag in a:taglist |
154 let close = <SID>HtmlIndentClose(a:lnum, g:html_indent_tags) | 73 let s:indent_tags[itag] = 1 |
155 if 0 != open || 0 != close | 74 let s:indent_tags['/'.itag] = -1 |
156 return open - close | 75 endfor |
76 endfunc "}}} | |
77 func! s:AddBlockTag(tag, id, ...) "{{{ | |
78 if !(a:id >= 2 && a:id < 2+len(s:endtags)) | |
79 return | |
80 endif | |
81 let s:indent_tags[a:tag] = a:id | |
82 if a:0 == 0 | |
83 let s:indent_tags['/'.a:tag] = -a:id | |
84 let s:endtags[a:id-2] = "</".a:tag.">" | |
85 else | |
86 let s:indent_tags[a:1] = -a:id | |
87 let s:endtags[a:id-2] = a:1 | |
88 endif | |
89 endfunc "}}} | |
90 func! s:RemoveITags(taglist) "{{{ | |
91 " remove itags (protect blocktags from being removed) | |
92 for itag in a:taglist | |
93 if !has_key(s:indent_tags, itag) || s:indent_tags[itag] != 1 | |
94 continue | |
95 endif | |
96 unlet s:indent_tags[itag] | |
97 if itag =~ '^\w\+$' | |
98 unlet s:indent_tags["/".itag] | |
99 endif | |
100 endfor | |
101 endfunc "}}} | |
102 " Add Indent Tags: {{{ | |
103 if !exists("s:indent_tags") | |
104 let s:indent_tags = {} | |
105 endif | |
106 | |
107 " old tags: | |
108 call s:AddITags(['a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big', | |
109 \ 'blockquote', 'button', 'caption', 'center', 'cite', 'code', 'colgroup', | |
110 \ 'del', 'dfn', 'dir', 'div', 'dl', 'em', 'fieldset', 'font', 'form', | |
111 \ 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'iframe', 'ins', 'kbd', | |
112 \ 'label', 'legend', 'map', 'menu', 'noframes', 'noscript', 'object', 'ol', | |
113 \ 'optgroup', 'q', 's', 'samp', 'select', 'small', 'span', 'strong', 'sub', | |
114 \ 'sup', 'table', 'textarea', 'title', 'tt', 'u', 'ul', 'var', 'th', 'td', | |
115 \ 'tr', 'tfoot', 'thead']) | |
116 | |
117 " tags added 2011 Sep 09 (especially HTML5 tags): | |
118 call s:AddITags(['area', 'article', 'aside', 'audio', 'bdi', 'canvas', | |
119 \ 'command', 'datalist', 'details', 'embed', 'figure', 'footer', | |
120 \ 'header', 'group', 'keygen', 'mark', 'math', 'meter', 'nav', 'output', | |
121 \ 'progress', 'ruby', 'section', 'svg', 'texture', 'time', 'video', | |
122 \ 'wbr', 'text']) | |
123 | |
124 "}}} | |
125 " Add Block Tags: contain alien content "{{{ | |
126 call s:AddBlockTag('pre', 2) | |
127 call s:AddBlockTag('script', 3) | |
128 call s:AddBlockTag('style', 4) | |
129 call s:AddBlockTag('<!--', 5, '-->') | |
130 "}}} | |
131 | |
132 func! s:CountITags(...) "{{{ | |
133 | |
134 " relative indent steps for current line [unit &sw]: | |
135 let s:curind = 0 | |
136 " relative indent steps for next line [unit &sw]: | |
137 let s:nextrel = 0 | |
138 | |
139 if a:0==0 | |
140 let s:block = s:newstate.block | |
141 let tmpline = substitute(s:curline, '<\zs\/\=\w\+\>\|<!--\|-->', '\=s:CheckTag(submatch(0))', 'g') | |
142 if s:block == 3 | |
143 let s:newstate.scripttype = s:GetScriptType(matchstr(tmpline, '\C.*<SCRIPT\>\zs[^>]*')) | |
144 endif | |
145 let s:newstate.block = s:block | |
146 else | |
147 let s:block = 0 " assume starting outside of a block | |
148 let s:countonly = 1 " don't change state | |
149 let tmpline = substitute(s:altline, '<\zs\/\=\w\+\>\|<!--\|-->', '\=s:CheckTag(submatch(0))', 'g') | |
150 let s:countonly = 0 | |
151 endif | |
152 endfunc "}}} | |
153 func! s:CheckTag(itag) "{{{ | |
154 " "tag" or "/tag" or "<!--" or "-->" | |
155 let ind = get(s:indent_tags, a:itag) | |
156 if ind == -1 | |
157 " closing tag | |
158 if s:block != 0 | |
159 " ignore itag within a block | |
160 return "foo" | |
161 endif | |
162 if s:nextrel == 0 | |
163 let s:curind -= 1 | |
164 else | |
165 let s:nextrel -= 1 | |
166 endif | |
167 " if s:curind >= 1 | |
168 " let s:curind -= 1 | |
169 " else | |
170 " let s:nextrel -= 1 | |
171 " endif | |
172 elseif ind == 1 | |
173 " opening tag | |
174 if s:block != 0 | |
175 return "foo" | |
176 endif | |
177 let s:nextrel += 1 | |
178 elseif ind != 0 | |
179 " block-tag (opening or closing) | |
180 return s:Blocktag(a:itag, ind) | |
181 endif | |
182 " else ind==0 (other tag found): keep indent | |
183 return "foo" " no matter | |
184 endfunc "}}} | |
185 func! s:Blocktag(blocktag, ind) "{{{ | |
186 if a:ind > 0 | |
187 " a block starts here | |
188 if s:block != 0 | |
189 " already in a block (nesting) - ignore | |
190 " especially ignore comments after other blocktags | |
191 return "foo" | |
192 endif | |
193 let s:block = a:ind " block type | |
194 if s:countonly | |
195 return "foo" | |
196 endif | |
197 let s:newstate.blocklnr = v:lnum | |
198 " save allover indent for the endtag | |
199 let s:newstate.blocktagind = b:indent.baseindent + (s:nextrel + s:curind) * &shiftwidth | |
200 if a:ind == 3 | |
201 return "SCRIPT" " all except this must be lowercase | |
202 " line is to be checked again for the type attribute | |
203 endif | |
204 else | |
205 let s:block = 0 | |
206 " we get here if starting and closing block-tag on same line | |
207 endif | |
208 return "foo" | |
209 endfunc "}}} | |
210 func! s:GetScriptType(str) "{{{ | |
211 if a:str == "" || a:str =~ "java" | |
212 return "javascript" | |
213 else | |
214 return "" | |
215 endif | |
216 endfunc "}}} | |
217 | |
218 func! s:FreshState(lnum) "{{{ | |
219 " Look back in the file (lines 1 to a:lnum-1) to calc a state for line | |
220 " a:lnum. A state is to know ALL relevant details about the lines | |
221 " 1..a:lnum-1, initial calculating (here!) can be slow, but updating is | |
222 " fast (incremental). | |
223 " State: | |
224 " lnum last indented line == prevnonblank(a:lnum - 1) | |
225 " block = 0 a:lnum located within special tag: 0:none, 2:<pre>, | |
226 " 3:<script>, 4:<style>, 5:<!-- | |
227 " baseindent use this indent for line a:lnum as a start - kind of | |
228 " autoindent (if block==0) | |
229 " scripttype = '' type attribute of a script tag (if block==3) | |
230 " blocktagind indent for current opening (get) and closing (set) | |
231 " blocktag (if block!=0) | |
232 " blocklnr lnum of starting blocktag (if block!=0) | |
233 " inattr line {lnum} starts with attributes of a tag | |
234 let state = {} | |
235 let state.lnum = prevnonblank(a:lnum - 1) | |
236 let state.scripttype = "" | |
237 let state.blocktagind = -1 | |
238 let state.block = 0 | |
239 let state.baseindent = 0 | |
240 let state.blocklnr = 0 | |
241 let state.inattr = 0 | |
242 | |
243 if state.lnum == 0 | |
244 return state | |
245 endif | |
246 | |
247 " Heuristic: | |
248 " remember startline state.lnum | |
249 " look back for <pre, </pre, <script, </script, <style, </style tags | |
250 " remember stopline | |
251 " if opening tag found, | |
252 " assume a:lnum within block | |
253 " else | |
254 " look back in result range (stopline, startline) for comment | |
255 " \ delimiters (<!--, -->) | |
256 " if comment opener found, | |
257 " assume a:lnum within comment | |
258 " else | |
259 " assume usual html for a:lnum | |
260 " if a:lnum-1 has a closing comment | |
261 " look back to get indent of comment opener | |
262 " FI | |
263 | |
264 " look back for blocktag | |
265 call cursor(a:lnum, 1) | |
266 let [stopline, stopcol] = searchpos('\c<\zs\/\=\%(pre\>\|script\>\|style\>\)', "bW") | |
267 " fugly ... why isn't there searchstr() | |
268 let tagline = tolower(getline(stopline)) | |
269 let blocktag = matchstr(tagline, '\/\=\%(pre\>\|script\>\|style\>\)', stopcol-1) | |
270 if stopline > 0 && blocktag[0] != "/" | |
271 " opening tag found, assume a:lnum within block | |
272 let state.block = s:indent_tags[blocktag] | |
273 if state.block == 3 | |
274 let state.scripttype = s:GetScriptType(matchstr(tagline, '\>[^>]*', stopcol)) | |
275 endif | |
276 let state.blocklnr = stopline | |
277 " check preceding tags in the line: | |
278 let s:altline = tagline[: stopcol-2] | |
279 call s:CountITags(1) | |
280 let state.blocktagind = indent(stopline) + (s:curind + s:nextrel) * &shiftwidth | |
281 return state | |
282 elseif stopline == state.lnum | |
283 " handle special case: previous line (= state.lnum) contains a | |
284 " closing blocktag which is preceded by line-noise; | |
285 " blocktag == "/..." | |
286 let swendtag = match(tagline, '^\s*</') >= 0 | |
287 if !swendtag | |
288 let [bline, bcol] = searchpos('<'.blocktag[1:].'\>', "bW") | |
289 let s:altline = tolower(getline(bline)[: bcol-2]) | |
290 call s:CountITags(1) | |
291 let state.baseindent = indent(bline) + (s:nextrel+s:curline) * &shiftwidth | |
292 return state | |
293 endif | |
294 endif | |
295 | |
296 " else look back for comment | |
297 call cursor(a:lnum, 1) | |
298 let [comline, comcol, found] = searchpos('\(<!--\)\|-->', 'bpW', stopline) | |
299 if found == 2 | |
300 " comment opener found, assume a:lnum within comment | |
301 let state.block = 5 | |
302 let state.blocklnr = comline | |
303 " check preceding tags in the line: | |
304 let s:altline = tolower(getline(comline)[: comcol-2]) | |
305 call s:CountITags(1) | |
306 let state.blocktagind = indent(comline) + (s:curind + s:nextrel) * &shiftwidth | |
307 return state | |
308 endif | |
309 | |
310 " else within usual html | |
311 let s:altline = tolower(getline(state.lnum)) | |
312 " check a:lnum-1 for closing comment (we need indent from the opening line) | |
313 let comcol = stridx(s:altline, '-->') | |
314 if comcol >= 0 | |
315 call cursor(state.lnum, comcol+1) | |
316 let [comline, comcol] = searchpos('<!--', 'bW') | |
317 if comline == state.lnum | |
318 let s:altline = s:altline[: comcol-2] | |
319 else | |
320 let s:altline = tolower(getline(comline)[: comcol-2]) | |
321 endif | |
322 call s:CountITags(1) | |
323 let state.baseindent = indent(comline) + (s:nextrel+s:curline) * &shiftwidth | |
324 return state | |
325 " TODO check tags that follow "-->" | |
326 endif | |
327 | |
328 " else no comments | |
329 call s:CountITags(1) | |
330 let state.baseindent = indent(state.lnum) + s:nextrel * &shiftwidth | |
331 " line starts with end tag | |
332 let swendtag = match(s:altline, '^\s*</') >= 0 | |
333 if !swendtag | |
334 let state.baseindent += s:curind * &shiftwidth | |
335 endif | |
336 return state | |
337 endfunc "}}} | |
338 | |
339 func! s:Alien2() "{{{ | |
340 " <pre> block | |
341 return -1 | |
342 endfunc "}}} | |
343 func! s:Alien3() "{{{ | |
344 " <script> javascript | |
345 if prevnonblank(v:lnum-1) == b:indent.blocklnr | |
346 " indent for the first line after <script> | |
347 return eval(s:js1indent) | |
348 endif | |
349 if b:indent.scripttype == "javascript" | |
350 return cindent(v:lnum) | |
351 else | |
352 return -1 | |
353 endif | |
354 endfunc "}}} | |
355 func! s:Alien4() "{{{ | |
356 " <style> | |
357 if prevnonblank(v:lnum-1) == b:indent.blocklnr | |
358 " indent for first content line | |
359 return eval(s:css1indent) | |
360 endif | |
361 return s:CSSIndent() | |
362 endfunc | |
363 | |
364 func! s:CSSIndent() "{{{ | |
365 " adopted $VIMRUNTIME/indent/css.vim | |
366 if getline(v:lnum) =~ '^\s*[*}]' | |
367 return cindent(v:lnum) | |
368 endif | |
369 let minline = b:indent.blocklnr | |
370 let pnum = s:css_prevnoncomment(v:lnum - 1, minline) | |
371 if pnum <= minline | |
372 " < is to catch errors | |
373 " indent for first content line after comments | |
374 return eval(s:css1indent) | |
375 endif | |
376 let ind = indent(pnum) + s:css_countbraces(pnum, 1) * &sw | |
377 let pline = getline(pnum) | |
378 if pline =~ '}\s*$' | |
379 let ind -= (s:css_countbraces(pnum, 0) - (pline =~ '^\s*}')) * &sw | |
380 endif | |
381 return ind | |
382 endfunc "}}} | |
383 func! s:css_prevnoncomment(lnum, stopline) "{{{ | |
384 " caller starts from a line a:lnum-1 that is not a comment | |
385 let lnum = prevnonblank(a:lnum) | |
386 let ccol = match(getline(lnum), '\*/') | |
387 if ccol < 0 | |
388 return lnum | |
389 endif | |
390 call cursor(lnum, ccol+1) | |
391 let lnum = search('/\*', 'bW', a:stopline) | |
392 if indent(".") == virtcol(".")-1 | |
393 return prevnonblank(lnum-1) | |
394 else | |
395 return lnum | |
396 endif | |
397 endfunc "}}} | |
398 func! s:css_countbraces(lnum, count_open) "{{{ | |
399 let brs = substitute(getline(a:lnum),'[''"].\{-}[''"]\|/\*.\{-}\*/\|/\*.*$\|[^{}]','','g') | |
400 let n_open = 0 | |
401 let n_close = 0 | |
402 for brace in split(brs, '\zs') | |
403 if brace == "{" | |
404 let n_open += 1 | |
405 elseif brace == "}" | |
406 if n_open > 0 | |
407 let n_open -= 1 | |
408 else | |
409 let n_close += 1 | |
157 endif | 410 endif |
158 endif | 411 endif |
159 endif | 412 endfor |
160 if '' != &syntax && | 413 return a:count_open ? n_open : n_close |
161 \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && | 414 endfunc "}}} |
162 \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)), 1), 'name') | 415 |
163 \ =~ '\(css\|java\).*' | 416 "}}} |
164 if a:style == match(getline(a:lnum), '^\s*}') | 417 func! s:Alien5() "{{{ |
165 return <SID>HtmlIndentOpenAlt(a:lnum) - <SID>HtmlIndentCloseAlt(a:lnum) | 418 " <!-- --> |
166 endif | 419 return -1 |
167 endif | 420 endfunc "}}} |
168 return 0 | 421 |
169 endfun | 422 func! HtmlIndent() "{{{ |
170 | 423 let s:curline = tolower(getline(v:lnum)) |
171 fun! HtmlIndentGet(lnum) | 424 |
172 " Find a non-empty line above the current line. | 425 let s:newstate = {} |
173 let lnum = prevnonblank(a:lnum - 1) | 426 let s:newstate.lnum = v:lnum |
174 | 427 |
175 " Hit the start of the file, use zero indent. | 428 " is the first non-blank in the line the start of a tag? |
176 if lnum == 0 | 429 let swendtag = match(s:curline, '^\s*</') >= 0 |
177 return 0 | 430 |
178 endif | 431 if prevnonblank(v:lnum-1) == b:indent.lnum && s:usestate |
179 | 432 " use state (continue from previous line) |
180 let restore_ic = &ic | 433 else |
181 setlocal ic " ignore case | 434 " start over (know nothing) |
182 | 435 let b:indent = s:FreshState(v:lnum) |
183 " [-- special handling for <pre>: no indenting --] | 436 endif |
184 if getline(a:lnum) =~ '\c</pre>' | 437 |
185 \ || 0 < searchpair('\c<pre>', '', '\c</pre>', 'nWb') | 438 if b:indent.block >= 2 |
186 \ || 0 < searchpair('\c<pre>', '', '\c</pre>', 'nW') | 439 " within block |
187 " we're in a line with </pre> or inside <pre> ... </pre> | 440 let endtag = s:endtags[b:indent.block-2] |
188 if restore_ic == 0 | 441 let blockend = stridx(s:curline, endtag) |
189 setlocal noic | 442 if blockend >= 0 |
190 endif | 443 " block ends here |
191 return -1 | 444 let s:newstate.block = 0 |
192 endif | 445 " calc indent for REST OF LINE (may start more blocks): |
193 | 446 let s:curline = strpart(s:curline, blockend+strlen(endtag)) |
194 " [-- special handling for <javascript>: use cindent --] | 447 call s:CountITags() |
195 let js = '<script.*type\s*=\s*.*java' | 448 if swendtag && b:indent.block != 5 |
196 | 449 let indent = b:indent.blocktagind + s:curind * &shiftwidth |
197 """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | 450 let s:newstate.baseindent = indent + s:nextrel * &shiftwidth |
198 " by Tye Zdrojewski <zdro@yahoo.com>, 05 Jun 2006 | 451 else |
199 " ZDR: This needs to be an AND (we are 'after the start of the pair' AND | 452 let indent = s:Alien{b:indent.block}() |
200 " we are 'before the end of the pair'). Otherwise, indentation | 453 let s:newstate.baseindent = b:indent.blocktagind + s:nextrel * &shiftwidth |
201 " before the start of the script block will be affected; the end of | |
202 " the pair will still match if we are before the beginning of the | |
203 " pair. | |
204 " | |
205 if 0 < searchpair(js, '', '</script>', 'nWb') | |
206 \ && 0 < searchpair(js, '', '</script>', 'nW') | |
207 " we're inside javascript | |
208 if getline(lnum) !~ js && getline(a:lnum) != '</script>' | |
209 if restore_ic == 0 | |
210 setlocal noic | |
211 endif | 454 endif |
212 return cindent(a:lnum) | 455 call extend(b:indent, s:newstate, "force") |
213 endif | 456 return indent |
214 endif | 457 else |
215 | 458 " block continues |
216 if getline(lnum) =~ '\c</pre>' | 459 " indent this line with alien method |
217 " line before the current line a:lnum contains | 460 let indent = s:Alien{b:indent.block}() |
218 " a closing </pre>. --> search for line before | 461 call extend(b:indent, s:newstate, "force") |
219 " starting <pre> to restore the indent. | 462 return indent |
220 let preline = prevnonblank(search('\c<pre>', 'bW') - 1) | 463 endif |
221 if preline > 0 | 464 else |
222 if restore_ic == 0 | 465 " not within a block - within usual html |
223 setlocal noic | 466 " if < 2 then always 0 |
224 endif | 467 let s:newstate.block = b:indent.block |
225 return indent(preline) | 468 call s:CountITags() |
226 endif | 469 if swendtag |
227 endif | 470 let indent = b:indent.baseindent + s:curind * &shiftwidth |
228 | 471 let s:newstate.baseindent = indent + s:nextrel * &shiftwidth |
229 let ind = <SID>HtmlIndentSum(lnum, -1) | 472 else |
230 let ind = ind + <SID>HtmlIndentSum(a:lnum, 0) | 473 let indent = b:indent.baseindent |
231 | 474 let s:newstate.baseindent = indent + (s:curind + s:nextrel) * &shiftwidth |
232 if restore_ic == 0 | 475 endif |
233 setlocal noic | 476 call extend(b:indent, s:newstate, "force") |
234 endif | 477 return indent |
235 | 478 endif |
236 return indent(lnum) + (&sw * ind) | 479 |
237 endfun | 480 endfunc "}}} |
481 | |
482 " check user settings (first time), clear cpo, Modeline: {{{1 | |
483 | |
484 " DEBUG: | |
485 com! -nargs=* IndHtmlLocal <args> | |
486 | |
487 call HtmlIndent_CheckUserSettings() | |
238 | 488 |
239 let &cpo = s:cpo_save | 489 let &cpo = s:cpo_save |
240 unlet s:cpo_save | 490 unlet s:cpo_save |
241 | 491 |
242 " [-- EOF <runtime>/indent/html.vim --] | 492 " vim:set fdm=marker ts=8: |