6

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.

0

2 Answers 2

7

The following seems to patch syntax folding onto the Pascal syntax that ships with Vim. Put this into ~/.vim/after/syntax/pascal.vim:

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 :-)

3

The easiest way to create some simple folding is using the foldexpr option.

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:


PS.

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.

4
  • you might want to use the a and s for embedded blocks (loops and so)
    – elyashiv
    Feb 27, 2015 at 9:55
  • @elyashiv I don't understand what you mean? Feb 27, 2015 at 9:56
  • your solution would work for functions and so, but not for blocks embedded in them. you can use the a1 and s1 return values for implementing this.
    – elyashiv
    Mar 1, 2015 at 6:03
  • @elyashiv Like I said, I have no idea how Pascal looks as I've never programmed a line of Pascal. I've conservatively implemented a very basic foldexpr (this is also why we anchor the matches to the start of the line). In any case, using syntax-based folding is probably the better way to go if you want full folding of everything... Many people only use folding for functions, though, so this simple method may still prove useful for some :-) Mar 1, 2015 at 6:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.