克隆 Sublime Text 3 的语法高亮定义

9
有没有一种简单的方法可以从现有的高亮定义中派生自己的定制sublime text 3高亮定义?
我已经安装了AAAPackageDev,如创建新的高亮语法定义教程所建议的那样,但是我发现克隆一个将使我更快地开始。至少,我想知道如何浏览与sublime一起提供的默认语法定义。
如果你真的想非常具体,我所希望实现的只是一个原始的高亮方案,在我的自定义开放和关闭令牌之间的任何字符串都会被着色。在我自己定义的另一对不同的令牌之间的任何字符串都将用第二种颜色着色。一个好处是也可以将令牌本身变灰。
(Ubuntu 14.04)
谢谢!
2个回答

21
2015年5月10日更新:Sublime Text 3 build 3084引入了全新的sublime-syntax格式,用于编写语法定义。它比旧系统更好,Sublime从TextMate继承了旧系统。新系统应该很快出现在公共ST3 beta版本中。由于ST3是推荐使用的Sublime版本,建议使用新系统而不是下面描述的系统编写任何新的高亮显示器。


这里是Sublime Text语法高亮的速成课程。
设置
首先,正如@lthreed指出的那样,你可以使用PackageResourceViewer查看Sublime Text附带的默认包。这些.tmLanguage文件都是以plist格式编写的,非常难以阅读和理解。 PackageDev可以将plist文件转换为更易读的JSON或YAML格式。在查看默认包时,请确保首先将其转换为YAML。请注意,PackageDev可能无法完美地转换它。不要紧,你只需将代码用作参考即可。 plist是Sublime理解的本机格式,但这并不意味着你应该像那样编写它。我强烈建议你使用YAML编写你的高亮器,并使用PackageDev将其转换为plist。不要用JSON编写它。JSON不支持原始字符串。所有正则表达式都必须进行双重转义。这是一场绝对的噩梦。只需使用YAML即可。
你可以通过打开命令面板(在Mac上按cmd+shift+p)并选择PackageDev: New YAML Syntax Definition来开始一个新的语法定义。当你准备好进行测试时,打开命令面板并选择PackageDev: Convert (YAML, JSON, PList) to...,PackageDev将会确定你有一个YAML文件并想要转换为plist。转换会将您的.YAML-tmLanguage文件转换为Sublime能够理解的.tmLanguage文件。将该文件放置在/Packages/User目录中,Sublime将会加载并应用它(您可能需要重新启动)。
Sublime的语法高亮是如何工作的?
您正在编写的语法定义不会直接为文本着色。它将“作用域名称”应用于文本。然后,像 Monokai 和 Solarized 这样的主题作者会制作文件,将作用域名称与颜色关联起来。您可以自己编写作用域名称,但应坚持使用官方 TextMate 作用域名称。这些作用域名称可能对您匹配的代码毫无意义。没关系。尽力而为即可。如果必须编写一个作用域名称,请以 TextMate 作用域名称为起点。例如,不要使用 string.quoted.double.xxx(其中 xxx 是您匹配的语言的文件扩展名),而是可以编写一个称为 string.quoted.triple.xxx 的作用域名称。

代码示例

下面是一个假想的 matt 语言的语法定义,其文件扩展名为 .matt。它只有两个规则:一个用于匹配一个带有管道分隔符的字符串,另一个用于匹配一个带有更复杂分隔符的字符串。

# [PackageDev] target_format: plist, ext: tmLanguage
---
name: Mattlang
scopeName: source.matt
fileTypes: [matt]

patterns:
- include: '#pipe-string'
- include: '#complex-string'

# Rules defined in the repository can reference each other. You can include
# one rule inside another.
repository:
  # This is a rule of the begin-end form. The rule matches a string bounded by
  # pipes, such as |hello there|
  pipe-string:
    # The optional 'name' field lets you apply a single scope to everything,
    # including the begin-end pipes. All the scope names must end with .matt
    name: everything.matt
    # We have to escape the pipe character, because it's a special character in
    # the Oniguruma regex syntax (and most other regex engines).
    begin: \|
    # 'beginCaptures' is required if you want the pipes to be colored differently
    beginCaptures:
      # In regex jargon, the begin pipe is 'captured'. Capture group 0 means the
      # entire match, which in this case is just the pipe.
      '0': {name: entire.begin.match.matt}
    # The optional 'contentName' field lets you apply a scope to all the text
    # between (but not including) the begin-end pipes.
    contentName: stuff.between.the.pipes.matt
    patterns:
    # These rules will only be applied to the text *BETWEEN* the pipes. Sublime
    # will go through the rules from top to bottom and try to match the text, so
    # higher rules have a higher "precedence" and will get matched first.
    # Given the text |hello there|, Sublime will see an 'h' character and move
    # through the rules from top to bottom trying to find a rule that starts
    # with 'h'. The #hell rule will match the 'h' and the rest of the
    # characters. The #hell scope name will be applied to the 'hell' text and 
    # Sublime will resume trying to find the next match at the 'o' character.
    # The 'o' character WILL NOT match #hello. You can think of the matched text
    # as being removed from the stream entirely. The point is: order matters.
    - include: '#hell'
    - include: '#hello'
    - end: \|
    endCaptures:
      '0': {name: entire.end.match.matt}

  # This is the other form of rule you can define. It's extremely simple --
  # just a scope name and a regex pattern to match. Note that these rules will
  # only match text on the same line, unlike begin-end rules, which can cover
  # multiple lines.
  hell:
    name: some.other.scope.matt
    match: hell

  hello:
    name: some.scope.matt
    match: hello

  # This rule matches a string that starts with $!! and ends with !!$,
  # e.g. !!$hello there!!$
  complex-string:
    # I've labeled the capture groups.
    #      |---0---|
    #      |--1-||3|
    begin: (!(!))($)
    #        |2|
    beginCaptures:
      '0': {name: full.match.matt}
      '1': {name: both.exclamation.marks.matt}
      '2': {name: second.exclamation.mark.matt}
      '3': {name: dollar.sign.matt}
    # It's ok to leave out the 'patterns' field. Technically, all you really
    # need is a 'begin' field and an 'end' field.
    end: ((!)!)($)
    endCaptures:
      '0': {name: everything.matt}
      '1': {name: both.exclamation.marks.matt}
      '2': {name: first.exclamation.mark.matt}
      '3': {name: dollar.sign.matt}

7

如果您安装了PackageResourceViewer,则可以打开任何内置的压缩资源。执行PackageResourceViewer: Open Resource,然后选择您熟悉的语言。接着选择带有.tmLanguage扩展名的文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接