I mostly want it to automatically create folds for between a
begin and an
end, although if there's anything more advanced that would be welcome too.
I've looked in the help for the pascal syntax and it doesn't support syntax folding.
The following seems to patch syntax folding onto the Pascal syntax that ships with Vim. Put this into
syn clear pascalLabel pascalStatement pascalStruct syn keyword pascalLabel goto label syn keyword pascalStatement procedure function syn keyword pascalStatement program const var type if !exists("pascal_traditional") syn keyword pascalStatement constructor destructor implementation inherited syn keyword pascalStatement unit uses syntax region pascalInterface matchgroup=pascalStatement start="\<interface\>" end="\<end\>" transparent fold syntax region pascalObject matchgroup=pascalStruct start="\<object\>" end="\<end\>" transparent fold endif syn keyword pascalRecordCaseLabel case contained containedin=pascalRecord syntax region pascalBlock matchgroup=pascalStatement start="\<begin\>" end="\<end\>" transparent fold syntax region pascalCase matchgroup=pascalLabel start="\<case\>" end="\<end\>" transparent fold syntax region pascalRecord matchgroup=pascalStruct start="\<record\>" end="\<end\>" transparent fold contains=TOP,pascalCase highlight def link pascalRecordCaseLabel pascalLabel setlocal foldmethod=syntax
I had to
:syn-clear some existing definitions. It would be better if the author of the syntax plugin included this into the main script. Also note that I'm not too familiar with Pascal syntax, and hacked this together quickly. No warranties :-)
The easiest way to create some simple folding is using the
Vim runs this code for every line, you can get the line contents, do some logic with it, and return a number (and some other special values) to tell Vim what the fold level should be.
Here is an example:
fun! PascalFold(lnum) " Get the line for which Vim wants to know the folding level let l:line = getline(a:lnum) " Does this line begin with 'begin'? Then tell Vim this starts a fold " with level 1 if l:line =~ '^begin' return '>1' " Does this line begin with 'end'? Then tell Vim this ends a fold " with level 1 elseif l:line =~ '^end' return '<1' " Else use the foldlevel of the previous line (0 or 1) else return '=' endif endfun " Set this only for Pascal files au FileType pascal setlocal foldmethod=expr foldexpr=PascalFold(v:lnum)
The logic is not very complicated, and should be self-explanatory.
I have never programmed Pascal, so I don't know the syntax, which is required to give a really good answer (specifically, the anything more advanced part). If this is not enough to get you started, then perhaps you should explain what you want to fold, exactly, by example.
For more information, see:
Another (perhaps better) way to do this is to set
foldmethod=syntax and modify the
syntax/pascal.vim file... but that requires a bit more work from the looks of it.