@wooorm/starry-night
Version:
Syntax highlighting, like GitHub
505 lines (502 loc) • 16.9 kB
JavaScript
// This is a TextMate grammar distributed by `starry-night`.
// This grammar is developed at
// <https://github.com/JohnnyMorganz/Luau.tmLanguage>
// and licensed `mit`.
// See <https://github.com/wooorm/starry-night> for more info.
/**
* @import {Grammar} from '@wooorm/starry-night'
*/
/** @type {Grammar} */
const grammar = {
extensions: ['.luau'],
names: ['luau'],
patterns: [
{include: '#function-definition'},
{include: '#number'},
{include: '#string'},
{include: '#shebang'},
{include: '#comment'},
{include: '#local-declaration'},
{include: '#for-loop'},
{include: '#type-alias-declaration'},
{include: '#keyword'},
{include: '#language_constant'},
{include: '#standard_library'},
{include: '#identifier'},
{include: '#operator'},
{include: '#parentheses'},
{include: '#table'},
{include: '#type_cast'},
{include: '#type_annotation'},
{include: '#attribute'}
],
repository: {
attribute: {
patterns: [
{
captures: {
1: {name: 'keyword.operator.attribute.luau'},
2: {name: 'storage.type.attribute.luau'}
},
match: '(@)([a-zA-Z_][a-zA-Z0-9_]*)',
name: 'meta.attribute.luau'
}
]
},
comment: {
patterns: [
{
begin: '--\\[(=*)\\[',
end: '\\]\\1\\]',
name: 'comment.block.luau',
patterns: [
{
begin: '(```luau?)\\s+',
beginCaptures: {1: {name: 'comment.luau'}},
end: '(```)',
endCaptures: {1: {name: 'comment.luau'}},
name: 'keyword.operator.other.luau',
patterns: [{include: 'source.luau'}]
},
{include: '#doc_comment_tags'}
]
},
{
begin: '---',
end: '\\n',
name: 'comment.line.double-dash.documentation.luau',
patterns: [{include: '#doc_comment_tags'}]
},
{begin: '--', end: '\\n', name: 'comment.line.double-dash.luau'}
]
},
doc_comment_tags: {
patterns: [
{match: '@\\w+', name: 'storage.type.class.luadoc.luau'},
{
captures: {
1: {name: 'storage.type.class.luadoc.luau'},
2: {name: 'variable.parameter.luau'}
},
match: '((?<=[\\s*!\\/])[\\\\@]param)(?:\\s)+(\\b\\w+\\b)'
}
]
},
'for-loop': {
begin: '\\b(for)\\b',
beginCaptures: {1: {name: 'keyword.control.luau'}},
end: '\\b(in)\\b|(=)',
endCaptures: {
1: {name: 'keyword.control.luau'},
2: {name: 'keyword.operator.assignment.luau'}
},
patterns: [
{
begin: '(:)',
beginCaptures: {1: {name: 'keyword.operator.type.luau'}},
end: '(?=\\s*in\\b|\\s*[=,]|\\s*$)',
patterns: [{include: '#type_literal'}]
},
{
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b',
name: 'variable.parameter.luau'
}
]
},
'function-definition': {
begin: '\\b(?:(local)\\s+)?(function)\\b(?![,:])',
beginCaptures: {
1: {name: 'storage.modifier.local.luau'},
2: {name: 'keyword.control.luau'}
},
end: '(?<=[\\)\\-{}\\[\\]"\'])',
name: 'meta.function.luau',
patterns: [
{include: '#comment'},
{include: '#generics-declaration'},
{
begin: '(\\()',
beginCaptures: {
1: {name: 'punctuation.definition.parameters.begin.luau'}
},
end: '(\\))',
endCaptures: {
1: {name: 'punctuation.definition.parameters.end.luau'}
},
name: 'meta.parameter.luau',
patterns: [
{include: '#comment'},
{
match: '\\.\\.\\.',
name: 'variable.parameter.function.varargs.luau'
},
{
match: '[a-zA-Z_][a-zA-Z0-9_]*',
name: 'variable.parameter.function.luau'
},
{match: ',', name: 'punctuation.separator.arguments.luau'},
{
begin: ':',
beginCaptures: {0: {name: 'keyword.operator.type.luau'}},
end: '(?=[\\),])',
patterns: [{include: '#type_literal'}]
}
]
},
{
match:
'\\b(__add|__call|__concat|__div|__eq|__index|__le|__len|__lt|__metatable|__mod|__mode|__mul|__newindex|__pow|__sub|__tostring|__unm|__iter|__idiv)\\b',
name: 'variable.language.metamethod.luau'
},
{
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b',
name: 'entity.name.function.luau'
}
]
},
'generics-declaration': {
begin: '(<)',
end: '(>)',
patterns: [
{match: '[a-zA-Z_][a-zA-Z0-9_]*', name: 'entity.name.type.luau'},
{match: '=', name: 'keyword.operator.assignment.luau'},
{include: '#type_literal'}
]
},
identifier: {
patterns: [
{
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b(?=\\s*(?:[({"\']|\\[\\[))',
name: 'entity.name.function.luau'
},
{
match: '(?<=[^.]\\.|:)\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b',
name: 'variable.other.property.luau'
},
{
match: '\\b([A-Z_][A-Z0-9_]*)\\b',
name: 'variable.other.constant.luau'
},
{
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b',
name: 'variable.other.readwrite.luau'
}
]
},
interpolated_string_expression: {
begin: '\\{',
beginCaptures: {
0: {
name: 'punctuation.definition.interpolated-string-expression.begin.luau'
}
},
contentName: 'meta.embedded.line.luau',
end: '\\}',
endCaptures: {
0: {
name: 'punctuation.definition.interpolated-string-expression.end.luau'
}
},
name: 'meta.template.expression.luau',
patterns: [{include: 'source.luau'}]
},
keyword: {
patterns: [
{
match:
'\\b(break|do|else|for|if|elseif|return|then|repeat|while|until|end|in|continue)\\b',
name: 'keyword.control.luau'
},
{match: '\\b(local)\\b', name: 'storage.modifier.local.luau'},
{match: '\\b(function)\\b(?![,:])', name: 'keyword.control.luau'},
{
match: '(?<![^.]\\.|:)\\b(self)\\b',
name: 'variable.language.self.luau'
},
{
match: '\\b(and|or|not)\\b',
name: 'keyword.operator.logical.luau keyword.operator.wordlike.luau'
},
{
match:
'(?<=[^.]\\.|:)\\b(__add|__call|__concat|__div|__eq|__index|__le|__len|__lt|__metatable|__mod|__mode|__mul|__newindex|__pow|__sub|__tostring|__unm)\\b',
name: 'variable.language.metamethod.luau'
},
{match: '(?<![.])\\.{3}(?!\\.)', name: 'keyword.other.unit.luau'}
]
},
language_constant: {
patterns: [
{
match: '(?<![^.]\\.|:)\\b(false)\\b',
name: 'constant.language.boolean.false.luau'
},
{
match: '(?<![^.]\\.|:)\\b(true)\\b',
name: 'constant.language.boolean.true.luau'
},
{
match: '(?<![^.]\\.|:)\\b(nil(?!:))\\b',
name: 'constant.language.nil.luau'
}
]
},
'local-declaration': {
begin: '\\b(local)\\b',
beginCaptures: {1: {name: 'storage.modifier.local.luau'}},
end: '(?=\\s*do\\b|\\s*[=;]|\\s*$)',
patterns: [
{include: '#comment'},
{include: '#attribute'},
{
begin: '(:)',
beginCaptures: {1: {name: 'keyword.operator.type.luau'}},
end: '(?=\\s*do\\b|\\s*[=;,]|\\s*$)',
patterns: [{include: '#type_literal'}]
},
{
match: '\\b([A-Z_][A-Z0-9_]*)\\b',
name: 'variable.other.constant.luau'
},
{
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b',
name: 'variable.other.readwrite.luau'
}
]
},
number: {
patterns: [
{
match:
'\\b0_*[xX]_*[\\da-fA-F_]*(?:[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?',
name: 'constant.numeric.hex.luau'
},
{
match:
'\\b0_*[bB][01_]+(?:[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?',
name: 'constant.numeric.binary.luau'
},
{
match:
'(?:\\d[\\d_]*(?:\\.[\\d_]*)?|\\.\\d[\\d_]*)(?:[eE][\\+\\-]?_*\\d[\\d_]*(?:\\.[\\d_]*)?)?',
name: 'constant.numeric.decimal.luau'
}
]
},
operator: {
patterns: [
{match: '==|~=|!=|<=?|>=?', name: 'keyword.operator.comparison.luau'},
{
match: '\\+=|-=|/=|//=|\\*=|%=|\\^=|\\.\\.=|=',
name: 'keyword.operator.assignment.luau'
},
{
match: '\\+|-|%|\\*|\\/\\/|\\/|\\^',
name: 'keyword.operator.arithmetic.luau'
},
{match: '#|(?<!\\.)\\.{2}(?!\\.)', name: 'keyword.operator.other.luau'}
]
},
parentheses: {
begin: '(\\()',
beginCaptures: {1: {name: 'punctuation.arguments.begin.luau'}},
end: '(\\))',
endCaptures: {1: {name: 'punctuation.arguments.end.luau'}},
patterns: [
{match: ',', name: 'punctuation.separator.arguments.luau'},
{include: 'source.luau'}
]
},
shebang: {
captures: {1: {name: 'punctuation.definition.comment.luau'}},
match: '\\A(#!).*$\\n?',
name: 'comment.line.shebang.luau'
},
standard_library: {
patterns: [
{
match:
'(?<![^.]\\.|:)\\b(assert|collectgarbage|error|gcinfo|getfenv|getmetatable|ipairs|loadstring|newproxy|next|pairs|pcall|print|rawequal|rawset|require|select|setfenv|setmetatable|tonumber|tostring|type|typeof|unpack|xpcall)\\b',
name: 'support.function.luau'
},
{
match: '(?<![^.]\\.|:)\\b(_G|_VERSION)\\b',
name: 'constant.language.luau'
},
{
match:
'(?<![^.]\\.|:)\\b(bit32\\.(?:arshift|band|bnot|bor|btest|bxor|extract|lrotate|lshift|replace|rrotate|rshift|countlz|countrz|byteswap)|coroutine\\.(?:create|isyieldable|resume|running|status|wrap|yield|close)|debug\\.(?:info|loadmodule|profilebegin|profileend|traceback)|math\\.(?:abs|acos|asin|atan|atan2|ceil|clamp|cos|cosh|deg|exp|floor|fmod|frexp|ldexp|log|log10|max|min|modf|noise|pow|rad|random|randomseed|round|sign|sin|sinh|sqrt|tan|tanh)|os\\.(?:clock|date|difftime|time)|string\\.(?:byte|char|find|format|gmatch|gsub|len|lower|match|pack|packsize|rep|reverse|split|sub|unpack|upper)|table\\.(?:concat|create|find|foreach|foreachi|getn|insert|maxn|move|pack|remove|sort|unpack|clear|freeze|isfrozen|clone)|task\\.(?:spawn|synchronize|desynchronize|wait|defer|delay)|utf8\\.(?:char|codepoint|codes|graphemes|len|nfcnormalize|nfdnormalize|offset)|buffer\\.(?:create|fromstring|tostring|len|readi8|readu8|readi16|readu16|readi32|readu32|readf32|readf64|writei8|writeu8|writei16|writeu16|writei32|writeu32|writef32|writef64|readstring|writestring|copy|fill))\\b',
name: 'support.function.luau'
},
{
match:
'(?<![^.]\\.|:)\\b(bit32|buffer|coroutine|debug|math(\\.(huge|pi))?|os|string|table|task|utf8(\\.charpattern)?)\\b',
name: 'support.constant.luau'
},
{
match:
'(?<![^.]\\.|:)\\b(delay|DebuggerManager|elapsedTime|PluginManager|printidentity|settings|spawn|stats|tick|time|UserSettings|version|wait|warn)\\b',
name: 'support.function.luau'
},
{
match:
'(?<![^.]\\.|:)\\b(game|plugin|shared|script|workspace|Enum(?:\\.\\w+){0,2})\\b',
name: 'constant.language.luau'
}
]
},
string: {
patterns: [
{
begin: '"',
end: '"',
name: 'string.quoted.double.luau',
patterns: [{include: '#string_escape'}]
},
{
begin: "'",
end: "'",
name: 'string.quoted.single.luau',
patterns: [{include: '#string_escape'}]
},
{
begin: '\\[(=*)\\[',
end: '\\]\\1\\]',
name: 'string.other.multiline.luau'
},
{
begin: '`',
end: '`',
name: 'string.interpolated.luau',
patterns: [
{include: '#interpolated_string_expression'},
{include: '#string_escape'}
]
}
]
},
string_escape: {
patterns: [
{
match: '\\\\[abfnrtvz\'"`{\\\\]',
name: 'constant.character.escape.luau'
},
{match: '\\\\\\d{1,3}', name: 'constant.character.escape.luau'},
{match: '\\\\x[0-9a-fA-F]{2}', name: 'constant.character.escape.luau'},
{
match: '\\\\u\\{[0-9a-fA-F]*\\}',
name: 'constant.character.escape.luau'
},
{match: '\\\\$', name: 'constant.character.escape.luau'}
]
},
table: {
begin: '(\\{)',
beginCaptures: {1: {name: 'punctuation.table.begin.luau'}},
end: '(\\})',
endCaptures: {1: {name: 'punctuation.table.end.luau'}},
patterns: [
{match: '[,;]', name: 'punctuation.separator.fields.luau'},
{include: 'source.luau'}
]
},
'type-alias-declaration': {
begin: '^\\b(?:(export)\\s+)?(type)\\b',
beginCaptures: {
1: {name: 'storage.modifier.visibility.luau'},
2: {name: 'storage.type.luau'}
},
end: '(?=\\s*$)|(?=\\s*;)',
patterns: [
{include: '#type_literal'},
{match: '=', name: 'keyword.operator.assignment.luau'}
]
},
type_annotation: {
begin: ':(?!\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b(?=\\s*(?:[({"\']|\\[\\[)))',
end: '(?<=\\))(?!\\s*->)|=|;|$|(?=\\breturn\\b)|(?=\\bend\\b)',
patterns: [{include: '#comment'}, {include: '#type_literal'}]
},
type_cast: {
begin: '(::)',
beginCaptures: {1: {name: 'keyword.operator.typecast.luau'}},
end: '(?=^|[;),}\\]:?\\-\\+\\>](?!\\s*[&\\|])|$|\\b(break|do|else|for|if|elseif|return|then|repeat|while|until|end|in|continue)\\b)',
patterns: [{include: '#type_literal'}]
},
type_literal: {
patterns: [
{include: '#comment'},
{include: '#string'},
{match: '\\?|\\&|\\|', name: 'keyword.operator.type.luau'},
{match: '->', name: 'keyword.operator.type.function.luau'},
{match: '\\b(false)\\b', name: 'constant.language.boolean.false.luau'},
{match: '\\b(true)\\b', name: 'constant.language.boolean.true.luau'},
{
match: '\\b(nil|string|number|boolean|thread|userdata|symbol|any)\\b',
name: 'support.type.primitive.luau'
},
{
begin: '\\b(typeof)\\b(\\()',
beginCaptures: {
1: {name: 'support.function.luau'},
2: {name: 'punctuation.arguments.begin.typeof.luau'}
},
end: '(\\))',
endCaptures: {1: {name: 'punctuation.arguments.end.typeof.luau'}},
patterns: [{include: 'source.luau'}]
},
{
begin: '(<)',
beginCaptures: {
1: {name: 'punctuation.definition.typeparameters.begin.luau'}
},
end: '(>)',
endCaptures: {
1: {name: 'punctuation.definition.typeparameters.end.luau'}
},
patterns: [
{match: '=', name: 'keyword.operator.assignment.luau'},
{include: '#type_literal'}
]
},
{
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b',
name: 'entity.name.type.luau'
},
{
begin: '\\{',
end: '\\}',
patterns: [
{begin: '\\[', end: '\\]', patterns: [{include: '#type_literal'}]},
{
captures: {
1: {name: 'variable.property.luau'},
2: {name: 'keyword.operator.type.luau'}
},
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b(:)'
},
{include: '#type_literal'},
{match: '[,;]', name: 'punctuation.separator.fields.type.luau'}
]
},
{
begin: '\\(',
end: '\\)',
patterns: [
{
captures: {
1: {name: 'variable.parameter.luau'},
2: {name: 'keyword.operator.type.luau'}
},
match: '\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b(:)',
name: 'variable.parameter.luau'
},
{include: '#type_literal'}
]
}
]
}
},
scopeName: 'source.luau'
}
export default grammar