- 0 Talk
-
Java/C/C++ folding
Duplicate tip
This tip is very similar to the following:
These tips need to be merged – see the merge guidelines.
This tip is deprecated for the following reasons:
The functionality described in this Tip has been mostly replaced with syntax folding in version 7. Nevertheless, the default Java syntax file still only includes braces.
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.
Comments
Edit
TO DO
- Merge in some of the following info
- prune what is incorrect (for example, the java.vim syntax file last update 2010 March 23 still lacks folding of javadoc)
- bring this to the attention of the java.vim syntax maintainer
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
This is another fold function which enables folding in any C/java/actionscript/php file or XML/HTML. Also when its mixed (for example an php file containing javascript and php). I made it because the syntax & marker foldingmethods did not fit my needs. For example, if I have a big function with a big function comment, I want to fold both with one action. This script makes it possible, because its a bit more bruteforce.
set viewoptions=folds
au BufWinLeave * mkview
au BufWinEnter * silent loadview
vmap <space> zf
" CROSSFOLD FUNCTION
" ==================
" Made by the Coder of Salvation (http://leon.vankammen.eu) @ 2010
"
" inspired by Max Ischenko's http://www.vim.org/tips/tip.php?tip_id=108
" this is great when :
" - you have big functions with big comments
" - you have files containing multiple syntaxes (like html and javascript in 1 php file)
"
" USAGE: 1) press space on the beginning of a functioncomment and it will fold comment + function
" 2) press space on the beginning of an xml/html tag and it will fold the tag
"
function ToggleFold()
set foldmethod=manual
if foldlevel('.') == 0
" No fold exists at the current line,
" so create a fold based on braces or brackets
let x = line('.') " the current line number (start fold)
let y = x + 1 " the end line number (end fold)
let i = indent('.') " the indentation of the current line
let last = line('$') " the last line number
normal 0
" determine endtoken
if ( &ft == "xml" || &ft == "html" )
let endtoken = "<"
normal j
else
let endtoken = "}"
endif
" goto endtoken on same indent
while ( indent( search( endtoken ) ) != i )
endwhile
let y = line('.')
" if we have extra blank space to fold, increment lastline for fold
if( y != last && strlen( getline(y+1) ) == 0 )
let y = y + 1
endif
" if last line, something went wrong and we are dealing with a comment?
if y == last
echo "?? hmm..got last line of file as fold-end, maybe try 'zf' on a visual selection?"
return
endif
" Create the fold from x to y
execute x . "," . y . " fold"
normal j
else
" Delete the fold on the current line
normal zd
endif
endfunction
nmap <space> :call ToggleFold()<CR>"