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 / dos / indent / sml.vim < prev    next >
Encoding:
Text File  |  2010-08-15  |  6.5 KB  |  218 lines

  1. " Vim indent file
  2. " Language:     SML
  3. " Maintainer:    Saikat Guha <sg266@cornell.edu>
  4. "                 Hubert Chao <hc85@cornell.edu>
  5. " Original OCaml Version:
  6. "                 Jean-Francois Yuen  <jfyuen@ifrance.com>
  7. "               Mike Leary          <leary@nwlink.com>
  8. "               Markus Mottl        <markus@oefai.at>
  9. " OCaml URL:    http://www.oefai.at/~markus/vim/indent/ocaml.vim
  10. " Last Change:  2003 Jan 04    - Adapted to SML
  11. "                 2002 Nov 06 - Some fixes (JY)
  12. "               2002 Oct 28 - Fixed bug with indentation of ']' (MM)
  13. "               2002 Oct 22 - Major rewrite (JY)
  14.  
  15. " Only load this indent file when no other was loaded.
  16. if exists("b:did_indent")
  17.   finish
  18. endif
  19. let b:did_indent = 1
  20.  
  21. setlocal expandtab
  22. setlocal indentexpr=GetSMLIndent()
  23. setlocal indentkeys+=0=and,0=else,0=end,0=handle,0=if,0=in,0=let,0=then,0=val,0=fun,0=\|,0=*),0)
  24. setlocal nolisp
  25. setlocal nosmartindent
  26. setlocal textwidth=80
  27. setlocal shiftwidth=2
  28.  
  29. " Comment formatting
  30. if (has("comments"))
  31.   set comments=sr:(*,mb:*,ex:*)
  32.   set fo=cqort
  33. endif
  34.  
  35. " Only define the function once.
  36. "if exists("*GetSMLIndent")
  37. "finish
  38. "endif
  39.  
  40. " Define some patterns:
  41. let s:beflet = '^\s*\(initializer\|method\|try\)\|\(\<\(begin\|do\|else\|in\|then\|try\)\|->\|;\)\s*$'
  42. let s:letpat = '^\s*\(let\|type\|module\|class\|open\|exception\|val\|include\|external\)\>'
  43. let s:letlim = '\(\<\(sig\|struct\)\|;;\)\s*$'
  44. let s:lim = '^\s*\(exception\|external\|include\|let\|module\|open\|type\|val\)\>'
  45. let s:module = '\<\%(let\|sig\|struct\)\>'
  46. let s:obj = '^\s*\(constraint\|inherit\|initializer\|method\|val\)\>\|\<\(object\|object\s*(.*)\)\s*$'
  47. let s:type = '^\s*\%(let\|type\)\>.*='
  48. let s:val = '^\s*\(val\|external\)\>.*:'
  49.  
  50. " Skipping pattern, for comments
  51. function! s:SkipPattern(lnum, pat)
  52.   let def = prevnonblank(a:lnum - 1)
  53.   while def > 0 && getline(def) =~ a:pat
  54.     let def = prevnonblank(def - 1)
  55.   endwhile
  56.   return def
  57. endfunction
  58.  
  59. " Indent for ';;' to match multiple 'let'
  60. function! s:GetInd(lnum, pat, lim)
  61.   let llet = search(a:pat, 'bW')
  62.   let old = indent(a:lnum)
  63.   while llet > 0
  64.     let old = indent(llet)
  65.     let nb = s:SkipPattern(llet, '^\s*(\*.*\*)\s*$')
  66.     if getline(nb) =~ a:lim
  67.       return old
  68.     endif
  69.     let llet = search(a:pat, 'bW')
  70.   endwhile
  71.   return old
  72. endfunction
  73.  
  74. " Indent pairs
  75. function! s:FindPair(pstart, pmid, pend)
  76.   call search(a:pend, 'bW')
  77. "  return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
  78.   let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')
  79.   if lno == -1
  80.     return indent(lno)
  81.   else
  82.     return col(".") - 1
  83.   endif
  84. endfunction
  85.  
  86. function! s:FindLet(pstart, pmid, pend)
  87.   call search(a:pend, 'bW')
  88. "  return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
  89.   let lno = searchpair(a:pstart, a:pmid, a:pend, 'bW', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"')
  90.   let moduleLine = getline(lno)
  91.   if lno == -1 || moduleLine =~ '^\s*\(fun\|structure\|signature\)\>'
  92.     return indent(lno)
  93.   else
  94.     return col(".") - 1
  95.   endif
  96. endfunction
  97.  
  98. " Indent 'let'
  99. "function! s:FindLet(pstart, pmid, pend)
  100. "  call search(a:pend, 'bW')
  101. "  return indent(searchpair(a:pstart, a:pmid, a:pend, 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment" || getline(".") =~ "^\\s*let\\>.*=.*\\<in\\s*$" || getline(prevnonblank(".") - 1) =~ "^\\s*let\\>.*=\\s*$\\|" . s:beflet'))
  102. "endfunction
  103.  
  104. function! GetSMLIndent()
  105.   " Find a non-blank line above the current line.
  106.   let lnum = prevnonblank(v:lnum - 1)
  107.  
  108.   " At the start of the file use zero indent.
  109.   if lnum == 0
  110.     return 0
  111.   endif
  112.  
  113.   let ind = indent(lnum)
  114.   let lline = getline(lnum)
  115.  
  116.     " Return double 'shiftwidth' after lines matching:
  117.     if lline =~ '^\s*|.*=>\s*$'
  118.         return ind + &sw + &sw
  119.     elseif lline =~ '^\s*val\>.*=\s*$'
  120.         return ind + &sw
  121.     endif
  122.  
  123.   let line = getline(v:lnum)
  124.  
  125.     " Indent lines starting with 'end' to matching module
  126.     if line =~ '^\s*end\>'
  127.         return s:FindLet(s:module, '', '\<end\>')
  128.  
  129.     " Match 'else' with 'if'
  130.     elseif line =~ '^\s*else\>'
  131.           if lline !~ '^\s*\(if\|else\|then\)\>'
  132.                 return s:FindPair('\<if\>', '', '\<then\>')
  133.           else
  134.           return ind
  135.         endif
  136.  
  137.     " Match 'then' with 'if'
  138.     elseif line =~ '^\s*then\>'
  139.       if lline !~ '^\s*\(if\|else\|then\)\>'
  140.           return s:FindPair('\<if\>', '', '\<then\>')
  141.     else
  142.       return ind
  143.     endif
  144.  
  145.     " Indent if current line begins with ']'
  146.     elseif line =~ '^\s*\]'
  147.         return s:FindPair('\[','','\]')
  148.  
  149.   " Indent current line starting with 'in' to last matching 'let'
  150.     elseif line =~ '^\s*in\>'
  151.         let ind = s:FindLet('\<let\>','','\<in\>')
  152.  
  153.     " Indent from last matching module if line matches:
  154.     elseif line =~ '^\s*\(fun\|val\|open\|structure\|and\|datatype\|type\|exception\)\>'
  155.         cursor(lnum,1)
  156.           let lastModule = indent(searchpair(s:module, '', '\<end\>', 'bWn', 'synIDattr(synID(line("."), col("."), 0), "name") =~? "string\\|comment"'))
  157.         if lastModule == -1
  158.             return 0
  159.         else
  160.             return lastModule + &sw
  161.         endif
  162.  
  163.     " Indent lines starting with '|' from matching 'case', 'handle'
  164.     elseif line =~ '^\s*|'
  165.         " cursor(lnum,1)
  166.         let lastSwitch = search('\<\(case\|handle\|fun\|datatype\)\>','bW')
  167.         let switchLine = getline(lastSwitch)
  168.         let switchLineIndent = indent(lastSwitch)
  169.         if lline =~ '^\s*|'
  170.           return ind
  171.         endif
  172.         if switchLine =~ '\<case\>'
  173.             return col(".") + 2
  174.         elseif switchLine =~ '\<handle\>'
  175.             return switchLineIndent + &sw
  176.         elseif switchLine =~ '\<datatype\>'
  177.             call search('=')
  178.             return col(".") - 1
  179.         else
  180.             return switchLineIndent + 2
  181.         endif
  182.  
  183.  
  184.   " Indent if last line ends with 'sig', 'struct', 'let', 'then', 'else',
  185.   " 'in'
  186.   elseif lline =~ '\<\(sig\|struct\|let\|in\|then\|else\)\s*$'
  187.         let ind = ind + &sw
  188.  
  189.   " Indent if last line ends with 'of', align from 'case'
  190.   elseif lline =~ '\<\(of\)\s*$'
  191.         call search('\<case\>',"bW")
  192.         let ind = col(".")+4
  193.  
  194.     " Indent if current line starts with 'of'
  195.   elseif line =~ '^\s*of\>'
  196.         call search('\<case\>',"bW")
  197.         let ind = col(".")+1
  198.  
  199.  
  200.     " Indent if last line starts with 'fun', 'case', 'fn'
  201.     elseif lline =~ '^\s*\(fun\|fn\|case\)\>'
  202.         let ind = ind + &sw
  203.  
  204.     endif
  205.  
  206.     " Don't indent 'let' if last line started with 'fun', 'fn'
  207.     if line =~ '^\s*let\>'
  208.         if lline =~ '^\s*\(fun\|fn\)'
  209.             let ind = ind - &sw
  210.         endif
  211.   endif
  212.  
  213.   return ind
  214.  
  215. endfunction
  216.  
  217. " vim:sw=2
  218.