语法定义

Sublime Text可以同时使用.sublime语法和.tmLanguage文件语法高亮。本文档介绍.sublime语法文件。

概述

升华语法文件是YAML文件具有小头,后跟上下文的列表。每个上下文都有一个模式列表,描述如何在该上下文中突出显示文本,以及如何更改当前文本。

这里有一个小例子用来突出显示C的语法文件。

%YAML 1.2  ---  name: C  file_extensions: [c, h]  scope: source.c    contexts:    main:      - match: \b(if|else|for|while)\b        scope: keyword.control.c  

在它的核心,一个语法定义指定范围(例如,keyword.control.c)文本区域。这些范围由颜色方案用于突出显示文本。

该语法文件包含一个背景下,主要的,相匹配的话[如果,否则,对,同时],并为它们分配范围keyword.control.c。上下文名称主要特别:每一个语法必须定义一个主要方面,因为它会在文件的开头使用。

在比赛关键是一个正则表达式,使用Ruby的语法。在上面的例子中,\ b用于确保仅字边界匹配,以确保字如别处不被视为关键字。

需要注意的是,由于YAML语法,制表符不中不允许.sublime语法文件。

标题

标题区域中的允许键为:

上下文

对于大多数语言,您将需要多个上下文。例如,在C,我们不希望为在一个字符串的中间字加以强调作为关键字。这里有一个如何处理这个的例子:

%YAML 1.2  ---  name: C  file_extensions: [c, h]  scope: source.c    contexts:    main:      - match: \b(if|else|for|while)\b        scope: keyword.control.c      - match: '"'        push: string      string:      - meta_scope: string.quoted.double.c      - match: \\.        scope: constant.character.escape.c      - match: '"'        pop: true  

第二个格局已经添加到相匹配的双引号字符的主要背景(请注意,'“'用于此,作为一个独立的报价将是一个YAML语法错误),并推动一个新的上下文,串,到上下文堆栈,这意味着文件的其余部分将使用字符串上下文而不是主上下文进行处理,直到字符串上下文从堆栈弹出。

字符串上下文引入了一个新的模式:meta_scope。这将分配string.quoted.double.c而字符串上下文是堆栈范围扩大到所有文本。

虽然Sublime Text编辑,你可以查阅一下范围已按适用于尖号下的文本控制+ Shift + P(OSX)或按Ctrl + Alt + Shift + P(Windows和Linux)。

字符串上下文有两种模式:第一个匹配反斜杠字符后跟任何其他,第二个匹配引号字符。注意,最后一个模式指定一个动作:当遇到未转义的引用时,字符串上下文将从上下文栈中弹出,返回使用主上下文分配范围。

当上下文具有多个模式时,将找到最左边的一个。当多个图案在相同位置匹配时,将选择第一个定义的图案。

元模式

必须在上下文中的任何匹配或包含模式之前首先列出元模式。

匹配模式

一个匹配模式可以包含以下键:

注意该动作:推,流行,组,和语法是排他性的,其中只有一个可在单个匹配图案中使用。

在此示例中,正则表达式包括两个捕获,捕获键用于为每个捕获分配不同的范围:

- match: "^\\s*(#)\\s*\\b(include)\\b"    captures:      1: meta.preprocessor.c++      2: keyword.control.include.c++  

包括模式

通常,将一个上下文的内容包括在另一个上下文中是方便的。例如,您可以定义几种不同的上下文来解析C语言,并且几乎所有的上下文都可以包含注释。不要将相关的匹配模式复制到每个上下文中,您可以包括它们:

expr:    - include: comments    - match: \b[0-9]+\b      scope: constant.numeric.c    ...  

这里,所有匹配模式和包含在注释上下文中定义的模式都将被拉入。它们将被插入到包含模式的位置,所以你仍然可以控制模式的顺序。在注释上下文中定义的任何元模式都将被忽略。

