开发者

Vim: define syntax rules within functions?

I'd like to dynamically create syntax rules inside a function. For example, something like:

fun! DoStuff(word)
    syntax match Error 开发者_运维百科'\<'.word.'\>' contained
    ... other stuff ...
endf

But, apparently* that doesn't work. So… How can I do it?

*: Vim script is still voodoo, as far as I'm concerned


fun! DoStuff(word)
    exec 'syntax match Error /\<'.a:word.'\>/ contained'
endf


The reason you've been having problems isn't that syn match can't be used in a function, it's that when it's used in the way you've described, it is entered literally. I'm not sure what the details are of the implementation, but I'd expect it to treat the pattern as \< (delimited by quotation marks) and then it would have some unrecognised strings at the end. It won't treat the . as a concatenation operator. Therefore, what you have to do (as Mykola Golubyev correctly pointed out), you have to create the command as one long string:

'syntax match Error /\<' . a:word . '\>/ contained'

which, if the argument is foobar gives:

'syntax match Error /\<foobar\>/ contained'

and then you have to use exec to actually run that command.

An aside (but quite an important one in my opinion)...

If you're simply adding \< and \> around the word, use syn keyword instead: the \< and \> are implied and the matcher is much faster (which can make a difference to the responsiveness of vim if you have a lot of keywords).

You could simply use a command in that case (although this wouldn't work if you're trying to do something more complicated):

:command! -nargs=1 DoStuff syn keyword Error <args> contained
:DoStuff MyKeyword

If you need to use a function:

function! DoStuff(word)
    exec 'syntax keyword Error ' . a:word . ' contained'
endfunction

For more information, there are some useful documents here:

:help :syn-keyword
:help :syn-match
:help :command
:help :command-nargs
:help :function
:help :exec

As a really random aside, a little known vim fact is that you can fractionally shorten the match command as exec automatically adds spaces between arguments, so:

exec 'syntax keyword Error ' . a:word . ' contained'

becomes

exec 'syntax keyword Error' a:word 'contained'

... but it's probably more readable the first way!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