为vim语法区域找到正确的结束序列

时间:2018-11-01 13:00:48

标签: vim syntax-highlighting vim-syntax-highlighting

我有一个语法文件,其中:

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

当我在文件中使用它时,我得到以下信息(在matlab end中有多种用途。它可以结束loop / if / switch语句或用作“数组中的最后一个条目”( -1(在某些其他语言中为-1),因此此处*end*将用于标记突出显示的单词,请注意,*符号不在程序中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

1 个答案:

答案 0 :(得分:0)

这不能仅用于单个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\>"

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