VSCode: change precedence of rules in custom TextMate grammar?

房东的猫 提交于 2020-06-17 22:57:45

问题


In a simple to-do list language grammar that I made, some scopes overlap in their regex rules, so certain scopes are not being recognized at all. I'd like to give these scopes precedence so that they're recognized within another scope.

Currently it looks like this:

The scopes are:

  • urgent (red; lines starting with XXam/pm or *)
  • waiting (yellow; lines starting with `)
  • url (purple; words starting with http)
  • tag (blue; words starting with @)

I'd like tags and URLs to be colored even within urgent or waiting lines, but currently the Scope and Token Inspector shows that the entirety of lines 2 and 3 are the urgent scope, and all of line 4 is the waiting scope, even though those lines should have tags and URLs in them.

I've tried reversing the order of the definitions in the .tmLanguage file, but that didn't make any difference. Here are those definitions:

<dict>
  <key>match</key>
  <string>\B\@\w+</string>
  <key>name</key>
  <string>constant.language.tag.todotxt</string>
</dict>
<dict>
  <key>match</key>
  <string>http.*?( |$)</string>
  <key>name</key>
  <string>constant.language.url.todotxt</string>
</dict>
<dict>
  <key>match</key>
  <string>^`.*$</string>
  <key>name</key>
  <string>constant.language.waiting.todotxt</string>
</dict>
<dict>
  <key>match</key>
  <string>^\*.*$|^\d.{0,5}[ap]m.*$</string>
  <key>name</key>
  <string>constant.language.urgent.todotxt</string>
</dict>

So, what needs to change for the tag and url scopes to be recognized even when they're within the urgent and waiting scopes?

Update: an imperfect workaround

I can prevent the scopes from overlapping by making the urgent and waiting scopes (red and yellow) end as soon as a tag or url is encountered on the line, using these regular expressions:

<key>match</key>
<string>^`.*?(?= @| http|$)</string>
<key>name</key>
<string>constant.language.waiting.todotxt</string>
...
<key>match</key>
<string>(^\*.*?|^\d.{0,5}[ap]m.*?)(?= @| http|$)</string>
<key>name</key>
<string>constant.language.urgent.todotxt</string>

The limitation of this workaround is that tags and URLs must be at the end the line, otherwise normal text appears where it shouldn't:

Ideally I would still prefer that tags and URLs be recognized WITHIN the urgent and waiting scopes, so that an urgent or waiting scope can continue even after tags and/or URLs in the middle of the line.

来源:https://stackoverflow.com/questions/62197602/vscode-change-precedence-of-rules-in-custom-textmate-grammar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!