I work with quite a bit of multi-platform C/C++ code, separated by common #defines (#if WIN, #if UNIX, etc). It would be nice if I could have vim automatically fold the sections I'm currently not interested in when I open a file. I've searched through the vim script archives, but I haven't found anything useful. Any suggestions? Places to start?
Just add a folding region to your syntax http://vim.wikia.com/wiki/Syntax_folding_of_Vim_scripts#Syntax_definitions
:syn region myFold start="\#IF" end="\#ENDIF" transparent fold
:syn sync fromstart
:set foldmethod=syntax
To add to @hometoasts answer, you can add that command as a comment in the first ten or last ten lines of the file and vim will automatically use it for that file.
/* vim: syn region regionName start="regex" end="regex": */
A quick addition to Denton's addition: to use the new syntax rule with any C or C++ code, add it to a file at $VIMRUNTIME/syntax/c.vim
and cpp.vim
. ($VIMRUNTIME
is where your local Vim code lives: ~/.vim
on Unix.) Also, the values for start
and end
in the syntax definition are regular expressions, so you can use ^#if
and ^#endif
to ensure they only match those strings at the start of a line.
Sweet. And here I was thinking I'd have to hack together some massive script. I should have known better :)
Spoke too soon. I dropped that into a .vim/syntax/c.vim file, and all it did was fold all the methods, totally ignoring the #if's.
I've always used forldmethod=marker and defined my own fold tags placed within comments.
this is for defining the characters that define the open and close folds. in this case open is "<(" and close is ")>" replace these with whatever you'd like.
set foldmethod=marker
set foldmarker=<(,)>
This is my custom function to decide what to display of the folded text:
set foldtext=GetCustomFoldText()
function GetCustomFoldText()
let preline = substitute(getline(v:foldstart),'<(','<(+)','')
let line = substitute(preline,"\t",' ','g')
let nextLnNum = v:foldstart + 1
let nextline = getline(nextLnNum)
let foldTtl = v:foldend - v:foldstart
return line . ' | ' . nextline . ' (' . foldTtl . ' lines)>'
endfunction
Hope that helps.
I have a huge code base and so a large number of #defines. Each file has numerous #ifdef's and most of the times they are nested. I tried many of the vim scripts but they always used to run into some error with the code I have. So in the end I put all my defines in a header file and included it in the file that I wanted to work with and did a gcc on it like this
gcc -E -C -P source.cpp > output.cpp
The -E command gets gcc to run only the pre-processor on the file, so all the unwanted code within the undefined #ifdef's are removed. The -C option retains the comments in the file. The -P option inhibits generation of linemarkers in the output from the preprocessor.