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 / unix / vim-6.2.tar.bz2 / vim-6.2.tar / vim62 / runtime / indent / pov.vim < prev    next >
Encoding:
Text File  |  2002-10-20  |  2.6 KB  |  85 lines

  1. " Vim indent file
  2. " Language: PoV-Ray Scene Description Language
  3. " Maintainer: David Necas (Yeti) <yeti@physics.muni.cz>
  4. " Last Change: 2002-10-20
  5. " URI: http://trific.ath.cx/Ftp/vim/indent/pov.vim
  6.  
  7. " Only load this indent file when no other was loaded.
  8. if exists("b:did_indent")
  9.   finish
  10. endif
  11. let b:did_indent = 1
  12.  
  13. " Some preliminary settings.
  14. setlocal nolisp " Make sure lisp indenting doesn't supersede us.
  15.  
  16. setlocal indentexpr=GetPoVRayIndent()
  17. setlocal indentkeys+==else,=end,0]
  18.  
  19. " Only define the function once.
  20. if exists("*GetPoVRayIndent")
  21.   finish
  22. endif
  23.  
  24. " Counts matches of a regexp <rexp> in line number <line>.
  25. " Doesn't count matches inside strings and comments (as defined by current
  26. " syntax).
  27. function! s:MatchCount(line, rexp)
  28.   let str = getline(a:line)
  29.   let i = 0
  30.   let n = 0
  31.   while i >= 0
  32.     let i = matchend(str, a:rexp, i)
  33.     if i >= 0 && synIDattr(synID(a:line, i, 0), "name") !~? "string\|comment"
  34.       let n = n + 1
  35.     endif
  36.   endwhile
  37.   return n
  38. endfunction
  39.  
  40. " The main function.  Returns indent amount.
  41. function GetPoVRayIndent()
  42.   " If we are inside a comment (may be nested in obscure ways), give up
  43.   if synIDattr(synID(v:lnum, indent(v:lnum)+1, 0), "name") =~? "string\|comment"
  44.     return -1
  45.   endif
  46.  
  47.   " Search backwards for the frist non-empty, non-comment line.
  48.   let plnum = prevnonblank(v:lnum - 1)
  49.   let plind = indent(plnum)
  50.   while plnum > 0 && synIDattr(synID(plnum, plind+1, 0), "name") =~? "comment"
  51.     let plnum = prevnonblank(plnum - 1)
  52.     let plind = indent(plnum)
  53.   endwhile
  54.  
  55.   " Start indenting from zero
  56.   if plnum == 0
  57.     return 0
  58.   endif
  59.  
  60.   " Analyse previous nonempty line.
  61.   let chg = 0
  62.   let chg = chg + s:MatchCount(plnum, '[[{(]')
  63.   let chg = chg + s:MatchCount(plnum, '#\s*\%(if\|ifdef\|ifndef\|switch\|while\|macro\|else\)\>')
  64.   let chg = chg - s:MatchCount(plnum, '#\s*end\>')
  65.   let chg = chg - s:MatchCount(plnum, '[]})]')
  66.   " Dirty hack for people writing #if and #else on the same line.
  67.   let chg = chg - s:MatchCount(plnum, '#\s*\%(if\|ifdef\|ifndef\|switch\)\>.*#\s*else\>')
  68.   " When chg > 0, then we opened groups and we should indent more, but when
  69.   " chg < 0, we closed groups and this already affected the previous line,
  70.   " so we should not dedent.  And when everything else fails, scream.
  71.   let chg = chg > 0 ? chg : 0
  72.  
  73.   " Analyse current line
  74.   " FIXME: If we have to dedent, we should try to find the indentation of the
  75.   " opening line.
  76.   let cur = s:MatchCount(v:lnum, '^\s*\%(#\s*\%(end\|else\)\>\|[]})]\)')
  77.   if cur > 0
  78.     let final = plind + (chg - cur) * &sw
  79.   else
  80.     let final = plind + chg * &sw
  81.   endif
  82.  
  83.   return final < 0 ? 0 : final
  84. endfunction
  85.