3 " Maintainer: Csaba Hoch <csaba.hoch@gmail.com>
4 " Last Change: 2007 Dec 08
6 " Only load this indent file when no other was loaded.
7 if exists("b:did_indent")
12 setlocal indentexpr=ErlangIndent()
13 setlocal indentkeys+==after,=end,=catch,=),=],=}
15 " Only define the functions once.
16 if exists("*ErlangIndent")
20 " The function go through the whole line, analyses it and sets the indentation
22 " l: the number of the line to be examined.
23 function s:ErlangIndentAtferLine(l)
24 let i = 0 " the index of the current character in the line
25 let length = strlen(a:l) " the length of the line
26 let ind = 0 " how much should be the difference between the indentation of
27 " the current line and the indentation of the next line?
28 " e.g. +1: the indentation of the next line should be equal to
29 " the indentation of the current line plus one shiftwidth
30 let lastFun = 0 " the last token was a 'fun'
31 let lastReceive = 0 " the last token was a 'receive'; needed for 'after'
32 let lastHashMark = 0 " the last token was a 'hashmark'
34 while 0<= i && i < length
36 " m: the next value of the i
40 let m = matchend(a:l,'"\%([^"\\]\|\\.\)*"',i)
43 let m = matchend(a:l,"'[^']*'",i)
45 elseif a:l[i] =~ "[a-z]"
46 let m = matchend(a:l,".[[:alnum:]_]*",i)
51 elseif a:l[(i):(m-1)] =~ '^\%(case\|if\|try\)$'
53 elseif a:l[(i):(m-1)] =~ '^receive$'
56 elseif a:l[(i):(m-1)] =~ '^begin$'
59 elseif a:l[(i):(m-1)] =~ '^end$'
62 elseif a:l[(i):(m-1)] =~ '^after$'
69 elseif a:l[(i):(m-1)] =~ '^fun$'
74 elseif a:l[i] =~ "[A-Z_]"
75 let m = matchend(a:l,".[[:alnum:]_]*",i)
80 elseif a:l[i] == "." && (i+1>=length || a:l[i+1]!~ "[0-9]")
88 elseif a:l[i] == '-' && (i+1<length && a:l[i+1]=='>')
99 elseif a:l[i] =~ '[({[]'
105 elseif a:l[i] =~ '[)}\]]'
121 function s:FindPrevNonBlankNonComment(lnum)
122 let lnum = prevnonblank(a:lnum)
123 let line = getline(lnum)
124 " continue to search above if the current line begins with a '%'
125 while line =~ '^\s*%.*$'
126 let lnum = prevnonblank(lnum - 1)
130 let line = getline(lnum)
135 function ErlangIndent()
137 " Find a non-blank line above the current line.
138 let lnum = prevnonblank(v:lnum - 1)
140 " Hit the start of the file, use zero indent.
145 let prevline = getline(lnum)
146 let currline = getline(v:lnum)
148 let ind = indent(lnum) + &sw * s:ErlangIndentAtferLine(prevline)
151 if prevline =~ '^\s*\%(after\|end\)\>'
152 let ind = ind + 2*&sw
154 if currline =~ '^\s*end\>'
155 let ind = ind - 2*&sw
157 if currline =~ '^\s*after\>'
158 let plnum = s:FindPrevNonBlankNonComment(v:lnum-1)
159 if getline(plnum) =~ '^[^%]*\<receive\>\s*\%(%.*\)\=$'
160 let ind = ind - 1*&sw
161 " If the 'receive' is not in the same line as the 'after'
163 let ind = ind - 2*&sw
166 if prevline =~ '^\s*[)}\]]'
167 let ind = ind + 1*&sw
169 if currline =~ '^\s*[)}\]]'
170 let ind = ind - 1*&sw
172 if prevline =~ '^\s*\%(catch\)\s*\%(%\|$\)'
173 let ind = ind + 1*&sw
175 if currline =~ '^\s*\%(catch\)\s*\%(%\|$\)'
176 let ind = ind - 1*&sw