1" Vim indent file 2" Language: Pascal 3" Maintainer: Neil Carter <[email protected]> 4" Created: 2004 Jul 13 5" Last Change: 2005 Jun 07 6" TODO: Reduce indentation on line after a statement that flowed across 7" two lines (e.g. parameter list closed on second line). Also, increase 8" indent of a becomes-statement that flows onto second line. 9 10" Only load this indent file when no other was loaded. 11if exists("b:did_indent") 12 finish 13endif 14let b:did_indent = 1 15 16setlocal indentexpr=GetPascalIndent(v:lnum) 17" Appending an & to an option sets it to its default value. 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:GetPrevLineNum( line_num ) 29 30 " Skip over comments and conditional directives 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" call input( "nline = ".nline ) 42 43 return nline 44 45endfunction 46 47 48function! GetPascalIndent( line_num ) 49 if a:line_num == 0 50 return 0 51 endif 52 53 " If in the middle of a three-part comment 54 if getline( a:line_num ) =~ '^\s*\*\ ' 55 return indent( a:line_num ) 56 endif 57 58 " We have to subtract one to start on the line before the current 59 " one. Otherwise, prevnonblank() returns the current line! 60 let prev_line_num = s:GetPrevLineNum( a:line_num ) 61 let prev_line = getline( prev_line_num ) 62 let indnt = indent( prev_line_num ) 63 64 let this_line = getline( a:line_num ) 65 66 " At the start of a block, we have to indent the newly-created line 67 " based on the previous line. 68 " =~ means matches a regular expression 69 " a question mark after =~ means ignore case (# means match case) 70 " const, type, var should always appear at the start of a line, but 71 " begin can appear anywhere in the line. 72 " if one of the following keywords appear in the previous line with 73 " nothing before it but optional whitespace, and nothing after it. 74 " Has to be end of line at end to show this is not a routine 75 " parameter list. Otherwise, you'd end up with cascading vars. 76 77 " These words appear alone on a line (apart from whitespace). 78 if prev_line =~ '^\s*\(const\|var\|begin\|repeat\|private\)$' 79 " Place an & before an option to obtain its value. 80 let indnt = indnt + &shiftwidth 81 endif 82 83 " Words preceded by optional whitespace and followed by anything. 84 if prev_line =~ '^\s*\(for\|if\|else\|case\)' 85 " Place an & before an option to obtain its value. 86 let indnt = indnt + &shiftwidth 87 " if this is a multistatement block then we need to align the 88 " begin with the previous line. 89 if this_line =~ '^\s*begin' 90 let indnt = indnt - &shiftwidth 91 endif 92 endif 93 " These words may have text before them on the line (hence the .*). 94 if prev_line =~ '^.*\s*\<\(object\|record\)\>$' 95 let indnt = indnt + &shiftwidth 96 endif 97 " If we have opened a bracket and the contents spills over one line, 98 " then indent one level beyond the bracket's first line. RE = an 99 " opening bracket followed by any amount of anything other than a 100 " closing bracket and then the end-of-line. If we didn't include the 101 " end of line, this RE would match even closed brackets, since it 102 " would match everything up to the closing bracket. 103 " This test isn't clever enough to handle brackets inside strings or 104 " comments. 105 if prev_line =~ '([^*][^)]*$' 106 let indnt = indnt + &shiftwidth 107 endif 108 109 " If we just closed a bracket that started on a previous line, then 110 " unindent. 111 if prev_line =~ '^[^(]*[^*])' 112 let indnt = indnt - &shiftwidth 113 endif 114 115 " At the end of a block, we have to unindent both the current line 116 " (the 'end;' for instance) and the newly-created line. 117 if this_line =~ '^\s*\(end;\|until\|else\)' 118 let indnt = indnt - &shiftwidth 119 endif 120 121 " Keywords that always appear at the start of a line. 122 " Problem is that function and procedure keywords should be indented 123 " if within a class declaration. 124 if this_line =~ '^\s*\<type\|uses\|$IFDEF\|$ENDIF\|procedure\|function\>' 125 let indnt = 0 126 endif 127 if prev_line =~ '^\s*\<type\|uses\>' 128 let indnt = &shiftwidth 129 endif 130 131 " Put conditional compile directives on first column. 132 if this_line =~ '^\s*{\$' 133 let indnt = 0 134 endif 135 136 return indnt 137endfunction 138 139" TODO: end; should align with the previous (begin/record/object/else). 140" "else begin" is the only case where begin does not appear at the start 141" of the line. 142 143" TODO: Don't align with {$IFDEF} 144 145"Example from vb.vim 146" regular expression match, case insensitive 147"if previous_line =~? 148" start of line, zero or more whitespace 149"'^\s* 150" start of word 151"\< 152" 153"\( 154" begin\| 155" \%( 156" \%( 157" private\|public\|friend 158" \) 159" \s\+ 160" \) 161" zero or more of the previous atom 162" \= 163" \%( 164" function\|sub\|property 165" \) 166" \|select\|case\|default\|if 167"\> 168" .\{-}\<then\>\s*$\|else\|elseif\|do\|for\|while\|enum\|with 169"\) 170" end of word 171"\>' 172" let ind = ind + &sw 173"endif 174