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