runtime(tex): improve syntax highlighting

this change includes the following changes:
- a macro option must be #1–#9
- add \providecommand
- add starred versions of \newcommand, \newenvironment, and their
  variants
- add number of arguments to \(re)newenvironment

Signed-off-by: Eisuke Kawashima <e-kwsm@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/runtime/syntax/tex.vim b/runtime/syntax/tex.vim
index 4f35bba..109ce61 100644
--- a/runtime/syntax/tex.vim
+++ b/runtime/syntax/tex.vim
@@ -5,6 +5,8 @@
 " Last Change:	Apr 22, 2022
 "   2024 Feb 19 by Vim Project: announce adoption
 "   2025 Jan 18 by Vim Project: add texEmphStyle to texMatchGroup, #16228
+"   2025 Feb 08 by Vim Project: improve macro option, \providecommand, 
+"                               \newcommand and \newenvironment #16543
 " Version:	121
 " Former URL:	http://www.drchip.org/astronaut/vim/index.html#SYNTAX_TEX
 "
@@ -167,7 +169,7 @@
 if !s:tex_no_error
  syn cluster texCmdGroup		add=texMathError
 endif
-syn cluster texEnvGroup			contains=texMatcher,texMathDelim,texSpecialChar,texStatement
+syn cluster texEnvGroup			contains=texDefParm,texMatcher,texMathDelim,texSpecialChar,texStatement
 syn cluster texFoldGroup		contains=texAccent,texBadMath,texComment,texDefCmd,texDelimiter,texDocType,texInput,texInputFile,texLength,texLigature,texMatcher,texMathZoneV,texMathZoneW,texMathZoneX,texMathZoneY,texMathZoneZ,texNewCmd,texNewEnv,texOnlyMath,texOption,texParen,texRefZone,texSection,texBeginEnd,texSectionZone,texSpaceCode,texSpecialChar,texStatement,texString,texTypeSize,texTypeStyle,texZone,@texMathZones,texTitle,texAbstract,texBoldStyle,texItalStyle,texEmphStyle,texNoSpell
 syn cluster texBoldGroup		contains=texAccent,texBadMath,texComment,texDefCmd,texDelimiter,texDocType,texInput,texInputFile,texLength,texLigature,texMathZoneV,texMathZoneW,texMathZoneX,texMathZoneY,texMathZoneZ,texNewCmd,texNewEnv,texOnlyMath,texOption,texParen,texRefZone,texSection,texBeginEnd,texSectionZone,texSpaceCode,texSpecialChar,texStatement,texString,texTypeSize,texTypeStyle,texZone,@texMathZones,texTitle,texAbstract,texBoldStyle,texBoldItalStyle,texNoSpell
 syn cluster texItalGroup		contains=texAccent,texBadMath,texComment,texDefCmd,texDelimiter,texDocType,texInput,texInputFile,texLength,texLigature,texMathZoneV,texMathZoneW,texMathZoneX,texMathZoneY,texMathZoneZ,texNewCmd,texNewEnv,texOnlyMath,texOption,texParen,texRefZone,texSection,texBeginEnd,texSectionZone,texSpaceCode,texSpecialChar,texStatement,texString,texTypeSize,texTypeStyle,texZone,@texMathZones,texTitle,texAbstract,texItalStyle,texEmphStyle,texItalBoldStyle,texNoSpell
@@ -287,7 +289,7 @@
 syn match texDelimiter		"\\\\"
 
 " Tex/Latex Options: {{{1
-syn match texOption		"[^\\]\zs#\d\+\|^#\d\+"
+syn match texOption		"[^\\]\zs#[1-9]\|^#[1-9]"
 
 " texAccent (tnx to Karim Belabas) avoids annoying highlighting for accents: {{{1
 if b:tex_stylish
@@ -669,16 +671,46 @@
 endif
 syn match  texRefZone		'\\cite\%([tp]\*\=\)\=\>' nextgroup=texRefOption,texCite
 
