Частичное совпадение синтаксиса Vim

Sep 29 2020

Я пытаюсь сопоставить символ новой строки в файле синтаксиса Vim, я могу заставить его работать, когда я использую шаблон в Vim, но когда я помещаю его в свой файл синтаксиса, он не выделяется, когда у меня новая строка и когда должно.

Регулярное выражение часть , которую я использую для нового матча строки: \_s(также пробовал с \nс: \(\n\|\s\))

Патерн: [,(]\(\_s*\w\+:\)\?\_s*\zs\w\+

Упрощенный вариант шаблона: [,(]\_s*\zs\w\+(то же самое для примера и цели вопроса)

Код файла синтаксиса внутри .vim/syntax/python.vim:

syn match pythonFunctionParam '[,(]\_s*\zs\w\+'
[...]
hi link pythonFunctionParam Error
[...]
let b:current_syntax = 'python'

Вот образец тестового файла для воспроизведения test.py:

a(matched_by_all=2, matched_by_all="anything")
b(  matched_by_all=3,
    matched_only_by_vim_search='test'
)
c(
    matched_only_by_vim_search=3
    matched_by_none="it's normal"
)

Когда я использую интегрированный поиск Vim ( /[,(]\_s*\zs\w\+), я получаю следующие совпадения:

  matched_by_all    matched_by_all
    matched_by_all
    matched_only_by_vim_search


    matched_only_by_vim_search
    

Так что все работает, ожидалось

Когда я использую синтаксис syn matchс одним и тем же регулярным выражением, я получаю разные совпадения (меньше совпадений):

  matched_by_all    matched_by_all
    matched_by_all






Вы можете видеть, когда есть (или ,в той же строке, она будет соответствовать, но не если это новая строка.

Итак, мой вопрос: как получить такое же совпадение в моем файле синтаксиса?

Ответы

1 MaximKim Sep 29 2020 at 21:17

Похоже, движку регулярных выражений синтаксиса vim не нравится \zsи \_s. Если вы удалите, \zsвы увидите совпадения:

Я бы выбрал другой подход:

  1. определить прозрачную область вызова функции, которая содержит параметры функции
  2. определить параметр содержащейся функции
syn region pythonFunctionCall start='\k\+\_s*(\zs' end='\ze)' contains=pythonFunctionParam transparent keepend
syn match pythonFunctionParam '\k\+\(\s*=\s*[^,]\+\)\?' contained
hi link pythonFunctionParam Error

ПРИМЕЧАНИЕ. PythonFunctionParam - это всего лишь простой пример, который вы можете настроить.

1 filbranden Sep 29 2020 at 21:53

Существует явное исключение из того, как \zsработает совпадение синтаксиса, поскольку оно должно совпадать в той же строке, что и начало шаблона.

Смотрите :help syn-multi-line:

Шаблоны могут включать "\ n", чтобы соответствовать концу строки. В основном это работает должным образом, но есть несколько исключений.

При использовании начального шаблона со смещением начало совпадения не может начинаться со следующей строки. Однако выделение может начинаться со следующей строки. Использование \zsпредмета также требует, чтобы начало матча не перемещалось на другую строку.

Вы можете обойти это, используя вместо этого поиск с нулевой шириной :

syn match pythonFunctionParam '\([,(]\_s*\)\@<=\w\+'

Но учтите, что такие матчи обычно дороже. Если вы его используете, постарайтесь ограничить его возможности. Механизм синтаксиса в Vim также предлагает другие механизмы, которые могут помочь вам сузить круг совпадений, например, вы можете сопоставлять определенные группы только тогда, когда они встречаются внутри определенных других групп, это может помочь реализовать такой синтаксис с использованием более простых сопоставлений.