Я решил узнать больше о vim и его подсветке синтаксиса. Используя примеры для других, я создаю свой собственный файл синтаксиса для Markdown. Я видел mkd.vim, и у него тоже есть эта проблема. Моя проблема заключается между элементами списка и выделением блока кода.
Кодовый блок определение:
Пример:
Regular text
this is code, monospaced and left untouched by markdown
another line of code
Regular Text
Мой синтаксис Vim для блока кода:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
Элемент списка Unorder определение:
Пример:
Regular text
- item 1
- sub item 1
- sub item 2
- item 2
this is part of item 2
so is this
- item 3, still in the same list
- sub item 1
- sub item 2
Regular text, list ends above
Мой синтаксис Vim для определения элемента списка unorder (я выделяю только [-+*]):
syn region mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end = ".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl
hi link mkdListItem operator
Я не могу заставить выделение работать с последними двумя правилами для списка и с блоком кода.
Это пример, который нарушает мою подсветку синтаксиса:
Regular text
- Item 1
- Item 2
part of item 2
- these 2 line should be highlighted as a list item
- but they are highlighted as a code block
В настоящее время я не могу понять, как заставить выделение работать так, как я хочу.
Забыл добавить «глобальное» правило синтаксиса, используемое в обоих правилах, перечисленных ниже. Это необходимо для того, чтобы они начинались с пустой строки.
syn match mkdBlankLine /^\s*\n/ nextgroup=mkdCodeBlock,mkdListItem transparent
Еще одно примечание: я должен был быть более ясным. В моем файле синтаксиса правила списка появляются перед правилами цитат.





Просто убедитесь, что определение mkdListItem находится после определения mkdCodeBlock, например:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
syn region mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end = ".*" contained nextgroup=mkdListItem,mkdListSkipNL contains=@Spell skipnl
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL skipnl
hi link mkdListItem operator
syn match mkdBlankLine /^\s*\n/ nextgroup=mkdCodeBlock,mkdListItem transparent
Документация Vim говорит в :help :syn-define:
"Если в одной позиции совпадает более одного элемента, то тот, который был определены ПОСЛЕДНИЕ победы. Таким образом, вы можете переопределить ранее определенные элементы синтаксиса с помощью используя элемент, соответствующий тому же тексту. Но ключевое слово всегда предшествует совпадение или регион. И ключевое слово с совпадающим регистром всегда стоит перед ключевое слово с игнорированием регистра ".
Ты прав. Я обновил свой вопрос (внизу), мои правила списка находятся перед моим правилом цитаты. Не могли бы вы перевернуть свой пример, чтобы цитата была перед списком. Тогда я могу принять твой ответ.
hcs42 был правильным. Я помню, как читал этот раздел сейчас, но я забыл об этом, пока hcs24 не напомнил мне об этом.
Вот мой обновленный синтаксис (несколько других настроек), который работает:
"""""""""""""""""""""""""""""""""""""""
" Code Blocks:
" Indent with at least 4 space or 1 tab
" This rule must appear for mkdListItem, or highlighting gets messed up
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
"""""""""""""""""""""""""""""""""""""""
" Lists:
" These first two rules need to be first or the highlighting will be
" incorrect
" Continue a list on the current line or next line
syn match mkdListCont /\s*[^-+*].*/ contained nextgroup=mkdListCont,mkdListItem,mkdListSkipNL contains=@Spell skipnl transparent
" Skip empty lines
syn match mkdListSkipNL /\s*\n/ contained nextgroup=mkdListItem,mkdListSkipNL
" Unorder list
syn match mkdListItem /\s*[-*+]\s\+/ contained nextgroup=mkdListSkipNL,mkdListCont skipnl
Тао Чжынь, возможно, он охватывает ваши варианты использования, но не охватывает синтаксис Markdown. В Markdown элемент списка мог содержит блок кода. Вы можете взглянуть на мое решение здесь
TL; DR; проблема в том, что vim не позволяет вам сказать что-то вроде: блок, имеющий тот же отступ, что и его контейнер + 4 пробела. Единственное решение, которое я нашел, - это создать правила для каждого типа блоков, которые могут содержаться в элементах списка для каждого уровня отступа (на самом деле я поддерживаю 42 уровня отступа, но это произвольное число)
Итак, у меня есть markdownCodeBlockInListItemAtLevel1, в котором должен содержится в markdownListItemAtLevel1, и у него должно быть не менее 8 ведущих пробелов, а затем markdownCodeBlockInListItemAtLevel2, чтобы должен содержался в начале markdownListItemAtLevel1, в котором должно содержаться как минимум 10 пробелов markdownListItemAtLevel1, который должен быть в markdownListItemAtLevel2, который должен содержать не менее 10 пробелов markdownListItemAtLevel1, который должен содержать не менее 10 пробелов. ...
Я знаю, что прошло несколько лет, но, возможно, кто-то сочтет этот ответ полезным, поскольку весь синтаксис, основанный на отступах, страдает той же проблемой.
Здорово. Заставляет меня наконец изучить скрипты vim. :)