1" Description: html indenter 2" Author: Johannes Zellner <[email protected]> 3" Last Change: Tue, 27 Apr 2004 10:28:39 CEST 4" Globals: g:html_indent_tags -- indenting tags 5" g:html_indent_strict -- inhibit 'O O' elements 6" g:html_indent_strict_table -- inhibit 'O -' elements 7 8" Only load this indent file when no other was loaded. 9if exists("b:did_indent") 10 finish 11endif 12let b:did_indent = 1 13 14 15" [-- local settings (must come before aborting the script) --] 16setlocal indentexpr=HtmlIndentGet(v:lnum) 17setlocal indentkeys=o,O,*<Return>,<>>,<bs>,{,} 18 19 20if exists('g:html_indent_tags') 21 unlet g:html_indent_tags 22endif 23 24" [-- helper function to assemble tag list --] 25fun! <SID>HtmlIndentPush(tag) 26 if exists('g:html_indent_tags') 27 let g:html_indent_tags = g:html_indent_tags.'\|'.a:tag 28 else 29 let g:html_indent_tags = a:tag 30 endif 31endfun 32 33 34" [-- <ELEMENT ? - - ...> --] 35call <SID>HtmlIndentPush('a') 36call <SID>HtmlIndentPush('abbr') 37call <SID>HtmlIndentPush('acronym') 38call <SID>HtmlIndentPush('address') 39call <SID>HtmlIndentPush('b') 40call <SID>HtmlIndentPush('bdo') 41call <SID>HtmlIndentPush('big') 42call <SID>HtmlIndentPush('blockquote') 43call <SID>HtmlIndentPush('button') 44call <SID>HtmlIndentPush('caption') 45call <SID>HtmlIndentPush('center') 46call <SID>HtmlIndentPush('cite') 47call <SID>HtmlIndentPush('code') 48call <SID>HtmlIndentPush('colgroup') 49call <SID>HtmlIndentPush('del') 50call <SID>HtmlIndentPush('dfn') 51call <SID>HtmlIndentPush('dir') 52call <SID>HtmlIndentPush('div') 53call <SID>HtmlIndentPush('dl') 54call <SID>HtmlIndentPush('em') 55call <SID>HtmlIndentPush('fieldset') 56call <SID>HtmlIndentPush('font') 57call <SID>HtmlIndentPush('form') 58call <SID>HtmlIndentPush('frameset') 59call <SID>HtmlIndentPush('h1') 60call <SID>HtmlIndentPush('h2') 61call <SID>HtmlIndentPush('h3') 62call <SID>HtmlIndentPush('h4') 63call <SID>HtmlIndentPush('h5') 64call <SID>HtmlIndentPush('h6') 65call <SID>HtmlIndentPush('i') 66call <SID>HtmlIndentPush('iframe') 67call <SID>HtmlIndentPush('ins') 68call <SID>HtmlIndentPush('kbd') 69call <SID>HtmlIndentPush('label') 70call <SID>HtmlIndentPush('legend') 71call <SID>HtmlIndentPush('map') 72call <SID>HtmlIndentPush('menu') 73call <SID>HtmlIndentPush('noframes') 74call <SID>HtmlIndentPush('noscript') 75call <SID>HtmlIndentPush('object') 76call <SID>HtmlIndentPush('ol') 77call <SID>HtmlIndentPush('optgroup') 78" call <SID>HtmlIndentPush('pre') 79call <SID>HtmlIndentPush('q') 80call <SID>HtmlIndentPush('s') 81call <SID>HtmlIndentPush('samp') 82call <SID>HtmlIndentPush('script') 83call <SID>HtmlIndentPush('select') 84call <SID>HtmlIndentPush('small') 85call <SID>HtmlIndentPush('span') 86call <SID>HtmlIndentPush('strong') 87call <SID>HtmlIndentPush('style') 88call <SID>HtmlIndentPush('sub') 89call <SID>HtmlIndentPush('sup') 90call <SID>HtmlIndentPush('table') 91call <SID>HtmlIndentPush('textarea') 92call <SID>HtmlIndentPush('title') 93call <SID>HtmlIndentPush('tt') 94call <SID>HtmlIndentPush('u') 95call <SID>HtmlIndentPush('ul') 96call <SID>HtmlIndentPush('var') 97 98 99" [-- <ELEMENT ? O O ...> --] 100if !exists('g:html_indent_strict') 101 call <SID>HtmlIndentPush('body') 102 call <SID>HtmlIndentPush('head') 103 call <SID>HtmlIndentPush('html') 104 call <SID>HtmlIndentPush('tbody') 105endif 106 107 108" [-- <ELEMENT ? O - ...> --] 109if !exists('g:html_indent_strict_table') 110 call <SID>HtmlIndentPush('th') 111 call <SID>HtmlIndentPush('td') 112 call <SID>HtmlIndentPush('tr') 113 call <SID>HtmlIndentPush('tfoot') 114 call <SID>HtmlIndentPush('thead') 115endif 116 117delfun <SID>HtmlIndentPush 118 119set cpo-=C 120 121" [-- count indent-increasing tags of line a:lnum --] 122fun! <SID>HtmlIndentOpen(lnum, pattern) 123 let s = substitute('x'.getline(a:lnum), 124 \ '.\{-}\(\(<\)\('.a:pattern.'\)\>\)', "\1", 'g') 125 let s = substitute(s, "[^\1].*$", '', '') 126 return strlen(s) 127endfun 128 129" [-- count indent-decreasing tags of line a:lnum --] 130fun! <SID>HtmlIndentClose(lnum, pattern) 131 let s = substitute('x'.getline(a:lnum), 132 \ '.\{-}\(\(<\)/\('.a:pattern.'\)\>>\)', "\1", 'g') 133 let s = substitute(s, "[^\1].*$", '', '') 134 return strlen(s) 135endfun 136 137" [-- count indent-increasing '{' of (java|css) line a:lnum --] 138fun! <SID>HtmlIndentOpenAlt(lnum) 139 return strlen(substitute(getline(a:lnum), '[^{]\+', '', 'g')) 140endfun 141 142" [-- count indent-decreasing '}' of (java|css) line a:lnum --] 143fun! <SID>HtmlIndentCloseAlt(lnum) 144 return strlen(substitute(getline(a:lnum), '[^}]\+', '', 'g')) 145endfun 146 147" [-- return the sum of indents respecting the syntax of a:lnum --] 148fun! <SID>HtmlIndentSum(lnum, style) 149 if a:style == match(getline(a:lnum), '^\s*</') 150 if a:style == match(getline(a:lnum), '^\s*</\<\('.g:html_indent_tags.'\)\>') 151 let open = <SID>HtmlIndentOpen(a:lnum, g:html_indent_tags) 152 let close = <SID>HtmlIndentClose(a:lnum, g:html_indent_tags) 153 if 0 != open || 0 != close 154 return open - close 155 endif 156 endif 157 endif 158 if '' != &syntax && 159 \ synIDattr(synID(a:lnum, 1, 1), 'name') =~ '\(css\|java\).*' && 160 \ synIDattr(synID(a:lnum, strlen(getline(a:lnum)), 1), 'name') 161 \ =~ '\(css\|java\).*' 162 if a:style == match(getline(a:lnum), '^\s*}') 163 return <SID>HtmlIndentOpenAlt(a:lnum) - <SID>HtmlIndentCloseAlt(a:lnum) 164 endif 165 endif 166 return 0 167endfun 168 169fun! HtmlIndentGet(lnum) 170 " Find a non-empty line above the current line. 171 let lnum = prevnonblank(a:lnum - 1) 172 173 " Hit the start of the file, use zero indent. 174 if lnum == 0 175 return 0 176 endif 177 178 let restore_ic = &ic 179 setlocal ic " ignore case 180 181 " [-- special handling for <pre>: no indenting --] 182 if getline(a:lnum) =~ '\c</pre>' 183 \ || 0 < searchpair('\c<pre>', '', '\c</pre>', 'nWb') 184 \ || 0 < searchpair('\c<pre>', '', '\c</pre>', 'nW') 185 " we're in a line with </pre> or inside <pre> ... </pre> 186 return -1 187 endif 188 189 " [-- special handling for <javascript>: use cindent --] 190 let js = '<script.*type\s*=\s*.*java' 191 if 0 < searchpair(js, '', '</script>', 'nWb') 192 \ || 0 < searchpair(js, '', '</script>', 'nW') 193 " we're inside javascript 194 if getline(lnum) !~ js && getline(a:lnum) != '</script>' 195 return cindent(a:lnum) 196 endif 197 endif 198 199 if getline(lnum) =~ '\c</pre>' 200 " line before the current line a:lnum contains 201 " a closing </pre>. --> search for line before 202 " starting <pre> to restore the indent. 203 let preline = prevnonblank(search('\c<pre>', 'bW') - 1) 204 if preline > 0 205 return indent(preline) 206 endif 207 endif 208 209 let ind = <SID>HtmlIndentSum(lnum, -1) 210 let ind = ind + <SID>HtmlIndentSum(a:lnum, 0) 211 212 if restore_ic == 0 213 setlocal noic 214 endif 215 216 return indent(lnum) + (&sw * ind) 217endfun 218 219" [-- EOF <runtime>/indent/html.vim --] 220