Mercurial > hg > RemoteEditor > vim7
comparison runtime/indent/erlang.vim @ 48:67300faee616 v7-3-618
v7-3-618
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 01 Aug 2012 18:08:28 +0900 |
parents | db46d51a3939 |
children |
comparison
equal
deleted
inserted
replaced
47:6c0584ec21b1 | 48:67300faee616 |
---|---|
1 " Vim indent file | 1 " Vim indent file |
2 " Language: Erlang | 2 " Language: Erlang |
3 " Maintainer: Csaba Hoch <csaba.hoch@gmail.com> | 3 " Author: Csaba Hoch <csaba.hoch@gmail.com> |
4 " Contributor: Edwin Fine <efine145_nospam01 at usa dot net> | 4 " Contributors: Edwin Fine <efine145_nospam01 at usa dot net> |
5 " Last Change: 2008 Mar 12 | 5 " Pawel 'kTT' Salata <rockplayer.pl@gmail.com> |
6 | 6 " Ricardo Catalinas Jiménez <jimenezrick@gmail.com> |
7 " Only load this indent file when no other was loaded. | 7 " License: Vim license |
8 " Version: 2011/09/06 | |
9 | |
10 " Only load this indent file when no other was loaded | |
8 if exists("b:did_indent") | 11 if exists("b:did_indent") |
9 finish | 12 finish |
13 else | |
14 let b:did_indent = 1 | |
10 endif | 15 endif |
11 let b:did_indent = 1 | |
12 | 16 |
13 setlocal indentexpr=ErlangIndent() | 17 setlocal indentexpr=ErlangIndent() |
14 setlocal indentkeys+==after,=end,=catch,=),=],=} | 18 setlocal indentkeys+==after,=end,=catch,=),=],=} |
15 | 19 |
16 " Only define the functions once. | 20 " Only define the functions once |
17 if exists("*ErlangIndent") | 21 if exists("*ErlangIndent") |
18 finish | 22 finish |
19 endif | 23 endif |
20 | 24 |
21 " The function go through the whole line, analyses it and sets the indentation | 25 " The function goes through the whole line, analyses it and returns the |
22 " (ind variable). | 26 " indentation level. |
23 " l: the number of the line to be examined. | 27 " |
24 function s:ErlangIndentAtferLine(l) | 28 " line: the line to be examined |
25 let i = 0 " the index of the current character in the line | 29 " return: the indentation level of the examined line |
26 let length = strlen(a:l) " the length of the line | 30 function s:ErlangIndentAfterLine(line) |
31 let linelen = strlen(a:line) " the length of the line | |
32 let i = 0 " the index of the current character in the line | |
27 let ind = 0 " how much should be the difference between the indentation of | 33 let ind = 0 " how much should be the difference between the indentation of |
28 " the current line and the indentation of the next line? | 34 " the current line and the indentation of the next line? |
29 " e.g. +1: the indentation of the next line should be equal to | 35 " e.g. +1: the indentation of the next line should be equal to |
30 " the indentation of the current line plus one shiftwidth | 36 " the indentation of the current line plus one shiftwidth |
31 let lastFun = 0 " the last token was a 'fun' | 37 let last_fun = 0 " the last token was a 'fun' |
32 let lastReceive = 0 " the last token was a 'receive'; needed for 'after' | 38 let last_receive = 0 " the last token was a 'receive'; needed for 'after' |
33 let lastHashMark = 0 " the last token was a 'hashmark' | 39 let last_hash_sym = 0 " the last token was a '#' |
34 | 40 |
35 while 0<= i && i < length | 41 " Ignore comments |
36 | 42 if a:line =~# '^\s*%' |
43 return 0 | |
44 endif | |
45 | |
46 " Partial function head where the guard is missing | |
47 if a:line =~# "\\(^\\l[[:alnum:]_]*\\)\\|\\(^'[^']\\+'\\)(" && a:line !~# '->' | |
48 return 2 | |
49 endif | |
50 | |
51 " The missing guard from the split function head | |
52 if a:line =~# '^\s*when\s\+.*->' | |
53 return -1 | |
54 endif | |
55 | |
56 while 0<=i && i<linelen | |
37 " m: the next value of the i | 57 " m: the next value of the i |
38 if a:l[i] == '%' | 58 if a:line[i] == '"' |
39 break | 59 let m = matchend(a:line,'"\%([^"\\]\|\\.\)*"',i) |
40 elseif a:l[i] == '"' | 60 let last_receive = 0 |
41 let m = matchend(a:l,'"\%([^"\\]\|\\.\)*"',i) | 61 elseif a:line[i] == "'" |
42 let lastReceive = 0 | 62 let m = matchend(a:line,"'[^']*'",i) |
43 elseif a:l[i] == "'" | 63 let last_receive = 0 |
44 let m = matchend(a:l,"'[^']*'",i) | 64 elseif a:line[i] =~# "[a-z]" |
45 let lastReceive = 0 | 65 let m = matchend(a:line,".[[:alnum:]_]*",i) |
46 elseif a:l[i] =~# "[a-z]" | 66 if last_fun |
47 let m = matchend(a:l,".[[:alnum:]_]*",i) | |
48 if lastFun | |
49 let ind = ind - 1 | 67 let ind = ind - 1 |
50 let lastFun = 0 | 68 let last_fun = 0 |
51 let lastReceive = 0 | 69 let last_receive = 0 |
52 elseif a:l[(i):(m-1)] =~# '^\%(case\|if\|try\)$' | 70 elseif a:line[(i):(m-1)] =~# '^\%(case\|if\|try\)$' |
53 let ind = ind + 1 | 71 let ind = ind + 1 |
54 elseif a:l[(i):(m-1)] =~# '^receive$' | 72 elseif a:line[(i):(m-1)] =~# '^receive$' |
55 let ind = ind + 1 | 73 let ind = ind + 1 |
56 let lastReceive = 1 | 74 let last_receive = 1 |
57 elseif a:l[(i):(m-1)] =~# '^begin$' | 75 elseif a:line[(i):(m-1)] =~# '^begin$' |
58 let ind = ind + 2 | 76 let ind = ind + 2 |
59 let lastReceive = 0 | 77 let last_receive = 0 |
60 elseif a:l[(i):(m-1)] =~# '^end$' | 78 elseif a:line[(i):(m-1)] =~# '^end$' |
61 let ind = ind - 2 | 79 let ind = ind - 2 |
62 let lastReceive = 0 | 80 let last_receive = 0 |
63 elseif a:l[(i):(m-1)] =~# '^after$' | 81 elseif a:line[(i):(m-1)] =~# '^after$' |
64 if lastReceive == 0 | 82 if last_receive == 0 |
65 let ind = ind - 1 | 83 let ind = ind - 1 |
66 else | 84 else |
67 let ind = ind + 0 | 85 let ind = ind + 0 |
68 end | 86 endif |
69 let lastReceive = 0 | 87 let last_receive = 0 |
70 elseif a:l[(i):(m-1)] =~# '^fun$' | 88 elseif a:line[(i):(m-1)] =~# '^fun$' |
71 let ind = ind + 1 | 89 let ind = ind + 1 |
72 let lastFun = 1 | 90 let last_fun = 1 |
73 let lastReceive = 0 | 91 let last_receive = 0 |
74 endif | 92 endif |
75 elseif a:l[i] =~# "[A-Z_]" | 93 elseif a:line[i] =~# "[A-Z_]" |
76 let m = matchend(a:l,".[[:alnum:]_]*",i) | 94 let m = matchend(a:line,".[[:alnum:]_]*",i) |
77 let lastReceive = 0 | 95 let last_receive = 0 |
78 elseif a:l[i] == '$' | 96 elseif a:line[i] == '$' |
79 let m = i+2 | 97 let m = i+2 |
80 let lastReceive = 0 | 98 let last_receive = 0 |
81 elseif a:l[i] == "." && (i+1>=length || a:l[i+1]!~ "[0-9]") | 99 elseif a:line[i] == "." && (i+1>=linelen || a:line[i+1]!~ "[0-9]") |
82 let m = i+1 | 100 let m = i+1 |
83 if lastHashMark | 101 if last_hash_sym |
84 let lastHashMark = 0 | 102 let last_hash_sym = 0 |
85 else | 103 else |
86 let ind = ind - 1 | 104 let ind = ind - 1 |
87 end | 105 endif |
88 let lastReceive = 0 | 106 let last_receive = 0 |
89 elseif a:l[i] == '-' && (i+1<length && a:l[i+1]=='>') | 107 elseif a:line[i] == '-' && (i+1<linelen && a:line[i+1]=='>') |
90 let m = i+2 | 108 let m = i+2 |
91 let ind = ind + 1 | 109 let ind = ind + 1 |
92 let lastReceive = 0 | 110 let last_receive = 0 |
93 elseif a:l[i] == ';' | 111 elseif a:line[i] == ';' && a:line[(i):(linelen)] !~# '.*->.*' |
94 let m = i+1 | 112 let m = i+1 |
95 let ind = ind - 1 | 113 let ind = ind - 1 |
96 let lastReceive = 0 | 114 let last_receive = 0 |
97 elseif a:l[i] == '#' | 115 elseif a:line[i] == '#' |
98 let m = i+1 | 116 let m = i+1 |
99 let lastHashMark = 1 | 117 let last_hash_sym = 1 |
100 elseif a:l[i] =~# '[({[]' | 118 elseif a:line[i] =~# '[({[]' |
101 let m = i+1 | 119 let m = i+1 |
102 let ind = ind + 1 | 120 let ind = ind + 1 |
103 let lastFun = 0 | 121 let last_fun = 0 |
104 let lastReceive = 0 | 122 let last_receive = 0 |
105 let lastHashMark = 0 | 123 let last_hash_sym = 0 |
106 elseif a:l[i] =~# '[)}\]]' | 124 elseif a:line[i] =~# '[)}\]]' |
107 let m = i+1 | 125 let m = i+1 |
108 let ind = ind - 1 | 126 let ind = ind - 1 |
109 let lastReceive = 0 | 127 let last_receive = 0 |
110 else | 128 else |
111 let m = i+1 | 129 let m = i+1 |
112 endif | 130 endif |
113 | 131 |
114 let i = m | 132 let i = m |
115 | |
116 endwhile | 133 endwhile |
117 | 134 |
118 return ind | 135 return ind |
119 | |
120 endfunction | 136 endfunction |
121 | 137 |
122 function s:FindPrevNonBlankNonComment(lnum) | 138 function s:FindPrevNonBlankNonComment(lnum) |
123 let lnum = prevnonblank(a:lnum) | 139 let lnum = prevnonblank(a:lnum) |
124 let line = getline(lnum) | 140 let line = getline(lnum) |
125 " continue to search above if the current line begins with a '%' | 141 " Continue to search above if the current line begins with a '%' |
126 while line =~# '^\s*%.*$' | 142 while line =~# '^\s*%.*$' |
127 let lnum = prevnonblank(lnum - 1) | 143 let lnum = prevnonblank(lnum - 1) |
128 if 0 == lnum | 144 if 0 == lnum |
129 return 0 | 145 return 0 |
130 endif | 146 endif |
131 let line = getline(lnum) | 147 let line = getline(lnum) |
132 endwhile | 148 endwhile |
133 return lnum | 149 return lnum |
134 endfunction | 150 endfunction |
135 | 151 |
152 " The function returns the indentation level of the line adjusted to a mutiple | |
153 " of 'shiftwidth' option. | |
154 " | |
155 " lnum: line number | |
156 " return: the indentation level of the line | |
157 function s:GetLineIndent(lnum) | |
158 return (indent(a:lnum) / &sw) * &sw | |
159 endfunction | |
160 | |
136 function ErlangIndent() | 161 function ErlangIndent() |
137 | 162 " Find a non-blank line above the current line |
138 " Find a non-blank line above the current line. | |
139 let lnum = prevnonblank(v:lnum - 1) | 163 let lnum = prevnonblank(v:lnum - 1) |
140 | 164 |
141 " Hit the start of the file, use zero indent. | 165 " Hit the start of the file, use zero indent |
142 if lnum == 0 | 166 if lnum == 0 |
143 return 0 | 167 return 0 |
144 endif | 168 endif |
145 | 169 |
146 let prevline = getline(lnum) | 170 let prevline = getline(lnum) |
147 let currline = getline(v:lnum) | 171 let currline = getline(v:lnum) |
148 | 172 |
149 let ind = indent(lnum) + &sw * s:ErlangIndentAtferLine(prevline) | 173 let ind_after = s:ErlangIndentAfterLine(prevline) |
150 | 174 if ind_after != 0 |
151 " special cases: | 175 let ind = s:GetLineIndent(lnum) + ind_after * &sw |
176 else | |
177 let ind = indent(lnum) + ind_after * &sw | |
178 endif | |
179 | |
180 " Special cases: | |
152 if prevline =~# '^\s*\%(after\|end\)\>' | 181 if prevline =~# '^\s*\%(after\|end\)\>' |
153 let ind = ind + 2*&sw | 182 let ind = ind + 2*&sw |
154 endif | 183 endif |
155 if currline =~# '^\s*end\>' | 184 if currline =~# '^\s*end\>' |
156 let ind = ind - 2*&sw | 185 let ind = ind - 2*&sw |
157 endif | 186 endif |
158 if currline =~# '^\s*after\>' | 187 if currline =~# '^\s*after\>' |
159 let plnum = s:FindPrevNonBlankNonComment(v:lnum-1) | 188 let plnum = s:FindPrevNonBlankNonComment(v:lnum-1) |
160 if getline(plnum) =~# '^[^%]*\<receive\>\s*\%(%.*\)\=$' | 189 if getline(plnum) =~# '^[^%]*\<receive\>\s*\%(%.*\)\=$' |
190 " If the 'receive' is not in the same line as the 'after' | |
161 let ind = ind - 1*&sw | 191 let ind = ind - 1*&sw |
162 " If the 'receive' is not in the same line as the 'after' | |
163 else | 192 else |
164 let ind = ind - 2*&sw | 193 let ind = ind - 2*&sw |
165 endif | 194 endif |
166 endif | 195 endif |
167 if prevline =~# '^\s*[)}\]]' | 196 if prevline =~# '^\s*[)}\]]' |
179 | 208 |
180 if ind<0 | 209 if ind<0 |
181 let ind = 0 | 210 let ind = 0 |
182 endif | 211 endif |
183 return ind | 212 return ind |
184 | 213 endfunction |
185 endfunction | |
186 | |
187 " TODO: | |
188 " | |
189 " f() -> | |
190 " x("foo | |
191 " bar") | |
192 " , | |
193 " bad_indent. | |
194 " | |
195 " fun | |
196 " init/0, | |
197 " bad_indent | |
198 " | |
199 " #rec | |
200 " .field, | |
201 " bad_indent | |
202 " | |
203 " case X of | |
204 " 1 when A; B -> | |
205 " bad_indent | |
206 |