首页 > 解决方案 > 找到 vim 语法区域高亮的正确结束顺序

问题描述

我有一个语法文件:

syn region matlabLoop
            \ matchgroup=matlabRepeat
            \ start="\<for\>"
            \ end="\<end\>"
            \ transparent
            \ fold
hi def link matlabRepeat        Repeat

当我在文件中使用它时,我得到以下信息(在 matlabend中有多种用途。它可以结束循环/if/switch 语句或用作“数组中的最后一个条目”(在某些其他语言中为-1),所以这里*end*将用于标记突出显示的单词,注意这些*符号不在程序中 a end)

a =  rand(1,3); % something like [0.0123145 1 0.545341]
for i = 1:numel(a)
    if numel(a(i:*end*)) ==numel(a)
        fprintf('i is probably 1')
    *end*
end

标签: vimsyntax-highlightingvim-syntax-highlighting

解决方案


这不能仅适用于该单个matlabLoop区域。您还需要完整解析包含的if...end结构;即整个条件块的另一个语法定义。或者您正在扩展现有的$VIMRUNTIME/syntax/matlab.vim语法脚本(带有折叠)?以下假设(但该解决方案也适用于独立的语法定义)。

该语法脚本为 定义了一个简单的关键字end,因此它将匹配任何地方。如果你想i:end从匹配中排除,你需要使匹配更精确,例如使用否定的后向断言(“不能以冒号开头” - 我不知道 Matlab 语法,所以这只是关于技术,而不是完全正确的解决方案)。

这是语法脚本的原始定义:

syn keyword matlabConditional       else elseif end if otherwise

为了删除end,我们必须清除它并重新定义:

syntax clear matlabConditional
syntax keyword matlabConditional else elseif if otherwise

现在我们可以指定更精确的规范,使用:help /\@<!前面没有冒号的断言,并\<...\>保持原始定义的关键字边界:

syntax match matlabConditional ":\@<!\<end\>"

如果您认为此扩展通常对语法有用,请向语法脚本作者提交补丁;他的联系信息在该文件的标题中。


推荐阅读