Reputation: 472
I usually code in C, and I have in my .vimrc set foldmethod=syntax
, which works very well as it folds braces and comments and everything.
But sometimes I need to fold big chunks of code so that they don't get in my way (for example a group of related functions), and I usually do this with set foldmethod=marker
and the markers >>>
and <<<
.
I have been trying to add a new sync region and the nearest thing I have come with is:
syn region cFoldMarkers start='>>>' end='<<<' containedin=cComment transparent fold
but this creates a mess as it somehow it matches with comments.
Is there a way of achieving both objectives? or should I give up of doing this with syntax and just set markers for braces, comments and my custom one?
Thanks in advance
Upvotes: 5
Views: 1024
Reputation: 2884
Plugin syntaxMarkerFold adds this functionality.
containedin=cComment
means that whole region (whole fold) is contained in single comment; we want only markers to be in comments (two separate comments).
Surprisingly enough, it matches markers not belonging to any syntax group too; it's also undesired behaviour for us.
By leaving only
syn region cFoldMarkers start='>>>' end='<<<' transparent fold
it finds start of region and folds it. But it doesn't have so much luck with the end, so Vim just folds to the end of file.
So we need to add matching comments to the RegExp of region (\s*//.\{-}
) and for some pecultiar reason, define matchgroup=Comment
syn region cFoldMarkers matchgroup=Comment start='\s*//.\{-}>>>' end='\s*//.\{-}<<<' transparent fold
Now it should fold just where we want.
Of course, there are more edge cases, which require more handling.
We would also like to be able to use any marker and different valid comments than just //
.
Not to mention leveled marker folding (e.g. {{{1
).
Have a look at the code of my syntaxMarkerFold plugin to check how I've resolved those issues.
Upvotes: 1
Reputation: 472
Okay, after... like 5 hours trying to do it with syntax folding, I have given up and changed to expression folding.
Following this question: LLVM-IR syntax folding for vim I have created a folding function that more or less does what I want:
function! CFold()
let this_line = getline(v:lnum)
" Matching of braces
if match(this_line, '}') >= 0
return 's1'
elseif match(this_line, '{$') >= 0
return 'a1'
" Matching of comments
elseif match(this_line, '/\*') >= 0
if match(this_line, '\*/$') == -1
return 'a1'
" Matching custom folding
elseif match(this_line, '>>>') >= 0
return 'a1'
elseif match(this_line, '<<<') >= 0
return 's1'
endif
elseif match(this_line, '\*/$') >= 0
return 's1'
endif
return '='
endfunction
setlocal foldmethod=expr
setlocal foldexpr=CFold()
Upvotes: 1