Vim Markdownの強調表示(リストアイテムとコードブロックの競合)
質問
vimとその構文の強調表示についてさらに学習することにしました。 他の例を使用して、Markdown用の独自の構文ファイルを作成しています。 mkd.vim を見ましたが、この問題もあります。 私の問題は、リストアイテムとコードブロックの強調表示の間にあります。
コードブロック定義:
- 最初の行は空白です
- 2行目は、少なくとも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
リスト項目定義:
- 最初の行は空白です
- 2行目は[-+ *]で始まり、その後にスペースが続きます
- リストは空白行で終了し、通常の(リストではない)行
- 行項目の間に任意の数の空白行を追加できます
- サブリストはインデント(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
リストの最後の2つのルールおよびコードブロックで機能する強調表示を取得できません。
これは、構文の強調表示を壊す例です。
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
現在、ハイライトを自分の思い通りに機能させる方法を理解できません
" global"を追加するのを忘れた以下にリストされている両方の規則で使用される構文規則。空白行で始まることを確認するためです。
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
Tao Zhyn、あなたのユースケースをカバーしているかもしれませんが、Markdown構文をカバーしていません。 Markdownでは、リストアイテムにコードブロックを含めることができます。あなたは私の解決策を見ることができますこちら
TL; DR;問題は、vimが次のようなことを言ってくれないことです:そのコンテナと同じインデントを持つスペース+ 4スペース。私が見つけた唯一の解決策は、各レベルのインデントのリスト項目に含めることができる各種類のブロックのルールを生成することです(実際には42レベルのインデントをサポートしていますが、それは任意の数です)
だからmarkdownCodeBlockInListItemAtLevel1があり、 はmarkdownListItemAtLevel1に含まれている必要があり、少なくとも8つの先行スペースが必要です。次に、
数年が経過したことは知っていますが、インデントに基づくすべての構文は同じ問題に苦しんでいるので、誰かがこの答えを役立つと考えるかもしれません