-" Handle (re)newcommand, (re)newenvironment : {{{1
-syn match  texNewCmd				"\\\%(re\)\=newcommand\>"		nextgroup=texCmdName skipwhite skipnl
+" Handle (re)newcommand, providecommand, (re)newenvironment : {{{1
+" EXAMPLE:
+"
+" The followings are valid (ignoring error due to redefinition):
+"
+" \newcommand{\foo}{body}
+" \newcommand{\foo}[1]{#1}
+" \newcommand{\foo}[1][def]{#1}
+"
+" The followings are ill-formed:
+"
+" \newcommand{\foo}{#1}		! Illegal parameter number in definition of \foo.
+" \newcommand{\foo}[x]{…}	! Missing number, treated as zero.
+" \newcommand{\foo}[10]{…}	! You already have nine parameters.
+syn match  texNewCmd				"\\\%(\%(re\)\=new\|provide\)command\>\*\?"	nextgroup=texCmdName skipwhite skipnl
 if s:tex_fast =~# 'V'
   syn region texCmdName contained matchgroup=texDelimiter start="{"rs=s+1  end="}"		nextgroup=texCmdArgs,texCmdBody skipwhite skipnl
-  syn region texCmdArgs contained matchgroup=texDelimiter start="\["rs=s+1 end="]"		nextgroup=texCmdBody skipwhite skipnl
+  syn region texCmdArgs contained matchgroup=texDelimiter start="\["rs=s+1 end="]"		nextgroup=texCmdDefaultPar,texCmdBody skipwhite skipnl
+  syn region texCmdDefaultPar contained matchgroup=texDelimiter start="\["rs=s+1 end="]"	nextgroup=texCmdBody skipwhite skipnl
   syn region texCmdBody contained matchgroup=texDelimiter start="{"rs=s+1 skip="\\\\\|\\[{}]"	matchgroup=texDelimiter end="}" contains=@texCmdGroup
 endif
-syn match  texNewEnv				"\\\%(re\)\=newenvironment\>"		nextgroup=texEnvName skipwhite skipnl
+" EXAMPLE:
+"
+" The followings are valid (ignoring error due to redefinition):
+"
+" \newenvironment{baz}{beg}{end}
+" \newenvironment{baz}[1]{beg #1}{end}
+" \newenvironment{baz}[1][default]{beg #1}{end}
+"
+" The followings are invalid:
+"
+" \newenvironment{baz}{#1}{…}		! Illegal parameter number in definition of \baz.
+" \newenvironment{baz}[x]{…}{…}		! Missing number, treated as zero.
+" \newenvironment{baz}[10]{…}{…}	! You already have nine parameters.
+" \newenvironment{baz}[1]{…}{#1}	! Illegal parameter number in definition of \endbaz.
+syn match  texNewEnv				"\\\%(re\)\=newenvironment\>\*\?"		nextgroup=texEnvName skipwhite skipnl
 if s:tex_fast =~# 'V'
-  syn region texEnvName contained matchgroup=texDelimiter start="{"rs=s+1  end="}"		nextgroup=texEnvBgn skipwhite skipnl
+  syn region texEnvName contained matchgroup=texDelimiter start="{"rs=s+1  end="}"		nextgroup=texEnvArgs,texEnvBgn skipwhite skipnl
+  syn region texEnvArgs contained matchgroup=texDelimiter start="\["rs=s+1 end="]"		nextgroup=texEnvDefaultPar,texEnvBgn skipwhite skipnl
+  syn region texEnvDefaultPar contained matchgroup=texDelimiter start="\["rs=s+1 end="]"	nextgroup=texEnvBgn skipwhite skipnl
   syn region texEnvBgn  contained matchgroup=texDelimiter start="{"rs=s+1  end="}"		nextgroup=texEnvEnd skipwhite skipnl contains=@texEnvGroup
   syn region texEnvEnd  contained matchgroup=texDelimiter start="{"rs=s+1  end="}"		skipwhite skipnl contains=@texEnvGroup
 endif
@@ -693,7 +725,7 @@
   syn match texDefName contained		"\\\A"					nextgroup=texDefParms,texCmdBody skipwhite skipnl
 endif
 syn match texDefParms  contained		"#[^{]*"	contains=texDefParm	nextgroup=texCmdBody skipwhite skipnl
-syn match  texDefParm  contained		"#\d\+"
+syn match  texDefParm  contained		"#[1-9]"
 
 " TeX Lengths: {{{1
 syn match  texLength		"\<\d\+\([.,]\d\+\)\=\s*\(true\)\=\s*\(bp\|cc\|cm\|dd\|em\|ex\|in\|mm\|pc\|pt\|sp\)\>"
@@ -1325,6 +1357,7 @@
   hi def link texDef		Statement
   hi def link texDefParm	Special
   hi def link texDelimiter	Delimiter
+  hi def link texEnvArgs	Number
   hi def link texInput		Special
   hi def link texInputFile	Special
   hi def link texLength		Number