home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / runtime / indent / xml.vim < prev    next >
Encoding:
Text File  |  2012-05-31  |  2.7 KB  |  100 lines

  1. " Language:    xml
  2. " Maintainer:    Johannes Zellner <johannes@zellner.org>
  3. " Last Change:    2012 May 18
  4. " Notes:    1) does not indent pure non-xml code (e.g. embedded scripts)
  5. "        2) will be confused by unbalanced tags in comments
  6. "        or CDATA sections.
  7. "        2009-05-26 patch by Nikolai Weibull
  8. " TODO:     implement pre-like tags, see xml_indent_open / xml_indent_close
  9.  
  10. " Only load this indent file when no other was loaded.
  11. if exists("b:did_indent")
  12.     finish
  13. endif
  14. let b:did_indent = 1
  15. let s:keepcpo= &cpo
  16. set cpo&vim
  17.  
  18. " [-- local settings (must come before aborting the script) --]
  19. setlocal indentexpr=XmlIndentGet(v:lnum,1)
  20. setlocal indentkeys=o,O,*<Return>,<>>,<<>,/,{,}
  21.  
  22. if !exists('b:xml_indent_open')
  23.     let b:xml_indent_open = '.\{-}<\a'
  24.     " pre tag, e.g. <address>
  25.     " let b:xml_indent_open = '.\{-}<[/]\@!\(address\)\@!'
  26. endif
  27.  
  28. if !exists('b:xml_indent_close')
  29.     let b:xml_indent_close = '.\{-}</'
  30.     " end pre tag, e.g. </address>
  31.     " let b:xml_indent_close = '.\{-}</\(address\)\@!'
  32. endif
  33.  
  34. " [-- finish, if the function already exists --]
  35. if exists('*XmlIndentGet') | finish | endif
  36.  
  37. fun! <SID>XmlIndentWithPattern(line, pat)
  38.     let s = substitute('x'.a:line, a:pat, "\1", 'g')
  39.     return strlen(substitute(s, "[^\1].*$", '', ''))
  40. endfun
  41.  
  42. " [-- check if it's xml --]
  43. fun! <SID>XmlIndentSynCheck(lnum)
  44.     if '' != &syntax
  45.     let syn1 = synIDattr(synID(a:lnum, 1, 1), 'name')
  46.     let syn2 = synIDattr(synID(a:lnum, strlen(getline(a:lnum)) - 1, 1), 'name')
  47.     if '' != syn1 && syn1 !~ 'xml' && '' != syn2 && syn2 !~ 'xml'
  48.         " don't indent pure non-xml code
  49.         return 0
  50.     elseif syn1 =~ '^xmlComment' && syn2 =~ '^xmlComment'
  51.         " indent comments specially
  52.         return -1
  53.     endif
  54.     endif
  55.     return 1
  56. endfun
  57.  
  58. " [-- return the sum of indents of a:lnum --]
  59. fun! <SID>XmlIndentSum(lnum, style, add)
  60.     let line = getline(a:lnum)
  61.     if a:style == match(line, '^\s*</')
  62.     return (&sw *
  63.     \  (<SID>XmlIndentWithPattern(line, b:xml_indent_open)
  64.     \ - <SID>XmlIndentWithPattern(line, b:xml_indent_close)
  65.     \ - <SID>XmlIndentWithPattern(line, '.\{-}/>'))) + a:add
  66.     else
  67.     return a:add
  68.     endif
  69. endfun
  70.  
  71. fun! XmlIndentGet(lnum, use_syntax_check)
  72.     " Find a non-empty line above the current line.
  73.     let lnum = prevnonblank(a:lnum - 1)
  74.  
  75.     " Hit the start of the file, use zero indent.
  76.     if lnum == 0
  77.     return 0
  78.     endif
  79.  
  80.     if a:use_syntax_check
  81.     let check_lnum = <SID>XmlIndentSynCheck(lnum)
  82.     let check_alnum = <SID>XmlIndentSynCheck(a:lnum)
  83.     if 0 == check_lnum || 0 == check_alnum
  84.         return indent(a:lnum)
  85.     elseif -1 == check_lnum || -1 == check_alnum
  86.         return -1
  87.     endif
  88.     endif
  89.  
  90.     let ind = <SID>XmlIndentSum(lnum, -1, indent(lnum))
  91.     let ind = <SID>XmlIndentSum(a:lnum, 0, ind)
  92.  
  93.     return ind
  94. endfun
  95.  
  96. let &cpo = s:keepcpo
  97. unlet s:keepcpo
  98.  
  99. " vim:ts=8
  100.