3 " Maintainer: Csaba Hoch <csaba.hoch@gmail.com>
4 " Contributor: Edwin Fine <efine145_nospam01 at usa dot net>
5 " Last Change: 2008 Mar 12
7 " Only load this indent file when no other was loaded.
8 if exists("b:did_indent")
13 setlocal indentexpr=ErlangIndent()
14 setlocal indentkeys+==after,=end,=catch,=),=],=}
16 " Only define the functions once.
17 if exists("*ErlangIndent")
21 " The function go through the whole line, analyses it and sets the indentation
23 " l: the number of the line to be examined.
24 function s:ErlangIndentAtferLine(l)
25 let i = 0 " the index of the current character in the line
26 let length = strlen(a:l) " the length of the line
27 let ind = 0 " how much should be the difference between the indentation of
28 " the current line and the indentation of the next line?
29 " e.g. +1: the indentation of the next line should be equal to
30 " the indentation of the current line plus one shiftwidth
31 let lastFun = 0 " the last token was a 'fun'
32 let lastReceive = 0 " the last token was a 'receive'; needed for 'after'
33 let lastHashMark = 0 " the last token was a 'hashmark'
35 while 0<= i && i < length
37 " m: the next value of the i
41 let m = matchend(a:l,'"\%([^"\\]\|\\.\)*"',i)
44 let m = matchend(a:l,"'[^']*'",i)
46 elseif a:l[i] =~# "[a-z]"
47 let m = matchend(a:l,".[[:alnum:]_]*",i)
52 elseif a:l[(i):(m-1)] =~# '^\%(case\|if\|try\)$'
54 elseif a:l[(i):(m-1)] =~# '^receive$'
57 elseif a:l[(i):(m-1)] =~# '^begin$'
60 elseif a:l[(i):(m-1)] =~# '^end$'
63 elseif a:l[(i):(m-1)] =~# '^after$'
70 elseif a:l[(i):(m-1)] =~# '^fun$'
75 elseif a:l[i] =~# "[A-Z_]"
76 let m = matchend(a:l,".[[:alnum:]_]*",i)
81 elseif a:l[i] == "." && (i+1>=length || a:l[i+1]!~ "[0-9]")
89 elseif a:l[i] == '-' && (i+1<length && a:l[i+1]=='>')
100 elseif a:l[i] =~# '[({[]'
106 elseif a:l[i] =~# '[)}\]]'
122 function s:FindPrevNonBlankNonComment(lnum)
123 let lnum = prevnonblank(a:lnum)
124 let line = getline(lnum)
125 " continue to search above if the current line begins with a '%'
126 while line =~# '^\s*%.*$'
127 let lnum = prevnonblank(lnum - 1)
131 let line = getline(lnum)
136 function ErlangIndent()
138 " Find a non-blank line above the current line.
139 let lnum = prevnonblank(v:lnum - 1)
141 " Hit the start of the file, use zero indent.
146 let prevline = getline(lnum)
147 let currline = getline(v:lnum)
149 let ind = indent(lnum) + &sw * s:ErlangIndentAtferLine(prevline)
152 if prevline =~# '^\s*\%(after\|end\)\>'
153 let ind = ind + 2*&sw
155 if currline =~# '^\s*end\>'
156 let ind = ind - 2*&sw
158 if currline =~# '^\s*after\>'
159 let plnum = s:FindPrevNonBlankNonComment(v:lnum-1)
160 if getline(plnum) =~# '^[^%]*\<receive\>\s*\%(%.*\)\=$'
161 let ind = ind - 1*&sw
162 " If the 'receive' is not in the same line as the 'after'
164 let ind = ind - 2*&sw
167 if prevline =~# '^\s*[)}\]]'
168 let ind = ind + 1*&sw
170 if currline =~# '^\s*[)}\]]'
171 let ind = ind - 1*&sw
173 if prevline =~# '^\s*\%(catch\)\s*\%(%\|$\)'
174 let ind = ind + 1*&sw
176 if currline =~# '^\s*\%(catch\)\s*\%(%\|$\)'
177 let ind = ind - 1*&sw