使用诸如注释之类的元素,包含它们是很常见的,因为它更容易使它们自动包含在每个上下文中,而只是列出异常。可以通过创建上下文命名为此原型,它会自动在每隔一个上下文的顶部包括,除非上下文使用meta_include_prototype元模式。例如:

prototype:    - include: comments    string:    - meta_include_prototype: false    ...  

在C中,/ *一个字符串内不启动的注释,因此字符串上下文表明原型应该不包括在内。

包括其他文件

Sublime语法文件支持嵌入另一个语法定义的一个语法定义的概念。例如,HTML可以包含嵌入式JavaScript。下面是一个HTML的基本语法定义的例子:

scope: text.html    contexts:    main:      - match: <script>        push: Packages/JavaScript/JavaScript.sublime-syntax        with_prototype:          - match: (?=</script>)            pop: true      - match: "<"        scope: punctuation.definition.tag.begin      - match: ">"        scope: punctuation.definition.tag.end  

注意上面的第一条规则。这表明,当我们遇到一个<SCRIPT>标记中的主要方面JavaScript.sublime语法应推入上下文堆栈。它还定义了另一个关键,with_prototype。这包含了将要插入到内定义的每个上下文模式清单JavaScript.sublime语法。注意,with_prototype是概念上类似于原型上下文,但是它会一直被插入到每一个引用上下文不论其的meta_include_prototype设置。

在这种情况下,会插入将会弹出当前上下文的格局,而下一个文本是</ SCRIPT>标记。请注意,它实际上并不匹配</ SCRIPT>标记,它只是利用前向断言,它在这里扮演两个重要角色:它既允许HTML规则匹配结束标记,彰显其正常每个AS和它将确保所有的JavaScript上下文将被弹出。上下文堆栈可以是在JavaScript串的中间,例如,但当</ SCRIPT>遇到,两者中的JavaScript串和主上下文将得到弹出关闭。

请注意,虽然崇高文本支持.sublime语法和.tmLanguage文件,它不可能包含.tmLanguage一中的文件.sublime语法之一。

另一个常见的场景是包括HTML的模板语言。这里是一个例子,这一次的一个子集神社

scope: text.jinja  contexts:    main:      - match: ""        push: "Packages/HTML/HTML.sublime-syntax"        with_prototype:          - match: "{{"            push: expr      expr:      - match: "}}"        pop: true      - match: \b(if|else)\b        scope: keyword.control  

这与HTML-embedding-JavaScript示例非常不同,因为模板化语言往往从内到外操作:默认情况下,它需要作为HTML,只转义到某些表达式上的底层模板语言。

在上面的示例中,我们可以看到它默认在HTML模式下运行:主上下文包含一个总是匹配,不消耗任何文本,只包括HTML语法的单一模式。

其中,被包括在HTML语法中,神社语法指令({{...}} )经由包括with_prototype键,从而得到注射到HTML语法每上下文(和JavaScript,通过传递性)。

变量

几个正则表达式有相同的部分并不罕见。为了避免重复输入,您可以使用变量:

variables:    ident: '[A-Za-z_][A-Za-z_0-9]*'  contexts:    main:      - match: '\b{{ident}}\b'        scope: keyword.control  

变量必须在.sublime语法文件的顶层被定义,并通过regxes内引用{{VARNAME}} 。变量本身可以包括其他变量。请注意,这不符合任何文本{{[A-ZA-Z0-9 _] +}}将不被视为一个变量,因此正则表达式仍然可以包括文字{{ characers,例如。

所选示例

支架平衡

此示例突出显示了没有相应开放括号的关闭括号:

name: C  scope: source.c    contexts:    main:      - match: \(        push: brackets      - match: \)        scope: invalid.illegal.stray-bracket-end      brackets:      - match: \)        pop: true      - include: main  

顺序上下文

此示例将突出显示包含过多分号的C语言风格:

for_stmt:    - match: \(      set: for_stmt_expr1  for_stmt_expr1:    - match: ";"      set: for_stmt_expr2    - match: \)      pop: true    - include: expr  for_stmt_expr2:    - match: ";"      set: for_stmt_expr3    - match: \)      pop: true    - include: expr  for_stmt_expr3:    - match: \)      pop: true    - match: ";"      scope: invalid.illegal.stray-semi-colon    - include: expr  

