1
0

html.vim 7.3 KB

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