Sublimetext3 如何在我当前的语言定义中正确嵌入另一种语言?

Sublimetext3 如何在我当前的语言定义中正确嵌入另一种语言?,sublimetext3,syntax-highlighting,smalltalk,Sublimetext3,Syntax Highlighting,Smalltalk,我已经为Sublime Text 3添加了一个突出显示功能,支持嵌入式C代码 smalltalk代码中的内联C(总是以^%\{开头,以%\}$结尾)代码 一个简单的例子(不是很多C,但需要一个简单的例子): 在Sublime文本中有一个新功能嵌入(甚至还有一个) 我试着这样做: - match: '^%\{' embed: scope:source.c embed_scope: meta.environment.embedded.c.smalltalk source.c.embedded

我已经为Sublime Text 3添加了一个突出显示功能,支持嵌入式C代码

smalltalk代码中的
内联C
(总是以
^%\{
开头,以
%\}$
结尾)代码

一个简单的例子(不是很多
C
,但需要一个简单的例子):

在Sublime文本中有一个新功能
嵌入
(甚至还有一个)

我试着这样做:

- match: '^%\{'
  embed: scope:source.c
  embed_scope: meta.environment.embedded.c.smalltalk source.c.embedded
  escape: '%\}$'
然而,我无法将其正确地纳入我的计划中


有人知道如何正确地将一种语言嵌入另一种语言吗?

这个问题有点棘手,因为您提供了一个示例语法定义和一些Smalltalk源代码的示例,但是提供的代码没有通过提供的语法突出显示,因为它的结构不正确

在这里,我们假设您提供的Smalltalk示例如下。这可能是有效的,也可能是无效的(我已经很久没有使用Smalltalk了),但它突出了您的语法,所以让我们调用它来进行测试

对象子类:测试[
西格布特
“如果操作系统不支持,则返回SIGABRT-0的信号号
(unix系统中的数值不相同)
%{/*无上下文*/
#ifdef SIGABRT
返回(_mkSmallInteger(SIGABRT));
#否则
返回(_mkSmallInteger(0));
#恩迪夫
%}
!
].
您上面提供的语法匹配是正确的,所以我猜您的问题在于您在语法中的位置

因此,让我们假设在语法定义中,有不止一个地方我们可能想要匹配这些C块中的一个;在这种情况下,我们可能希望以包含匹配项的语法创建一个新的
上下文
,以便我们可以
在需要的地方包含它:

c-block:
-匹配:“\{”
嵌入:范围:source.c
嵌入范围:meta.environment.embedded.c.smalltalk source.c.embedded
转义:“\}$”
这是与您上面提供的相同的摘录,但放在上下文中。所以让我们假设,像这样的块可以出现的第一个地方是在块体中。您的语法中有一个
块体
上下文,因此我们将
包含
粘贴到块体的末尾,以包含此新上下文:

块体:
-包括:布拉格语
-包括:选择器
-包括:文字
-包括:区块
-包括:评论
-包括:c-块
然而,这并没有达到预期的结果;突出显示不正确:

很明显,突出显示至少在C注释开始时出错,可能更早。如果在光标位于注释上时使用
Tools>Developer>Show Scope Name
,则可以看到分配的范围是
source.smalltalk entity.Name.function
,这意味着语法将C注释开头视为方法名

看起来
%{
构造未正确突出显示,并且检查显示
%
字符的范围是
source.smalltalk关键字.other

所以在现实中,目前的问题是,有了上述定义,不再将
%{
视为C块的开始,而是将其视为关键字,如果它是关键字,则匹配C块的规则根本不会触发

如果查看语法,则
main
上下文如下所示:

- match: '^%\{'
  embed: scope:source.c
  embed_scope: meta.environment.embedded.c.smalltalk source.c.embedded
  escape: '%\}$'
main:
-匹配:'([a-zA-Z][a-zA-Z0-9]*)\s*(子类:)\s*([a-zA-Z][a-zA-Z0-9]*)\s*\['
捕获:
1:entity.other.class
2:关键字:其他
3:entity.name.type
推送:
-匹配:'\]'
波普:没错
-包括:布拉格语
-匹配:“([a-zA-Z][a-zA-Z0-9]*:)\s*([a-zA-Z][a-zA-Z0-9]*)”
捕获:
1:entity.name.function
3:变量。其他
-匹配:([a-zA-Z][a-zA-Z0-9]*)”
范围:entity.name.function
-包括:区块
-包括:评论
-包括:块体
这些规则表明,当我们看到一行以
基类subclass:subclass[
开头时,我们正在进入一个匿名上下文(通过
推送
)来处理类主体(或块或任何东西)的内容

匿名上下文包含在看到结束符
]
时弹出的规则,两个不同的匹配项用于查找函数名,然后在
的上下文中分别包含
注释
块体

当您
包含
时,升华会从该上下文中获取所有
匹配
规则,并在插入点插入它们的副本,就像您刚刚在此处手动输入一样

此外,当
上下文中有多条规则可能匹配时,上下文中的第一条
匹配规则就是应用的规则(即它“赢得”平局)

作用域
关键字.other
应用于
pragma
上下文以及
选择器
上下文中的规则,并且
选择器
上下文可以匹配单个
%
字符作为关键字

因此,这里的问题是,由于
块体
上下文的包含列表中
选择器
之后出现
包含c-块
,因此
选择器
上下文在c-块的规则可以找到它之前查找并匹配
%
字符

然后,解决方案是将
include c-block
的位置移到该项之前,以确保它首先匹配:

块体:
-包括:c-块
-包括:布拉格语
-包括:选择器
-包括:文字
-包括: