Выделение Vim Markdown (элементы списка и конфликты блоков кода)
Я решил узнать больше о vim и подсветке синтаксиса.
Используя примеры для других, я создаю свой собственный файл синтаксиса для Markdown. Я видел mkd.vim и у этой проблемы тоже.
Моя проблема связана с элементами списка и подсветкой блока кода.
Блок кода определение:
- первая строка пуста
- вторая строка начинается с не менее 4 пробелов или 1 вкладки
Блок
- заканчивается пустой строкой
Пример:
Regular text
this is code, monospaced and left untouched by markdown
another line of code
Regular Text
Синтаксис My Vim для кода:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
Упорядочить элемент списка определение:
- первая строка пуста
- вторая строка начинается с [- + *], а затем пробела
- список завершается пустой строкой, а затем обычной (без списка) строкой
- между позициями можно добавить любое количество пустых строк.
- дополнительный список указывается отступом (4 пробела или 1 вкладка)
- строка нормального текста после включения элемента списка в качестве продолжения этого элемента списка
Пример:
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
Синтаксис My Vim для определения позиции списка неупорядоченных элементов (выделяю только [-+*]
):
syn region mkdListItem start=/\s*[-*+]\s\+/ matchgroup=pdcListText end=".*" contained nextgroup=mkdListItem,mkdListSkipNL [email protected] 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
Другое примечание: я должен был быть более ясным. В моем синтаксическом файле правила списка отображаются перед Правилами Blockquote
Ответы
Ответ 1
Просто убедитесь, что определение 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 [email protected] 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
:
"В случае, если более чем один элемент совпадает с той же позицией,
определенных LAST. Таким образом, вы можете переопределить ранее определенные элементы синтаксиса на
используя элемент, который соответствует одному и тому же тексту. Но ключевое слово всегда идет перед
совпадения или региона. И ключевое слово с подходящим случаем всегда идет до
ключевое слово с игнорированием случая. "
Ответ 2
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 [email protected] 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
Ответ 3
Tao Zhyn, который, возможно, охватывает ваши варианты использования, но не охватывает синтаксис Markdown. В Markdown элемент списка может содержать блок кода. Вы можете взглянуть на мое решение здесь
TL; DR; проблема в том, что vim не позволяет вам сказать что-то вроде: блок с таким же отступом, как и контейнер + 4 пробела. Единственное решение, которое я нашел, - генерировать правила для каждого типа блоков, которые могут содержаться в элементах списка для каждого уровня отступов (фактически я поддерживаю 42 уровня отступов, но это произвольное число)
Итак, у меня есть markdownCodeBlockInListItemAtLevel1, который должен содержать в markdownListItemAtLevel1, и он должен иметь по крайней мере 8 ведущих пробелов, затем markdownCodeBlockInListItemAtLevel2, который должен содержать в файле markdownListItemAtLevel2, который должен содержаться в markdownListItemAtLevel1 ant должен иметь как минимум 10 ведущих пробелов, ecc...
Я знаю, что прошло несколько лет, но, возможно, кто-то посчитает этот ответ полезным, поскольку весь синтаксис, основанный на отступе, страдает одной и той же проблемой.