xref: /vim-8.2.3635/runtime/indent/pascal.vim (revision 6e649224)
10e4d877eSBram Moolenaar" Vim indent file
20e4d877eSBram Moolenaar" Language:    Pascal
30e4d877eSBram Moolenaar" Maintainer:  Neil Carter <[email protected]>
40e4d877eSBram Moolenaar" Created:     2004 Jul 13
5*6e649224SBram Moolenaar" Last Change: 2021 Sep 22
6adc2182cSBram Moolenaar"
7*6e649224SBram Moolenaar" For further documentation, see https://psy.swansea.ac.uk/staff/carter/vim/
80e4d877eSBram Moolenaar
9520470a9SBram Moolenaar
100e4d877eSBram Moolenaarif exists("b:did_indent")
110e4d877eSBram Moolenaar	finish
120e4d877eSBram Moolenaarendif
130e4d877eSBram Moolenaarlet b:did_indent = 1
140e4d877eSBram Moolenaar
150e4d877eSBram Moolenaarsetlocal indentexpr=GetPascalIndent(v:lnum)
160e4d877eSBram Moolenaarsetlocal indentkeys&
17520470a9SBram Moolenaarsetlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for
18520470a9SBram Moolenaarsetlocal indentkeys+==program,==function,==procedure,==object,==private
19520470a9SBram Moolenaarsetlocal indentkeys+==record,==if,==else,==case
200e4d877eSBram Moolenaar
21*6e649224SBram Moolenaarlet b:undo_indent = 'setlocal indentexpr< indentkeys<'
2290df4b9dSBram Moolenaar
230e4d877eSBram Moolenaarif exists("*GetPascalIndent")
240e4d877eSBram Moolenaar	finish
250e4d877eSBram Moolenaarendif
260e4d877eSBram Moolenaar
270e4d877eSBram Moolenaar
28*6e649224SBram Moolenaar" ________________________________________________________________
29520470a9SBram Moolenaarfunction! s:GetPrevNonCommentLineNum( line_num )
300e4d877eSBram Moolenaar
31520470a9SBram Moolenaar	" Skip lines starting with a comment
32520470a9SBram Moolenaar	let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)'
330e4d877eSBram Moolenaar
340e4d877eSBram Moolenaar	let nline = a:line_num
350e4d877eSBram Moolenaar	while nline > 0
360e4d877eSBram Moolenaar		let nline = prevnonblank(nline-1)
370e4d877eSBram Moolenaar		if getline(nline) !~? SKIP_LINES
380e4d877eSBram Moolenaar			break
390e4d877eSBram Moolenaar		endif
400e4d877eSBram Moolenaar	endwhile
410e4d877eSBram Moolenaar
420e4d877eSBram Moolenaar	return nline
430e4d877eSBram Moolenaarendfunction
440e4d877eSBram Moolenaar
450e4d877eSBram Moolenaar
46*6e649224SBram Moolenaar" ________________________________________________________________
47adc2182cSBram Moolenaarfunction! s:PurifyCode( line_num )
48adc2182cSBram Moolenaar	" Strip any trailing comments and whitespace
49adc2182cSBram Moolenaar	let pureline = 'TODO'
50adc2182cSBram Moolenaar	return pureline
51adc2182cSBram Moolenaarendfunction
52adc2182cSBram Moolenaar
53adc2182cSBram Moolenaar
54*6e649224SBram Moolenaar" ________________________________________________________________
550e4d877eSBram Moolenaarfunction! GetPascalIndent( line_num )
56adc2182cSBram Moolenaar
57520470a9SBram Moolenaar	" Line 0 always goes at column 0
580e4d877eSBram Moolenaar	if a:line_num == 0
590e4d877eSBram Moolenaar		return 0
600e4d877eSBram Moolenaar	endif
610e4d877eSBram Moolenaar
62520470a9SBram Moolenaar	let this_codeline = getline( a:line_num )
63520470a9SBram Moolenaar
64adc2182cSBram Moolenaar
65adc2182cSBram Moolenaar	" SAME INDENT
66adc2182cSBram Moolenaar
67adc2182cSBram Moolenaar	" Middle of a three-part comment
68520470a9SBram Moolenaar	if this_codeline =~ '^\s*\*'
69adc2182cSBram Moolenaar		return indent( a:line_num - 1)
700e4d877eSBram Moolenaar	endif
710e4d877eSBram Moolenaar
72adc2182cSBram Moolenaar
73adc2182cSBram Moolenaar	" COLUMN 1 ALWAYS
74adc2182cSBram Moolenaar
75adc2182cSBram Moolenaar	" Last line of the program
76adc2182cSBram Moolenaar	if this_codeline =~ '^\s*end\.'
77adc2182cSBram Moolenaar		return 0
78adc2182cSBram Moolenaar	endif
79adc2182cSBram Moolenaar
80adc2182cSBram Moolenaar	" Compiler directives, allowing "(*" and "{"
81adc2182cSBram Moolenaar	"if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)'
82adc2182cSBram Moolenaar	if this_codeline =~ '^\s*\({\|(\*\)\$'
83adc2182cSBram Moolenaar		return 0
84adc2182cSBram Moolenaar	endif
85adc2182cSBram Moolenaar
86adc2182cSBram Moolenaar	" section headers
87adc2182cSBram Moolenaar	if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>'
88adc2182cSBram Moolenaar		return 0
89adc2182cSBram Moolenaar	endif
90adc2182cSBram Moolenaar
91adc2182cSBram Moolenaar	" Subroutine separators, lines ending with "const" or "var"
92adc2182cSBram Moolenaar	if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$'
93adc2182cSBram Moolenaar		return 0
94adc2182cSBram Moolenaar	endif
95adc2182cSBram Moolenaar
96adc2182cSBram Moolenaar
97adc2182cSBram Moolenaar	" OTHERWISE, WE NEED TO LOOK FURTHER BACK...
98adc2182cSBram Moolenaar
99520470a9SBram Moolenaar	let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num )
100520470a9SBram Moolenaar	let prev_codeline = getline( prev_codeline_num )
101520470a9SBram Moolenaar	let indnt = indent( prev_codeline_num )
1020e4d877eSBram Moolenaar
103adc2182cSBram Moolenaar
104adc2182cSBram Moolenaar	" INCREASE INDENT
105adc2182cSBram Moolenaar
106adc2182cSBram Moolenaar	" If the PREVIOUS LINE ended in these items, always indent
107adc2182cSBram Moolenaar	if prev_codeline =~ '\<\(type\|const\|var\)$'
1083ec574f2SBram Moolenaar		return indnt + shiftwidth()
1090e4d877eSBram Moolenaar	endif
1100e4d877eSBram Moolenaar
111adc2182cSBram Moolenaar	if prev_codeline =~ '\<repeat$'
112adc2182cSBram Moolenaar		if this_codeline !~ '^\s*until\>'
1133ec574f2SBram Moolenaar			return indnt + shiftwidth()
114adc2182cSBram Moolenaar		else
115adc2182cSBram Moolenaar			return indnt
116adc2182cSBram Moolenaar		endif
117520470a9SBram Moolenaar	endif
118520470a9SBram Moolenaar
119adc2182cSBram Moolenaar	if prev_codeline =~ '\<\(begin\|record\)$'
120adc2182cSBram Moolenaar		if this_codeline !~ '^\s*end\>'
1213ec574f2SBram Moolenaar			return indnt + shiftwidth()
122adc2182cSBram Moolenaar		else
123adc2182cSBram Moolenaar			return indnt
124adc2182cSBram Moolenaar		endif
125520470a9SBram Moolenaar	endif
126520470a9SBram Moolenaar
127adc2182cSBram Moolenaar	" If the PREVIOUS LINE ended with these items, indent if not
128adc2182cSBram Moolenaar	" followed by "begin"
129adc2182cSBram Moolenaar	if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$'
130adc2182cSBram Moolenaar		if this_codeline !~ '^\s*begin\>'
1313ec574f2SBram Moolenaar			return indnt + shiftwidth()
132adc2182cSBram Moolenaar		else
133adc2182cSBram Moolenaar			" If it does start with "begin" then keep the same indent
1343ec574f2SBram Moolenaar			"return indnt + shiftwidth()
135adc2182cSBram Moolenaar			return indnt
136adc2182cSBram Moolenaar		endif
137520470a9SBram Moolenaar	endif
138520470a9SBram Moolenaar
139adc2182cSBram Moolenaar	" Inside a parameter list (i.e. a "(" without a ")"). ???? Considers
140adc2182cSBram Moolenaar	" only the line before the current one. TODO: Get it working for
141adc2182cSBram Moolenaar	" parameter lists longer than two lines.
142adc2182cSBram Moolenaar	if prev_codeline =~ '([^)]\+$'
1433ec574f2SBram Moolenaar		return indnt + shiftwidth()
144520470a9SBram Moolenaar	endif
145520470a9SBram Moolenaar
146520470a9SBram Moolenaar
147adc2182cSBram Moolenaar	" DECREASE INDENT
148520470a9SBram Moolenaar
149adc2182cSBram Moolenaar	" Lines starting with "else", but not following line ending with
150adc2182cSBram Moolenaar	" "end".
151adc2182cSBram Moolenaar	if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$'
1523ec574f2SBram Moolenaar		return indnt - shiftwidth()
153520470a9SBram Moolenaar	endif
154520470a9SBram Moolenaar
155adc2182cSBram Moolenaar	" Lines after a single-statement branch/loop.
156adc2182cSBram Moolenaar	" Two lines before ended in "then", "else", or "do"
157adc2182cSBram Moolenaar	" Previous line didn't end in "begin"
158adc2182cSBram Moolenaar	let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num )
159adc2182cSBram Moolenaar	let prev2_codeline = getline( prev2_codeline_num )
160adc2182cSBram Moolenaar	if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$'
161adc2182cSBram Moolenaar		" If the next code line after a single statement branch/loop
162adc2182cSBram Moolenaar		" starts with "end", "except" or "finally", we need an
163adc2182cSBram Moolenaar		" additional unindentation.
164adc2182cSBram Moolenaar		if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$'
165adc2182cSBram Moolenaar			" Note that we don't return from here.
1663ec574f2SBram Moolenaar			return indnt - 2 * shiftwidth()
1670e4d877eSBram Moolenaar		endif
1683ec574f2SBram Moolenaar		return indnt - shiftwidth()
1690e4d877eSBram Moolenaar	endif
1700e4d877eSBram Moolenaar
171adc2182cSBram Moolenaar	" Lines starting with "until" or "end". This rule must be overridden
172adc2182cSBram Moolenaar	" by the one for "end" after a single-statement branch/loop. In
173adc2182cSBram Moolenaar	" other words that rule should come before this one.
174adc2182cSBram Moolenaar	if this_codeline =~ '^\s*\(end\|until\)\>'
1753ec574f2SBram Moolenaar		return indnt - shiftwidth()
176adc2182cSBram Moolenaar	endif
177adc2182cSBram Moolenaar
178adc2182cSBram Moolenaar
179adc2182cSBram Moolenaar	" MISCELLANEOUS THINGS TO CATCH
180adc2182cSBram Moolenaar
181adc2182cSBram Moolenaar	" Most "begin"s will have been handled by now. Any remaining
182adc2182cSBram Moolenaar	" "begin"s on their own line should go in column 1.
183adc2182cSBram Moolenaar	if this_codeline =~ '^\s*begin$'
184adc2182cSBram Moolenaar		return 0
185adc2182cSBram Moolenaar	endif
186adc2182cSBram Moolenaar
187adc2182cSBram Moolenaar
188*6e649224SBram Moolenaar" ________________________________________________________________
189adc2182cSBram Moolenaar" Object/Borland Pascal/Delphi Extensions
190520470a9SBram Moolenaar"
191adc2182cSBram Moolenaar" Note that extended-pascal is handled here, unless it is simpler to
192adc2182cSBram Moolenaar" handle them in the standard-pascal section above.
193adc2182cSBram Moolenaar
194adc2182cSBram Moolenaar
195adc2182cSBram Moolenaar	" COLUMN 1 ALWAYS
196adc2182cSBram Moolenaar
197adc2182cSBram Moolenaar	" section headers at start of line.
198adc2182cSBram Moolenaar	if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>'
199adc2182cSBram Moolenaar		return 0
200adc2182cSBram Moolenaar	endif
201adc2182cSBram Moolenaar
202adc2182cSBram Moolenaar
203adc2182cSBram Moolenaar	" INDENT ONCE
204adc2182cSBram Moolenaar
205adc2182cSBram Moolenaar	" If the PREVIOUS LINE ended in these items, always indent.
206adc2182cSBram Moolenaar	if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$'
2073ec574f2SBram Moolenaar		return indnt + shiftwidth()
2080e4d877eSBram Moolenaar	endif
2090e4d877eSBram Moolenaar
210adc2182cSBram Moolenaar	" ???? Indent "procedure" and "functions" if they appear within an
211adc2182cSBram Moolenaar	" class/object definition. But that means overriding standard-pascal
212adc2182cSBram Moolenaar	" rule where these words always go in column 1.
213adc2182cSBram Moolenaar
214adc2182cSBram Moolenaar
215adc2182cSBram Moolenaar	" UNINDENT ONCE
216adc2182cSBram Moolenaar
217adc2182cSBram Moolenaar	if this_codeline =~ '^\s*\(except\|finally\)$'
2183ec574f2SBram Moolenaar		return indnt - shiftwidth()
219adc2182cSBram Moolenaar	endif
220adc2182cSBram Moolenaar
221adc2182cSBram Moolenaar	if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$'
2223ec574f2SBram Moolenaar		return indnt - shiftwidth()
223adc2182cSBram Moolenaar	endif
224adc2182cSBram Moolenaar
225adc2182cSBram Moolenaar
226adc2182cSBram Moolenaar	" If nothing changed, return same indent.
2270e4d877eSBram Moolenaar	return indnt
2280e4d877eSBram Moolenaarendfunction
2290e4d877eSBram Moolenaar
230