Wednesday, January 6, 2010

Re: #ifdef block's color



On Wed, Jan 6, 2010 at 5:25 PM, A. S. Budden <abudden@gmail.com> wrote:
> > From: vim_use@googlegroups.com [mailto:vim_use@googlegroups.com] On Behalf
> > Of ext Gusman
> > Subject: #ifdef block's color
> >
> > Dear All,
> >
> > Currently I'am working with a big source code in C language which have many
> > #ifdef directives in there. It's so difficult for me to read the code flow
> > while I can't determine which #ifdef is defined or not defined.
> >
> > Is there plugin can make undefined #ifdef code block same as #if 0 code
> > block.

2010/1/6 Marczis, Peter (NSN - HU/Budapest) <peter.marczis@nsn.com>:
> Hi,
> I think you can modify the c syntax file, in $VIMRUNTIME\syntax\c.vim.
> There are more region definition, but you will find the IF 0 definition, you
> should mod, that regexp to match #if  instead...

You'll need to parse your tags file to work out what all the defined
names are (a bit like the way the ctags highlighter works [1]).  You
can then generate a list of tags and do something like this (I'll
leave ParseTagsFileForDefines( ) to you for now...):

   let list_of_defined_names = ParseTagsFileForDefines()
   " Returns a list like ['NDEBUG', 'ANOTHER_DEFINE', 'DEFINED_NAME_2']
   let list_of_defined_names = ['NDEBUG', 'ANOTHER_DEFINE', 'DEFINED_NAME_2']

   let start_if_regexp = '^\s*\(%:\|#\)\s*ifdef\s\+\('
   let start_ifn_regexp = '^\s*\(%:\|#\)\s*ifndef\s\+\('

   for item in other_list
       let start_if_regexp .= '\<' . item . '\>'
       let start_if_regexp .= '\|'

       let start_ifn_regexp .= '\<' . item . '\>'
       let start_ifn_regexp .= '\|'
   endfor

   " Strip the trailing | and replace it with )
   let start_if_regexp = start_if_regexp[0:len(start_if_regexp)-2] . ')'
   let start_ifn_regexp = start_ifn_regexp[0:len(start_ifn_regexp)-2] . ')'

   " Add a negative look-ahead and end-of-line catching
   let start_if_regexp .= '\@!\(\k\{-}\)\s*$'
   let start_ifn_regexp .= '\s*$'

   " We now have #ifdef (NDEBUG|ANOTHER_DEFINE|DEFINED_NAME_2)\@!
   " and a #ifndef (NDEBUG|ANOTHER_DEFINE|DEFINED_NAME_2)
   " with escaped brackets and word protection (\<, \>)

   " Make it work
   exe 'syn region cCppIFDEFNotDefined start="' . start_if_regexp .
'" end=".\@=\|$" contains=cCppNotDefined2'
   exe 'syn region cCppIFNDEFNotDefined start="' . start_ifn_regexp .
 '" end=".\@=\|$" contains=cCppNotDefined2'

   " Add the catch for the end of the region
   syn region cCppNotDefined2 contained start="\k\+\s*$"
end="^\s*\(%:\|#\)\s*\(endif\>\|else\>\|elif\>\)"
contains=cSpaceError,cCppSkip
   hi link cCppIFDEFNotDefined Comment
   hi link cCppIFNDEFNotDefined Comment
   hi link cCppNotDefined2 cCppIFDEFNotDefined

   " Optional: if you use rainbow.vim you may need this:
   syn cluster cBracketGroup
add=cCppIFDEFNotDefined,cCppIFNDEFNotDefined,cCppNotDefined2
   syn cluster cCppBracketGroup
add=cCppIFDEFNotDefined,cCppIFNDEFNotDefined,cCppNotDefined2
   syn cluster cCurlyGroup
add=cCppIFDEFNotDefined,cCppIFNDEFNotDefined,cCppNotDefined2
   syn cluster cParenGroup
add=cCppIFDEFNotDefined,cCppIFNDEFNotDefined,cCppNotDefined2
   syn cluster cCppParenGroup
add=cCppIFDEFNotDefined,cCppIFNDEFNotDefined,cCppNotDefined2


The biggest problem that you'll have is that if there are a lot of
defined names in your tags file, it'll do one of two things:

1) Slow down vim so much that it's unusable (as it'll be a really
complicated regexp)
2) Give an error message due to the pattern being too long.

There may be a better way of doing this (Eclipse can do this after
all, so I'd hope Vim can), but I don't know what it is...

Al

[1] http://sites.google.com/site/abudden/contents/Vim-Scripts/ctags-highlighting

--
http://sites.google.com/site/abudden

--
You received this message from the "vim_use" maillist.
For more information, visit http://www.vim.org/maillist.php


Your idea to parse tags file is interesting. My plan is putting all defined (selected by user using hotkey) #ifdef into a file, and make a plugin to parse it.

Actually I still don't know when VIM start to parsing and generate the highlight. Does vim generate the highlight only when we open the file?

--
Best Regards,


Gusman Dharma P

No comments: