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
代码块的我的 Vim 语法:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
Unorder List item 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
另一个注释:我应该更清楚。 在我的语法文件中,列表规则出现在块引用规则之前
I decide to learn more about vim and its syntax highlighting.
Using examples for others, I am creating my own syntax file for Markdown. I have seen mkd.vim and it has this problem too.
My issue is between list items and code block highlighting.
Code Block definition:
- first line is blank
- second line begins with at least 4 spaces or 1 tab
- block is finished with a blank line
Example:
Regular text
this is code, monospaced and left untouched by markdown
another line of code
Regular Text
My Vim syntax for code block:
syn match mkdCodeBlock /\(\s\{4,}\|\t\{1,}\).*\n/ contained nextgroup=mkdCodeBlock
hi link mkdCodeBlock comment
Unorder List item definition:
- first line is blank
- second line begins with a [-+*] followed by a space
- the list is finished with a blank line then a normal (non-list) line
- in between line items any number of blank lines can be added
- a sub list is specified by indenting (4 space or 1 tab)
- a line of normal text after a list item is include as a continuation of that list item
Example:
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 syntax for unorder list item definition (I only highlight [-+*]
):
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
I cannot get the highlighting to work with the last two rule for list and with a code block.
This is an example that breaks my syntax highlighting:
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
I currently cannot figure out how to get the highlighting to work the way I want it too
Forgot to add a "global" syntax rule used in both rules listed below. It is to ensure a that they start with a blank line.
syn match mkdBlankLine /^\s*\n/ nextgroup=mkdCodeBlock,mkdListItem transparent
Another Note: I should have been more clear. In my syntax file, the List rules appear before the Blockquote Rules
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Tai Zhyn,这可能涵盖了您的用例,但不涵盖 Markdown 语法。 在 Markdown 中,列表项可以包含代码块。 您可以在此处查看我的解决方案
TL;DR; 问题是 vim 不允许你说这样的话:一个与其容器具有相同缩进的块 + 4 个空格。 我找到的唯一解决方案是为每种缩进级别的列表项中包含的每种块生成规则(实际上我支持 42 级缩进,但它是任意数字)
所以我有 markdownCodeBlockInListItemAtLevel1 ,必须 包含在 markdownListItemAtLevel1 中并且需要至少有 8 个前导空格,然后 必须 包含在 markdownListItemAtLevel2 中的 markdownCodeBlockInListItemAtLevel2 必须至少包含在 markdownListItemAtLevel1 中10 个前导空格,ecc...
我知道几年过去了,但也许有人会认为这个答案很有帮助,因为所有基于缩进的语法都遇到同样的问题
Tao Zhyn, that maybe covers your use cases but it doesn't cover the Markdown syntax. In Markdown a list item could contain a code block. You could take a look at my solution here
TL;DR; the problem is that vim doesn't let you say something like: a block that have the same indentation as its container + 4 spaces. The only solution I found is to generate rules for each kind of blocks that could be contained in a list items for each level of indentation (actually I support 42 level of indentation but it's an arbitrary number)
So I have markdownCodeBlockInListItemAtLevel1 that must be contained in a markdownListItemAtLevel1 and it needs to have at least 8 leading spaces, an then markdownCodeBlockInListItemAtLevel2 that must be contained in a markdownListItemAtLevel2 that must be contained in a markdownListItemAtLevel1 ant needs to have at least 10 leading spaces, ecc...
I know that a few years have passed but maybe someone would consider this answer helpful since all syntax based on indentation suffers of the same problem
hcs42 是正确的。 我确实记得现在读过该部分,但我忘记了,直到 hcs24 提醒我。
这是我更新的有效语法(其他一些调整):
hcs42 was correct. I do remember reading that section now, but I forgot about it until hcs24 reminded me about it.
Here is my updated syntax (few other tweaks) that works:
只需确保 mkdListItem 的定义位于 mkdCodeBlock 的定义之后,如下所示:
Vim 文档在
:help :syn-define
中说道:“如果多个项目在同一位置匹配,则一个是
定义了最后的胜利。 因此,您可以通过以下方式覆盖先前定义的语法项
使用与相同文本匹配的项目。 但关键字总是出现在
匹配或区域。 并且大小写匹配的关键字总是出现在
关键字忽略大小写。”
Just make sure that the definition of mkdListItem is after the definition of mkdCodeBlock, like this:
Vim documentation says in
:help :syn-define
:"In case more than one item matches at the same position, the one that was
defined LAST wins. Thus you can override previously defined syntax items by
using an item that matches the same text. But a keyword always goes before a
match or region. And a keyword with matching case always goes before a
keyword with ignoring case."