%YAML 1.2
---
name: Odin
file_extensions:
- odin
first_line_match: "-[*]-( Mode:)? Odin -[*]-"
scope: source.odin
variables:
identifier: '\b[[:alpha:]_][[:alnum:]_]*\b'
type_chars: '[[:alnum:]\s,._^<>\[\]-]'
screaming_identifier: '\b[A-Z_](?![a-z])[A-Z_0-9]+\b'
contexts:
main:
- include: global
global:
- include: comments
- include: types
- include: keywords
- include: functions-and-declarations
- include: strings
- include: string-escaped-char
block-comment:
- match: /\*
scope: punctuation.definition.comment.odin
push:
- meta_scope: comment.block.odin
- match: \*/
scope: punctuation.definition.comment.odin
pop: true
- include: block-comment
comments:
- include: block-comment
- match: //
scope: punctuation.definition.comment.odin
push:
- meta_scope: comment.line.double-slash.odin
- match: \n
pop: true
- match: "#!"
scope: punctuation.definition.comment.odin
push:
- meta_scope: comment.line.double-slash.odin
- match: \n
pop: true
keywords:
- match: \b(import|foreign|package)\b
scope: keyword.control.odin
- match: \b(if|else|when|for|in|not_in|defer|switch|return|const|do|where)\b
scope: keyword.control.odin
- match: \b(fallthrough|break|continue|case)\b
scope: keyword.control.odin
- match: \b(using|([#]force_inline)|([#]force_no_inline))\b
scope: keyword.control.odin
- match: \b(asm|or_else|or_return|or_break|or_continue)\b
scope: keyword.control.odin
- match: \b(distinct)\b
scope: keyword.operator.odin
- match: \b(context)\b
scope: keyword.operator.odin
- match: '(\!\=)'
scope: keyword.operator.odin
- match: '(\&\&|\|\||\!)'
scope: keyword.logic.odin
- match: (->|\!=|==|::|:=?|\?|=|\*=?|/=?|\+=?|-=?|<<=?|>>=?|>=?|<=?|%=?|\^=?|\|=?|\|\|=?|&=?|&&=?|!=?|~=?|!)
scope: keyword.operator.odin
- match: \b(nil|true|false)\b
scope: constant.language.odin
- match: '\b(\d(\d|_)*(\.\d(\d|_)*)?)((e|E)(\+|-)?\d+)?[ijk]?\b'
scope: constant.numeric.odin
- match: '\b((0b(0|1|_)+)|(0o(\d|_)+)|(0d(\d|_)+)|(0[xXh](\h|_)+))[ijk]?\b'
scope: constant.numeric.odin
- match: '---'
scope: constant.numeric.odin
- match: \b(struct|enum|union|map|bit_set|bit_field|dynamic|matrix)\b
scope: storage.type.odin
- match: \b(cast|transmute|auto_cast)\b
scope: keyword.function.odin
- match: '([#]\s*{{identifier}})'
scope: keyword.tag.odin
- match: '(#\+\s*)(.*(?=(//|/\*))|.*)'
scope: keyword.tag.odin
- match: '(\x40\s*{{identifier}})'
scope: keyword.tag.odin
- match: '(\x40\s*[(]\s*{{identifier}})\s*[)]'
scope: keyword.tag.odin
- match: '@'
scope: keyword.operator.odin
- match: '(\(|\)|\{|\}|\[|\]|,|;)'
scope: punctuation.separator.odin
- match: '(\&|\^)'
scope: keyword.operator.pointer.odin
- match: '(\.)'
scope: punctuation.accessor.odin
functions-and-declarations:
- match: '\b({{identifier}})\s*(:)\s*(:)\s*(proc)'
captures:
1: meta.function.odin entity.name.function.odin
2: keyword.operator.odin
3: keyword.operator.odin
4: storage.type.odin
- match: '\b({{identifier}})\s*(:)\s*(:)\s*([#]force_inline|[#]force_no_inline)\s+(proc)'
captures:
1: meta.function.odin entity.name.function.odin
2: keyword.operator.odin
3: keyword.operator.odin
4: keyword.control.odin
5: storage.type.odin
- match: \b(size_of|align_of|offset_of|type_of)\b\s*(\()
captures:
1: keyword.function.odin
2: punctuation.separator.odin
- match: \b(type_info_of|typeid_of)\b\s*(\()
captures:
1: keyword.function.odin
2: punctuation.separator.odin
- match: (proc)\s*[\(]
captures:
1: storage.type.odin
- match: ({{identifier}})\s*[!]?\s*(\()
captures:
1: support.function.odin
2: punctuation.separator.odin
- match: '\b({{identifier}})\s*(:)\s*(:)\s*(struct|union|enum|bit_set)'
captures:
1: meta.type.odin entity.name.type.odin
2: keyword.operator.odin
3: keyword.operator.odin
4: storage.type.odin
- match: '\b({{identifier}})\s*(:)\s*(:)\s*([#]\s*type)'
captures:
1: meta.type.odin entity.name.type.odin
2: keyword.operator.odin
3: keyword.operator.odin
4: keyword.tag.odin
- match: '\b({{identifier}})\s*(:)\s*(:)\s*'
captures:
1: meta.constant.odin entity.name.type.odin
2: keyword.operator.odin
3: keyword.operator.odin
types:
- match: '\b(struct|enum|union|bit_set)\b(?:(\{)(\}))?'
captures:
1: storage.type.odin
2: meta.block.odin punctuation.definition.block.begin.odin
3: meta.block.odin punctuation.definition.block.end.odin
- match: '\b(proc)\b'
scope: storage.type.odin
- match: (\[)(\d*)(\])(?=[[:alpha:]_])
scope: meta.brackets.odin
captures:
1: punctuation.definition.brackets.begin.odin punctuation.separator.odin
2: constant.numeric.odin
3: punctuation.definition.brackets.end.odin punctuation.separator.odin
- include: basic-types
- match: '(\$)\s*({{identifier}})'
captures:
1: keyword.generic.odin
2: storage.type.odin
basic-types:
- match: '\b(i8|i16|i32|i64|i128|int)\b'
scope: storage.type.odin
- match: '\b(u8|u16|u32|u64|u128|uint|uintptr)\b'
scope: storage.type.odin
- match: '\b(f16|f32|f64)\b'
scope: storage.type.odin
- match: '\b(f16le|f32le|f64le)\b'
scope: storage.type.odin
- match: '\b(f16be|f32be|f64be)\b'
scope: storage.type.odin
- match: '\b(complex32|complex64|complex128)\b'
scope: storage.type.odin
- match: '\b(quaternion64|quaternion128|quaternion256)\b'
scope: storage.type.odin
- match: '\b(bool|b8|b16|b32|b64)\b'
scope: storage.type.odin
- match: '\b(string|cstring|rune)\b'
scope: storage.type.odin
- match: '\b(rawptr)\b'
scope: storage.type.odin
- match: '\b(any|typeid)\b'
scope: storage.type.odin
- match: '\b(byte)\b'
scope: storage.type.odin
- match: '\b(u16le|u32le|u64le|u128le|i16le|i32le|i64le|i128le)\b'
scope: storage.type.odin
- match: '\b(i16be|i32be|i64be|i128be|u16be|u32be|u64be|u128be)\b'
scope: storage.type.odin
strings:
- match: '"'
scope: punctuation.definition.string.begin.odin
push:
- meta_scope: string.quoted.double.odin
- match: '"'
scope: punctuation.definition.string.end.odin
pop: true
- include: string-escaped-char
- match: "`"
scope: punctuation.definition.string.begin.odin
push:
- meta_scope: string.quoted.raw.odin
- match: "`"
scope: punctuation.definition.string.end.odin
pop: true
- match: "'"
scope: punctuation.definition.string.begin.odin
push:
- meta_scope: string.quoted.raw.odin
- match: "'"
scope: punctuation.definition.string.end.odin
pop: true
- include: string-escaped-char
string-escaped-char:
- match: '\\(\\|[abefnrutv''"]|x\h{2}|u\h{4}|U\h{8}|[0-7]{3})'
scope: constant.character.escape.odin
- match: \\.
scope: invalid.illegal.unknown-escape.odin