vim-patch:5a1124e: runtime(c): compound literal braces are highlighted as errors

Problem: Braces in C compound literals and initializers inside parentheses
         and brackets are highlighted as errors.

Solution: Recognize those initializer blocks while preserving syntax recovery
          for malformed parentheses.

fixes:  vim/vim#18709
closes: vim/vim#20842

5a1124e4f5

Co-authored-by: Bogdan Barbu <l4b.bogdan.barbu@gmail.com>
This commit is contained in:
zeertzjq
2026-08-05 07:02:19 +08:00
parent e795115351
commit 743a8d448c

View File

@@ -1,7 +1,7 @@
" Vim syntax file
" Language: C
" Maintainer: The Vim Project <https://github.com/vim/vim>
" Last Change: 2026 Jun 01
" Last Change: 2026 Jul 25
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
" Quit when a (custom) syntax file was already loaded
@@ -138,7 +138,7 @@ endif
" This should be before cErrInParen to avoid problems with #define ({ xxx })
if exists("c_curly_error")
syn match cCurlyError "}"
syn region cBlock start="{" end="}" contains=ALLBUT,cBadBlock,cCurlyError,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBracket,@cStringGroup,@Spell fold
syn region cBlock start="{" end="}" contains=ALLBUT,cBadBlock,cCurlyError,cInitBlock,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBracket,@cStringGroup,@Spell fold
else
syn region cBlock start="{" end="}" transparent fold
endif
@@ -146,7 +146,7 @@ endif
" Catch errors caused by wrong parenthesis and brackets.
" Also accept <% for {, %> for }, <: for [ and :> for ] (C99)
" But avoid matching <::.
syn cluster cParenGroup contains=cParenError,cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserLabel,cBitField,cOctalZero,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom
syn cluster cParenGroup contains=cParenError,cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserLabel,cBitField,cOctalZero,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom,cBadParenBlock
if exists("c_no_curly_error")
if s:in_cpp_family && !exists("cpp_no_cpp11")
syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,@cStringGroup,@Spell
@@ -198,8 +198,15 @@ endif
if s:ft ==# 'c' || exists("cpp_no_cpp11")
syn region cBadBlock keepend start="{" end="}" contained containedin=cParen,cBracket,cBadBlock transparent fold
if !exists("c_no_curly_error") && !exists("c_no_bracket_error")
" Do not mistake an unmatched ')' followed by a block for a compound literal.
syn region cBadParenBlock keepend transparent start=')\_s*\ze\%({\|<%\)' matchgroup=cErrInBracket end='}\|%>' contained containedin=cBracket,cBadBlock contains=ALLBUT,cBlock,cBadBlock,cInitBlock,@cParenGroup,cErrInParen,cCppParen,cCppBracket,@cStringGroup,@Spell
endif
endif
" Compound literals and initializers may appear inside parentheses or brackets.
syn region cInitBlock transparent matchgroup=cInitBlock start='\%([)=]\_s*\)\@<=\%({\|<%\)' end='}\|%>' contained containedin=cParen,cBracket,cBadBlock contains=ALLBUT,cBlock,cCurlyError,@cParenGroup,cErrInParen,cCppParen,cErrInBracket,cCppBracket,@cStringGroup,@Spell,cInitBlock fold
"integer number, or floating point number without a dot and with "f".
syn case ignore
syn match cNumbers display transparent "\<\d\|\.\d" contains=cNumber,cFloat,cOctalError,cOctal