| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | " Vim indent file | 
					
						
							|  |  |  | " Language:    Pascal | 
					
						
							|  |  |  | " Maintainer:  Neil Carter <n.carter@swansea.ac.uk> | 
					
						
							|  |  |  | " Created:     2004 Jul 13 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | " Last Change: 2011 Apr 01 | 
					
						
							|  |  |  | " | 
					
						
							|  |  |  | " This is version 2.0, a complete rewrite. | 
					
						
							|  |  |  | " | 
					
						
							|  |  |  | " For further documentation, see http://psy.swansea.ac.uk/staff/carter/vim/ | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if exists("b:did_indent") | 
					
						
							|  |  |  | 	finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | let b:did_indent = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | setlocal indentexpr=GetPascalIndent(v:lnum) | 
					
						
							|  |  |  | setlocal indentkeys& | 
					
						
							|  |  |  | setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for | 
					
						
							|  |  |  | setlocal indentkeys+==program,==function,==procedure,==object,==private | 
					
						
							|  |  |  | setlocal indentkeys+==record,==if,==else,==case | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if exists("*GetPascalIndent") | 
					
						
							|  |  |  | 	finish | 
					
						
							|  |  |  | endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function! s:GetPrevNonCommentLineNum( line_num ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" Skip lines starting with a comment | 
					
						
							|  |  |  | 	let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	let nline = a:line_num | 
					
						
							|  |  |  | 	while nline > 0 | 
					
						
							|  |  |  | 		let nline = prevnonblank(nline-1) | 
					
						
							|  |  |  | 		if getline(nline) !~? SKIP_LINES | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		endif | 
					
						
							|  |  |  | 	endwhile | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nline | 
					
						
							|  |  |  | endfunction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | function! s:PurifyCode( line_num ) | 
					
						
							|  |  |  | 	" Strip any trailing comments and whitespace | 
					
						
							|  |  |  | 	let pureline = 'TODO' | 
					
						
							|  |  |  | 	return pureline | 
					
						
							|  |  |  | endfunction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | function! GetPascalIndent( line_num ) | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 	" Line 0 always goes at column 0 | 
					
						
							|  |  |  | 	if a:line_num == 0 | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	let this_codeline = getline( a:line_num ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	" SAME INDENT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" Middle of a three-part comment | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 	if this_codeline =~ '^\s*\*' | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 		return indent( a:line_num - 1) | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" COLUMN 1 ALWAYS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" Last line of the program | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*end\.' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		return 0 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" Compiler directives, allowing "(*" and "{" | 
					
						
							|  |  |  | 	"if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)' | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*\({\|(\*\)\$' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		return 0 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" section headers | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		return 0 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" Subroutine separators, lines ending with "const" or "var" | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		return 0 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" OTHERWISE, WE NEED TO LOOK FURTHER BACK... | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num ) | 
					
						
							|  |  |  | 	let prev_codeline = getline( prev_codeline_num ) | 
					
						
							|  |  |  | 	let indnt = indent( prev_codeline_num ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" INCREASE INDENT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" If the PREVIOUS LINE ended in these items, always indent | 
					
						
							|  |  |  | 	if prev_codeline =~ '\<\(type\|const\|var\)$' | 
					
						
							|  |  |  | 		return indnt + &shiftwidth | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	if prev_codeline =~ '\<repeat$' | 
					
						
							|  |  |  | 		if this_codeline !~ '^\s*until\>' | 
					
						
							|  |  |  | 			return indnt + &shiftwidth | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return indnt | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		endif | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	endif | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	if prev_codeline =~ '\<\(begin\|record\)$' | 
					
						
							|  |  |  | 		if this_codeline !~ '^\s*end\>' | 
					
						
							|  |  |  | 			return indnt + &shiftwidth | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			return indnt | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		endif | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" If the PREVIOUS LINE ended with these items, indent if not | 
					
						
							|  |  |  | 	" followed by "begin" | 
					
						
							|  |  |  | 	if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$' | 
					
						
							|  |  |  | 		if this_codeline !~ '^\s*begin\>' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 			return indnt + &shiftwidth | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 		else | 
					
						
							|  |  |  | 			" If it does start with "begin" then keep the same indent | 
					
						
							|  |  |  | 			"return indnt + &shiftwidth | 
					
						
							|  |  |  | 			return indnt | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		endif | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" Inside a parameter list (i.e. a "(" without a ")"). ???? Considers | 
					
						
							|  |  |  | 	" only the line before the current one. TODO: Get it working for | 
					
						
							|  |  |  | 	" parameter lists longer than two lines. | 
					
						
							|  |  |  | 	if prev_codeline =~ '([^)]\+$' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		return indnt + &shiftwidth | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	" DECREASE INDENT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" Lines starting with "else", but not following line ending with | 
					
						
							|  |  |  | 	" "end". | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$' | 
					
						
							|  |  |  | 		return indnt - &shiftwidth | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" Lines after a single-statement branch/loop. | 
					
						
							|  |  |  | 	" Two lines before ended in "then", "else", or "do" | 
					
						
							|  |  |  | 	" Previous line didn't end in "begin" | 
					
						
							|  |  |  | 	let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num ) | 
					
						
							|  |  |  | 	let prev2_codeline = getline( prev2_codeline_num ) | 
					
						
							|  |  |  | 	if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$' | 
					
						
							|  |  |  | 		" If the next code line after a single statement branch/loop | 
					
						
							|  |  |  | 		" starts with "end", "except" or "finally", we need an | 
					
						
							|  |  |  | 		" additional unindentation. | 
					
						
							|  |  |  | 		if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$' | 
					
						
							|  |  |  | 			" Note that we don't return from here. | 
					
						
							|  |  |  | 			return indnt - &shiftwidth - &shiftwidth | 
					
						
							|  |  |  | 		endif | 
					
						
							|  |  |  | 		return indnt - &shiftwidth | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" Lines starting with "until" or "end". This rule must be overridden | 
					
						
							|  |  |  | 	" by the one for "end" after a single-statement branch/loop. In | 
					
						
							|  |  |  | 	" other words that rule should come before this one. | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*\(end\|until\)\>' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		return indnt - &shiftwidth | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	" MISCELLANEOUS THINGS TO CATCH | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" Most "begin"s will have been handled by now. Any remaining | 
					
						
							|  |  |  | 	" "begin"s on their own line should go in column 1. | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*begin$' | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " ____________________________________________________________________ | 
					
						
							|  |  |  | " Object/Borland Pascal/Delphi Extensions | 
					
						
							|  |  |  | " | 
					
						
							|  |  |  | " Note that extended-pascal is handled here, unless it is simpler to | 
					
						
							|  |  |  | " handle them in the standard-pascal section above. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" COLUMN 1 ALWAYS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" section headers at start of line. | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>' | 
					
						
							|  |  |  | 		return 0 | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" INDENT ONCE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" If the PREVIOUS LINE ended in these items, always indent. | 
					
						
							|  |  |  | 	if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$' | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 		return indnt + &shiftwidth | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-04-01 18:03:16 +02:00
										 |  |  | 	" ???? Indent "procedure" and "functions" if they appear within an | 
					
						
							|  |  |  | 	" class/object definition. But that means overriding standard-pascal | 
					
						
							|  |  |  | 	" rule where these words always go in column 1. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" UNINDENT ONCE | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*\(except\|finally\)$' | 
					
						
							|  |  |  | 		return indnt - &shiftwidth | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$' | 
					
						
							|  |  |  | 		return indnt - &shiftwidth | 
					
						
							|  |  |  | 	endif | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | " ____________________________________________________________________ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	" If nothing changed, return same indent. | 
					
						
							| 
									
										
										
										
											2005-07-05 21:48:14 +00:00
										 |  |  | 	return indnt | 
					
						
							|  |  |  | endfunction | 
					
						
							|  |  |  | 
 |