blob: c7955d669b372cad830dfab0738054d0c5fd62b6 [file] [log] [blame]
Bram Moolenaar53180ce2005-07-05 21:48:14 +00001" Vim indent file
2" Language: Pascal
3" Maintainer: Neil Carter <n.carter@swansea.ac.uk>
4" Created: 2004 Jul 13
Bram Moolenaar3ec574f2017-06-13 18:12:01 +02005" Last Change: 2017 Jun 13
Bram Moolenaaradc21822011-04-01 18:03:16 +02006"
7" This is version 2.0, a complete rewrite.
8"
9" For further documentation, see http://psy.swansea.ac.uk/staff/carter/vim/
Bram Moolenaar53180ce2005-07-05 21:48:14 +000010
11
12if exists("b:did_indent")
13 finish
14endif
15let b:did_indent = 1
16
17setlocal indentexpr=GetPascalIndent(v:lnum)
18setlocal indentkeys&
19setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for
20setlocal indentkeys+==program,==function,==procedure,==object,==private
21setlocal indentkeys+==record,==if,==else,==case
22
23if exists("*GetPascalIndent")
24 finish
25endif
26
27
28function! s:GetPrevNonCommentLineNum( line_num )
29
30 " Skip lines starting with a comment
31 let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)'
32
33 let nline = a:line_num
34 while nline > 0
35 let nline = prevnonblank(nline-1)
36 if getline(nline) !~? SKIP_LINES
37 break
38 endif
39 endwhile
40
41 return nline
42endfunction
43
44
Bram Moolenaaradc21822011-04-01 18:03:16 +020045function! s:PurifyCode( line_num )
46 " Strip any trailing comments and whitespace
47 let pureline = 'TODO'
48 return pureline
49endfunction
50
51
Bram Moolenaar53180ce2005-07-05 21:48:14 +000052function! GetPascalIndent( line_num )
Bram Moolenaaradc21822011-04-01 18:03:16 +020053
Bram Moolenaar53180ce2005-07-05 21:48:14 +000054 " Line 0 always goes at column 0
55 if a:line_num == 0
56 return 0
57 endif
58
59 let this_codeline = getline( a:line_num )
60
Bram Moolenaaradc21822011-04-01 18:03:16 +020061
62 " SAME INDENT
63
64 " Middle of a three-part comment
Bram Moolenaar53180ce2005-07-05 21:48:14 +000065 if this_codeline =~ '^\s*\*'
Bram Moolenaaradc21822011-04-01 18:03:16 +020066 return indent( a:line_num - 1)
Bram Moolenaar53180ce2005-07-05 21:48:14 +000067 endif
68
Bram Moolenaaradc21822011-04-01 18:03:16 +020069
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...
95
Bram Moolenaar53180ce2005-07-05 21:48:14 +000096 let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num )
97 let prev_codeline = getline( prev_codeline_num )
98 let indnt = indent( prev_codeline_num )
99
Bram Moolenaaradc21822011-04-01 18:03:16 +0200100
101 " INCREASE INDENT
102
103 " If the PREVIOUS LINE ended in these items, always indent
104 if prev_codeline =~ '\<\(type\|const\|var\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200105 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000106 endif
107
Bram Moolenaaradc21822011-04-01 18:03:16 +0200108 if prev_codeline =~ '\<repeat$'
109 if this_codeline !~ '^\s*until\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200110 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200111 else
112 return indnt
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000113 endif
114 endif
115
Bram Moolenaaradc21822011-04-01 18:03:16 +0200116 if prev_codeline =~ '\<\(begin\|record\)$'
117 if this_codeline !~ '^\s*end\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200118 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200119 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\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200128 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200129 else
130 " If it does start with "begin" then keep the same indent
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200131 "return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200132 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 =~ '([^)]\+$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200140 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000141 endif
142
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000143
Bram Moolenaaradc21822011-04-01 18:03:16 +0200144 " DECREASE INDENT
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000145
Bram Moolenaaradc21822011-04-01 18:03:16 +0200146 " Lines starting with "else", but not following line ending with
147 " "end".
148 if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200149 return indnt - shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000150 endif
151
Bram Moolenaaradc21822011-04-01 18:03:16 +0200152 " 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.
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200163 return indnt - 2 * shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200164 endif
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200165 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200166 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\)\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200172 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200173 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\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200204 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000205 endif
206
Bram Moolenaaradc21822011-04-01 18:03:16 +0200207 " ???? Indent "procedure" and "functions" if they appear within an
208 " class/object definition. But that means overriding standard-pascal
209 " rule where these words always go in column 1.
210
211
212 " UNINDENT ONCE
213
214 if this_codeline =~ '^\s*\(except\|finally\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200215 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200216 endif
217
218 if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200219 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200220 endif
221
222
223" ____________________________________________________________________
224
225 " If nothing changed, return same indent.
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000226 return indnt
227endfunction
228