neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

pascal.vim (5793B)


      1 " Vim indent file
      2 " Language:    Pascal
      3 " Maintainer:  Neil Carter <n.carter@swansea.ac.uk>
      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 
     10 if exists("b:did_indent")
     11 finish
     12 endif
     13 let b:did_indent = 1
     14 
     15 setlocal indentexpr=GetPascalIndent(v:lnum)
     16 setlocal indentkeys&
     17 setlocal indentkeys+==end;,==const,==type,==var,==begin,==repeat,==until,==for
     18 setlocal indentkeys+==program,==function,==procedure,==object,==private
     19 setlocal indentkeys+==record,==if,==else,==case
     20 
     21 let b:undo_indent = 'setlocal indentexpr< indentkeys<'
     22 
     23 if exists("*GetPascalIndent")
     24 finish
     25 endif
     26 
     27 
     28 " ________________________________________________________________
     29 function! 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
     43 endfunction
     44 
     45 
     46 " ________________________________________________________________
     47 function! s:PurifyCode( line_num )
     48 " Strip any trailing comments and whitespace
     49 let pureline = 'TODO'
     50 return pureline
     51 endfunction
     52 
     53 
     54 " ________________________________________________________________
     55 function! 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
    228 endfunction