HI~您好,欢迎您访问"北京金科合创软件官方网站",购买正版软件、海外正版软件商城就选金科软件(Goldk Software) 咨询热线:15210221926  金科软件-国内外正版软件服务商
您的位置: 首页>技术支持>Sublime Text

Sublime Text 语法定义

发布时间:2021-12-28 17:16:11点击量:

先决条件
为了遵循本教程,您需要安装 PackageDev (打开新窗口),一个旨在简化为 Sublime Text 创建新语法定义的包。按照自述文件“入门”部分中的安装说明进行操作。
文件格式
Sublime Text 使用属性列表 (打开新窗口)(Plist) 文件来存储语法定义。但是,因为编辑 XML 文件是一项繁琐的任务,所以我们将使用YAML (打开新窗口)相反,然后将其转换为 Plist 格式。这就是PackageDev包(上面提到的)的用武之地。
笔记
如果您在本教程中遇到意外错误,很可能是 PackageDev或 YAML 造成的。不要立即认为您的问题是由于 Sublime Text 中的错误造成的。
无论如何,如果您更喜欢在 XML 中工作,请手动编辑 Plist 文件,但请始终牢记它们在转义序列、许多 XML 标签等方面的不同需求。
范围
作用域是 Sublime Text 中的一个关键概念。本质上,它们在缓冲区中被命名为文本区域。它们自己不会做任何事情,但是当 Sublime Text 需要上下文信息时会偷看它们。
例如,当你触发一个片段时,Sublime Text 检查绑定到片段的范围并查看插入符号在文件中的位置。如果插入符号的当前位置与代码段的范围选择器匹配,则 Sublime Text 将其关闭。否则,什么都不会发生。
信息
作用域和作用域选择器之间略有不同:作用域是在语法定义中定义的名称,而作用域选择器用于诸如片段和目标作用域的键绑定之类的项目。创建新的语法定义时,您关心范围;当您想将片段限制在某个范围内时,您可以使用范围选择器。
范围可以嵌套以实现高度的粒度。您可以像使用 CSS 选择器一样深入查看层次结构。例如,多亏了范围选择器,您可以仅在 Python 源代码中的单引号字符串中激活键绑定,而不能在任何其他语言的单引号字符串中激活键绑定。
Sublime Text 继承了 Textmate 的作用域概念,Textmate 是 Mac 的文本编辑器。 Textmate 的在线手册 (打开新窗口)包含对 Sublime Text 用户也有用的范围选择器的更多信息。特别是,配色方案广泛使用范围来以所需的颜色设计语言的各个方面。
语法定义的工作原理
从本质上讲,语法定义是与范围名称配对的正则表达式数组。Sublime Text 将尝试将这些模式与缓冲区的文本进行匹配,并将相应的范围名称附加到所有出现的地方。这些正则表达式和作用域名称对称为规则。
规则按顺序应用,一次一行。规则按以下顺序应用:
1.在一行中的第一个位置匹配的规则
2.数组中最先出现的规则
每个规则都使用匹配的文本区域,因此将被排除在下一个规则的匹配尝试之外(除了少数例外)。实际上,这意味着您在创建新的语法定义时应该注意从更具体的规则到更通用的规则。否则,贪婪的正则表达式可能会吞下您希望采用不同样式的部分。
可以组合来自单独文件的语法定义,也可以递归应用它们。
你的第一个语法定义
举例来说,让我们为 Sublime Text 片段创建一个语法定义。我们将设置实际片段内容的样式,而不是整个 .sublime-snippet文件。
笔记
由于语法定义主要用于启用语法突出显示,我们将使用短语to style表示将源代码文件分解为范围。但是请记住,颜色与语法定义不同,而且作用域除了语法高亮之外还有更多用途。
以下是我们想要在片段中设置样式的元素:
•变量 ( $PARAM1, $USER_NAME\ ...)
•简单字段 ( $0, $1\ ...)
•带有占位符 ( ${1:Hello}) 的复杂字段
•嵌套字段 ( ${1:Hello ${2:World}!})
•转义序列 ( \$, \<, ...)
•非法序列 ( $, <, \, ...)
以下是我们不想设置样式的元素,因为它们对于本示例来说太复杂了:
•变量替换 ( ${1/Hello/Hi/g})
笔记
在继续之前,请确保您已按照上述说明安装了PackageDev包。
创建新的语法定义
要创建新的语法定义,请执行以下步骤:
1.转到工具 | 套餐 | 包开发 | 新的语法定义
2.将新文件Packages/User作为.YAML-tmLanguage文件保存在您的文件夹中。
你现在应该看到一个这样的文件:



