#ifdef block's color

473 vistas
Ir al primer mensaje no leído

Gusman

no leída,
6 ene 2010, 3:55:09 a.m.6/1/2010
para vim...@googlegroups.com
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.

Thank you in advance.



Best Regards,


Gusman Dharma P

Marczis, Peter (NSN - HU/Budapest)

no leída,
6 ene 2010, 4:39:10 a.m.6/1/2010
para vim...@googlegroups.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...
 
Br,
    Peter.


From: vim...@googlegroups.com [mailto:vim...@googlegroups.com] On Behalf Of ext Gusman
Sent: Wednesday, January 06, 2010 9:55 AM
To: vim...@googlegroups.com
Subject: #ifdef block's color

A. S. Budden

no leída,
6 ene 2010, 5:25:45 a.m.6/1/2010
para vim...@googlegroups.com
> > From: vim...@googlegroups.com [mailto:vim...@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....@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

Gusman

no leída,
6 ene 2010, 10:49:25 p.m.6/1/2010
para vim...@googlegroups.com
--
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?

--

Ben Fritz

no leída,
7 ene 2010, 11:18:28 a.m.7/1/2010
para vim_use

On Jan 6, 9:49 pm, Gusman <gusman...@gmail.com> wrote:
>
> 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?
>

Vim parses the file to determine the syntax highlighting when loading
a file, or applying a new file type, or when turning syntax on. I
believe you might also be able to trigger it with a :doautocmd Syntax
{syntax, e.g. c} or a :doautocmd FileType {filetype, e.g. c}.
Regardless, you don't really need to know under what conditions it was
triggered, if you just place any additional rules you desire in the
appropriate directory (like $HOME/vimfiles/syntax or $HOME/vimfiles/
after/syntax), or use an autocmd Syntax event.

However, I would suggest a different approach, based on my own usage.

I have folding defined for #ifdef, etc. by placing the following in
$HOME/vimfiles/after/syntax/c.vim (based loosely on extra folding for
the Vim scripting language found at http://vim.wikia.com/wiki/Syntax_folding_of_Vim_scripts):

" fold #if...#else...#endif constructs
syn region IfFoldContainer
\ start="^\s*#\s*if\(n\?def\)\?\>"
\ end="#\s*endif\>"
\ skip=+"\%(\\"\|[^"]\)\{-}\\\@<!"\|'[^']\{-}'\|'\\''\|//.*+
\ transparent
\ keepend extend
\ containedin=NONE
\ contains=SynFoldIf,SynFoldElif,SynFoldElse
syn region SynFoldIf
\ start="^\s*#\s*if\(n\?def\)\?\>"
\ end="^\s*#\s*el\(se\|if\)\>"ms=s-1,me=s-1
\ skip=+"\%(\\"\|[^"]\)\{-}\\\@<!"\|'[^']\{-}'\|'\\''\|//.*+
\ fold transparent
\ keepend
\ contained
\ nextgroup=SynFoldElif,SynFoldElse
\ contains=TOP
syn region SynFoldElif
\ start="^\s*#\s*elif\>"
\ end="^\s*#\s*el\(se\|if\)\>"ms=s-1,me=s-1
\ skip=+"\%(\\"\|[^"]\)\{-}\\\@<!"\|'[^']\{-}'\|'\\''\|//.*+
\ fold transparent
\ keepend
\ contained
\ nextgroup=SynFoldElse
\ contains=TOP
syn region SynFoldElse
\ start="^\s*#\s*else\>"
\ end="^\s*#\s*endif\>"
\ skip=+"\%(\\"\|[^"]\)\{-}\\\@<!"\|'[^']\{-}'\|'\\''\|//.*+
\ fold transparent
\ keepend
\ contained
\ contains=TOP

Now, when I encounter a macro that I know is not defined, I can press
zc to fold away all the code that will not be compiled in.

You could extend this by creating a mapping to add the macro name
under the cursor to a file/list containing all defined macros, and
another mapping to execute zc if the current section of code is not in
your list.

You could extend this further by automatically running your close-a-
fold command on every #if, #else, or #elif in your code using a Syntax
autocmd event and the :g command (assuming you like to have all folds
open when you load the file). You could also set up a mapping to do
this at will instead.

The close-a-fold command would do something like this, on the current
line:

1. Look for #ifdef {something not in your list} and close it
2. Look for #ifndef {something in your list} and close it
3. Look for #if defined({something not in your list}) or #elif defined
({something not in your list}) (with potential ||, && logic that you
will need to parse) and close it
4. Look for #if !defined({something in your list}) or #elif !defined
({something in your list}) (with potential ||, && logic that you will
need to parse) and close it
5. Look for #else and use the matchit plugin to look for the above
cases, and close it if required

Tony Mechelynck

no leída,
12 mar 2010, 12:23:21 a.m.12/3/2010
para vim...@googlegroups.com,Gusman

I don't think there is a foolproof way to do this (unless... see last
paragraph), because of all the places where macros can be defined (the
concrete examples below apply to gcc, but most compilers have similar
mechanisms):

- in the source of the same file, before they are used (the easiest)
- in included "files"
- in included <files>, whose location is found by searching all
directories listed in -I switches on the compiler's command-line
- by -D switches on the compiler command-line
- for predefined compiler-specific macros, they don't need a definition

This means that the identical same source file can be compiled twice
with different "true" and "false" #if regions, with absolutely no
changes to the source file itself. For instance whenever there are
patches to the C source, I compile two versions from the same Makefile:
one version has its sources in .build/vim/vim72/src/, the other's
sources, in .build/vim/vim72/src/tiny/, are (every single one of them)
softlinks to files of the same name in the parent directory.

Quite a number of the defines are set in auto/config.h which is
different between both; but several are also defined (especially for the
Huge version) on the compiler command-line.

When reading the Vim source, I can look ahead and behind for #if / #else
/ #endif blocks, and maybe use cscope to find where (if anywhere) the
name is defined (which may be in an include file which is not part of
the Vim distribution), but I think that the task of determining which
macros are defined (and with which value if any) at which point in the
source is a task for a source preprocessor (including the "preprocess"
phase of a multistep compiler such as gcc), not for an editor.


One way to get it though (I think) would be (if your compiler allows it)
to run only the preprocessor step, with the exact same implicit and
explicit defines as for a "real" compile, and examine the output of that
preprocess, where, I suppose, all macros would be resolved, and "false
#if blocks" removed.


Best regards,
Tony.
--
"I have seen the future and it is just like the present, only longer."
-- Kehlog Albran, "The Profit"

Charles Campbell

no leída,
12 mar 2010, 10:50:28 a.m.12/3/2010
para vim...@googlegroups.com

> On 06/01/10 09:55, Gusman wrote:
>> 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.
>>
>> Thank you in advance.
>>
>>
>>
>> Best Regards,
>>
>>
>> Gusman Dharma P
>>
>
http://www.vim.org/scripts/script.php?script_id=7

Simply found by searching for ifdef using vim.sf.net's search box.

Regards,
Chip Campbell

Responder a todos
Responder al autor
Reenviar
0 mensajes nuevos