Mercurial > vim
comparison runtime/indent/vhdl.vim @ 646:eeda7c3124c5
updated for version 7.0188
author | vimboss |
---|---|
date | Thu, 26 Jan 2006 22:17:47 +0000 |
parents | |
children | 9032e4668296 |
comparison
equal
deleted
inserted
replaced
645:ffab4a526a50 | 646:eeda7c3124c5 |
---|---|
1 " VHDL indent file ('93 syntax) | |
2 " Language: VHDL | |
3 " Maintainer: Gerald Lai <laigera+vim?gmail.com> | |
4 " Credits: N. J. Heo & Janez Stangelj | |
5 " Version: 1.1 | |
6 " Last Change: 2006 Jan 25 | |
7 | |
8 " only load this indent file when no other was loaded | |
9 if exists("b:did_indent") | |
10 finish | |
11 endif | |
12 let b:did_indent = 1 | |
13 | |
14 " setup indent options for local VHDL buffer | |
15 setlocal indentexpr=GetVHDLindent() | |
16 setlocal indentkeys=!^F,o,O,e,0(,0) | |
17 setlocal indentkeys+==~if,=~then,=~elsif,=~else | |
18 setlocal indentkeys+==~begin,=~is,=~select,=~-- | |
19 | |
20 " move around | |
21 " keywords: "architecture", "block", "configuration", "component", "entity", "function", "package", "procedure", "process", "record", "units" | |
22 let b:vhdl_explore = '\%(architecture\|block\|configuration\|component\|entity\|function\|package\|procedure\|process\|record\|units\)' | |
23 nnoremap <silent><buffer>[[ :cal search('\%(\<end\s\+\)\@<!\<'.b:vhdl_explore.'\>\c','bW')<CR> | |
24 nnoremap <silent><buffer>]] :cal search('\%(\<end\s\+\)\@<!\<'.b:vhdl_explore.'\>\c','W')<CR> | |
25 nnoremap <silent><buffer>[] :cal search('\<end\s\+'.b:vhdl_explore.'\>\c','bW')<CR> | |
26 nnoremap <silent><buffer>][ :cal search('\<end\s\+'.b:vhdl_explore.'\>\c','W')<CR> | |
27 | |
28 " constants | |
29 " not a comment | |
30 let s:NC = '\%(--.*\)\@<!' | |
31 " end of string | |
32 let s:ES = '\s*\%(--.*\)\=$' | |
33 " no "end" keyword in front | |
34 let s:NE = '\%(\<end\s\+\)\@<!' | |
35 | |
36 " for matchit plugin | |
37 if exists("loaded_matchit") | |
38 let b:match_ignorecase = 1 | |
39 let b:match_words = | |
40 \ s:NE.'\<if\>:\<elsif\>:\<else\>:\<end\s\+if\>,'. | |
41 \ s:NE.'\<case\>:\<when\>:\<end\s\+case\>,'. | |
42 \ s:NE.'\<loop\>:\<end\s\+loop\>,'. | |
43 \ s:NE.'\<for\>:\<end\s\+for\>,'. | |
44 \ s:NE.'\<generate\>:\<end\s\+generate\>,'. | |
45 \ s:NE.'\<record\>:\<end\s\+record\>,'. | |
46 \ s:NE.'\<units\>:\<end\s\+units\>,'. | |
47 \ s:NE.'\<process\>:\<end\s\+process\>,'. | |
48 \ s:NE.'\<block\>:\<end\s\+block\>,'. | |
49 \ s:NE.'\<function\>:\<end\s\+function\>,'. | |
50 \ s:NE.'\<entity\>:\<end\s\+entity\>,'. | |
51 \ s:NE.'\<component\>:\<end\s\+component\>,'. | |
52 \ s:NE.'\<architecture\>:\<end\s\+architecture\>,'. | |
53 \ s:NE.'\<package\>:\<end\s\+package\>,'. | |
54 \ s:NE.'\<procedure\>:\<end\s\+procedure\>,'. | |
55 \ s:NE.'\<configuration\>:\<end\s\+configuration\>' | |
56 endif | |
57 | |
58 " only define indent function once | |
59 if exists("*GetVHDLindent") | |
60 finish | |
61 endif | |
62 | |
63 function GetVHDLindent() | |
64 " store current line & string | |
65 let curn = v:lnum | |
66 let curs = getline(curn) | |
67 | |
68 " find previous line that is not a comment | |
69 let prevn = prevnonblank(curn - 1) | |
70 let prevs = getline(prevn) | |
71 while prevn > 0 && prevs =~ '^\s*--' | |
72 let prevn = prevnonblank(prevn - 1) | |
73 let prevs = getline(prevn) | |
74 endwhile | |
75 | |
76 " default indent starts as previous non-comment line's indent | |
77 let ind = prevn > 0 ? indent(prevn) : 0 | |
78 " backup default | |
79 let ind2 = ind | |
80 | |
81 " indent: previous line's comment position, otherwise follow next non-comment line if possible | |
82 " keyword: "--" | |
83 " where: start of current line | |
84 if curs =~ '^\s*--' | |
85 let pn = curn - 1 | |
86 let ps = getline(pn) | |
87 if ps =~ '--' | |
88 return stridx(ps, '--') | |
89 else | |
90 " find nextnonblank line that is not a comment | |
91 let nn = nextnonblank(curn + 1) | |
92 let ns = getline(nn) | |
93 while nn > 0 && ns =~ '^\s*--' | |
94 let nn = nextnonblank(nn + 1) | |
95 let ns = getline(nn) | |
96 endwhile | |
97 let n = indent(nn) | |
98 return n != -1 ? n : ind | |
99 endif | |
100 endif | |
101 | |
102 " **************************************************************************************** | |
103 " indent: align generic variables & port names | |
104 " keywords: "generic", "map", "port" + "(", provided current line is part of mapping | |
105 " where: anywhere in previous 2 lines | |
106 " find following previous non-comment line | |
107 let pn = prevnonblank(prevn - 1) | |
108 let ps = getline(pn) | |
109 while pn > 0 && ps =~ '^\s*--' | |
110 let pn = prevnonblank(pn - 1) | |
111 let ps = getline(pn) | |
112 endwhile | |
113 if (curs =~ '^\s*)' || curs =~? s:NC.'\%(\<\%(generic\|map\|port\)\>.*\)\@<!\%(=>\s*\S\+\|:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)\)') && (prevs =~? s:NC.'\<\%(generic\|map\|port\)\s*(\%(\s*\w\)\=' || (ps =~? s:NC.'\<\%(generic\|map\|port\)'.s:ES && prevs =~ '^\s*(')) | |
114 " align closing ")" with opening "(" | |
115 if curs =~ '^\s*)' | |
116 return stridx(prevs, '(') | |
117 endif | |
118 let m = matchend(prevs, '(\s*\ze\w') | |
119 if m != -1 | |
120 return m | |
121 else | |
122 return stridx(prevs, '(') + &sw | |
123 endif | |
124 endif | |
125 | |
126 " indent: align conditional/select statement | |
127 " keywords: "<=" without ";" ending | |
128 " where: anywhere in previous line | |
129 if prevs =~ s:NC.'<=[^;]*'.s:ES | |
130 return matchend(prevs, '<=\s*\ze.') | |
131 endif | |
132 | |
133 " indent: backtrace previous non-comment lines for next smaller or equal size indent | |
134 " keywords: "end" + "record", "units" | |
135 " where: start of previous line | |
136 " keyword: ")" | |
137 " where: start of previous line | |
138 " keyword: without "<=" + ";" ending | |
139 " where: anywhere in previous line | |
140 " keyword: "=>" + ")" ending, provided current line does not begin with ")" | |
141 " where: anywhere in previous line | |
142 " _note_: indent allowed to leave this filter | |
143 let m = 0 | |
144 if prevs =~? '^\s*end\s\+\%(record\|units\)\>' | |
145 let m = 3 | |
146 elseif prevs =~ '^\s*)' | |
147 let m = 1 | |
148 elseif prevs =~ s:NC.'\%(<=.*\)\@<!;'.s:ES || (curs !~ '^\s*)' && prevs =~ s:NC.'=>.*'.s:NC.')'.s:ES) | |
149 let m = 2 | |
150 endif | |
151 | |
152 if m > 0 | |
153 let pn = prevnonblank(prevn - 1) | |
154 let ps = getline(pn) | |
155 while pn > 0 | |
156 let t = indent(pn) | |
157 if ps !~ '^\s*--' && t < ind | |
158 " make sure one of these is true | |
159 " keywords: "generic", "map", "port" | |
160 " where: anywhere in previous non-comment line | |
161 " keyword: "(" | |
162 " where: start of previous non-comment line | |
163 " keywords: "<=" without ";" ending | |
164 " where: anywhere in previous non-comment line | |
165 if m < 3 && ps !~ s:NC.'<=[^;]*'.s:ES | |
166 if ps =~? s:NC.'\<\%(generic\|map\|port\)\>' || ps =~ '^\s*(' | |
167 let ind = t | |
168 endif | |
169 break | |
170 endif | |
171 let ind = t | |
172 if m > 1 | |
173 " find following previous non-comment line | |
174 let ppn = prevnonblank(pn - 1) | |
175 let pps = getline(ppn) | |
176 while ppn > 0 && pps =~ '^\s*--' | |
177 let ppn = prevnonblank(ppn - 1) | |
178 let pps = getline(ppn) | |
179 endwhile | |
180 " indent: follow | |
181 " keyword: "select" | |
182 " where: end of following previous non-comment line | |
183 " keyword: "type" | |
184 " where: start of following previous non-comment line | |
185 if m == 2 | |
186 let s1 = s:NC.'\<select'.s:ES | |
187 if ps !~? s1 && pps =~? s1 | |
188 let ind = indent(ppn) | |
189 endif | |
190 elseif m == 3 | |
191 let s1 = '^\s*type\>' | |
192 if ps !~? s1 && pps =~? s1 | |
193 let ind = indent(ppn) | |
194 endif | |
195 endif | |
196 endif | |
197 break | |
198 endif | |
199 let pn = prevnonblank(pn - 1) | |
200 let ps = getline(pn) | |
201 endwhile | |
202 endif | |
203 | |
204 " indent: follow indent of previous opening statement, otherwise -sw | |
205 " keyword: "begin" | |
206 " where: anywhere in current line | |
207 if curs =~? s:NC.'\<begin\>' | |
208 let ind = ind - &sw | |
209 " find previous opening statement of | |
210 " keywords: "architecture", "block", "entity", "function", "generate", "procedure", "process" | |
211 let s2 = s:NC.s:NE.'\<\%(architecture\|block\|entity\|function\|generate\|procedure\|process\)\>' | |
212 if curs !~? s2.'.*'.s:NC.'\<begin\>.*'.s:ES && prevs =~? s2 | |
213 let ind = ind + &sw | |
214 endif | |
215 return ind | |
216 endif | |
217 | |
218 " indent: +sw if previous line is previous opening statement | |
219 " keywords: "record", "units" | |
220 " where: anywhere in current line | |
221 if curs =~? s:NC.s:NE.'\<\%(record\|units\)\>' | |
222 " find previous opening statement of | |
223 " keyword: "type" | |
224 let s3 = s:NC.s:NE.'\<type\>' | |
225 if curs !~? s3.'.*'.s:NC.'\<\%(record\|units\)\>.*'.s:ES && prevs =~? s3 | |
226 let ind = ind + &sw | |
227 endif | |
228 return ind | |
229 endif | |
230 | |
231 " **************************************************************************************** | |
232 " indent: 0 | |
233 " keywords: "architecture", "configuration", "entity", "library", "package" | |
234 " where: start of current line | |
235 if curs =~? '^\s*\%(architecture\|configuration\|entity\|library\|package\)\>' | |
236 return 0 | |
237 endif | |
238 | |
239 " indent: follow indent of previous opening statement | |
240 " keyword: "is" | |
241 " where: start of current line | |
242 " find previous opening statement of | |
243 " keywords: "architecture", "block", "configuration", "entity", "function", "package", "procedure", "process", "type" | |
244 if curs =~? '^\s*\<is\>' && prevs =~? s:NC.s:NE.'\<\%(architecture\|block\|configuration\|entity\|function\|package\|procedure\|process\|type\)\>' | |
245 return indent(prevn) | |
246 endif | |
247 | |
248 " indent: follow indent of previous opening statement | |
249 " keyword: "then" | |
250 " where: start of current line | |
251 " find previous opening statement of | |
252 " keywords: "elsif", "if" | |
253 if curs =~? '^\s*\<then\>' && (prevs =~? s:NC.'\<elsif\>' || prevs =~? s:NC.s:NE.'\<if\>') | |
254 return indent(prevn) | |
255 endif | |
256 | |
257 " indent: follow indent of previous opening statement | |
258 " keyword: "generate" | |
259 " where: start of current line | |
260 " find previous opening statement of | |
261 " keywords: "for", "if" | |
262 if curs =~? '^\s*\<generate\>' && (prevs =~? s:NC.'\<for\>' || prevs =~? s:NC.s:NE.'\<if\>') | |
263 return indent(prevn) | |
264 endif | |
265 | |
266 " indent: +sw | |
267 " keywords: "block", "for", "loop", "process", "record", "units" | |
268 " removed: "case", "if" | |
269 " where: anywhere in previous line | |
270 if prevs =~? s:NC.s:NE.'\<\%(block\|for\|loop\|process\|record\|units\)\>' | |
271 return ind + &sw | |
272 endif | |
273 | |
274 " indent: +sw | |
275 " keywords: "begin" | |
276 " removed: "elsif", "while" | |
277 " where: anywhere in previous line | |
278 if prevs =~? s:NC.'\<begin\>' | |
279 return ind + &sw | |
280 endif | |
281 | |
282 " indent: +sw | |
283 " keywords: "architecture", "component", "configuration", "entity", "package" | |
284 " removed: "package", "when", "with" | |
285 " where: start of previous line | |
286 if prevs =~? '^\s*\%(architecture\|component\|configuration\|entity\|package\)\>' | |
287 return ind + &sw | |
288 endif | |
289 | |
290 " indent: +sw | |
291 " keyword: "generate", "is", "select", "=>" | |
292 " where: end of previous line | |
293 if prevs =~? s:NC.'\<\%(generate\|is\|select\)'.s:ES || prevs =~? s:NC.'=>'.s:ES | |
294 return ind + &sw | |
295 endif | |
296 | |
297 " indent: +sw | |
298 " keyword: "else", "then" | |
299 " where: end of previous line | |
300 " _note_: indent allowed to leave this filter | |
301 if prevs =~? s:NC.'\<\%(else\|then\)'.s:ES | |
302 let ind = ind + &sw | |
303 endif | |
304 | |
305 " **************************************************************************************** | |
306 " indent: -sw if previous line does not begin with "when" | |
307 " keywords: "when" | |
308 " where: start of current line | |
309 let s4 = '^\s*when\>' | |
310 if curs =~? s4 && prevs !~? s4 | |
311 return ind - &sw | |
312 endif | |
313 | |
314 " indent: -sw | |
315 " keywords: "else", "elsif" | |
316 " where: start of current line | |
317 if curs =~? '^\s*\%(else\|elsif\)\>' | |
318 return ind - &sw | |
319 endif | |
320 | |
321 " indent: -sw | |
322 " keywords: "end" + "block", "component", "for", "function", "generate", "if", "loop", "procedure", "process", "record", "units" | |
323 " where: start of current line | |
324 " keyword: ")" | |
325 " where: start of current line | |
326 if curs =~? '^\s*end\s\+\%(block\|component\|for\|function\|generate\|if\|loop\|procedure\|process\|record\|units\)\>' || curs =~ '^\s*)' | |
327 return ind - &sw | |
328 endif | |
329 | |
330 " indent: backtrace previous non-comment lines; -sw if begin with "when", follow if begin with "case" | |
331 " keyword: "end" + "case" | |
332 " where: start of current line | |
333 if curs =~? '^\s*end\s\+case\>' | |
334 " find following previous non-comment line | |
335 let pn = prevn | |
336 let ps = getline(pn) | |
337 while pn > 0 | |
338 if ps !~ '^\s*--' | |
339 if ps =~? '^\s*when\>' | |
340 return indent(pn) - &sw | |
341 elseif ps =~? '^\s*case\>' | |
342 return indent(pn) | |
343 endif | |
344 endif | |
345 let pn = prevnonblank(pn - 1) | |
346 let ps = getline(pn) | |
347 endwhile | |
348 return ind | |
349 endif | |
350 | |
351 " indent: 0 | |
352 " keywords: "end" + "architecture", "configuration", "entity", "package" | |
353 " where: start of current line | |
354 if curs =~? '^\s*end\s\+\%(architecture\|configuration\|entity\|package\)\>' | |
355 return 0 | |
356 endif | |
357 | |
358 " indent: -sw | |
359 " keywords: "end" + identifier | |
360 " where: start of current line | |
361 if curs =~? '^\s*end\s\+\w\+\>' | |
362 return ind - &sw | |
363 endif | |
364 | |
365 " **************************************************************************************** | |
366 " indent: maintain default | |
367 " keywords: without "generic", "map", "port" + ":" but not ":=" + "in", "out", "inout", "buffer", "linkage", variable & ":=" | |
368 " where: anywhere in current line | |
369 if curs =~? s:NC.'\%(\<\%(generic\|map\|port\)\>.*\)\@<!:[^=]\@=\s*\%(\%(in\|out\|inout\|buffer\|linkage\)\>\|\w\+\s\+:=\)' | |
370 return ind2 | |
371 endif | |
372 | |
373 " return leftover filtered indent | |
374 return ind | |
375 endfunction |