Причина, по которой у вас возникли проблемы, состоит не в том, что syn match
нельзя использовать в функции, а в том, что когда она используется описанным вами способом, она вводится буквально. Я не уверен, каковы детали реализации, но я ожидал бы, что шаблон будет обрабатываться как \<
(ограниченный кавычками), и тогда в конце будут некоторые нераспознанные строки. Он не будет рассматривать .
как оператор конкатенации. Поэтому, что вы должны сделать (как правильно указал Николай Голубев), вы должны создать команду в виде одной длинной строки:
'syntax match Error /\<' . a:word . '\>/ contained'
который, если аргумент foobar дает:
'syntax match Error /\<foobar\>/ contained'
и затем вы должны использовать exec
для фактического запуска этой команды.
В стороне (но, на мой взгляд, довольно важный) ...
Если вы просто добавляете \<
и \>
вокруг слова, используйте вместо него syn keyword
: подразумеваются \<
и \>
, и средство сопоставления на намного быстрее (что может повлиять на отзывчивость vim, если у вас много ключевых слов).
В этом случае вы можете просто использовать команду (хотя это не сработает, если вы пытаетесь сделать что-то более сложное):
:command! -nargs=1 DoStuff syn keyword Error <args> contained
:DoStuff MyKeyword
Если вам нужно использовать функцию:
function! DoStuff(word)
exec 'syntax keyword Error ' . a:word . ' contained'
endfunction
Для получения дополнительной информации, здесь есть несколько полезных документов:
:help :syn-keyword
:help :syn-match
:help :command
:help :command-nargs
:help :function
:help :exec
В качестве действительно случайного, малоизвестного факта vim является то, что вы можете частично сократить команду match, так как exec
автоматически добавляет пробелы между аргументами, поэтому:
exec 'syntax keyword Error ' . a:word . ' contained'
становится
exec 'syntax keyword Error' a:word 'contained'
... но это, вероятно, более читабельно с первого взгляда!