vim-jp/vim-cpp

Wrong C++ highlighting

mattn opened this issue · 14 comments

mattn commented

I'm not sure, but removing ^ fixes this syntax.

diff --git a/syntax/c.vim b/syntax/c.vim
index 85042e4..b7dedb3 100644
--- a/syntax/c.vim
+++ b/syntax/c.vim
@@ -388,11 +388,11 @@ if !exists("c_no_if0")
 endif
 syn region cIncluded   display contained start=+"+ skip=+\\\\\|\\"+ end=+"+
 syn match  cIncluded   display contained "<[^>]*>"
-syn match  cInclude    display "^\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded
+syn match  cInclude    display "\s*\(%:\|#\)\s*include\>\s*["<]" contains=cIncluded
 "syn match cLineSkip   "\\$"
 syn cluster    cPreProcGroup   contains=cPreCondit,cIncluded,cInclude,cDefine,cErrInParen,cErrInBracket,cUserLabel,cSpecial,cOctalZero,cCppOutWrapper,cCppInWrapper,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cString,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cParen,cBracket,cMulti,cBadBlock
-syn region cDefine     start="^\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
-syn region cPreProc    start="^\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
+syn region cDefine     start="\s*\(%:\|#\)\s*\(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell
+syn region cPreProc    start="\s*\(%:\|#\)\s*\(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell

 " Highlight User Labels
 syn cluster    cMultiGroup contains=cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserCont,cUserLabel,cBitField,cOctalZero,cCppOutWrapper,cCppInWrapper,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cCppParen,cCppBracket,cCppString
rhysd commented

I think \s* at the head of pattern should be removed as well.

mattn commented

right

Since when is putting a comment before #if valid C?

mattn commented

@brammool This should fix it.

8976dec

diff --git a/syntax/c.vim b/syntax/c.vim
index cc99f67..82148e7 100644
--- a/syntax/c.vim
+++ b/syntax/c.vim
@@ -358,8 +358,8 @@ if !exists("c_no_c99") " ISO C99
 endif

 " Accept %: for # (C99)
-syn region cPreCondit  start="^\s*\zs\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError
-syn match  cPreConditMatch display "^\s*\zs\(%:\|#\)\s*\(else\|endif\)\>"
+syn region cPreCondit  start="\s*\zs\(%:\|#\)\s*\(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError
+syn match  cPreConditMatch display "\s*\zs\(%:\|#\)\s*\(else\|endif\)\>"
 if !exists("c_no_if0")
   syn cluster  cCppOutInGroup  contains=cCppInIf,cCppInElse,cCppInElse2,cCppOutIf,cCppOutIf2,cCppOutElse,cCppInSkip,cCppOutSkip
   syn region   cCppOutWrapper  start="^\s*\zs\(%:\|#\)\s*if\s\+0\+\s*\($\|//\|/\*\|&\)" end=".\@=\|$" contains=cCppOutIf,cCppOutElse,@NoSpell fold
mattn commented

@brammool or, do you ask me why need this change?

mattn commented

@brammool Ah, I understanded it just now. vim/vim#1257 (comment)

mattn commented

I rebased this repository. And reverted 8976dec

So this issue still are remaining.

@brammool: This was likely always valid C/C++, you can check yourself with gcc or g++. The requirement seems to be the line needs to be devoid of statements before the preprocessor directive.

(void)0; #ifdef POSIX
#endif
error: stray # in program
(void)0; #ifdef POSIX
         ^

and an ensuing error about the mismatched #endif.

@brammool: That was a counterexample, the bug was about this case:

/**/ #ifdef POSIX
#endif

Which isn't highlighted properly by Vim (or GitHub), despite being valid C/C++. There may be any amount of whitespace before a preprocessor directive on a line and comments seem to count as part of this whitespace. This will compile whereas the other example does not.

@brammool: Okay, but C89 comments are properly detected already. It seems like the fix involves relaxing the requirement that the # start the line, and the directive text follow immediately after it.

This one is more of a syntactic oddity but there are other issues open (#43, #49) about syntax highlighting deficiencies that are related to this one. I don't understand Vim enough to fix them, but I can vouch that most of what has been reported are actual things found in many projects.

But that's kind of besides the point - the standard allows such syntax, and the highlighter should, ideally, support it. I understand there will be limitations but this isn't yet trying to parse and understand C/C++.

mattn commented

To fix this, it need the regexp pattern enough to be confusable. And it will take heavy load.