Java/C/C++ folding
From Vim Tips Wiki
Duplicate tip
This tip is very similar to the following:
These tips need to be merged – see the merge guidelines.
Tip 1150 Previous Next created February 23, 2006 · complexity intermediate · author Salman Halim · version 6.0
Here are some functions I use to fold Java code. They are probably easily applicable to C/C++ code also:
" Javadoc comments (/** and */ pairs) and code sections (marked by {} pairs) mark the start and end of folds. All other
" lines simply take the fold level that is going so far.
function! MyFoldLevel( lineNumber )
let thisLine = getline( a:lineNumber )
" If the entire Javadoc comment or the {} pair is on one line, then don't create a fold for it.
if ( thisLine =~ '\%(\%(/\*\*\).*\%(\*/\)\)\|\%({.*}\)' )
return '='
elseif ( thisLine =~ '\%(^\s*/\*\*\s*$\)\|{' )
return "a1"
elseif ( thisLine =~ '\%(^\s*\*/\s*$\)\|}' )
return "s1"
endif
return '='
endfunction
setlocal foldexpr=MyFoldLevel(v:lnum)
setlocal foldmethod=expr
The 'foldexpr' basically folds away multi-line JavaDoc and {} blocks. This is different from setting up:
set foldmethod=marker
set foldmarker={,}
in that it also fold away JavaDocs -- the {} pair folding is the same effect as these two settings, however.
[edit] Comments
In Vim 7.0, this can be accomplished by using the syntax file. It has been implemented in the syntax\c.vim in cvs. But the Java one is missing this folding info.
I use Vim 7 alpha exclusively, actually. This line from syntax/java.vim:
syn match javaBraces "[{}]"
is what causes the problem, I think. The problem is that this line from syntax/c.vim:
syntax region cBlock start="{" end="}" transparent fold
When applied to java.vim, causes folds to START fine, but never end -- so the entire file becomes one large fold with subsequent opening braces that extend the fold till the bottom of the file.
I emailed this to both the maintainer of the Java syntax file as well as the Vim developers' list:
syntax clear javaBraces
syntax clear javaDocComment
syn region javaBraces start="{" end="}" transparent fold
syn region javaDocComment start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaTodo,@Spell fold
Basically, until they update the syntax/java.vim, putting the above in your after/syntax/java.vim should fix things. (You'll have to set fdm=syntax in your ftplugin, of course.)
- Using 7.2.79 here, and this doesn't appear to be necessary anymore
However, if you're not using Vim 7 yet, my original solution with expression should yield the same results...
Works like a charm!
This is a nice tip for cleaning up Java source. Thanks for posting it! I haven't checked the 7.0 behavior, and I'm betting it's handled cleanly, but I had to make one change for 6.x. We'll all encounter code like this at some point:
try {
//stuff
} catch (Exception e) {
//stuff
}
To fix it, I tweaked the fold-excluding regular expression to check for close-stuff-open braces on the same line. The behavior actually makes sense, too, since you should only see that brace style in compound control structures. The fold applies to the outside pair (the if, try, etc.) and it turns out pretty clean. Here's the new line I'm using:
if ( thisLine =~ '\%(\%(/\*\*\).*\%(\*/\)\)\|\%({.*}\)\|\%(}.*{\)' )
I'm using Ubuntu 9.04 here with Vim 7.2.079. This folding problem still exists, but the solution of editing the syntax file works fine. Just put the below code in at the end of your syntax/java.vim. (You'll have to set fdm=syntax in your ftplugin, of course.)
syntax clear javaBraces
syntax clear javaDocComment
syn region javaBraces start="{" end="}" transparent fold
syn region javaDocComment start="/\*\*" end="\*/" keepend contains=javaCommentTitle,@javaHtml,javaDocTags,javaDocSeeTag,javaTodo,@Spell fold
