2

Is it possible to get VIM to recognize syntax changes inside a particular region? Specifically, I am trying to get LaTeX3's \ExplSyntaxOn...\ExplSyntaxOff syntax to be highlighted, but only inside a particular region. The \makeatletter...\makeatother syntax region would be similar.

Here is an example file to highlight:

\documentclass{article}

\ExplSyntaxOn
\tl_new:N \l_@@_local_var_tl
\tl_new:N \g_@@_global_var_tl
\tl_if_eq:nnTF {\l_@@_local_var_tl} {\g_@@_global_var_tl}
{ Hello, world! }
{ Goodbye, world! }
\ExplSyntaxOff

\begin{document}
\ExplSyntaxOn
\tl_new:N \l_@@_local_var_tl
\tl_new:N \g_@@_global_var_tl
\tl_if_eq:nnTF {\l_@@_local_var_tl} {\g_@@_global_var_tl}
{ Hello, world! }
{ Goodbye, world! }
\ExplSyntaxOff
\end{document}

I tried this so far (in ~/.vim/after/syntax/tex.vim):

syntax region texLaTeX3Zone matchgroup=texStatement start="\\ExplSyntaxOn\>"
  \   end="\\ExplSyntaxOff\>" skip="[^\\]%.*\\ExplSyntaxOff" transparent
  \ keepend

syntax match texLaTeX3DefCmd "\\[a-zA-Z_:@]\+" nextgroup=texDefParms,texCmdBody
  \   skipwhite skipnl contained containedin=texLaTeX3Zone
highlight link texLaTeX3DefCmd texStatement

However, anything that is inside braces (which is region texCmdBody) or after \begin{document} (which is region texDocZone), or any other region for that matter, doesn't get highlighted properly.

It doesn't work to leave contained off, as that would make it match everywhere, even outside the region, and it doesn't work to use containedin=ALL, because then it highlights it in other regions that are not contained within texLaTeX3Zone.

Short of making the new highlighting part of every region in the document---I only want it between \ExplSyntaxOn and \ExplSyntaxOff---is there a way to do this?

1 Answer 1

0

I finally was inspired to try including TeX syntax inside another TeX region, which created an infinite loop, but that idea resulted in something that actually did work:

syntax cluster TeXsyntax contains=@texBoldGroup,@texChapterGroup,@texCmdGroup,
\   @texCommentGroup,@texDocGroup,@texEnvGroup,@texFoldGroup,@texItalGroup,
\   @texMatchGroup,@texMatchNMGroup,@texMathMatchGroup,
\   @texMathZoneGroup,@texMathZones,@texParaGroup,@texPartGroup,
\   @texPreambleMatchGroup,@texRefGroup,@texSectionGroup,
\   @texSubSectionGroup,@texSubSubSectionGroup
" @texMathDelimGroup cannot be in there; it makes all text following _ an error
if b:tex_stylish
  syntax cluster TeXsyntax add=@texStyleGroup
endif

" Fix \makeatother...\makeatletter regions
syntax region texMakeAtLetter start='\\makeatletter\>'
\   end='\\makeatother\>' end='%stopzone\>' skip='^\s*%.*\\makeatother' keepend
\   contains=@TeXsyntax
syntax match texAtStatement contained
\   containedin=texMakeAtLetter '\\[a-zA-Z@]\+\*\=' contains=NONE
highlight link texAtStatement texStatement

" Fix \ExplSyntaxOn...\ExplSyntaxOff regions
syntax region texLaTeX3Zone matchgroup=texStatement start="\\ExplSyntaxOn\>"
  \   end="\\ExplSyntaxOff\>" skip="[^\\]%.*\\ExplSyntaxOff"
  \   keepend contains=@TeXsyntax,texLateX3Statement
syntax region texLaTeX3Zone matchgroup=texStatement start="\\ExplSyntaxOn\>"
  \   end="\\ExplSyntaxOff\>" skip="[^\\]%.*\\ExplSyntaxOff"
  \   keepend contains=@TeXsyntax,texLateX3Statement
  \   contained containedin=texDocZone

if b:tex_stylish
  syntax match texLaTeX3Statement "\\[a-zA-Z_:@]\+"
    \   skipwhite skipnl contained containedin=texLaTeX3Zone contains=NONE
else
  syntax match texLaTeX3Statement "\\[a-zA-Z_:]\+"
    \   skipwhite skipnl contained containedin=texLaTeX3Zone contains=NONE
endif
highlight link texLaTeX3Statement texStatement

This implementation does not allow @ inside \ExplSyntaxOn...\ExplSyntaxOff unless b:tex_stylish is set to true, but since the only TeX expl3 commands that include @ are inside .dtx files (for which b:tex_stylish is set to true by default), that should not be a problem.

Edit: this is an incomplete (read: buggy) block of code. Some issue include disruption of the section/subsection/etc. highlighting in documentation after \ExplSyntaxOn is issued. I will keep thinking about it.

4
  • You should be able to just uncheck the box if you want to unaccept your answer. It may be time gated though since accepting shouldn't just be done on a whim.
    – Dom
    Commented Jul 13 at 4:06
  • @Dom It says "User has already voted this way. Undo the vote, or change the vote to continue" every time I try to un-check it.
    – karlh
    Commented Jul 14 at 0:49
  • Looks like a bug: meta.stackexchange.com/questions/401366/…. you may be able to unaccept after the 48 hour period.
    – Dom
    Commented Jul 14 at 15:24
  • @Dom it worked this time---thanks!
    – karlh
    Commented Jul 16 at 6:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.