高级堆栈使用

在C中,符号常与定义的typedef关键字。这样转到定义可以挑出来,符号应该有entity.name.type重视他们的范围。

这样做可能有点棘手,因为typedef有时很简单,他们可以变得相当复杂:

typedef int coordinate_t;    typedef struct  {      int x;      int y;  } point_t;  

要识别这些,在匹配typedef关键字之后,两个上下文将被压入堆栈:第一个将识别一个类型名称,然后弹出,而第二个将识别类型的引入名称:

main:    - match: \btypedef\b      scope: keyword.control.c      set: [typedef_after_typename, typename]    typename:    - match: \bstruct\b      set:        - match: "{"          set:            - match: "}"              pop: true    - match: \b[A-Za-z_][A-Za-z_0-9]*\b      pop: true    typedef_after_typename:    - match: \b[A-Za-z_][A-Za-z_0-9]*\b      scope: entity.name.type      pop: true  

在上面的例子中,类型名称是一个可重复使用的情况下,将在一个类型名称读取并当它这样做弹出本身堆栈。它可以在需要使用类型的任何上下文中使用,例如在typedef中或作为函数参数。

的主要上下文使用该推栈上两个上下文,与该列表中的最右边的上下文成为堆栈上的最顶层上下文匹配模式。一旦类型名上下文本身弹出,所述typedef_after_typename上下文将在堆栈的顶部。

还要注意内使用匿名上下文为简便起见上述类型名称上下文。

PHP Heredocs

这个例子说明了如何匹配here文档在PHP。在主要方面的匹配模式捕获定界符标识,并在定界符背景下对应的流行模式是指用这个捕获的文本\ 1符号:

name: PHP  scope: source.php    contexts:    main:      - match: <<<([A-Za-z][A-Za-z0-9_]*)        push: heredoc      heredoc:      - meta_scope: string.unquoted.heredoc      - match: ^\1;          pop: true  

测试

当构建一个语法定义,而不是手动检查范围与show_scope_name命令,你可以定义一个语法测试文件,将做检查为您提供:

// SYNTAX TEST "Packages/C/C.sublime-syntax"  #pragma once  // <- source.c meta.preprocessor.c++   // <- keyword.control.import    // foo  // ^ source.c comment.line  // <- punctuation.definition.comment    /* foo */  // ^ source.c comment.block  // <- punctuation.definition.comment.begin  //     ^ punctuation.definition.comment.end    #include "stdio.h"  // <- meta.preprocessor.include.c++  //       ^ meta string punctuation.definition.string.begin  //               ^ meta string punctuation.definition.string.end  int square(int x)  // <- storage.type  //  ^ meta.function entity.name.function  //         ^ storage.type  {      return x * x;  //  ^^^^^^ keyword.control  }    "Hello, World! // not a comment";  // ^ string.quoted.double  //                  ^ string.quoted.double - comment  

要创建一个,请遵循这些规则

  1. 确保文件名开头syntax_test_。
  2. 确保文件保存在Packages目录中的某个位置:对应的.sublime语法文件旁边是一个不错的选择。
  3. 确保文件的第一行开头:<comment_token>语法TEST“<syntax_file>” 。注意,该语法文件可以是一个.sublime语法或.tmLanguage文件。

一旦满足上述条件,运行生成与选择的语法测试或语法定义文件的命令将运行所有语法试验,并显示在输出面板的结果。下一个结果(F4),可用于导航到第一失败的测试。

在语法测试文件中的每个测试必须先启动评论令牌(在第一行建立的,它实际上并不一定要根据语法注释),然后或者一个^或< -令牌。

两种类型的测试是: