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 / pascal.vim < prev    next >
Encoding:
Text File  |  2011-05-27  |  5.5 KB  |  229 lines

  1. " Vim indent file
  2. " Language:    Pascal
  3. " Maintainer:  Neil Carter <n.carter@swansea.ac.uk>
  4. " Created:     2004 Jul 13
  5. " Last Change: 2011 Apr 01
  6. "
  7. " This is version 2.0, a complete rewrite.
  8. "
  9. " For further documentation, see http://psy.swansea.ac.uk/staff/carter/vim/
  10.  
  11.  
  12. if exists("b:did_indent")
  13.     finish
  14. endif
  15. let b:did_indent = 1
  16.  
  17. setlocal indentexpr=GetPascalIndent(v:lnum)
  18. setlocal indentkeys&
  19. setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for
  20. setlocal indentkeys+==program,==function,==procedure,==object,==private
  21. setlocal indentkeys+==record,==if,==else,==case
  22.  
  23. if exists("*GetPascalIndent")
  24.     finish
  25. endif
  26.  
  27.  
  28. function! s:GetPrevNonCommentLineNum( line_num )
  29.  
  30.     " Skip lines starting with a comment
  31.     let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)'
  32.  
  33.     let nline = a:line_num
  34.     while nline > 0
  35.         let nline = prevnonblank(nline-1)
  36.         if getline(nline) !~? SKIP_LINES
  37.             break
  38.         endif
  39.     endwhile
  40.  
  41.     return nline
  42. endfunction
  43.  
  44.  
  45. function! s:PurifyCode( line_num )
  46.     " Strip any trailing comments and whitespace
  47.     let pureline = 'TODO'
  48.     return pureline
  49. endfunction
  50.  
  51.  
  52. function! GetPascalIndent( line_num )
  53.  
  54.     " Line 0 always goes at column 0
  55.     if a:line_num == 0
  56.         return 0
  57.     endif
  58.  
  59.     let this_codeline = getline( a:line_num )
  60.  
  61.  
  62.     " SAME INDENT
  63.  
  64.     " Middle of a three-part comment
  65.     if this_codeline =~ '^\s*\*'
  66.         return indent( a:line_num - 1)
  67.     endif
  68.  
  69.  
  70.     " COLUMN 1 ALWAYS
  71.  
  72.     " Last line of the program
  73.     if this_codeline =~ '^\s*end\.'
  74.         return 0
  75.     endif
  76.  
  77.     " Compiler directives, allowing "(*" and "{"
  78.     "if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)'
  79.     if this_codeline =~ '^\s*\({\|(\*\)\$'
  80.         return 0
  81.     endif
  82.  
  83.     " section headers
  84.     if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>'
  85.         return 0
  86.     endif
  87.  
  88.     " Subroutine separators, lines ending with "const" or "var"
  89.     if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$'
  90.         return 0
  91.     endif
  92.  
  93.  
  94.     " OTHERWISE, WE NEED TO LOOK FURTHER BACK...
  95.  
  96.     let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num )
  97.     let prev_codeline = getline( prev_codeline_num )
  98.     let indnt = indent( prev_codeline_num )
  99.  
  100.  
  101.     " INCREASE INDENT
  102.  
  103.     " If the PREVIOUS LINE ended in these items, always indent
  104.     if prev_codeline =~ '\<\(type\|const\|var\)$'
  105.         return indnt + &shiftwidth
  106.     endif
  107.  
  108.     if prev_codeline =~ '\<repeat$'
  109.         if this_codeline !~ '^\s*until\>'
  110.             return indnt + &shiftwidth
  111.         else
  112.             return indnt
  113.         endif
  114.     endif
  115.  
  116.     if prev_codeline =~ '\<\(begin\|record\)$'
  117.         if this_codeline !~ '^\s*end\>'
  118.             return indnt + &shiftwidth
  119.         else
  120.             return indnt
  121.         endif
  122.     endif
  123.  
  124.     " If the PREVIOUS LINE ended with these items, indent if not
  125.     " followed by "begin"
  126.     if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$'
  127.         if this_codeline !~ '^\s*begin\>'
  128.             return indnt + &shiftwidth
  129.         else
  130.             " If it does start with "begin" then keep the same indent
  131.             "return indnt + &shiftwidth
  132.             return indnt
  133.         endif
  134.     endif
  135.  
  136.     " Inside a parameter list (i.e. a "(" without a ")"). ???? Considers
  137.     " only the line before the current one. TODO: Get it working for
  138.     " parameter lists longer than two lines.
  139.     if prev_codeline =~ '([^)]\+$'
  140.         return indnt + &shiftwidth
  141.     endif
  142.  
  143.  
  144.     " DECREASE INDENT
  145.  
  146.     " Lines starting with "else", but not following line ending with
  147.     " "end".
  148.     if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$'
  149.         return indnt - &shiftwidth
  150.     endif
  151.  
  152.     " Lines after a single-statement branch/loop.
  153.     " Two lines before ended in "then", "else", or "do"
  154.     " Previous line didn't end in "begin"
  155.     let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num )
  156.     let prev2_codeline = getline( prev2_codeline_num )
  157.     if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$'
  158.         " If the next code line after a single statement branch/loop
  159.         " starts with "end", "except" or "finally", we need an
  160.         " additional unindentation.
  161.         if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$'
  162.             " Note that we don't return from here.
  163.             return indnt - &shiftwidth - &shiftwidth
  164.         endif
  165.         return indnt - &shiftwidth
  166.     endif
  167.  
  168.     " Lines starting with "until" or "end". This rule must be overridden
  169.     " by the one for "end" after a single-statement branch/loop. In
  170.     " other words that rule should come before this one.
  171.     if this_codeline =~ '^\s*\(end\|until\)\>'
  172.         return indnt - &shiftwidth
  173.     endif
  174.  
  175.  
  176.     " MISCELLANEOUS THINGS TO CATCH
  177.  
  178.     " Most "begin"s will have been handled by now. Any remaining
  179.     " "begin"s on their own line should go in column 1.
  180.     if this_codeline =~ '^\s*begin$'
  181.         return 0
  182.     endif
  183.  
  184.  
  185. " ____________________________________________________________________
  186. " Object/Borland Pascal/Delphi Extensions
  187. "
  188. " Note that extended-pascal is handled here, unless it is simpler to
  189. " handle them in the standard-pascal section above.
  190.  
  191.  
  192.     " COLUMN 1 ALWAYS
  193.  
  194.     " section headers at start of line.
  195.     if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>'
  196.         return 0
  197.     endif
  198.  
  199.  
  200.     " INDENT ONCE
  201.  
  202.     " If the PREVIOUS LINE ended in these items, always indent.
  203.     if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$'
  204.         return indnt + &shiftwidth
  205.     endif
  206.  
  207.     " ???? Indent "procedure" and "functions" if they appear within an
  208.     " class/object definition. But that means overriding standard-pascal
  209.     " rule where these words always go in column 1.
  210.  
  211.  
  212.     " UNINDENT ONCE
  213.  
  214.     if this_codeline =~ '^\s*\(except\|finally\)$'
  215.         return indnt - &shiftwidth
  216.     endif
  217.  
  218.     if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$'
  219.         return indnt - &shiftwidth
  220.     endif
  221.  
  222.  
  223. " ____________________________________________________________________
  224.  
  225.     " If nothing changed, return same indent.
  226.     return indnt
  227. endfunction
  228.  
  229.