让我们检查一下关键要素。
•name
Sublime Text 将在语法定义下拉列表中显示的名称。使用简短的描述性名称。通常,您将使用为其创建语法定义的编程语言的名称。
•scopeName
此语法定义的最高范围。它采用形式 source.<lang_name>或text.<lang_name>。对于编程语言,请使用source. 对于标记和其他所有内容,请使用text.
•fileTypes
这是一个文件扩展名列表(没有前导点)。当打开这些类型的文件时,Sublime Text 会自动为它们激活这个语法定义。
•uuid
这是此语法定义的唯一标识符。每个新的语法定义都有自己的 uuid。即使 Sublime Text 本身忽略它,也不要修改它。
•patterns
您的模式的容器。
对于我们的示例,请使用以下信息填充模板:



笔记
YAML 不是一种非常严格的格式,但是当您不知道它的约定时可能会让人头疼。它支持单引号和双引号,但您也可以省略它们,只要内容不会创建另一个 YAML 文字。如果转换为 Plist 失败,请查看输出面板以获取有关错误的更多信息。稍后我们将解释如何将 YAML 中的语法定义转换为 Plist。这也将涵盖模板中的第一个注释行。
该---和...是可选的。
分析模式
所述patterns阵列可包含多种类型的元件。我们将在以下部分中查看其中的一些。
火柴
比赛采用这种形式:



Sublime Text 使用Oniguruma (打开新窗口)的语法定义中正则表达式的语法。几个现有的语法定义利用了这个正则表达式引擎支持的特性,这些特性不是 perl 样式正则表达式的一部分,因此需要 Oniguruma。
match
正则表达式 Sublime Text 将用于查找匹配项。
name
应应用于任何出现的范围的名称match。
comment
关于此模式的可选注释。
让我们回到我们的例子。它看起来像这样:



也就是说,确保patterns数组为空。
现在我们可以开始为 Sublime 片段添加规则。让我们从简单的字段开始。这些可以与正则表达式匹配,如下所示:



然后我们可以像这样构建我们的模式:



选择正确的范围名称
命名范围有时并不明显。检查Textmate 命名约定 (打开新窗口)有关范围名称的指导。PackageDev根据这些约定自动提供范围名称的补全。如果您想实现与现有颜色的最高兼容性,重用那里列出的基本类别非常重要。
配色方案中有硬编码的范围名称。它们不可能包含您能想到的所有范围名称,因此它们有时会针对标准名称和一些稀有名称(例如 CSS 或 Markdown)。这意味着使用相同语法定义的两种配色方案可能会以不同的方式呈现文本!
还要记住,您应该使用最适合您的需求或偏好的范围名称。constant.numeric如果您有充分的理由,那么将范围分配给数字以外的任何内容是完全 没问题的。
我们也可以将它添加到我们的语法定义中:



笔记
您应该使用两个空格作为缩进。这是 YAML 的推荐缩进,并与如上所示的列表对齐。
我们现在准备将我们的文件转换为.tmLanguage. .tmLanguage出于兼容性原因,语法定义使用 Textmate 的扩展名。如上所述,它们只是 Plist XML 文件。
请按照以下步骤执行转换:
•确保Automatic在工具 | 中选择。构建系统,或选择Convert to ....
•按Ctrl B。一个.tmLanguage文件会为你在同一文件夹作为您的生成.YAML-tmLanguage文件。
•Sublime Text 将重新加载对语法定义的更改。
如果您想知道为什么PackageDev知道您要将文件转换为什么:它在第一个注释行中指定。
您现在已经创建了您的第一个语法定义。接下来,打开一个新文件并使用扩展名保存它.ssraw。缓冲区的语法名称应自动切换为“Sublime Snippet (Raw)”,如果您键入$1或任何其他简单的代码段字段,您应该获得语法突出显示。
让我们继续为环境变量创建另一个规则。



重复以上步骤更新.tmLanguage文件。
微调匹配
例如,您可能已经注意到,整个文本的$PARAM1样式都相同。根据您的需要或个人喜好,您可能希望$脱颖而出。这就是captures切入点。使用捕获,您可以将模式分解为多个组件以单独定位它们。
让我们重写我们以前使用的模式之一captures:



