highlight as comment code in #if 1 ... #else .... #endif

54 views
Skip to first unread message

Dominique Pelle

unread,
Jun 22, 2008, 9:05:09 AM6/22/08
to vim...@googlegroups.com
When editing C code, Vim highlights code in between #if 0... #endif
as comment, which is nice.

But Vim does not highlight as comment code in the #else condition of
#if 1 ... #else ... #endif

For example, in vim7/src/term.c contains:

#if 1
{(int)KS_SO, "\033|31m"}, /* standout: white on blue */
{(int)KS_SE, "\033|0m"}, /* standout end */
#else
{(int)KS_SO, "\033|F"}, /* standout: high intensity */
{(int)KS_SE, "\033|f"}, /* standout end */
#endif

Code in between #else ... #endif could be highlighted as comment.

I looked into runtime/syntax/c.vim, but it's not clear to me yet how
it can be achieved. Is this doable?

-- Dominique

Ben Schmidt

unread,
Jun 22, 2008, 11:14:46 AM6/22/08
to vim...@googlegroups.com

I found this a fun challenge! It's not all that easy, but I think I've
managed it! I doubt it will handle really tough cases, but it should be
able to get the main ones right, I think. See the attached patch. What
it does is essentially define a new type of PreProcessor directive
that's an #if {some number other than zero}, then define the first part
of it (up to #else, but ignoring nested PreProcessor directives) to be
displayed as normal code, and then the #else part as a comment. You can
make the #else itself display as a coment by removing the cCppOut4
matchgroup.

Ben.

c.vim.patch

Dominique Pelle

unread,
Jun 22, 2008, 3:01:32 PM6/22/08
to vim...@googlegroups.com


Thanks Ben, it does not look easy indeed. I've applied the patch
but something is wrong, it does not work for me:

#if 1... #else... #endif does not get commented after #else

#if 0 ... #endif no longer gets commented out after patching c.vim

Not sure what's missing.

-- Dominique

Ben Schmidt

unread,
Jun 23, 2008, 2:24:01 PM6/23/08
to vim...@googlegroups.com

Hmm. That's odd. It works for me.

Where have you put it; have you patched the one in $VIMRUNTIME or
installed it in ~/.vim/syntax? Either of those should work.

Did you reload Vim with the new script in place or do a :syn clear
before sourcing it? I find if I had the original syntax loaded and then
just source the new syntax it doesn't work without that. Adding syn
clear near the top of c.vim would help that, I suppose, but it might
break things if a different syntax file sources it.

Do you have any other ~/.vim/syntax/c.vim or ~/.vim/after/syntax/c.vim
or variable or highlight settings in your .vimrc that might be affecting
it?

I'll attach my original unpatched file; maybe you started with a
different version of c.vim to me. Perhaps try comparing my original to
your original.

I'll append my test case and attach a screen shot of what I see now if I
open it, too, now I have the patched file in ~/.vim/syntax.

If none of that helps you to track it down, I guess it's probably best
for you to send your :set and :let output and see if we can spot
something there that is affecting it...

Cheers,

Ben.

#if 1
float x;
#ifdef SOMETHING
float y=0;
#else
float y=1;
#endif
float z;
#else
double x;
#ifdef SOMETHING
double y=0;
#else
double y=1;
#endif
double z;
#endif

#if 0
float x;
#ifdef SOMETHING
float y=0;
#else
float y=1;
#endif
float z;
#else
double x;
#ifdef SOMETHING
double y=0;
#else
double y=1;
#endif
double z;
#endif

c.vim
Picture 3.png

Dominique Pelle

unread,
Jun 23, 2008, 4:51:08 PM6/23/08
to vim...@googlegroups.com

I've patched my file $VIMRUNTIME/syntax/c.vim


> Did you reload Vim with the new script in place or do a :syn clear
> before sourcing it? I find if I had the original syntax loaded and then
> just source the new syntax it doesn't work without that. Adding syn
> clear near the top of c.vim would help that, I suppose, but it might
> break things if a different syntax file sources it.

I exited and restarted Vim.


> Do you have any other ~/.vim/syntax/c.vim or ~/.vim/after/syntax/c.vim
> or variable or highlight settings in your .vimrc that might be affecting
> it?

I had the OmniCompletion plugin and a couple of other irrelevant plugins.
I removed everything in my ~/.vim directory and it still would not work.


Ah, interesting! On your sample file, it actually works.
But if I open Vim's source file vim7/src/term.c (around line 690)
(which is what I was using so far for testing), it does not work and
patch even breaks comments in #if 0.

Can you check whether it works for you on that source file?

I'll try to see whether I can make it work when I have more time,
maybe next weekend.

Thanks!
-- Dominique

Ben Schmidt

unread,
Jun 24, 2008, 12:10:28 AM6/24/08
to vim...@googlegroups.com
>>>>> When editing C code, Vim highlights code in between #if 0... #endif
>>>>> as comment, which is nice.
>>>>>
>>>>> But Vim does not highlight as comment code in the #else condition of
>>>>> #if 1 ... #else ... #endif
[...]

>>>>> Code in between #else ... #endif could be highlighted as comment.
>>>>>
>>>>> I looked into runtime/syntax/c.vim, but it's not clear to me yet how
>>>>> it can be achieved. Is this doable?
>>>>>
>>>> I found this a fun challenge! It's not all that easy, but I think I've
>>>> managed it!
>>>>
>>> Thanks Ben, it does not look easy indeed. I've applied the patch
>>> but something is wrong, it does not work for me:
>>>
>> Hmm. That's odd. It works for me.
>>
> Ah, interesting! On your sample file, it actually works.
> But if I open Vim's source file vim7/src/term.c (around line 690)
> (which is what I was using so far for testing), it does not work and
> patch even breaks comments in #if 0.
>
> Can you check whether it works for you on that source file?

Mmm. It doesn't.

The problem was more obscure than I guessed, too.

I've attached two. I believe they are equivalent in the way they match,
but I have adjusted highlighting in the later one to be more consistent:
it only highlights the bodies of the directives as comments, not the
directives themselves, which I think is better, and more correct.

The main problem was that the syntax groups were not listed in a couple
of clusters that avoid them being matched where they shouldn't, so an
earlier #if defined(WIN3264) in the file had picked up the 3264 as
starting a region to highlight as included, and it was busy waiting for
the #else to highlight as a comment!

I'll be interested to know if you pick up any more bugs!

Cheers,

Ben.


Ben Schmidt

unread,
Jun 24, 2008, 12:47:34 AM6/24/08
to vim...@googlegroups.com
[Alright, alright; here are the attachments. At the moment I can't
attach files while writing mail, so I keep forgetting!]
c.vim_2.patch
c.vim_3.patch

Dominique Pelle

unread,
Jun 28, 2008, 5:05:23 PM6/28/08
to vim...@googlegroups.com


Ben,

I've been using c.vim_3.patch. It's quite nice in most common
cases. Thanks. I found a case where it fails though. In the test
case below, line with comment "BUG" is in between #if 0...#endif
so it should be highlighted as comment. But with the patch, it is no
longer highlighted as comment. It was highlighted as comment
without the patch. Same bug happens with both patches. I realize
that it's not easy to get it right in all cases.

#if 1
foo(); /* good, not highlighted as comment */
# if 0
foo(); /* BUG: should be highlighted as comment, but is not */
# endif
#else
foo(); /* good, highlighted as comment */
#endif

You can find a screenshot of what I see here:

http://dominique.pelle.free.fr/pic/testcase_bug_if_1.png

You can see (in the bottom green statusline) that what
should normally be a comment where the red cursor is,
is actually in the cCppSkip2 highlight group.

Regards
-- Dominique

Peng Yu

unread,
Jul 12, 2008, 9:11:10 PM7/12/08
to vim_use


On Jun 23, 11:47 pm, Ben Schmidt <mail_ben_schm...@yahoo.com.au>
wrote:
> c.vim_2.patch
> 5KDownload
>
> c.vim_3.patch
> 5KDownload

Would you please attach you latest c.vim as one file? That would be
easier to download.

Thanks,
Peng

Ben Schmidt

unread,
Jul 13, 2008, 6:29:40 AM7/13/08
to vim...@googlegroups.com, dominiq...@gmail.com, Peng...@gmail.com
> Ben,
>
> I've been using c.vim_3.patch. It's quite nice in most common
> cases. Thanks. I found a case where it fails though. In the test
> case below, line with comment "BUG" is in between #if 0...#endif
> so it should be highlighted as comment. But with the patch, it is no
> longer highlighted as comment. It was highlighted as comment
> without the patch. Same bug happens with both patches. I realize
> that it's not easy to get it right in all cases.
>
> #if 1
> foo(); /* good, not highlighted as comment */
> # if 0
> foo(); /* BUG: should be highlighted as comment, but is not */
> # endif
> #else
> foo(); /* good, highlighted as comment */
> #endif
>
> You can find a screenshot of what I see here:
>
> http://dominique.pelle.free.fr/pic/testcase_bug_if_1.png
>
> You can see (in the bottom green statusline) that what
> should normally be a comment where the red cursor is,
> is actually in the cCppSkip2 highlight group.
>
> Regards
> -- Dominique

Didn't see this reply earlier, but noticed it due to the more recent
question about this same issue!

I didn't really allow for nesting in my initial attempt. I thought it
was unlikely to occur. Apparently not!

I've tried doing a more thorough rewrite of the relevant parts of the
syntax file to allow for it, and I think I've succeeded. It seems to
work for all four combinations of two-level nesting, so I don't see why
it won't work for deeper levels. Time will tell.

Likewise, parsing preprocessor directives so fully like this in some
ways is just asking for trouble! Often the logic of preprocessor
directives (if, else, endif) 'overlaps' the logic of underlying C code
(braces). This is awkward at the best of times, but parsing them as
fully as this may break other things, particularly folding, I think. It
may work well, though: it depends on other things in the syntax file and
what's common and not in C code. Time will tell.

If time tells that it works well without breaking things, I suggest we
ask Bram to consider including the patch.

I've attached the patch and resulting file. I use it by putting c.vim in my
~/.vim/syntax directory.

Ben.

c.vim_4.patch
c.vim

Ben Schmidt

unread,
Jul 13, 2008, 11:30:28 AM7/13/08
to vim...@googlegroups.com
> I've tried doing a more thorough rewrite of the relevant parts of the
> syntax file to allow for nesting, and I think I've succeeded. It seems to

> work for all four combinations of two-level nesting, so I don't see why
> it won't work for deeper levels. Time will tell.
>
> Likewise, parsing preprocessor directives so fully like this in some
> ways is just asking for trouble! Often the logic of preprocessor
> directives (if, else, endif) 'overlaps' the logic of underlying C code
> (braces). This is awkward at the best of times, but parsing them as
> fully as this may break other things, particularly folding, I think. It
> may work well, though: it depends on other things in the syntax file and
> what's common and not in C code. Time will tell.
>
> If time tells that it works well without breaking things, I suggest we
> ask Bram to consider including the patch.
>
> I've attached the patch and resulting file. I use it by putting c.vim in my
> ~/.vim/syntax directory.

I forgot to make a few final changes to take care of some more simple cases...
I've remembered now. The revised patch and result is attached.

Ben.


c.vim_5.patch
c.vim

Peng Yu

unread,
Jul 15, 2008, 2:33:46 AM7/15/08
to vim_use


On Jul 13, 10:30 am, Ben Schmidt <mail_ben_schm...@yahoo.com.au>
wrote:
Will this file be updated in the new vim release?

BTW, I'm using google groups. I don't see how to add attachments to
posts. Would you please let me know how you do it?

Thanks,
Peng

Tony Mechelynck

unread,
Jul 15, 2008, 3:08:24 AM7/15/08
to vim...@googlegroups.com

I post to Google Groups from a gmail account which I read by POP: this
allows me to use a dedicated mail/news client (i.e., not a browser) to
post to these lists. When I send to an email with attachment to vim_use,
you see them that way on the list.


Best regards,
Tony.
--
"What's the use of a good quotation if you can't change it?"
-- Dr. Who

Ben Schmidt

unread,
Sep 6, 2008, 7:59:02 PM9/6/08
to vim...@googlegroups.com
In another thread, Peng referred to this thread:

> #elif is not highlighted correctly in vim. I've applied the patch
> posted at the following thread. Can somebody take a look to fix the
> bug.

So I am posting a revised patch here which juggles some patterns to fix
this and another more obscure case or two. It deals with a few more
cases properly now, and hopefully doesn't break anything. Please test!

Ben.

> #include <iostream>
>
> int main() {
> #if 0
> std::cout << 0 << std::endl;
> #elif 0
> std::cout << 1 << std::endl;
> #else
> std::cout << 2 << std::endl;
> #endif
> }

c.vim_6.patch

Ben Schmidt

unread,
Sep 6, 2008, 8:21:03 PM9/6/08
to vim...@googlegroups.com
> So I am posting a revised patch here which juggles some patterns to fix
> this and another more obscure case or two. It deals with a few more
> cases properly now, and hopefully doesn't break anything. Please test!

And here is an already-patched version, for people who find it easier just to drop
the modified version in ~/.vim/syntax like I do.

Smiles,

Ben.


c.vim

Peng Yu

unread,
Sep 6, 2008, 10:42:19 PM9/6/08
to vim_use


On Sep 6, 6:59 pm, Ben Schmidt <mail_ben_schm...@yahoo.com.au> wrote:
> In another thread, Peng referred to this thread:
>
> > #elif is not highlighted correctly in vim. I've applied the patch
> > posted at the following thread. Can somebody take a look to fix the
> > bug.
>
> So I am posting a revised patch here which juggles some patterns to fix
> this and another more obscure case or two. It deals with a few more
> cases properly now, and hopefully doesn't break anything. Please test!

Thank you for fixing it so quickly. It works for the test case that I
have. I'll let you know if I come across other bugs.

Peng

Peng Yu

unread,
Sep 13, 2008, 11:24:43 PM9/13/08
to vim_use
It seems that there is some problem when I view the same file with
more than one splited windows. An example file is posted below.

Suppose the cursor is on the '0' after '#if' (no matter which splited
window the cursor is in). If I press 'r' then '1', the '0' will be
replaced by '1'. But the highlight is only updated in the first
splited window but not in others.

Thanks,
Peng

$ cat main.cc

Ben Schmidt

unread,
Sep 14, 2008, 7:36:07 AM9/14/08
to vim...@googlegroups.com, Bram Moolenaar
> It seems that there is some problem when I view the same file with
> more than one splited windows. An example file is posted below.
>
> Suppose the cursor is on the '0' after '#if' (no matter which splited
> window the cursor is in). If I press 'r' then '1', the '0' will be
> replaced by '1'. But the highlight is only updated in the first
> splited window but not in others.
>
> Thanks,
> Peng
>
> $ cat main.cc
> #include <iostream>
>
> int main() {
> #if 0
> std::cout << 0 << std::endl;
> #elif 0
> std::cout << 1 << std::endl;
> #else
> std::cout << 2 << std::endl;
> #endif
> }

Well, this one's a problem in Vim itself, not in my modification of the syntax
highlighting!

One more for the to do if it isn't there already, I suppose, Bram?

The patch/updated C syntax file that exposes the problem is here, if it helps:

http://groups.google.com/group/vim_use/msg/abe5f007acfee8bd
http://groups.google.com/group/vim_use/msg/307f4bca9fc0b0b7

Ben.

Bram Moolenaar

unread,
Sep 14, 2008, 8:55:45 AM9/14/08
to Ben Schmidt, vim...@googlegroups.com

Ben Schmidt wrote:

One can reproduce it with the standard C highlighting. Edit some C
code, ":split" and delete a ")" so that "{" gets highlighted. The
other window isn't updated.

--
"I can't complain, but sometimes I still do." (Joe Walsh)

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Reply all
Reply to author
Forward
0 new messages