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