Подсветка Vim Markdown (элементы списка и конфликты блоков кода)

StackOverflow https://stackoverflow.com/questions/137952

Вопрос

Я решил узнать больше о vim и его подсветке синтаксиса.Используя примеры других, я создаю свой собственный файл синтаксиса для Markdown.Я видел mkd.vim и у него тоже есть эта проблема.Моя проблема заключается между элементами списка и подсветкой блока кода.

Кодовый блок определение:

  • первая строка пуста
  • вторая строка начинается как минимум с 4 пробелов или 1 табуляции
  • блок заканчивается пустой строкой

Пример:

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

Упорядочить элемент списка определение:

  • первая строка пуста
  • вторая строка начинается с [-+*], за которым следует пробел
  • список заканчивается пустой строкой, а затем обычной строкой (не списком)
  • между позициями можно добавить любое количество пустых строк
  • подсписок указывается с помощью отступа (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

Мой синтаксис Vim для определения элемента списка упорядочения (я выделяю только [-+*]):

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 элемент списка мог содержать блок кода.Вы можете взглянуть на мое решение здесь

ТЛ;ДР;проблема в том, что vim не позволяет вам сказать что-то вроде: блок, имеющий тот же отступ, что и его контейнер + 4 пробела.Единственное решение, которое я нашел, — это сгенерировать правила для каждого типа блоков, которые могут содержаться в элементах списка для каждого уровня отступа (на самом деле я поддерживаю 42 уровня отступов, но это произвольное число).

Итак, у меня есть markdownCodeBlockInListItemAtLevel1, который должен содержаться в markdownListItemAtLevel1 и иметь не менее 8 начальных пробелов, а затем markdownCodeBlockInListItemAtLevel2, который должен содержаться в markdownListItemAtLevel2, который должен содержаться в markdownListItemAtLevel1, ant должен иметь не менее 10 ведущих пробелов и т. д.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top