11

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

現在、ハイライトを希望どおりに機能させる方法がわかりません


以下にリストされている両方のルールで使用される「グローバル」構文ルールを追加するのを忘れていました。空白行で始まるようにするためです。

syn match mkdBlankLine   /^\s*\n/    nextgroup=mkdCodeBlock,mkdListItem transparent

別の注記: もっと明確にすべきでした。私の構文ファイルでは、List 規則が Blockquote 規則の前に表示されます。


4

3 に答える 3

7

次のように、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ます:

「同じ位置で複数の項目が一致する場合、最後に定義された項目が優先されます。したがって、同じテキストに一致する項目を使用して、以前に定義された構文項目をオーバーライドできます。ただし、キーワードは常に一致または領域の前に配置されます。また、大文字と小文字が一致するキーワードは、大文字と小文字を無視するキーワードの前に常に配置されます。」

于 2008-09-26T07:43:12.497 に答える
1

hcs42 は正しかった。そのセクションを今読んだことは覚えていますが、hcs24 がそれを思い出させるまで忘れていました。

これが機能する私の更新された構文(他のいくつかの微調整)です:

""""""""""""""""""""""""""""""""""
" コード ブロック:

" 少なくとも 4 つのスペースまたは 1 つのタブでインデントする
" このルールは mkdListItem に表示する必要があります。そうしないと、強調表示が台無しになります
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ 含まれる nextgroup=mkdCodeBlock  

""""""""""""""""""""""""""""""""""
" リスト:

" これらの最初の 2 つのルールを最初にする必要があります。
" 正しくない

" 現在の行または次の行にリストを続ける
syn match mkdListCont /\s*[^-+*].*/ 含まれる nextgroup=mkdListCont,mkdListItem,mkdListSkipNL contains=@Spell skipnl transparent

" 空行をスキップ
syn match mkdListSkipNL /\s*\n/ 含まれる nextgroup=mkdListItem,mkdListSkipNL

" 順不同リスト
syn match mkdListItem /\s*[-*+]\s\+/ 含まれる nextgroup=mkdListSkipNL,mkdListCont skipnl
于 2008-09-26T22:09:31.173 に答える
0

Tao Zhyn、それはおそらくあなたのユースケースをカバーしていますが、Markdown 構文はカバーしていません。Markdown では、リスト項目にコード ブロックを含めることができました。ここで私のソリューションを見ることができます

TL;DR; 問題は、vim では次のようなことを言わせないことです: a block that has the same indentation with its container + 4 つのスペース。私が見つけた唯一の解決策は、各レベルのインデントのリスト項目に含めることができるブロックの種類ごとにルールを生成することです (実際には 42 レベルのインデントをサポートしていますが、それは任意の数です)。

したがって、 markdownListItemAtLevel1 に含まれている必要がある markdownCodeBlockInListItemAtLevel1 があり、少なくとも 8 つの先頭のスペースが必要です。次に、markdownListItemAtLevel1 に含まれている必要がある markdownListItemAtLevel2 に含まれている必要がある markdownCodeBlockInListItemAtLevel2 には、少なくとも 10 個の先頭のスペースが必要です。ecc ...

数年が経過したことは知っていますが、インデントに基づくすべての構文が同じ問題を抱えているため、誰かがこの回答を役立つと考えるかもしれません

于 2014-03-23T17:00:38.490 に答える