vim sed嵌入式语法突出显示

时间:2018-10-30 10:23:47

标签: vim sed syntax

我无法获得sed嵌入式语法高级工作。

我搜索了一下,没有发现专门针对sed的。

这就是我最后得到的:

if exists("b:current_syntax")                                                                                                                                                                                                                                             
    unlet b:current_syntax                                                                                                                                                                                                                                                  
endif                                                                                                                                                                                                                                                                     
syntax include @sed syntax/sed.vim                                                                                                                                                                                                                                        
syntax region sedEmbed start=+\<sed\>+ end=+'+ contains=@sed

但是没有效果。 怎么了?

1 个答案:

答案 0 :(得分:1)

您已经关闭。一个问题是start=end=模式默认包含在区域中。 sed语法被那些混淆了。也就是说,它已经将sed解释为s///命令。

可以用:help :syn-pattern-offset解决此问题。粗略地讲,您让(语法包括)匹配仅在sed(区域结束匹配)+ 1个空格+起始单引号(给出ms=e+1)之后开始:

syntax region sedEmbed start=+\<sed\>+ms=e+3 end=+'+ contains=@sed

但是我宁愿更改起始正则表达式,并在匹配项中包含起始单引号,在两者之间处理任意数量的空格(TODO:如果还接受-n-e之类的sed参数,需要)。同样,需要将结束匹配设置为在结束区域模式之前:

syntax region sedEmbed start="\<sed\s\+'"ms=e+1 end="'"me=s-1 contains=@sed

这样,我可以在缓冲区中突出显示sed 's/foo/bar/g'之类的东西。

与基本语法集成

正如您提到的那样,您看到“没有效果”(而不是混乱的突出显示),我怀疑您实际上是在具有预先存在的语法(可能为sh)的缓冲区中运行此语法扩展。这会导致其他问题,因为原始语法元素会使您的覆盖区域模糊,从而使其不匹配。

要解决此问题,您需要找出导致突出显示的原始基本语法组。 :syn list显示所有活动的组,但是安装SyntaxAttr.vim - Show syntax highlighting attributes of character under cursor插件更容易。 (我维持着extended fork。)

对我来说,以下方法可以工作,但是会稍微破坏原始的shell语法:

setfiletype sh
if exists("b:current_syntax")                                                                                                                                                                                                                                             
    unlet b:current_syntax                                                                                                                                                                                                                                                  
endif                                                                                                                                                                                                                                                                     

" Remove sh.vim syntax items that are "in the way".
syn clear kshStatement
syn clear bashStatement
syn clear shQuote
syn clear shSingleQuote

syntax include @sed syntax/sed.vim                                                                                                                                                                                                                                        
syntax region sedEmbed start="\<sed\s\+'"ms=e+1 end="'"me=s-1 contains=@sed

作为:help sh-awk

的变体

该文档扩展名提供了将其他语言嵌入到Shell脚本语法中的几乎完美的蓝图,并命名了需要包含和扩展的syntax/sh.vim语法组。为了使其适应sed,我进行了以下更改:

  • 仍然需要清除bashStatementkshStatement,以避免关键字match混淆添加区域的匹配。
  • 添加对多个sed表达式(-e ... -e ...)和行继续的支持。
  • 还原正确的b:current_syntax值。
syn clear kshStatement
syn clear bashStatement

let s:save_syntax = b:current_syntax
unlet b:current_syntax
syn include @shSedScript syntax/sed.vim
let b:current_syntax = s:save_syntax
unlet s:save_syntax

syn match shSedLineContinuation "\\\s*$" contained skipempty nextgroup=shSedExpression
syn match shSedExpression "\%(^\|\_s\+\)-\a*e\a*\_s\+" contained nextgroup=shSedScriptCode
syn region shSedScriptCode matchgroup=shSedCommand start=+[=\\]\@<!'+ skip=+\\'+ end=+'+ contains=@shSedScript contained skipwhite skipempty nextgroup=shSedLineContinuation,shSedExpression
syn region shSedScriptEmbedded matchgroup=shSedCommand start=+\<sed\>+ skip=+\\$+ end=+[=\\]\@<!'+me=e-1 contains=@shIdList,@shExprList2 nextgroup=shSedScriptCode
syn cluster shCommandSubList add=shSedScriptEmbedded

hi def link shSedCommand Type
hi def link shSedExpression shSetOption