blob: 1f39fd1cad100d35175ef02e4aa3509e7aedef14 [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 Moolenaar90df4b92021-07-07 20:26:08 +02005" Last Change: 2021 Jul 01
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
Bram Moolenaar90df4b92021-07-07 20:26:08 +020023let b:undo_indent = "setl indentkeys< indentexpr<"
24
Bram Moolenaar53180ce2005-07-05 21:48:14 +000025if exists("*GetPascalIndent")
26 finish
27endif
28
29
30function! s:GetPrevNonCommentLineNum( line_num )
31
32 " Skip lines starting with a comment
33 let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)'
34
35 let nline = a:line_num
36 while nline > 0
37 let nline = prevnonblank(nline-1)
38 if getline(nline) !~? SKIP_LINES
39 break
40 endif
41 endwhile
42
43 return nline
44endfunction
45
46
Bram Moolenaaradc21822011-04-01 18:03:16 +020047function! s:PurifyCode( line_num )
48 " Strip any trailing comments and whitespace
49 let pureline = 'TODO'
50 return pureline
51endfunction
52
53
Bram Moolenaar53180ce2005-07-05 21:48:14 +000054function! GetPascalIndent( line_num )
Bram Moolenaaradc21822011-04-01 18:03:16 +020055
Bram Moolenaar53180ce2005-07-05 21:48:14 +000056 " Line 0 always goes at column 0
57 if a:line_num == 0
58 return 0
59 endif
60
61 let this_codeline = getline( a:line_num )
62
Bram Moolenaaradc21822011-04-01 18:03:16 +020063
64 " SAME INDENT
65
66 " Middle of a three-part comment
Bram Moolenaar53180ce2005-07-05 21:48:14 +000067 if this_codeline =~ '^\s*\*'
Bram Moolenaaradc21822011-04-01 18:03:16 +020068 return indent( a:line_num - 1)
Bram Moolenaar53180ce2005-07-05 21:48:14 +000069 endif
70
Bram Moolenaaradc21822011-04-01 18:03:16 +020071
72 " COLUMN 1 ALWAYS
73
74 " Last line of the program
75 if this_codeline =~ '^\s*end\.'
76 return 0
77 endif
78
79 " Compiler directives, allowing "(*" and "{"
80 "if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)'
81 if this_codeline =~ '^\s*\({\|(\*\)\$'
82 return 0
83 endif
84
85 " section headers
86 if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>'
87 return 0
88 endif
89
90 " Subroutine separators, lines ending with "const" or "var"
91 if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$'
92 return 0
93 endif
94
95
96 " OTHERWISE, WE NEED TO LOOK FURTHER BACK...
97
Bram Moolenaar53180ce2005-07-05 21:48:14 +000098 let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num )
99 let prev_codeline = getline( prev_codeline_num )
100 let indnt = indent( prev_codeline_num )
101
Bram Moolenaaradc21822011-04-01 18:03:16 +0200102
103 " INCREASE INDENT
104
105 " If the PREVIOUS LINE ended in these items, always indent
106 if prev_codeline =~ '\<\(type\|const\|var\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200107 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000108 endif
109
Bram Moolenaaradc21822011-04-01 18:03:16 +0200110 if prev_codeline =~ '\<repeat$'
111 if this_codeline !~ '^\s*until\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200112 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200113 else
114 return indnt
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000115 endif
116 endif
117
Bram Moolenaaradc21822011-04-01 18:03:16 +0200118 if prev_codeline =~ '\<\(begin\|record\)$'
119 if this_codeline !~ '^\s*end\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200120 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200121 else
122 return indnt
123 endif
124 endif
125
126 " If the PREVIOUS LINE ended with these items, indent if not
127 " followed by "begin"
128 if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$'
129 if this_codeline !~ '^\s*begin\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200130 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200131 else
132 " If it does start with "begin" then keep the same indent
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200133 "return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200134 return indnt
135 endif
136 endif
137
138 " Inside a parameter list (i.e. a "(" without a ")"). ???? Considers
139 " only the line before the current one. TODO: Get it working for
140 " parameter lists longer than two lines.
141 if prev_codeline =~ '([^)]\+$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200142 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000143 endif
144
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000145
Bram Moolenaaradc21822011-04-01 18:03:16 +0200146 " DECREASE INDENT
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000147
Bram Moolenaaradc21822011-04-01 18:03:16 +0200148 " Lines starting with "else", but not following line ending with
149 " "end".
150 if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200151 return indnt - shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000152 endif
153
Bram Moolenaaradc21822011-04-01 18:03:16 +0200154 " Lines after a single-statement branch/loop.
155 " Two lines before ended in "then", "else", or "do"
156 " Previous line didn't end in "begin"
157 let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num )
158 let prev2_codeline = getline( prev2_codeline_num )
159 if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$'
160 " If the next code line after a single statement branch/loop
161 " starts with "end", "except" or "finally", we need an
162 " additional unindentation.
163 if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$'
164 " Note that we don't return from here.
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200165 return indnt - 2 * shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200166 endif
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200167 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200168 endif
169
170 " Lines starting with "until" or "end". This rule must be overridden
171 " by the one for "end" after a single-statement branch/loop. In
172 " other words that rule should come before this one.
173 if this_codeline =~ '^\s*\(end\|until\)\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200174 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200175 endif
176
177
178 " MISCELLANEOUS THINGS TO CATCH
179
180 " Most "begin"s will have been handled by now. Any remaining
181 " "begin"s on their own line should go in column 1.
182 if this_codeline =~ '^\s*begin$'
183 return 0
184 endif
185
186
187" ____________________________________________________________________
188" Object/Borland Pascal/Delphi Extensions
189"
190" Note that extended-pascal is handled here, unless it is simpler to
191" handle them in the standard-pascal section above.
192
193
194 " COLUMN 1 ALWAYS
195
196 " section headers at start of line.
197 if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>'
198 return 0
199 endif
200
201
202 " INDENT ONCE
203
204 " If the PREVIOUS LINE ended in these items, always indent.
205 if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200206 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000207 endif
208
Bram Moolenaaradc21822011-04-01 18:03:16 +0200209 " ???? Indent "procedure" and "functions" if they appear within an
210 " class/object definition. But that means overriding standard-pascal
211 " rule where these words always go in column 1.
212
213
214 " UNINDENT ONCE
215
216 if this_codeline =~ '^\s*\(except\|finally\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200217 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200218 endif
219
220 if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200221 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200222 endif
223
224
225" ____________________________________________________________________
226
227 " If nothing changed, return same indent.
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000228 return indnt
229endfunction
230