TypeScript-TmLanguage/TypeScriptReact.YAML-tmLang...

210 строки
6.4 KiB
YAML

# [PackageDev] target_format: plist, ext: tmLanguage
# Similar to TypeScript.YAML-tmLanguage except:
# - Remove type assertion (cast.expr.tsx)
# - Add JSX expression (HTML-like expression).
---
name: TypeScriptReact
scopeName: source.tsx
fileTypes: [tsx]
uuid: 805375ec-d614-41f5-8993-5843fe63ea82
repository:
# Additions:
# expression repository need to include jsx first followed by whaterver ts grammar says
expression:
patterns:
- include: '#jsx'
# Overrides:
# We need to override this to make sure cast is not matched from typescript
# We can safely include jsx because thats the first rule matched anyways so it wont impact at all
cast:
patterns:
- include: '#jsx'
# jsx syntax is taken from https://github.com/babel/babel-sublime
jsx-tag-attributes:
patterns:
- include: '#jsx-tag-attribute-name'
- include: '#jsx-tag-attribute-assignment'
- include: '#jsx-string-double-quoted'
- include: '#jsx-string-single-quoted'
- include: '#jsx-evaluated-code'
jsx-tag-attribute-name:
match: |-
(?x)
\s*
([_$a-zA-Z][-$\w]*)
(?=\s|=|/?>|/\*|//)
captures:
'1': {name: entity.other.attribute-name.tsx}
jsx-tag-attribute-assignment:
name: keyword.operator.assignment.tsx
match: =(?=\s*(?:'|"|{|/\*|//|\n))
jsx-string-double-quoted:
name: string.quoted.double.tsx
begin: '"'
end: '"'
beginCaptures:
'0': {name: punctuation.definition.string.begin.tsx}
endCaptures:
'0': {name: punctuation.definition.string.end.tsx}
patterns:
- include: '#jsx-entities'
jsx-string-single-quoted:
name: string.quoted.single.tsx
begin: "'"
end: "'"
beginCaptures:
'0': {name: punctuation.definition.string.begin.tsx}
endCaptures:
'0': {name: punctuation.definition.string.end.tsx}
patterns:
- include: '#jsx-entities'
jsx-entities:
patterns:
- name: constant.character.entity.tsx
match: (&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)
captures:
'1': {name: punctuation.definition.entity.tsx}
'3': {name: punctuation.definition.entity.tsx}
- name: invalid.illegal.bad-ampersand.tsx
match: '&'
jsx-evaluated-code:
name: meta.embedded.expression.tsx
begin: \{
end: \}
beginCaptures:
'0': { name: punctuation.section.embedded.begin.tsx }
endCaptures:
'0': { name: punctuation.section.embedded.end.tsx }
patterns:
- include: '#expression'
jsx-tag-attributes-illegal:
name: invalid.illegal.attribute.tsx
match: \S+
jsx-tag-without-attributes-in-expression:
begin: |-
(?x)
(?<=[({\[,?=>:*]|&&|\|\||\?|\Wreturn|^return|\Wdefault|^)\s*
(?=(<)\s*((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\w.]*))(?<!\.|-))\s*(>))
end: (?!\s*(<)\s*((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\w.]*))(?<!\.|-))\s*(>))
patterns:
- include: '#jsx-tag-without-attributes'
jsx-tag-without-attributes:
name: meta.tag.without-attributes.tsx
begin: (<)\s*((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\w.]*))(?<!\.|-))\s*(>)
end: (</)\s*((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\w.]*))(?<!\.|-))\s*(>)
beginCaptures:
'1': {name: punctuation.definition.tag.begin.tsx}
'2': {name: entity.name.tag.tsx}
'3': {name: support.class.component.tsx}
'4': {name: punctuation.definition.tag.end.tsx}
endCaptures:
'1': {name: punctuation.definition.tag.begin.tsx}
'2': {name: entity.name.tag.tsx}
'3': {name: support.class.component.tsx}
'4': {name: punctuation.definition.tag.end.tsx}
contentName: meta.jsx.children.tsx
patterns:
- include: '#jsx-children'
jsx-tag-in-expression:
# We need to differentiate between the relational '<' operator and the beginning of a tag using the surrounding context.
begin: |-
(?x)
(?<=[({\[,?=>:*]|&&|\|\||\?|\Wreturn|^return|\Wdefault|^)\s*
(?!<\s*[_$[:alpha:]][_$[:alnum:]]*((\s+extends\s+[^=>])|,)) # look ahead is not type parameter of arrow
(?=(<)\s*
([_$a-zA-Z][-$\w.]*(?<!\.|-))
(?=\s+(?!\?)|/?>))
end: (/>)|(?:(</)\s*((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\w.]*))(?<!\.|-))\s*(>))
endCaptures:
'0': { name: meta.tag.tsx }
'1': { name: punctuation.definition.tag.end.tsx }
'2': { name: punctuation.definition.tag.begin.tsx }
'3': { name: entity.name.tag.tsx }
'4': { name: support.class.component.tsx }
'5': { name: punctuation.definition.tag.end.tsx }
patterns:
- include: '#jsx-tag'
jsx-child-tag:
# Because this would be included from the jsx-children, this doesnt need to inspect surrounding context
begin: |-
(?x)
(?=(<)\s*
([_$a-zA-Z][-$\w.]*(?<!\.|-))
(?=\s+(?!\?)|/?>))
end: (/>)|(?:(</)\s*((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\w.]*))(?<!\.|-))\s*(>))
endCaptures:
'0': { name: meta.tag.tsx }
'1': { name: punctuation.definition.tag.end.tsx }
'2': { name: punctuation.definition.tag.begin.tsx }
'3': { name: entity.name.tag.tsx }
'4': { name: support.class.component.tsx }
'5': { name: punctuation.definition.tag.end.tsx }
patterns:
- include: '#jsx-tag'
jsx-tag:
name: meta.tag.tsx
begin: |-
(?x)
(?=(<)\s*
([_$a-zA-Z][-$\w.]*(?<!\.|-))
(?=\s+(?!\?)|/?>))
end: (?=(/>)|(?:(</)\s*([_$a-zA-Z][-$\w.]*(?<!\.|-))\s*(>)))
patterns:
- begin: |-
(?x)
(<)\s*
((?:[a-z][a-z0-9]*|([_$a-zA-Z][-$\w.]*))(?<!\.|-))
(?=\s+(?!\?)|/?>)
beginCaptures:
'1': { name: punctuation.definition.tag.begin.tsx }
'2': { name: entity.name.tag.tsx }
'3': { name: support.class.component.tsx }
end: (?=[/]?>)
patterns:
- include: '#comment'
- include: '#jsx-tag-attributes'
- include: '#jsx-tag-attributes-illegal'
- begin: (>)
beginCaptures:
'1': { name: punctuation.definition.tag.end.tsx }
end: (?=</)
contentName: meta.jsx.children.tsx
patterns:
- include: '#jsx-children'
jsx-tag-invalid:
name: invalid.illegal.tag.incomplete.tsx
match: <\s*>
jsx-children:
patterns:
- include: '#jsx-tag-without-attributes'
- include: '#jsx-child-tag'
- include: '#jsx-tag-invalid'
- include: '#jsx-evaluated-code'
- include: '#jsx-entities'
jsx:
patterns:
- include: '#jsx-tag-without-attributes-in-expression'
- include: '#jsx-tag-in-expression'
- include: '#jsx-tag-invalid'
...