Выделение 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...

Я знаю, что прошло несколько лет, но, возможно, кто-то посчитает этот ответ полезным, поскольку весь синтаксис, основанный на отступе, страдает одной и той же проблемой.