Mercurial > vim
annotate runtime/indent/ada.vim @ 4531:1be43c095aff v7.3.1013
updated for version 7.3.1013
Problem: New regexp logging is a bit messy.
Solution: Consistently use #defines, add explanatory comment. (Taro Muraoka)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Sat, 25 May 2013 12:18:39 +0200 |
parents | 8201108e9cf0 |
children | 47b1887483da |
rev | line source |
---|---|
1121 | 1 "------------------------------------------------------------------------------ |
2 " Description: Vim Ada indent file | |
3 " Language: Ada (2005) | |
2034 | 4 " $Id: ada.vim 887 2008-07-08 14:29:01Z krischik $ |
1121 | 5 " Copyright: Copyright (C) 2006 Martin Krischik |
1668 | 6 " Maintainer: Martin Krischik <krischik@users.sourceforge.net> |
1121 | 7 " Neil Bird <neil@fnxweb.com> |
1668 | 8 " Ned Okie <nokie@radford.edu> |
2034 | 9 " $Author: krischik $ |
10 " $Date: 2008-07-08 16:29:01 +0200 (Di, 08 Jul 2008) $ | |
1668 | 11 " Version: 4.6 |
2034 | 12 " $Revision: 887 $ |
1668 | 13 " $HeadURL: https://gnuada.svn.sourceforge.net/svnroot/gnuada/trunk/tools/vim/indent/ada.vim $ |
1121 | 14 " History: 24.05.2006 MK Unified Headers |
15 " 16.07.2006 MK Ada-Mode as vim-ball | |
16 " 15.10.2006 MK Bram's suggestion for runtime integration | |
17 " 05.11.2006 MK Bram suggested to save on spaces | |
1668 | 18 " 19.09.2007 NO g: missing before ada#Comment |
1121 | 19 " Help Page: ft-vim-indent |
20 "------------------------------------------------------------------------------ | |
7 | 21 " ToDo: |
22 " Verify handling of multi-line exprs. and recovery upon the final ';'. | |
23 " Correctly find comments given '"' and "" ==> " syntax. | |
24 " Combine the two large block-indent functions into one? | |
1121 | 25 "------------------------------------------------------------------------------ |
7 | 26 |
27 " Only load this indent file when no other was loaded. | |
1121 | 28 if exists("b:did_indent") || version < 700 |
7 | 29 finish |
30 endif | |
1121 | 31 |
1668 | 32 let b:did_indent = 45 |
7 | 33 |
34 setlocal indentexpr=GetAdaIndent() | |
35 setlocal indentkeys-=0{,0} | |
36 setlocal indentkeys+=0=~then,0=~end,0=~elsif,0=~when,0=~exception,0=~begin,0=~is,0=~record | |
37 | |
38 " Only define the functions once. | |
39 if exists("*GetAdaIndent") | |
40 finish | |
41 endif | |
3507
8201108e9cf0
More runtime file fixes for 'compatible' mode.
Bram Moolenaar <bram@vim.org>
parents:
3496
diff
changeset
|
42 let s:keepcpo= &cpo |
8201108e9cf0
More runtime file fixes for 'compatible' mode.
Bram Moolenaar <bram@vim.org>
parents:
3496
diff
changeset
|
43 set cpo&vim |
7 | 44 |
1121 | 45 if exists("g:ada_with_gnat_project_files") |
46 let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\<is\>[^;]*$\|\(type\>.*\)\=\<record\>\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|project\>\|then\>\|when\>\|is\>\)' | |
47 else | |
48 let s:AdaBlockStart = '^\s*\(if\>\|while\>\|else\>\|elsif\>\|loop\>\|for\>.*\<\(loop\|use\)\>\|declare\>\|begin\>\|type\>.*\<is\>[^;]*$\|\(type\>.*\)\=\<record\>\|procedure\>\|function\>\|accept\>\|do\>\|task\>\|package\>\|then\>\|when\>\|is\>\)' | |
49 endif | |
7 | 50 |
1121 | 51 " Section: s:MainBlockIndent {{{1 |
52 " | |
36 | 53 " Try to find indent of the block we're in |
7 | 54 " prev_indent = the previous line's indent |
55 " prev_lnum = previous line (to start looking on) | |
56 " blockstart = expr. that indicates a possible start of this block | |
57 " stop_at = if non-null, if a matching line is found, gives up! | |
58 " No recursive previous block analysis: simply look for a valid line | |
59 " with a lesser or equal indent than we currently (on prev_lnum) have. | |
60 " This shouldn't work as well as it appears to with lines that are currently | |
61 " nowhere near the correct indent (e.g., start of line)! | |
62 " Seems to work OK as it 'starts' with the indent of the /previous/ line. | |
1121 | 63 function s:MainBlockIndent (prev_indent, prev_lnum, blockstart, stop_at) |
7 | 64 let lnum = a:prev_lnum |
1668 | 65 let line = substitute( getline(lnum), g:ada#Comment, '', '' ) |
7 | 66 while lnum > 1 |
67 if a:stop_at != '' && line =~ '^\s*' . a:stop_at && indent(lnum) < a:prev_indent | |
856 | 68 return a:prev_indent |
7 | 69 elseif line =~ '^\s*' . a:blockstart |
856 | 70 let ind = indent(lnum) |
71 if ind < a:prev_indent | |
72 return ind | |
73 endif | |
7 | 74 endif |
75 | |
76 let lnum = prevnonblank(lnum - 1) | |
77 " Get previous non-blank/non-comment-only line | |
78 while 1 | |
1668 | 79 let line = substitute( getline(lnum), g:ada#Comment, '', '' ) |
856 | 80 if line !~ '^\s*$' && line !~ '^\s*#' |
81 break | |
82 endif | |
83 let lnum = prevnonblank(lnum - 1) | |
84 if lnum <= 0 | |
85 return a:prev_indent | |
86 endif | |
7 | 87 endwhile |
88 endwhile | |
89 " Fallback - just move back one | |
90 return a:prev_indent - &sw | |
1121 | 91 endfunction MainBlockIndent |
7 | 92 |
1121 | 93 " Section: s:EndBlockIndent {{{1 |
94 " | |
7 | 95 " Try to find indent of the block we're in (and about to complete), |
96 " including handling of nested blocks. Works on the 'end' of a block. | |
97 " prev_indent = the previous line's indent | |
98 " prev_lnum = previous line (to start looking on) | |
99 " blockstart = expr. that indicates a possible start of this block | |
100 " blockend = expr. that indicates a possible end of this block | |
101 function s:EndBlockIndent( prev_indent, prev_lnum, blockstart, blockend ) | |
102 let lnum = a:prev_lnum | |
103 let line = getline(lnum) | |
104 let ends = 0 | |
105 while lnum > 1 | |
106 if getline(lnum) =~ '^\s*' . a:blockstart | |
107 let ind = indent(lnum) | |
856 | 108 if ends <= 0 |
109 if ind < a:prev_indent | |
7 | 110 return ind |
856 | 111 endif |
112 else | |
113 let ends = ends - 1 | |
7 | 114 endif |
115 elseif getline(lnum) =~ '^\s*' . a:blockend | |
856 | 116 let ends = ends + 1 |
7 | 117 endif |
118 | |
119 let lnum = prevnonblank(lnum - 1) | |
120 " Get previous non-blank/non-comment-only line | |
121 while 1 | |
122 let line = getline(lnum) | |
1668 | 123 let line = substitute( line, g:ada#Comment, '', '' ) |
7 | 124 if line !~ '^\s*$' |
125 break | |
126 endif | |
127 let lnum = prevnonblank(lnum - 1) | |
128 if lnum <= 0 | |
129 return a:prev_indent | |
130 endif | |
131 endwhile | |
132 endwhile | |
133 " Fallback - just move back one | |
134 return a:prev_indent - &sw | |
1121 | 135 endfunction EndBlockIndent |
7 | 136 |
1121 | 137 " Section: s:StatementIndent {{{1 |
138 " | |
36 | 139 " Return indent of previous statement-start |
7 | 140 " (after we've indented due to multi-line statements). |
141 " This time, we start searching on the line *before* the one given (which is | |
142 " the end of a statement - we want the previous beginning). | |
143 function s:StatementIndent( current_indent, prev_lnum ) | |
144 let lnum = a:prev_lnum | |
145 while lnum > 0 | |
146 let prev_lnum = lnum | |
147 let lnum = prevnonblank(lnum - 1) | |
148 " Get previous non-blank/non-comment-only line | |
149 while 1 | |
1668 | 150 let line = substitute( getline(lnum), g:ada#Comment, '', '' ) |
151 | |
856 | 152 if line !~ '^\s*$' && line !~ '^\s*#' |
153 break | |
154 endif | |
155 let lnum = prevnonblank(lnum - 1) | |
156 if lnum <= 0 | |
157 return a:current_indent | |
158 endif | |
7 | 159 endwhile |
160 " Leave indent alone if our ';' line is part of a ';'-delineated | |
161 " aggregate (e.g., procedure args.) or first line after a block start. | |
162 if line =~ s:AdaBlockStart || line =~ '(\s*$' | |
856 | 163 return a:current_indent |
7 | 164 endif |
165 if line !~ '[.=(]\s*$' | |
856 | 166 let ind = indent(prev_lnum) |
167 if ind < a:current_indent | |
168 return ind | |
169 endif | |
7 | 170 endif |
171 endwhile | |
172 " Fallback - just use current one | |
173 return a:current_indent | |
1121 | 174 endfunction StatementIndent |
7 | 175 |
176 | |
1121 | 177 " Section: GetAdaIndent {{{1 |
178 " | |
7 | 179 " Find correct indent of a new line based upon what went before |
1121 | 180 " |
7 | 181 function GetAdaIndent() |
182 " Find a non-blank line above the current line. | |
183 let lnum = prevnonblank(v:lnum - 1) | |
184 let ind = indent(lnum) | |
185 let package_line = 0 | |
186 | |
187 " Get previous non-blank/non-comment-only/non-cpp line | |
188 while 1 | |
1121 | 189 let line = substitute( getline(lnum), g:ada#Comment, '', '' ) |
7 | 190 if line !~ '^\s*$' && line !~ '^\s*#' |
856 | 191 break |
7 | 192 endif |
193 let lnum = prevnonblank(lnum - 1) | |
194 if lnum <= 0 | |
856 | 195 return ind |
7 | 196 endif |
197 endwhile | |
198 | |
199 " Get default indent (from prev. line) | |
200 let ind = indent(lnum) | |
36 | 201 let initind = ind |
7 | 202 |
203 " Now check what's on the previous line | |
204 if line =~ s:AdaBlockStart || line =~ '(\s*$' | |
205 " Check for false matches to AdaBlockStart | |
206 let false_match = 0 | |
207 if line =~ '^\s*\(procedure\|function\|package\)\>.*\<is\s*new\>' | |
856 | 208 " Generic instantiation |
209 let false_match = 1 | |
7 | 210 elseif line =~ ')\s*;\s*$' || line =~ '^\([^(]*([^)]*)\)*[^(]*;\s*$' |
856 | 211 " forward declaration |
212 let false_match = 1 | |
7 | 213 endif |
214 " Move indent in | |
215 if ! false_match | |
856 | 216 let ind = ind + &sw |
7 | 217 endif |
218 elseif line =~ '^\s*\(case\|exception\)\>' | |
219 " Move indent in twice (next 'when' will move back) | |
220 let ind = ind + 2 * &sw | |
221 elseif line =~ '^\s*end\s*record\>' | |
222 " Move indent back to tallying 'type' preceeding the 'record'. | |
223 " Allow indent to be equal to 'end record's. | |
224 let ind = s:MainBlockIndent( ind+&sw, lnum, 'type\>', '' ) | |
225 elseif line =~ '\(^\s*new\>.*\)\@<!)\s*[;,]\s*$' | |
226 " Revert to indent of line that started this parenthesis pair | |
227 exe lnum | |
228 exe 'normal! $F)%' | |
229 if getline('.') =~ '^\s*(' | |
1668 | 230 " Dire layout - use previous indent (could check for g:ada#Comment here) |
856 | 231 let ind = indent( prevnonblank( line('.')-1 ) ) |
7 | 232 else |
856 | 233 let ind = indent('.') |
7 | 234 endif |
235 exe v:lnum | |
236 elseif line =~ '[.=(]\s*$' | |
237 " A statement continuation - move in one | |
238 let ind = ind + &sw | |
239 elseif line =~ '^\s*new\>' | |
240 " Multiple line generic instantiation ('package blah is\nnew thingy') | |
241 let ind = s:StatementIndent( ind - &sw, lnum ) | |
242 elseif line =~ ';\s*$' | |
36 | 243 " Statement end (but not 'end' ) - try to find current statement-start indent |
7 | 244 let ind = s:StatementIndent( ind, lnum ) |
245 endif | |
246 | |
247 " Check for potential argument list on next line | |
248 let continuation = (line =~ '[A-Za-z0-9_]\s*$') | |
249 | |
250 | |
251 " Check current line; search for simplistic matching start-of-block | |
252 let line = getline(v:lnum) | |
253 if line =~ '^\s*#' | |
254 " Start of line for ada-pp | |
255 let ind = 0 | |
256 elseif continuation && line =~ '^\s*(' | |
36 | 257 " Don't do this if we've already indented due to the previous line |
258 if ind == initind | |
856 | 259 let ind = ind + &sw |
36 | 260 endif |
7 | 261 elseif line =~ '^\s*\(begin\|is\)\>' |
262 let ind = s:MainBlockIndent( ind, lnum, '\(procedure\|function\|declare\|package\|task\)\>', 'begin\>' ) | |
263 elseif line =~ '^\s*record\>' | |
36 | 264 let ind = s:MainBlockIndent( ind, lnum, 'type\>\|for\>.*\<use\>', '' ) + &sw |
7 | 265 elseif line =~ '^\s*\(else\|elsif\)\>' |
266 let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' ) | |
267 elseif line =~ '^\s*when\>' | |
268 " Align 'when' one /in/ from matching block start | |
269 let ind = s:MainBlockIndent( ind, lnum, '\(case\|exception\)\>', '' ) + &sw | |
270 elseif line =~ '^\s*end\>\s*\<if\>' | |
271 " End of if statements | |
272 let ind = s:EndBlockIndent( ind, lnum, 'if\>', 'end\>\s*\<if\>' ) | |
273 elseif line =~ '^\s*end\>\s*\<loop\>' | |
274 " End of loops | |
275 let ind = s:EndBlockIndent( ind, lnum, '\(\(while\|for\)\>.*\)\?\<loop\>', 'end\>\s*\<loop\>' ) | |
276 elseif line =~ '^\s*end\>\s*\<record\>' | |
277 " End of records | |
278 let ind = s:EndBlockIndent( ind, lnum, '\(type\>.*\)\=\<record\>', 'end\>\s*\<record\>' ) | |
279 elseif line =~ '^\s*end\>\s*\<procedure\>' | |
280 " End of procedures | |
281 let ind = s:EndBlockIndent( ind, lnum, 'procedure\>.*\<is\>', 'end\>\s*\<procedure\>' ) | |
282 elseif line =~ '^\s*end\>\s*\<case\>' | |
283 " End of case statement | |
284 let ind = s:EndBlockIndent( ind, lnum, 'case\>.*\<is\>', 'end\>\s*\<case\>' ) | |
285 elseif line =~ '^\s*end\>' | |
286 " General case for end | |
36 | 287 let ind = s:MainBlockIndent( ind, lnum, '\(if\|while\|for\|loop\|accept\|begin\|record\|case\|exception\|package\)\>', '' ) |
7 | 288 elseif line =~ '^\s*exception\>' |
289 let ind = s:MainBlockIndent( ind, lnum, 'begin\>', '' ) | |
290 elseif line =~ '^\s*then\>' | |
291 let ind = s:MainBlockIndent( ind, lnum, 'if\>', '' ) | |
292 endif | |
293 | |
294 return ind | |
1121 | 295 endfunction GetAdaIndent |
296 | |
3496
d1e4abe8342c
Fixed compatible mode in most runtime files.
Bram Moolenaar <bram@vim.org>
parents:
2034
diff
changeset
|
297 let &cpo = s:keepcpo |
d1e4abe8342c
Fixed compatible mode in most runtime files.
Bram Moolenaar <bram@vim.org>
parents:
2034
diff
changeset
|
298 unlet s:keepcpo |
d1e4abe8342c
Fixed compatible mode in most runtime files.
Bram Moolenaar <bram@vim.org>
parents:
2034
diff
changeset
|
299 |
1121 | 300 finish " 1}}} |
7 | 301 |
1121 | 302 "------------------------------------------------------------------------------ |
303 " Copyright (C) 2006 Martin Krischik | |
304 " | |
305 " Vim is Charityware - see ":help license" or uganda.txt for licence details. | |
306 "------------------------------------------------------------------------------ | |
307 " vim: textwidth=78 wrap tabstop=8 shiftwidth=3 softtabstop=3 noexpandtab | |
308 " vim: foldmethod=marker |