xref: /vim-8.2.3635/runtime/indent/pascal.vim (revision cb03397a)
1" Vim indent file
2" Language:    Pascal
3" Maintainer:  Neil Carter <[email protected]>
4" Created:     2004 Jul 13
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/
10
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
45function! s:PurifyCode( line_num )
46	" Strip any trailing comments and whitespace
47	let pureline = 'TODO'
48	return pureline
49endfunction
50
51
52function! GetPascalIndent( line_num )
53
54	" 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
61
62	" SAME INDENT
63
64	" Middle of a three-part comment
65	if this_codeline =~ '^\s*\*'
66		return indent( a:line_num - 1)
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...
95
96	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
100
101	" INCREASE INDENT
102
103	" If the PREVIOUS LINE ended in these items, always indent
104	if prev_codeline =~ '\<\(type\|const\|var\)$'
105		return indnt + &shiftwidth
106	endif
107
108	if prev_codeline =~ '\<repeat$'
109		if this_codeline !~ '^\s*until\>'
110			return indnt + &shiftwidth
111		else
112			return indnt
113		endif
114	endif
115
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 =~ '([^)]\+$'
140		return indnt + &shiftwidth
141	endif
142
143
144	" DECREASE INDENT
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\)$'
204		return indnt + &shiftwidth
205	endif
206
207	" ???? 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\)$'
215		return indnt - &shiftwidth
216	endif
217
218	if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$'
219		return indnt - &shiftwidth
220	endif
221
222
223" ____________________________________________________________________
224
225	" If nothing changed, return same indent.
226	return indnt
227endfunction
228
229