Opening with search text does inclusive search
[MacVim.git] / runtime / indent / erlang.vim
blob5ce3f82e0e1139cef2fc40282483db7eca086f13
1 " Vim indent file
2 " Language:     Erlang
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")
9   finish
10 endif
11 let b:did_indent = 1
13 setlocal indentexpr=ErlangIndent()
14 setlocal indentkeys+==after,=end,=catch,=),=],=}
16 " Only define the functions once.
17 if exists("*ErlangIndent")
18    finish
19 endif
21 " The function go through the whole line, analyses it and sets the indentation
22 " (ind variable).
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
38         if a:l[i] == '%'
39             break
40         elseif a:l[i] == '"'
41             let m = matchend(a:l,'"\%([^"\\]\|\\.\)*"',i)
42             let lastReceive = 0
43         elseif a:l[i] == "'"
44             let m = matchend(a:l,"'[^']*'",i)
45             let lastReceive = 0
46         elseif a:l[i] =~# "[a-z]"
47             let m = matchend(a:l,".[[:alnum:]_]*",i)
48             if lastFun
49                 let ind = ind - 1
50                 let lastFun = 0
51                 let lastReceive = 0
52             elseif a:l[(i):(m-1)] =~# '^\%(case\|if\|try\)$'
53                 let ind = ind + 1
54             elseif a:l[(i):(m-1)] =~# '^receive$'
55                 let ind = ind + 1
56                 let lastReceive = 1
57             elseif a:l[(i):(m-1)] =~# '^begin$'
58                 let ind = ind + 2
59                 let lastReceive = 0
60             elseif a:l[(i):(m-1)] =~# '^end$'
61                 let ind = ind - 2
62                 let lastReceive = 0
63             elseif a:l[(i):(m-1)] =~# '^after$'
64                 if lastReceive == 0
65                     let ind = ind - 1
66                 else
67                     let ind = ind + 0
68                 end
69                 let lastReceive = 0
70             elseif a:l[(i):(m-1)] =~# '^fun$'
71                 let ind = ind + 1
72                 let lastFun = 1
73                 let lastReceive = 0
74             endif
75         elseif a:l[i] =~# "[A-Z_]"
76             let m = matchend(a:l,".[[:alnum:]_]*",i)
77             let lastReceive = 0
78         elseif a:l[i] == '$'
79             let m = i+2
80             let lastReceive = 0
81         elseif a:l[i] == "." && (i+1>=length || a:l[i+1]!~ "[0-9]")
82             let m = i+1
83             if lastHashMark
84                 let lastHashMark = 0
85             else
86                 let ind = ind - 1
87             end
88             let lastReceive = 0
89         elseif a:l[i] == '-' && (i+1<length && a:l[i+1]=='>')
90             let m = i+2
91             let ind = ind + 1
92             let lastReceive = 0
93         elseif a:l[i] == ';'
94             let m = i+1
95             let ind = ind - 1
96             let lastReceive = 0
97         elseif a:l[i] == '#'
98             let m = i+1
99             let lastHashMark = 1
100         elseif a:l[i] =~# '[({[]'
101             let m = i+1
102             let ind = ind + 1
103             let lastFun = 0
104             let lastReceive = 0
105             let lastHashMark = 0
106         elseif a:l[i] =~# '[)}\]]'
107             let m = i+1
108             let ind = ind - 1
109             let lastReceive = 0
110         else
111             let m = i+1
112         endif
114         let i = m
116     endwhile
118     return ind
120 endfunction
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)
128         if 0 == lnum
129             return 0
130         endif
131         let line = getline(lnum)
132     endwhile
133     return lnum
134 endfunction
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.
142     if lnum == 0
143         return 0
144     endif
146     let prevline = getline(lnum)
147     let currline = getline(v:lnum)
149     let ind = indent(lnum) + &sw * s:ErlangIndentAtferLine(prevline)
151     " special cases:
152     if prevline =~# '^\s*\%(after\|end\)\>'
153         let ind = ind + 2*&sw
154     endif
155     if currline =~# '^\s*end\>'
156         let ind = ind - 2*&sw
157     endif
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'
163         else
164             let ind = ind - 2*&sw
165         endif
166     endif
167     if prevline =~# '^\s*[)}\]]'
168         let ind = ind + 1*&sw
169     endif
170     if currline =~# '^\s*[)}\]]'
171         let ind = ind - 1*&sw
172     endif
173     if prevline =~# '^\s*\%(catch\)\s*\%(%\|$\)'
174         let ind = ind + 1*&sw
175     endif
176     if currline =~# '^\s*\%(catch\)\s*\%(%\|$\)'
177         let ind = ind - 1*&sw
178     endif
180     if ind<0
181         let ind = 0
182     endif
183     return ind
185 endfunction
187 " TODO:
189 " f() ->
190 "     x("foo
191 "         bar")
192 "         ,
193 "         bad_indent.
195 " fun
196 "     init/0,
197 "     bad_indent
199 "     #rec
200 "     .field,
201 " bad_indent
203 " case X of
204 "     1 when A; B ->
205 "     bad_indent