Display code in appropriate #ifdef block according to the value of identifier

271 views Asked by At

I have a C codebase with source files using #ifdef blocks all over. There are multiple identifiers and corresponding ifdefs (with the ifdefs nested to multiple levels). While viewing the code in vim, is there a way for me to define multiple identifiers and view/highlight my code such that I see only those ifdef blocks which are applicable when an identifier is defined.

#if defined(ID1) && (ID1 == 1)
// code 1
#elif defined(ID1) && (ID1 == 2)
// code 2

When set ID=1, my view should only display/highlight code 1, when ID=2 my view should only display/highlight code 2, otherwise if ID is not defined, both code 1 and code 2 should not be highlighted or displayed.

2

There are 2 answers

0
Igbanam On BEST ANSWER
DISCLAIMER

This is generally a bad idea. You never want to hide text in a source file. 
Compiling different code branches based on flags set at compile time is a 
different story. But viewing the code, you should always see what you ask 
the compiler to build

That said, if you want to hide code when reading, there are a couple ways you can achieve that

  1. Fold it: See :help fold for more details
  2. Syntax: junegunn/limelight.vim is a good tool to selectively turn off syntax highlighting for code spaces outside the region your cursor is in.
0
idbrii On

Here's a slightly functional solution for folding C++.

First setup general ifdef folding. This should catch #if, #ifdef, and #ifndef:

function! FoldtextForC()
    " Show the whole #if line
    return getline(v:foldstart)
endfun
set foldtext=FoldtextForC()
set foldmarker=#if,#endif

Then you could do something like this to close all the DEBUG folds:

:g/#ifdef DEBUG/foldclose

After running that command this code sample will look like this (set foldcolumn=3 so you can see the folding):

some linux code folded

You'd probably want to write something smarter that does :foldopen!, collects all the defines, separates into defined and undefined, builds the appropriate regex, and does the above command with your improved regex.


The alternative is to write a 'foldexpr' that does something similar but only folds blocks that are not compiled. Then you can always :foldclose! to hide everything that's not compiled and :foldopen! to see everything again.