vim-cpp icon indicating copy to clipboard operation
vim-cpp copied to clipboard

Wrong C++ highlighting

Open mattn opened this issue 8 years ago • 14 comments

https://github.com/vim/vim/issues/1005

mattn avatar Aug 28 '16 23:08 mattn

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

mattn avatar Aug 29 '16 00:08 mattn

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

rhysd avatar Sep 01 '16 01:09 rhysd

right

mattn avatar Sep 01 '16 01:09 mattn

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

brammool avatar Nov 17 '16 13:11 brammool

@brammool This should fix it.

https://github.com/vim-jp/vim-cpp/commit/8976dec324bdd2168f642945025a9f061644c4e3

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 avatar Nov 18 '16 00:11 mattn

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

mattn avatar Nov 18 '16 00:11 mattn

@brammool Ah, I understanded it just now. https://github.com/vim/vim/issues/1257#issuecomment-261250723

mattn avatar Nov 18 '16 00:11 mattn

I rebased this repository. And reverted https://github.com/vim-jp/vim-cpp/commit/8976dec324bdd2168f642945025a9f061644c4e3

So this issue still are remaining.

mattn avatar Apr 26 '17 07:04 mattn

@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.

ghost avatar May 14 '17 21:05 ghost

Robot wrote:

@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.

Vim doesn't see the #ifdef as preproc, thus I would think that is OK. Highlighting it as an error doesn't seem useful. It would cause a lot of flickering while typing.

-- ERIC IDLE PLAYED: THE DEAD COLLECTOR, MR BINT (A VILLAGE NE'ER-DO -WELL VERY KEEN ON BURNING WITCHES), SIR ROBIN, THE GUARD WHO DOESN'T HICOUGH BUT TRIES TO GET THINGS STRAIGHT, CONCORDE (SIR LAUNCELOT'S TRUSTY STEED), ROGER THE SHRUBBER (A SHRUBBER), BROTHER MAYNARD "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \
\\ an exciting new programming language -- http://www.Zimbu.org /// \\ help me help AIDS victims -- http://ICCF-Holland.org ///

brammool avatar May 15 '17 07:05 brammool

@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.

ghost avatar May 15 '17 15:05 ghost

@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.

I'm quite sure older C standards do not allow this. I would never write it like this anyway.

Currently we recognize the # at the start of the line. Allowing a comment before it isn't that easy. Properly detecting /* */ comments is difficult anyway.

I think we can just leave this out.

-- (letter from Mark to Mike, about the film's probable certificate) For an 'A' we would have to: Lose as many shits as possible; Take Jesus Christ out, if possible; Loose "I fart in your general direction"; Lose "the oral sex"; Lose "oh, fuck off"; Lose "We make castanets out of your testicles" "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \
\\ an exciting new programming language -- http://www.Zimbu.org /// \\ help me help AIDS victims -- http://ICCF-Holland.org ///

brammool avatar May 16 '17 06:05 brammool

@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++.

ghost avatar May 17 '17 16:05 ghost

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

mattn avatar May 17 '17 23:05 mattn