Vim Markdown 高亮(列表项和代码块冲突)

Posted

技术标签:

【中文标题】Vim Markdown 高亮(列表项和代码块冲突)【英文标题】:Vim Markdown highlighting (list items and code block conflicts) 【发布时间】:2010-09-13 08:52:43 【问题描述】:

我决定进一步了解 vim 及其语法高亮。 使用其他人的示例,我正在为 Markdown 创建自己的语法文件。我见过mkd.vim,它也有这个问题。 我的问题是在列表项和代码块突出显示之间。

代码块definition:

第一行是空白 第二行以至少 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

未排序列表项definition:

第一行是空白 第二行以 [-+*] 开头,后跟一个空格 列表以空行结束,然后是正常(非列表)行 在行项目之间可以添加任意数量的空行 通过缩进指定子列表(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

另一个注意事项:我应该更清楚。在我的语法文件中,列表规则出现在块引用规则之前


【问题讨论】:

酷。让我终于想学习 vim 脚本了。 :) 【参考方案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 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 中说:

"如果多个项目在同一位置匹配,则 定义 LAST 获胜。因此,您可以覆盖以前定义的语法项 使用与相同文本匹配的项目。但是关键字总是在a之前 匹配或区域。并且大小写匹配的关键字总是在a之前 关键字忽略大小写。”

【讨论】:

你是对的。我已经更新了我的问题(底部),我的列表规则在我的块引用规则之前。你能把你的例子翻过来吗,所以块引用在列表之前。那么我可以接受你的回答。【参考方案2】:

hcs42 是正确的。我确实记得现在读过那部分,但我忘记了,直到 hcs24 提醒我。

这是我更新的有效语法(其他一些调整):

""""""""""""""""""""""""""""""""""""""""" " 代码块: " 缩进至少 4 个空格或 1 个制表符 " 这个规则必须出现在 mkdListItem 中,否则突出显示会搞砸 同步匹配 mkdCodeBlock /\(\s\4,\|\t\1,\).*\n/ 包含 nextgroup=mkdCodeBlock """"""""""""""""""""""""""""""""""""""""" " 列表: " 前两条规则必须放在首位,否则突出显示将是 “不正确 " 继续当前行或下一行的列表 syn match mkdListCont /\s*[^-+*].*/ contains nextgroup=mkdListCont,mkdListItem,mkdListSkipNL contains=@Spell skipnl transparent " 跳过空行 同步匹配 mkdListSkipNL /\s*\n/ 包含 nextgroup=mkdListItem,mkdListSkipNL " 无序列表 syn match mkdListItem /\s*[-*+]\s\+/ 包含 nextgroup=mkdListSkipNL,mkdListCont skipnl

【讨论】:

【参考方案3】:

Tao Zhyn,这可能涵盖了您的用例,但不涵盖 Markdown 语法。在 Markdown 中,列表项可以包含代码块。你可以看看我的解决方案here

TL;DR;问题是 vim 不允许你说这样的话:一个与其容器具有相同缩进的块 + 4 个空格。我找到的唯一解决方案是为每种类型的块生成规则,这些块可以包含在每个缩进级别的列表项中(实际上我支持 42 级缩进,但它是一个任意数字)

所以我有 必须 包含在 markdownListItemAtLevel1 中的 markdownCodeBlockInListItemAtLevel1 并且它需要至少有 8 个前导空格,然后 必须 包含在 markdownListItemAtLevel2 中的 markdownCodeBlockInListItemAtLevel2必须包含在一个 markdownListItemAtLevel1 蚂蚁需要至少有 10 个前导空格,ecc...

我知道几年过去了,但也许有人会认为这个答案很有帮助,因为所有基于缩进的语法都存在同样的问题

【讨论】:

以上是关于Vim Markdown 高亮(列表项和代码块冲突)的主要内容,如果未能解决你的问题,请参考以下文章

Markdown-语法

Markdown-语法

9 - 支持 Markdown 语法和代码高亮

Leafage 诞生记(四nuxt/content使用限制如何进行markdown解析并高亮代码块)

The usage of Markdown---代码块

设置grep高亮显示匹配项和基本用法