Mercurial > hg > RemoteEditor > vim7
comparison runtime/indent/pascal.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 | 76efa0be13f1 |
children |
comparison
equal
deleted
inserted
replaced
47:6c0584ec21b1 | 48:67300faee616 |
---|---|
1 " Vim indent file | 1 " Vim indent file |
2 " Language: Pascal | 2 " Language: Pascal |
3 " Maintainer: Neil Carter <n.carter@swansea.ac.uk> | 3 " Maintainer: Neil Carter <n.carter@swansea.ac.uk> |
4 " Created: 2004 Jul 13 | 4 " Created: 2004 Jul 13 |
5 " Last Change: 2005 Jul 05 | 5 " Last Change: 2011 Apr 01 |
6 " | |
7 " This is version 2.0, a complete rewrite. | |
8 " | |
9 " For further documentation, see http://psy.swansea.ac.uk/staff/carter/vim/ | |
6 | 10 |
7 | 11 |
8 if exists("b:did_indent") | 12 if exists("b:did_indent") |
9 finish | 13 finish |
10 endif | 14 endif |
36 | 40 |
37 return nline | 41 return nline |
38 endfunction | 42 endfunction |
39 | 43 |
40 | 44 |
45 function! s:PurifyCode( line_num ) | |
46 " Strip any trailing comments and whitespace | |
47 let pureline = 'TODO' | |
48 return pureline | |
49 endfunction | |
50 | |
51 | |
41 function! GetPascalIndent( line_num ) | 52 function! GetPascalIndent( line_num ) |
53 | |
42 " Line 0 always goes at column 0 | 54 " Line 0 always goes at column 0 |
43 if a:line_num == 0 | 55 if a:line_num == 0 |
44 return 0 | 56 return 0 |
45 endif | 57 endif |
46 | 58 |
47 let this_codeline = getline( a:line_num ) | 59 let this_codeline = getline( a:line_num ) |
48 | 60 |
49 " If in the middle of a three-part comment | 61 |
62 " SAME INDENT | |
63 | |
64 " Middle of a three-part comment | |
50 if this_codeline =~ '^\s*\*' | 65 if this_codeline =~ '^\s*\*' |
51 return indent( a:line_num ) | 66 return indent( a:line_num - 1) |
52 endif | 67 endif |
68 | |
69 | |
70 " COLUMN 1 ALWAYS | |
71 | |
72 " Last line of the program | |
73 if this_codeline =~ '^\s*end\.' | |
74 return 0 | |
75 endif | |
76 | |
77 " Compiler directives, allowing "(*" and "{" | |
78 "if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)' | |
79 if this_codeline =~ '^\s*\({\|(\*\)\$' | |
80 return 0 | |
81 endif | |
82 | |
83 " section headers | |
84 if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>' | |
85 return 0 | |
86 endif | |
87 | |
88 " Subroutine separators, lines ending with "const" or "var" | |
89 if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$' | |
90 return 0 | |
91 endif | |
92 | |
93 | |
94 " OTHERWISE, WE NEED TO LOOK FURTHER BACK... | |
53 | 95 |
54 let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num ) | 96 let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num ) |
55 let prev_codeline = getline( prev_codeline_num ) | 97 let prev_codeline = getline( prev_codeline_num ) |
56 let indnt = indent( prev_codeline_num ) | 98 let indnt = indent( prev_codeline_num ) |
57 | 99 |
58 " Compiler directives should always go in column zero. | 100 |
59 if this_codeline =~ '^\s*{\(\$IFDEF\|\$ELSE\|\$ENDIF\)' | 101 " INCREASE INDENT |
60 return 0 | 102 |
61 endif | 103 " If the PREVIOUS LINE ended in these items, always indent |
62 | 104 if prev_codeline =~ '\<\(type\|const\|var\)$' |
63 " These items have nothing before or after (not even a comment), and | 105 return indnt + &shiftwidth |
64 " go on column 0. Make sure that the ^\s* is followed by \( to make | 106 endif |
65 " ORs work properly, and not include the start of line (this must | 107 |
66 " always appear). | 108 if prev_codeline =~ '\<repeat$' |
67 " The bracketed expression with the underline is a routine | 109 if this_codeline !~ '^\s*until\>' |
68 " separator. This is one case where we do indent comment lines. | |
69 if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\<\(const\|var\)\>\)$' | |
70 return 0 | |
71 endif | |
72 | |
73 " These items may have text after them, and go on column 0 (in most | |
74 " cases). The problem is that "function" and "procedure" keywords | |
75 " should be indented if within a class declaration. | |
76 if this_codeline =~ '^\s*\<\(program\|type\|uses\|procedure\|function\)\>' | |
77 return 0 | |
78 endif | |
79 | |
80 " BEGIN | |
81 " If the begin does not come after "if", "for", or "else", then it | |
82 " goes in column 0 | |
83 if this_codeline =~ '^\s*begin\>' && prev_codeline !~ '^\s*\<\(if\|for\|else\)\>' | |
84 return 0 | |
85 endif | |
86 | |
87 " These keywords are indented once only. | |
88 if this_codeline =~ '^\s*\<\(private\)\>' | |
89 return &shiftwidth | |
90 endif | |
91 | |
92 " If the PREVIOUS LINE contained these items, the current line is | |
93 " always indented once. | |
94 if prev_codeline =~ '^\s*\<\(type\|uses\)\>' | |
95 return &shiftwidth | |
96 endif | |
97 | |
98 " These keywords are indented once only. Possibly surrounded by | |
99 " other chars. | |
100 if this_codeline =~ '^.\+\<\(object\|record\)\>' | |
101 return &shiftwidth | |
102 endif | |
103 | |
104 " If the previous line was indenting... | |
105 if prev_codeline =~ '^\s*\<\(for\|if\|case\|else\|end\ else\)\>' | |
106 " then indent. | |
107 let indnt = indnt + &shiftwidth | |
108 " BUT... if this is the start of a multistatement block then we | |
109 " need to align the begin with the previous line. | |
110 if this_codeline =~ '^\s*begin\>' | |
111 return indnt - &shiftwidth | |
112 endif | |
113 | |
114 " We also need to keep the indentation level constant if the | |
115 " whole if-then statement was on one line. | |
116 if prev_codeline =~ '\<then\>.\+' | |
117 let indnt = indnt - &shiftwidth | |
118 endif | |
119 endif | |
120 | |
121 " PREVIOUS-LINE BEGIN | |
122 " If the previous line was an indenting keyword then indent once... | |
123 if prev_codeline =~ '^\s*\<\(const\|var\|begin\|repeat\|private\)\>' | |
124 " But only if this is another var in a list. | |
125 if this_codeline !~ '^\s*var\>' | |
126 return indnt + &shiftwidth | 110 return indnt + &shiftwidth |
127 endif | 111 else |
128 endif | 112 return indnt |
129 | 113 endif |
130 " PREVIOUS-LINE BEGIN | 114 endif |
131 " Indent code after a case statement begin | 115 |
132 if prev_codeline =~ '\:\ begin\>' | 116 if prev_codeline =~ '\<\(begin\|record\)$' |
117 if this_codeline !~ '^\s*end\>' | |
118 return indnt + &shiftwidth | |
119 else | |
120 return indnt | |
121 endif | |
122 endif | |
123 | |
124 " If the PREVIOUS LINE ended with these items, indent if not | |
125 " followed by "begin" | |
126 if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$' | |
127 if this_codeline !~ '^\s*begin\>' | |
128 return indnt + &shiftwidth | |
129 else | |
130 " If it does start with "begin" then keep the same indent | |
131 "return indnt + &shiftwidth | |
132 return indnt | |
133 endif | |
134 endif | |
135 | |
136 " Inside a parameter list (i.e. a "(" without a ")"). ???? Considers | |
137 " only the line before the current one. TODO: Get it working for | |
138 " parameter lists longer than two lines. | |
139 if prev_codeline =~ '([^)]\+$' | |
133 return indnt + &shiftwidth | 140 return indnt + &shiftwidth |
134 endif | 141 endif |
135 | 142 |
136 " These words may have text before them on the line (hence the .*) | 143 |
137 " but are followed by nothing. Always indent once only. | 144 " DECREASE INDENT |
138 if prev_codeline =~ '^\(.*\|\s*\)\<\(object\|record\)\>$' | 145 |
146 " Lines starting with "else", but not following line ending with | |
147 " "end". | |
148 if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$' | |
149 return indnt - &shiftwidth | |
150 endif | |
151 | |
152 " Lines after a single-statement branch/loop. | |
153 " Two lines before ended in "then", "else", or "do" | |
154 " Previous line didn't end in "begin" | |
155 let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num ) | |
156 let prev2_codeline = getline( prev2_codeline_num ) | |
157 if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$' | |
158 " If the next code line after a single statement branch/loop | |
159 " starts with "end", "except" or "finally", we need an | |
160 " additional unindentation. | |
161 if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$' | |
162 " Note that we don't return from here. | |
163 return indnt - &shiftwidth - &shiftwidth | |
164 endif | |
165 return indnt - &shiftwidth | |
166 endif | |
167 | |
168 " Lines starting with "until" or "end". This rule must be overridden | |
169 " by the one for "end" after a single-statement branch/loop. In | |
170 " other words that rule should come before this one. | |
171 if this_codeline =~ '^\s*\(end\|until\)\>' | |
172 return indnt - &shiftwidth | |
173 endif | |
174 | |
175 | |
176 " MISCELLANEOUS THINGS TO CATCH | |
177 | |
178 " Most "begin"s will have been handled by now. Any remaining | |
179 " "begin"s on their own line should go in column 1. | |
180 if this_codeline =~ '^\s*begin$' | |
181 return 0 | |
182 endif | |
183 | |
184 | |
185 " ____________________________________________________________________ | |
186 " Object/Borland Pascal/Delphi Extensions | |
187 " | |
188 " Note that extended-pascal is handled here, unless it is simpler to | |
189 " handle them in the standard-pascal section above. | |
190 | |
191 | |
192 " COLUMN 1 ALWAYS | |
193 | |
194 " section headers at start of line. | |
195 if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>' | |
196 return 0 | |
197 endif | |
198 | |
199 | |
200 " INDENT ONCE | |
201 | |
202 " If the PREVIOUS LINE ended in these items, always indent. | |
203 if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$' | |
139 return indnt + &shiftwidth | 204 return indnt + &shiftwidth |
140 endif | 205 endif |
141 | 206 |
142 " If we just closed a bracket that started on a previous line, then | 207 " ???? Indent "procedure" and "functions" if they appear within an |
143 " unindent. But don't return yet -- we need to check for further | 208 " class/object definition. But that means overriding standard-pascal |
144 " unindentation (for end/until/else) | 209 " rule where these words always go in column 1. |
145 if prev_codeline =~ '^[^(]*[^*])' | 210 |
146 let indnt = indnt - &shiftwidth | 211 |
147 endif | 212 " UNINDENT ONCE |
148 | 213 |
149 " At the end of a block, we have to unindent both the current line | 214 if this_codeline =~ '^\s*\(except\|finally\)$' |
150 " (the "end" for instance) and the newly-created line. | 215 return indnt - &shiftwidth |
151 if this_codeline =~ '^\s*\<\(end\|until\|else\)\>' | 216 endif |
152 return indnt - &shiftwidth | 217 |
153 endif | 218 if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$' |
154 | 219 return indnt - &shiftwidth |
155 " If we have opened a bracket and it continues over one line, | 220 endif |
156 " then indent once. | 221 |
157 " | 222 |
158 " RE = an opening bracket followed by any amount of anything other | 223 " ____________________________________________________________________ |
159 " than a closing bracket and then the end-of-line. | 224 |
160 " | 225 " If nothing changed, return same indent. |
161 " If we didn't include the end of line, this RE would match even | |
162 " closed brackets, since it would match everything up to the closing | |
163 " bracket. | |
164 " | |
165 " This test isn't clever enough to handle brackets inside strings or | |
166 " comments. | |
167 if prev_codeline =~ '([^*]\=[^)]*$' | |
168 return indnt + &shiftwidth | |
169 endif | |
170 | |
171 return indnt | 226 return indnt |
172 endfunction | 227 endfunction |
173 | 228 |