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 / fortran.vim < prev    next >
Encoding:
Text File  |  2012-05-31  |  6.6 KB  |  206 lines

  1. " Vim indent file
  2. " Language:    Fortran95 (and Fortran90, Fortran77, F and elf90)
  3. " Version:    0.40
  4. " Last Change:    2011 Dec. 28
  5. " Maintainer:    Ajit J. Thakkar <ajit@unb.ca>; <http://www.unb.ca/chem/ajit/>
  6. " Usage:    Do :help fortran-indent from Vim
  7.  
  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.  
  14. let s:cposet=&cpoptions
  15. set cpoptions&vim
  16.  
  17. setlocal indentkeys+==~end,=~case,=~if,=~else,=~do,=~where,=~elsewhere,=~select
  18. setlocal indentkeys+==~endif,=~enddo,=~endwhere,=~endselect,=~elseif
  19. setlocal indentkeys+==~type,=~interface,=~forall,=~associate,=~block,=~enum
  20. setlocal indentkeys+==~endforall,=~endassociate,=~endblock,=~endenum
  21. if exists("b:fortran_indent_more") || exists("g:fortran_indent_more")
  22.   setlocal indentkeys+==~function,=~subroutine,=~module,=~contains,=~program
  23.   setlocal indentkeys+==~endfunction,=~endsubroutine,=~endmodule
  24.   setlocal indentkeys+==~endprogram
  25. endif
  26.  
  27. " Determine whether this is a fixed or free format source file
  28. " if this hasn't been done yet
  29. if !exists("b:fortran_fixed_source")
  30.   if exists("fortran_free_source")
  31.     " User guarantees free source form
  32.     let b:fortran_fixed_source = 0
  33.   elseif exists("fortran_fixed_source")
  34.     " User guarantees fixed source form
  35.     let b:fortran_fixed_source = 1
  36.   else
  37.     " f90 and f95 allow both fixed and free source form
  38.     " assume fixed source form unless signs of free source form
  39.     " are detected in the first five columns of the first 250 lines
  40.     " Detection becomes more accurate and time-consuming if more lines
  41.     " are checked. Increase the limit below if you keep lots of comments at
  42.     " the very top of each file and you have a fast computer
  43.     let s:lmax = 500
  44.     if ( s:lmax > line("$") )
  45.       let s:lmax = line("$")
  46.     endif
  47.     let b:fortran_fixed_source = 1
  48.     let s:ln=1
  49.     while s:ln <= s:lmax
  50.       let s:test = strpart(getline(s:ln),0,5)
  51.       if s:test !~ '^[Cc*]' && s:test !~ '^ *[!#]' && s:test =~ '[^ 0-9\t]' && s:test !~ '^[ 0-9]*\t'
  52.     let b:fortran_fixed_source = 0
  53.     break
  54.       endif
  55.       let s:ln = s:ln + 1
  56.     endwhile
  57.   endif
  58. endif
  59.  
  60. " Define the appropriate indent function but only once
  61. if (b:fortran_fixed_source == 1)
  62.   setlocal indentexpr=FortranGetFixedIndent()
  63.   if exists("*FortranGetFixedIndent")
  64.     finish
  65.   endif
  66. else
  67.   setlocal indentexpr=FortranGetFreeIndent()
  68.   if exists("*FortranGetFreeIndent")
  69.     finish
  70.   endif
  71. endif
  72.  
  73. function FortranGetIndent(lnum)
  74.   let ind = indent(a:lnum)
  75.   let prevline=getline(a:lnum)
  76.   " Strip tail comment
  77.   let prevstat=substitute(prevline, '!.*$', '', '')
  78.   let prev2line=getline(a:lnum-1)
  79.   let prev2stat=substitute(prev2line, '!.*$', '', '')
  80.  
  81.   "Indent do loops only if they are all guaranteed to be of do/end do type
  82.   if exists("b:fortran_do_enddo") || exists("g:fortran_do_enddo")
  83.     if prevstat =~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*do\>'
  84.       let ind = ind + &sw
  85.     endif
  86.     if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*end\s*do\>'
  87.       let ind = ind - &sw
  88.     endif
  89.   endif
  90.  
  91.   "Add a shiftwidth to statements following if, else, else if, case,
  92.   "where, else where, forall, type, interface and associate statements
  93.   if prevstat =~? '^\s*\(case\|else\|else\s*if\|else\s*where\)\>'
  94.     \ ||prevstat=~? '^\s*\(type\|interface\|associate\|enum\)\>'
  95.     \ ||prevstat=~?'^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*\(forall\|where\|block\)\>'
  96.     \ ||prevstat=~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*if\>'
  97.      let ind = ind + &sw
  98.     " Remove unwanted indent after logical and arithmetic ifs
  99.     if prevstat =~? '\<if\>' && prevstat !~? '\<then\>'
  100.       let ind = ind - &sw
  101.     endif
  102.     " Remove unwanted indent after type( statements
  103.     if prevstat =~? '^\s*type\s*('
  104.       let ind = ind - &sw
  105.     endif
  106.   endif
  107.  
  108.   "Indent program units unless instructed otherwise
  109.   if !exists("b:fortran_indent_less") && !exists("g:fortran_indent_less")
  110.     let prefix='\(\(pure\|impure\|elemental\|recursive\)\s\+\)\{,2}'
  111.     let type='\(\(integer\|real\|double\s\+precision\|complex\|logical'
  112.           \.'\|character\|type\|class\)\s*\S*\s\+\)\='
  113.     if prevstat =~? '^\s*\(module\|contains\|program\)\>'
  114.             \ ||prevstat =~? '^\s*'.prefix.'subroutine\>'
  115.             \ ||prevstat =~? '^\s*'.prefix.type.'function\>'
  116.             \ ||prevstat =~? '^\s*'.type.prefix.'function\>'
  117.       let ind = ind + &sw
  118.     endif
  119.     if getline(v:lnum) =~? '^\s*contains\>'
  120.           \ ||getline(v:lnum)=~? '^\s*end\s*'
  121.           \ .'\(function\|subroutine\|module\|program\)\>'
  122.       let ind = ind - &sw
  123.     endif
  124.   endif
  125.  
  126.   "Subtract a shiftwidth from else, else if, elsewhere, case, end if,
  127.   " end where, end select, end forall, end interface, end associate,
  128.   " end enum, and end type statements
  129.   if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*'
  130.         \. '\(else\|else\s*if\|else\s*where\|case\|'
  131.         \. 'end\s*\(if\|where\|select\|interface\|'
  132.         \. 'type\|forall\|associate\|enum\)\)\>'
  133.     let ind = ind - &sw
  134.     " Fix indent for case statement immediately after select
  135.     if prevstat =~? '\<select\s\+\(case\|type\)\>'
  136.       let ind = ind + &sw
  137.     endif
  138.   endif
  139.  
  140.   "First continuation line
  141.   if prevstat =~ '&\s*$' && prev2stat !~ '&\s*$'
  142.     let ind = ind + &sw
  143.   endif
  144.   "Line after last continuation line
  145.   if prevstat !~ '&\s*$' && prev2stat =~ '&\s*$'
  146.     let ind = ind - &sw
  147.   endif
  148.  
  149.   return ind
  150. endfunction
  151.  
  152. function FortranGetFreeIndent()
  153.   "Find the previous non-blank line
  154.   let lnum = prevnonblank(v:lnum - 1)
  155.  
  156.   "Use zero indent at the top of the file
  157.   if lnum == 0
  158.     return 0
  159.   endif
  160.  
  161.   let ind=FortranGetIndent(lnum)
  162.   return ind
  163. endfunction
  164.  
  165. function FortranGetFixedIndent()
  166.   let currline=getline(v:lnum)
  167.   "Don't indent comments, continuation lines and labelled lines
  168.   if strpart(currline,0,6) =~ '[^ \t]'
  169.     let ind = indent(v:lnum)
  170.     return ind
  171.   endif
  172.  
  173.   "Find the previous line which is not blank, not a comment,
  174.   "not a continuation line, and does not have a label
  175.   let lnum = v:lnum - 1
  176.   while lnum > 0
  177.     let prevline=getline(lnum)
  178.     if (prevline =~ "^[C*!]") || (prevline =~ "^\s*$")
  179.     \ || (strpart(prevline,5,1) !~ "[ 0]")
  180.       " Skip comments, blank lines and continuation lines
  181.       let lnum = lnum - 1
  182.     else
  183.       let test=strpart(prevline,0,5)
  184.       if test =~ "[0-9]"
  185.     " Skip lines with statement numbers
  186.     let lnum = lnum - 1
  187.       else
  188.     break
  189.       endif
  190.     endif
  191.   endwhile
  192.  
  193.   "First line must begin at column 7
  194.   if lnum == 0
  195.     return 6
  196.   endif
  197.  
  198.   let ind=FortranGetIndent(lnum)
  199.   return ind
  200. endfunction
  201.  
  202. let &cpoptions=s:cposet
  203. unlet s:cposet
  204.  
  205. " vim:sw=2 tw=130
  206.