1" Vim indent file 2" Language: Pascal 3" Maintainer: Neil Carter <[email protected]> 4" Created: 2004 Jul 13 5" Last Change: 2021 Jul 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 23let b:undo_indent = "setl indentkeys< indentexpr<" 24 25if exists("*GetPascalIndent") 26 finish 27endif 28 29 30function! s:GetPrevNonCommentLineNum( line_num ) 31 32 " Skip lines starting with a comment 33 let SKIP_LINES = '^\s*\(\((\*\)\|\(\*\ \)\|\(\*)\)\|{\|}\)' 34 35 let nline = a:line_num 36 while nline > 0 37 let nline = prevnonblank(nline-1) 38 if getline(nline) !~? SKIP_LINES 39 break 40 endif 41 endwhile 42 43 return nline 44endfunction 45 46 47function! s:PurifyCode( line_num ) 48 " Strip any trailing comments and whitespace 49 let pureline = 'TODO' 50 return pureline 51endfunction 52 53 54function! GetPascalIndent( line_num ) 55 56 " Line 0 always goes at column 0 57 if a:line_num == 0 58 return 0 59 endif 60 61 let this_codeline = getline( a:line_num ) 62 63 64 " SAME INDENT 65 66 " Middle of a three-part comment 67 if this_codeline =~ '^\s*\*' 68 return indent( a:line_num - 1) 69 endif 70 71 72 " COLUMN 1 ALWAYS 73 74 " Last line of the program 75 if this_codeline =~ '^\s*end\.' 76 return 0 77 endif 78 79 " Compiler directives, allowing "(*" and "{" 80 "if this_codeline =~ '^\s*\({\|(\*\)$\(IFDEF\|IFNDEF\|ELSE\|ENDIF\)' 81 if this_codeline =~ '^\s*\({\|(\*\)\$' 82 return 0 83 endif 84 85 " section headers 86 if this_codeline =~ '^\s*\(program\|procedure\|function\|type\)\>' 87 return 0 88 endif 89 90 " Subroutine separators, lines ending with "const" or "var" 91 if this_codeline =~ '^\s*\((\*\ _\+\ \*)\|\(const\|var\)\)$' 92 return 0 93 endif 94 95 96 " OTHERWISE, WE NEED TO LOOK FURTHER BACK... 97 98 let prev_codeline_num = s:GetPrevNonCommentLineNum( a:line_num ) 99 let prev_codeline = getline( prev_codeline_num ) 100 let indnt = indent( prev_codeline_num ) 101 102 103 " INCREASE INDENT 104 105 " If the PREVIOUS LINE ended in these items, always indent 106 if prev_codeline =~ '\<\(type\|const\|var\)$' 107 return indnt + shiftwidth() 108 endif 109 110 if prev_codeline =~ '\<repeat$' 111 if this_codeline !~ '^\s*until\>' 112 return indnt + shiftwidth() 113 else 114 return indnt 115 endif 116 endif 117 118 if prev_codeline =~ '\<\(begin\|record\)$' 119 if this_codeline !~ '^\s*end\>' 120 return indnt + shiftwidth() 121 else 122 return indnt 123 endif 124 endif 125 126 " If the PREVIOUS LINE ended with these items, indent if not 127 " followed by "begin" 128 if prev_codeline =~ '\<\(\|else\|then\|do\)$' || prev_codeline =~ ':$' 129 if this_codeline !~ '^\s*begin\>' 130 return indnt + shiftwidth() 131 else 132 " If it does start with "begin" then keep the same indent 133 "return indnt + shiftwidth() 134 return indnt 135 endif 136 endif 137 138 " Inside a parameter list (i.e. a "(" without a ")"). ???? Considers 139 " only the line before the current one. TODO: Get it working for 140 " parameter lists longer than two lines. 141 if prev_codeline =~ '([^)]\+$' 142 return indnt + shiftwidth() 143 endif 144 145 146 " DECREASE INDENT 147 148 " Lines starting with "else", but not following line ending with 149 " "end". 150 if this_codeline =~ '^\s*else\>' && prev_codeline !~ '\<end$' 151 return indnt - shiftwidth() 152 endif 153 154 " Lines after a single-statement branch/loop. 155 " Two lines before ended in "then", "else", or "do" 156 " Previous line didn't end in "begin" 157 let prev2_codeline_num = s:GetPrevNonCommentLineNum( prev_codeline_num ) 158 let prev2_codeline = getline( prev2_codeline_num ) 159 if prev2_codeline =~ '\<\(then\|else\|do\)$' && prev_codeline !~ '\<begin$' 160 " If the next code line after a single statement branch/loop 161 " starts with "end", "except" or "finally", we need an 162 " additional unindentation. 163 if this_codeline =~ '^\s*\(end;\|except\|finally\|\)$' 164 " Note that we don't return from here. 165 return indnt - 2 * shiftwidth() 166 endif 167 return indnt - shiftwidth() 168 endif 169 170 " Lines starting with "until" or "end". This rule must be overridden 171 " by the one for "end" after a single-statement branch/loop. In 172 " other words that rule should come before this one. 173 if this_codeline =~ '^\s*\(end\|until\)\>' 174 return indnt - shiftwidth() 175 endif 176 177 178 " MISCELLANEOUS THINGS TO CATCH 179 180 " Most "begin"s will have been handled by now. Any remaining 181 " "begin"s on their own line should go in column 1. 182 if this_codeline =~ '^\s*begin$' 183 return 0 184 endif 185 186 187" ____________________________________________________________________ 188" Object/Borland Pascal/Delphi Extensions 189" 190" Note that extended-pascal is handled here, unless it is simpler to 191" handle them in the standard-pascal section above. 192 193 194 " COLUMN 1 ALWAYS 195 196 " section headers at start of line. 197 if this_codeline =~ '^\s*\(interface\|implementation\|uses\|unit\)\>' 198 return 0 199 endif 200 201 202 " INDENT ONCE 203 204 " If the PREVIOUS LINE ended in these items, always indent. 205 if prev_codeline =~ '^\s*\(unit\|uses\|try\|except\|finally\|private\|protected\|public\|published\)$' 206 return indnt + shiftwidth() 207 endif 208 209 " ???? Indent "procedure" and "functions" if they appear within an 210 " class/object definition. But that means overriding standard-pascal 211 " rule where these words always go in column 1. 212 213 214 " UNINDENT ONCE 215 216 if this_codeline =~ '^\s*\(except\|finally\)$' 217 return indnt - shiftwidth() 218 endif 219 220 if this_codeline =~ '^\s*\(private\|protected\|public\|published\)$' 221 return indnt - shiftwidth() 222 endif 223 224 225" ____________________________________________________________________ 226 227 " If nothing changed, return same indent. 228 return indnt 229endfunction 230 231