捕获给您的规则带来了复杂性,但它们非常简单。请注意数字如何从左到右引用括号中的组。当然,您可以根据需要拥有任意数量的捕获组。
笔记
感谢PackageDev1,在新行上书写并按 Tab 键将自动完成。'1': {name: }
可以说,您希望另一个范围与这个范围在视觉上保持一致。继续并改变它。
笔记
与通常的正则表达式和替换一样,捕获组 '0'适用于整个匹配。
开始结束规则
到目前为止,我们一直在使用一个简单的规则。尽管我们已经了解了如何将模式分解为更小的组件,但有时您还是希望将源代码的大部分目标明确地由开始和结束标记分隔。
用引号或其他定界结构括起来的文字字符串最好由开始-结束规则处理。这是以下规则之一的骨架:



好吧,至少在他们最简单的版本中。让我们来看看一个包含所有可用选项的选项:



有些元素可能看起来很熟悉,但它们的组合可能令人生畏。让我们分别检查它们。
name
就像简单的捕获一样,这会将以下范围名称设置为整个匹配,包括begin和end标记。实际上,这将创建嵌套的范围beginCaptures,endCaptures 以及patterns该规则中定义。选修的。
contentName
与namethis 仅将范围名称应用于封闭文本不同。选修的。
begin
此范围的开始标记的正则表达式。
end
此范围的结束标记的正则表达式。
beginCaptures
为begin标记捕获。它们的工作方式类似于简单匹配的捕获。选修的。
endCaptures
与beginCaptures但对于end标记相同。选修的。
patterns
仅与开始结束的内容匹配的模式数组;他们不反对由消耗的文本匹配begin或 end自己。选修的。
我们将使用此规则在片段中设置嵌套复杂字段的样式:



这是我们将在本教程中看到的最复杂的模式。的begin和 end键是不言自明的:它们定义之间包围的区域 ${<NUMBER>:和}。我们需要将开始模式包装到引号中,否则结尾:会告诉解析器期待另一个字典键。beginCaptures进一步将开始标记划分为更小的范围。
然而,最有趣的部分是patterns. 递归和排序的重要性终于在这里出现了。
我们在上面已经看到字段可以嵌套。为了解决这个问题,我们需要递归地设置嵌套字段的样式。这就是include当我们为它提供$self值时规则所做的:它递归地将我们的整个语法定义应用于我们的开始 - 结束规则捕获的文本。这部分排除单独由正则表达式所消耗的文本begin和 end。
请记住,匹配的文本会被消耗;因此,它被排除在下一次匹配尝试之外并且不能再次匹配。
为了完成复杂的字段,我们将占位符的样式设置为字符串。由于我们已经匹配了复杂字段中所有可能的标记,我们可以安全地告诉 Sublime Text 给任何剩余的文本 ( .) 一个文字字符串范围。请注意,如果我们使模式贪婪 ( .+) ,这将不起作用,因为这包括可能的嵌套引用。
笔记
我们可以使用contentName: string.other.ssraw而不是最后一个模式,但通过这种方式我们介绍了排序的重要性以及如何使用匹配。
最后的润色
最后,让我们对转义序列和非法序列进行样式设置,然后我们就可以结束了。



这里唯一困难的事情是不要忘记[]将数组包含在 YAML 中,因此必须用引号括起来。除此之外,如果您熟悉正则表达式,规则非常简单。
但是,您必须注意将第二条规则放在与该$字符匹配的任何其他规则之后,否则它将被消耗并导致后面的每个表达式都不匹配。
此外,即使添加了这两个附加规则,请注意我们上面的递归开始-结束规则继续按预期工作。
最后,这是最终的语法定义:



使用“存储库”有更多可用的构造和代码重用技术,但上述解释应该可以帮助您开始创建语法定义。
笔记
如果您之前使用 JSON 进行语法定义,您仍然可以这样做,因为PackageDev是向后兼容的。
如果您想考虑切换到 YAML(从 JSON 或直接从 Plist),它提供了一个名为的命令,该命令PackageDev: Convert to YAML and Rearrange Syntax Definition将以愉快的方式自动格式化生成的 YAML。
 

上一篇:Sublime text 命令面板介绍

下一篇:返回列表

微信公众号

  • 回到顶部
  • 15210221926
  • Goldk-AGE
  • 微信公众号