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