使用Vim的syn-include和syn-region嵌入语法高亮时遇到问题

18 投票
2 回答
3002 浏览
提问于 2025-04-16 12:53

我想让Vim对所有以.Rtex结尾的文件进行语法高亮,具体要求如下:

  • 所有顶层文本都要高亮显示为TeX
  • 例外情况:任何被\begin{python}...\end{python}包裹的文本要高亮显示为Python

我能单独实现这两个要求,但无法同时实现。我觉得TeX的高亮可能覆盖了我想要的Python高亮,或者让它无法生效,我现在卡在这里,想搞清楚原因。

第一步:编辑.vimrc文件,让.Rtex文件的类型设置为rtex

  au BufRead *.Rtex setf rtex

第二步:创建~/.vim/syntax/rtex.vim文件。这个文件的内容将决定如何高亮.Rtex文件。

第三步:启用一般的顶层TeX高亮,让rtex.vim看起来像这样:

runtime! syntax/tex.vim

现在如果我打开一个.Rtex文件,整个文件都被高亮为TeX,包括\begin{python}...\end{python}中的文本,这正是我预期的效果。

第四步:按照Vim的:help syn-include中的说明,加入Python高亮,并应用到所有被\begin{python}\end{python}包围的区域。我的rtex.vim文件现在看起来像这样:

runtime! syntax/tex.vim
unlet! b:current_syntax
syntax include @Python syntax/python.vim
syntax region pythonCode start="\\begin{python}" end="\\end{python}" contains=@Python

unlet! b:current_syntax这个命令是为了强制执行python.vim语法文件,即使已经有其他语法(TeX)在运行。

问题:现在如果我打开一个.Rtex文件,整个文件仍然只被高亮为TeX。\begin{python}...\end{python}区域似乎没有任何效果。

实验:如果我去掉或注释掉runtime!命令,我确实能在\begin{python}...\end{python}区域内得到Python高亮,正如我所希望的那样,但当然文档的其他部分就没有TeX高亮了。因此我得出结论,TeX高亮似乎是导致Python区域无法生效的原因。

有没有Vim高手能给我一些建议?我现在很困惑。我查阅了好几页相关的内容和StackOverflow的问题,但到目前为止都没有找到解决办法:

2 个回答

0

我不知道这是否有帮助,但我在使用Rnw文件时,有一个小技巧可以同时利用tex和rnoweb的功能,方法如下:

 au BufEnter *.Rnw set filetype=tex | set filetype=rnoweb 

你觉得改编一下这个方法能在你的情况下用得上吗?

20

经过一番对手册的研究和大量的尝试与错误,我终于自己解决了这个问题(这让我感到既尴尬又欣慰),现在我把这个经验记录下来,以便以后的人参考。

简单来说,我认为问题出在python高亮没有生效,因为pythonCode区域被包含在tex.vim定义的某个区域或高亮组里,所以它并不是顶层的。解决办法是要同时include(而不仅仅是runtimetex.vim,给它起个名字,比如@TeX,然后在我的python区域定义中添加containedin=@TeX。所以现在syntax/rtex.vim看起来是这样的:

let b:current_syntax = ''
unlet b:current_syntax
runtime! syntax/tex.vim

let b:current_syntax = ''
unlet b:current_syntax
syntax include @TeX syntax/tex.vim

let b:current_syntax = ''
unlet b:current_syntax
syntax include @Python syntax/python.vim
syntax region pythonCode matchgroup=Snip start="\\begin{python}" end="\\end{python}" containedin=@TeX contains=@Python

hi link Snip SpecialComment
let b:current_syntax = 'rtex'

这样就可以了!我不太确定那些unlet b:current_syntax命令是否都是绝对必要的。我还给python区域的分隔符加了一个匹配组(Snip),这样它们也能被高亮显示(用SpecialComment颜色),而不是像默认那样只是 plain,因为它们不再被认为是TeX的一部分。

现在,为不同的语言添加更多的高亮区域变得很简单(例如,\begin{Scode}...\end{Scode}),这对学习文档编程非常有帮助——这也是我最初提问的动机。

编辑:这里有一张截图,展示了在TeX文档中如何嵌入Python和R代码:

截图:Python和R嵌入在TeX中

撰写回答