The bug is not complicated, but it appears in all Vims, such as gVim and Vim (Windows/Linux).
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
Old C standards don't allow it. Does someone know what was the first when a comment before a preprocessor directive was allowed?
This is also not working:
#include\
<bits/stdc++.h>
This editor of ideone handles preprocessors quite good.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub,
I'll look into it vim-jp/vim-cpp#41
This could be fixed with a dedicated intermediate block comment but it hardly seems worth the effort. I can't easily find any examples of this in the wild.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I had a look at this again. The cause is that every preprocessor anchor in the C syntax file uses ^\s*\zs\%(%:\|#\), which only allows whitespace before the #, so a block comment in front of the directive (/**/ #include) isn't recognized. Comments are folded to a space in translation phase 3 (before preprocessing), so /**/ #include is actually valid in every C/C++ standard, which answers the original question about "since which standard".
It can be done. The fix is to allow a run of leading block comments in the anchor and drop the \zs: the \zs makes the effective match start at the #, so it loses to the leftmost cComment region; starting the match at column 1 lets the (later defined) directive win, and listing cComment in contains keeps the leading comment highlighted as a comment.
diff --git a/runtime/syntax/c.vim b/runtime/syntax/c.vim index 64bcd3e368..655486b3d3 100644 --- a/runtime/syntax/c.vim +++ b/runtime/syntax/c.vim @@ -458,11 +458,11 @@ endif " Accept %: for # (C99) 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 if !exists("c_no_c23") - syn region cPreCondit start="^\s*\zs\%(%:\|#\)\s*\%(el\)\=\%(if\|ifdef\|ifndef\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError + syn region cPreCondit start="^\s*\%(/\*.\{-}\*/\s*\)*\%(%:\|#\)\s*\%(el\)\=\%(if\|ifdef\|ifndef\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError else - 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 region cPreCondit start="^\s*\%(/\*.\{-}\*/\s*\)*\%(%:\|#\)\s*\%(if\|ifdef\|ifndef\|elif\)\>" skip="\\$" end="$" keepend contains=cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError endif -syn match cPreConditMatch display "^\s*\zs\%(%:\|#\)\s*\%(else\|endif\)\>" +syn match cPreConditMatch display "^\s*\%(/\*.\{-}\*/\s*\)*\%(%:\|#\)\s*\%(else\|endif\)\>" contains=cComment 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 @@ -510,15 +510,15 @@ if !exists("c_no_if0") endif syn region cIncluded display contained start=+"+ skip=+\\\\\|\\"+ end=+"+ syn match cIncluded display contained "<[^>]*>" -syn match cInclude display "^\s*\zs\%(%:\|#\)\s*include\>\s*["<]" contains=cIncluded +syn match cInclude display "^\s*\%(/\*.\{-}\*/\s*\)*\%(%:\|#\)\s*include\>\s*["<]" contains=cIncluded,cComment if !exists("c_no_c23") && !s:in_cpp_family - syn region cInclude start="^\s*\zs\%(%:\|#\)\s*embed\>" skip="\\$" end="$" keepend contains=cEmbed,cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError + syn region cInclude start="^\s*\%(/\*.\{-}\*/\s*\)*\%(%:\|#\)\s*embed\>" skip="\\$" end="$" keepend contains=cEmbed,cComment,cCommentL,cCppString,cCharacter,cCppParen,cParenError,cNumbers,cCommentError,cSpaceError syn match cEmbed contained "\%(%:\|#\)\s*embed\>" nextgroup=cIncluded skipwhite transparent syn cluster cPreProcGroup add=cEmbed endif "syn match cLineSkip "\\$" -syn region cDefine start="^\s*\zs\%(%:\|#\)\s*\%(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell -syn region cPreProc start="^\s*\zs\%(%:\|#\)\s*\%(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell +syn region cDefine start="^\s*\%(/\*.\{-}\*/\s*\)*\%(%:\|#\)\s*\%(define\|undef\)\>" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell +syn region cPreProc start="^\s*\%(/\*.\{-}\*/\s*\)*\%(%:\|#\)\s*\%(pragma\>\|line\>\|warning\>\|warn\>\|error\>\)" skip="\\$" end="$" keepend contains=ALLBUT,@cPreProcGroup,@Spell " Optional embedded Autodoc parsing if exists("c_autodoc")
This handles /**/ #include, several stacked comments before the #, and the %: digraph form, while strings, line comments and a mid-line # are still left alone. It does not cover a comment spanning multiple lines before the directive, nor a comment placed between # and the keyword.
The trade-off worth noting is that the extra \%(/\*.\{-}\*/\s*\)* is attempted at the start of every line in every C/C++ file, so it adds a little cost to the common case for a construct that seems quite rare in practice. Posting the analysis and patch here in case it's useful.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()
It would be better to use a line-start anchored optional chain of comments using nextgroup that terminated at preprocessor directives. This would allow multiline comments to precede the directive and would prevent unwanted background highlighting artifacts.
However, from a quick inspection, it appears that preprocessor directives are the only line-start anchored syntax groups in the file. Why don't we just drop that anchoring? The # isn't valid anywhere else at top level.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
Triage notifications, keep track of coding agent tasks and review pull requests on the go with GitHub Mobile for iOS and Android. Download it today!
You are receiving this because you are subscribed to this thread.![]()