yggdrasil/syntaxes/TypeScript.sublime-syntax
xfy d549f4a476 feat(highlight): 新增 TypeScript 语法高亮
新增 syntaxes/TypeScript.sublime-syntax,覆盖声明/控制流关键字、
interface/type/enum 类型声明、函数声明与箭头函数、装饰器、原始类型
与标准库类型、访问修饰符、模板字符串(含 ${} 插值)、各类数字字面量。

同时修复别名表:移除旧的 ts/typescript/tsx -> js 降级映射。这些别名
在没有 TS 语法时是临时降级方案,但 find_syntax 按扩展名->名字->别名
顺序匹配,别名会抢先于扩展名命中内置 JS,导致新增的 TS 语法被永久
遮蔽(诊断输出为 source js 而非 source ts)。改为映射 typescript -> ts
扩展名,使其正确走自定义 TypeScript 语法。

新增两个回归测试覆盖关键字/类型高亮与别名解析。
2026-06-16 15:35:44 +08:00

223 lines
6.5 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

%YAML 1.2
---
# https://www.typescriptlang.org/docs/handbook/intro.html
# Sublime Text syntax definition for TypeScript / TSX.
name: TypeScript
scope: source.ts
file_extensions:
- ts
- tsx
- mts
- cts
variables:
identifier: '[A-Za-z_$][A-Za-z0-9_$]*'
line_break: '(?:\x0D\x0A?|\x0A)'
contexts:
main:
- include: whitespace
- include: comments
- include: decorator
- include: strings
- include: numbers
- include: declaration-keywords
- include: control-keywords
- include: modifiers
- include: type-declaration
- include: function-declaration
- include: types
- include: constants
- include: function-calls
- include: property-access
- include: punctuation
- include: identifiers
whitespace:
- match: '[\t ]+'
comments:
- match: '/\*'
scope: punctuation.definition.comment.ts
push:
- meta_scope: comment.block.ts
- match: '\*/'
scope: punctuation.definition.comment.ts
pop: 1
- match: '//'
scope: punctuation.definition.comment.ts
push:
- meta_scope: comment.line.double-slash.ts
- match: '{{line_break}}'
pop: 1
# 装饰器:@Component、@Injectable
decorator:
- match: '@{{identifier}}(?:\.{{identifier}})*'
scope: entity.other.attribute-name.ts
push:
- match: '\('
scope: punctuation.section.arguments.begin.ts
push:
- match: '\)'
scope: punctuation.section.arguments.end.ts
pop: 1
- include: main
- match: '(?=\S)'
pop: 1
strings:
# 模板字符串 `...${expr}...`
- match: '`'
scope: punctuation.definition.string.begin.ts
push:
- meta_scope: string.quoted.other.ts
- match: '\$\{'
scope: punctuation.section.interpolation.begin.ts
push:
- clear_scopes: 1
- meta_scope: meta.interpolation.ts
- include: main
- match: '\}'
scope: punctuation.section.interpolation.end.ts
pop: 1
- match: '\\[nrt`\\$]'
scope: constant.character.escape.ts
- match: '`'
scope: punctuation.definition.string.end.ts
pop: 1
# 双引号字符串
- match: '"'
scope: punctuation.definition.string.begin.ts
push:
- meta_scope: string.quoted.double.ts
- match: '\\[nrt"\\]'
scope: constant.character.escape.ts
- match: '"'
scope: punctuation.definition.string.end.ts
pop: 1
- match: '{{line_break}}'
scope: invalid.illegal.unclosed-string.ts
pop: 1
# 单引号字符串
- match: "'"
scope: punctuation.definition.string.begin.ts
push:
- meta_scope: string.quoted.single.ts
- match: "\\\\[nrt'\\\\]"
scope: constant.character.escape.ts
- match: "'"
scope: punctuation.definition.string.end.ts
pop: 1
numbers:
# 十六进制
- match: '\b0[xX][0-9A-Fa-f_]+'
scope: constant.numeric.integer.hexadecimal.ts
# 二进制
- match: '\b0[bB][01_]+'
scope: constant.numeric.integer.binary.ts
# 八进制
- match: '\b0[oO][0-7_]+'
scope: constant.numeric.integer.octal.ts
# 浮点(含科学计数法)
- match: '\b[0-9][0-9_]*(?:\.[0-9][0-9_]*)?(?:[eE][-+]?[0-9]+)?\b'
scope: constant.numeric.decimal.ts
# BigInt 后缀
- match: '\b[0-9][0-9_]*n\b'
scope: constant.numeric.integer.decimal.ts
# 声明类关键字
declaration-keywords:
- match: '\b(?:var|let|const|function|class|interface|type|enum|namespace|module|import|export|from|as|default)\b'
scope: keyword.declaration.ts
- match: '\b(?:new|delete|typeof|instanceof|in|of|keyof|infer|is|readonly|asserts)\b'
scope: keyword.operator.type.ts
# 控制流关键字
control-keywords:
- match: '\b(?:if|else|for|while|do|switch|case|break|continue|return|throw|try|catch|finally|await|yield)\b'
scope: keyword.control.ts
- match: '\b(?:async|await)\b'
scope: keyword.control.async.ts
- match: '\b(?:true|false|null|undefined|this|super)\b'
scope: constant.language.ts
# 访问修饰符
modifiers:
- match: '\b(?:public|private|protected|static|abstract|readonly|override|declare|get|set)\b'
scope: storage.modifier.ts
# type 别名与 interface 的名字识别
type-declaration:
- match: '\b(type)\s+({{identifier}})'
captures:
1: keyword.declaration.ts
2: entity.name.type.ts
- match: '\b(interface)\s+({{identifier}})'
captures:
1: keyword.declaration.ts
2: entity.name.type.ts
- match: '\b(enum)\s+({{identifier}})'
captures:
1: keyword.declaration.ts
2: entity.name.type.ts
# 函数声明function name( / 方法名(
function-declaration:
- match: '\b(function)\s+\*?\s*({{identifier}})'
captures:
1: keyword.declaration.ts
2: entity.name.function.ts
- match: '\b({{identifier}})\s*(?=\(|\<)'
captures:
1: entity.name.function.ts
# 内置/常用类型
types:
- match: '\b(?:string|number|boolean|void|object|symbol|bigint|never|unknown|any)\b'
scope: support.type.primitive.ts
- match: '\b(?:Array|Promise|Map|Set|Date|RegExp|Error|Record|Partial|Required|Readonly|Pick|Omit|ReturnType|Parameters|InstanceType|ReadonlyArray)\b'
scope: support.type.ts
# 常量
constants:
- match: '\b(?:console|Math|JSON|Object|Number|String|Boolean|Symbol|window|document|globalThis|process)\b'
scope: support.class.ts
- match: '\b[A-Z][A-Z0-9_]+\b'
scope: variable.other.constant.ts
# 函数调用
function-calls:
- match: '\b({{identifier}})\s*(?=\()'
captures:
1: variable.function.ts
# 属性访问:.method(
property-access:
- match: '\.({{identifier}})\s*(?=\()'
captures:
1: variable.function.ts
- match: '\.({{identifier}})\b'
captures:
1: variable.other.property.ts
punctuation:
- match: '[\(\)\{\}\[\];,]'
scope: punctuation.ts
- match: '=>'
scope: storage.type.function.arrow.ts
- match: '<(?=[A-Za-z_$])'
scope: punctuation.definition.typeparameters.begin.ts
- match: '=>|[-+*/%=<>!&|?~^]+'
scope: keyword.operator.ts
# 大写开头的标识符视为类型/类名
identifiers:
- match: '\b[A-Z][A-Za-z0-9_$]*\b'
scope: entity.name.type.ts
- match: '{{identifier}}'
scope: variable.ts