blob: b21b7256b241ebdc2e813f2280818fddd1126a26 [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 Moolenaar6e649222021-10-04 21:32:54 +01005" Last Change: 2021 Sep 22
Bram Moolenaaradc21822011-04-01 18:03:16 +02006"
Bram Moolenaar6e649222021-10-04 21:32:54 +01007" For further documentation, see https://psy.swansea.ac.uk/staff/carter/vim/
Bram Moolenaar53180ce2005-07-05 21:48:14 +00008
9
10if exists("b:did_indent")
11 finish
12endif
13let b:did_indent = 1
14
15setlocal indentexpr=GetPascalIndent(v:lnum)
16setlocal indentkeys&
17setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for
18setlocal indentkeys+==program,==function,==procedure,==object,==private
19setlocal indentkeys+==record,==if,==else,==case
20
Bram Moolenaar6e649222021-10-04 21:32:54 +010021let b:undo_indent = 'setlocal indentexpr< indentkeys<'
Bram Moolenaar90df4b92021-07-07 20:26:08 +020022
Bram Moolenaar53180ce2005-07-05 21:48:14 +000023if exists("*GetPascalIndent")
24 finish
25endif
26
27
Bram Moolenaar6e649222021-10-04 21:32:54 +010028" ________________________________________________________________
Bram Moolenaar53180ce2005-07-05 21:48:14 +000029function! s:GetPrevNonCommentLineNum( line_num )
30
31 " Skip lines starting with a comment
32 let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)'
33
34 let nline = a:line_num
35 while nline > 0
36 let nline = prevnonblank(nline-1)
37 if getline(nline) !~? SKIP_LINES
38 break
39 endif
40 endwhile
41
42 return nline
43endfunction
44
45
Bram Moolenaar6e649222021-10-04 21:32:54 +010046" ________________________________________________________________
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 Moolenaar6e649222021-10-04 21:32:54 +010054" ________________________________________________________________
Bram Moolenaar53180ce2005-07-05 21:48:14 +000055function! GetPascalIndent( line_num )
Bram Moolenaaradc21822011-04-01 18:03:16 +020056
Bram Moolenaar53180ce2005-07-05 21:48:14 +000057 " Line 0 always goes at column 0
58 if a:line_num == 0
59 return 0
60 endif
61
62 let this_codeline = getline( a:line_num )
63
Bram Moolenaaradc21822011-04-01 18:03:16 +020064
65 " SAME INDENT
66
67 " Middle of a three-part comment
Bram Moolenaar53180ce2005-07-05 21:48:14 +000068 if this_codeline =~ '^\s*\*'
Bram Moolenaaradc21822011-04-01 18:03:16 +020069 return indent( a:line_num - 1)
Bram Moolenaar53180ce2005-07-05 21:48:14 +000070 endif
71
Bram Moolenaaradc21822011-04-01 18:03:16 +020072
73 " COLUMN 1 ALWAYS
74
75 " Last line of the program
76 if this_codeline =~ '^\s*end\.'
77 return 0
78 endif
79
80 " Compiler directives, allowing "(*" and "{"
81 "if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)'
82 if this_codeline =~ '^\s*\({\|(\*\)\$'
83 return 0
84 endif
85
86 " section headers
87 if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>'
88 return 0
89 endif
90
91 " Subroutine separators, lines ending with "const" or "var"
92 if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$'
93 return 0
94 endif
95
96
97 " OTHERWISE, WE NEED TO LOOK FURTHER BACK...
98
Bram Moolenaar53180ce2005-07-05 21:48:14 +000099 let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num )
100 let prev_codeline = getline( prev_codeline_num )
101 let indnt = indent( prev_codeline_num )
102
Bram Moolenaaradc21822011-04-01 18:03:16 +0200103
104 " INCREASE INDENT
105
106 " If the PREVIOUS LINE ended in these items, always indent
107 if prev_codeline =~ '\<\(type\|const\|var\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200108 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000109 endif
110
Bram Moolenaaradc21822011-04-01 18:03:16 +0200111 if prev_codeline =~ '\<repeat$'
112 if this_codeline !~ '^\s*until\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200113 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200114 else
115 return indnt
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000116 endif
117 endif
118
Bram Moolenaaradc21822011-04-01 18:03:16 +0200119 if prev_codeline =~ '\<\(begin\|record\)$'
120 if this_codeline !~ '^\s*end\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200121 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200122 else
123 return indnt
124 endif
125 endif
126
127 " If the PREVIOUS LINE ended with these items, indent if not
128 " followed by "begin"
129 if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$'
130 if this_codeline !~ '^\s*begin\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200131 return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200132 else
133 " If it does start with "begin" then keep the same indent
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200134 "return indnt + shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200135 return indnt
136 endif
137 endif
138
139 " Inside a parameter list (i.e. a "(" without a ")"). ???? Considers
140 " only the line before the current one. TODO: Get it working for
141 " parameter lists longer than two lines.
142 if prev_codeline =~ '([^)]\+$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200143 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000144 endif
145
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000146
Bram Moolenaaradc21822011-04-01 18:03:16 +0200147 " DECREASE INDENT
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000148
Bram Moolenaaradc21822011-04-01 18:03:16 +0200149 " Lines starting with "else", but not following line ending with
150 " "end".
151 if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200152 return indnt - shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000153 endif
154
Bram Moolenaaradc21822011-04-01 18:03:16 +0200155 " Lines after a single-statement branch/loop.
156 " Two lines before ended in "then", "else", or "do"
157 " Previous line didn't end in "begin"
158 let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num )
159 let prev2_codeline = getline( prev2_codeline_num )
160 if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$'
161 " If the next code line after a single statement branch/loop
162 " starts with "end", "except" or "finally", we need an
163 " additional unindentation.
164 if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$'
165 " Note that we don't return from here.
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200166 return indnt - 2 * shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200167 endif
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200168 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200169 endif
170
171 " Lines starting with "until" or "end". This rule must be overridden
172 " by the one for "end" after a single-statement branch/loop. In
173 " other words that rule should come before this one.
174 if this_codeline =~ '^\s*\(end\|until\)\>'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200175 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200176 endif
177
178
179 " MISCELLANEOUS THINGS TO CATCH
180
181 " Most "begin"s will have been handled by now. Any remaining
182 " "begin"s on their own line should go in column 1.
183 if this_codeline =~ '^\s*begin$'
184 return 0
185 endif
186
187
Bram Moolenaar6e649222021-10-04 21:32:54 +0100188" ________________________________________________________________
Bram Moolenaaradc21822011-04-01 18:03:16 +0200189" Object/Borland Pascal/Delphi Extensions
190"
191" Note that extended-pascal is handled here, unless it is simpler to
192" handle them in the standard-pascal section above.
193
194
195 " COLUMN 1 ALWAYS
196
197 " section headers at start of line.
198 if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>'
199 return 0
200 endif
201
202
203 " INDENT ONCE
204
205 " If the PREVIOUS LINE ended in these items, always indent.
206 if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200207 return indnt + shiftwidth()
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000208 endif
209
Bram Moolenaaradc21822011-04-01 18:03:16 +0200210 " ???? Indent "procedure" and "functions" if they appear within an
211 " class/object definition. But that means overriding standard-pascal
212 " rule where these words always go in column 1.
213
214
215 " UNINDENT ONCE
216
217 if this_codeline =~ '^\s*\(except\|finally\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200218 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200219 endif
220
221 if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$'
Bram Moolenaar3ec574f2017-06-13 18:12:01 +0200222 return indnt - shiftwidth()
Bram Moolenaaradc21822011-04-01 18:03:16 +0200223 endif
224
225
Bram Moolenaaradc21822011-04-01 18:03:16 +0200226 " If nothing changed, return same indent.
Bram Moolenaar53180ce2005-07-05 21:48:14 +0000227 return indnt
228endfunction
229