2 " Language: Fortran95 (and Fortran90, Fortran77, F and elf90)
4 " URL: http://www.unb.ca/chem/ajit/indent/fortran.vim
5 " Last Change: 2006 Nov 16
6 " Maintainer: Ajit J. Thakkar <ajit@unb.ca>; <http://www.unb.ca/chem/ajit/>
7 " Usage: Do :help fortran-indent from Vim
9 " Only load this indent file when no other was loaded.
10 if exists("b:did_indent")
15 setlocal indentkeys+==~end,=~case,=~if,=~else,=~do,=~where,=~elsewhere,=~select
16 setlocal indentkeys+==~endif,=~enddo,=~endwhere,=~endselect
17 setlocal indentkeys+==~type,=~interface
19 " Determine whether this is a fixed or free format source file
20 " if this hasn't been done yet
21 if !exists("b:fortran_fixed_source")
22 if exists("fortran_free_source")
23 " User guarantees free source form
24 let b:fortran_fixed_source = 0
25 elseif exists("fortran_fixed_source")
26 " User guarantees fixed source form
27 let b:fortran_fixed_source = 1
29 " f90 and f95 allow both fixed and free source form
30 " assume fixed source form unless signs of free source form
31 " are detected in the first five columns of the first 250 lines
32 " Detection becomes more accurate and time-consuming if more lines
33 " are checked. Increase the limit below if you keep lots of comments at
34 " the very top of each file and you have a fast computer
36 if ( s:lmax > line("$") )
37 let s:lmax = line("$")
39 let b:fortran_fixed_source = 1
42 let s:test = strpart(getline(s:ln),0,5)
43 if s:test[0] !~ '[Cc*!#]' && s:test !~ '^ \+[!#]' && s:test =~ '[^ 0-9\t]'
44 let b:fortran_fixed_source = 0
52 " Define the appropriate indent function but only once
53 if (b:fortran_fixed_source == 1)
54 setlocal indentexpr=FortranGetFixedIndent()
55 if exists("*FortranGetFixedIndent")
59 setlocal indentexpr=FortranGetFreeIndent()
60 if exists("*FortranGetFreeIndent")
65 let s:cposet=&cpoptions
68 function FortranGetIndent(lnum)
69 let ind = indent(a:lnum)
70 let prevline=getline(a:lnum)
72 let prevstat=substitute(prevline, '!.*$', '', '')
74 "Indent do loops only if they are all guaranteed to be of do/end do type
75 if exists("b:fortran_do_enddo") || exists("g:fortran_do_enddo")
76 if prevstat =~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*do\>'
79 if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*end\s*do\>'
84 "Add a shiftwidth to statements following if, else, case,
85 "where, elsewhere, type and interface statements
86 if prevstat =~? '^\s*\(\d\+\s\)\=\s*\(else\|case\|where\|elsewhere\)\>'
87 \ ||prevstat =~? '^\s*\(\d\+\s\)\=\s*\(type\|interface\)\>'
88 \ || prevstat =~? '^\s*\(\d\+\s\)\=\s*\(\a\w*\s*:\)\=\s*if\>'
90 " Remove unwanted indent after logical and arithmetic ifs
91 if prevstat =~? '\<if\>' && prevstat !~? '\<then\>'
94 " Remove unwanted indent after type( statements
95 if prevstat =~? '\<type\s*('
100 "Subtract a shiftwidth from else, elsewhere, case, end if,
101 " end where, end select, end interface and end type statements
102 if getline(v:lnum) =~? '^\s*\(\d\+\s\)\=\s*'
103 \. '\(else\|elsewhere\|case\|end\s*\(if\|where\|select\|interface\|type\)\)\>'
105 " Fix indent for case statement immediately after select
106 if prevstat =~? '\<select\>'
114 function FortranGetFreeIndent()
115 "Find the previous non-blank line
116 let lnum = prevnonblank(v:lnum - 1)
118 "Use zero indent at the top of the file
123 let ind=FortranGetIndent(lnum)
127 function FortranGetFixedIndent()
128 let currline=getline(v:lnum)
129 "Don't indent comments, continuation lines and labelled lines
130 if strpart(currline,0,6) =~ '[^ \t]'
131 let ind = indent(v:lnum)
135 "Find the previous line which is not blank, not a comment,
136 "not a continuation line, and does not have a label
137 let lnum = v:lnum - 1
139 let prevline=getline(lnum)
140 if (prevline =~ "^[C*!]") || (prevline =~ "^\s*$")
141 \ || (strpart(prevline,5,1) !~ "[ 0]")
142 " Skip comments, blank lines and continuation lines
145 let test=strpart(prevline,0,5)
147 " Skip lines with statement numbers
155 "First line must begin at column 7
160 let ind=FortranGetIndent(lnum)
164 let &cpoptions=s:cposet